「.Xを読み込んでみる3(読み込み編)」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>では実際にXファイルを読み込んでみます。<br />
今回は読み込み編という事で3角ポリゴンのみです。<br /></strong><a href="http://www.geocities.co.jp/Playtown-Spade/7188/"><strong>http://www.geocities.co.jp/Playtown-Spade/7188/</strong></a><strong><br />
こちらのデータを使わせて頂いています。<br />
事前に3角ポリゴンに変換してテクスチャを PNG 形式に変換しています。</strong></p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=91&file=xload.png" /></p>
<p>PNG.h</p>
<table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td>
<p>#include "lodepng.h"</p>
<p>//テクスチャクラス<br />
class TEXTURE{<br />
protected:<br />
LodePNG_Decoder decoder;//デコーダ<br />
unsigned char* buffer;//バッファ<br />
size_t buffersize, imagesize;//サイズ<br />
public:<br />
TEXTURE();<br />
TEXTURE(const char* FileName);//コンストラクタ<br />
void LOAD_PNG(const char* FileName);//PNG読み込み<br />
unsigned char* image;//イメージポインタ<br />
unsigned int Width,Height;//画像サイズ<br />
};<br />
TEXTURE::TEXTURE(){<br />
}<br />
TEXTURE::TEXTURE(const char* FileName){<br />
LOAD_PNG(FileName);<br />
}<br />
void TEXTURE::LOAD_PNG(const char* FileName){<br />
LodePNG_Decoder_init(&decoder);<br />
//ロード<br />
LodePNG_loadFile(&buffer, &buffersize, FileName);<br />
//デコード<br />
LodePNG_decode(&decoder, &image, &imagesize, buffer,
buffersize);<br />
//幅,高さ<br />
Width = decoder.infoPng.width;Height = decoder.infoPng.height;<br />
}</p>
</td>
</tr></tbody></table><p>xfile.h</p>
<table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td>
<p>#include "PNG.h"</p>
<p>using namespace std;<br />
//3つのベクトル<br />
struct Vector3f{<br />
float x;<br />
float y;<br />
float z;<br />
}vec3d;<br />
Vector3f & operator*(Vector3f &v,float size){<br />
v.x *= size;<br />
v.y *= size;<br />
v.z *= size;<br />
return v;<br />
}<br />
//4つのベクトル<br />
struct Vector4f{<br />
float x;<br />
float y;<br />
float z;<br />
float w;<br />
}vec4d;<br />
//4つのカラー<br />
struct Color4{<br />
float r;<br />
float g;<br />
float b;<br />
float a;<br />
};<br />
//4つの反射<br />
struct Reflection4{<br />
Color4 diffuse;<br />
Color4 ambient;<br />
Color4 emission;<br />
Color4 specular;<br />
};<br />
//UV座標<br />
struct UV{<br />
float u;//u値<br />
float v;//v値<br />
}vec2d;<br />
struct Vector4I{<br />
int x;<br />
int y;<br />
int z;<br />
int w;<br />
};<br />
//ポリゴンデータ<br />
struct Triangle{<br />
Vector3f TriVer;<br />
Vector3f TriNor;<br />
UV TriUV;<br />
}Tri;<br />
//ポリゴンデータ<br />
struct Quadrangle{<br />
Vector3f QuadVer;<br />
Vector3f QuadNor;<br />
UV QuadUV;<br />
}Quad;<br />
//マテリアル構造体<br />
struct MATERIAL{<br />
string MaterialName;//マテリアル名<br />
Reflection4 MaterialColor;//反射<br />
float Shininess;//shininess<br />
string TextureName;//テクスチャ名<br />
int TexNo;//テクスチャNO.<br />
vector <Triangle> Tridata;//三角面データ<br />
vector <Quadrangle> Quaddata;//四角面データ<br />
}mtl;<br />
//モデルクラス<br />
class MODEL{<br />
protected:<br />
vector <MATERIAL> Material;<br />
vector <TEXTURE*> TexData;//テクスチャデータ<br />
vector<GLuint> TexID;//テクスチャID<br />
GLuint TexID2;<br />
TEXTURE* tex;<br />
public:<br />
MODEL();<br />
MODEL(char* FileName,int size);//コンストラクタ<br />
bool XFILE_Load(char* FileName,int size);//ロード<br />
void Draw();<br />
};<br />
MODEL::MODEL(){<br />
}<br />
MODEL::MODEL(char* FileName,int size){<br />
XFILE_Load(FileName, size);<br />
}<br />
//描画<br />
void MODEL::Draw(){<br />
glEnableClientState(GL_VERTEX_ARRAY);<br />
glEnableClientState(GL_NORMAL_ARRAY);<br />
for(int i=0;i<(signed)Material.size();i++){<br />
glPushMatrix();<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,(const GLfloat
*)&Material[i].MaterialColor.ambient);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(const GLfloat
*)&Material[i].MaterialColor.diffuse);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,(const GLfloat
*)&Material[i].MaterialColor.specular);<br />
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Material[i].Shininess);<br />
if(Material[i].TexNo>0){<br />
glEnableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glEnable(GL_TEXTURE_2D);<br />
glBindTexture(GL_TEXTURE_2D, TexID[Material[i].TexNo-1]);<br />
}else{<br />
glDisable(GL_TEXTURE_2D);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
}<br />
if(Material[i].Tridata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Tri) ,
&Material[i].Tridata[0].TriVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Tri),&Material[i].Tridata[0].TriNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Tri),
&Material[i].Tridata[0].TriUV.u);<br />
glDrawArrays(GL_TRIANGLES,0,Material[i].Tridata.size());<br />
}<br />
if(Material[i].Quaddata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Quad) ,
&Material[i].Quaddata[0].QuadVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Quad),&Material[i].Quaddata[0].QuadNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Quad),
&Material[i].Quaddata[0].QuadUV.u);<br />
glDrawArrays(GL_QUADS,0,Material[i].Quaddata.size());<br />
}<br />
glPopMatrix();<br />
}<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glDisable(GL_TEXTURE_2D);<br />
}</p>
<p>//Xファイル読み込み<br />
bool MODEL::XFILE_Load(char* FileName,int size){<br />
vector <Vector3f> Vertex;//頂点<br />
vector <Vector3f> Normal;//法線<br />
vector <UV> uv;//UV<br />
vector <int> VertexIndex;<br />
vector <int> NormalIndex;<br />
vector <int> MaterialIndex;</p>
<p> char key[255];<br />
char buf[255];<br />
//Xファイルを開いて内容を読み込む<br />
FILE* fp=NULL;<br />
fopen_s(&fp,FileName,"rt");<br />
<br />
int v1=0,v2=0,v3=0;<br />
int Count=0;<br />
bool flag=false;<br />
string str="";</p>
<p> //読み込み <br />
fseek(fp,SEEK_SET,0);<br />
while(!feof(fp))<br />
{<br />
//キーワード 読み込み<br />
ZeroMemory(key,sizeof(key));<br />
fscanf_s(fp,"%s ",key,sizeof(key));</p>
<p> if(strcmp(key,"Material")==0)<br />
{<br />
if(flag)Material.push_back(mtl);<br />
flag=true;<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//ディフューズ<br />
fscanf_s(fp,"%f;%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z,&vec4d.w);<br />
mtl.MaterialColor.diffuse=(const Color4 &)vec4d;<br />
//SHININESS <br />
fscanf_s(fp,"%f;",&mtl.Shininess);<br />
//スペキュラー <br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.specular=(const Color4 &)vec4d;<br />
//エミッシブ <br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.ambient=(const Color4 &)vec4d;</p>
<p> //テクスチャー<br />
fscanf_s(fp,"%s ",key,sizeof(key)); <br />
if(strcmp(key,"TextureFilename")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//map_Kd テクスチャー <br />
fscanf_s(fp,"%s",buf,255);<br />
mtl.TextureName=buf;<br />
str=mtl.TextureName;<br />
mtl.TextureName=str.substr(str.find_first_of('\"',0)+1,str.find_last_of('\"',255)-1);<br />
//テクスチャを作成<br />
TexData.push_back(tex);<br />
TexData[TexData.size()-1] = new TEXTURE(mtl.TextureName.c_str());;<br />
mtl.TexNo=TexData.size();<br />
TexID.push_back(TexID2);<br />
glGenTextures(1, (GLuint *)&TexID[TexData.size()-1]);<br />
glBindTexture(GL_TEXTURE_2D, TexID[TexData.size()-1]);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);<br />
<br />
glEnable(GL_TEXTURE_2D);<br />
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,TexData[TexData.size()-1]->Width,
TexData[TexData.size()-1]->Height,<br />
0,GL_RGBA, GL_UNSIGNED_BYTE, TexData[TexData.size()-1]->image);<br />
glDisable(GL_TEXTURE_2D); <br />
}<br />
}<br />
//頂点 読み込み<br />
if(strcmp(key,"Mesh")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Vertex.push_back(vec3d*(float)size);<br />
} <br />
//頂点インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy;<br />
fscanf_s(fp,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
VertexIndex.push_back(v1);<br />
VertexIndex.push_back(v2);<br />
VertexIndex.push_back(v3);<br />
} <br />
}</p>
<p> //法線 読み込み<br />
if(strcmp(key,"MeshNormals")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Normal.push_back(vec3d);<br />
}<br />
//法線インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy;<br />
fscanf_s(fp,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
NormalIndex.push_back(v1);<br />
NormalIndex.push_back(v2);<br />
NormalIndex.push_back(v3);<br />
} <br />
}</p>
<p> //テクスチャー座標 読み込み<br />
if(strcmp(key,"MeshTextureCoords")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;,",&vec2d.u,&vec2d.v);<br />
uv.push_back(vec2d);<br />
} <br />
}<br />
//マテリアルリスト<br />
if(strcmp(key,"MeshMaterialList")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//空改行<br />
fgets(buf,sizeof(buf),fp);//マテリアル数<br />
fgets(buf,sizeof(buf),fp);//リスト要素数<br />
Count=atoi(buf);<br />
for(int i=0;i<Count;i++)<br />
{<br />
fgets(buf,sizeof(buf),fp);<br />
int test=atoi(buf);<br />
MaterialIndex.push_back(test);<br />
}<br />
}<br />
}<br />
if(flag)Material.push_back(mtl);</p>
<p> fclose(fp);</p>
<p> for(int i=0;i<Material.size();i++){<br />
for(int j=0;j<VertexIndex.size();j++){<br />
if(MaterialIndex[j/3]==i){<br />
Tri.TriVer=Vertex[VertexIndex[j]];<br />
Tri.TriNor=Normal[NormalIndex[j]];<br />
Tri.TriUV=uv[VertexIndex[j]];<br />
Material[i].Tridata.push_back(Tri);<br />
}<br />
}<br />
}</p>
<p> Vertex.clear(); <br />
Normal.clear();<br />
uv.clear();<br />
VertexIndex.clear();<br />
NormalIndex.clear();</p>
<p> return true;<br />
}</p>
<p> </p>
</td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include "xfile.h"</p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>float angle=0.0f;<br />
MODEL* model;</p>
<p>void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glViewport(0,0,WIDTH,HEIGHT);<br />
glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
gluPerspective(30.0, WIDTH/HEIGHT, 0.1, 2000.0);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
gluLookAt(0.0, 500.0, 500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);</p>
<p> glRotatef(angle,1.0f,0.0f,0.0f);//回転<br />
glRotatef(angle,0.0f,1.0f,0.0f);//回転</p>
<p> model->Draw();<br />
glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
glutPostRedisplay();<br />
angle+=0.2f;<br />
}<br />
void Init(){<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glEnable(GL_BLEND);<br />
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_LIGHT0);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_CULL_FACE);<br />
glCullFace(GL_BACK);<br />
model = new MODEL("sample.x",100);<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutCreateWindow("Xローダ");<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}<br />
</p>
</td>
</tr></tbody></table><p> </p>
<p><strong>では実際にXファイルを読み込んでみます。<br />
今回は読み込み編という事で3角ポリゴンのみです。</strong><br /><a href="http://www.geocities.co.jp/Playtown-Spade/7188/"><strong>http://www.geocities.co.jp/Playtown-Spade/7188/</strong></a><br /><strong>こちらのデータを使わせて頂いています。<br />
事前にメタセコイアで3角ポリゴンに変換してテクスチャを<br />
PNG 形式に変換しています。<br />
Xファイルのテンプレートを除去しないと読み込みできません。</strong></p>
<p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=91&file=xload.png" /></p>
<p>PNG.h</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#include "lodepng.h"</p>
<p>//テクスチャクラス<br />
class TEXTURE{<br />
protected:<br />
LodePNG_Decoder decoder;//デコーダ<br />
unsigned char* buffer;//バッファ<br />
size_t buffersize, imagesize;//サイズ<br />
public:<br />
TEXTURE();<br />
TEXTURE(const char* FileName);//コンストラクタ<br />
void LOAD_PNG(const char* FileName);//PNG読み込み<br />
unsigned char* image;//イメージポインタ<br />
unsigned int Width,Height;//画像サイズ<br />
};<br />
TEXTURE::TEXTURE(){<br />
}<br />
TEXTURE::TEXTURE(const char* FileName){<br />
LOAD_PNG(FileName);<br />
}<br />
void TEXTURE::LOAD_PNG(const char* FileName){<br />
LodePNG_Decoder_init(&decoder);<br />
//ロード<br />
LodePNG_loadFile(&buffer, &buffersize, FileName);<br />
//デコード<br />
LodePNG_decode(&decoder, &image, &imagesize, buffer,
buffersize);<br />
//幅,高さ<br />
Width = decoder.infoPng.width;Height = decoder.infoPng.height;<br />
}</p>
</td>
</tr></tbody></table><p>xfile.h</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#include "PNG.h"</p>
<p>using namespace std;<br />
//3つのベクトル<br />
struct Vector3f{<br />
float x;<br />
float y;<br />
float z;<br />
}vec3d;<br />
Vector3f & operator*(Vector3f &v,float size){<br />
v.x *= size;<br />
v.y *= size;<br />
v.z *= size;<br />
return v;<br />
}<br />
//4つのベクトル<br />
struct Vector4f{<br />
float x;<br />
float y;<br />
float z;<br />
float w;<br />
}vec4d;<br />
//4つのカラー<br />
struct Color4{<br />
float r;<br />
float g;<br />
float b;<br />
float a;<br />
};<br />
//4つの反射<br />
struct Reflection4{<br />
Color4 diffuse;<br />
Color4 ambient;<br />
Color4 emission;<br />
Color4 specular;<br />
};<br />
//UV座標<br />
struct UV{<br />
float u;//u値<br />
float v;//v値<br />
}vec2d;<br />
struct Vector4I{<br />
int x;<br />
int y;<br />
int z;<br />
int w;<br />
};<br />
//ポリゴンデータ<br />
struct Triangle{<br />
Vector3f TriVer;<br />
Vector3f TriNor;<br />
UV TriUV;<br />
}Tri;<br />
//ポリゴンデータ<br />
struct Quadrangle{<br />
Vector3f QuadVer;<br />
Vector3f QuadNor;<br />
UV QuadUV;<br />
}Quad;<br />
//マテリアル構造体<br />
struct MATERIAL{<br />
string MaterialName;//マテリアル名<br />
Reflection4 MaterialColor;//反射<br />
float Shininess;//shininess<br />
string TextureName;//テクスチャ名<br />
int TexNo;//テクスチャNO.<br />
vector <Triangle> Tridata;//三角面データ<br />
vector <Quadrangle> Quaddata;//四角面データ<br />
}mtl;<br />
//モデルクラス<br />
class MODEL{<br />
protected:<br />
vector <MATERIAL> Material;<br />
vector <TEXTURE*> TexData;//テクスチャデータ<br />
vector<GLuint> TexID;//テクスチャID<br />
GLuint TexID2;<br />
TEXTURE* tex;<br />
public:<br />
MODEL();<br />
MODEL(char* FileName,int size);//コンストラクタ<br />
bool XFILE_Load(char* FileName,int size);//ロード<br />
void Draw();<br />
};<br />
MODEL::MODEL(){<br />
}<br />
MODEL::MODEL(char* FileName,int size){<br />
XFILE_Load(FileName, size);<br />
}<br />
//描画<br />
void MODEL::Draw(){<br />
glEnableClientState(GL_VERTEX_ARRAY);<br />
glEnableClientState(GL_NORMAL_ARRAY);<br />
for(int i=0;i<(signed)Material.size();i++){<br />
glPushMatrix();<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,(const GLfloat
*)&Material[i].MaterialColor.ambient);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(const GLfloat
*)&Material[i].MaterialColor.diffuse);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,(const GLfloat
*)&Material[i].MaterialColor.specular);<br />
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Material[i].Shininess);<br />
if(Material[i].TexNo>0){<br />
glEnableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glEnable(GL_TEXTURE_2D);<br />
glBindTexture(GL_TEXTURE_2D, TexID[Material[i].TexNo-1]);<br />
}else{<br />
glDisable(GL_TEXTURE_2D);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
}<br />
if(Material[i].Tridata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Tri) ,
&Material[i].Tridata[0].TriVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Tri),&Material[i].Tridata[0].TriNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Tri),
&Material[i].Tridata[0].TriUV.u);<br />
glDrawArrays(GL_TRIANGLES,0,Material[i].Tridata.size());<br />
}<br />
if(Material[i].Quaddata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Quad) ,
&Material[i].Quaddata[0].QuadVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Quad),&Material[i].Quaddata[0].QuadNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Quad),
&Material[i].Quaddata[0].QuadUV.u);<br />
glDrawArrays(GL_QUADS,0,Material[i].Quaddata.size());<br />
}<br />
glPopMatrix();<br />
}<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glDisable(GL_TEXTURE_2D);<br />
}</p>
<p>//Xファイル読み込み<br />
bool MODEL::XFILE_Load(char* FileName,int size){<br />
vector <Vector3f> Vertex;//頂点<br />
vector <Vector3f> Normal;//法線<br />
vector <UV> uv;//UV<br />
vector <int> VertexIndex;<br />
vector <int> NormalIndex;<br />
vector <int> MaterialIndex;</p>
<p> char key[255];<br />
char buf[255];<br />
//Xファイルを開いて内容を読み込む<br />
FILE* fp=NULL;<br />
fopen_s(&fp,FileName,"rt");<br />
<br />
int v1=0,v2=0,v3=0;<br />
int Count=0;<br />
bool flag=false;<br />
string str="";</p>
<p> //読み込み <br />
fseek(fp,SEEK_SET,0);<br />
while(!feof(fp))<br />
{<br />
//キーワード 読み込み<br />
ZeroMemory(key,sizeof(key));<br />
fscanf_s(fp,"%s ",key,sizeof(key));</p>
<p> if(strcmp(key,"Material")==0)<br />
{<br />
if(flag)Material.push_back(mtl);<br />
flag=true;<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//ディフューズ<br />
fscanf_s(fp,"%f;%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z,&vec4d.w);<br />
mtl.MaterialColor.diffuse=(const Color4 &)vec4d;<br />
//SHININESS <br />
fscanf_s(fp,"%f;",&mtl.Shininess);<br />
//スペキュラー <br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.specular=(const Color4 &)vec4d;<br />
//エミッシブ <br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.ambient=(const Color4 &)vec4d;</p>
<p> //テクスチャー<br />
fscanf_s(fp,"%s ",key,sizeof(key)); <br />
if(strcmp(key,"TextureFilename")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//map_Kd テクスチャー <br />
fscanf_s(fp,"%s",buf,255);<br />
mtl.TextureName=buf;<br />
str=mtl.TextureName;<br />
mtl.TextureName=str.substr(str.find_first_of('\"',0)+1,str.find_last_of('\"',255)-1);<br />
//テクスチャを作成<br />
TexData.push_back(tex);<br />
TexData[TexData.size()-1] = new TEXTURE(mtl.TextureName.c_str());;<br />
mtl.TexNo=TexData.size();<br />
TexID.push_back(TexID2);<br />
glGenTextures(1, (GLuint *)&TexID[TexData.size()-1]);<br />
glBindTexture(GL_TEXTURE_2D, TexID[TexData.size()-1]);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);<br />
<br />
glEnable(GL_TEXTURE_2D);<br />
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,TexData[TexData.size()-1]->Width,
TexData[TexData.size()-1]->Height,<br />
0,GL_RGBA, GL_UNSIGNED_BYTE, TexData[TexData.size()-1]->image);<br />
glDisable(GL_TEXTURE_2D); <br />
}<br />
}<br />
//頂点 読み込み<br />
if(strcmp(key,"Mesh")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Vertex.push_back(vec3d*(float)size);<br />
} <br />
//頂点インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy;<br />
fscanf_s(fp,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
VertexIndex.push_back(v1);<br />
VertexIndex.push_back(v2);<br />
VertexIndex.push_back(v3);<br />
} <br />
}</p>
<p> //法線 読み込み<br />
if(strcmp(key,"MeshNormals")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Normal.push_back(vec3d);<br />
}<br />
//法線インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy;<br />
fscanf_s(fp,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
NormalIndex.push_back(v1);<br />
NormalIndex.push_back(v2);<br />
NormalIndex.push_back(v3);<br />
} <br />
}</p>
<p> //テクスチャー座標 読み込み<br />
if(strcmp(key,"MeshTextureCoords")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;,",&vec2d.u,&vec2d.v);<br />
uv.push_back(vec2d);<br />
} <br />
}<br />
//マテリアルリスト<br />
if(strcmp(key,"MeshMaterialList")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//空改行<br />
fgets(buf,sizeof(buf),fp);//マテリアル数<br />
fgets(buf,sizeof(buf),fp);//リスト要素数<br />
Count=atoi(buf);<br />
for(int i=0;i<Count;i++)<br />
{<br />
fgets(buf,sizeof(buf),fp);<br />
int test=atoi(buf);<br />
MaterialIndex.push_back(test);<br />
}<br />
}<br />
}<br />
if(flag)Material.push_back(mtl);</p>
<p> fclose(fp);</p>
<p> for(int i=0;i<(signed)Material.size();i++){<br />
for(int j=0;j<(signed)VertexIndex.size();j++){<br />
if(MaterialIndex[j/3]==i){<br />
Tri.TriVer=Vertex[VertexIndex[j]];<br />
Tri.TriNor=Normal[NormalIndex[j]];<br />
Tri.TriUV=uv[VertexIndex[j]];<br />
Material[i].Tridata.push_back(Tri);<br />
}<br />
}<br />
}</p>
<p> Vertex.clear(); <br />
Normal.clear();<br />
uv.clear();<br />
VertexIndex.clear();<br />
NormalIndex.clear();</p>
<p> return true;<br />
}</p>
</td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include "xfile.h"</p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>float angle=0.0f;<br />
MODEL* model;</p>
<p>void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glViewport(0,0,WIDTH,HEIGHT);<br />
glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
gluPerspective(30.0, WIDTH/HEIGHT, 0.1, 2000.0);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
gluLookAt(0.0, 500.0, 500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);</p>
<p> glRotatef(angle,1.0f,0.0f,0.0f);//回転<br />
glRotatef(angle,0.0f,1.0f,0.0f);//回転</p>
<p> model->Draw();<br />
glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
angle+=2.0f;<br />
Sleep(1);<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glEnable(GL_BLEND);<br />
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_LIGHT0);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_CULL_FACE);<br />
glCullFace(GL_BACK);<br />
model = new MODEL("sample.x",100);<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("Xローダ");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>