# OpenGL Matrix question

This topic is 5022 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I am trying to sort my model by material. However currently I render the code using the following -
	for(int z = 0; z < _3ds_->numNodes; z++)
{
NodeInfo *node = &_3ds_->pNodes[z];

glMultMatrixf((float *)&node->matrix);
glTranslatef(node->pivot[0], node->pivot[1], node->pivot[2]);

for(int i = 0; i < _3ds_->numGroups; i++)
{
Groups *g = &_3ds_->pGroups;

int size = g->numFaces;
glMultMatrixf((float *)&g->matrix);

for(int j = 0 ; j < size; j++)
{
glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&g->faceList[j].material.ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&g->faceList[j].material.diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&g->faceList[j].material.specular);
glMaterialfv(GL_FRONT, GL_SHININESS, (float *)&g->faceList[j].material.shininess);

unsigned int texId = tex.GetTextureID(g->faceList[j].material.textureName);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, g->faceList[j].material.texId);

glBegin(GL_TRIANGLES);
glNormal3fv((float *)&g->faceList[j].normal);
for(int k = 0; k < 3; k++)
{
glTexCoord2fv( (float *)&_3ds_->texel[g->faceList[j].face[k]]);
glNormal3fv((float *)&g->normals[3 * j + k]);
glVertex3fv((float *)&_3ds_->verts[g->faceList[j].face[k]]);

}
glEnd();
}

}
}


However if I sort using the material the matrix transformation for each vertex will also change and I will need to keep a set of transformation matrix per vertex. Is there a way to send opengl information about matrix transformation per vertex when doing VBO's or do I need to multiply each vertex by the matrix before storing it to send a batch of vertices sorted on material basis for rendering. Thanks

##### Share on other sites
I'd suggest you split your model up into sub-meshes BEFORE executing your main loop. This pre-processing will significantly improve your performance. That way, you just need to specify a transform for each batch of vertices rather than per-vertex.

Basically just throw the triangles with the same material into the same sub-mesh. Then your code will look something like follows:

[sourcefor (int z = 0; z < preprocessednodes->numNodes; z++){  PPNodeInfo *node = preprocessednodes->pNodes[z];  glPushMatrix();  glMultMatrixf((float *)&node->matrix);  glTranslatef(node->pivot[0], node->pivot[1], node->pivot[2]);  for (int i = 0; i < node->numSubMeshes; i++)  {    // setup the material for this sub-mesh    glMaterialfv(GL_FRONT, GL_AMBIENT, (float *)&node->submesh.material.ambient);    glMaterialfv(GL_FRONT, GL_DIFFUSE, (float *)&node->submesh.material.diffuse);    glMaterialfv(GL_FRONT, GL_SPECULAR, (float *)&node->submesh.material.specular);    glMaterialfv(GL_FRONT, GL_SHININESS, (float *)&node->submesh.material.shininess);    // setup the texture etc...       // now render your entire sub-mesh    glBegin(GL_TRIANGLES);    for (j = 0; j < size; j++)    {      glTexCoord2fv( (float *)&_3ds_->texel[g->faceList[j].face[0]]);      glNormal3fv((float *)&g->normals[3 * j + 0]);      glVertex3fv((float *)&_3ds_->verts[g->faceList[j].face[0]]);      glTexCoord2fv( (float *)&_3ds_->texel[g->faceList[j].face[1]]);      glNormal3fv((float *)&g->normals[3 * j + 1]);      glVertex3fv((float *)&_3ds_->verts[g->faceList[j].face[1]]);      glTexCoord2fv( (float *)&_3ds_->texel[g->faceList[j].face[2]]);      glNormal3fv((float *)&g->normals[3 * j + 2]);      glVertex3fv((float *)&_3ds_->verts[g->faceList[j].face[2]]);    }     glEnd();   glPopMatrix(); }	}

There are TONS of optimizations you could do here as well.

1.) instead of outright rendering your sub-meshes as you render the mesh, you could add your sub-mesh to a linked list (based on material). Then traverse each linked list, setup the material once and render the submeshes in the linked list, setting up the material only once per sub-mesh. This will reduce material state change even between multiple 'parent' meshes.

2.) Tristrip your sub-meshes (for NVidia cards), or optimize your triangle indices such that they you get good triangle cache hits (mainly for ATI cards)

3.) Put your sub-meshes in a display list or in a vertex-array/VBO.

4.) You could put your translate into your matrix (since the matrix contains a translation component anyway!) ie.
glMultMatrixf((float *)&node->matrix);
glTranslatef(node->pivot[0], node->pivot[1], node->pivot[2]);
would just become:
glMultMatrixf((float *)&node->matrix);

I'm sure there's more, but that's just it off the top of my head...

1. 1
2. 2
Rutin
18
3. 3
4. 4
5. 5

• 26
• 11
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633701
• Total Posts
3013443
×