OpenGLES中的屏幕到世界坐标转换是一项简单的任务吗?

Rex*_*ids 5 iphone opengl-es eaglview

iPhon e 上的屏幕到世界问题

我有一个在EAGLView中渲染的3D模型(CUBE),我希望能够检测到何时触摸立方体的给定面的中心(从任何方向角度).听起来很简单但不是......

问题:
如何准确地将屏幕坐标(触摸点)与世界坐标(OpenGL 3D空间中的位置)相关联?当然,将给定点转换为屏幕/世界轴的"百分比"似乎是合乎逻辑的解决方案,但是当我需要缩放或旋转3D空间时会出现问题.注意:旋转和放大和缩小3D空间将改变2D屏幕坐标与3D世界坐标的关系...此外,您必须允许3D空间中的视点和对象之间的"距离" .起初,这似乎是一个"简单的任务",但是当您实际检查需求时会发生变化.而且我没有找到人们在iPhone上这样做的例子.这通常是怎么做的?

一个"简单"的任务?:
当然,人们可能会承担编写API的任务,作为屏幕和世界之间的中间人,但创建这样一个框架的任务需要一些严肃的设计,并且可能需要"时间"做-不是可以成为一个载人 4小时... 4小时正好是我的最后期限.

问题:

  • 有哪些最简单的方法可以了解我是否触及了iPhone OpenGL ES世界中3D空间中的特定位置?

Lou*_*our 7

您现在可以在http://code.google.com/p/iphone-glu/中找到gluUnProject.我与iphone-glu项目没有联系,还没有尝试过我自己,只是想分享这个链接.

你会如何使用这样的功能?本PDF提到:

实用程序库例程gluUnProject()执行转换的这种反转.给定一个位置的三维窗口坐标以及影响它们的所有变换,gluUnProject()返回它起源的世界坐标.

int 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);
Run Code Online (Sandbox Code Playgroud)

使用由模型视图矩阵(modelMatrix),投影矩阵(projMatrix)和视口(视口)定义的变换将指定的窗口坐标(winx,winy,winz)映射到对象坐标.生成的对象坐标以objx,objy和objz返回.该函数返回GL_TRUE,表示成功,或GL_FALSE,表示失败(例如不可逆矩阵).此操作不会尝试将坐标剪切到视口或消除glDepthRange()之外的深度值.

试图扭转转型过程存在固有的困难.二维屏幕位置可以源自三维空间中整条线上的任何位置.为了消除结果的歧义,gluUnProject()要求提供窗口深度坐标(winz),并根据glDepthRange()指定winz.对于glDepthRange()的默认值,0.0的winz将请求近剪裁平面处的变换点的世界坐标,而1.0的winz将请求远剪裁平面处的点.

例3-8(再次参见PDF)通过读取鼠标位置并确定变换它的近和远剪裁平面的三维点来演示gluUnProject().计算出的世界坐标打印到标准输出,但渲染窗口本身只是黑色.

在性能方面,我通过Google快速发现了这一点,作为使用gluUnProject可能不想做的事情的一个示例,其中包含可能导致更好替代方案的链接.我完全不知道它对iPhone有多适用,因为我仍然是OpenGL ES的新手.一个月后再问我一次.;-)


Mic*_*and 1

目前有两种解决方案。他们都应该实现最终目标,尽管方式不同:他们不是回答“鼠标下的世界坐标是什么?”,而是回答“鼠标下渲染什么对象?”的问题。

一种是将模型的简化版本绘制到屏幕外缓冲区,使用不同的颜色渲染每个面的中心(并调整照明,以便保留相同的颜色)。然后,您可以检测缓冲区中的这些颜色(例如像素图),并将鼠标位置映射到它们。

另一种是使用OpenGL拾取。这里有一个看起来不错的教程。基本思想是将 OpenGL 置于选择模式,将视口限制为感兴趣点周围的一个小(可能 3x3 或 5x5)窗口,然后使用 OpenGL“名称”(整数)渲染场景(或其简化版本)标识符)来识别构成每个面的组件。在此过程结束时,OpenGL 可以为您提供在选择视口中渲染的名称列表。将这些标识符映射回原始对象将使您可以确定鼠标光标下方的对象。