Cubo doesn't rotate, except when window changes

Hi. I have a very single openGL program that is supposed to rotate a cube. However, when the program runs and the window opens, the cube just stays still, without moving as I expect.

However, when I maximize and then minimize the window, it rotates (just once). Then if I maximize and minimize again, it rotates again a bit more and so it happens whenever I repeat such procedure.

The question is why? Here is the Opengl code (minus the cube’s code) with a bit of the window code to add context of what is being used where:

glEnable (GL_DEPTH_TEST);
while (5) {
		XNextEvent (dpy,&xev);
		printf ("Boto!");
		if (xev.type == Expose) {
			XGetWindowAttributes (dpy,win,&gwa);
			glViewport (0,0,gwa.width,gwa.height);
			display (width,height);
			glXSwapBuffers (dpy,win);
		}
		else if (xev.type == KeyPress) {
			glXMakeCurrent (dpy,None,NULL);
			glXDestroyContext (dpy,glc);
			XDestroyWindow (dpy,win);
			XCloseDisplay (dpy);
			break;
		}
	}
void display(int width, int height) {
	glClearColor (0,0,0,0);
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		

	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	gluPerspective (45,(GLfloat)width/(GLfloat)height,1,100);

	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity ();
	gluLookAt (0,0,10,0,0,0,0,1,0);		

	glTranslatef (0,3,0);
	glRotatef (rot_angle,0,0,1);
	glBegin (GL_QUADS);			
		glVertex3f (-.75, -.75, 0); glColor3f (1,0,0);
		.....
	glEnd ();
	rot_angle+=1.2;
}

From XNextEvent:
If the event queue is empty, XNextEvent flushes the output buffer and blocks until an event is received.

Carsten identified the problem, but didn’t say what to do about it.

If you want to wait until either an event is received or a certain amount of time has elapsed, you can use select or poll to wait with timeout on a file descriptor. You can query the descriptor for a given X display using the ConnectionNumber macro or the XConnectionNumber function.

If a timeout occurs, you should redraw the window. If there is activity on the descriptor, you should call XPending to check if there is an event waiting before calling XNextEvent to retrieve it. This ensures that XNextEvent won’t block.

But you should use ideally a toolkit to handle such details.

Hi. After reading both posts and part of what was in the link from carsten_neumann, I did change the code to…

	while (1) {
         if (XPending (dpy) > 0) 
				XNextEvent (dpy,&xev);
			else if (xev.type == Expose) {
					XGetWindowAttributes (dpy,win,&gwa);
					glViewport (0,0,gwa.width,gwa.height);
					rot_angle+=1.2;
					display (width,height);
					glXSwapBuffers (dpy,win);
			}
			else if (xev.type == KeyPress) {
				glXMakeCurrent (dpy,None,NULL);
				glXDestroyContext (dpy,glc);
				XDestroyWindow (dpy,win);
				XCloseDisplay (dpy);
				//loop=false;
				break;
			}
	}

.and now the code perform as I expected it. I did not use anything from your first paragraph, so I am unsure of possible side effects of not doing these things

The program is using a busy wait, so it will consume CPU cycles (100% of one core) even if there’s no input. Note that if you want continuous animation, you probably shouldn’t bother checking for Expose events, but just redraw the window constantly. Although you might still want to use a timer; if you don’t have vsync enabled (via glXSwapIntervalEXT, from GLX_EXT_swap_control, you could easily end up redrawing faster than the monitor’s refresh rate, which just wastes CPU and GPU cycles).

Also, you’re using the contents of xev even if you didn’t actually read an event into that structure. The entire inner loop (other than the XPending call itself) should be conditional upon XPending returning a positive value.

The entire inner loop (other than the XPending call itself) should be conditional upon XPending returning a positive value.

If I do so, the initial problem returns.

so it will consume CPU cycles (100% of one core) even if there’s no input

Cpu use happens to be minimal, although xorg is somewhat greater. Far from 100%.

Also, you’re using the contents of xev even if you didn’t actually read an event into that structure

Isn’t it used to close the program when a key is pressed?

Note that if you want continuous animation, you probably shouldn’t bother checking for Expose events, but just redraw the window constantly

Like this?

// else if (xev.type == Expose) {
XGetWindowAttributes (dpy,win,&gwa);
glViewport (0,0,gwa.width,gwa.height);
rot_angle+=1.2;
display (width,height);
glXSwapBuffers (dpy,win);
// }

It did not change anything, so fine by me.