gluUnProject issue
Hello,
I am having a problem with gluUnProject.
I drew a Cube with gluPerspective and rotate it on the Y axis when dragged by mouse. Now I need to place a small sphere on the face of the cube depending on my mouse click (presently if I press P and then click mouse left button then convert the window position to object position).
Everything works fine , if I dont rotate the cube(ie I am able to place the
small sphere on the cube where I click). Now If I rotate the cube , then click on the cube (ie P + mouse) the sphere is not placed where I click. It behaves weirdly. I am new to opengl, please help.
I am having a problem with gluUnProject.
I drew a Cube with gluPerspective and rotate it on the Y axis when dragged by mouse. Now I need to place a small sphere on the face of the cube depending on my mouse click (presently if I press P and then click mouse left button then convert the window position to object position).
Everything works fine , if I dont rotate the cube(ie I am able to place the
small sphere on the cube where I click). Now If I rotate the cube , then click on the cube (ie P + mouse) the sphere is not placed where I click. It behaves weirdly. I am new to opengl, please help.
Not enough information.
Below is the code...My intention here is to place the small sphere on the tetrahedron at the position specified by the mouse. It does not work when I rotate the tetrahedron. Hope this gives insight to my problem
Code:
#include <GL/glut.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
void Display();
void Reshape(int w,int h);
static float _angle = 0.0f;
static int stop = 0;
static int rotate = 0;
static int lastx = 0;
static int lasty = 0;
static float rotation_angle = 0.0f;
static bool edit_poly = false;;
static bool second_point = false;
static double object_coord_start[3];
void mouseMovement(int x, int y) {
if(rotate == 1)
{
int diffx=x-lastx; //check the difference between the current x and the last x position
int diffy=y-lasty; //check the difference between the current y and the last y position
lastx=x; //set lastx to the current x position
lasty=y; //set lasty to the current y position
_angle = _angle + (float)diffx;
glutPostRedisplay(); //Tell GLUT that the display has changed
}
else
{
lastx = 0;
lasty = 0;
}
}
void keyboard (unsigned char key, int x, int y) {
/* Called when a key is pressed */
if (key == 27) exit (0); /* 27 is the Escape key */
if(key == 'p')
{
edit_poly = true;
}
}
void mouseEvent(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
rotate = 1;
lastx = x;
lasty = y;
if ( edit_poly == true)
{
GLint viewport[4];
GLdouble projection[16],modelview[16];
GLfloat wx=x,wy,wz;
glGetIntegerv(GL_VIEWPORT,viewport);
y=viewport[3]-y;
wy=y;
glGetDoublev(GL_MODELVIEW_MATRIX,modelview);
glGetDoublev(GL_PROJECTION_MATRIX,projection);
glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&wz);
GLU_FALSE == gluUnProject(wx,wy,wz,modelview,projection,viewport,&object_coord_start[0],&object_coord_start[1],&object_coord_start[2]);
glutPostRedisplay();
}
}
else if (state == GLUT_UP)
{
rotate = 0;
if ( edit_poly == true)
{
edit_poly = false;
}
}
}
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("ex");
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc (keyboard); /* Register the "keyboard" function */
glutMotionFunc(mouseMovement); //check for mouse movement
glutMouseFunc(mouseEvent);
glutMainLoop();
return 0;
}
GLdouble ox=0.0,oy=0.0,oz=0.0;
void Display() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//gluLookAt(10.0,0.0,20.0,0.0,0.0,0.0,0.0,1.0,0.0);
gluLookAt (0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(_angle, 0.0f, 1.0f, 0.0f);
//glRotatef(45,1.0,0.0,0.0);
glColor3f(1,0,0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(2.0, 0.0, 0.0);
glVertex3f(1.0,2.0,0.0);
glVertex3f(0.0, 0.0, 0.0);
//glVertex3f(1.0, 1.0, 2.0);
glEnd();
glColor3f(0,1,0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(1.0, 2.0, 0.0);
glVertex3f(1.0,1.0,2.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glColor3f(1,1,0);
glBegin(GL_POLYGON);
glVertex3f(2.0,0.0, 0.0);
glVertex3f(1.0,2.0,0.0);
glVertex3f(1.0, 1.0, 2.0);
glVertex3f(2.0, 0.0, 0.0);
glEnd();
glColor3f(0,0,1);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(2.0,0.0, 0.0);
glVertex3f(1.0,1.0,2.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
//glPopMatrix();
glPushMatrix();
glColor3f(0,1,1);
glDepthMask(GL_FALSE);
glTranslated(object_coord_start[0],object_coord_start[1],object_coord_start[2]);
glutSolidSphere(0.1,15,15);
glDepthMask(GL_TRUE);
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
The way you do it, it won't work because the matrices you retrieve in mouseEvent() aren't the matrices that were used to draw the cube because of push/pop. You need to store those when drawing or computing them, then use them with unProject() later.
Thanks for the help. It is solved now.