152 lines
4.6 KiB
C++
152 lines
4.6 KiB
C++
#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/log/LogInfo.h>
|
|
|
|
namespace hgl
|
|
{
|
|
namespace graph
|
|
{
|
|
bool LoadMeshFile(MeshData &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
|