Here is the primary part of my code:
Header:
typedef struct Texture_t
{
char Filename[64];
char Name[64];
};
typedef struct Reference_t
{
char Filename[64];
char Name[64];
long lStart; // Faces
long lNum;
long lStartVert;
long lNumVert;
long Id;
long Sid;
t_PolygonMode Type;
bool bShow;
};
class t_MdlHeader
{
public:
unsigned int Version;
char Modelname[64];
long lNumTextures;
long lNumVerts;
long lNumFaces;
long lNumReferences;
long lNumNodes;
long lNumFixedNodes;
long lNumFrames;
long lNumSequences;
long lNumBControllers;
// Vertex array data
long *VertNodeIdArray;
float *VertLengthArray;
t_Vec3f *VertPosArray;
t_Vec3f *VertOrigPosArray;
t_Vec2f *VertTexCoordArray;
t_Vec3f *VertNormalArray;
// Model data
Texture_t *Textures;
Reference_t *References;
t_GlTexture *TextureData;
bool bLoaded;
bool Load(const char *Filename);
void Destroy();
void Render();
void Update();
t_MdlHeader();
};
Loading
bool t_MdlHeader::Load(const char *Filename)
{
if(!m_Render.bInstalled) return false;
FILE *f;
char Temp[64];
long l;
m_Console.Message(“Model: Loading model: %s”, Filename);
// Make the global filename and global foldername
sprintf(Temp, “models/%s/%s.mdl”, Filename, Filename);
f = fopen(Temp, “rb”);
if(!f)
{
m_Console.Error(false, “Couldn’t open model file!”);
return false;
}
// Basic info
fread(&Version, sizeof(unsigned int), 1, f);
fread(Modelname, sizeof(char), 64, f);
if(Version != 1)
{
m_Console.Error(false, “Invalid model version!”);
return false;
}
// Elements number info
fread(&lNumTextures, sizeof(long), 1, f);
fread(&lNumVerts, sizeof(long), 1, f);
fread(&lNumFaces, sizeof(long), 1, f);
fread(&lNumReferences, sizeof(long), 1, f);
fread(&lNumNodes, sizeof(long), 1, f);
fread(&lNumFixedNodes, sizeof(long), 1, f);
fread(&lNumFrames, sizeof(long), 1, f);
fread(&lNumSequences, sizeof(long), 1, f);
fread(&lNumBControllers, sizeof(long), 1, f);
// Allocate memory for vertexs
VertNodeIdArray = new long[lNumVerts];
VertLengthArray = new float[lNumVerts];
VertPosArray = new t_Vec3f[lNumVerts];
VertOrigPosArray = new t_Vec3f[lNumVerts];
VertTexCoordArray = new t_Vec2f[lNumVerts];
VertNormalArray = new t_Vec3f[lNumVerts];
if(VertNodeIdArray==NULL | | VertLengthArray==NULL | | VertPosArray==NULL | |
VertOrigPosArray==NULL | | VertTexCoordArray==NULL | | VertNormalArray==NULL)
{
m_Console.Error(false, “Not enough memory for storing vertices.”);
return false;
}
// Allocate memory for elements
Textures = new Texture_t[lNumTextures];
Faces = new Face_t[lNumFaces];
References = new Reference_t[lNumReferences];
Nodes = new Node_t[lNumNodes];
FixedNodes = new FixedNode_t[lNumFixedNodes];
Frames = new Frame_t[lNumFrames];
Sequences = new Sequence_t[lNumSequences];
TextureData = new t_GlTexture[lNumTextures];
if(Textures==NULL | | Faces==NULL | | References==NULL | | Nodes==NULL | |
FixedNodes==NULL | | Frames==NULL | | Sequences==NULL | | TextureData==NULL)
{
m_Console.Error(false, “Not enough memory for storing elements.”);
return false;
}
// Load data
fread(Textures, sizeof(Texture_t), lNumTextures, f);
fread(VertNodeIdArray, sizeof(long), lNumVerts, f);
fread(VertPosArray, sizeof(t_Vec3f), lNumVerts, f);
fread(VertTexCoordArray, sizeof(t_Vec2f), lNumVerts, f);
fread(VertNormalArray, sizeof(t_Vec3f), lNumVerts, f);
fread(Faces, sizeof(Face_t), lNumFaces, f);
fread(References, sizeof(Reference_t), lNumReferences, f);
fread(Nodes, sizeof(Node_t), lNumNodes, f);
fread(FixedNodes, sizeof(FixedNode_t), lNumFixedNodes, f);
fread(Frames, sizeof(Frame_t), lNumFrames, f);
fread(Sequences, sizeof(Sequence_t), lNumSequences, f);
fread(BControllers, sizeof(BController_t), lNumBControllers, f);
fclose(f);
// Load textures
for(l=0; l<lNumTextures; l++)
{
sprintf(Temp, “models/%s/%s”, Filename, Textures[l].Filename);
TextureData[l].LoadTGA(Temp, true);
}
// Loaded
bLoaded = true;
return true;
}
Rendering
void t_MdlHeader::Render()
{
if(bLoaded==false) return;
if(m_Render.bInstalled==false) return;
// Lighting
glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, Light0Dif);
glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_AMBIENT, Light1Amb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, Light1Dif);
glLightfv(GL_LIGHT1, GL_POSITION, Light1Pos);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
if(mouse_b & 1)
{
glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
glRotatef(fModelRotate, 0.0f, 0.0f, 1.0f);
}
else
{
glLoadIdentity();
glTranslatef(5.0f, -10.0f, -3.5f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
}
static long n, m, k;
Reference_t *pRef;
t_GlTexture *pTextr;
t_GlTexture *pShine;
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, VertPosArray);
glTexCoordPointer(2, GL_FLOAT, 0, VertTexCoordArray);
glNormalPointer(GL_FLOAT, 3, VertNormalArray);
glLockArraysEXT(0, lNumVerts);
for(n=0; n<lNumReferences; n++)
{
if(References[n].bShow==false) n++;
switch( References[n].Type )
{
case SOLID:
pRef = &References[n];
pTextr = &TextureData[pRef->Id];
glBindTexture(GL_TEXTURE_2D, *pTextr->iData);
glDrawArrays(GL_TRIANGLES, pRef->lStartVert, pRef->lStartVert+pRef->lNumVert);
break;
case SHINE:
pRef = &References[n];
pTextr = &TextureData[pRef->Id];
pShine = &TextureData[pRef->Sid];
glBindTexture(GL_TEXTURE_2D, *pTextr->iData);
glDrawArrays(GL_TRIANGLES, pRef->lStartVert, pRef->lStartVert+pRef->lNumVert);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D, *pShine->iData);
glDrawArrays(GL_TRIANGLES, pRef->lStartVert, pRef->lStartVert+pRef->lNumVert);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
break;
case BLENDED:
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
pRef = &References[n];
pTextr = &TextureData[pRef->Id];
glBindTexture(GL_TEXTURE_2D, *pTextr->iData);
glDrawArrays(GL_TRIANGLES, pRef->lStartVert, pRef->lStartVert+pRef->lNumVert);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glEnable(GL_LIGHTING);
break;
}
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glUnlockArraysEXT();
glDisable(GL_LIGHTING);
}