From 51780a68ee0ed10d678ca69bd3508a9dab5792a9 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Tue, 19 May 2020 19:03:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BAssimpLoaderMesh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/AssimpLoaderMesh.cpp | 27 +-- example/Vulkan/AssimpLoaderMesh.h | 3 +- example/Vulkan/CMakeLists.txt | 3 + example/Vulkan/SimplePBRForward.cpp | 272 ++++++++++++++++++++++++++++ 4 files changed, 290 insertions(+), 15 deletions(-) create mode 100644 example/Vulkan/SimplePBRForward.cpp diff --git a/example/Vulkan/AssimpLoaderMesh.cpp b/example/Vulkan/AssimpLoaderMesh.cpp index b9f70844..873c04f5 100644 --- a/example/Vulkan/AssimpLoaderMesh.cpp +++ b/example/Vulkan/AssimpLoaderMesh.cpp @@ -179,7 +179,7 @@ private: void AssimpLoaderMesh::GetBoundingBox(const aiNode *node,aiVector3D *min_pos,aiVector3D *max_pos) { - Matrix4f root_matrix=hgl::graph::MATRIX_FROM_OPENGL_COORDINATE; + Matrix4f root_matrix=hgl::graph::GetOpenGL2VulkanMatrix(); min_pos->x = min_pos->y = min_pos->z = 1e10f; max_pos->x = max_pos->y = max_pos->z = -1e10f; @@ -264,8 +264,12 @@ public: private: - bool Load(ModelSceneNode *msn,const aiNode *node) + bool Load(int level,ModelSceneNode *msn,const aiNode *node) { + for(int i=0;imName.C_Str()<name=node->mName.C_Str(); msn->local_matrix=MatrixConvert(node->mTransformation); @@ -282,7 +286,7 @@ private: { ModelSceneNode *sub=new ModelSceneNode; - if(!Load(sub,node->mChildren[i])) + if(!Load(level+1,sub,node->mChildren[i])) { delete sub; return(false); @@ -300,10 +304,12 @@ public: { model_data->root_node=new ModelSceneNode; - if(!Load(model_data->root_node,scene->mRootNode)) + std::cout<<"SceneRoot"<root_node,scene->mRootNode)) return(false); - model_data->root_node->local_matrix=hgl::graph::MATRIX_FROM_OPENGL_COORDINATE*model_data->root_node->local_matrix; + model_data->root_node->local_matrix=hgl::graph::GetOpenGL2VulkanMatrix()*model_data->root_node->local_matrix; return(true); } };//class AssimpLoaderMesh @@ -314,16 +320,11 @@ ModelData *AssimpLoadModel(const OSString &filename) if(!scene)return(nullptr); - AssimpLoaderMesh *alm=new AssimpLoaderMesh(ClipFileMainname(filename),scene); - - ModelData *data=nullptr; + AutoDelete alm=new AssimpLoaderMesh(ClipFileMainname(filename),scene); if(alm->LoadMesh()) - { if(alm->LoadScene()) - data=alm->GetModelData(); - } + return alm->GetModelData(); - delete alm; - return data; + return(nullptr); } diff --git a/example/Vulkan/AssimpLoaderMesh.h b/example/Vulkan/AssimpLoaderMesh.h index 91d4148d..f709ec92 100644 --- a/example/Vulkan/AssimpLoaderMesh.h +++ b/example/Vulkan/AssimpLoaderMesh.h @@ -36,12 +36,11 @@ struct ModelSceneNode struct ModelData { - AABB bounding_box; - ObjectList mesh_data; Map mesh_by_name; ModelSceneNode *root_node; + AABB bounding_box; public: diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index 86c7236c..553ad052 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -33,3 +33,6 @@ CreateProject(11.Atomsphere Atomsphere.cpp) CreateProject(13.DeferredModel DeferredModel.cpp) #CreateProject(14.AutoMaterial auto_material.cpp) + +CreateProject(14.SimplePBRForward SimplePBRForward.cpp AssimpLoaderMesh.h AssimpLoaderMesh.cpp) +target_link_libraries(14.SimplePBRForward assimp) \ No newline at end of file diff --git a/example/Vulkan/SimplePBRForward.cpp b/example/Vulkan/SimplePBRForward.cpp new file mode 100644 index 00000000..92e5489b --- /dev/null +++ b/example/Vulkan/SimplePBRForward.cpp @@ -0,0 +1,272 @@ +// 简易 PBR 前向渲染 + +#include"ViewModelFramework.h" +#include +#include +#include + +#include"AssimpLoaderMesh.h" +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +vulkan::Renderable *CreateMeshRenderable(SceneDB *db,vulkan::Material *mtl,const MeshData *mesh) +{ + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + uint draw_count=0; + + if(mesh->indices16.GetCount()>0) + draw_count=mesh->indices16.GetCount(); + else + draw_count=mesh->indices32.GetCount(); + + vulkan::Renderable *render_obj=nullptr; + { + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding==-1) + return(nullptr); + + vulkan::VertexBuffer *vbo=db->CreateVBO(FMT_RGB32F,mesh->position.GetCount(),mesh->position.GetData()); + + render_obj=mtl->CreateRenderable(); + render_obj->Set(vertex_binding,vbo); + render_obj->SetBoundingBox(mesh->bounding_box); + } + + const int normal_binding=vsm->GetStageInputBinding("Normal"); + + if(normal_binding!=-1) + { + vulkan::VertexBuffer *vbo=db->CreateVBO(FMT_RGB32F,mesh->normal.GetCount(),mesh->normal.GetData()); + + render_obj->Set(normal_binding,vbo); + } + + const int tagent_binding=vsm->GetStageInputBinding("Tangent"); + + if(tagent_binding!=-1) + { + vulkan::VertexBuffer *vbo=db->CreateVBO(FMT_RGB32F,mesh->tangent.GetCount(),mesh->tangent.GetData()); + + render_obj->Set(tagent_binding,vbo); + } + + const int bitagent_binding=vsm->GetStageInputBinding("Bitangent"); + + if(bitagent_binding!=-1) + { + vulkan::VertexBuffer *vbo=db->CreateVBO(FMT_RGB32F,mesh->bitangent.GetCount(),mesh->bitangent.GetData()); + + render_obj->Set(bitagent_binding,vbo); + } + + if(mesh->indices16.GetCount()>0) + render_obj->Set(db->CreateIBO16(mesh->indices16.GetCount(),mesh->indices16.GetData())); + else + render_obj->Set(db->CreateIBO32(mesh->indices32.GetCount(),mesh->indices32.GetData())); + + db->Add(render_obj); + return(render_obj); +} + +class TestApp:public ViewModelFramework +{ +private: + + vulkan::Material * material =nullptr; + vulkan::MaterialInstance * material_instance =nullptr; + + vulkan::Pipeline * pipeline_wireframe =nullptr; + vulkan::Pipeline * pipeline_lines =nullptr; + +private: + + ModelData *model_data; + + vulkan::Renderable **mesh_renderable; + RenderableInstance **mesh_renderable_instance; + + vulkan::Renderable *axis_renderable; + RenderableInstance *axis_renderable_instance; + + vulkan::Renderable *bbox_renderable; + RenderableInstance *bbox_renderable_instance; + +private: + + bool InitMaterial() + { + material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition3D.vert.spv"), + OS_TEXT("res/shader/FlatColor.frag.spv")); + if(!material) + return(false); + + material_instance=material->CreateInstance(); + + db->Add(material); + db->Add(material_instance); + return(true); + } + + void CreateRenderObject() + { + const uint count=model_data->mesh_data.GetCount(); + MeshData **md=model_data->mesh_data.GetData(); + + mesh_renderable =new vulkan::Renderable *[count]; + mesh_renderable_instance=new RenderableInstance *[count]; + + for(uint i=0;iCreateRenderableInstance(pipeline_wireframe,material_instance,mesh_renderable[i]); + ++md; + } + + { + AxisCreateInfo aci; + + aci.root=model_data->bounding_box.CenterPoint().xyz(); + aci.size=model_data->bounding_box.HalfSize().xyz(); + + axis_renderable=CreateRenderableAxis(db,material,&aci); + axis_renderable_instance=db->CreateRenderableInstance(pipeline_lines,material_instance,axis_renderable); + } + + { + CubeCreateInfo cci; + + cci.center=model_data->bounding_box.CenterPoint().xyz(); + cci.size=model_data->bounding_box.Size().xyz(); + + bbox_renderable=CreateRenderableBoundingBox(db,material,&cci); + bbox_renderable_instance=db->CreateRenderableInstance(pipeline_lines,material_instance,bbox_renderable); + } + } + + bool InitUBO() + { + if(!InitCameraUBO(material_instance,"world")) + return(false); + + material_instance->Update(); + return(true); + } + + bool InitPipeline() + { + AutoDelete + pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); + pipeline_creater->SetDepthTest(false); + pipeline_creater->SetDepthWrite(false); + pipeline_creater->SetPolygonMode(VK_POLYGON_MODE_LINE); + pipeline_creater->CloseCullFace(); + pipeline_creater->Set(PRIM_TRIANGLES); + + pipeline_wireframe=pipeline_creater->Create(); + + if(!pipeline_wireframe) + return(false); + + db->Add(pipeline_wireframe); + + pipeline_creater->SetPolygonMode(VK_POLYGON_MODE_FILL); + pipeline_creater->Set(PRIM_LINES); + + pipeline_lines=pipeline_creater->Create(); + + if(!pipeline_lines) + return(false); + + db->Add(pipeline_lines); + return(true); + } + + void CreateSceneNode(SceneNode *scene_node,ModelSceneNode *model_node) + { + scene_node->SetLocalMatrix(model_node->local_matrix); + + { + const uint count=model_node->mesh_index.GetCount(); + const uint32 *mesh_index=model_node->mesh_index.GetData(); + + for(uint i=0;iAdd(mesh_renderable_instance[*mesh_index]); + + ++mesh_index; + } + } + + { + const uint count=model_node->children_node.GetCount(); + ModelSceneNode **sub_model_node=model_node->children_node.GetData(); + + for(uint i=0;iCreateSubNode(),*sub_model_node); + + ++sub_model_node; + } + } + } + +public: + + bool Init(ModelData *md) + { + if(!md) + return(false); + + model_data=md; + + if(!ViewModelFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT,model_data->bounding_box)) + return(false); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + if(!InitPipeline()) + return(false); + + CreateRenderObject(); + + render_root.Add(axis_renderable_instance); + render_root.Add(bbox_renderable_instance); + + CreateSceneNode(render_root.CreateSubNode(),model_data->root_node); + + return(true); + } +};//class TestApp:public ViewModelFramework + +#ifdef _WIN32 +int wmain(int argc,wchar_t **argv) +#else +int main(int argc,char **argv) +#endif// +{ + TestApp app; + + ModelData *model_data=AssimpLoadModel(OS_TEXT("res/model/DamagedHelmet/DamagedHelmet.glb")); + + if(!model_data) + return -1; + + if(app.Init(model_data)) + while(app.Run()); + + if(model_data) + delete model_data; + + return 0; +}