1

I have been trying to animate a simple box that moves from left to right in the viewport while changing its color at random. It is meant to restart animating on a left mouse click, and close on a right mouse click. I have been debugging my code below, and though I think my methodology is reasonable, whenever I run the code, color change does not happen, and the animation hangs immediately. Principally I am wondering if this has to do with my use of Sleep() (which documentation leads me to believe should accept milliseconds as arguments), or if my loop structure in general is the problem. When I debug, though, it seems to exit the loop without throwing an exception.

Code below - any help in resolving the hanging issue?

#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <GL/gl.h>
#include <unistd.h>
//#include <assert.h>

float boxX = 0;
float boxY = 100;
float boxWidth = 75;
float boxHeight = 75;

void display(void)
{
int const windowWidth  = glutGet(GLUT_WINDOW_WIDTH);
int const windowHeight = glutGet(GLUT_WINDOW_HEIGHT);
float const aspectRatio = (float)windowWidth / (float)windowHeight;

glClearColor (0.0, 0.0, 0.0, 0.0); /* Set background to black */
glClear (GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(aspectRatio, aspectRatio, aspectRatio, aspectRatio, -1.0, 1.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

while (boxX != windowWidth)
{
    glClear (GL_COLOR_BUFFER_BIT);

    float leftCorner = (float)boxX / windowWidth;
    float rightCorner = leftCorner + (float)boxWidth / windowWidth;
    float bottomCorner = (float)boxY / windowHeight;
    float topCorner = bottomCorner + (float)boxY / windowHeight;

    glBegin(GL_POLYGON);

    glColor3f (rand(), rand(), rand()); //Randomize the box's colour as it moves

    glVertex2d(leftCorner, topCorner);
    glVertex2d(rightCorner, topCorner);
    glVertex2d(rightCorner, bottomCorner);
    glVertex2d(leftCorner, bottomCorner);

    glEnd();

    boxX += 0.1; //Move the box

    glutSwapBuffers();
    Sleep(200000);
    glutPostRedisplay();

}

}

void mouseBehav( int button, int state, int x, int y )
{
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{

    int windowID = glutCreateWindow ("Rainbow Box Animation");
    glutDestroyWindow (windowID);
    exit (0);

    glutPostRedisplay();

}

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        boxX = 0;
        glutPostRedisplay();

    }

}

int main(int argc, char** argv)
{

glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition ((glutGet(GLUT_SCREEN_WIDTH)-250)/2, (glutGet(GLUT_SCREEN_HEIGHT)-250)/2);
glutCreateWindow ("Rainbow Box Animation");

glutMouseFunc(mouseBehav);
glutDisplayFunc(display);
glutMainLoop();

return 0;

}
genpfault
  • 51,148
  • 11
  • 85
  • 139
Rome_Leader
  • 2,518
  • 9
  • 42
  • 73

1 Answers1

0

using sleep() in a glutDisplayFunc() callback

No. Just...no.

Set up a timer callback for ~16-33ms and update boxX in that:

#include <GL/glut.h>

float boxX = 0;
float boxY = 0;
float boxWidth = 75;
float boxHeight = 75;
bool animate = false;

void timer( int value )
{
    const int w = glutGet(GLUT_WINDOW_WIDTH);
    if( boxX + boxWidth >= w / 2 )
    {
        animate = false;
    }

    if( animate )
    {
        boxX += 1; //Move the box
    }

    glutTimerFunc( 16, timer, 0 );
    glutPostRedisplay();
}

void display()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    const int w = glutGet(GLUT_WINDOW_WIDTH);
    const int h = glutGet(GLUT_WINDOW_HEIGHT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho( -w/2, w/2, -h/2, h/2, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    const float leftCorner = boxX;
    const float rightCorner = leftCorner + boxWidth;
    const float bottomCorner = boxY;
    const float topCorner = bottomCorner + boxHeight;

    glBegin(GL_POLYGON);
    glColor3ub(rand()%255, rand()%255, rand()%255); //Randomize the box's colour as it moves
    glVertex2d(leftCorner, topCorner);
    glVertex2d(rightCorner, topCorner);
    glVertex2d(rightCorner, bottomCorner);
    glVertex2d(leftCorner, bottomCorner);
    glEnd();

    glutSwapBuffers();
}

void mouse( int button, int state, int x, int y )
{
    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {
        exit(0);
    }

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        boxX = 0;
        animate = true;
    }
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition( (glutGet(GLUT_SCREEN_WIDTH)-250)/2, (glutGet(GLUT_SCREEN_HEIGHT)-250)/ 2);
    glutCreateWindow ("Rainbow Box Animation");

    glutMouseFunc(mouse);
    glutDisplayFunc(display);
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();

    return 0;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • OK, point taken RE: sleep. Removing the while structure via your method and in general seems to resolve the loop, but my square no longer draws. Not sure why this is - I tried both your unsigned coloring approach and my original one. – Rome_Leader Sep 23 '14 at 22:37