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

时间:2017-06-20 19:05:39

标签: android opengl-es-2.0 projection-matrix frustum

我想知道在使用透视投影时是否有一种简单的方法来翻转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);

}

1 个答案:

答案 0 :(得分:1)

使用正交矩阵或平截头体矩阵的差异非常小,因此最简单的答案是简单地交换bottomtop参数,甚至可以将它们设置为您需要的任何参数。

但要更多地考虑视锥体:

这种方法的作用是创建一个矩阵,根据与near的距离来缩放对象。它的设计使near处的对象按1.0缩放。例如,如果您将一个坐标为leftrighttopbottom的矩形设为xy,那么{{1}如near并且不使用其他矩阵,但截头锥体的结果将是一个全屏矩形。

通常不会绘制更接近z的对象,并且将根据所有参数(near)进行线性缩放。 far参数只会影响您的对象停止绘制的位置。因此,在大多数情况下,如果你设置一个非常大的far值,但是一个非常重要,那么没有区别;具有大far值的效果将是深度测试的精度。因此,当使用深度缓冲区时,请确保此值尽可能小,但仍足以看到所有对象。

在大多数情况下,我们用视角定义视锥体作为角度。您可以定义常量farnearfar,然后根据fovright = tan(fov)*near*0.5计算边界参数。这些只是一些例子,因为有很多方法可以定义它。

在您的情况下,没有理由不随意定义这些值。所以有top = tan(fov)*near*0.5*(viewHeight/viewWidth)left = 0.0right = widthbottom = height之类的内容。但是你仍然需要定义必须为正的近远值。然后,如果你的物体距离为0.0,那么它们都将被剪裁。

为了避免这种情况,最好使用top = 0.0程序生成另一个矩阵,该矩阵可以定义" camera"在你的场景中的位置。只需将其放到lookAt,您就应该看到与使用正交投影完全相同的对象。现在的问题是,如果你想放大"放大"通过将相机放在靠近物体的地方,这些物体将不再被绘制。

要实现类似的功能,您需要为实例z=-near定义一些最大比例。那么你要做的是将所有边界参数(maxZoom = 10.0top ...)除以该值。您还可以将此比例应用于left矩阵中的z值,以查看场景未缩放。

因此,一般来说,要翻转坐标,您可以修改边框值,也可以看看矩阵。还有其他方法,但这些都非常标准。我希望这能为你解决一些问题。