Рисуем квадратик

This commit is contained in:
2025-02-15 16:55:43 +06:00
parent 35d71c211b
commit dce0272653
31 changed files with 434 additions and 174 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
/.cache
/.vscode
/build
/Work/*
/CMakeFiles
/CMakeCache.txt

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.13)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") # -rdynamic
project (LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description")
@@ -59,10 +60,10 @@ target_link_libraries(${PROJECT_NAME} PUBLIC TOS_Lib)
# Static Assets
file(GLOB_RECURSE ASSETS RELATIVE "${PROJECT_SOURCE_DIR}/Work/assets" "Work/assets/*.*")
file(GLOB_RECURSE ASSETS RELATIVE "${PROJECT_SOURCE_DIR}/assets" "assets/*.*")
add_custom_command(OUTPUT assets.o resources.cpp INPUT ${ASSETS}
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ${CMAKE_CURRENT_SOURCE_DIR}/Src/assets.py ${ASSETS}
COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/Work/assets" && ld -r -b binary -o '${CMAKE_CURRENT_BINARY_DIR}/assets.o' ${ASSETS}
COMMAND cd "${CMAKE_CURRENT_SOURCE_DIR}/assets" && ld -r -b binary -o '${CMAKE_CURRENT_BINARY_DIR}/assets.o' ${ASSETS}
COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${CMAKE_CURRENT_BINARY_DIR}/assets.o ${CMAKE_CURRENT_BINARY_DIR}/assets.o)
SET_SOURCE_FILES_PROPERTIES(assets.o PROPERTIES EXTERNAL_OBJECT true GENERATED true)

View File

@@ -177,8 +177,6 @@ void ServerSession::onCursorMove(float xMove, float yMove) {
PYR += deltaPYR;
PYR_Offset = deltaPYR+deltaTime*PYR_Offset;
glm::vec3 front = Camera.Quat*glm::vec3(0.0f, 0.0f, -1.0f);
}
void ServerSession::onCursorBtn(ISurfaceEventListener::EnumCursorBtn btn, bool state) {
@@ -197,6 +195,19 @@ void ServerSession::onJoystick() {
void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
GTime = gTime;
if(!RS)
return;
// Расчёт камеры
{
float deltaTime = 1-std::min<float>(gTime-PYR_At, 1/PYR_TIME_DELTA)*PYR_TIME_DELTA;
glm::quat quat =
glm::angleAxis(PYR.x-deltaTime*PYR_Offset.x, glm::vec3(1.f, 0.f, 0.f))
* glm::angleAxis(PYR.y-deltaTime*PYR_Offset.y, glm::vec3(0.f, 1.f, 0.f));
RS->setCameraPos(0, {0, 0, 0}, quat);
}
}
coro<> ServerSession::run() {

View File

@@ -37,7 +37,7 @@ class ServerSession : public AsyncObject, public IServerSession, public ISurface
boost::lockfree::spsc_queue<ParsedPacket*> NetInputPackets;
//
// PYR - поворот камеры по осям xyz в радианах, PYR_Offset для сглаживание поворота
glm::vec3 PYR = glm::vec3(0), PYR_Offset = glm::vec3(0);
double PYR_At = 0;
static constexpr float PYR_TIME_DELTA = 30;

View File

@@ -34,7 +34,7 @@ namespace LV::Client::VK {
struct ServerObj {
Server::GameServer GS;
Net::Server LS;
Net::SocketServer LS;
ServerObj(asio::io_context &ioc)
: GS(ioc, ""), LS(ioc, [&](tcp::socket sock) -> coro<> { co_await GS.pushSocketConnect(std::move(sock)); }, 7890)
@@ -89,6 +89,19 @@ Vulkan::Vulkan(asio::io_context &ioc)
} catch(const std::exception &exc) {
LOG.error() << "Vulkan::run: " << exc.what();
}
try { Game.RSession = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.RSession = nullptr: " << exc.what();
}
try { Game.Session = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.Session = nullptr: " << exc.what();
}
try { Game.Server = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.Server = nullptr: " << exc.what();
}
GuardLock.reset();
});
}
@@ -155,18 +168,6 @@ void Vulkan::run()
} catch(const std::exception &exc) {
LOG.error() << "Game.Server->GS.shutdown: " << exc.what();
}
try { Game.RSession = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.RSession = nullptr: " << exc.what();
}
try { Game.Session = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.Session = nullptr: " << exc.what();
}
try { Game.Server = nullptr; } catch(const std::exception &exc) {
LOG.error() << "Game.Server = nullptr: " << exc.what();
}
}
if(Game.Session) {
@@ -235,7 +236,7 @@ void Vulkan::run()
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = Graphics.InlineTexture.Image,
.image = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image, // Graphics.InlineTexture.Image,
.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
};
@@ -246,7 +247,7 @@ void Vulkan::run()
{
const VkClearValue clear_values[2] =
{
[0] = { .color = { .float32 = { 0.2f, 0.2f, 0.4f, 1.f }}},
[0] = { .color = { .float32 = { 0.1f, 0.1f, 0.1f, 1.f }}},
[1] = { .depthStencil = { 1, 0 } },
};
@@ -255,7 +256,7 @@ void Vulkan::run()
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = nullptr,
.renderPass = Graphics.RenderPass,
.framebuffer = Graphics.InlineTexture.Frame,
.framebuffer = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].FrameBuffer, //Graphics.InlineTexture.Frame,
.renderArea = VkRect2D {
.offset = {0, 0},
.extent = Screen.FrameExtent
@@ -288,69 +289,163 @@ void Vulkan::run()
glm::ivec2 interfaceSize = {int(Screen.Width*720/minSize), int(Screen.Height*720/minSize)};
}
vkCmdEndRenderPass(Graphics.CommandBufferRender);
// vkCmdEndRenderPass(Graphics.CommandBufferRender);
// {
// VkImageMemoryBarrier src_barrier =
// {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .pNext = nullptr,
// .srcAccessMask = 0,
// .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = Graphics.InlineTexture.Image,
// .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
// };
// VkImageMemoryBarrier dst_barrier =
// {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .pNext = nullptr,
// .srcAccessMask = 0,
// .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
// .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image,
// .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
// };
// vkCmdPipelineBarrier(
// Graphics.CommandBufferRender,
// VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// 0,
// 0, nullptr,
// 0, nullptr,
// 1, &src_barrier
// );
// vkCmdPipelineBarrier(
// Graphics.CommandBufferRender,
// VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// 0,
// 0, nullptr,
// 0, nullptr,
// 1, &dst_barrier
// );
// VkImageCopy copy_region =
// {
// .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
// .srcOffset = {0, 0, 0},
// .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
// .dstOffset = {0, 0, 0},
// .extent = {Screen.FrameExtent.width, Screen.FrameExtent.height, 1}
// };
// vkCmdCopyImage(
// Graphics.CommandBufferRender,
// Graphics.InlineTexture.Image,
// VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
// Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// 1, &copy_region
// );
// VkImageMemoryBarrier post_copy_barrier =
// {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .pNext = nullptr,
// .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
// .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image,
// .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
// };
// vkCmdPipelineBarrier(
// Graphics.CommandBufferRender,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// 0,
// 0, nullptr,
// 0, nullptr,
// 1, &post_copy_barrier
// );
// }
{
VkImageMemoryBarrier prePresentBarrier =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = Graphics.InlineTexture.Image,
.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
};
// {
// VkImageMemoryBarrier prePresentBarrier =
// {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .pNext = nullptr,
// .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = Graphics.InlineTexture.Image,
// .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
// };
vkCmdPipelineBarrier(Graphics.CommandBufferRender, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
0, 0, nullptr, 0, nullptr, 1, &prePresentBarrier);
}
// vkCmdPipelineBarrier(Graphics.CommandBufferRender, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
// 0, 0, nullptr, 0, nullptr, 1, &prePresentBarrier);
// }
{
VkImageMemoryBarrier image_memory_barrier =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image,
.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
};
// {
// VkImageMemoryBarrier image_memory_barrier =
// {
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
// .pNext = nullptr,
// .srcAccessMask = 0,
// .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
// .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
// .image = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].Image,
// .subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }
// };
vkCmdPipelineBarrier(Graphics.CommandBufferRender, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
// vkCmdPipelineBarrier(Graphics.CommandBufferRender, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
// }
{
const VkClearValue clear_values[2] =
{
[0] = { .color = { .float32 = { 0.1f, 0.1f, 0.1f, 1.0f }}},
[1] = { .depthStencil = { 1, 0 } },
};
// {
// const VkClearValue clear_values[2] =
// {
// [0] = { .color = { .float32 = { 0.1f, 0.1f, 0.1f, 1.0f }}},
// [1] = { .depthStencil = { 1, 0 } },
// };
const VkRenderPassBeginInfo rp_begin =
{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = nullptr,
.renderPass = Graphics.RenderPass,
.framebuffer = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].FrameBuffer,
.renderArea = VkRect2D {
.offset = {0, 0},
.extent = Screen.FrameExtent
},
.clearValueCount = 2,
.pClearValues = clear_values
};
// const VkRenderPassBeginInfo rp_begin =
// {
// .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
// .pNext = nullptr,
// .renderPass = Graphics.RenderPass,
// .framebuffer = Graphics.DrawBuffers[Graphics.DrawBufferCurrent].FrameBuffer,
// .renderArea = VkRect2D {
// .offset = {0, 0},
// .extent = Screen.FrameExtent
// },
// .clearValueCount = 2,
// .pClearValues = clear_values
// };
vkCmdBeginRenderPass(Graphics.CommandBufferRender, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
}
// vkCmdBeginRenderPass(Graphics.CommandBufferRender, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
// }
#ifdef HAS_IMGUI
ImGui_ImplVulkan_NewFrame();
@@ -629,7 +724,8 @@ void Vulkan::buildSwapchains()
.imageColorSpace = Graphics.SurfaceColorSpace,
.imageExtent = swapchainExtent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
@@ -777,9 +873,10 @@ void Vulkan::buildSwapchains()
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage =
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
@@ -1876,7 +1973,7 @@ bool Vulkan::needFullVulkanRebuild()
return false;
}
std::shared_ptr<ShaderModule> Vulkan::createShader(const ByteBuffer &data)
std::shared_ptr<ShaderModule> Vulkan::createShader(std::string_view data)
{
assert(Graphics.Device);
assert(data.size());
@@ -1886,11 +1983,6 @@ std::shared_ptr<ShaderModule> Vulkan::createShader(const ByteBuffer &data)
return module;
}
std::shared_ptr<ShaderModule> Vulkan::createShaderFromFile(std::filesystem::path file)
{
return createShader(std::ifstream(file));
}
void Vulkan::registerDependent(std::shared_ptr<IVulkanDependent> dependent)
{
assert(Graphics.Device);
@@ -2457,8 +2549,8 @@ void Pipeline::init(Vulkan *instance)
// Shader
ShaderModule::ShaderModule(const ByteBuffer &buff)
: Source(buff)
ShaderModule::ShaderModule(std::string_view view)
: Source(view)
{}
void ShaderModule::free(Vulkan *instance)
@@ -4467,10 +4559,10 @@ PipelineVF::~PipelineVF() = default;
void PipelineVF::init(Vulkan *instance)
{
if(!ShaderVertex)
ShaderVertex = instance->createShaderFromFile(PathVertex);
ShaderVertex = instance->createShader(getResource(PathVertex)->makeView());
if(!ShaderFragment)
ShaderFragment = instance->createShaderFromFile(PathFragment);
ShaderFragment = instance->createShader(getResource(PathFragment)->makeView());
Settings.ShaderStages =
{
@@ -4525,13 +4617,13 @@ PipelineVGF::~PipelineVGF() = default;
void PipelineVGF::init(Vulkan *instance)
{
if(!ShaderVertex)
ShaderVertex = instance->createShaderFromFile(PathVertex);
ShaderVertex = instance->createShader(getResource(PathVertex)->makeView());
if(!ShaderGeometry)
ShaderGeometry = instance->createShaderFromFile(PathGeometry);
ShaderGeometry = instance->createShader(getResource(PathGeometry)->makeView());
if(!ShaderFragment)
ShaderFragment = instance->createShaderFromFile(PathFragment);
ShaderFragment = instance->createShader(getResource(PathFragment)->makeView());
Settings.ShaderStages =
{

View File

@@ -327,9 +327,7 @@ public:
/* Части графических конвейеров
Удалить можно только после полной деинициализации вулкана */
// Загрузка шейдера
std::shared_ptr<ShaderModule> createShader(const ByteBuffer &data);
// Загрузка шейдера с файла
std::shared_ptr<ShaderModule> createShaderFromFile(std::filesystem::path file);
std::shared_ptr<ShaderModule> createShader(std::string_view data);
// Регистрация объекта зависимого от изменений в графическом конвейере
void registerDependent(std::shared_ptr<IVulkanDependent> dependent);
// Регистрация объекта зависимого от изменений в графическом конвейере
@@ -472,14 +470,14 @@ public:
*/
class ShaderModule : public IVulkanDependent {
VkShaderModule Module = VK_NULL_HANDLE;
ByteBuffer Source;
std::string Source;
protected:
virtual void free(Vulkan *instance) override;
virtual void init(Vulkan *instance) override;
public:
ShaderModule(const ByteBuffer &buff);
ShaderModule(std::string_view view);
virtual ~ShaderModule();
VkShaderModule getModule() const { return Module; }

View File

@@ -1,4 +1,7 @@
#include "VulkanRenderSession.hpp"
#include "Client/Vulkan/Vulkan.hpp"
#include "assets.hpp"
#include <glm/ext/matrix_transform.hpp>
#include <vulkan/vulkan_core.h>
namespace LV::Client::VK {
@@ -29,8 +32,11 @@ void VulkanRenderSession::free(Vulkan *instance) {
if(MainAtlasDescLayout)
vkDestroyDescriptorSetLayout(instance->Graphics.Device, MainAtlasDescLayout, nullptr);
if(LightMapDescLayout)
vkDestroyDescriptorSetLayout(instance->Graphics.Device, LightMapDescLayout, nullptr);
if(VoxelLightMapDescLayout)
vkDestroyDescriptorSetLayout(instance->Graphics.Device, VoxelLightMapDescLayout, nullptr);
if(DescriptorPool)
vkDestroyDescriptorPool(instance->Graphics.Device, DescriptorPool, nullptr);
}
VoxelOpaquePipeline = VK_NULL_HANDLE;
@@ -41,7 +47,13 @@ void VulkanRenderSession::free(Vulkan *instance) {
MainAtlas_LightMap_PipelineLayout = VK_NULL_HANDLE;
MainAtlasDescLayout = VK_NULL_HANDLE;
LightMapDescLayout = VK_NULL_HANDLE;
VoxelLightMapDescLayout = VK_NULL_HANDLE;
DescriptorPool = VK_NULL_HANDLE;
MainAtlasDescriptor = VK_NULL_HANDLE;
VoxelLightMapDescriptor = VK_NULL_HANDLE;
VKCTX = nullptr;
}
void VulkanRenderSession::init(Vulkan *instance) {
@@ -50,6 +62,23 @@ void VulkanRenderSession::init(Vulkan *instance) {
}
// Разметка дескрипторов
if(!DescriptorPool) {
std::vector<VkDescriptorPoolSize> pool_sizes = {
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3},
{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 3}
};
VkDescriptorPoolCreateInfo descriptor_pool = {};
descriptor_pool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptor_pool.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
descriptor_pool.maxSets = 8;
descriptor_pool.poolSizeCount = (uint32_t) pool_sizes.size();
descriptor_pool.pPoolSizes = pool_sizes.data();
assert(!vkCreateDescriptorPool(VkInst->Graphics.Device, &descriptor_pool, nullptr,
&DescriptorPool));
}
if(!MainAtlasDescLayout) {
std::vector<VkDescriptorSetLayoutBinding> shaderLayoutBindings =
{
@@ -81,7 +110,20 @@ void VulkanRenderSession::init(Vulkan *instance) {
instance->Graphics.Device, &descriptorLayout, nullptr, &MainAtlasDescLayout));
}
if(!LightMapDescLayout) {
if(!MainAtlasDescriptor) {
VkDescriptorSetAllocateInfo ciAllocInfo =
{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = DescriptorPool,
.descriptorSetCount = 1,
.pSetLayouts = &MainAtlasDescLayout
};
assert(!vkAllocateDescriptorSets(instance->Graphics.Device, &ciAllocInfo, &MainAtlasDescriptor));
}
if(!VoxelLightMapDescLayout) {
std::vector<VkDescriptorSetLayoutBinding> shaderLayoutBindings =
{
{
@@ -108,9 +150,21 @@ void VulkanRenderSession::init(Vulkan *instance) {
.pBindings = shaderLayoutBindings.data()
};
assert(!vkCreateDescriptorSetLayout( instance->Graphics.Device, &descriptorLayout, nullptr, &LightMapDescLayout));
assert(!vkCreateDescriptorSetLayout( instance->Graphics.Device, &descriptorLayout, nullptr, &VoxelLightMapDescLayout));
}
if(!VoxelLightMapDescriptor) {
VkDescriptorSetAllocateInfo ciAllocInfo =
{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = DescriptorPool,
.descriptorSetCount = 1,
.pSetLayouts = &VoxelLightMapDescLayout
};
assert(!vkAllocateDescriptorSets(instance->Graphics.Device, &ciAllocInfo, &VoxelLightMapDescriptor));
}
std::vector<VkPushConstantRange> worldWideShaderPushConstants =
{
@@ -121,12 +175,39 @@ void VulkanRenderSession::init(Vulkan *instance) {
}
};
if(!VKCTX) {
VKCTX = std::make_shared<VulkanContext>(VkInst);
VKCTX->MainTest.atlasAddCallbackOnUniformChange([this]() -> bool {
updateDescriptor_MainAtlas();
return true;
});
VKCTX->LightDummy.atlasAddCallbackOnUniformChange([this]() -> bool {
updateDescriptor_VoxelsLight();
return true;
});
NodeVertexStatic *array = (NodeVertexStatic*) VKCTX->TestQuad.mapMemory();
array[0] = {112, 114, 113, 0, 0, 0, 0, 0, 0};
array[1] = {114, 114, 113, 0, 0, 0, 0, 65535, 0};
array[2] = {114, 112, 113, 0, 0, 0, 0, 65535, 65535};
array[3] = {112, 114, 113, 0, 0, 0, 0, 0, 0};
array[4] = {114, 112, 113, 0, 0, 0, 0, 65535, 65535};
array[5] = {112, 112, 113, 0, 0, 0, 0, 0, 65535};
VKCTX->TestQuad.unMapMemory();
}
updateDescriptor_MainAtlas();
updateDescriptor_VoxelsLight();
updateDescriptor_ChunksLight();
// Разметка графических конвейеров
if(!MainAtlas_LightMap_PipelineLayout) {
std::vector<VkDescriptorSetLayout> layouts =
{
MainAtlasDescLayout,
LightMapDescLayout
VoxelLightMapDescLayout
};
const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
@@ -168,16 +249,16 @@ void VulkanRenderSession::init(Vulkan *instance) {
{
// Для статичных непрозрачных и полупрозрачных вокселей
if(!VoxelShaderVertex)
VoxelShaderVertex = VkInst->createShaderFromFile("assets/shaders/chunk/voxel.vert.bin");
VoxelShaderVertex = VkInst->createShader(getResource("shaders/chunk/voxel.vert.bin")->makeView());
if(!VoxelShaderGeometry)
VoxelShaderGeometry = VkInst->createShaderFromFile("assets/shaders/chunk/voxel.geom.bin");
VoxelShaderGeometry = VkInst->createShader(getResource("shaders/chunk/voxel.geom.bin")->makeView());
if(!VoxelShaderFragmentOpaque)
VoxelShaderFragmentOpaque = VkInst->createShaderFromFile("assets/shaders/chunk/voxel_opaque.frag.bin");
VoxelShaderFragmentOpaque = VkInst->createShader(getResource("shaders/chunk/voxel_opaque.frag.bin")->makeView());
if(!VoxelShaderFragmentTransparent)
VoxelShaderFragmentTransparent = VkInst->createShaderFromFile("assets/shaders/chunk/voxel_transparent.frag.bin");
VoxelShaderFragmentTransparent = VkInst->createShader(getResource("shaders/chunk/voxel_transparent.frag.bin")->makeView());
// Конвейер шейдеров
std::vector<VkPipelineShaderStageCreateInfo> shaderStages =
@@ -404,16 +485,16 @@ void VulkanRenderSession::init(Vulkan *instance) {
// Для статичных непрозрачных и полупрозрачных нод
if(!NodeShaderVertex)
NodeShaderVertex = VkInst->createShaderFromFile("assets/shaders/chunk/node.vert.bin");
NodeShaderVertex = VkInst->createShader(getResource("shaders/chunk/node.vert.bin")->makeView());
if(!NodeShaderGeometry)
NodeShaderGeometry = VkInst->createShaderFromFile("assets/shaders/chunk/node.geom.bin");
NodeShaderGeometry = VkInst->createShader(getResource("shaders/chunk/node.geom.bin")->makeView());
if(!NodeShaderFragmentOpaque)
NodeShaderFragmentOpaque = VkInst->createShaderFromFile("assets/shaders/chunk/node_opaque.frag.bin");
NodeShaderFragmentOpaque = VkInst->createShader(getResource("shaders/chunk/node_opaque.frag.bin")->makeView());
if(!NodeShaderFragmentTransparent)
NodeShaderFragmentTransparent = VkInst->createShaderFromFile("assets/shaders/chunk/node_transparent.frag.bin");
NodeShaderFragmentTransparent = VkInst->createShader(getResource("shaders/chunk/node_transparent.frag.bin")->makeView());
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
@@ -510,6 +591,85 @@ void VulkanRenderSession::beforeDraw() {
}
void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd) {
glm::mat4 proj = glm::perspective<float>(75, float(VkInst->Screen.Width)/float(VkInst->Screen.Height), 0.5, std::pow(2, 17));
PCO.ProjView = glm::mat4(Quat);
//PCO.ProjView *= proj;
PCO.Model = glm::mat4(1); //= glm::rotate(glm::mat4(1), float(gTime/10), glm::vec3(0, 1, 0));
vkCmdBindPipeline(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS, NodeStaticOpaquePipeline);
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, 0, sizeof(WorldPCO), &PCO);
vkCmdBindDescriptorSets(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
MainAtlas_LightMap_PipelineLayout, 0, 2,
(const VkDescriptorSet[]) {MainAtlasDescriptor, VoxelLightMapDescriptor}, 0, nullptr);
VkDeviceSize vkOffsets = 0;
VkBuffer vkBuffer = VKCTX->TestQuad;
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
vkCmdDraw(drawCmd, 6, 1, 0, 0);
}
void VulkanRenderSession::updateDescriptor_MainAtlas() {
VkDescriptorBufferInfo bufferInfo = VKCTX->MainTest;
VkDescriptorImageInfo imageInfo = VKCTX->MainTest;
std::vector<VkWriteDescriptorSet> ciDescriptorSet =
{
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = MainAtlasDescriptor,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &imageInfo
}, {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = MainAtlasDescriptor,
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &bufferInfo
}
};
vkUpdateDescriptorSets(VkInst->Graphics.Device, ciDescriptorSet.size(), ciDescriptorSet.data(), 0, nullptr);
}
void VulkanRenderSession::updateDescriptor_VoxelsLight() {
VkDescriptorBufferInfo bufferInfo = VKCTX->LightDummy;
VkDescriptorImageInfo imageInfo = VKCTX->LightDummy;
std::vector<VkWriteDescriptorSet> ciDescriptorSet =
{
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = VoxelLightMapDescriptor,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &imageInfo
}, {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = VoxelLightMapDescriptor,
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &bufferInfo
}
};
vkUpdateDescriptorSets(VkInst->Graphics.Device, ciDescriptorSet.size(), ciDescriptorSet.data(), 0, nullptr);
}
void VulkanRenderSession::updateDescriptor_ChunksLight() {
}

View File

@@ -3,6 +3,7 @@
#include "Common/Abstract.hpp"
#include <Client/Vulkan/Vulkan.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <vulkan/vulkan_core.h>
/*
У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур
@@ -52,7 +53,6 @@ struct VoxelVertexPoint {
};
/*
Из-за карт освещения индексов не будет
Максимальный размер меша 14^3 м от центра ноды
Координатное пространство то же, что и у вокселей + 8 позиций с двух сторон
Рисуется полигонами
@@ -78,6 +78,20 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
Pos::Object Pos;
glm::quat Quat;
struct VulkanContext {
AtlasImage MainTest, LightDummy;
Buffer TestQuad;
VulkanContext(Vulkan *vkInst)
: MainTest(vkInst), LightDummy(vkInst),
TestQuad(vkInst, sizeof(NodeVertexStatic)*6)
{}
};
std::shared_ptr<VulkanContext> VKCTX;
VkDescriptorPool DescriptorPool = VK_NULL_HANDLE;
/*
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Текстурный атлас
@@ -85,13 +99,15 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Данные к атласу
*/
VkDescriptorSetLayout MainAtlasDescLayout = VK_NULL_HANDLE;
VkDescriptorSet MainAtlasDescriptor = VK_NULL_HANDLE;
/*
.binding = 2,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Карта освещения
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Воксельная карта освещения
.binding = 3,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Информация о размерах карты для приведения размеров
*/
VkDescriptorSetLayout LightMapDescLayout = VK_NULL_HANDLE;
VkDescriptorSetLayout VoxelLightMapDescLayout = VK_NULL_HANDLE;
VkDescriptorSet VoxelLightMapDescriptor = VK_NULL_HANDLE;
// Для отрисовки с использованием текстурного атласа и карты освещения
VkPipelineLayout MainAtlas_LightMap_PipelineLayout = VK_NULL_HANDLE;
@@ -146,6 +162,11 @@ public:
void beforeDraw();
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd);
private:
void updateDescriptor_MainAtlas();
void updateDescriptor_VoxelsLight();
void updateDescriptor_ChunksLight();
};
}

View File

@@ -9,55 +9,34 @@ namespace LV::Net {
using namespace TOS;
Server::~Server() {
stop();
wait();
bool SocketServer::isStopped() {
return !Acceptor.is_open();
}
bool Server::isStopped() {
return !IsAlive;
}
void Server::stop() {
NeedClose = true;
NeedClose.notify_all();
if(Acceptor.is_open())
Acceptor.close();
}
void Server::wait() {
while(bool val = IsAlive)
IsAlive.wait(val);
}
coro<void> Server::async_wait() {
co_await Lock.async_wait();
}
coro<void> Server::run() {
IsAlive.store(true);
try {
while(true) { // TODO: ловить ошибки на async_accept
co_spawn(OnConnect(co_await Acceptor.async_accept()));
coro<void> SocketServer::run(std::function<coro<>(tcp::socket)> onConnect) {
while(true) { // TODO: ловить ошибки на async_accept
try {
co_spawn(onConnect(co_await Acceptor.async_accept()));
} catch(const std::exception &exc) {
if(const boost::system::system_error *errc = dynamic_cast<const boost::system::system_error*>(&exc);
errc && (errc->code() == asio::error::operation_aborted || errc->code() == asio::error::bad_descriptor))
break;
}
} catch(const std::exception &exc) {
//if(!NeedClose)
// TODO: std::cout << exc.what() << std::endl;
}
Lock.cancel();
IsAlive.store(false);
IsAlive.notify_all();
}
AsyncSocket::~AsyncSocket() {
boost::lock_guard lock(SendPackets.Mtx);
if(SendPackets.Context)
SendPackets.Context->NeedShutdown = true;
boost::lock_guard lock(SendPackets.Mtx);
if(Socket.is_open())
try { Socket.close(); } catch(...) {}
SendPackets.SenderGuard.cancel();
WorkDeadline.cancel();
}
@@ -70,7 +49,7 @@ void AsyncSocket::pushPackets(std::vector<Packet> *simplePackets, std::vector<Sm
|| SendPackets.SmartBuffer.size() + (smartPackets ? smartPackets->size() : 0) >= MAX_SMART_PACKETS
|| SendPackets.SizeInQueue >= MAX_PACKETS_SIZE_IN_WAIT))
{
Socket.close();
try { Socket.close(); } catch(...) {}
// TODO: std::cout << "Передоз пакетами, сокет закрыт" << std::endl;
}
@@ -143,7 +122,7 @@ coro<> AsyncSocket::read(std::byte *data, uint32_t size) {
void AsyncSocket::closeRead() {
if(Socket.is_open() && !ReadShutdowned) {
ReadShutdowned = true;
Socket.shutdown(boost::asio::socket_base::shutdown_receive);
try { Socket.shutdown(boost::asio::socket_base::shutdown_receive); } catch(...) {}
}
}

View File

@@ -9,41 +9,30 @@
#include <boost/asio/write.hpp>
#include <boost/thread.hpp>
#include <boost/circular_buffer.hpp>
#include <condition_variable>
namespace LV::Net {
class Server : public AsyncObject {
class SocketServer : public AsyncObject {
protected:
std::atomic_bool IsAlive = false, NeedClose = false;
tcp::acceptor Acceptor;
asio::deadline_timer Lock;
std::function<coro<>(tcp::socket)> OnConnect;
public:
Server(asio::io_context &ioc, std::function<coro<>(tcp::socket)> &&onConnect, uint16_t port = 0)
: AsyncObject(ioc), Acceptor(ioc, tcp::endpoint(tcp::v4(), port)), Lock(ioc, boost::posix_time::pos_infin), OnConnect(std::move(onConnect))
SocketServer(asio::io_context &ioc, std::function<coro<>(tcp::socket)> &&onConnect, uint16_t port = 0)
: AsyncObject(ioc), Acceptor(ioc, tcp::endpoint(tcp::v4(), port))
{
assert(OnConnect);
assert(onConnect);
co_spawn(run());
IsAlive.store(true);
IsAlive.notify_all();
co_spawn(run(std::move(onConnect)));
}
~Server();
bool isStopped();
uint16_t getPort() {
return Acceptor.local_endpoint().port();
}
void stop();
void wait();
coro<void> async_wait();
protected:
coro<void> run();
coro<void> run(std::function<coro<>(tcp::socket)> onConnect);
};
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN

8
imgui.ini Normal file
View File

@@ -0,0 +1,8 @@
[Window][Debug##Default]
Pos=0,0
Size=400,400
[Window][MainMenu]
Pos=0,0
Size=960,540