Archived

This topic is now archived and is closed to further replies.

mstein

model drawing optimization

Recommended Posts

lets say i am importing my 3d data from .3ds model and then i draw it like this:
  
glPushMatrix();
	glColor3f(1.0,0.0,0.0);
	glBegin(GL_TRIANGLES);
	for(int i=0; i<numFaces; i++){
		for(int j=0; j<3; j++){
			glVertex3f(vertices[tris[i].data[j]].x,vertices[tris[i].data[j]].y,vertices[tris[i].data[j]].z);
		}
	}
	glEnd();
glPopMatrix();
  
My question is, what is the best way to optimize this. A display list, using vertex arrays, triangle strips. I guess I do not understand how when parsing the data from the model file you could create a triangle strip. The only way i see to optimize this is by using a display list . . . any help.

Share this post


Link to post
Share on other sites
a quick and easy recommendation would be to create a reference pointer like this:

vertex* vertex_ref=vertices[tris.data[j]];

and assign it once for each point, then you don''t have to do all those array lookups for each point in glVertex3f(), just dereference vertex_ref->x, y and z. You should see a noticable improvement. This will also keep you from having to change your underlying 3d mesh data structures.



Cheers

Share this post


Link to post
Share on other sites
That is a silly micro-optimization, check out the following code and the corresponding gcc asm output (compiled with -O3) (note it still performs the array offset):


      
void one(void)
{

for(int i=0;i<64;i++)
{
for(int j=0;j<3;j++)
{
vertex* vertex_ref = &verts[tris[i].data[j]];
printf("%f %f %f\n",vertex_ref->x,vertex_ref->y,vertex_ref->z);
}
}

}




void two(void)
{
for(int i=0;i<64;i++)
{
for(int j=0;j<3;j++)
printf("%f %f %f\n",verts[tris[i].data[j]].x,verts[tris[i].data[j]].y,verts[tris[i].data[j]].z);
}

}



  

.globl _two__Fv
.def _two__Fv; .scl 2; .type 32; .endef
_two__Fv:
pushl %ebp
movl %esp,%ebp
subl $28,%esp
pushl %edi
pushl %esi
pushl %ebx
xorl %eax,%eax
.p2align 4,,7
L18:
leal 1(%eax),%edi
leal (%eax,%eax,2),%eax
leal _tris(,%eax,4),%ebx
movl $2,%esi
.p2align 4,,7
L22:
addl $-4,%esp
movl (%ebx),%eax
leal (%eax,%eax,2),%eax
sall $2,%eax
subl $8,%esp
flds _verts+8(%eax)
fstpl (%esp)
subl $8,%esp
flds _verts+4(%eax)
fstpl (%esp)
subl $8,%esp
flds _verts(%eax)
fstpl (%esp)
pushl $LC0
call _printf
addl $32,%esp
addl $4,%ebx
decl %esi
jns L22
movl %edi,%eax
cmpl $63,%eax
jle L18
leal -40(%ebp),%esp
popl %ebx
popl %esi
popl %edi
leave
ret
.def ___main; .scl 2; .type 32; .endef
LC1:
.ascii "\12\0"
.align 4
.globl _one__Fv
.def _one__Fv; .scl 2; .type 32; .endef
_one__Fv:
pushl %ebp
movl %esp,%ebp
subl $28,%esp
pushl %edi
pushl %esi
pushl %ebx
xorl %eax,%eax
.p2align 4,,7
L6:
leal 1(%eax),%edi
leal (%eax,%eax,2),%eax
leal _tris(,%eax,4),%ebx
movl $2,%esi
.p2align 4,,7
L10:
movl (%ebx),%eax
leal (%eax,%eax,2),%eax
sall $2,%eax
addl $-4,%esp
subl $8,%esp
flds _verts+8(%eax)
fstpl (%esp)
subl $8,%esp
flds _verts+4(%eax)
fstpl (%esp)
subl $8,%esp
flds _verts(%eax)
fstpl (%esp)
pushl $LC0
call _printf
addl $32,%esp
addl $4,%ebx
decl %esi
jns L10
movl %edi,%eax
cmpl $63,%eax
jle L6
leal -40(%ebp),%esp
popl %ebx
popl %esi
popl %edi
leave
ret


The moral: you will not see any speedup, but it might help with readability if that is a problem.

As for optimizations, display lists or vertex arrays will definitely help. Since you've already got the data in arrays it will be nearly trivial to convert to using vertex arrays (I won't do it here and deprive you of the fun of looking in the Red Book, OpenGL specs or googling for a tutorial).

I wouldn't suggest worrying about trying to stripify (ie convert to triangle strips) the mesh just yet, there will almost certainly be other areas of your engine which need optimization first.


[edited by - JuNC on March 7, 2003 8:31:09 AM]

[edited by - JuNC on March 7, 2003 8:31:47 AM]

Share this post


Link to post
Share on other sites
JuNC was right, that was a silly post. I was thinking of my own code which also is looping through all my mesh objects and dereferencing those as well as the vertex array. By using a reference pointer there, I got a huge speed up (800->2200 fps), but that doesn't really apply to mstein's case. Sorry sorry for the confusion.

my code example:


    
for(obj_counter=0; obj_counter<objects.size(); obj_counter++)
mesh_ref=objects[obj_counter];
{
if(mesh_ref->has_texture)
{
tex_res=(texture_resource*)rm->get_resource(mesh_ref->material_ID);
glBindTexture(GL_TEXTURE_2D, tex_res->activate());

glBegin(GL_TRIANGLES);
for(tri_counter=0;tri_counter<mesh_ref->num_of_faces ;tri_counter++)
{
ti=mesh_ref->faces[tri_counter].text_index[0];
vi=mesh_ref->faces[tri_counter].vert_index[0];
glNormal3fv(mesh_ref->normals[vi].points);
glTexCoord2fv(mesh_ref->tex_verts[ti].points);
glVertex3fv(mesh_ref->verts[vi].points);



cheers

[edited by - scourage on March 11, 2003 6:09:06 PM]

Share this post


Link to post
Share on other sites
Kind of OT but ...

Interestingly Intel are recommending that you use the array lookup method rather than a pointer. Apparently the CPU (P3 / P4)is friendlier to you that way!

Share this post


Link to post
Share on other sites