我希望在3D中获得鼠标点击位置。下面是我的代码,它的简单,它有什么不对。在哪里我做错了..?为什么我没有得到x和y的确切值?任何想法?
void glPerspective()
{
glViewport(0, 0, WINDOW_SIZE_W, WINDOW_SIZE_H);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLdouble)WINDOW_SIZE_W / (GLdouble)WINDOW_SIZE_H, 0.1, 100000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, m_zoom, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glPerspective(); // perspective view
Some_rotation_and_translation();
glGetDoublev( GL_PROJECTION_MATRIX, OGLMprojection );
glGetDoublev( GL_MODELVIEW_MATRIX, OGLMmodelview );
glGetIntegerv( GL_VIEWPORT, OGLMviewport );
Render_Triangular_model();
glPopMatrix();
swapbuffer();
}
GLpoint GetOGLMousePos(GLint x, GLint y)
{
GLdouble winX = 0.0, winY = 0.0, winZ = 0.0;
GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;
winX = (float)x;
winY = (float)OGLMviewport[3] - (float)y; // invert winY so that down lowers value
glReadPixels( x, GLint(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, OGLMmodelview, OGLMprojection, OGLMviewport, &posX, &posY, &posZ);
return GLpoint(posX, posY, posZ);
}
答案 0 :(得分:4)
当您致电glGetDoublev( GL_MODELVIEW_MATRIX, OGLMmodelview )
时,我认为您正在为“三角模型”获取 world 变换矩阵。该矩阵表示从局部对象坐标到世界坐标的变换。
我很确定gluUnProject
假设它使用 view 变换矩阵进行操作,该矩阵从世界坐标映射到相机空间坐标。
所以,我认为这是错配,并且可以通过将glGet *调用移出glPushMatrix - glPopMatrix块来修复错误。
实际上,我认为获取GL_PROJECTION_MATRIX
和GL_VIEWPORT
是可以而且应该在鼠标功能中完成的事情,如本示例所示(Tomas Hamala):
/*
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|GLUT_DEPTH);
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();
}
这是一个完整的,有效的示例,即使您无法修复现有代码,也可以使用它。
希望有所帮助。
答案 1 :(得分:2)
感谢您宝贵的时间。现在它解决了。我在下面提到了这个问题。通常我们习惯在编程期间忽略(浮点或双精度)变量,我认为我们不应该这样做。
GLpoint GetOGLMousePos(GLint x, GLint y)
{
GLfloat winX = 0.0, winY = 0.0, winZ = 0.0; **// never ever make a mistake between float and double.
I wasted my 4 days to solve this and the problem was, I was using GLdouble here instead of GLfloat.
Try GLdouble here you will see a hell difference in output values.**
GLdouble posX = 0.0, posY = 0.0, posZ = 0.0;
winX = (float)x;
winY = (float)OGLMviewport[3] - (float)y; // invert winY so that down lowers value
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, OGLMmodelview, OGLMprojection, OGLMviewport, &posX, &posY, &posZ);
return GLpoint(posX, posY, -posZ); // invert z value
}