Jump to content
  • Advertisement
Sign in to follow this  
CRACK123

OpenGL Matrix question

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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:

[source
for (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...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!