From 593b0b4a03c712a6de38b3fdf5bdc3fa4df3ef3c Mon Sep 17 00:00:00 2001 From: hyzboy Date: Thu, 23 May 2019 19:23:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=BB=E5=9C=86=E8=A7=92?= =?UTF-8?q?=E7=9F=A9=E5=BD=A2=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/Geometry2D.cpp | 201 +++++++++++++++-------- example/Vulkan/indices_rect.cpp | 12 +- example/Vulkan/main.cpp | 12 +- inc/hgl/graph/vulkan/VKMaterial.h | 2 +- inc/hgl/graph/vulkan/VKPipeline.h | 2 +- inc/hgl/graph/vulkan/VKRenderable.h | 24 ++- src/RenderDevice/Vulkan/VKMaterial.cpp | 4 +- src/RenderDevice/Vulkan/VKRenderable.cpp | 3 +- 8 files changed, 178 insertions(+), 82 deletions(-) diff --git a/example/Vulkan/Geometry2D.cpp b/example/Vulkan/Geometry2D.cpp index 6e21e28c..33ef1c32 100644 --- a/example/Vulkan/Geometry2D.cpp +++ b/example/Vulkan/Geometry2D.cpp @@ -25,9 +25,6 @@ struct WorldConfig struct RectangleCreateInfo { RectScope2f scope; - vec3 normal; - Color4f color; - RectScope2f tex_coord; }; VK_NAMESPACE_BEGIN @@ -109,7 +106,7 @@ vulkan::Renderable *CreateRectangle(vulkan::Device *device,vulkan::Material *mtl { const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); - vulkan::Renderable *render_obj=mtl->CreateRenderable(); + vulkan::Renderable *render_obj=mtl->CreateRenderable(VERTEX_COUNT); const int vertex_binding=vsm->GetStageInputBinding("Vertex"); @@ -124,60 +121,105 @@ vulkan::Renderable *CreateRectangle(vulkan::Device *device,vulkan::Material *mtl render_obj->Set(vertex_binding,device->CreateVBO(vertex)); delete vertex; } - - const int normal_binding=vsm->GetStageInputBinding("Normal"); - - if(normal_binding!=-1) + else { - VB3f *normal=new VB3f(VERTEX_COUNT); - - normal->Begin(); - normal->Write(rci->normal,VERTEX_COUNT); - normal->End(); - - render_obj->Set(normal_binding,device->CreateVBO(normal)); - delete normal; - } - - const int color_binding=vsm->GetStageInputBinding("Color"); - - if(color_binding!=-1) - { - VB4f *color=new VB4f(VERTEX_COUNT); - - color->Begin(); - color->Write(rci->color,VERTEX_COUNT); - color->End(); - - render_obj->Set(color_binding,device->CreateVBO(color)); - delete color; - } - - const int tex_coord_binding=vsm->GetStageInputBinding("TexCoord"); - - if(tex_coord_binding!=-1) - { - VB2f *tex_coord=new VB2f(VERTEX_COUNT); - - tex_coord->Begin(); - tex_coord->WriteRectFan(rci->tex_coord); - tex_coord->End(); - - render_obj->Set(tex_coord_binding,device->CreateVBO(tex_coord)); - delete tex_coord; + delete render_obj; + return nullptr; } return render_obj; } -/** - * 创建一个圆角矩形 - * @param r 半径 - * @param rp 半径精度 - */ -//Mesh *CreateRoundrectangle(float l,float t,float w,float h,float r,uint32_t rp) -//{ -//} +struct RoundRectangleCreateInfo:public RectangleCreateInfo +{ + float radius; //圆角半径 + uint32_t round_per; //圆角精度 +}; + +vulkan::Renderable *CreateRoundRectangle(vulkan::Device *device,vulkan::Material *mtl,const RoundRectangleCreateInfo *rci) +{ + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + vulkan::Renderable *render_obj=nullptr; + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + VB2f *vertex=nullptr; + + if(rci->radius==0||rci->round_per<=1) //这是要画矩形 + { + vertex=new VB2f(4); + + vertex->Begin(); + vertex->WriteRectFan(rci->scope); + vertex->End(); + } + else + { + float radius=rci->radius; + + if(radius>rci->scope.GetWidth()/2.0f)radius=rci->scope.GetWidth()/2.0f; + if(radius>rci->scope.GetHeight()/2.0f)radius=rci->scope.GetHeight()/2.0f; + + vertex=new VB2f(1+rci->round_per*4); + + vertex->Begin(); + + vec2 *coord=new vec2[rci->round_per]; + + for(uint i=0;iround_per;i++) + { + float ang=float(i)/float(rci->round_per-1)*90.0f; + + float x=sin(hgl_ang2rad(ang))*radius; + float y=cos(hgl_ang2rad(ang))*radius; + + coord[i].x=x; + coord[i].y=y; + + //生成的是右上角的 + vertex->Write( rci->scope.GetRight()-radius+x, + rci->scope.GetTop()+radius-y); + } + + //右下角 + for(uint i=0;iround_per;i++) + { + vertex->Write(rci->scope.GetRight() -radius+coord[rci->round_per-1-i].x, + rci->scope.GetBottom()-radius+coord[rci->round_per-1-i].y); + } + + //左下角 + for(uint i=0;iround_per;i++) + { + vertex->Write(rci->scope.GetLeft() +radius-coord[i].x, + rci->scope.GetBottom()-radius+coord[i].y); + } + + //左上角 + for(uint i=0;iround_per;i++) + { + vertex->Write(rci->scope.GetLeft() +radius-coord[rci->round_per-1-i].x, + rci->scope.GetTop() +radius-coord[rci->round_per-1-i].y); + } + + vertex->Write(rci->scope.GetRight() -radius+coord[0].x, + rci->scope.GetTop() +radius-coord[0].y); + + delete[] coord; + + vertex->End(); + } + + render_obj=mtl->CreateRenderable(vertex->GetCount()); + render_obj->Set(vertex_binding,device->CreateVBO(vertex)); + + delete vertex; + + return render_obj; +} class TestApp:public VulkanApplicationFramework { @@ -186,8 +228,10 @@ private: uint swap_chain_count=0; vulkan::Material * material =nullptr; - vulkan::DescriptorSets * desciptor_sets =nullptr; + vulkan::DescriptorSets * descriptor_sets =nullptr; vulkan::Renderable * render_obj =nullptr; + vulkan::RenderableInstance *render_instance =nullptr; + vulkan::Buffer * ubo_mvp =nullptr; vulkan::Pipeline * pipeline =nullptr; @@ -200,13 +244,14 @@ public: ~TestApp() { + SAFE_CLEAR(render_instance); SAFE_CLEAR(color_buffer); SAFE_CLEAR(vertex_buffer); SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); SAFE_CLEAR(pipeline); SAFE_CLEAR(ubo_mvp); SAFE_CLEAR(render_obj); - SAFE_CLEAR(desciptor_sets); + SAFE_CLEAR(descriptor_sets); SAFE_CLEAR(material); } @@ -219,17 +264,25 @@ private: if(!material) return(false); - desciptor_sets=material->CreateDescriptorSets(); + descriptor_sets=material->CreateDescriptorSets(); return(true); } bool CreateRenderObject() { - struct RectangleCreateInfo rci; + //struct RectangleCreateInfo rci; - rci.scope.Set(10,10,10,10); + //rci.scope.Set(10,10,10,10); - render_obj=CreateRectangle(device,material,&rci); + //render_obj=CreateRectangle(device,material,&rci); + + struct RoundRectangleCreateInfo rrci; + + rrci.scope.Set(10,10,SCREEN_WIDTH-20,SCREEN_HEIGHT-20); + rrci.radius=8; //半径为8 + rrci.round_per=8; //圆角切分成8段 + + render_obj=CreateRoundRectangle(device,material,&rrci); return render_obj; } @@ -245,10 +298,10 @@ private: if(!ubo_mvp) return(false); - if(!desciptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) + if(!descriptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) return(false); - desciptor_sets->Update(); + descriptor_sets->Update(); return(true); } @@ -271,6 +324,27 @@ private: return pipeline; } + void Draw(vulkan::CommandBuffer *cb,vulkan::RenderableInstance *ri) + { + cb->Bind(ri->GetPipeline()); + cb->Bind(ri->GetDescriptorSets()); + + vulkan::Renderable *obj=ri->GetRenderable(); + + cb->Bind(obj); + + const vulkan::IndexBuffer *ib=obj->GetIndexBuffer(); + + if(ib) + { + cb->DrawIndexed(ib->GetCount()); + } + else + { + cb->Draw(obj->GetDrawCount()); + } + } + bool InitCommandBuffer() { cmd_buf=hgl_zero_new(swap_chain_count); @@ -284,10 +358,7 @@ private: cmd_buf[i]->Begin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); - cmd_buf[i]->Bind(pipeline); - cmd_buf[i]->Bind(desciptor_sets); - cmd_buf[i]->Bind(render_obj); - cmd_buf[i]->Draw(VERTEX_COUNT); + Draw(cmd_buf[i],render_instance); cmd_buf[i]->EndRenderPass(); cmd_buf[i]->End(); } @@ -316,6 +387,8 @@ public: if(!InitPipeline()) return(false); + render_instance=new vulkan::RenderableInstance(pipeline,descriptor_sets,render_obj); + if(!InitCommandBuffer()) return(false); diff --git a/example/Vulkan/indices_rect.cpp b/example/Vulkan/indices_rect.cpp index ca271a18..7ec0fd0e 100644 --- a/example/Vulkan/indices_rect.cpp +++ b/example/Vulkan/indices_rect.cpp @@ -40,7 +40,7 @@ private: uint swap_chain_count=0; vulkan::Material * material =nullptr; - vulkan::DescriptorSets * desciptor_sets =nullptr; + vulkan::DescriptorSets * descriptor_sets =nullptr; vulkan::Renderable * render_obj =nullptr; vulkan::Buffer * ubo_mvp =nullptr; @@ -60,7 +60,7 @@ public: SAFE_CLEAR(pipeline); SAFE_CLEAR(ubo_mvp); SAFE_CLEAR(render_obj); - SAFE_CLEAR(desciptor_sets); + SAFE_CLEAR(descriptor_sets); SAFE_CLEAR(material); } @@ -74,7 +74,7 @@ private: return(false); render_obj=material->CreateRenderable(); - desciptor_sets=material->CreateDescriptorSets(); + descriptor_sets=material->CreateDescriptorSets(); return(true); } @@ -89,10 +89,10 @@ private: if(!ubo_mvp) return(false); - if(!desciptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) + if(!descriptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) return(false); - desciptor_sets->Update(); + descriptor_sets->Update(); return(true); } @@ -136,7 +136,7 @@ private: cmd_buf[i]->Begin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); cmd_buf[i]->Bind(pipeline); - cmd_buf[i]->Bind(desciptor_sets); + cmd_buf[i]->Bind(descriptor_sets); cmd_buf[i]->Bind(render_obj); cmd_buf[i]->DrawIndexed(INDEX_COUNT); cmd_buf[i]->EndRenderPass(); diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 83686abd..f4659205 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -41,7 +41,7 @@ private: uint swap_chain_count=0; vulkan::Material * material =nullptr; - vulkan::DescriptorSets * desciptor_sets =nullptr; + vulkan::DescriptorSets * descriptor_sets =nullptr; vulkan::Renderable * render_obj =nullptr; vulkan::Buffer * ubo_mvp =nullptr; @@ -61,7 +61,7 @@ public: SAFE_CLEAR(pipeline); SAFE_CLEAR(ubo_mvp); SAFE_CLEAR(render_obj); - SAFE_CLEAR(desciptor_sets); + SAFE_CLEAR(descriptor_sets); SAFE_CLEAR(material); } @@ -75,7 +75,7 @@ private: return(false); render_obj=material->CreateRenderable(); - desciptor_sets=material->CreateDescriptorSets(); + descriptor_sets=material->CreateDescriptorSets(); return(true); } @@ -90,10 +90,10 @@ private: if(!ubo_mvp) return(false); - if(!desciptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) + if(!descriptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) return(false); - desciptor_sets->Update(); + descriptor_sets->Update(); return(true); } @@ -150,7 +150,7 @@ private: cmd_buf[i]->Begin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); cmd_buf[i]->Bind(pipeline); - cmd_buf[i]->Bind(desciptor_sets); + cmd_buf[i]->Bind(descriptor_sets); cmd_buf[i]->Bind(render_obj); cmd_buf[i]->Draw(VERTEX_COUNT); cmd_buf[i]->EndRenderPass(); diff --git a/inc/hgl/graph/vulkan/VKMaterial.h b/inc/hgl/graph/vulkan/VKMaterial.h index c6e7ac4d..9832b3de 100644 --- a/inc/hgl/graph/vulkan/VKMaterial.h +++ b/inc/hgl/graph/vulkan/VKMaterial.h @@ -57,7 +57,7 @@ public: void Write(VkPipelineVertexInputStateCreateInfo &vis)const; - Renderable *CreateRenderable(); + Renderable *CreateRenderable(const uint32_t draw_count); };//class Material VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_MATERIAL_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKPipeline.h b/inc/hgl/graph/vulkan/VKPipeline.h index 83e4a01e..2f5f44b5 100644 --- a/inc/hgl/graph/vulkan/VKPipeline.h +++ b/inc/hgl/graph/vulkan/VKPipeline.h @@ -145,7 +145,7 @@ public: { cba=colorBlendAttachments.GetData(); - for(uint i=0;iblendEnable) { alpha_blend=true; diff --git a/inc/hgl/graph/vulkan/VKRenderable.h b/inc/hgl/graph/vulkan/VKRenderable.h index 61d868cb..d52233ff 100644 --- a/inc/hgl/graph/vulkan/VKRenderable.h +++ b/inc/hgl/graph/vulkan/VKRenderable.h @@ -2,6 +2,7 @@ #define HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE #include +#include #include VK_NAMESPACE_BEGIN /** @@ -17,14 +18,27 @@ class Renderable VkBuffer *buf_list=nullptr; VkDeviceSize *buf_offset=nullptr; + uint32_t draw_count; + IndexBuffer *indices_buffer=nullptr; VkDeviceSize indices_offset=0; +protected: + + friend class RenderableInstance; + + uint ref_count=0; + + uint RefInc(){return ++ref_count;} + uint RefDec(){return --ref_count;} + public: - Renderable(const VertexShaderModule *); + Renderable(const VertexShaderModule *,const uint32_t dc); virtual ~Renderable(); + const uint GetRefCount()const{return ref_count;} + bool Set(const int stage_input_binding, VertexBuffer *vb,VkDeviceSize offset=0); bool Set(const UTF8String &name, VertexBuffer *vb,VkDeviceSize offset=0); @@ -39,6 +53,14 @@ public: public: + const uint32_t GetDrawCount ()const ///<取得当前对象绘制需要多少个顶点 + { + if(indices_buffer) + return indices_buffer->GetCount(); + + return draw_count; + } + const int GetBufferCount ()const{return buf_count;} const VkBuffer * GetBuffer ()const{return buf_list;} const VkDeviceSize * GetOffset ()const{return buf_offset;} diff --git a/src/RenderDevice/Vulkan/VKMaterial.cpp b/src/RenderDevice/Vulkan/VKMaterial.cpp index 7c7cf1cf..0ba62d6f 100644 --- a/src/RenderDevice/Vulkan/VKMaterial.cpp +++ b/src/RenderDevice/Vulkan/VKMaterial.cpp @@ -114,8 +114,8 @@ void Material::Write(VkPipelineVertexInputStateCreateInfo &vis)const return vab->Write(vis); } -Renderable *Material::CreateRenderable() +Renderable *Material::CreateRenderable(const uint32_t draw_count) { - return(new Renderable(vertex_sm)); + return(new Renderable(vertex_sm,draw_count)); } VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderable.cpp b/src/RenderDevice/Vulkan/VKRenderable.cpp index 1e2194d0..28d2092b 100644 --- a/src/RenderDevice/Vulkan/VKRenderable.cpp +++ b/src/RenderDevice/Vulkan/VKRenderable.cpp @@ -3,9 +3,10 @@ #include VK_NAMESPACE_BEGIN -Renderable::Renderable(const VertexShaderModule *vsm) +Renderable::Renderable(const VertexShaderModule *vsm,const uint32_t dc) { vertex_sm=vsm; + draw_count=dc; buf_count=vertex_sm->GetAttrCount();