19,464
社区成员
发帖
与我相关
我的任务
分享
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
int MOUSE_BUTTON = -1;
int MOUSE_POS_X = 0;
int MOUSE_POS_Y = 0;
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity (); /* clear the matrix */
glColor3f (1.0, 1.0, 1.0);
glTranslatef(0.0f, 0.0f, -3.0f);
glPushMatrix();
{
glTranslatef(0.0f, 0.0f, -2.0f);
glBegin( GL_QUADS );
{
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, 0.0f );
glVertex3f( 0.0f, 1.0f, 0.0f );
}
glEnd();
}
glPopMatrix();
if ( MOUSE_BUTTON == GLUT_LEFT_BUTTON )
{
GLint viewport[ 4 ];
GLdouble projection[ 16 ];
GLdouble modelview[ 16 ];
GLfloat winX,winY,winZ;
GLdouble posX,posY,posZ;
glGetIntegerv( GL_VIEWPORT, viewport );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
winX = (GLfloat)MOUSE_POS_X;
winY = (GLfloat)( viewport[3] - MOUSE_POS_Y );
glReadBuffer(GL_BACK);
glReadPixels( winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ );
printf( "screen = %f,%f,%f\n", winX, winY, winZ );
printf( "world = %f,%f,%f\n", posX, posY, posZ );
MOUSE_BUTTON = -1;
}
glutSwapBuffers();
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
glEnable( GL_DEPTH_TEST );
}
void mouse_func(int button, int state, int x, int y)
{
if ( state == GLUT_UP )
{
MOUSE_BUTTON = button;
MOUSE_POS_X = x;
MOUSE_POS_Y = y;
display();
}
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective( 45.0f, w/h, 0.1, 100.0 );
glMatrixMode (GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 400);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse_func);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
GLint GLAPIENTRY
gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
const GLdouble modelMatrix[16],
const GLdouble projMatrix[16],
const GLint viewport[4],
GLdouble *objx, GLdouble *objy, GLdouble *objz)
{
double finalMatrix[16]; //最终矩阵
double in[4];
double out[4];
__gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); //finalMatrix = 世界变换*相机变换*投影变换
if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE); 逆矩阵(从投影坐标到世界坐标)
in[0]=winx;//客户区窗口坐标x
in[1]=winy;//客户区窗口坐标y
in[2]=winz;//坐标z(深度)
in[3]=1.0; //w分量
//viewport[0] = 窗口左端坐标(在以ScreenCoordinate作坐标系的时候有用)viewport[2] = width viewport[3] = height
/* Map x and y from window coordinates */
in[0] = (in[0] - viewport[0]) / viewport[2]; // x([-1,+1]) = 2 *(screenPosX - screenLeft) / screenWidth - 1
in[1] = (in[1] - viewport[1]) / viewport[3]; // x([-1,+1]) = 2 *(screenPosY - screenTop) / screenHeight - 1
/* Map to range -1 to 1 */
in[0] = in[0] * 2 - 1;
in[1] = in[1] * 2 - 1;
in[2] = in[2] * 2 - 1;
__gluMultMatrixVecd(finalMatrix, in, out); //将已经转化到标准设备空间的坐标*逆矩阵 = 世界空间坐标
if (out[3] == 0.0) return(GL_FALSE);
out[0] /= out[3]; out[3]为w分量,除w分量投影到三维空间
out[1] /= out[3];
out[2] /= out[3];
*objx = out[0]; //[objx,objy,objz] =[x,y,z]
*objy = out[1];
*objz = out[2];
return(GL_TRUE);
}