增加新的Mesh/Material文件,以及SceneFile加载代码(未完成不可用)

This commit is contained in:
hyzboy 2019-05-30 20:32:44 +08:00
parent d70c564474
commit 188b8f9c2a
9 changed files with 694 additions and 5 deletions

View File

@ -11,3 +11,4 @@ CreateProject(2.texture_rect texture_rect)
target_link_libraries(2.texture_rect TGATexture)
CreateProject(3.Geometry2D Geometry2D)
CreateProject(4.Geometry3D Geometry3D)
CreateProject(5.LoadModel LoadModel)

View File

@ -10,8 +10,8 @@
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
class TestApp:public VulkanApplicationFramework
{

View File

@ -0,0 +1,237 @@
// 5.LoadModel
// 加载纯色无贴图模型
#include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/SceneDB.h>
#include<hgl/graph/RenderableInstance.h>
#include<hgl/graph/RenderList.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
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::Buffer * ubo_world_matrix =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.type=CameraType::Perspective;
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=90;
camera.width=SCREEN_WIDTH;
camera.height=SCREEN_HEIGHT;
camera.Refresh(); //更新矩阵计算
}
bool InitMaterial()
{
material=shader_manage->CreateMaterial(OS_TEXT("PositionColor3D.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;
pgci.side_step.u=10;
pgci.side_step.v=10;
pgci.color.Set(0.75,0,0,1);
pgci.side_color.Set(1,0,0,1);
ro_plane_grid[0]=CreatePlaneGrid(db,material,&pgci);
pgci.color.Set(0,0.75,0,1);
pgci.side_color.Set(0,1,0,1);
ro_plane_grid[1]=CreatePlaneGrid(db,material,&pgci);
pgci.color.Set(0,0,0.75,1);
pgci.side_color.Set(0,0,1,1);
ro_plane_grid[2]=CreatePlaneGrid(db,material,&pgci);
}
}
bool InitUBO()
{
const VkExtent2D extent=device->GetExtent();
ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&camera.matrix);
if(!ubo_world_matrix)
return(false);
if(!descriptor_sets->BindUBO(material->GetUBO("world"),*ubo_world_matrix))
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();
if(!pipeline_line)
return(false);
db->Add(pipeline_line);
delete pipeline_creater;
}
return pipeline_line;
}
bool InitScene()
{
const float rad90=hgl_ang2rad(90);
render_root.Add(db->CreateRenderableInstance(pipeline_line,descriptor_sets,ro_plane_grid[0]));
render_root.Add(db->CreateRenderableInstance(pipeline_line,descriptor_sets,ro_plane_grid[1]),rotate(rad90,0,1,0));
render_root.Add(db->CreateRenderableInstance(pipeline_line,descriptor_sets,ro_plane_grid[2]),rotate(rad90,1,0,0));
render_root.RefreshMatrix();
render_root.ExpendToList(&render_list);
return(true);
}
bool InitCommandBuffer()
{
cmd_buf=hgl_zero_new<vulkan::CommandBuffer *>(swap_chain_count);
for(uint i=0;i<swap_chain_count;i++)
{
cmd_buf[i]=device->CreateCommandBuffer();
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;
}

View File

@ -44,7 +44,6 @@ namespace hgl
/**
*
* @param filename
* @param fullname
*/
template<typename T>
@ -63,6 +62,25 @@ namespace hgl
return fullname.SubString(pos+1);
}
/**
* ()
* @param filename
* @param split_char ,'.'
*/
template<typename T>
inline BaseString<T> ClipFileMainname(const BaseString<T> &filename,const T split_char='.')
{
if(filename.Length()<=1)
return(BaseString<T>());
const int pos=filename.FindRightChar(split_char);
if(pos==-1)
return BaseString<T>(filename);
return filename.SubString(0,pos);
}
/**
*
*/

View File

@ -2,6 +2,7 @@
#define HGL_GRAPH_MATERIAL_INCLUDE
#include<hgl/graph/TextureType.h>
#include<hgl/type/Color4f.h>
namespace hgl
{
namespace graph

View File

@ -8,7 +8,11 @@
${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h
${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h
${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h
${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h)
${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h
${ROOT_INCLUDE_PATH}/hgl/graph/Mesh.h
${ROOT_INCLUDE_PATH}/hgl/graph/Material.h
${ROOT_INCLUDE_PATH}/hgl/graph/TextureType.h
)
SET(SCENE_GRAPH_SOURCE AABox.cpp
Camera.cpp
@ -16,7 +20,10 @@ SET(SCENE_GRAPH_SOURCE AABox.cpp
SceneDB.cpp
SceneNode.cpp
SceneOrient.cpp
InlineGeometry.cpp)
InlineGeometry.cpp
Material.cpp
Mesh.cpp
SceneFile.cpp)
SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER})
SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE})

View File

@ -0,0 +1,68 @@
#include<hgl/graph/Material.h>
#include<hgl/io/FileInputStream.h>
#include<hgl/io/DataInputStream.h>
#include<hgl/LogInfo.h>
namespace hgl
{
namespace graph
{
bool LoadMaterialFile(MaterialData &md,const OSString &filename)//,Texture **tex_list)
{
io::FileInputStream fis;
io::LEDataInputStream dis(&fis);
if(!fis.Open(filename))
RETURN_FALSE;
uint8 flag[9];
if(dis.ReadFully(flag,9)!=9)
RETURN_FALSE;
if(memcmp(flag,"Material\x1A",9))
RETURN_FALSE;
uint8 ver;
if(!dis.ReadUint8(ver))RETURN_FALSE;
if(ver!=1)RETURN_FALSE;
if(dis.ReadFloat(md.diffuse,3)!=3)RETURN_FALSE;
if(dis.ReadFloat(md.specular,3)!=3)RETURN_FALSE;
if(dis.ReadFloat(md.ambient,3)!=3)RETURN_FALSE;
if(dis.ReadFloat(md.emission,3)!=3)RETURN_FALSE;
if(!dis.ReadFloat(md.shininess))RETURN_FALSE;
if(!dis.ReadBool(md.wireframe))RETURN_FALSE;
if(!dis.ReadBool(md.two_sided))RETURN_FALSE;
if(!dis.ReadUint8(md.tex_count))RETURN_FALSE;
md.Init(md.tex_count);
for(uint8 i=0;i<md.tex_count;i++)
{
MaterialTextureData *mtd=&(md.tex_list[i]);
uint8 tt;
if(!dis.ReadUint8(tt))RETURN_FALSE;
mtd->type=(TextureType)tt;
if(!dis.ReadInt32(mtd->tex_id))RETURN_FALSE;
if(!dis.ReadUint8(mtd->uvindex))RETURN_FALSE;
if(!dis.ReadFloat(mtd->blend))RETURN_FALSE;
if(!dis.ReadUint8(mtd->op))RETURN_FALSE;
uint8 wm[2];
if(!dis.ReadUint8(wm,2))RETURN_FALSE;
hgl_typecpy(mtd->wrap_mode,wm,2);
//mtl.SetTexture(mtd->type,tex_list[mtd->tex_id]);
}
return(true);
}
}//namespace graph
}//namespace hgl

150
src/SceneGraph/Mesh.cpp Normal file
View File

@ -0,0 +1,150 @@
#include<hgl/graph/Mesh.h>
#include<hgl/graph/Material.h>
#include<hgl/graph/VertexBuffer.h>
#include<hgl/io/FileInputStream.h>
#include<hgl/io/DataInputStream.h>
#include<hgl/LogInfo.h>
namespace hgl
{
namespace graph
{
bool LoadMeshFile(MeshFileHeader &md,const OSString &filename,MaterialData *md_list)
{
MeshFileHeader mfh;
io::FileInputStream fis;
io::LEDataInputStream dis(&fis);
if(!fis.Open(filename))
RETURN_FALSE;
if(dis.ReadFully(&mfh,sizeof(mfh))!=sizeof(mfh))
RETURN_FALSE;
if(mfh.texcoord_channels<=0)
RETURN_FALSE;
MaterialData *mtd=&(md_list[mfh.material_index]);
uint8 *uv_comp=nullptr;
float **uv_data=nullptr;
VertexBufferCreater **uv_vb=nullptr;
md.va=new VertexArray(mfh.primitive_type);
{
VB3f *vertex=new VB3f(mfh.vertices_number);
dis.ReadFully(vertex->Begin(),vertex->GetBytes());vertex->End();
md.va->SetVertex(vertex);
}
if(mfh.ntb)
{
const uint size=mfh.vertices_number*3*sizeof(float);
if(mtl->GetLightMode()==HGL_NONE_LIGHT)
{
if(mfh.ntb==NTB_BIT_ALL)
dis.Seek(size*3,io::soCurrent);
else
dis.Seek(size,io::soCurrent);
}
else
{
VB3f *normal=new VB3f(mfh.vertices_number);
dis.ReadFully(normal->Begin(),normal->GetBytes());normal->End();
md.va->SetNormal(normal);
if(mfh.ntb==NTB_BIT_ALL)
dis.Seek(normal->GetBytes()*2,io::soCurrent); //跳过tangent和bitangent
}
}
if(mfh.color_channels)
{
VB4ub *color=new VB4ub(mfh.vertices_number);
dis.ReadFully(color->Begin(),color->GetBytes());color->End();
md.va->SetColor(color,HGL_PC_RGBA);
dis.Seek(mfh.vertices_number*4*(mfh.color_channels-1),io::soCurrent); //跳过vertex color
}
if(mfh.texcoord_channels)
{
uv_comp=new uint8[mfh.texcoord_channels];
uv_data=new float *[mfh.texcoord_channels];
uv_vb=new VertexBufferBase *[mfh.texcoord_channels];
dis.ReadUint8(uv_comp,mfh.texcoord_channels);
uint32 uv_total=0;
for(int i=0;i<mfh.texcoord_channels;i++)
{
uv_total+=uv_comp[i];
uv_data[i]=new float[uv_comp[i]*mfh.vertices_number*sizeof(float)];
}
for(int i=0;i<mfh.texcoord_channels;i++)
{
dis.ReadFloat(uv_data[i],uv_comp[i]*mfh.vertices_number);
if(uv_comp[i]==1)
uv_vb[i]=new VB1f(mfh.vertices_number,uv_data[i]);
else
if(uv_comp[i]==2)
uv_vb[i]=new VB2f(mfh.vertices_number,uv_data[i]);
else
uv_vb[i]=nullptr;
}
}
if(mfh.vertices_number>0xFFFF)
{
VB4u32 *face=new VB4u32(mfh.faces_number*3);
dis.ReadFully(face->Begin(),face->GetBytes());face->End();
md.va->SetIndex(face);
}
else
{
VB4u16 *face=new VB4u16(mfh.faces_number*3);
dis.ReadFully(face->Begin(),face->GetBytes());face->End();
md.va->SetIndex(face);
}
fis.Close();
for(int i=0;i<mtd->tex_count;i++)
{
MaterialTextureData *mt=&(mtd->tex_list[i]);
md.va->SetVertexBuffer(VertexBufferType(mt->type-mtcDiffuse+vbtDiffuseTexCoord),uv_vb[mt->uvindex]);
}
md.r=new Renderable(md.va,mtl);
for(int i=0;i<mtd->tex_count;i++)
{
MaterialTextureData *mt=&(mtd->tex_list[i]);
md.r->SetTexCoord(mt->type,VertexBufferType(mt->type-mtcDiffuse+vbtDiffuseTexCoord));
}
SAFE_CLEAR_OBJECT_ARRAY(uv_data,mfh.texcoord_channels);
//SAFE_CLEAR_OBJECT_ARRAY(uv_vb,mfh.texcoord_channels);
SAFE_CLEAR_ARRAY(uv_comp);
md.r->AutoCreateShader(true,nullptr,filename);
return(true);
}
}//namespace graph
}//namespace hgl

View File

@ -0,0 +1,207 @@
#include<hgl/graph/SceneDB.h>
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/Material.h>
#include<hgl/graph/Mesh.h>
#include<hgl/io/FileInputStream.h>
#include<hgl/io/DataInputStream.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/LogInfo.h>
namespace hgl
{
namespace graph
{
bool LoadMaterialFile(MaterialData &md,const OSString &filename);
bool LoadMeshFile(MeshFileHeader &md,const OSString &filename,MaterialData *md_list);
namespace
{
class SceneLoader
{
SceneDB *db;
SceneNode *root_node;
OSString main_filename;
uint32 tex_count=0;
private:
uint32 mtl_count=0;
MaterialData *md_list;
void LoadMaterial()
{
md_list=new MaterialData[mtl_count];
for(int i=0;i<mtl_count;i++)
LoadMaterialFile(md_list[i],main_filename+OS_TEXT(".")+OSString(i)+OS_TEXT(".material"));
}
private:
uint32 mesh_count=0;
MeshFileHeader *mesh_list;
void LoadMesh()
{
mesh_list=new MeshFileHeader[mesh_count];
for(int i=0;i<mesh_count;i++)
LoadMeshFile(mesh_list[i],main_filename+OS_TEXT(".")+OSString(i)+OS_TEXT(".mesh"),md_list);
}
private:
void AddMesh(SceneNode *node,const uint32 *mesh_index,const uint32 count)
{
//for(int i=0;i<count;i++)
// node->Add(mesh_list[mesh_index[i]]);
}
bool LoadScene(SceneNode *node,io::DataInputStream *dis)
{
UTF8String node_name;
if(!dis->ReadUTF8String(node_name))
RETURN_FALSE;
//bounding box
{
float box[6];
if(dis->ReadFloat(box,6)!=6)
RETURN_FALSE;
vec bb_min(box[0],box[1],box[2],1);
vec bb_max(box[3],box[4],box[5],1);
AABB bb(bb_min,bb_max);
node->SetBoundingBox(bb);
}
//matrix
{
Matrix4f mat;
if(dis->ReadFloat((float *)&mat,16)!=16)
RETURN_FALSE;
node->SetLocalMatrix(mat);
}
//mesh
{
uint32 count;
if(!dis->ReadUint32(count))
RETURN_FALSE;
uint32 *index=new uint32[count];
if(dis->ReadUint32(index,count)!=count)
{
delete[] index;
RETURN_FALSE;
}
AddMesh(node,index,count);
delete[] index;
}//mesh
//children
{
uint32 children_count;
if(!dis->ReadUint32(children_count))
RETURN_FALSE;
for(uint32 i=0;i<children_count;i++)
{
SceneNode *sub_node=new SceneNode;
if(!LoadScene(sub_node,dis))
{
delete sub_node;
RETURN_FALSE;
}
node->Add(sub_node);
}
}//children
return(true);
}
public:
SceneLoader(SceneDB *sdb,SceneNode *rn)
{
db=sdb;
root_node=rn;
}
bool Load(const OSString &mn,io::DataInputStream *dis)
{
main_filename=mn;
uint8 flag[6],ver;
if(dis->ReadFully(flag,6)!=6)
RETURN_FALSE;
if(memcmp(flag,"SCENE\x1A",6))
RETURN_FALSE;
if(!dis->ReadUint8(ver))
RETURN_FALSE;
if(ver!=1)
RETURN_FALSE;
if(!dis->ReadUint32(mtl_count))
RETURN_FALSE;
if(!dis->ReadUint32(tex_count))
RETURN_FALSE;
// LoadTextures();
LoadMaterial();
if(!dis->ReadUint32(mesh_count))
RETURN_FALSE;
LoadMesh();
return LoadScene(root_node,dis);
}
};//class SceneLoader
}//namespace
SceneNode *LoadScene(const OSString &fullname,SceneDB *db)
{
io::OpenFileInputStream fis(fullname);
if(!fis)
return(nullptr);
SceneNode *root=new SceneNode;
io::LEDataInputStream *dis=new io::LEDataInputStream(&fis);
SceneLoader sl(db,root);
const OSString filename=filesystem::ClipFileMainname(fullname);
if(!sl.Load(filename,dis))
{
delete root;
root=nullptr;
}
delete dis;
return root;
}
}//namespace graph
}//namespace hgl