diff --git a/CMSceneGraph b/CMSceneGraph index 57a35560..02ede84e 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 57a355602415294de7bcfdca9bd935db5b484388 +Subproject commit 02ede84ecd6e25cd705503018a53444bfda5af39 diff --git a/example/Vulkan/DrawTile.cpp b/example/Vulkan/DrawTile.cpp index 9fca958b..c2a1c2f5 100644 --- a/example/Vulkan/DrawTile.cpp +++ b/example/Vulkan/DrawTile.cpp @@ -114,9 +114,11 @@ private: float left =0; float top =0; + tile_data->BeginCommit(); + for(int i=0;ito=tile_data->Add((*tb)->bmp); //添加一个tile图片 + (*tb)->to=tile_data->Commit((*tb)->bmp); //添加一个tile图片 vp=WriteRect(vp,left+BORDER, //产生绘制顶点信息 top +BORDER, @@ -141,6 +143,8 @@ private: ++tb; } + tile_data->EndCommit(); + return(true); } @@ -202,7 +206,7 @@ private: AutoDelete pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); pipeline_creater->CloseCullFace(); - pipeline_creater->Set(PRIM_2D_RECTANGLES); + pipeline_creater->Set(PRIM_RECTANGLES); pipeline=pipeline_creater->Create(); diff --git a/inc/hgl/graph/TileData.h b/inc/hgl/graph/TileData.h index 6bfb66e9..0a59e529 100644 --- a/inc/hgl/graph/TileData.h +++ b/inc/hgl/graph/TileData.h @@ -16,7 +16,7 @@ namespace hgl { int col,row; //当前tile在整个纹理中的tile位置 - RectScope2d uv_pixel; //以象素为单位的tile位置和尺寸 + RectScope2i uv_pixel; //以象素为单位的tile位置和尺寸 RectScope2d uv_float; //以浮点为单位的tile位置和尺寸 };//struct TileObject @@ -30,20 +30,26 @@ namespace hgl protected: - vulkan::Buffer *tile_buffer; /// to_pool; /// commit_list; + uint commit_offset; + uint8 *commit_ptr; + + bool CommitTile(TileObject *,const void *,const uint,const int,const int); ///<提交一个Tile数据 public: @@ -60,11 +66,15 @@ namespace hgl TileData(Device *,Texture2D *,const uint tw,const uint th); virtual ~TileData(); - TileObject *Add(const void *,const uint,const int=-1,const int=-1); ///<增加一个Tile - TileObject *Add(BitmapData *bmp){return this->Add(bmp->data,bmp->total_bytes,bmp->width,bmp->height);} ///<增加一个Tile + void BeginCommit(); + + TileObject *Commit(const void *,const uint,const int=-1,const int=-1); ///<提交一个Tile + TileObject *Commit(BitmapData *bmp){return this->Commit(bmp->data,bmp->total_bytes,bmp->width,bmp->height);}///<提交一个Tile + bool Change(TileObject *,const void *,const uint,const int=-1,const int=-1); ///<更改一个Tile的数据内容 + + int EndCommit(); bool Delete(TileObject *); ///<删除一个Tile - bool Change(TileObject *,const void *,const uint,const int=-1,const int=-1); ///<更改一个Tile的数据内容 void Clear(); ///<清除Tile数据 };//class TileData }//namespace graph diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h index 9657e445..633877c2 100644 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ b/inc/hgl/graph/vulkan/VKDevice.h @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -179,9 +181,35 @@ public: //Texture const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, const VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL); + bool ChangeTexture2D(Texture2D *,Buffer *buf,const VkBufferImageCopy *,const int count); + bool ChangeTexture2D(Texture2D *,Buffer *buf,const List &); + bool ChangeTexture2D(Texture2D *,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height); bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size); + template + bool ChangeTexture2D(Texture2D *tex,Buffer *buf,const RectScope2 &rs) + { + return ChangeTexture2D( tex, + buf, + rs.GetLeft(), + rs.GetTop(), + rs.GetWidth(), + rs.GetHeight()); + } + + template + bool ChangeTexture2D(Texture2D *tex,void *data,const RectScope2 &rs,uint32_t size) + { + return ChangeTexture2D( tex, + buf, + rs.GetLeft(), + rs.GetTop(), + rs.GetWidth(), + rs.GetHeight(), + size); + } + public: // Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr); diff --git a/inc/hgl/graph/vulkan/VKPrimivate.h b/inc/hgl/graph/vulkan/VKPrimivate.h index 8e319e28..139ef7fc 100644 --- a/inc/hgl/graph/vulkan/VKPrimivate.h +++ b/inc/hgl/graph/vulkan/VKPrimivate.h @@ -14,7 +14,7 @@ #define PRIM_TRIANGLES_ADJ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ///<代表一个有六个顶点的Primitive,其中第1,3,5个顶点代表一个Triangle,而地2,4,6个点提供邻近信息.(由1起算) #define PRIM_TRIANGLE_STRIP_ADJ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY ///<4+2N个Vertices代表N个Primitive,其中1,3,5,7,9...代表原本的Triangle strip形成Triangle,而2,4,6,8,10...代表邻近提供信息的点.(由1起算) #define PRIM_PATCHS VK_PRIMITIVE_TOPOLOGY_PATCH_LIST -#define PRIM_2D_RECTANGLES 0x100 ///<矩形(并非原生支持。以画点形式在每个点的Position中传递Left,Top,Width,Height。在Geometry Shader中转换为2个三角形。用于2D游戏或UI) +#define PRIM_RECTANGLES 0x100 ///<矩形(并非原生支持。以画点形式在每个点的Position中传递Left,Top,Width,Height。在Geometry Shader中转换为2个三角形。用于2D游戏或UI) #define PRIM_BEGIN VK_PRIMITIVE_TOPOLOGY_POINT_LIST #define PRIM_END VK_PRIMITIVE_TOPOLOGY_PATCH_LIST constexpr uint32_t PRIM_RANGE =PRIM_END-PRIM_BEGIN+1; diff --git a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp b/src/RenderDevice/Vulkan/VKDeviceTexture.cpp index 98db55b4..2d727186 100644 --- a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp +++ b/src/RenderDevice/Vulkan/VKDeviceTexture.cpp @@ -109,29 +109,11 @@ Texture2D *Device::CreateTexture2D(const VkFormat format,void *data,uint32_t wid return(tex); } -bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height) +bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count) { - if(!tex||!buf - ||left<0||left+width>tex->GetWidth() - ||top<0||top+height>tex->GetHeight() - ||width<=0||height<=0) + if(!tex||!buf) return(false); - VkBufferImageCopy buffer_image_copy; - buffer_image_copy.bufferOffset = 0; - buffer_image_copy.bufferRowLength = 0; - buffer_image_copy.bufferImageHeight = 0; - buffer_image_copy.imageSubresource.aspectMask = tex->GetAspect(); - buffer_image_copy.imageSubresource.mipLevel = 0; - buffer_image_copy.imageSubresource.baseArrayLayer = 0; - buffer_image_copy.imageSubresource.layerCount = 1; - buffer_image_copy.imageOffset.x = left; - buffer_image_copy.imageOffset.y = top; - buffer_image_copy.imageOffset.z = 0; - buffer_image_copy.imageExtent.width = width; - buffer_image_copy.imageExtent.height= height; - buffer_image_copy.imageExtent.depth = 1; - VkImageSubresourceRange subresourceRange; subresourceRange.aspectMask = tex->GetAspect(); subresourceRange.baseMipLevel = 0; @@ -164,8 +146,8 @@ bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t t buf->GetBuffer(), tex->GetImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, - &buffer_image_copy); + count, + buffer_image_copy); imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; @@ -186,6 +168,70 @@ bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t t return(true); } +bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const List &ir_list) +{ + if(!tex||!buf||ir_list.GetCount()<=0) + return(false); + + const int ir_count=ir_list.GetCount(); + int count=0; + + AutoDeleteArray buffer_image_copy=new VkBufferImageCopy[ir_count]; + VkBufferImageCopy *tp=buffer_image_copy; + const ImageRegion *sp=ir_list.GetData(); + + VkDeviceSize offset=0; + + for(int i=0;ibufferOffset = offset; + tp->bufferRowLength = 0; + tp->bufferImageHeight = 0; + tp->imageSubresource.aspectMask = tex->GetAspect(); + tp->imageSubresource.mipLevel = 0; + tp->imageSubresource.baseArrayLayer = 0; + tp->imageSubresource.layerCount = 1; + tp->imageOffset.x = sp->left; + tp->imageOffset.y = sp->top; + tp->imageOffset.z = 0; + tp->imageExtent.width = sp->width; + tp->imageExtent.height= sp->height; + tp->imageExtent.depth = 1; + + offset+=sp->bytes; + ++sp; + ++tp; + } + + return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count); +} + +bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height) +{ + if(!tex||!buf + ||left<0||left+width>tex->GetWidth() + ||top<0||top+height>tex->GetHeight() + ||width<=0||height<=0) + return(false); + + VkBufferImageCopy buffer_image_copy; + buffer_image_copy.bufferOffset = 0; + buffer_image_copy.bufferRowLength = 0; + buffer_image_copy.bufferImageHeight = 0; + buffer_image_copy.imageSubresource.aspectMask = tex->GetAspect(); + buffer_image_copy.imageSubresource.mipLevel = 0; + buffer_image_copy.imageSubresource.baseArrayLayer = 0; + buffer_image_copy.imageSubresource.layerCount = 1; + buffer_image_copy.imageOffset.x = left; + buffer_image_copy.imageOffset.y = top; + buffer_image_copy.imageOffset.z = 0; + buffer_image_copy.imageExtent.width = width; + buffer_image_copy.imageExtent.height= height; + buffer_image_copy.imageExtent.depth = 1; + + return ChangeTexture2D(tex,buf,&buffer_image_copy,1); +} + bool Device::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size) { if(!tex||!data diff --git a/src/RenderDevice/Vulkan/VKPipeline.cpp b/src/RenderDevice/Vulkan/VKPipeline.cpp index 20011ba0..28593974 100644 --- a/src/RenderDevice/Vulkan/VKPipeline.cpp +++ b/src/RenderDevice/Vulkan/VKPipeline.cpp @@ -220,12 +220,12 @@ PipelineCreater::PipelineCreater(Device *dev,const Material *material,const Rend bool PipelineCreater::Set(const uint topology,bool restart) { if(topologyPRIM_END) - if(topology!=PRIM_2D_RECTANGLES)return(false); + if(topology!=PRIM_RECTANGLES)return(false); inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssembly.pNext = nullptr; inputAssembly.flags = 0; - inputAssembly.topology = VkPrimitiveTopology(topology==PRIM_2D_RECTANGLES?VK_PRIMITIVE_TOPOLOGY_POINT_LIST:topology); + inputAssembly.topology = VkPrimitiveTopology(topology==PRIM_RECTANGLES?VK_PRIMITIVE_TOPOLOGY_POINT_LIST:topology); inputAssembly.primitiveRestartEnable = restart; pipelineInfo.pInputAssemblyState = &inputAssembly; diff --git a/src/SceneGraph/TileData.cpp b/src/SceneGraph/TileData.cpp index 4e03c95e..710b76a3 100644 --- a/src/SceneGraph/TileData.cpp +++ b/src/SceneGraph/TileData.cpp @@ -48,9 +48,13 @@ namespace hgl } } - tile_bytes=tile_width*tile_height*GetStrideByFormat(tile_texture->GetFormat()); + pixel_bytes =GetStrideByFormat(tile_texture->GetFormat()); + tile_bytes =tile_width*tile_height*pixel_bytes; - tile_buffer=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tile_bytes,nullptr); + tile_buffer=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tile_bytes*tile_max_count,nullptr); + + commit_offset=0; + commit_ptr=nullptr; } TileData::~TileData() @@ -58,9 +62,36 @@ namespace hgl SAFE_CLEAR(tile_buffer); SAFE_CLEAR(tile_texture); } - - bool TileData::WriteTile(TileObject *obj,const void *data,const uint bytes,int ctw,int cth) + + void TileData::BeginCommit() { + commit_list.ClearData(); + commit_offset=0; + commit_ptr=(uint8 *)tile_buffer->Map(); + } + + int TileData::EndCommit() + { + const int commit_count=commit_list.GetCount(); + + if(commit_count<=0) + return -1; + + tile_buffer->Unmap(); + commit_ptr=nullptr; + + if(!device->ChangeTexture2D(tile_texture,tile_buffer,commit_list)) + return -2; + + const int result=commit_list.GetCount(); + + commit_list.ClearData(); + return result; + } + + bool TileData::CommitTile(TileObject *obj,const void *data,const uint bytes,int ctw,int cth) + { + if(!commit_ptr)return(false); if(!obj||!data||!bytes||ctw<=0||cth<=0) return(false); @@ -72,14 +103,23 @@ namespace hgl tile_texture->GetWidth(), tile_texture->GetHeight()); - tile_buffer->Write(data,0,bytes); + const int commit_count=commit_list.GetCount(); - device->ChangeTexture2D(tile_texture, - tile_buffer, - obj->uv_pixel.GetLeft(), - obj->uv_pixel.GetTop(), - tile_width, - tile_height); + if(commit_count>=tile_max_count) //理论上不可能 + return(false); + + memcpy(commit_ptr,data,bytes); + commit_ptr+=bytes; + + ImageRegion ir; + + ir.left =obj->uv_pixel.GetLeft(); + ir.top =obj->uv_pixel.GetTop(); + ir.width =obj->uv_pixel.GetWidth(); + ir.height =obj->uv_pixel.GetHeight(); + ir.bytes =bytes; + + commit_list.Add(ir); return(true); } @@ -92,8 +132,9 @@ namespace hgl * @param cth 当前tile高度,-1表示等同全局设置 * @return 为增加的Tile创建的对象 */ - TileObject *TileData::Add(const void *data,const uint bytes,const int ctw,const int cth) + TileObject *TileData::Commit(const void *data,const uint bytes,const int ctw,const int cth) { + if(!commit_ptr)return(false); if(!data||!bytes||ctw<=0||cth<=0) return(nullptr); @@ -102,7 +143,7 @@ namespace hgl if(!to_pool.Get(obj)) return(nullptr); - WriteTile(obj,data,bytes,ctw,cth); + CommitTile(obj,data,bytes,ctw,cth); tile_count++; return(obj); @@ -131,13 +172,14 @@ namespace hgl */ bool TileData::Change(TileObject *obj,const void *data,const uint bytes,const int ctw,const int cth) { + if(!commit_ptr)return(false); if(!obj||!data||!bytes||ctw<=0||cth<=0) return(false); if(!to_pool.IsActive(obj)) return(false); - return WriteTile(obj,data,bytes,ctw,cth); + return CommitTile(obj,data,bytes,ctw,cth); } /**