OpenGL ES 2.0 :使用透视投影翻转 y 坐标



我想知道在使用透视投影时是否有一种简单的方法来翻转 y 坐标?关于这个问题的线索似乎集中在正射投影上。我正在将基于 Canvas 的游戏转换为 OpenGL ES 2.0,并且具有相对复杂的碰撞检测。很多语法都基于 y 轴从屏幕顶部以 0 开始,在屏幕底部结束,例如 2560

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
game_width = width;
game_height = height;
GLES20.glViewport(0, 0, width, height);
// while the width will vary as per aspect ratio.
final float ratio = (float) width / height;
final float left = -ratio;
final float right = ratio;
final float bottom = -1.0f;
final float top = 1.0f;
final float near = 1f;
final float far = 40.0f;
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}

使用正交矩阵或视锥矩阵几乎没有区别,因此最简单的答案是简单地交换bottomtop参数,甚至将它们设置为您需要的任何参数。

但是要多研究一下视锥体:

此方法的作用是创建一个矩阵,该矩阵将根据与near的距离缩放对象。它的设计使near的对象按1.0缩放。例如,如果你把一个坐标leftrighttopbottom的矩形放成xy,然后nearz,除了视锥之外不使用其他矩阵,结果将完全是一个全屏矩形。

通常不会绘制靠近near的对象,而那些更远的对象将根据除far以外的所有参数线性缩放。far参数只影响对象停止绘制的位置。因此,在大多数情况下,如果您输入一个非常大的far值,但放置一个非常重要的值,则没有区别;具有大far值的效果将是深度测试的精度。因此,在使用深度缓冲区时,请确保此值尽可能小,但仍足够大以查看所有对象。

在大多数情况下,我们将视场视锥定义为角度。您可以定义常量nearfarfov,然后根据这些常量计算边界参数,如right = tan(fov)*near*0.5top = tan(fov)*near*0.5*(viewHeight/viewWidth)。这些只是一些例子,因为有很多方法可以定义它。

在您的情况下,没有理由不随心所欲地定义这些值。所以有类似left = 0.0right = widthbottom = heighttop = 0.0的东西。但是,您仍然需要定义必须为正的近值和远值。然后,如果您的对象在 0.0 距离处,则它们将被全部剪裁。

为了避免这种情况,最好使用lookAt过程,该过程将生成另一个矩阵,该矩阵可以定义场景中的"相机"位置。只需将其放在z=-near,您应该像使用正交投影一样看到对象。现在的问题是,如果你想通过将相机靠近对象来"放大",这些对象将不会再次被绘制。

要实现类似的东西,您需要为例如maxZoom = 10.0定义一些最大比例。然后你要做的是将所有边界参数(topleft...)除以该值。您还需要将此比例应用于lookAt矩阵中的z值,以查看场景未缩放。

所以一般来说,要翻转坐标,你可以修改边框值,或者你可以玩矩阵。还有其他方法,但这些都是非常标准的。我希望这能为您澄清一些事情。

最新更新