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

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 /.cache
/.vscode /.vscode
/build /build
/Work/*
/CMakeFiles /CMakeFiles
/CMakeCache.txt /CMakeCache.txt

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections") 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 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") # -rdynamic
project (LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description") project (LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description")
@@ -59,10 +60,10 @@ target_link_libraries(${PROJECT_NAME} PUBLIC TOS_Lib)
# Static Assets # 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} 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_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) 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) 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 += deltaPYR;
PYR_Offset = deltaPYR+deltaTime*PYR_Offset; 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) { void ServerSession::onCursorBtn(ISurfaceEventListener::EnumCursorBtn btn, bool state) {
@@ -197,6 +195,19 @@ void ServerSession::onJoystick() {
void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) { void ServerSession::atFreeDrawTime(GlobalTime gTime, float dTime) {
GTime = gTime; 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() { coro<> ServerSession::run() {

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,7 @@
#include "VulkanRenderSession.hpp" #include "VulkanRenderSession.hpp"
#include "Client/Vulkan/Vulkan.hpp"
#include "assets.hpp"
#include <glm/ext/matrix_transform.hpp>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
namespace LV::Client::VK { namespace LV::Client::VK {
@@ -29,8 +32,11 @@ void VulkanRenderSession::free(Vulkan *instance) {
if(MainAtlasDescLayout) if(MainAtlasDescLayout)
vkDestroyDescriptorSetLayout(instance->Graphics.Device, MainAtlasDescLayout, nullptr); vkDestroyDescriptorSetLayout(instance->Graphics.Device, MainAtlasDescLayout, nullptr);
if(LightMapDescLayout) if(VoxelLightMapDescLayout)
vkDestroyDescriptorSetLayout(instance->Graphics.Device, LightMapDescLayout, nullptr); vkDestroyDescriptorSetLayout(instance->Graphics.Device, VoxelLightMapDescLayout, nullptr);
if(DescriptorPool)
vkDestroyDescriptorPool(instance->Graphics.Device, DescriptorPool, nullptr);
} }
VoxelOpaquePipeline = VK_NULL_HANDLE; VoxelOpaquePipeline = VK_NULL_HANDLE;
@@ -41,7 +47,13 @@ void VulkanRenderSession::free(Vulkan *instance) {
MainAtlas_LightMap_PipelineLayout = VK_NULL_HANDLE; MainAtlas_LightMap_PipelineLayout = VK_NULL_HANDLE;
MainAtlasDescLayout = 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) { 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) { if(!MainAtlasDescLayout) {
std::vector<VkDescriptorSetLayoutBinding> shaderLayoutBindings = std::vector<VkDescriptorSetLayoutBinding> shaderLayoutBindings =
{ {
@@ -81,7 +110,20 @@ void VulkanRenderSession::init(Vulkan *instance) {
instance->Graphics.Device, &descriptorLayout, nullptr, &MainAtlasDescLayout)); 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 = std::vector<VkDescriptorSetLayoutBinding> shaderLayoutBindings =
{ {
{ {
@@ -108,9 +150,21 @@ void VulkanRenderSession::init(Vulkan *instance) {
.pBindings = shaderLayoutBindings.data() .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 = 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) { if(!MainAtlas_LightMap_PipelineLayout) {
std::vector<VkDescriptorSetLayout> layouts = std::vector<VkDescriptorSetLayout> layouts =
{ {
MainAtlasDescLayout, MainAtlasDescLayout,
LightMapDescLayout VoxelLightMapDescLayout
}; };
const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
@@ -168,16 +249,16 @@ void VulkanRenderSession::init(Vulkan *instance) {
{ {
// Для статичных непрозрачных и полупрозрачных вокселей // Для статичных непрозрачных и полупрозрачных вокселей
if(!VoxelShaderVertex) if(!VoxelShaderVertex)
VoxelShaderVertex = VkInst->createShaderFromFile("assets/shaders/chunk/voxel.vert.bin"); VoxelShaderVertex = VkInst->createShader(getResource("shaders/chunk/voxel.vert.bin")->makeView());
if(!VoxelShaderGeometry) if(!VoxelShaderGeometry)
VoxelShaderGeometry = VkInst->createShaderFromFile("assets/shaders/chunk/voxel.geom.bin"); VoxelShaderGeometry = VkInst->createShader(getResource("shaders/chunk/voxel.geom.bin")->makeView());
if(!VoxelShaderFragmentOpaque) 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) 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 = std::vector<VkPipelineShaderStageCreateInfo> shaderStages =
@@ -404,16 +485,16 @@ void VulkanRenderSession::init(Vulkan *instance) {
// Для статичных непрозрачных и полупрозрачных нод // Для статичных непрозрачных и полупрозрачных нод
if(!NodeShaderVertex) if(!NodeShaderVertex)
NodeShaderVertex = VkInst->createShaderFromFile("assets/shaders/chunk/node.vert.bin"); NodeShaderVertex = VkInst->createShader(getResource("shaders/chunk/node.vert.bin")->makeView());
if(!NodeShaderGeometry) if(!NodeShaderGeometry)
NodeShaderGeometry = VkInst->createShaderFromFile("assets/shaders/chunk/node.geom.bin"); NodeShaderGeometry = VkInst->createShader(getResource("shaders/chunk/node.geom.bin")->makeView());
if(!NodeShaderFragmentOpaque) 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) 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, ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
@@ -510,6 +591,85 @@ void VulkanRenderSession::beforeDraw() {
} }
void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd) { 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 "Common/Abstract.hpp"
#include <Client/Vulkan/Vulkan.hpp> #include <Client/Vulkan/Vulkan.hpp>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
#include <vulkan/vulkan_core.h>
/* /*
У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур
@@ -52,7 +53,6 @@ struct VoxelVertexPoint {
}; };
/* /*
Из-за карт освещения индексов не будет
Максимальный размер меша 14^3 м от центра ноды Максимальный размер меша 14^3 м от центра ноды
Координатное пространство то же, что и у вокселей + 8 позиций с двух сторон Координатное пространство то же, что и у вокселей + 8 позиций с двух сторон
Рисуется полигонами Рисуется полигонами
@@ -78,6 +78,20 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
Pos::Object Pos; Pos::Object Pos;
glm::quat Quat; 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, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Текстурный атлас .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Текстурный атлас
@@ -85,13 +99,15 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Данные к атласу .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Данные к атласу
*/ */
VkDescriptorSetLayout MainAtlasDescLayout = VK_NULL_HANDLE; VkDescriptorSetLayout MainAtlasDescLayout = VK_NULL_HANDLE;
VkDescriptorSet MainAtlasDescriptor = VK_NULL_HANDLE;
/* /*
.binding = 2, .binding = 2,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Карта освещения .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Воксельная карта освещения
.binding = 3, .binding = 3,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Информация о размерах карты для приведения размеров .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; VkPipelineLayout MainAtlas_LightMap_PipelineLayout = VK_NULL_HANDLE;
@@ -146,6 +162,11 @@ public:
void beforeDraw(); void beforeDraw();
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd); 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; using namespace TOS;
Server::~Server() { bool SocketServer::isStopped() {
stop(); return !Acceptor.is_open();
wait();
} }
bool Server::isStopped() {
return !IsAlive;
}
void Server::stop() { coro<void> SocketServer::run(std::function<coro<>(tcp::socket)> onConnect) {
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 while(true) { // TODO: ловить ошибки на async_accept
co_spawn(OnConnect(co_await Acceptor.async_accept())); try {
} co_spawn(onConnect(co_await Acceptor.async_accept()));
} catch(const std::exception &exc) { } catch(const std::exception &exc) {
//if(!NeedClose) if(const boost::system::system_error *errc = dynamic_cast<const boost::system::system_error*>(&exc);
// TODO: std::cout << exc.what() << std::endl; errc && (errc->code() == asio::error::operation_aborted || errc->code() == asio::error::bad_descriptor))
break;
}
} }
Lock.cancel();
IsAlive.store(false);
IsAlive.notify_all();
} }
AsyncSocket::~AsyncSocket() { AsyncSocket::~AsyncSocket() {
boost::lock_guard lock(SendPackets.Mtx);
if(SendPackets.Context) if(SendPackets.Context)
SendPackets.Context->NeedShutdown = true; SendPackets.Context->NeedShutdown = true;
boost::lock_guard lock(SendPackets.Mtx);
if(Socket.is_open())
try { Socket.close(); } catch(...) {}
SendPackets.SenderGuard.cancel(); SendPackets.SenderGuard.cancel();
WorkDeadline.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.SmartBuffer.size() + (smartPackets ? smartPackets->size() : 0) >= MAX_SMART_PACKETS
|| SendPackets.SizeInQueue >= MAX_PACKETS_SIZE_IN_WAIT)) || SendPackets.SizeInQueue >= MAX_PACKETS_SIZE_IN_WAIT))
{ {
Socket.close(); try { Socket.close(); } catch(...) {}
// TODO: std::cout << "Передоз пакетами, сокет закрыт" << std::endl; // TODO: std::cout << "Передоз пакетами, сокет закрыт" << std::endl;
} }
@@ -143,7 +122,7 @@ coro<> AsyncSocket::read(std::byte *data, uint32_t size) {
void AsyncSocket::closeRead() { void AsyncSocket::closeRead() {
if(Socket.is_open() && !ReadShutdowned) { if(Socket.is_open() && !ReadShutdowned) {
ReadShutdowned = true; 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/asio/write.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/circular_buffer.hpp> #include <boost/circular_buffer.hpp>
#include <condition_variable>
namespace LV::Net { namespace LV::Net {
class Server : public AsyncObject { class SocketServer : public AsyncObject {
protected: protected:
std::atomic_bool IsAlive = false, NeedClose = false;
tcp::acceptor Acceptor; tcp::acceptor Acceptor;
asio::deadline_timer Lock;
std::function<coro<>(tcp::socket)> OnConnect;
public: public:
Server(asio::io_context &ioc, std::function<coro<>(tcp::socket)> &&onConnect, uint16_t port = 0) SocketServer(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)) : AsyncObject(ioc), Acceptor(ioc, tcp::endpoint(tcp::v4(), port))
{ {
assert(OnConnect); assert(onConnect);
co_spawn(run()); co_spawn(run(std::move(onConnect)));
IsAlive.store(true);
IsAlive.notify_all();
} }
~Server();
bool isStopped(); bool isStopped();
uint16_t getPort() { uint16_t getPort() {
return Acceptor.local_endpoint().port(); return Acceptor.local_endpoint().port();
} }
void stop();
void wait();
coro<void> async_wait();
protected: protected:
coro<void> run(); coro<void> run(std::function<coro<>(tcp::socket)> onConnect);
}; };
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN #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