0
\$\begingroup\$

I'm trying to render a large, procedural-generated shape with OpenGL, but I'm having some issues. I'm rendering the shape by composing it from many cubes, as follows:

int TRACK_MIDDLE2 = 107;
for (GLdouble i=0.00; i<2*M_PI;i+=0.001) {
    x = TRACK_MIDDLE2 * sin(i) + 0.5;
    y = TRACK_MIDDLE2 * cos(i);
    glPushMatrix();
    glTranslatef(x, y, -size - 0.4);
    Cube c2(size);
    c2.render(grey, dgrey);
    glPopMatrix();
}

The Cube render code looks like this:

glBegin(GL_POLYGON);
glColor3fv(c1);
glVertex3f(-size, -size, size);
glVertex3f(size, -size, size);
glVertex3f(size, size, size);
glVertex3f(-size, size, size);
glEnd();

glBegin(GL_POLYGON);
glColor3fv(c2);
glVertex3f(-size, size, size);
glVertex3f(size, size, size);
glVertex3f(size, size, -size);
glVertex3f(-size, -size, -size);
glEnd();


glBegin(GL_POLYGON);
glColor3fv(c2);
glVertex3f(-size, -size, -size);
glVertex3f(size, -size, -size);
glVertex3f(size, -size, size);
glVertex3f(-size, -size, size);
glEnd();

glBegin(GL_POLYGON);
glColor3fv(c2);
glVertex3f(-size, -size,-size);
glVertex3f(-size, -size, size);
glVertex3f(-size, size, size);
glVertex3f(-size, size, -size);
glEnd();

This is the result image:

It looks visually correct, but it renders very slowly. If I decrease increment of i in the for loop, I loose out on the "smoothness" of the shape, which is undesirable.

How can I improve the rendering speed of this mesh?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ avoid using glBegin(...)/glEnd(). You should be using precomputed vertices to draw the geometry: en.wikipedia.org/wiki/Vertex_Buffer_Object \$\endgroup\$
    – Raxvan
    Dec 3, 2013 at 16:12
  • \$\begingroup\$ It doesn't look like you are rendering a cylinder at all. It looks like you are rendering a corkscrew-like track or something. Is that true? That's a very different question than rendering a cylinder. \$\endgroup\$
    – user1430
    Dec 3, 2013 at 16:15

1 Answer 1

7
\$\begingroup\$

Your performance problems are likely coming from the shear number of draw calls you are making. Each "step" in your track parameterization is a distinct draw call (of a cube) using old, inefficient glBegin/glEnd "immediate mode" pairs to render each face.

This in efficient first because of your use of immediate mode, but also because you are just submitting tons of redundant geometry in very tiny batches. It's better to make fewer draw calls with larger batches of geometry, because that will balance the load on your CPU and GPU more evenly and avoid much of the overhead associated with state transfer in each draw call.

Modern OpenGL uses buffer objects. You will want to modify the parameterization of your track slightly so that instead of making a new cube for every step of the parameterization you generate the final vertices directly (so you won't be using the matrix stack manipulation functions either) and write those into the memory buffer that will back your vertex buffer object.

Then you render that vertex buffer object in a single draw call.

To familiarize yourself with buffer objects (in addition to the documentation I linked above), there are several tutorials online. A quick search turns up this one and this one, for example. A good read on modern OpenGL can be found here, as well.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .