From: Ben S. <bs...@ia...> - 2003-05-26 22:11:59
|
Unfortunately, as far as I can tell, gluUnProject is not as useful as it probably should be. What you can get out of it is a the position of your (x,y,z) screen coord in object/world coordinates. While that sounds useful in and of itself, it's really not. It sounds like you're trying to project the mouse position onto a plane (your grid). What has worked for me in the past is to get two points using gluUnProject, one at the screen position (z=0) and one slightly into the screen (z=0.02) [Yes, that is positive 0.02. In view coordinates Z points into the screen]. With those two points you can create a ray starting at the screen position cast in the direction of your plane. From there you can find the intersection point of the ray and the plane. With all that you can "click" on the grid. Some fun code (based on yours). This is more pseudocode than anything with the assumption of some basic classes defined (Point, Vector, ...). //--------------------------------------------------- // Unproject the point of the mouse to form a ray into the screen Point beg = // gluUnProject on the point (x,y,0.0) Point end = // gluUnProject on the point (x,y,0,02) // Create the ray Vector direction = end - beg; direction.normalize(); Ray ray(beg, direction); // Create the plane Point plane_position = // Some point on the plane Vector plane_normal = // The plane's normal Plane plane(plane_normal, plane_position); // Intersect the ray with the plane dist = plane.intersect(ray); if (dist < 0.0) { // No intersection } // Find the point of intersection Point pos_on_plane = ray.getOrigin() + ray.getDirection() * dist; // Jump up and down and celebrate our achievement doTheHappyDance(); //--------------------------------------------------- I hope that helps. Good luck! cheers, -Ben Scott bs...@ia... Chad Austin wrote: > Ian Overton wants to convert screen coordinates to coordinates on a grid > that he has drawn (with perspective). I've never used gluUnProject > before... Can someone help him? > > Thanks, > Chad > > Ian Overton wrote: > >> Alright I want to figure out how to take the mouse coords and convert >> them to something on the x z plane. I have made a grid and I want to >> be able to click on the grid and know exactly where that click was on >> that grid, so I will be able to make a wall. Problem is I have no idea >> how to do it, cause of the prespective and I've looked everywhere and >> they don't seem to know either. My code is in the broken_metal file. >> >> I have also found something that does kind of what I want, but when I >> try and do it to the grid it always gives huge numbers and it seems it >> does that on that unproject to, but yet it works. I don't know, can >> check it out and see if you can figure it out? >> I believe 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); >> gluUnProject(wx,wy,wz,modelview,projection,viewport,&ox,&oy,&oz); >> >> is the meat and patatos I don't really need to use glreadpixel, >> because I only need two of the three coords. The y coord is -10 >> >> >> >> ------------------------------------------------------------------------ >> >> // GLRect.c >> // The Drawing a simple 3D rectangle program with GLUT >> // OpenGL SuperBible, 2nd Edition >> // Richard S. Wright Jr. >> >> #include <windows.h> >> #include <gl/glut.h> >> #include <vector> >> #include <math.h> >> >> #define DEGTORAD(x) ((x)*0.017453292519943296) >> >> std::vector<int> walls; >> bool gofast=0; >> int window_width=0; >> int window_hieght=0; >> >> struct CAMERA >> { >> float position[3]; >> float orientation[3]; >> } cameraData; >> >> CAMERA pCamera; >> // Called to draw scene >> void RenderScene(void) >> { >> // Clear the window with current clearing color >> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); >> // Save matrix state and do the rotation >> glPushMatrix(); >> glRotatef(pCamera.orientation[0], 1.0f, 0.0f, 0.0f);//turn and >> move the camera to the rigth place >> glRotatef(pCamera.orientation[1], 0.0f, 1.0f, 0.0f); >> glRotatef(pCamera.orientation[2], 0.0f, 0.0f, 1.0f); >> glTranslatef(-pCamera.position[0],pCamera.position[1],pCamera.position[2]); >> >> >> glBegin(GL_LINES); >> glColor3f(0.0f, 1.0f, 1.0f); >> >> for(int y=-500; y<=500; y+=5) //make a grid >> { >> glVertex3i(y,-10,-500); >> glVertex3i(y,-10,500); >> glVertex3i(-500,-10,y); >> glVertex3i(500,-10,y); >> } >> >> glLoadIdentity(); >> glColor3f(1.0f, 1.0f, 1.0f); >> if(!walls.empty()) { >> for(y=0; y<walls.size(); y+=4)//plot my points I made with the >> mouse >> { >> glVertex3i(walls[y],-1,walls[y+1]); >> glVertex3i(walls[y+2],-1,walls[y+3]); >> } >> } >> glEnd(); >> >> // Restore transformations >> glPopMatrix(); >> >> glutSwapBuffers(); >> } >> >> void Keys(unsigned char key, int x, int y) >> { >> float fAngularVelocityX,fAngle; >> if(key == 'a') >> fAngularVelocityX = -5.0f; //look up >> >> if(key == 'z') >> fAngularVelocityX = 5.0f; //look down >> >> if(key == 0x1b)//esc quit >> exit(0); >> >> if(key == 'r' && !gofast) //run >> gofast=1; >> else >> gofast=0; >> >> >> if(key == 'a' || key == 'z') //update the camera >> { >> // Update Rotation angles (clamp the X rotation) >> fAngle = fAngularVelocityX + pCamera.orientation[0]; >> >> if((fAngle < 90.0f) && (fAngle > -90.0f)) >> pCamera.orientation[0] = fAngle; >> >> // Refresh the Window >> glutPostRedisplay(); >> } >> } >> >> void SpecialKeys(int key, int x, int y) >> { >> float fLinearVelocity=1; >> float fAngularVelocityY=0; >> int speed; >> if(gofast) >> speed=10; >> else >> speed=1; >> if(key == GLUT_KEY_UP) //go forward >> fLinearVelocity= 5.0f*speed; >> >> if(key == GLUT_KEY_DOWN) //go backward >> fLinearVelocity= -5.0f*speed; >> >> if(key == GLUT_KEY_LEFT) //turn to the left >> fAngularVelocityY = -5.0f*speed; >> >> if(key == GLUT_KEY_RIGHT) //turn to the right >> fAngularVelocityY = 5.0f*speed; >> >> pCamera.orientation[1] += fAngularVelocityY; >> >> // Update linear position >> pCamera.position[0] = fLinearVelocity * >> (float)(sin(DEGTORAD(pCamera.orientation[1]))) + pCamera.position[0]; >> pCamera.position[2] = fLinearVelocity * >> (float)(cos(DEGTORAD(pCamera.orientation[1]))) + pCamera.position[2]; >> >> // Refresh the Window >> glutPostRedisplay(); >> } >> >> // Setup the rendering state >> void SetupRC(void) >> { >> glEnable(GL_DEPTH_TEST); // Hidden surface removal >> >> // Set clear color to blue >> glClearColor(0.0f, 0.0f, 1.0f, 1.0f); >> >> // Camera initial position and orientation >> // Initially at Origin >> cameraData.position[0] = 0.0f; >> cameraData.position[1] = 0.0f; >> cameraData.position[2] = 0.0f; >> >> // Looking down negative Z Axis (North). Positive X is to the right >> cameraData.orientation[0] = 0.0f; >> cameraData.orientation[1] = 0.0f; >> cameraData.orientation[2] = 0.0f; >> } >> >> /*void moving_mouse (int x, int y) >> { >> int tempx,tempy; >> tempx=-x/(window_width/20) + window_width/20; >> tempy=(window_hieght-y); >> }*/ >> >> void MouseHandler(int button, int state, int x, int y) //if they >> clicked somewhere start making a new wall or finish a wall >> { >> int tempx,tempy; >> if(button == GLUT_LEFT && state == GLUT_DOWN) >> { >> tempx=-sin(DEGTORAD(x))*(window_hieght); >> tempy=cos(DEGTORAD(y))*(window_width); >> walls.push_back(tempx); >> walls.push_back(tempy); >> if(walls.size()%4==0) >> glutPostRedisplay(); >> glutMouseFunc(MouseHandler); >> } >> } >> >> void motion(int x, int y) //does the same thing as mousehandler, but >> it changes the current point they are doing, and if nothing has been >> clicked it marks the first click as the first point and then after as >> the finial point. >> { >> int tempx,tempy; >> tempx=-sin(DEGTORAD(x))*(window_hieght); >> tempy=cos(DEGTORAD(y))*(window_width); >> >> if(walls.size()%4==0) >> { >> walls[walls.size()-2]=tempx; >> walls[walls.size()-1]=tempy; >> glutPostRedisplay(); >> } >> else >> { >> walls.push_back(tempx); >> walls.push_back(tempy); >> } >> } >> >> // Called by GLUT library when the window has chanaged size >> void ChangeSize(GLsizei w, GLsizei h) >> { >> float fAspect; >> >> window_width=w; >> window_hieght=h; >> // Prevent a divide by zero >> if(h == 0) >> h = 1; >> >> // Set Viewport to window dimensions >> glViewport(0, 0, w, h); >> >> // Reset coordinate system >> glMatrixMode(GL_PROJECTION); >> glLoadIdentity(); >> >> fAspect = (float)w/(float)h; >> gluPerspective(45.0,fAspect, 1.0, 500.0); >> glMatrixMode(GL_MODELVIEW); >> glLoadIdentity(); >> } >> >> // Main program entry point >> void main(void) >> { >> glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); >> glutCreateWindow("Broken Metal"); >> glutDisplayFunc(RenderScene); >> //glutFullScreen(); >> glutKeyboardFunc(Keys); >> glutSpecialFunc(SpecialKeys); >> glutReshapeFunc(ChangeSize); >> glutMotionFunc(motion); >> glutMouseFunc(MouseHandler); >> glutPassiveMotionFunc(moving_mouse); >> SetupRC(); >> >> glutMainLoop(); >> } >> >> >> >> ------------------------------------------------------------------------ >> >> /* >> gcc -Wall -lglut -lGLU -lGL unproject.c -o unproject >> */ >> >> #include <GL/glut.h> >> >> void Display(); >> void Reshape(int w,int h); >> void Mouse(int button,int state,int x,int y); >> >> int main(int argc,char **argv) { >> glutInit(&argc,argv); >> glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); >> glutInitWindowSize(500,500); >> glutInitWindowPosition(100,100); >> glutCreateWindow(argv[0]); >> glutDisplayFunc(Display); >> glutReshapeFunc(Reshape); >> glutMouseFunc(Mouse); >> >> glEnable(GL_LIGHTING); >> glEnable(GL_LIGHT0); >> glEnable(GL_DEPTH_TEST); >> >> 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); >> >> glPushMatrix(); >> glRotatef(45,1.0,0.0,0.0); >> glutSolidTorus(4.0,5.0,20,20); >> glPopMatrix(); >> >> glPushMatrix(); >> glDepthMask(GL_FALSE); >> glTranslated(ox,oy,oz); >> glutSolidSphere(0.5,15,15); >> glDepthMask(GL_TRUE); >> glPopMatrix(); >> >> glFlush(); >> } >> >> void Reshape(int w,int h) { >> glViewport(0,0,w,h); >> glMatrixMode(GL_PROJECTION); >> glLoadIdentity(); >> gluPerspective(45.0,(float)w/(float)h,5.0,30.0); >> glMatrixMode(GL_MODELVIEW); >> } >> >> void Mouse(int button,int state,int x,int y) { >> GLint viewport[4]; >> GLdouble modelview[16],projection[16]; >> GLfloat wx=x,wy,wz; >> >> if(state!=GLUT_DOWN) >> return; >> if(button==GLUT_RIGHT_BUTTON) >> exit(0); >> 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); >> gluUnProject(wx,wy,wz,modelview,projection,viewport,&ox,&oy,&oz); >> glutPostRedisplay(); >> } > > > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: ObjectStore. > If flattening out C++ or Java code to make your application fit in a > relational database is painful, don't do it! Check out ObjectStore. > Now part of Progress Software. http://www.objectstore.net/sourceforge > _______________________________________________ > ISUGameDev-devel mailing list > ISU...@li... > https://lists.sourceforge.net/lists/listinfo/isugamedev-devel > |