delay function


void delay(float secs)
{
	float end = clock() / CLOCKS_PER_SEC + secs;
	while ((clock() / CLOCKS_PER_SEC) < end);
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		delay(1);
		glColor3f(1.0f, 1.0f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	}
}

I am drawing a square then I am drawing a dimmed square then I want to wait a second and then draw a undimmed square. well this code draws a square but then it does not draw a dimmed square or wait to draw a undimmed square.

It seems like you forgot to render the screen after drawing a square - I don’t know where exactly you call SwapBuffers, but before the delay there’s none - so you’ll never see the first square but the second one which will compleately overdraw the first.

I also suggest to change the Vertices of the second one so that the squares just overlap in a smaller area. Then you wouldnt need to render between them and the delay too. Depends on what you need it for

This won’t work, for a variety of reasons.

If you’re using GLUT, you should draw the first square and use glutTimerFunc() to register a callback which will be invoked after one second. That callback should call glutPostRedisplay(), which will cause your display function to be called. That should draw the second square. Use a variable to keep track of which version of the square the display function should draw at any given time. Also, you should call glutSwapBuffers() at the end of your display function to ensure that what you draw is actually visible on screen.

pbivens, with OpenGL, in most cases you’re drawing to an invisible buffer (term: “double-buffering”). Not only that, the drawing commands you call in your application aren’t executed immediately; instead, they’re recorded for execution later.

So sleeping in your application is not the way to force the execution of your draw commands and to display the result on-screen.

Instead, how you request that both of these be done is to call *SwapBuffers. If you’re using GLUT, you should call glutSwapBuffers().


void delay(int v)
{
	glColor3f(1.0f, 1.0f, 0.0f);
	glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	glutPostRedisplay();
	glutTimerFunc(1000, delay, v);
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		delay(0);
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		glutSwapBuffers();
	}
}

well I am working on my code as per gclements I have made some changes. but it still does not work however it does flicker when I hit the yellow square. thanks for all the help. I am close to solving this problem I just need a little help.

I suggest you don’t draw anything in your timer callback. Draw everything in one “draw” function based on the current program state.

Also, you need to call glutPostRedisplay anytime you want a draw to occur. I don’t know, but I suspect you want that to happen more than every 1 second (the rate that you’re currently calling it, based on your timer callback interval).

For testing, just drop a glutPostRedisplay at the end of your init() and draw() functions so that it’s just called as often as possible. Then after you get things working well, you can scale back and only request a redraw when it’s needed if you want.


void delay(int v)
{
	glColor3f(1.0f, 1.0f, 0.0f);
	glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	glutPostRedisplay();
	glutTimerFunc(1000, delay, v);
	glFlush();
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		glFlush();
	}
}

well I have made some progress when I hit the square it blinks on and off and it continues to do so. I took the drawing routine out of the timer but it does not work at all.

well I finally solved this problem. here is the code I am using.


void delay(int v)
{
	glColor3f(1.0f, 1.0f, 0.0f);
	glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	glutTimerFunc(1000, delay, v);
	glFlush();
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		glFlush();
	}

thanks for all the help [SOLVED]

I have made more progress.


void delay_one(int v)
{
	glColor3f(1.0f, 1.0f, 0.0f);
	glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	glutTimerFunc(1000, delay_one, v);
	glFlush();
}
void delay_two(int v)
{
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(10.0f, 90.0f, 90.0f, 10.0f);
	glutTimerFunc(1000, delay_two, v);
	glFlush();
}
void delay_three(int v)
{
	glColor3f(0.0f, 1.0f, 0.0f);
	glRectf(-90.0f, -10.0f, -10.0f, -90.0f);
	glutTimerFunc(1000, delay_three, v);
	glFlush();
}
void delay_four(int v)
{
	glColor3f(0.0f, 0.0f, 1.0f);
	glRectf(10.0f, -10.0f, 90.0f, -90.0f);
	glutTimerFunc(1000, delay_four, v);
	glFlush();
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		glFlush();
	}
	if (board[0][1] == 1)
	{
		glColor3f(0.5f, 0.0f, 0.0f);
		glRectf(10.0f, 90.0f, 90.0f, 10.0f);
		glFlush();
	}
	if (board[1][0] == 1)
	{
		glColor3f(0.0f, 0.5f, 0.0f);
		glRectf(-90.0f, -10.0f, -10.0f, -90.0f);
		glFlush();
	}
	if (board[1][1] == 1)
	{
		glColor3f(0.0f, 0.0f, 0.5f);
		glRectf(10.0f, -10.0f, 90.0f, -90.0f);
		glFlush();
	}
}

void onMouseButton(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
        if (x >= 130 && x <= 370 && y <= 270 && y >= 30)
		{
            board[0][0] = 1;
		}
		if (x >= 430 && x <= 670 && y <= 270 && y >= 30)
		{
			board[0][1] = 1;
		}
		if (x >= 130 && x <= 370 && y <= 570 && y >= 330)
		{
			board[1][0] = 1;
		}
		if (x >= 430 && x <= 670 && y <= 570 && y >= 330)
		{
			board[1][1] = 1;
		}
	draw_button();
	}
	glFlush();
}

I am building a simon game. However when I press a square and another square it turns both squares off and on. I want to turn on and off one square at a time.

First: the only place you should be calling OpenGL functions is during initialisation and from the display callback (whether in the display function itself or in other functions called from it). Other callbacks shouldn’t call OpenGL functions, directly or indirectly. The display function needs to be able to draw the scene based upon the program state. Other functions simply modify that state.

So to change the display in response to events (keyboard, mouse, timer), you change some variables in response to those events (and if necessary, force a display update with glutPostRedisplay()). The display function just takes those variables into account when deciding what to draw.

I am going to work on this problem more.

I am building a simon game. However when I press a square and another square it turns both squares off and on. I want to turn on and off one square at a time.

Post your code, or at least the important parts.

I have already posted my code above.

I am working on a simon game. I am using c++ and opengl.I am able to draw four buttons. When press a button with the mouse it turns off and on. however it also turns on and off the other buttons. I want it to turn on and off only a single button at a time. here is some of my code.


void delay_one(int v)
{
	glColor3f(1.0f, 1.0f, 0.0f);
	glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
	glutTimerFunc(1000, delay_one, v);
	glFlush();
}
void delay_two(int v)
{
	glColor3f(1.0f, 0.0f, 0.0f);
	glRectf(10.0f, 90.0f, 90.0f, 10.0f);
	glutTimerFunc(1000, delay_two, v);
	glFlush();
}
void delay_three(int v)
{
	glColor3f(0.0f, 1.0f, 0.0f);
	glRectf(-90.0f, -10.0f, -10.0f, -90.0f);
	glutTimerFunc(1000, delay_three, v);
	glFlush();
}
void delay_four(int v)
{
	glColor3f(0.0f, 0.0f, 1.0f);
	glRectf(10.0f, -10.0f, 90.0f, -90.0f);
	glutTimerFunc(1000, delay_four, v);
	glFlush();
}
void draw_button()
{
	if (board[0][0] == 1)
	{
		glColor3f(0.5f, 0.5f, 0.0f);
		glRectf(-90.0f, 90.0f, -10.0f, 10.0f);
		glFlush();
	}
	if (board[0][1] == 1)
	{
		glColor3f(0.5f, 0.0f, 0.0f);
		glRectf(10.0f, 90.0f, 90.0f, 10.0f);
		glFlush();
	}
	if (board[1][0] == 1)
	{
		glColor3f(0.0f, 0.5f, 0.0f);
		glRectf(-90.0f, -10.0f, -10.0f, -90.0f);
		glFlush();
	}
	if (board[1][1] == 1)
	{
		glColor3f(0.0f, 0.0f, 0.5f);
		glRectf(10.0f, -10.0f, 90.0f, -90.0f);
		glFlush();
	}
}

let me know if you need more code.

Starting another thread isn’t going to help. And the fact that you shouldn’t be calling OpenGL functions outside of the display callback isn’t going to change.

well here is my display callback function


void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	Draw_Buttons();
	glFinish();
	draw_button();
}

I have done some research on display callback, I think that the display callback is what is used to display my game to the screen. let me know if I have a understanding of callbacks.

Correct. And the display callback is the only time you should be drawing anything. The other callbacks (mouse, keyboard, timer) should only be changing variables which affect the drawing performed by the display callback.

You should probably have an array of flags which indicate whether each button is “lit”. The timer callback would change those flags (and call glutPostRedisplay), the display callback would read them to determine how to draw each button (dark or light).

cool I am glad that I understand display callback functions. here is my mouse callback


void onMouseButton(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
        if (x >= 130 && x <= 370 && y <= 270 && y >= 30)
		{
            board[0][0] = 1;
		}
		if (x >= 430 && x <= 670 && y <= 270 && y >= 30)
		{
			board[0][1] = 1;
		}
		if (x >= 130 && x <= 370 && y <= 570 && y >= 330)
		{
			board[1][0] = 1;
		}
		if (x >= 430 && x <= 670 && y <= 570 && y >= 330)
		{
			board[1][1] = 1;
		}
	draw_button();
	}
	glFinish();
}

is this an array that you are talking about or something different?

[QUOTE=pbivens;1290239]cool I am glad that I understand display callback functions. here is my mouse callback


	draw_button();
	}
	glFinish();

[/QUOTE]
Those two function calls don’t belong there. After updating the [var]board[/var] array, the function should simply call glutPostRedisplay().

If you want the button state to change automatically after a given amount of timer, register a timer callback. As with the mouse callback, the timer callback should simply update the [var]board[/var] array then call glutPostRedisplay(); it shouldn’t attempt to draw anything itself.