Help: Rotating a square on mouse click

Hi everyone, I’m new on this forum. I’ve started an opengl class and the teacher gave us an assignment.

Basically a square has to start rotating to the left by itself on left mouse button click and stop rotating (freeze) on right mouse button click. All I got was just some skeleton code on which to work.

I’ve finished the program but it’s not working properly. I would be grateful if someone could take a look and tell me what my mistakes are.

Thank you in advance.


#include <stdlib.h>
#include <gl/glut.h>

static GLfloat spin =0.0;
void init()
{
	glClearColor (0,0,0,0);
}
void display()
{
	glClear(GL_COLOR_BUFFER_BIT); 
	glPushMatrix();
	glRotatef(spin,0.0,0.0,0.0);
	glColor3f(1,0,0);
	glRectf(-25.0, -25.0, 25.0, 25.0);
	glPopMatrix();
	//glutSwapBuffers();
	glFlush();
}
void spinDisplay()
{
	spin=spin + 0.1;
	if (spin > 360.0)
	{spin=0.0;}
	glutPostRedisplay();
}
void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,1,0,1,-1,1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void mouse(int buton, int state, int x, int y)
{
	switch(buton){
case GLUT_LEFT_BUTTON:
	if (state==GLUT_DOWN)
		glutIdleFunc(spinDisplay);
	break;
case GLUT_RIGHT_BUTTON:
	glutIdleFunc(NULL);
default:glutIdleFunc(NULL);

	break;
	}
}
int main(int argc, char** argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGB);
	glutInitWindowSize(600,600);
	//glutInitWindowPosition(50,50);
	glutCreateWindow(argv[0]);
	init();
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(mouse);
	glutMainLoop();
	return 0;
}

glRotatef(spin,0.0,0.0,0.0); -> RTFM
http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml

Look at the arguments, and ask yourself around which axis you want to rotate, it should put you on the right track.

thanks zbuffer, I’ve read that

Well I need to rotate it around the Z axis but I don’t quite understand what values for the x,y,z parameters I should use to achieve that.

My guess is to use glRotatef(spin,0.0,0.0,1.0); for counter clockwise rotation and glRotatef(spin,0.0,0.0,-1.0); for clockwise.

Tried that but it’s not working, or at least I can’t see it (reason below).

Also I don’t understand why my red square takes up the entire WindowSize and not the dimensions I gave it.

use glRotatef(spin,0.0,0.0,1.0); for counter clockwise rotation and glRotatef(spin,0.0,0.0,-1.0); for clockwise

For example. Or glRotatef(-spin,0.0,0.0,1.0);

Can not see the edge ? Then should try putting smaller coordinates :slight_smile:
For example with half, try, half again, try, until you see the edge.

2 main ways of learning are :

  • reading documentation and understanding it
  • experimenting stuff until it works somewhat

And in practice, doing both is great.

Hint :
http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

No, no, no you don’t understand, the square size problem is in the code, not in the values.

No matter how small I set

glRectf(-25.0, -25.0, 25.0, 25.0);

and how large I set

glutInitWindowSize(600,600); 

the red square will always take up the entire window.

What could it be? :eek:

Ok then you did not get my hint. Should work with glRectf(0.3, 0.3, 0.7, 0.7);

To be more specific, coordinates you send to opengl with glVertex(), glRect, etc are not in pixels, but are transformed by modelview matrix (here, identity = no change) and projection matrix (here, glOrtho keep x between 0 and 1, same for y, and between -1 and 1 for z), then scaled to fit glViewport values.

If you feel more comfortable working with pixels, replace your glOrtho with glOrtho(0,w,0,h,-1,1);

This is why I suggested you read the doc.

All you got was some skeleton code? Not the complete solution? Sheesh, how do they expect you to learn?

You’ll find soon that glRotate ‘sets’ the position, doesn’t ‘animate’ the position. You’re going to need a variable or two. [edit] Oh, you do, sorry. You just need to finish integrating that.

Bruce

Yes, you were right zbuffer, I had a misconception about how that worked.

thanks

It sort of works now except the square is centered in the bottom left corner and won’t stop rotating on right click. Anywaym I’ll read some docu to finish eveything up.

Ontopic:

I’m kind of confused about what you said. as far as I know glRotatef doesn;t animate it, but it does rotate it and actually the display function in the loop makes the animation happen.

Am I right?

Yes you are right the_big_noob, Bruce overreacted :slight_smile:

Putting spinDisplay as idle func means it is indeed called repeatedly by glut when there is no other event to process. It is not ideal as the rotation speed depends of the good will of glut, the cpu speed, other processes, etc but it is still something.

About centering the rotation : probably the easier is to center the glOrtho so that 0,0 is on the center of the screen, ie glOrtho(-1,1,-1,1,-1,1); and same for the rect coords.

I am surprised about the “won’t stop rotating on right click”.
Try some basic tracing with printf("was here 1
"); to check what paths are really used in your code (ie. does GLUT_RIGHT_BUTTON actually hapens, etc).

that’s genius, thanks I’ll try that.

thanks guys

Fixed it a few days ago, but I feel I should share it with everyone. Works like clockwork.

Here are the correct arguments for the functions that proved to be the troublemakers.

glRotatef(spin,0.0,0.0,1.0);
glRectf(-1.0, -1.0, 1.0, 1.0);


glOrtho(-2,2,-2,2,-1,1);
glutInitDisplayMode(GLUT_DOUBLE);

Hi, I’m learning Open GL and searched to find why my code from the book
OpenGL Programming Guide 3RD ED page 24 (same project as yours) wouldn’t rotate.
I compared my code to yours and noticed that the book omitted a ‘break’ after the first mouse function switch-case-if statement! !! The rest of the books code is correct and it now works. Thanks for helping! Correction : the book did have the break in it, but I didn’t notice until I saw your code here. Apologies, and thanks again! (Seems to be a good book by the way!)