openGL中用gluUnProject获得深度坐标的问题

storylike 2009-12-15 12:23:25
我是opengl新手。打算用鼠标点击屏幕来获取屏幕坐标的深度。在main中用glClearDepth(1.0f)把深度缓存都设为1.0了,然后在场景中画了一个正方形,当我用鼠标获取屏幕坐标然后再用 gluUnProject反投影获得相应世界坐标的时候发现获得的坐标很不准(包括深度坐标),找了很久都不知道问题出在哪里。。。哪位达人帮帮忙看看问题在哪,代码如下:

#include <GL/glut.h>
#include <GL/glu.h>
#include <conio.h>
#include <stdlib.h>
#include <GL/glaux.h>
#include <fstream>
#include <math.h>



int ww=600,hh=600;
int mouseX,mouseY;


GLint viewport[4],winX,winY,viewportX,viewportY;
GLdouble modelview[16];
GLdouble projection[16];

GLfloat viewportZ,winZ;
GLdouble posX,posY,posZ;






void mouse(int button,int state,int x,int y)
{ if (state==GLUT_DOWN&&button==GLUT_LEFT_BUTTON)
{

winX=winY=winZ=0.0;
posX=posY=posZ=0.0;
viewportZ=viewportY=viewportX=0.0;
winX=x;
winY=y;

viewportX=winX;
viewportY=hh-y;
glReadBuffer(GL_FRONT);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);



//获得屏幕坐标对应世界坐标的深度
glReadPixels(viewportX,viewportY, 1,1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

viewportZ=winZ;
//获得相应世界坐标
gluUnProject(viewportX, viewportY, viewportZ, modelview, projection, viewport, &posX, &posY, &posZ);


}


}

void init()
{
//设置观察和投影方式
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,-400,400,0,0,0,0,1,0);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60, 1, 0, 1000);

}



void reshape(GLsizei w,GLsizei h)
{

ww=w;
hh=h;
glViewport(0,0,w,h);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60., (double)w/(double)h, 1, 900.0);
glMatrixMode(GL_MODELVIEW);

}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,1.0,0.0);

glPolygonMode (GL_FRONT, GL_FILL);
glPolygonMode (GL_BACK, GL_LINE);
glBegin(GL_QUADS);

glVertex3f(-256.0f,-256.0f,0.0f);
glVertex3f(256.0f,-256.0f,0.0f);
glVertex3f(256.0f,256.0f,0.0f);
glVertex3f(-256.0f,256.0f,0.0f);
glEnd();


glutSwapBuffers();
}
int main(int argc, char ** argv)
{
glutInit(& argc, argv);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);

glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);

glutInitWindowSize(600,600);
glutInitWindowPosition(0,0);
glutCreateWindow("三维场景");
init();
glutDisplayFunc(display);

glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(mousemove);

glutMainLoop();
}
...全文
1092 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
peng_weida 2010-12-16
  • 打赏
  • 举报
回复
路过学习!以后可能会 遇到
waytofall 2010-12-09
  • 打赏
  • 举报
回复
再补充下,比如,将一个大的图片缩小,那么所有原图中的点对应在缩小后图的点能得出准确的值,
而将一个小的图片放大,就得不到了……数据在压缩之中损失了……
waytofall 2010-12-09
  • 打赏
  • 举报
回复
楼主,个人见解哈,我觉得,反变换本身就存在着误差,或者投影变换时不可逆的……而且深度值是用float村的,计算机浮点数本身就是不精确的,计算中存在太多舍如的误差……
opengl初学,一些想法,仅供参考
fandh 2009-12-17
  • 打赏
  • 举报
回复
gluPerspective实际与glFrushum效果是一样的,应该是一个锥形吧
建议使用glOrtho
不知道我理解的是否对,另外,我不是大牛,真正的大牛一般不来这上面混!
storylike 2009-12-16
  • 打赏
  • 举报
回复
晕,大牛们给个点拨撒
storylike 2009-12-15
  • 打赏
  • 举报
回复
我在Z=0平面画了个绿色的正方形,然后设置了观察方式;打算点鼠标,得到屏幕坐标(winX,winY),因为屏幕上显示的点都有一个深度值,所以再通过glReadPixels在帧缓存中获取此点的深度坐标存放待winZ中;预期点在屏幕绿色的的区域内(正方形上)会得到一个小于(0,1)的数(深度),如果点在其他黑色的地方,得到一个=1的数(没有模型遮挡,深度最大)。但实际上,运行上面的代码出现winZ并没有获得想要的值,偏差很大,不知道怎么回事
fandh 2009-12-15
  • 打赏
  • 举报
回复
楼主想做捕捉么?捕捉最好是三维投影到二维然后再捕捉,如果二维转化为3维本身不准的!
storylike 2009-12-15
  • 打赏
  • 举报
回复
我是这样想的,一开始,先用glClearDepth(1.0f) 将深度缓存全部清为1.0,打开深度测试glEnable(GL_DEPTH_TEST),定义测试函数glDepthFunc(GL_LEQUAL);然后再画正方形,这样屏幕上在正方形内的点由于深度小于1而得到重置,这样就可以通过获得点击点的深度坐标来得知其是否位于正方形内部
fandh 2009-12-15
  • 打赏
  • 举报
回复
不行的,鼠标点所在的三维面你不能确定!所以,你根本不能确定鼠标的具体的三维点,只能计算出一条射线!
但是,具体那个三维点,我不知道怎么确定!
storylike 2009-12-15
  • 打赏
  • 举报
回复
是啊。我是这样想的:鼠标点击只能获得viewport中的x、y值,但可以从帧缓存中得到选中点的深度坐标,因为屏幕显示的是深度最小的点,这样的话就可以求Z值了(模型矩阵和投影矩阵都通过glLookAt和glPerspective都是已知的)
fandh 2009-12-15
  • 打赏
  • 举报
回复
你是想将鼠标点显示出3维坐标点,对吧!
那你鼠标点所在的面知道么?还是投影!
storylike 2009-12-15
  • 打赏
  • 举报
回复
可是我想直接得到鼠标选中点的坐标啊,不是说判断一个三维空间的物体在二维屏幕投影有没有被鼠标选中的问题。不知道是我程序有问题还是glReadPixels得到的深度本来就不准确,这问题困扰了喔很长时间
fandh 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 storylike 的回复:]
我在Z=0平面画了个绿色的正方形,然后设置了观察方式;打算点鼠标,得到屏幕坐标(winX,winY),因为屏幕上显示的点都有一个深度值,所以再通过glReadPixels在帧缓存中获取此点的深度坐标存放待winZ中;预期点在屏幕绿色的的区域内(正方形上)会得到一个小于(0,1)的数(深度),如果点在其他黑色的地方,得到一个=1的数(没有模型遮挡,深度最大)。但实际上,运行上面的代码出现winZ并没?-
[/Quote]
你是准备用鼠标选中点吧(捕捉),如果是这样,先计算三维坐标在当前平面的投影!然后,用投影后的点与当前的鼠标点的距离是否小于一定的值做是否捕捉的判断!
degree_37 2009-12-15
  • 打赏
  • 举报
回复
opengl获得三维深度,确实是个比较头疼的问题,哪个环节参数不对,就得不到正确的值,我前段时间也整了好长时间,还是没结果,关注~

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧