From 28fede2dd4eb180b52ff15bfbb831a1ef82e2098 Mon Sep 17 00:00:00 2001 From: Lveyou <1339484752@qq.com> Date: Thu, 25 Jun 2026 18:11:42 +0800 Subject: [PATCH] =?UTF-8?q?*=20renderTarget=E5=9F=BA=E7=A1=80=E5=AE=8C?= =?UTF-8?q?=E6=88=90=EF=BC=8C=E6=8B=86=E5=88=862d=E5=92=8C3d=E6=B8=B2?= =?UTF-8?q?=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dl/render/dl_factory.cpp | 62 +++++++-- dl/render/dl_factory.h | 10 ++ dl/render/dl_factory_imp.h | 14 +- dl/render/dl_render_target.h | 31 +++++ dl/render/dl_sprite.h | 15 ++- dl/system/dl_system.cpp | 2 + dl/system/dl_system.h | 1 + dl/vk/dl_vk.cpp | 249 +++++++++++++++++++++++++---------- dl/vk/dl_vk.h | 28 ++-- 9 files changed, 309 insertions(+), 103 deletions(-) create mode 100644 dl/render/dl_render_target.h diff --git a/dl/render/dl_factory.cpp b/dl/render/dl_factory.cpp index 6db433a3..6bfc5a02 100644 --- a/dl/render/dl_factory.cpp +++ b/dl/render/dl_factory.cpp @@ -10,6 +10,8 @@ #include "system/dl_audio.h" #include "render/dl_render_def.h" #include "io/dl_input.h" +#include "system/dl_engine.h" +#include "system/dl_system.h" namespace dl { @@ -339,6 +341,31 @@ gcSprite Factory::CreateSprite(std::string_view name, size_t index /*= 0*/) return CreateSprite(GetSpriteId(name, index)); } +dl::gcSprite Factory::CreateSprite(size_t rt_id) +{ + auto spr = get_gc(); + + spr->_id._tex = rt_id; + spr->_id._rect = (size_t)-1; + spr->_bRenderTarget = true; + spr->_quad = createQuad(g_system->GetWindowSize(), false); + spr->_order = Z_DEFAULT_RENDER_TARGET; + + for (int i = 0; i != 4; ++i) + { + spr->_col[i] = ColorDef::WHITE; + } + spr->_uv[0] = { 0.0f, 0.0f }; + spr->_uv[1] = { 1.0f, 0.0f }; + spr->_uv[2] = { 1.0f, 1.0f }; + spr->_uv[3] = { 0.0f, 1.0f }; + +#ifndef NDEBUG + spr->_name = fmt::format("RenderTarget: {}", rt_id); +#endif + return spr; +} + bool Factory::RegisterSprite(std::string_view name, size_t index, Image* img, const Position& anchor) { if (!img) @@ -839,19 +866,18 @@ std::optional Factory::GetColorCheck(std::string_view name) void Factory::ExportTexture2D() { - for(size_t i = 0; i < g_vk->GetCanvasSize(); ++i) - { - VK::Canvas* canvas = g_vk->GetCanvas(i); - std::string str = fmt::format("{}{}.png", _strPathTemp, i); - g_vk->ExportTexture(canvas->_texture, str); - } + g_vk->ExportTextureCanvas(_strPathTemp); } void Factory::_render_sprite(Sprite* spr) { const SpriteID& id = g_factory->GetImp()->_idTrans; - VK::Canvas* canvas = g_vk->GetCanvas(spr->_id._tex); + VK::Canvas* canvas = nullptr; + if (!spr->_bRenderTarget) + canvas = g_vk->GetCanvasByTexture(spr->_id._tex); + else + canvas = g_vk->GetCanvasByRenderTarget(spr->_id._tex); assert(canvas); if (spr->_id._rect == -1 @@ -943,6 +969,17 @@ void Factory::_clear_render() _vecAnimation.clear(); } +void Factory::_render_rt() +{ + if(Engine::GetParamRef()._show3D) + _sprRenderTarget0->Render(); +} + +void Factory::_resize() +{ + _sprRenderTarget0->SetQuad(createQuad(g_system->GetWindowSize(), false)); +} + void Factory::_init_path() { if (!_bSetPath) @@ -977,9 +1014,10 @@ void Factory::_init_path() void Factory::_init_defualt_res() { // 先使用一下,保证gcSprite后于gcText析构 - gcSprite spr = CreateSpriteDefault(); - spr->SetColor(ColorDef::RED); + //gcSprite spr = CreateSpriteDefault(); + //spr->SetColor(ColorDef::RED); + _sprRenderTarget0 = CreateSprite(0); // 默认颜色 AddColor("red", ColorDef::RED); @@ -1172,14 +1210,14 @@ bool FactoryImp::_reg_image(Image* image_src, unsigned border, size_t& id_tex, s size_big >>= 1; assert(size_big); } - g_vk->CreateCanvas(id_tex, vec_image); + g_vk->CreateCanvasImage(id_tex, vec_image); for (size_t i = 0; i < vec_image.size(); ++i) { delete vec_image[i]; } } - Texture tex = g_vk->GetCanvas(id_tex)->_texture; + Texture tex = g_vk->GetCanvasByTexture(id_tex)->_texture; g_vk->UpdateTexture2D(tex, Align::GetLT(rect), image, createRectU(image->GetSize())); @@ -1309,7 +1347,7 @@ void Factory::_load_sprite_binary() map_tex_id[name][i] = _imp->_numTexStatic; log_msg("创建显存2d纹理:{},{}", _imp->_numTexStatic, path_out); //创建纹理资源(创建Canvas,并创建纹理) - g_vk->CreateCanvas(_imp->_numTexStatic++, vec_image); + g_vk->CreateCanvasImage(_imp->_numTexStatic++, vec_image); } for (size_t j = 0; j < vec_image.size(); ++j) { diff --git a/dl/render/dl_factory.h b/dl/render/dl_factory.h index 3cab46a1..6215dd9e 100644 --- a/dl/render/dl_factory.h +++ b/dl/render/dl_factory.h @@ -217,6 +217,11 @@ public: std::string_view name, std::size_t index = 0); /** + * @brief 创建一个精灵 + * @param[in] rt_id RenderTarget的id + */ + gcSprite CreateSprite(size_t rt_id); + /** * @brief 创建一个精灵,随机选中下标 * @param[in] name 名字,例如“ui.btn0” */ @@ -494,10 +499,15 @@ private: std::vector _vecSprite; std::vector _vecText; std::vector _vecAnimation; + // 默认RenderTarget精灵 + gcSprite _sprRenderTarget0; void _auto_render(); void _clear_render(); + void _render_rt(); + void _resize(); + //init之前会调用一次 void _init_path(); void _init_defualt_res();//初始化默认资源 diff --git a/dl/render/dl_factory_imp.h b/dl/render/dl_factory_imp.h index 5252a142..cc906138 100644 --- a/dl/render/dl_factory_imp.h +++ b/dl/render/dl_factory_imp.h @@ -57,12 +57,12 @@ public: }; //精灵信息(创建一个精灵必要的信息,通过SpriteID获得) struct SpriteInfo - { - RectU _rect;//在大图区域 - UV _uv[4];//计算出的uv - Color _color;//默认颜色 - Position _anchor;//锚点 - bool _bRightAngle;//是否顺时针旋转过(只影响uv) + { + RectU _rect; // 在大图区域 + UV _uv[4]; // 计算出的uv + Color _color; // 默认颜色 + Position _anchor; // 锚点 + bool _bRightAngle; // 是否顺时针旋转过(只影响uv) }; // 一个图片路径生成的所有精灵信息 struct SpriteGroup @@ -80,7 +80,7 @@ public: SpriteID _idTrans;// 半透明图像注册起始 id SpriteID _idSolid;// 纯色 id SpriteID _idSolidTrans;// 半透明纯色 id - std::size_t _numTexStatic;// 静态纹理数量 + size_t _numTexStatic;// 静态纹理数量 // 计算uv void _rect_to_uv(const RectU& rect, UV* uv, bool right_angle = false); diff --git a/dl/render/dl_render_target.h b/dl/render/dl_render_target.h new file mode 100644 index 00000000..9b521b7d --- /dev/null +++ b/dl/render/dl_render_target.h @@ -0,0 +1,31 @@ +/** +* @file dl_render_target.h +* @brief 渲染目标 绘制到纹理(3d) +* +* +* @version 1.0 +* @author lveyou +* @date 26-06-25 +* +* @note 0为3d渲染默认绘制目标,可自行创建更多 +*/ +#pragma once + +#include "dl_type.h" + +namespace dl +{ + +//! 渲染目标 +class RenderTarget +{ + friend class Factory; + + size_t GetId() { return _id; } +private: + RenderTarget() :_id{ -1 } {} + + size_t _id; +}; + +} diff --git a/dl/render/dl_sprite.h b/dl/render/dl_sprite.h index 5207ccd8..4b346d80 100644 --- a/dl/render/dl_sprite.h +++ b/dl/render/dl_sprite.h @@ -31,7 +31,9 @@ constexpr float Z_DEFAULT_UI = 0.6f; // ui系统使用 constexpr float Z_DEFAULT_PANEL = 0.7f; // 背景 -constexpr float Z_DEFAULT_BG = 0.99f; +constexpr float Z_DEFAULT_BG = 0.98f; +// RenderTarget +constexpr float Z_DEFAULT_RENDER_TARGET = 0.99f; constexpr Float LENGTH_NORMAL = 32.0f; @@ -44,8 +46,8 @@ using UV = Array; //! 精灵id struct SpriteID { - std::size_t _tex; //!< 纹理下标 - std::size_t _rect;//!< 区域下标 + std::size_t _tex; //!< 纹理下标 或 RenderTarget下标(由_bRenderTarget控制) + std::size_t _rect; //!< 区域下标 SpriteID() : _tex{}, _rect{} @@ -238,6 +240,7 @@ private: _blend{ 0 }, _bright{ 1.0f }, _ui(false), + _bRenderTarget{ false }, _bOwnCoor{ false }, _bRoundPixel{ true }, _bRender{} @@ -254,14 +257,14 @@ private: unsigned _sampler; unsigned _blend; float _bright; // 亮度 + float _order;// 与z等价 //id - SpriteID _id;// 1为纹理区域,可以为-1代表失效(手动指定uv的情况) + SpriteID _id;// _rect为纹理区域,-1代表失效(手动指定uv的情况) - float _order;// 与z等价 + bool _bRenderTarget; bool _ui;// 影响isPickup,防止穿透 bool _bOwnCoor;// 拥有coor,为真时析构会delete coor - bool _bRoundPixel;// 像素取整 // -------------------------temp 不复制的属性---------------------- diff --git a/dl/system/dl_system.cpp b/dl/system/dl_system.cpp index 5a918e38..38db5eb5 100644 --- a/dl/system/dl_system.cpp +++ b/dl/system/dl_system.cpp @@ -181,6 +181,7 @@ void System::Start(const ParamWindow& param) g_scene->_update(); if (_funcRun) _funcRun();//帧函数 + g_factory->_render_rt(); if (_lua._funcRun) g_lua->ExcuteFunction(_lua._funcRun); @@ -607,6 +608,7 @@ void System::_resize() if (g_vk) g_vk->SetFrameBufferResize(); g_ui->_resize(); + g_factory->_resize(); } diff --git a/dl/system/dl_system.h b/dl/system/dl_system.h index a86fb8b2..1f0e5bb4 100644 --- a/dl/system/dl_system.h +++ b/dl/system/dl_system.h @@ -198,6 +198,7 @@ public: //! 返回引擎运行状态 SystemStep GetStep() { return _step; } + //! 硬件码(md5 长度32) std::string GetHardwareId(); diff --git a/dl/vk/dl_vk.cpp b/dl/vk/dl_vk.cpp index ed4a93d2..1ce4721e 100644 --- a/dl/vk/dl_vk.cpp +++ b/dl/vk/dl_vk.cpp @@ -23,6 +23,8 @@ constexpr uint32_t BINDING_INDEX_IBL = 4; constexpr uint32_t BINDING_INDEX_BRDF = 5; constexpr uint32_t BINDING_INDEX_SHADOW = 6; +constexpr size_t CANVAS_ID_RENDER_TARGET_MAX = 16; + void VK::_init(GLFWwindow* window) { _curPushConstant = 0; @@ -105,6 +107,7 @@ void VK::_init(GLFWwindow* window) _create_pipeline_all(); size_t i = CreateRenderTarget(); + assert(i == 0); } void VK::_check_extension() @@ -1775,6 +1778,11 @@ void VK::_rebuild_swap_chain(GLFWwindow* window) vkDeviceWaitIdle(_device); _release_swap_chain(); + for (auto& iter : _allRenderTarget) + { + iter.Delete(_device); + } + #if DL_PLATFORM == DL_PLATFORM_ANDROID // 安卓需要重建surface,其他平台待观察 _create_surface(window); @@ -1784,6 +1792,12 @@ void VK::_rebuild_swap_chain(GLFWwindow* window) _create_color_resources(); _create_depth_resources(); _create_frame_buffer(); + + for (size_t i = 0; i < _allRenderTarget.size(); ++i) + { + CreateRenderTargetReal(i, _allRenderTarget[i]); + UpdateCanvasRenderTarget(i, _allRenderTarget[i]); + } } @@ -3758,8 +3772,8 @@ void VK::_delete_2d() vkDestroySampler(_device, _2d._textureSampler, nullptr); for (auto& iter : _2d._allCanvas) { - iter->Delete(_device); - delete iter; + iter.second->Delete(_device); + delete iter.second; } //索引缓冲 vkDestroyBuffer(_device, _2d._indexBuffer, nullptr); @@ -5322,6 +5336,15 @@ void VK::ExportTexture(Texture tex, std::string_view path_name) vkDestroyImage(_device, dst_image, nullptr); } +void VK::ExportTextureCanvas(std::string_view path) +{ + for (auto& iter : _2d._allCanvas) + { + std::string str = fmt::format("{}{}.png", path, iter.first); + ExportTexture(iter.second->_texture, str); + } +} + void VK::GenerateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels) { //检查线性过滤 可用 @@ -5440,6 +5463,66 @@ void VK::_create_color_resources() _colorImageView = CreateImageView(_colorImage, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); } +bool VK::CreateRenderTargetReal(size_t i, VKRenderTarget& rt) +{ + { + VkFormat colorFormat = _formatSwapChainImage; + CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, _param._msaaLevel, colorFormat, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texColor._image, rt._texColor._memory); + rt._texColor._imageView = CreateImageView(rt._texColor._image, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); + } + { + VkFormat depthFormat = FindDepthFormat(); + CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, _param._msaaLevel, + depthFormat, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texDepth._image, rt._texDepth._memory); + rt._texDepth._imageView = CreateImageView(rt._texDepth._image, depthFormat, + VK_IMAGE_ASPECT_DEPTH_BIT, 1); + + TransitionImageLayout(rt._texDepth._image, depthFormat, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + 1); + } + { + VkFormat colorFormat = _formatSwapChainImage; + CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, VK_SAMPLE_COUNT_1_BIT, colorFormat, + VK_IMAGE_TILING_OPTIMAL, + // translate标记不可写入到显存,sampled表示可以被后续作为shader资源 + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | // 导出纹理使用 + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texColorOut._image, rt._texColorOut._memory); + rt._texColorOut._imageView = CreateImageView(rt._texColorOut._image, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); + rt._texColorOut._width = _extentSwapChain.width; + rt._texColorOut._height = _extentSwapChain.height; + } + { + std::array attachments = { + rt._texColor._imageView, + rt._texDepth._imageView, + rt._texColorOut._imageView + }; + + VkFramebufferCreateInfo framebufferInfo{}; + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebufferInfo.renderPass = _renderPass3D; // 渲染流程 + framebufferInfo.attachmentCount = static_cast(attachments.size()); + framebufferInfo.pAttachments = attachments.data(); + framebufferInfo.width = _extentSwapChain.width; + framebufferInfo.height = _extentSwapChain.height; + framebufferInfo.layers = 1; + + if (vkCreateFramebuffer(_device, &framebufferInfo, nullptr, &rt._frameBuffer) != VK_SUCCESS) + { + log_damage0("创建帧缓冲区(RenderTarget)失败!"); + return false; + } + } + return true; +} + VkSampleCountFlagBits VK::GetMaxUsableSampleCount() { VkPhysicalDeviceProperties physicalDeviceProperties; @@ -5559,66 +5642,16 @@ void VK::SetSkybox(size_t i) size_t VK::CreateRenderTarget() { size_t i = _allRenderTarget.size(); + if (i >= CANVAS_ID_RENDER_TARGET_MAX) + { + log_err("RenderTarget数量超过上限:{}/{}", i, CANVAS_ID_RENDER_TARGET_MAX); + return -1; + } VKRenderTarget rt; - { - VkFormat colorFormat = _formatSwapChainImage; - CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, _param._msaaLevel, colorFormat, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texColor._image, rt._texColor._memory); - rt._texColor._imageView = CreateImageView(rt._texColor._image, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); - } - { - VkFormat depthFormat = FindDepthFormat(); - CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, _param._msaaLevel, - depthFormat, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texDepth._image, rt._texDepth._memory); - rt._texDepth._imageView = CreateImageView(rt._texDepth._image, depthFormat, - VK_IMAGE_ASPECT_DEPTH_BIT, 1); + CreateRenderTargetReal(i, rt); + CreateCanvasRenderTarget(i, rt); - TransitionImageLayout(rt._texDepth._image, depthFormat, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - 1); - } - { - VkFormat colorFormat = _formatSwapChainImage; - CreateImage(_extentSwapChain.width, _extentSwapChain.height, 1, VK_SAMPLE_COUNT_1_BIT, colorFormat, - VK_IMAGE_TILING_OPTIMAL, - // translate标记不可写入到显存,sampled表示可以被后续作为shader资源 - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, rt._texColorOut._image, rt._texColorOut._memory); - rt._texColorOut._imageView = CreateImageView(rt._texColorOut._image, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); - - // ai说法待验证 TransitionImageLayout 不需要,可在RenderPass处理 - // -> shader可访问 - /*TransitionImageLayout(rt._texColorOut._image, colorFormat, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - 1);*/ - } - { - std::array attachments = { - rt._texColor._imageView, - rt._texDepth._imageView, - rt._texColorOut._imageView - }; - - VkFramebufferCreateInfo framebufferInfo{}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = _renderPass3D; // 渲染流程 - framebufferInfo.attachmentCount = static_cast(attachments.size()); - framebufferInfo.pAttachments = attachments.data(); - framebufferInfo.width = _extentSwapChain.width; - framebufferInfo.height = _extentSwapChain.height; - framebufferInfo.layers = 1; - - if (vkCreateFramebuffer(_device, &framebufferInfo, nullptr, &rt._frameBuffer) != VK_SUCCESS) - { - log_damage0("创建帧缓冲区(RenderTarget)失败!"); - return -1; - } - } _allRenderTarget.push_back(rt); return i; } @@ -5729,21 +5762,27 @@ size_t VK::CreateTexture(std::string_view path_name, bool srgb) return ret; } -void VK::CreateCanvas(size_t id, const std::array& vec_image) +void VK::CreateCanvas(int id, Texture tex) { - assert(id == _2d._allCanvas.size()); + auto iter = _2d._allCanvas.find(id); + if (iter != _2d._allCanvas.end()) + { + log_damage("Canvas已存在:{}", id); + return; + } + Canvas* canvas = new Canvas(this); canvas->_id = id; - canvas->_texture = CreateTexture2D(vec_image); + canvas->_texture = tex; for (size_t i = 0; i < _countFrame; ++i) { canvas->_numVertex[i] = NUM_START_2D_VERTEX; CreateVertexBufferCPU(canvas->_numVertex[i], canvas->_vertexBuffer[i], canvas->_vertexBufferMemory[i], canvas->_vertexBufferSize[i]); } - - _2d._allCanvas.push_back(canvas); + + _2d._allCanvas[id] = canvas; //填充描述符 for (size_t i = 0; i < _countFrame; ++i) @@ -5783,6 +5822,79 @@ void VK::CreateCanvas(size_t id, const std::array& vec_im } } +void VK::CreateCanvasImage(size_t tex_id, const std::array& vec_image) +{ + CreateCanvas(CANVAS_ID_RENDER_TARGET_MAX + tex_id, CreateTexture2D(vec_image)); +} + +void VK::CreateCanvasRenderTarget(size_t rt_id, VKRenderTarget& rt) +{ + CreateCanvas(rt_id, rt._texColorOut); +} + +void VK::UpdateCanvasRenderTarget(size_t rt_id, VKRenderTarget& rt) +{ + Canvas* canvas = GetCanvas(rt_id); + assert(canvas); + canvas->_texture = rt._texColorOut; + + //填充描述符 + size_t id = rt_id; + for (size_t i = 0; i < _countFrame; ++i) + { + size_t index = id * _countFrame + i; + // ubo + VkDescriptorBufferInfo bufferInfo{}; + bufferInfo.buffer = _2d._uniformBuffers[i]; + bufferInfo.offset = 0; + bufferInfo.range = sizeof(VK2D::UBO); + // 纹理 + VkDescriptorImageInfo imageInfo{}; + imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageInfo.imageView = canvas->_texture._imageView; + imageInfo.sampler = _2d._textureSampler; + + std::array descriptorWrites{}; + descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[0].dstSet = _2d._descriptorSets[index]; + descriptorWrites[0].dstBinding = 0; + descriptorWrites[0].dstArrayElement = 0; + descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorWrites[0].descriptorCount = 1; + descriptorWrites[0].pBufferInfo = &bufferInfo; + + descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[1].dstSet = _2d._descriptorSets[index]; + descriptorWrites[1].dstBinding = 1; + descriptorWrites[1].dstArrayElement = 0; + descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrites[1].descriptorCount = 1; + descriptorWrites[1].pImageInfo = &imageInfo; + + vkUpdateDescriptorSets(_device, + (uint32_t)descriptorWrites.size(), descriptorWrites.data(), + 0, nullptr); + } +} + +VK::Canvas* VK::GetCanvas(int id) +{ + auto iter = _2d._allCanvas.find(id); + if (iter == _2d._allCanvas.end()) + return nullptr; + return iter->second; +} + +dl::VK::Canvas* VK::GetCanvasByTexture(size_t tex_id) +{ + return GetCanvas(CANVAS_ID_RENDER_TARGET_MAX + tex_id); +} + +dl::VK::Canvas* VK::GetCanvasByRenderTarget(size_t rt_id) +{ + return GetCanvas(rt_id); +} + Texture VK::CreateTexture2D(const std::array& vec_image) { for(auto& iter : vec_image) @@ -6132,13 +6244,14 @@ void VK::Update() _2d._vecDc.clear(); _2d._vecDcTrans.clear(); - //画布逻辑,更新顶点和cbo - //半透明需要排序,后面生成dc + // 画布逻辑,更新顶点和cbo + // 半透明需要排序,后面生成dc - //生成dc,并按z排序 + // 生成dc,并按z排序 std::multimap map_dc_translucent; - for (Canvas*& canvas : _2d._allCanvas) + for (auto& iter : _2d._allCanvas) { + Canvas*& canvas = iter.second; if (canvas->_allSprite.size() > NUM_MAX_2D_SPRITE) { log_warn("精灵数超过上限:{}", NUM_MAX_2D_SPRITE); diff --git a/dl/vk/dl_vk.h b/dl/vk/dl_vk.h index 3a7d3472..73fc2ca5 100644 --- a/dl/vk/dl_vk.h +++ b/dl/vk/dl_vk.h @@ -337,7 +337,7 @@ public: size_t _curPushConstant; // 当前使用 常量缓冲 下标 std::array _allRootCoor; // 所有根坐标系 Matrix4 _mat2D; // 2d世界坐标系 - std::vector _allCanvas; // 所有画布 + std::unordered_map _allCanvas; // 画布(RenderTarget + 静态 + Register精灵) RenderInfo2D _renderInfo; // 绘制信息 //------------------------缓存区域(避免每帧重分配内存)----------------------- std::vector _vecDc; @@ -438,7 +438,7 @@ public: { Texture _texColor; Texture _texDepth; - Texture _texColorOut; + Texture _texColorOut; // 由Canvas释放 VkFramebuffer _frameBuffer; void Delete(VkDevice device) @@ -446,7 +446,7 @@ public: vkDestroyFramebuffer(device, _frameBuffer, nullptr); _texColor.Delete(device); _texDepth.Delete(device); - _texColorOut.Delete(device); + //_texColorOut.Delete(device); } }; @@ -802,14 +802,15 @@ public: //! 创建Canvas(2d管线资源) - void CreateCanvas(size_t id, const std::array& vec_image); + void CreateCanvas(int id, Texture tex); + void CreateCanvasImage(size_t tex_id, const std::array& vec_image); + void CreateCanvasRenderTarget(size_t rt_id, VKRenderTarget& rt); - Canvas* GetCanvas(size_t id) - { - if (id >= _2d._allCanvas.size()) - return nullptr; - return _2d._allCanvas[id]; - } + void UpdateCanvasRenderTarget(size_t rt_id, VKRenderTarget& rt); + + Canvas* GetCanvas(int id); + Canvas* GetCanvasByTexture(size_t tex_id); + Canvas* GetCanvasByRenderTarget(size_t rt_id); size_t GetCanvasSize() { @@ -830,6 +831,8 @@ public: //!导出图像 void ExportTexture(Texture tex, std::string_view path_name); + void ExportTextureCanvas(std::string_view path); + //! 生成mipmap void GenerateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels); @@ -841,6 +844,9 @@ public: //! 设置当前天空盒 void SetSkybox(size_t i); + + // + bool CreateRenderTargetReal(size_t i, VKRenderTarget& rt); size_t CreateRenderTarget(); //! 返回绘制信息 @@ -1146,6 +1152,8 @@ private: void _create_depth_resources(); // 创建msaa资源 void _create_color_resources(); + + //2d管线 void _create_2d(); void _delete_2d();