我想知道在使用透视投影时是否有一种简单的方法来翻转 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);
}
使用正交矩阵或视锥矩阵几乎没有区别,因此最简单的答案是简单地交换bottom
和top
参数,甚至将它们设置为您需要的任何参数。
但是要多研究一下视锥体:
此方法的作用是创建一个矩阵,该矩阵将根据与near
的距离缩放对象。它的设计使near
的对象按1.0
缩放。例如,如果你把一个坐标left
、right
、top
、bottom
的矩形放成x
和y
,然后near
z
,除了视锥之外不使用其他矩阵,结果将完全是一个全屏矩形。
通常不会绘制靠近near
的对象,而那些更远的对象将根据除far
以外的所有参数线性缩放。far
参数只影响对象停止绘制的位置。因此,在大多数情况下,如果您输入一个非常大的far
值,但放置一个非常重要的值,则没有区别;具有大far
值的效果将是深度测试的精度。因此,在使用深度缓冲区时,请确保此值尽可能小,但仍足够大以查看所有对象。
在大多数情况下,我们将视场视锥定义为角度。您可以定义常量near
、far
和fov
,然后根据这些常量计算边界参数,如right = tan(fov)*near*0.5
和top = tan(fov)*near*0.5*(viewHeight/viewWidth)
。这些只是一些例子,因为有很多方法可以定义它。
在您的情况下,没有理由不随心所欲地定义这些值。所以有类似left = 0.0
、right = width
、bottom = height
和top = 0.0
的东西。但是,您仍然需要定义必须为正的近值和远值。然后,如果您的对象在 0.0 距离处,则它们将被全部剪裁。
为了避免这种情况,最好使用lookAt
过程,该过程将生成另一个矩阵,该矩阵可以定义场景中的"相机"位置。只需将其放在z=-near
,您应该像使用正交投影一样看到对象。现在的问题是,如果你想通过将相机靠近对象来"放大",这些对象将不会再次被绘制。
要实现类似的东西,您需要为例如maxZoom = 10.0
定义一些最大比例。然后你要做的是将所有边界参数(top
,left
...)除以该值。您还需要将此比例应用于lookAt
矩阵中的z
值,以查看场景未缩放。
所以一般来说,要翻转坐标,你可以修改边框值,或者你可以玩矩阵。还有其他方法,但这些都是非常标准的。我希望这能为您澄清一些事情。