Slow rendering

I’m using Borland C++ Builder 6, and trying to write a simple graphics engine in OpenGL. Everything works fine, except incredibly slow. For instance, I create a cube with distinct colors at its vertices, and get a rendering speed of about 75 FPS (my refresh rate). Then, when I add a map a texture to the cube, the refresh rate drops to a stumbling 37-42 FPS. I thought it might’ve been some overhead with the texture unit on my video card, and tested more objects, but with 9 cubes on the screen, I’m getting 18 FPS. Oddly enough, multitexturing the cubes only dropped the FPS to about 16. Does anyone have a clue why this is happening? I’m positive my code isn’t -that- screwed up, and my video card isn’t that slow. Thanks!

EDIT: I’m not using any VCL components or forms…just the Win32 API.

[This message has been edited by Nychold (edited 02-09-2004).]

What is your card/driver/OS/CPU ?

Athlon XP 1800+
256 MB DDR PC2100 RAM
GeForce 2 220 MX 64 MB DDR RAM (?)
Windows XP Professional

Not the most impressive specifications, but surely able to do this simple exercise. Plus, both Oni and Baldur’s Gate II play well on my system. XD

Edit: Drivers are the latest available from eVGA (my video card manufacturer)

[This message has been edited by Nychold (edited 02-09-2004).]

Geforce 2 mx are not very fast, but 16 fps for 9 multitextured cubes seem not enought indeed.

You may want to use NVidia drivers instead of your manufacturer’s ones, they are updated way much regularly.

Well, you have probably a problem in your code. Do you glTexImage2D() each frame/cube ? If so, it is not the good way.

May you could show your code ? And do not forget the [ CODE ] and [ /CODE ] around it (without the spaces) it is much easier to read on this board.

Showing the source code would probably not be such a wise idea, but would happily post it on the web someplace for download. Not that it’s long, but it’s broken up into about a dozen classes, and ~50 functions. Some are totally unneccesary for the rendering, but also don’t intefere, and make creating the graphics engine a little bit easier.

And no…in my initialization code, I create the textures and bind them just once (using gluBuild2DMipmaps and a self-made Targa file loader), assigning one texture to GL_TEXTURE0_ARB and the other to GL_TEXTURE1_ARB. (is that right? sorry, I’m at a school library computer, not my home system) Then, simply assign the texture coordinates and draw the cubes. I thought that was the fastest way. And if you want the source code, gimme a little bit and I’ll get it posted. :slight_smile:

[This message has been edited by Nychold (edited 02-10-2004).]

<snickers> Okay, now I really feel stupid. I left out two really important things:

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

Now, I’m getting ~73 FPS with a single textured cube and ~45 with a multitextured cube. But, I’m still getting some weird behavior.

The cube is spinning in multiple directions (about x, y, and z axes). It starts spinning really fast, then instantly slows down, then picks right back up again. It almost seems like the first few faces can be drawn quickly, but the back three faces take longer. Here’s my rendering code:

// … SNIP …
// Rotate and translate
theta+=1.0f;
if (theta>360.0f) theta-=360.0f;

phi+=0.3333f;
if (phi>360.0f) phi-=360.0f;

psi+=0.67653;
if (psi>360.0f) psi-=360.0f;

glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(theta,1.0f,0.0f,0.0f);
glRotatef(phi,0.0f,0.233f,0.0f);
glRotatef(psi,0.0f,0.0f,0.872f);

glCallList(cube);
glFlush();
// … SNIP …

int Engine::InitCube()
{
int retVal=glGenLists(1);

glNewList(retVal,GL_COMPILE);
glBegin(GL_QUADS);
{
// Front Face
glNormal3f(0.0f,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f(0.0f,0.0f,-1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
// Left Face
glNormal3f(-1.0f,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
// Right Face
glNormal3f(1.0f,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Top Face
glNormal3f(0.0f,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
// Bottom Face
glNormal3f(0.0f,-1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);

}
glEnd();
glEndList();
return retVal;
}

I apologize for the length of this code. InitCube only gets called once, and stored into a value “cube”. Any thoughts?

Your drawing code does not seem to be wrong.

You said that you have constant FPS and varying rotating speed ? So it is not a performance problem. Maybe you rotating code ? I do not see glPushMatrix/glPopMatrix around.