Поправка порядка рендера чанков
This commit is contained in:
@@ -31,11 +31,11 @@ project(LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description")
|
|||||||
add_library(luavox_common INTERFACE)
|
add_library(luavox_common INTERFACE)
|
||||||
target_compile_features(luavox_common INTERFACE cxx_std_23)
|
target_compile_features(luavox_common INTERFACE cxx_std_23)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
# if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
target_compile_options(luavox_common INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all)
|
# target_compile_options(luavox_common INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all)
|
||||||
target_link_options(luavox_common INTERFACE -fsanitize=address,undefined)
|
# target_link_options(luavox_common INTERFACE -fsanitize=address,undefined)
|
||||||
set(ENV{ASAN_OPTIONS} detect_leaks=0)
|
# set(ENV{ASAN_OPTIONS} detect_leaks=0)
|
||||||
endif()
|
# endif()
|
||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||||
target_compile_options(luavox_common INTERFACE -fcoroutines)
|
target_compile_options(luavox_common INTERFACE -fcoroutines)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <chrono>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@@ -158,17 +159,35 @@ void Vulkan::run()
|
|||||||
NeedShutdown = false;
|
NeedShutdown = false;
|
||||||
Graphics.ThisThread = std::this_thread::get_id();
|
Graphics.ThisThread = std::this_thread::get_id();
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
|
VkSemaphoreCreateInfo semaphoreCreateInfo = {
|
||||||
VkSemaphore SemaphoreImageAcquired, SemaphoreDrawComplete;
|
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
|
nullptr,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, NULL, &SemaphoreImageAcquired));
|
VkSemaphore SemaphoreImageAcquired[4], SemaphoreDrawComplete[4];
|
||||||
vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, NULL, &SemaphoreDrawComplete));
|
int semNext = 0;
|
||||||
|
|
||||||
|
for(int iter = 0; iter < 4; iter++) {
|
||||||
|
vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, nullptr, &SemaphoreImageAcquired[iter]));
|
||||||
|
vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, nullptr, &SemaphoreDrawComplete[iter]));
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFence drawEndFence = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
{
|
||||||
|
VkFenceCreateInfo info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.flags = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCreateFence(Graphics.Device, &info, nullptr, &drawEndFence);
|
||||||
|
}
|
||||||
|
|
||||||
double prevTime = glfwGetTime();
|
double prevTime = glfwGetTime();
|
||||||
while(!NeedShutdown)
|
while(!NeedShutdown)
|
||||||
{
|
{
|
||||||
|
|
||||||
float dTime = glfwGetTime()-prevTime;
|
float dTime = glfwGetTime()-prevTime;
|
||||||
prevTime += dTime;
|
prevTime += dTime;
|
||||||
|
|
||||||
@@ -230,7 +249,8 @@ void Vulkan::run()
|
|||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
VkResult err;
|
VkResult err;
|
||||||
err = vkAcquireNextImageKHR(Graphics.Device, Graphics.Swapchain, 1000000000ULL/20, SemaphoreImageAcquired, (VkFence) 0, &Graphics.DrawBufferCurrent);
|
semNext = ++semNext % 4;
|
||||||
|
err = vkAcquireNextImageKHR(Graphics.Device, Graphics.Swapchain, 1000000000ULL/20, SemaphoreImageAcquired[semNext], (VkFence) 0, &Graphics.DrawBufferCurrent);
|
||||||
GlobalTime gTime = glfwGetTime();
|
GlobalTime gTime = glfwGetTime();
|
||||||
|
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
@@ -529,19 +549,25 @@ void Vulkan::run()
|
|||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.waitSemaphoreCount = 1,
|
.waitSemaphoreCount = 1,
|
||||||
.pWaitSemaphores = &SemaphoreImageAcquired,
|
.pWaitSemaphores = &SemaphoreImageAcquired[semNext],
|
||||||
.pWaitDstStageMask = &pipe_stage_flags,
|
.pWaitDstStageMask = &pipe_stage_flags,
|
||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &Graphics.CommandBufferRender,
|
.pCommandBuffers = &Graphics.CommandBufferRender,
|
||||||
.signalSemaphoreCount = 1,
|
.signalSemaphoreCount = 1,
|
||||||
.pSignalSemaphores = &SemaphoreDrawComplete
|
.pSignalSemaphores = &SemaphoreDrawComplete[semNext]
|
||||||
};
|
};
|
||||||
|
|
||||||
//Рисуем, когда получим картинку
|
// Отправляем команды рендера в очередь
|
||||||
{
|
{
|
||||||
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
||||||
vkAssert(!vkQueueSubmit(*lockQueue, 1, &submit_info, nullFence));
|
vkAssert(!vkQueueSubmit(*lockQueue, 1, &submit_info, drawEndFence));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
// Насильно ожидаем завершения рендера кадра
|
||||||
|
vkWaitForFences(Graphics.Device, 1, &drawEndFence, true, -1);
|
||||||
|
vkResetFences(Graphics.Device, 1, &drawEndFence);
|
||||||
|
// LOG.debug() << (std::chrono::high_resolution_clock::now()-now).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -550,13 +576,13 @@ void Vulkan::run()
|
|||||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||||
.pNext = NULL,
|
.pNext = NULL,
|
||||||
.waitSemaphoreCount = 1,
|
.waitSemaphoreCount = 1,
|
||||||
.pWaitSemaphores = &SemaphoreDrawComplete,
|
.pWaitSemaphores = &SemaphoreDrawComplete[semNext],
|
||||||
.swapchainCount = 1,
|
.swapchainCount = 1,
|
||||||
.pSwapchains = &Graphics.Swapchain,
|
.pSwapchains = &Graphics.Swapchain,
|
||||||
.pImageIndices = &Graphics.DrawBufferCurrent
|
.pImageIndices = &Graphics.DrawBufferCurrent
|
||||||
};
|
};
|
||||||
|
|
||||||
// Завершаем картинку
|
// Передадим фрейм, когда рендер будет завершён
|
||||||
{
|
{
|
||||||
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
||||||
err = vkQueuePresentKHR(*lockQueue, &present);
|
err = vkQueuePresentKHR(*lockQueue, &present);
|
||||||
@@ -580,20 +606,21 @@ void Vulkan::run()
|
|||||||
|
|
||||||
Game.Session->atFreeDrawTime(gTime, dTime);
|
Game.Session->atFreeDrawTime(gTime, dTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vkAssert(!vkQueueWaitIdle(Graphics.DeviceQueueGraphic));
|
|
||||||
|
|
||||||
{
|
|
||||||
// Эту хрень надо убрать
|
|
||||||
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
|
||||||
vkDeviceWaitIdle(Graphics.Device);
|
|
||||||
lockQueue.unlock();
|
|
||||||
}
|
|
||||||
Screen.State = DrawState::End;
|
Screen.State = DrawState::End;
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDestroySemaphore(Graphics.Device, SemaphoreImageAcquired, nullptr);
|
{
|
||||||
vkDestroySemaphore(Graphics.Device, SemaphoreDrawComplete, nullptr);
|
auto lockQueue = Graphics.DeviceQueueGraphic.lock();
|
||||||
|
vkDeviceWaitIdle(Graphics.Device);
|
||||||
|
lockQueue.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int iter = 0; iter < 4; iter++) {
|
||||||
|
vkDestroySemaphore(Graphics.Device, SemaphoreImageAcquired[iter], nullptr);
|
||||||
|
vkDestroySemaphore(Graphics.Device, SemaphoreDrawComplete[iter], nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyFence(Graphics.Device, drawEndFence, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan::glfwCallbackError(int error, const char *description)
|
void Vulkan::glfwCallbackError(int error, const char *description)
|
||||||
@@ -777,8 +804,8 @@ void Vulkan::buildSwapchains()
|
|||||||
.imageColorSpace = Graphics.SurfaceColorSpace,
|
.imageColorSpace = Graphics.SurfaceColorSpace,
|
||||||
.imageExtent = swapchainExtent,
|
.imageExtent = swapchainExtent,
|
||||||
.imageArrayLayers = 1,
|
.imageArrayLayers = 1,
|
||||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||||
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
// | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||||
.queueFamilyIndexCount = 0,
|
.queueFamilyIndexCount = 0,
|
||||||
.pQueueFamilyIndices = nullptr,
|
.pQueueFamilyIndices = nullptr,
|
||||||
|
|||||||
@@ -816,7 +816,7 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
.flags = 0,
|
.flags = 0,
|
||||||
.depthTestEnable = true,
|
.depthTestEnable = true,
|
||||||
.depthWriteEnable = true,
|
.depthWriteEnable = true,
|
||||||
.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL,
|
.depthCompareOp = VK_COMPARE_OP_LESS,
|
||||||
.depthBoundsTestEnable = false,
|
.depthBoundsTestEnable = false,
|
||||||
.stencilTestEnable = false,
|
.stencilTestEnable = false,
|
||||||
.front = VkStencilOpState
|
.front = VkStencilOpState
|
||||||
@@ -1209,7 +1209,7 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4;
|
Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4;
|
||||||
Pos::GlobalRegion x64offset_region = x64offset >> 2;
|
Pos::GlobalRegion x64offset_region = x64offset >> 2;
|
||||||
|
|
||||||
auto [voxelVertexs, nodeVertexs] = VKCTX->ThreadVertexObj.getChunksForRender(WorldId, Pos, 1, PCO.ProjView, x64offset_region);
|
auto [voxelVertexs, nodeVertexs] = VKCTX->ThreadVertexObj.getChunksForRender(WorldId, Pos, 2, PCO.ProjView, x64offset_region);
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
@@ -1233,8 +1233,8 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
vkCmdDraw(drawCmd, vertexCount, 1, offset, 0);
|
vkCmdDraw(drawCmd, vertexCount, 1, offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TOS::Logger LOG = "VRS";
|
// TOS::Logger LOG = "VRS";
|
||||||
LOG.debug() << "Node: drawCals: " << nodeVertexs.size() << " vertexs: " << count;
|
// LOG.debug() << "Node: drawCals: " << nodeVertexs.size() << " vertexs: " << count;
|
||||||
|
|
||||||
PCO.Model = orig;
|
PCO.Model = orig;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Client/Abstract.hpp"
|
#include "Client/Abstract.hpp"
|
||||||
#include "Common/Abstract.hpp"
|
#include "Common/Abstract.hpp"
|
||||||
#include <Client/Vulkan/Vulkan.hpp>
|
#include <Client/Vulkan/Vulkan.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include "VertexPool.hpp"
|
#include "VertexPool.hpp"
|
||||||
#include "glm/fwd.hpp"
|
#include "glm/fwd.hpp"
|
||||||
#include "../FrustumCull.h"
|
#include "../FrustumCull.h"
|
||||||
|
#include "glm/geometric.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур
|
У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур
|
||||||
@@ -184,10 +186,11 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>,
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>,
|
||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>>
|
||||||
> getChunksForRender(WorldId_t worldId, Pos::Object pos, uint8_t distance, glm::mat4 projView, Pos::GlobalRegion x64offset) {
|
> getChunksForRender(WorldId_t worldId, Pos::Object pos, uint8_t distance, glm::mat4 projView, Pos::GlobalRegion x64offset) {
|
||||||
Pos::GlobalRegion center = pos >> Pos::Object_t::BS_Bit >> 4 >> 2;
|
Pos::GlobalChunk playerChunk = pos >> Pos::Object_t::BS_Bit >> 4;
|
||||||
|
Pos::GlobalRegion center = playerChunk >> 2;
|
||||||
|
|
||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> vertexVoxels;
|
std::vector<std::tuple<float, Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> vertexVoxels;
|
||||||
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> vertexNodes;
|
std::vector<std::tuple<float, Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> vertexNodes;
|
||||||
|
|
||||||
auto iterWorld = ChunkMesh.find(worldId);
|
auto iterWorld = ChunkMesh.find(worldId);
|
||||||
if(iterWorld == ChunkMesh.end())
|
if(iterWorld == ChunkMesh.end())
|
||||||
@@ -220,17 +223,50 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto &chunk = iterRegion->second[index];
|
auto &chunk = iterRegion->second[index];
|
||||||
|
|
||||||
|
float distance;
|
||||||
|
|
||||||
if(chunk.VoxelPointer)
|
if(chunk.VoxelPointer || chunk.NodePointer) {
|
||||||
vertexVoxels.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount);
|
Pos::GlobalChunk cp = local+Pos::GlobalChunk(localPos)-playerChunk;
|
||||||
if(chunk.NodePointer)
|
distance = cp.x*cp.x+cp.y*cp.y+cp.z*cp.z;
|
||||||
vertexNodes.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount);
|
}
|
||||||
|
|
||||||
|
if(chunk.VoxelPointer) {
|
||||||
|
vertexVoxels.emplace_back(distance, local+Pos::GlobalChunk(localPos), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(chunk.NodePointer) {
|
||||||
|
vertexNodes.emplace_back(distance, local+Pos::GlobalChunk(localPos), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::pair{vertexVoxels, vertexNodes};
|
auto sortByDistance = []
|
||||||
|
(
|
||||||
|
const std::tuple<float, Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>& a,
|
||||||
|
const std::tuple<float, Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>& b
|
||||||
|
) {
|
||||||
|
return std::get<0>(a) < std::get<0>(b);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::sort(vertexVoxels.begin(), vertexVoxels.end(), sortByDistance);
|
||||||
|
std::sort(vertexNodes.begin(), vertexNodes.end(), sortByDistance);
|
||||||
|
|
||||||
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> resVertexVoxels;
|
||||||
|
std::vector<std::tuple<Pos::GlobalChunk, std::pair<VkBuffer, int>, uint32_t>> resVertexNodes;
|
||||||
|
|
||||||
|
resVertexVoxels.reserve(vertexVoxels.size());
|
||||||
|
resVertexNodes.reserve(vertexNodes.size());
|
||||||
|
|
||||||
|
for(const auto& [d, pos, ptr, count] : vertexVoxels)
|
||||||
|
resVertexVoxels.emplace_back(pos, ptr, count);
|
||||||
|
|
||||||
|
for(const auto& [d, pos, ptr, count] : vertexNodes)
|
||||||
|
resVertexNodes.emplace_back(pos, ptr, count);
|
||||||
|
|
||||||
|
return std::pair{resVertexVoxels, resVertexNodes};
|
||||||
}
|
}
|
||||||
|
|
||||||
void join() {
|
void join() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#version 450
|
#version 460
|
||||||
|
|
||||||
layout (triangles) in;
|
layout (triangles) in;
|
||||||
layout (triangle_strip, max_vertices = 3) out;
|
layout (triangle_strip, max_vertices = 3) out;
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
#version 450
|
#version 460
|
||||||
|
|
||||||
layout(location = 0) in uvec3 Vertex;
|
layout(location = 0) in uvec3 Vertex;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,6 @@
|
|||||||
#version 450
|
#version 460
|
||||||
|
|
||||||
|
// layout(early_fragment_tests) in;
|
||||||
|
|
||||||
layout(location = 0) in FragmentObj {
|
layout(location = 0) in FragmentObj {
|
||||||
vec3 GeoPos; // Реальная позиция в мире
|
vec3 GeoPos; // Реальная позиция в мире
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
#version 450
|
#version 460
|
||||||
|
|
||||||
layout(location = 0) in FragmentObj {
|
layout(location = 0) in FragmentObj {
|
||||||
vec3 GeoPos; // Реальная позиция в мире
|
vec3 GeoPos; // Реальная позиция в мире
|
||||||
@@ -20,5 +20,5 @@ layout(set = 1, binding = 1) readonly buffer LightMapLayoutObj {
|
|||||||
} LightMapLayout;
|
} LightMapLayout;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
Frame = vec4(1);
|
Frame = vec4(Fragment.GeoPos, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user