查找/重新映射 OpenGL ES 坐标平面的边界
Posted
技术标签:
【中文标题】查找/重新映射 OpenGL ES 坐标平面的边界【英文标题】:Finding/Remapping bounds of OpenGL ES coordinate plane 【发布时间】:2015-10-07 02:42:48 【问题描述】:我正在尝试为我的 android 应用程序制作 2D 图形,该应用程序由六个细长的矩形组成,每个矩形的宽度约为屏幕的 1/6,并且等于屏幕的高度。我不确定确定屏幕上 x 和 y OpenGL 坐标平面边界的正确方法。最终我需要编写逻辑来测试触摸事件发生在 6 个矩形中的哪一个,所以我一直试图通过将 OpenGL 的坐标平面重新映射到设备的屏幕坐标平面(原点 (0,0) 是在屏幕的左上角而不是中间。
我这样声明我的六个矩形之一:
private float vertices1[] =
2.0f, 10.0f, 0.0f, // 0, Top Left
2.0f, -1.0f, 0.0f, // 1, Bottom Left
4.0f, -1.0f, 0.0f, // 2, Bottom Right
4.0f, 10.0f, 0.0f, // 3, Top Right
;
但由于我不确定 x 和 y 平面(在 OpenGL 坐标系中)上的可见限制是什么,我没有具体的方法来知道我的矩形需要实例化哪些顶点才能占据 1/6显示器。这样做的理想方法是什么?
我尝试了诸如using glOrthoof() 之类的方法来将 OpenGL 的坐标重新映射为易于使用的设备屏幕坐标:
gl.glViewport(0, 0, width, height);
// Select the projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset the projection matrix
gl.glLoadIdentity();
// Calculate the aspect ratio of the window
GLU.gluPerspective(gl, 45.0f,(float) width / (float) height,0.1f, 100.0f);
gl.glOrthof(0.0f,width,height, 0.0f, -1.0f, 5.0f);
// Select the modelview matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
// Reset the modelview matrix
gl.glLoadIdentity();
但是当我这样做时,我的矩形完全消失了。
【问题讨论】:
【参考方案1】:您当然不想对 2D 图形使用透视投影。这没有多大意义。透视投影是为了……嗯,创建透视投影,这仅在您的对象实际放置在 3D 空间中时才有用。
更糟糕的是,您有两个调用来设置透视矩阵:
GLU.gluPerspective(gl, 45.0f,(float) width / (float) height,0.1f, 100.0f);
gl.glOrthof(0.0f,width,height, 0.0f, -1.0f, 5.0f);
虽然这是合法的,但它很少有意义。如果你这样做,本质上会发生两个预测是连续应用的。所以首先要做的是摆脱gluPerspective()
的调用。
要放置 6 个矩形,您有几个选择。几乎最简单的方法是根本不应用任何转换。这意味着您将在规范化设备坐标(又名 NDC)中指定输入坐标,该坐标在 x 和 y 方向上都是 [-1.0, 1.0] 的范围。因此,对于并排渲染的 6 个矩形,所有矩形的 y 范围为 [-1.0, 1.0],第一个矩形的 x 范围为 [-1.0, -2.0/3.0],[-2.0 /3.0, -1.0/3.0] 为第二个,等等。
另一种选择是使用正交投影,这使得指定矩形更加方便。例如,x 的 [0.0, 6.0] 和 y 的 [0.0, 1.0] 范围会特别容易:
gl.glOrthof(0.0f, 6.0f, 0.0f, 1.0f, -1.0f, 1.0f);
那么所有矩形的 y 范围为 [0.0, 1.0],第一个矩形的 x 范围为 [0.0, 1.0],第二个矩形的 x 范围为 [1.0, 2.0],以此类推
顺便说一句,如果你刚开始接触 OpenGL,我会传 ES 1.x,直接学习 ES 2.0。 ES 1.x 在这一点上是一个遗留 API,我不会将它用于任何新的开发。
【讨论】:
感谢您的回复!我目前正在切换到 GLES 2.0;您概述的两种解决方案是否适用于 GLES 2.0?以上是关于查找/重新映射 OpenGL ES 坐标平面的边界的主要内容,如果未能解决你的问题,请参考以下文章