PDA

View Full Version : Help: Rotating a square on mouse click



the_big_noob
11-10-2010, 04:27 AM
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(&amp;argc,argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(600,600);
//glutInitWindowPosition(50,50);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

ZbuffeR
11-10-2010, 04:41 AM
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.

the_big_noob
11-10-2010, 04:57 AM
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.

ZbuffeR
11-10-2010, 06:52 AM
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 :)
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

the_big_noob
11-10-2010, 07:40 AM
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:

ZbuffeR
11-10-2010, 08:10 AM
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.

Bruce Wheaton
11-10-2010, 12:13 PM
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.

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

the_big_noob
11-10-2010, 01:30 PM
Ok then you did not get my hint. Should work with glRectf(0.3, 0.3, 0.7, 0.7);


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:


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

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?

ZbuffeR
11-10-2010, 02:01 PM
Yes you are right the_big_noob, Bruce overreacted :)

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\n"); to check what paths are really used in your code (ie. does GLUT_RIGHT_BUTTON actually hapens, etc).

the_big_noob
11-10-2010, 09:36 PM
Try some basic tracing with printf("was here 1\n");


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

thanks guys

the_big_noob
11-15-2010, 01:18 PM
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);