0
\$\begingroup\$

I have made a rotating cube and I got some performance drops while using two glRotatef calls. So basically this code is giving me 80FPS:

    //code 1
GLrotate_x += 0.4f;
GLrotate_y += 0.4f;
        glPushMatrix();
            glRotatef( GLrotate_y, 0.0f, 1.0f, 0.0f );
            glRotatef( GLrotate_x, 1.0f, 0.0f, 0.0f );
            glTranslatef(multiplxGL+0.5f+spaceGL/2, -multiplyGL-0.5f-spaceGL/2,  multiplzGL+0.5f+spaceGL/2);
            glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
        glPopMatrix();

While this one is giving me 100FPS

    //code 2
GLrotate_y += 0.4f;
        glPushMatrix();
            glRotatef( GLrotate_y, 1.0f, 1.0f, 0.0f );
            glTranslatef(multiplxGL+0.5f+spaceGL/2, -multiplyGL-0.5f-spaceGL/2,  multiplzGL+0.5f+spaceGL/2);
            glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
        glPopMatrix();

The rotate results from the rotation code 1 and code 2 are not the same (cube rotates different).I know that the code 1 is the most proper way here for the rotation but why the performance drops? Any chance of updating my code 1 to the performance of code 2?

On the other side in DirectX I use:

D3DXMatrixRotationYawPitchRoll(&matDXRotate, 
                                D3DXToRadian(DXrotate_y), 
                                D3DXToRadian(DXrotate_x), 
                                D3DXToRadian(0.0f));

and then

matDXStack->Push();
        D3DXMatrixTranslation(&matDXmove, multiplxDX + 0.5f + spaceDX / 2, multiplyDX + 0.5f + spaceDX / 2, multiplzDX + 0.5f + spaceDX / 2);
        matDXStack->LoadMatrix(&(matDXmove*matDXRotate));
        d3ddev->SetTransform(D3DTS_WORLD, matDXStack->GetTop());
        d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 36, 0, 12);
    matDXStack->Pop();

Which gives me 100 FPS and rotate results same as code 1.

\$\endgroup\$
3
  • \$\begingroup\$ You're not reconstructing the geometry every frame, right? \$\endgroup\$
    – Ben
    Apr 14 '14 at 5:11
  • 2
    \$\begingroup\$ glRotatef will cause performance drops, period. It’s been superseded by better mechanisms for 10 years and deprecated for 6 years now. You should learn yourself some modern OpenGL instead. \$\endgroup\$ Apr 14 '14 at 7:15
  • 1
    \$\begingroup\$ Not necessarily... glRotatef (...) does not violate hardware T&L or anything like that (in fact, long before D3D invented the term "hardware T&L", GL was able to implement transforms on the server-side). The matrix stack and its associated transformations can be implemented completely on the GPU (server). In fact, creating a transformation matrix from a sequence of glLoadIdentity (...), glTranslatef (...), glRotatef (...), etc. calls is sometimes quicker than transferring 16 floats using glLoadMatrixf (...) or glUniformMatrix4fv (...). \$\endgroup\$ Apr 16 '14 at 22:56
2
\$\begingroup\$

When measuring performance, use frame times, rather than FPS. In your case:

1000 ms /  80 FPS => 12.5 msec/frame
1000 ms / 100 FPS => 10.0 msec/frame

These are very even FPS numbers, which makes me suspect that they are tied to the display vsync. Have you tried disabling vsync (with a call like eglSwapInterval, or setting the Direct3D swap interval?

After confirming that that's not the issue, you could try constructing the OpenGL matrices manually, to see if that's the issue. None of those calculations should take anywhere near 2.5 msec, though.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you. Yes to get vsync to OFF state I use: in DirectX: D3DPRESENT_INTERVAL_IMMEDIATE; and in OpenGL: wglSwapIntervalEXT(0);. \$\endgroup\$
    – NightKn8
    Apr 15 '14 at 6:44
2
\$\begingroup\$

OpenGL 1.x's built-in matrix operations are notoriously slow, and may even cause pipeline flushes in some cases. To gain performance, translate your gl matrix operations to client-side code (there are several solutions, http://glm.g-truc.net/0.9.5/index.html and http://cmldev.net/ being popular ones).

If you already have a lot of code, you can easily write wrappers that will let you continue using the same-looking code (by simply renaming a couple of functions), for example..

matrix active_matrix;
matrix matrix_stack[64];
int matrix_stack_idx = 0;

void mlPushMatrix()
{
    matrix_stack[matrix_stack_idx] = active_matrix;
    matrix_stack_idx++;
    assert(matrix_stack_idx < 64);
}

void mlPopMatrix()
{
    assert(matrix_stack_idx > 0);
    matrix_stack_idx--;
    active_matrix = matrix_stack[matrix_stack_idx];
}

void mlLoadMatrix()
{
    glLoadMatrixf(active_matrix.data());
}

void mlTranslatef(float x, float y, float z)
{
    matrix t;
    matrix_translation(t,x,y,z);
    active_matrix = active_matrix * t;
}
\$\endgroup\$
0
\$\begingroup\$

Thank you all but I found an other way to do that. I created (or rather copied form this schema) a rotation matrix RotateMAT[16]:

#define OGLToRadian(degre) ((degre) * (M_PI / 180.0f))
//...

GLvoid ROT(float x, float y, float z) {
  const float cosA = cosf(OGLToRadian(GLrotate_y));
  const float sinA = sinf(OGLToRadian(GLrotate_y));
  float RotateMAT[16] = 
  {       
          ((x * x) * (1 - cosA)) + cosA,    ((x * y) * (1 - cosA)) - (z * sinA),    ((x * z) * (1 - cosA)) + (y * sinA),    0.0f,                   
    ((x * y) * (1 - cosA)) + (z * sinA),          ((y * y) * (1 - cosA)) + cosA,    ((y * z) * (1 - cosA)) - (x * sinA),    0.0f,
    ((x * z) * (1 - cosA)) - (y * sinA),    ((y * z) * (1 - cosA)) + (x * sinA),          ((z * z) * (1 - cosA)) + cosA,    0.0f,
                                   0.0f,                                   0.0f,                                   0.0f,    1.0f  
  };
  glMultMatrixf(RotateMAT);

}

Now with this code I can simply rotate like:

ROT( 0.0, -1.0,  0.0);
ROT(-1.0,  0.0,  0.0);

That works much faster (+20FPS) than OpenGL's glRotatef:

glRotatef( GLrotate_y, 0.0f, 1.0f, 0.0f );
glRotatef( GLrotate_x, 1.0f, 0.0f, 0.0f );
\$\endgroup\$
1
  • \$\begingroup\$ yes.. that is precisely what you'd use an external math library for. \$\endgroup\$ Apr 15 '14 at 15:59

You must log in to answer this question.

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