現在地: メニュー >> 実践編10 >> 実践編10::3dsファイルローダ >> lib3ds編02
INDEX: lib3ds編01 << lib3ds編02 >> lib3ds編03

複数のメッシュがある場合


メッシュ(モデルのパーツ)が複数ある場合は、メッシュの数だけループすればよい。
【例】
Lib3dsFile *m_model;
Lib3dsMesh *mesh;
… …
m_model = lib3ds_file_open(modelname);
… …
glBegin(GL_TRIANGLES);
for(int mLoop = 0; mLoop < m_model->nmeshes;++mLoop)
{
	mesh = m_model->meshes[mLoop];//mLoop番目のメッシュへのポインタ
	for(int loopX = 0;loopX < mesh->nfaces;++loopX)
	{

		glVertex3f(
			mesh->vertices[ mesh->faces[loopX].index[0] ][0],
			mesh->vertices[ mesh->faces[loopX].index[0] ][1],
			mesh->vertices[ mesh->faces[loopX].index[0] ][2]
		);

		glVertex3f(
			mesh->vertices[ mesh->faces[loopX].index[1] ][0],
			mesh->vertices[ mesh->faces[loopX].index[1] ][1],
			mesh->vertices[ mesh->faces[loopX].index[1] ][2]
		);

		glVertex3f(
			mesh->vertices[ mesh->faces[loopX].index[2] ][0],
			mesh->vertices[ mesh->faces[loopX].index[2] ][1],
			mesh->vertices[ mesh->faces[loopX].index[2] ][2]
		);

	}
}
glEnd();

サンプルコード


頂点配列を使う


法線データを持たない場合は、普通にデータをコピーするだけでよい。
【例】
struct Mesh
{
	int nIndex;//インデックス数
	std::vector<float> vertex;//頂点座標格納場所
	std::vector<unsigned short> index;//インデックスデータの格納場所
};
std::vector<Mesh> eachMesh;
… …
void load3dsModel()
{
	Lib3dsFile *m_model; //モデル全体
	Lib3dsMesh *mesh; //メッシュ単位

	//モデル読み込み
	m_model = lib3ds_file_open(modelname);
	if(m_model==NULL)
	{
		std::cerr << "can't Open file\n";
		exit(0);
	}


	eachMesh.resize(m_model->nmeshes);//メッシュ分メモリ確保
	for(int loop = 0; loop < m_model->nmeshes;++loop)
	{
		mesh = m_model->meshes[loop];//mLoop番目のメッシュへのポインタ
		
		//頂点データの取り出し
		eachMesh[loop].vertex.resize(mesh->nvertices*3);//頂点数*3要素
		memcpy(&eachMesh[loop].vertex[0],&mesh->vertices[0][0],sizeof(float)*mesh->nvertices*3);

		//インデックスデータの取り出し
		eachMesh[loop].nIndex = (mesh->nfaces*3);
		eachMesh[loop].index.resize( eachMesh[loop].nIndex );//面の数*3頂点分=総インデックス数
		for(int iloop = 0;iloop < mesh->nfaces;++iloop)
		{
			memcpy(&eachMesh[loop].index[iloop*3],&mesh->faces[iloop].index[0],sizeof(unsigned short)*3);
		}		
		
	}
	lib3ds_file_free(m_model);
}

… …
//描画
glEnableClientState(GL_VERTEX_ARRAY);
for(int loop = 0; loop < MeshNum;++loop)
{
	glVertexPointer(3, GL_FLOAT, 0,&eachMesh[loop].vertex[0]);
	glDrawElements(GL_TRIANGLES,eachMesh[loop].nIndex, GL_UNSIGNED_SHORT, &eachMesh[loop].index[0]);
}
glDisableClientState(GL_VERTEX_ARRAY);

… …
※C++「vector」を使用。

【注意点】

複数のメッシュになると、
その中には、空っぽのメッシュが存在したりする。
そこで、各メッシュで面の数が「0」の場合スキップする。
【例】
for(int loop = 0; loop < m_model->nmeshes;++loop)
{
	mesh = m_model->meshes[loop];//mLoop番目のメッシュへのポインタ
	if(mesh->nfaces == 0)
	{
		eachMesh[loop].flag = 1;
		continue;//スキップ
	}
	… …	
}
… …
//描画
glEnableClientState(GL_VERTEX_ARRAY);
for(int loop = 0; loop < MeshNum;++loop)
{
	if( eachMesh[loop].flag == 1){ continue;}
		… …
}
glDisableClientState(GL_VERTEX_ARRAY);

サンプルコード

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます