我想知道在使用透视投影时是否有一种简单的方法来翻转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);
}
答案 0 :(得分:1)
使用正交矩阵或平截头体矩阵的差异非常小,因此最简单的答案是简单地交换bottom
和top
参数,甚至可以将它们设置为您需要的任何参数。
但要更多地考虑视锥体:
这种方法的作用是创建一个矩阵,根据与near
的距离来缩放对象。它的设计使near
处的对象按1.0
缩放。例如,如果您将一个坐标为left
,right
,top
,bottom
的矩形设为x
和y
,那么{{1}如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
之类的内容。但是你仍然需要定义必须为正的近远值。然后,如果你的物体距离为0.0,那么它们都将被剪裁。
为了避免这种情况,最好使用top = 0.0
程序生成另一个矩阵,该矩阵可以定义" camera"在你的场景中的位置。只需将其放到lookAt
,您就应该看到与使用正交投影完全相同的对象。现在的问题是,如果你想放大"放大"通过将相机放在靠近物体的地方,这些物体将不再被绘制。
要实现类似的功能,您需要为实例z=-near
定义一些最大比例。那么你要做的是将所有边界参数(maxZoom = 10.0
,top
...)除以该值。您还可以将此比例应用于left
矩阵中的z
值,以查看场景未缩放。
因此,一般来说,要翻转坐标,您可以修改边框值,也可以看看矩阵。还有其他方法,但这些都非常标准。我希望这能为你解决一些问题。