Ok, here's my code. I'll explain it as best as I can at the end.
Object.h
Code:
#define MAX_OBJECTS 5000
...
typedef struct
{
//file hander stuff:
int numframes;
int numpoints;
int numtris;
//int numtexcoords;
///int numglcmds;
//int framesize;
/*int texwidth, texheight;
int currentframe;
int nextframe;
float interpolate;
mesh *triindex;
texcoord *st;
vector3d *points;
//vector3d *normals;*/
MS3DHeader *pHeader;
MS3DVertex *pVertex;
MS3DTriangle *pTriangle;
MS3DMaterial *pMaterial;
MS3DJoint *pJoint;
MS3DKeyframe *pFrame;
int m_numMeshes;
Mesh *m_pMeshes;
int m_numMaterials;
Material *m_pMaterials;
int m_numTriangles;
Triangle *m_pTriangles;
int m_numVertices;
Vertex *m_pVertices;
//object properties:
char name;
char *filename;
int textype;
int type;
int repeatx;
int repeaty;
bool isenvironmentmapped;
//physical attributes:
float m; //mass
float t; //time
float speed; //meters per second
vector3d accel; //acceleration
vector3d disp; //displacment
vector3d pos; //position
vector3d dir; //direction
vector3d scale; //scale
vector3d v; //velocity
matrix_4x4_type matrix; // Object matrix
}objectdata, *obj;
class object
{
public:
object();
virtual ~object();
void position(obj objectP,float x,float y,float z);
void translate(obj objectP,float x,float y,float z);
void translateW(obj objectP,float x,float y,float z);
void rotate(obj objectP,int x,int y,int z);
void scale(obj objectP,int x,int y,int z);
void calculatenormal(float *p1, float *p2, float *p3);
void calculatenormals(obj &objectP);
char createobject(int type, char *fName, char *texfName1, char *texfName2, int textype, int repeatx, int repeaty,
float px, float py, float pz,
float rx, float ry, float rz,
float sx, float sy, float sz);
void renderanimated(obj objectP, int startframe, int endframe, float percent);
void renderobjects();
};
extern objectdata objectP[MAX_OBJECTS];
Object.cpp (excerpt)
Code:
int num_objects = 0;
UINT bufferid = -1;
int i, j;
objectdata objectP[MAX_OBJECTS];
...
char object::createobject(int type, char *fName, char *texfName1, char *texfName2, int textype, int repeatx, int repeaty,
float px, float py, float pz,
float rx, float ry, float rz,
float sx, float sy, float sz)
{
objectP[num_objects].filename = fName;
objectP[num_objects].type = type;
objectP[num_objects].textype = textype;
objectP[num_objects].repeatx = repeatx;
objectP[num_objects].repeaty = repeaty;
objectP[num_objects].pos.x = px;
objectP[num_objects].pos.y = py;
objectP[num_objects].pos.z = pz;
objectP[num_objects].scale.x = sx;
objectP[num_objects].scale.y = sy;
objectP[num_objects].scale.z = sz;
/*if (objectP[num_objects].type!=0)
{
_ceCollision->createBbox(objectP[num_objects].pos.x, objectP[num_objects].pos.y, objectP[num_objects].pos.z,
objectP[num_objects].min.x, objectP[num_objects].min.y, objectP[num_objects].min.z,
objectP[num_objects].max.x, objectP[num_objects].max.y, objectP[num_objects].max.z);
}*/
if(type==0)
{
if(loadMS3D(&objectP[num_objects], fName)==NULL)
{
//TODO: Add Abort,Retry,Ignore dialouge box on error.
printf("ERROR! Unable to load MS3D object.\n");
return(1);//keep going anyway. tmp.
}
if (textype == 0)
{
objectP[num_objects].m_pMaterials->m_texture = CreateModelTextureJPG(texfName1);
objectP[num_objects].m_pMaterials->m_texture1 = CreateModelTextureJPG(texfName2);
}
else if(textype == 1)
{
objectP[num_objects].m_pMaterials->m_texture = CreateModelTextureDDS(texfName1);
objectP[num_objects].m_pMaterials->m_texture1 = CreateModelTextureDDS(texfName2);
}
else if(textype == 2)
glDisable(GL_TEXTURE_2D);
}
MatrIdentity_4x4(objectP[num_objects].matrix);
position(&objectP[num_objects], px, py, pz);
rotate(&objectP[num_objects], rx, ry, rz);
scale(&objectP[num_objects], sx, sy, sz);
computeTangentsAndBinormals(&objectP[num_objects]);
num_objects++;
return (1);
}
Modified MS3D draw function (to support loading method):
Code:
int index[3];
void drawMS3D(obj objectP, float scaleX, float scaleY)
{
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
GLboolean texEnabled = glIsEnabled( GL_TEXTURE_2D );
// Draw by group
for ( int i = 0; i < objectP->m_numMeshes; i++ )
{
int materialIndex = objectP->m_pMeshes[i].m_materialIndex;
if ( materialIndex >= 0 )
{
glMaterialfv( GL_FRONT, GL_AMBIENT, objectP->m_pMaterials[materialIndex].m_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, objectP->m_pMaterials[materialIndex].m_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, objectP->m_pMaterials[materialIndex].m_specular );
glMaterialfv( GL_FRONT, GL_EMISSION, objectP->m_pMaterials[materialIndex].m_emissive );
glMaterialf( GL_FRONT, GL_SHININESS, objectP->m_pMaterials[materialIndex].m_shininess );
if ( objectP->m_pMaterials[materialIndex].m_texture > 0 )
{
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, objectP->m_pMaterials[materialIndex].m_texture );
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, objectP->m_pMaterials[materialIndex].m_texture1 );
}
else
glDisable( GL_TEXTURE_2D );
}
else
{
// Material properties?
glDisable( GL_TEXTURE_2D );
}
glBegin( GL_TRIANGLES );
{
for ( int j = 0; j < objectP->m_pMeshes[i].m_numTriangles; j++ )
{
int triangleIndex = objectP->m_pMeshes[i].m_pTriangleIndices[j];
const Triangle *pTri = &objectP->m_pTriangles[triangleIndex];
index[0] = pTri->m_vertexIndices[0];
glNormal3fv( pTri->m_vertexNormals[0] );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, pTri->m_s[0]*scaleX, pTri->m_t[0]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[0]*scaleX, pTri->m_t[0]*scaleY );
glVertex3fv( objectP->m_pVertices[index[0]].m_location );
index[1] = pTri->m_vertexIndices[1];
glNormal3fv( pTri->m_vertexNormals[1] );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, pTri->m_s[1]*scaleX, pTri->m_t[1]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[1]*scaleX, pTri->m_t[1]*scaleY );
glVertex3fv( objectP->m_pVertices[index[1]].m_location );
index[2] = pTri->m_vertexIndices[2];
glNormal3fv( pTri->m_vertexNormals[2] );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, pTri->m_s[2]*scaleX, pTri->m_t[2]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[2]*scaleX, pTri->m_t[2]*scaleY );
glVertex3fv( objectP->m_pVertices[index[2]].m_location );
}
}
glEnd();
}
if ( texEnabled )
glEnable( GL_TEXTURE_2D );
else
glDisable( GL_TEXTURE_2D );
for(i=0; i<objectP->m_numVertices; i++)
{
_ceShader->attribute3fv(program[4], "rm_Tangent", objectP->m_pVertices[i].m_tangent);
_ceShader->attribute3fv(program[4], "rm_Binormal", objectP->m_pVertices[i].m_binormal);
}
}
Ok, first of all, the header struct contains pointers to MS3D data, loaded from the file, as well as engine variables. This struct is used as an array, declared by the line objectdata objectP[MAX_OBJECTS];. In the object create function, this array struct's variables are set by arguments taken from the function. The array index number starts at 0, and is increased at the end of the function. So every time this function is called, a new array index's struct values are set. For the drawing of the MS3D model, everything is the same as it would be with a single-model system, except the data (verticies, filenames, etc) are all called through the object class as pointers to the main MS3D struct's.
Iv'e posted quite a bit of code here, and the best explination I can come up with.
It shouldn't be too hard to get somthing like this working.
-psychopath