1

I'm just starting out with freeglut and glew and getting it running was already quite hard for me. So now I started coding with tutorials from swiftless and I had a square displayed worked fine. Now I got to the point where I want to make the square move with the arrow keys.

From the point I inserted the glutIdleFunc it started lagging. I cant move the window or click on anything else for about a minute. If I try draging the window then it moves after about 2 min.

I tried doing this with the following code :

#include <GL/glew.h> 
#include <GL/glut.h>

bool* keyStates = new bool[256]; 
float positionX = 0;
void renderPrimitive (void) 
{
    glBegin(GL_QUADS);
    glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
    glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
    glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
    glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
    glEnd();
}
void keySpecial (int key, int x, int y) 
{
    if (keyStates[GLUT_KEY_RIGHT]) 
    {   
        positionX++;
    }
}

void display (void) 
{

    glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
    glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
    glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
    glTranslatef(0.0f, 0.0f, -5.0f);
    renderPrimitive();
    glFlush(); // Flush the OpenGL buffers to the window
}

void reshape (int width, int height)
{
    glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
    glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
    glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
    gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
    glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}

void keyPressed (unsigned char key, int x, int y) 
{
    keyStates[key] = true; // Set the state of the current key to pressed
}

void keyUp (unsigned char key, int x, int y)
{
    keyStates[key] = false; // Set the state of the current key to not pressed
}

int main (int argc, char **argv) 
{
    glutInit(&argc, argv); // Initialize GLUT
    glutInitDisplayMode (GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
    glutInitWindowSize (500, 500); // Set the width and height of the window
    glutInitWindowPosition (100, 100); // Set the position of the window
    glutCreateWindow ("Your first OpenGL Window"); // Set the title for the window

    glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering

    glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for reshaping
    glutIdleFunc(display);
    glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses
    glutKeyboardUpFunc(keyUp); // Tell GLUT to use the method "keyUp" for key up events
    glutSpecialFunc(keySpecial);
    glutMainLoop(); // Enter GLUT's main loop
}

I don't expect this to be a hardware problem since my computer can play big games.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Shishi
  • 601
  • 2
  • 8
  • 27
  • `bool* keyStates = new bool[256];` Is this a valid thing to do at global scope, considering the issue of how to destroy this array? Even if it is, what possible reason would you have for doing this rather than creating a static array (e.g. `bool keyStates [256];`)? Also, do not use single buffered rendering it will only make your life more difficult if you intend to run it on a hybrid GPU solution or a compositing window manager (e.g. Aero in Windows Vista/7, compiz in Linux or Quartz in OS X). – Andon M. Coleman Sep 28 '13 at 17:16
  • `The bool* keyStates = new bool[256];` came from [link](http://www.swiftless.com/tutorials/opengl/keyboard.html) tutorial. Thanks for the advice though – Shishi Sep 28 '13 at 17:42
  • instead of single buffered rendering what should I use? – Shishi Sep 28 '13 at 17:56
  • 1
    Use `GLUT_DOUBLE` instead of `GLUT_SINGLE` and replace `glFlush (...)` with `glutSwapBuffers (...)`. – Andon M. Coleman Sep 28 '13 at 18:09

1 Answers1

2

You should avoid doing any GL drawing in the idle function. If you want to redraw your scene continuously, use an idle function like

void idle(void)
{
    glutPostRedisplay();
}

and see if that helps.

derhass
  • 43,833
  • 2
  • 57
  • 78
  • 2
    Good eye, the GLUT spec. says: "If enabled, the idle callback is continuously called when events are not being received." Depending on how the underlying platform buffers input / window events this could definitely produce the problem. And the issue would only become worse when double-buffering and VSYNC are used. – Andon M. Coleman Sep 28 '13 at 17:27
  • Or, you can register glutPostRedisplay itself as idle function. – datenwolf Sep 28 '13 at 17:30
  • The void idle function works great it doesnt lag. The only problem now is that I have to click in my window before it updates my screen any idea how I can fix this? – Shishi Sep 28 '13 at 17:54
  • @datenwolf if I do `glutIdleFunc(glutPostRedisplay);` it say that the function is incompatible with the parameters of type void – Shishi Sep 28 '13 at 17:58
  • Ooh I got what you meant `glutIdleFunc(idle)` now everything works fine – Shishi Sep 28 '13 at 18:21
  • @user1820557: Huh, glutPostRedisplay has the right type signature to be used as idle function. My bet is you accidently added a pair of parenthesis. – datenwolf Sep 28 '13 at 21:30