PDA

View Full Version : Slow...



Hylke Donker
12-09-2005, 10:43 AM
Hello,
I'm trying to render some sorta bycicle i've downloaded. But my problem is, my pc gets really slow because of it. When I render that model, my framerate is like 3 orso. I've counted the number of polygons, and it consists of 60552 polygons.
So my question is, why is my program so slow?
Is it because it has to render so many polygons, or is it manually because the way I render my scene?
Because I gues most video games that are currently out, use much more polygons to render there levels.
But I do use display lists and the depth buffer.
I just wanted to be certaint whether it's my crappy code or the number of polygons.
-- Begin edit --
My hardware:
GPU: Geforce FX 5600
CPU: AMD Athlon 2800
-- End edit --
-- Begin edit2 --
I've did some searching and found some info about my 3D card:
http://www.digit-life.com/articles2/gffx/nv31-nv34.html#p7
So if mpolygons are polygons * 10^6, then my card should be able to render atleast 18 million polygons per second.
Can anyone confirm that mpolygons are polygons * 10^6?
--End edit2 --
Thanx in advance,
Hylke

satan
12-09-2005, 03:06 PM
It looks like your code is the problem. But to help you we need more information about how you draw you model.

dorbie
12-10-2005, 12:27 AM
Did you write the code or are you running a demo someone wrote, if for example you're running an HDR demo with a tricycle that someone wrote to show off FBOs then it could grind your card to a halt but not because of something as simple as polygon count.

If you didn't write this code, (and your post makes my think you may not have), then you're really posting in the wrong forum.

Hylke Donker
12-10-2005, 01:12 AM
My source code is quite big.
The main files, where it all happens, are:
3DS.cpp (http://svn.gna.org/viewcvs/combatofdeath/trunk/3DS.cpp?rev=131&view=markup)
3DS.h (http://svn.gna.org/viewcvs/combatofdeath/trunk/3DS.h?rev=129&view=markup)
objects.cpp (http://svn.gna.org/viewcvs/combatofdeath/trunk/objects.cpp?rev=131&view=markup)
objects.h (http://svn.gna.org/viewcvs/combatofdeath/trunk/objects.h?rev=131&view=markup)

But what is basicly comes down to:

objects.cpp:

void Object::LoadModel()
{
[..]
model->RenderModel(); // Make display lists and stuff

listindex = glGenLists(1);
glNewList(listindex, GL_COMPILE);
glTranslatef(pos.at(0), pos.at(1), pos.at(2));
if(! RotateDefault1)
glRotatef(rotate.at(0), 1.0, 0.0, 0.0);
if(! RotateDefault2)
glRotatef(rotate.at(1), 0.0, 1.0, 0.0);
if(! RotateDefault3)
glRotatef(rotate.at(2), 0.0, 0.0, 1.0);
if(! ScaleDefault)
glScalef(scale.at(0), scale.at(1), scale.at(2));
model->RenderModel(); //Calls the function RenderModel from the class Model, and not the class Object
glEndList();
[..]
}

[..]

void Object::RenderModel() //This function differs from the function RenderMode in the class Object
{
if(TypeModel == OBJECT_MODEL_TYPE_3DS)
{
glPushMatrix();
glCallList(listindex);
glPopMatrix();
}
}3DS.cpp:

void Model::RenderModel()
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);

if(file->lights) //if we have lights in the model
{
EnableLights(); //enable all lights
glCallList(lightListIndex); //set lights.
}

Lib3dsNode *nodes = file->nodes;
if(nodes != 0)
for(nodes = file->nodes;nodes != 0;nodes = nodes->next) // Render all nodes <== gotta improve this
RenderUsingNodes(nodes);
else
RenderWithoutNodes();


if(file->lights)
DisableLights(); // disable lighting, we don't want it have it enabled longer than necessary
[..]
glDisable(GL_CULL_FACE);
glShadeModel(GL_FLAT);
}

[..]

void Model::RenderUsingNodes(Lib3dsNode *node)
{
[..]
if(! node->user.d) //Wheter we have a list or not, if not we're gonna create one
{
[..]
node->user.d = glGenLists(1); //alocate memory for one list
[..]
glNewList(node->user.d, GL_COMPILE); //here we create our list
{
renderNode(mesh);
}
glEndList(); // end of list
}
if(node->user.d) // if we have created a link list(with glNewList)
{
Lib3dsObjectData *tmpdat;
glPushMatrix(); //save transformation values
tmpdat = &amp;node->data.object; // get the position data
glMultMatrixf(&amp;node->matrix[0][0]); //adjust matrix according to the node
glTranslatef(-tmpdat->pivot[0], -tmpdat->pivot[1], -tmpdat->pivot[2]); //move to the right place;
glCallList(node->user.d); //render node
glPopMatrix(); //return transformation original values
}
}

void Model::RenderWithoutNodes()
{
[..]
if(! mesh->user.d) //Wheter we have a list or not, if not we're gonna create one
{
[..]
mesh->user.d = glGenLists(1); //alocate memory for one list
[..]
glNewList(mesh->user.d, GL_COMPILE); //here we create our list
{
renderNode(mesh);
}
glEndList(); // end of list
}
if(mesh->user.d) // if we have created a link list(with glNewList)
{
glPushMatrix(); //save transformation values
glMultMatrixf(&amp;mesh->matrix[0][0]); //adjust matrix according to the node

glCallList(mesh->user.d); //render node
glPopMatrix(); //return transformation original values
}
}

[..]

void Model::renderNode(Lib3dsMesh *mesh)
{

[..]
glMultMatrixf(&amp;m[0][0]); //adjust our current matrix to the matrix of the mesh
}
[..] if(mat) //if we have material
{
static GLfloat ambient[4] = { 0.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient); // Ambient color
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); //diffuse color
glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); //specular color
float shine;
shine = pow(2, 10.0 * mat->shininess);
if(shine > 128.0)
shine = 128.0;
glMaterialf(GL_FRONT, GL_SHININESS, shine);
}
else // if we do not have material properties, we have to set them manually
{
GLfloat diff[4] = { 0.75, 0.75, 0.75, 1.0 }; // color: white/grey
GLfloat amb[4] = { 0.25, 0.25, 0.25, 1.0 }; //color: black/dark gray
GLfloat spec[4] = { 0.0, 0.0, 0.0, 1.0 }; //color: completly black
glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
glMaterialfv(GL_FRONT, GL_AMBIENT, spec);
}
{
if(mesh->texels)
{
glBindTexture(GL_TEXTURE_2D, textureIndices.at(j));
j++;
}
glBegin(GL_TRIANGLES);
for(int i = 0;i < 3;i++)
{
glNormal3fv(normals[3*p+i]); //set normal vector of that point
if(mesh->texels)
glTexCoord2f(mesh->texelL[f->points[i]][0], mesh->texelL[f->points[i]][1]);
glVertex3fv(mesh->pointL[f->points[i]].pos); //Draw the damn triangle
}
glEnd();
}
}
[..]
}I did wrote this code myself.
If you want to check out all the source codes, check out:
http://svn.gna.org/viewcvs/combatofdeath/trunk/

dorbie
12-10-2005, 01:27 AM
OK, no problem, sorry for assuming you didn't write this.

GLTRIANGLES is an inefficient way to draw stuff, basically you're sending at least 3x more data than you need to and may be on an unoptimized path. In addition glDrawArrays or array range or some other variant is a much more efficient way to draw stuff, so you probably want to be drawing indexed meshed primitives for better performance and meshed with a view to cache coherency if you want to be really clever and allocated to be in the best memory i.e. card resident for static data, it can even eliminate the need for display list optimization.

In addition you have a lot of overheads in drawing this stuff, like matrix and material operations, that's fine if you have a lot of polygons per primitive but if you don't then those start to eat into your triangle rate very quickly.

The use of diaplay lists is good and helps some implementations optimize your drawing but it won't mesh your triangles for example. That's up to you, you're still pretty inefficient, and when you optimize yor triangle throughput your other OpenGL operations will become an even greater portion of your rendering time and a greater concern.

Hylke Donker
12-11-2005, 12:58 AM
Thank you for your reply.
But do you happen to know what is the average polygon rate per (game) map of, in example, Unreal Tournament 2004, so that I know what my card should be able to do?

12-11-2005, 08:14 AM
If we stay with a simple Frame Per Second (fps) metric, I noticed that rendering your bicycle.3DS mesh costs about 20fps using my trusty 600MHz PIII with GeForce FX 5200.

For an untextured mesh, this seems like a lot to me, so while optimizing your code to improve from 3 to 30fps will be critical, you may still find that reducing your polygon count will also be necessary.

P.S. I'm using SpaceTime (http://p-squared.com/SpaceTime.php) , which has a simple 3DS loader built in, to measure fps. It uses interleaved polygons (vertices, colours, normals) and display lists to boost frame rate.

Hylke Donker
12-12-2005, 03:43 AM
Originally posted by <Goatboi>:
If we stay with a simple Frame Per Second (fps) metric, I noticed that rendering your bicycle.3DS mesh costs about 20fps using my trusty 600MHz PIII with GeForce FX 5200.

For an untextured mesh, this seems like a lot to me, so while optimizing your code to improve from 3 to 30fps will be critical, you may still find that reducing your polygon count will also be necessary.
So I could atleast get a framerete of 30.Ok, thats good to know :p .


P.S. I'm using SpaceTime (http://p-squared.com/SpaceTime.php) , which has a simple 3DS loader built in, to measure fps. It uses interleaved polygons (vertices, colours, normals) and display lists to boost frame rate.Thanks, i'm pretty sure that will come in handy.

jide
12-13-2005, 01:47 PM
I didn't read all the topic but what I can say is that how many triangles you could draw per second depends on many factors, mainly: fill rate, texturing, lighting, culling and drawing methods (display lists, vertex arrays...)