From 4fdbe6a68648c00983c0aebc5aa7178be0a8745f Mon Sep 17 00:00:00 2001 From: hyzboy Date: Mon, 27 May 2019 22:48:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=8B=A5=E5=B9=B2=E5=86=85?= =?UTF-8?q?=E5=B5=8C=E5=87=A0=E4=BD=95=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/CMakeLists.txt | 1 + example/Vulkan/Geometry3D.cpp | 227 ++++++++++++++++++++++++++++++ inc/hgl/graph/InlineGeometry.h | 62 ++++++-- src/SceneGraph/InlineGeometry.cpp | 225 +++++++++++++++++++++++++++++ 4 files changed, 504 insertions(+), 11 deletions(-) create mode 100644 example/Vulkan/Geometry3D.cpp diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index c8e86979..4bdc0c9f 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -10,3 +10,4 @@ CreateProject(1.indices_rect indices_rect) CreateProject(2.texture_rect texture_rect) target_link_libraries(2.texture_rect TGATexture) CreateProject(3.Geometry2D Geometry2D) +CreateProject(4.Geometry3D Geometry3D) diff --git a/example/Vulkan/Geometry3D.cpp b/example/Vulkan/Geometry3D.cpp new file mode 100644 index 00000000..b104178f --- /dev/null +++ b/example/Vulkan/Geometry3D.cpp @@ -0,0 +1,227 @@ +// 4.Geometry3D + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); +bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); + +constexpr uint32_t SCREEN_WIDTH=128; +constexpr uint32_t SCREEN_HEIGHT=128; + +struct WorldConfig +{ + Matrix4f mvp; +}world; + +class TestApp:public VulkanApplicationFramework +{ +private: + + uint swap_chain_count=0; + + SceneDB * db =nullptr; + SceneNode render_root; + RenderList render_list; + + Camera camera; + + vulkan::Material * material =nullptr; + vulkan::DescriptorSets * descriptor_sets =nullptr; + + vulkan::Renderable *ro_plane_grid =nullptr, + *ro_cube =nullptr; + + vulkan::Buffer * ubo_mvp =nullptr; + + vulkan::Pipeline * pipeline_line =nullptr; + vulkan::CommandBuffer ** cmd_buf =nullptr; + +public: + + ~TestApp() + { + SAFE_CLEAR(db); + + SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); + } + +private: + + void InitCamera() + { + camera.center.Set(0,0,0); + camera.eye.Set(100,100,100); + camera.up_vector.Set(0,0,1); + camera.forward_vector.Set(0,1,0); + camera.znear=4; + camera.zfar=1000; + camera.fov=45; + camera.width=SCREEN_WIDTH; + camera.height=SCREEN_HEIGHT; + + camera.Refresh(); //¾ + + world.mvp=camera.projection*camera.modelview; + } + + bool InitMaterial() + { + material=shader_manage->CreateMaterial(OS_TEXT("OnlyPosition3D.vert.spv"), + OS_TEXT("FlatColor.frag.spv")); + if(!material) + return(false); + + descriptor_sets=material->CreateDescriptorSets(); + + db->Add(material); + db->Add(descriptor_sets); + return(true); + } + + void CreateRenderObject() + { + { + struct PlaneGridCreateInfo pgci; + + pgci.coord[0].Set(-100,-100,0); + pgci.coord[1].Set( 100,-100,0); + pgci.coord[2].Set( 100, 100,0); + pgci.coord[3].Set(-100, 100,0); + + pgci.step.u=20; + pgci.step.v=20; + + ro_plane_grid=CreatePlaneGrid(db,material,&pgci); + } + } + + bool InitUBO() + { + const VkExtent2D extent=device->GetExtent(); + + ubo_mvp=db->CreateUBO(sizeof(WorldConfig),&world); + + if(!ubo_mvp) + return(false); + + if(!descriptor_sets->BindUBO(material->GetUBO("world"),*ubo_mvp)) + return(false); + + descriptor_sets->Update(); + return(true); + } + + bool InitPipeline() + { + constexpr os_char PIPELINE_FILENAME[]=OS_TEXT("2DSolid.pipeline"); + + { + vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent()); + pipeline_creater->SetDepthTest(true); + pipeline_creater->SetDepthWrite(true); + pipeline_creater->CloseCullFace(); + pipeline_creater->Set(PRIM_LINES); + + pipeline_line=pipeline_creater->Create(); + db->Add(pipeline_line); + delete pipeline_creater; + } + + return pipeline_line; + } + + bool InitScene() + { + render_root.Add(db->CreateRenderableInstance(pipeline_line,descriptor_sets,ro_plane_grid)); + //render_root.Add(db->CreateRenderableInstance(pipeline,descriptor_sets,ro_round_rectangle)); + //render_root.Add(db->CreateRenderableInstance(pipeline,descriptor_sets,ro_circle)); + + render_root.RefreshMatrix(); + render_root.ExpendToList(&render_list); + + return(true); + } + + bool InitCommandBuffer() + { + cmd_buf=hgl_zero_new(swap_chain_count); + + for(uint i=0;iCreateCommandBuffer(); + + if(!cmd_buf[i]) + return(false); + + cmd_buf[i]->Begin(); + cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); + render_list.Render(cmd_buf[i]); + cmd_buf[i]->EndRenderPass(); + cmd_buf[i]->End(); + } + + return(true); + } + +public: + + bool Init() + { + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + swap_chain_count=device->GetSwapChainImageCount(); + + db=new SceneDB(device); + + InitCamera(); + + if(!InitMaterial()) + return(false); + + CreateRenderObject(); + + if(!InitUBO()) + return(false); + + if(!InitPipeline()) + return(false); + + if(!InitScene()) + return(false); + + if(!InitCommandBuffer()) + return(false); + + return(true); + } + + void Draw() override + { + const uint32_t frame_index=device->GetCurrentFrameIndices(); + + const vulkan::CommandBuffer *cb=cmd_buf[frame_index]; + + Submit(*cb); + } +};//class TestApp:public VulkanApplicationFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/inc/hgl/graph/InlineGeometry.h b/inc/hgl/graph/InlineGeometry.h index 19c603f8..1386bf0e 100644 --- a/inc/hgl/graph/InlineGeometry.h +++ b/inc/hgl/graph/InlineGeometry.h @@ -16,7 +16,7 @@ namespace hgl struct RectangleCreateInfo { RectScope2f scope; - }; + };//struct RectangleCreateInfo vulkan::Renderable *CreateRectangle(SceneDB *db,vulkan::Material *mtl,const RectangleCreateInfo *rci); @@ -25,23 +25,63 @@ namespace hgl */ struct RoundRectangleCreateInfo:public RectangleCreateInfo { - float radius; //圆角半径 - uint32_t round_per; //圆角精度 - }; + float radius; ///<圆角半径 + uint32_t round_per; ///<圆角精度 + };//struct RoundRectangleCreateInfo:public RectangleCreateInfo vulkan::Renderable *CreateRoundRectangle(SceneDB *db,vulkan::Material *mtl,const RoundRectangleCreateInfo *rci); /** * 圆形创建信息 */ - struct CircleCreateInfo - { - Vector2f center; //圆心坐标 - Vector2f radius; //半径 - uint field_count; //分段次数 - }; + struct CircleCreateInfo + { + Vector2f center; ///<圆心坐标 + Vector2f radius; ///<半径 + uint field_count; ///<分段次数 + };//struct CircleCreateInfo - vulkan::Renderable *CreateCircle(SceneDB *db,vulkan::Material *mtl,const CircleCreateInfo *rci); + vulkan::Renderable *CreateCircle(SceneDB *db,vulkan::Material *mtl,const CircleCreateInfo *rci); + + /** + * 平面网格创建信息 + */ + struct PlaneGridCreateInfo + { + Vector3f coord[4]; + vec2 step; + };//struct PlaneGridCreateInfo + + vulkan::Renderable *CreatePlaneGrid(SceneDB *db,vulkan::Material *mtl,const PlaneGridCreateInfo *pgci); + + struct PlaneCreateInfo + { + Vector2f tile; + };//struct PlaneCreateInfo + + vulkan::Renderable *CreatePlane(SceneDB *db,vulkan::Material *mtl,const PlaneCreateInfo *pci); + + struct CubeCreateInfo + { + Vector2f tile; + };//struct CubeCreateInfo + + /** + * 创建一个中心坐标为0,0,0,长宽高为1的立方体 + */ + vulkan::Renderable *CreateCube(SceneDB *db,vulkan::Material *mtl,const CubeCreateInfo *cci); + + struct BoundingBoxCreateInfo + { + AABB bounding_box; + };// + + /** + * 创建一个空心立方体,使用绑定盒的真实坐标 + */ + vulkan::Renderable *CreateBoundingBox(SceneDB *db,vulkan::Material *mtl,const BoundingBoxCreateInfo *bbci); + + //vulkan::Renderable *CreateSphere(SceneDB *db,vulkan::Material *mtl,const uint ); }//namespace graph };//namespace hgl #endif//HGL_GRAPH_INLINE_GEOMETRY_INCLUDE diff --git a/src/SceneGraph/InlineGeometry.cpp b/src/SceneGraph/InlineGeometry.cpp index 0aeb2826..dbf675d8 100644 --- a/src/SceneGraph/InlineGeometry.cpp +++ b/src/SceneGraph/InlineGeometry.cpp @@ -154,5 +154,230 @@ namespace hgl db->Add(render_obj); return render_obj; } + + vulkan::Renderable *CreatePlaneGrid(SceneDB *db,vulkan::Material *mtl,const PlaneGridCreateInfo *pgci) + { + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + VB3f *vertex=new VB3f(((pgci->step.u+1)+(pgci->step.v+1))*2); + + vertex->Begin(); + for(int row=0;row<=pgci->step.u;row++) + { + float pos=float(row)/float(pgci->step.u); + + vertex->WriteLine( to(pgci->coord[0],pgci->coord[1],pos), + to(pgci->coord[3],pgci->coord[2],pos)); + } + + for(int col=0;col<=pgci->step.v;col++) + { + float pos=float(col)/float(pgci->step.v); + + vertex->WriteLine(to(pgci->coord[1],pgci->coord[2],pos), + to(pgci->coord[0],pgci->coord[3],pos)); + } + vertex->End(); + + vulkan::Renderable *render_obj=mtl->CreateRenderable(vertex->GetCount()); + render_obj->Set(vertex_binding,db->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); + + delete vertex; + db->Add(render_obj); + return render_obj; + } + + vulkan::Renderable *CreatePlane(SceneDB *db,vulkan::Material *mtl,const PlaneCreateInfo *pci) + { + const float xy_vertices [] = { -0.5f,-0.5f,0.0f, +0.5f,-0.5f,0.0f, -0.5f,+0.5f,0.0f, +0.5f,+0.5f,0.0f}; + float xy_tex_coord[] = { 0.0f, 0.0f, 1.0f,0.0f, 0.0f,1.0f, 1.0f, 1.0f}; + const Vector3f xy_normal(0.0f,0.0f,1.0f); + const Vector3f xy_tangent(1.0f,0.0f,0.0f); + + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + vulkan::Renderable *render_obj=nullptr; + { + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + VB3f *vertex=new VB3f(4,xy_vertices); + + render_obj=mtl->CreateRenderable(vertex->GetCount()); + render_obj->Set(vertex_binding,db->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); + delete vertex; + } + + if(render_obj) + { + const int normal_binding=vsm->GetStageInputBinding("Normal"); + + if(normal_binding!=-1) + { + VB3f *normal=new VB3f(4); + + normal->Begin(); + normal->Fill(xy_normal,4); + normal->End(); + + render_obj->Set(normal_binding,db->CreateVBO(normal)); + delete normal; + } + + const int tagent_binding=vsm->GetStageInputBinding("Tangent"); + + if(tagent_binding!=-1) + { + VB3f *tangent=new VB3f(4); + + tangent->Begin(); + tangent->Fill(xy_tangent,4); + tangent->End(); + + render_obj->Set(tagent_binding,db->CreateVBO(tangent)); + delete tangent; + } + + const int texcoord_binding=vsm->GetStageInputBinding("TexCoord"); + + if(texcoord_binding!=-1) + { + xy_tex_coord[2]=xy_tex_coord[6]=pci->tile.x; + xy_tex_coord[5]=xy_tex_coord[7]=pci->tile.y; + + VB2f *tex_coord=new VB2f(4,xy_tex_coord); + + render_obj->Set(texcoord_binding,db->CreateVBO(tex_coord)); + delete tex_coord; + } + } + + db->Add(render_obj); + return render_obj; + } + + vulkan::Renderable *CreateCube(SceneDB *db,vulkan::Material *mtl,const CubeCreateInfo *cci) + { // Points of a cube. + /* 4 5 */ const float points[]={ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, + /* *------------* */ +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, + /* /| /| */ -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, + /* 0/ | 1/ | */ -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f }; + /* *--+---------* | */ // Normals of a cube. + /* | | | | */ const float normals[]={ +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, + /* | 7| | 6| */ +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, + /* | *---------+--* */ +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, + /* | / | / */ -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f }; + /* |/ 2|/ */ // The associated indices. + /* 3*------------* */ const uint16 indices[]={ 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 15, 14, 12, 14, 13, 16, 17, 18, 16, 18, 19, 20, 23, 22, 20, 22, 21 }; + + const float tangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, + 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f }; + + float tex_coords[] ={ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; + + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + vulkan::Renderable *render_obj=nullptr; + { + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + VB3f *vertex=new VB3f(24,points); + + render_obj=mtl->CreateRenderable(vertex->GetCount()); + render_obj->Set(vertex_binding,db->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); + delete vertex; + } + + const int normal_binding=vsm->GetStageInputBinding("Normal"); + + if(normal_binding!=-1) + { + VB3f *normal=new VB3f(24,normals); + + render_obj->Set(normal_binding,db->CreateVBO(normal)); + delete normal; + } + + const int tagent_binding=vsm->GetStageInputBinding("Tangent"); + + if(tagent_binding!=-1) + { + VB3f *tangent=new VB3f(24,tangents); + + render_obj->Set(tagent_binding,db->CreateVBO(tangent)); + delete tangent; + } + + const int texcoord_binding=vsm->GetStageInputBinding("TexCoord"); + + if(texcoord_binding!=-1) + { + float *tc=tex_coords; + for(uint i=0;i<24;i++) + { + (*tc)*=cci->tile.x;++tc; + (*tc)*=cci->tile.y;++tc; + } + + VB2f *tex_coord=new VB2f(24,tex_coords); + + render_obj->Set(texcoord_binding,db->CreateVBO(tex_coord)); + delete tex_coord; + } + + render_obj->Set(db->CreateIBO16(6*2*3,indices)); + return(render_obj); + } + + vulkan::Renderable *CreateBoundingBox(SceneDB *db,vulkan::Material *mtl,const BoundingBoxCreateInfo *bbci) + { + vec side[24]; + + bbci->bounding_box.ToEdgeList(side); + + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + vulkan::Renderable *render_obj=nullptr; + { + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + VB3f *vertex=new VB3f(24); + + vertex->Begin(); + vertex->Write(side,24); + vertex->End(); + + render_obj=mtl->CreateRenderable(vertex->GetCount()); + render_obj->Set(vertex_binding,db->CreateVBO(vertex)); + render_obj->SetBoundingBox(vertex->GetAABB()); + delete vertex; + } + + return render_obj; + } + + //vulkan::Renderable *CreateSphere(SceneDB *db,vulkan::Material *mtl,const SphereCreateInfo *sci) + //{ + //} }//namespace graph }//namespace hgl \ No newline at end of file