使用java(适用于Android)学习OpenGL ES 2.0。
目前,我正在使用以下内容来设置ViewPort,ViewMatrix和Frustum并进行翻译:
GLES20.glViewport(0, 0, width, height) // max, full screen
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY,
lookZ, upX, upY, upZ);
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
Matrix.translateM(mModelMatrix, 0, x, y, z);
这是我想做的事情:
简而言之,我想在设备屏幕上投影时,根据它们的位置和形状,尽可能真实地显示对象。 (在这个阶段,我不关心纹理,灯光等)。
问题:
假设我想要显示一个立方体(每个边缘长4英寸),就好像它漂浮在10"的显示屏后面20英寸处。我直接握在我眼前16英寸的平板电脑。视线位于(沿)z轴上,垂直穿过平板显示屏的中心,立方体的中心位于z轴上。
我应该传递给上述两个函数的参数的正确值是什么,以设置ViewMatrix和Frustum来模拟上述情况?
如果不使用SCALING,那么在模型空间中定义的多维数据集边缘的值(长度)是什么,以(0,0,0)为中心?
最后,z的值应该传递给上面的翻译函数,以便立方体显示在显示屏后面20英寸处?
我是否需要设置其他内容?
答案 0 :(得分:2)
让我们一步一步地完成这一过程。首先,使用inch
作为世界空间单位是有意义的。这样,您就不必在单位之间进行转换。
让我们从投影开始吧。如果您只希望平板电脑后面的对象可见,那么您只需将znear
设置为16. zfar
可以任意选择(取决于场景)。
接下来,我们需要垂直视野。如果平板电脑的屏幕高h inches
(可以根据宽高比和对角线长度计算。如果您需要此计算,请发表评论),fovy
可以按如下方式计算:
float fovy = 2 * atan(h / 2 / 16); //screen is 16 inches away
//needs to be converted to degrees
Matrix.perspectiveM(mProjectionMatrix, 0, fovy * 180.0f / PI, aspect, znear, zfar);
那已经是更难的部分。
让我们继续查看视图矩阵。如果您的相机未与世界坐标系对齐,则使用视图矩阵。现在它取决于您想要如何设置世界坐标系。如果你想让眼睛成为原点,你就根本不需要视图矩阵。我们也可以将显示指定为原点,如下所示:
//looking from 16 inches in front of the tablet to the origin
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 16, 0, 0, 0, 0, 1, 0);
定位立方体同样容易。如果你希望它的边长为4英寸,那么制作一个边长为4的立方体。如果你想让它的中心位于屏幕后面20英寸处,将它翻译一定数量(假设上面的视图矩阵): / p>
Matrix.translateM(mModelMatrix, 0, 0, 0, -20);