Simple Box Animation Not working

Hello, I am reading the 4th Edition of OpenGL Super Bible and in Chapter 2 it wants me to copy some code that will create a window with a red square bouncing around it. My probelm is that instead of the square bouncing around, it flashes in the middle of the window. I’m not positive where the problem is, but im pretty sure it’s here:


void TimerFunction(int value)
{
	// Rever direction when you reach left or right edge
	if(x1 > windowWidth - rsize || x1 < -windowWidth)
		xstep = -xstep;

	// Reverse direction when you reach top or bottom edge
	if(y1 > windowHeight || y1 < -windowHeight + rsize)
		ystep = -ystep;

	// Actually move the square;
	x1 += xstep;
	y1 += ystep;

	/* Check bounds. This is in case the window is made
	 * smaller while the rectangle is boundcing and the 
	 * rectangle suddenly finds itself outside the new 
	 * clipping volume */
	if( x1 > (windowWidth - rsize + xstep))
		x1 = windowWidth - rsize - 1;
	else if( x1 < -(windowWidth + xstep))
		x1 = -windowWidth - 1;

	if( y1 > (windowHeight = ystep))
		y1 = windowHeight - 1;
	else if( y1 < -(windowHeight - rsize + ystep))
		y1 = -windowHeight + rsize - 1;

	// Redraw the scene with new coordinates
	glutPostRedisplay();
	glutTimerFunc(33, TimerFunction, 1);
}

Really? Know one can help me with what i thought would be an easy problem to solve?

So easy to solve that even the code you posted looks correct.

How are the x1, y1 used to actually move the square ? Absolute values, or relative ?

You should also printf() these values so you can see if it is a drawing problem or a computing problem.

Here is the full code:


#include <glut.h>

// Initial square position and size
GLfloat x1		= 0.0f;
GLfloat y1		= 0.0f;
GLfloat rsize	= 25.0f;

// Step size in x and y directions
// (numbers of pixels to move each time)
GLfloat xstep	= 1.0f;
GLfloat ystep	= 1.0f;

// Keep track of windows changing width and hieght
GLfloat windowWidth;
GLfloat windowHeight;

///////////////////////////////////////////////////////////////////
// Call to draw scene
void RenderScene(void)
{
	// Clear the windo with current clearing color
	glClear(GL_COLOR_BUFFER_BIT);

	// Set current drawing color to red
	glColor3f(1.0f, 0.0f,0.0f);

	//Draw a filled rectangle with current color
	glRectf(x1, y1, x1 + rsize, y1 - rsize);

	// Flush drawing commands
	glutSwapBuffers();
}

///////////////////////////////////////////////////////////////////
// Called by GLUT when idle
void TimerFunction(int value)
{
	// Rever direction when you reach left or right edge
	if(x1 > windowWidth - rsize || x1 < -windowWidth)
		xstep = -xstep;

	// Reverse direction when you reach top or bottom edge
	if(y1 > windowHeight || y1 < -windowHeight + rsize)
		ystep = -ystep;

	// Actually move the square;
	x1 += xstep;
	y1 += ystep;

	/* Check bounds. This is in case the window is made
	 * smaller while the rectangle is boundcing and the 
	 * rectangle suddenly finds itself outside the new 
	 * clipping volume */
	if( x1 > (windowWidth - rsize + xstep))
		x1 = windowWidth - rsize - 1;
	else if( x1 < -(windowWidth + xstep))
		x1 = -windowWidth - 1;

	if( y1 > (windowHeight = ystep))
		y1 = windowHeight - 1;
	else if( y1 < -(windowHeight - rsize + ystep))
		y1 = -windowHeight + rsize - 1;

	// Redraw the scene with new coordinates
	glutPostRedisplay();
	glutTimerFunc(33, TimerFunction, 1);
}

//////////////////////////////////////////////////////////////////
// Set up the rendering state
void SetupRC(void)
{
	// Set clear color to blue
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}

//////////////////////////////////////////////////////////////////
// Called by GLUT when the window has changed size
void ChangeSize(GLsizei w, GLsizei h)
{
	GLfloat aspectRatio;

	// Prevent a dive by zero
	if(h == 0)
		h = 1;

	// Set viewport to window dimensions
	glViewport(0,0,w,h);

	// Reset coordinate system
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Establish clipping volume
	aspectRatio = (GLfloat)w / (GLfloat)h;
	if(w <= h)
		glOrtho (-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio,
				  1.0, -1.0);
	else
		glOrtho(-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0,
			     100.0, 1.0, -1.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

//////////////////////////////////////////////////////////////////
// Main program entry point
	int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Bounce");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutTimerFunc(33, TimerFunction, 1);

	SetupRC();
	glutMainLoop();

	return 0;
}

2 things:

1)windowWidth and windowHeight don’t equal anything. I made mine equal to a 100 (there’s a reason why I chose 100 look at the ChangeSize function).

  1. There is something simply wrong with:
    if( y1 > (windowHeight = ystep))
    y1 = windowHeight - 1;
    else if( y1 < -(windowHeight - rsize + ystep))
    y1 = -windowHeight + rsize - 1;

‘windowHeight = ystep’ should be ‘windowHeight + ystep’