OpenGL中没有一个规则只有一个mvpMatrix。这很好,因为您可以自定义很多视图。
如果您的所有应用程序都基于您在此处显示的 mvpMatrix,我建议您为您要求的提案创建另一个 mvpMatrix:将视图的中心放在左上角。
所以,答案很简单,让我们重新创建每个矩阵。首先,查看Matrix:
Matrix.setLookAtM(viewMatrix, 0,
0, 0, 6, //eye
0, 0, 0, //center
0, 1, 0); //UP *remove your -1
魔术如下。你必须颠倒底部和顶部:
float screenRatio = (float) width / height;
Matrix.orthoM(projectionMatrix, 0,
0, screenRatio, // left, right
1, 0, // bottom, top <----Solution is invert bottom with top
-1, 10); // near, far
最后:
Matrix.multiplyMM(
viewProjectionMatrix, 0,
projectionMatrix, 0,
viewMatrix, 0);
PS:不需要改变GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight);
OpenGL对于这个问题有很多解决方案,因为你可以尽可能地处理所有矩阵。
另一种解决方案是自定义您自己的矩阵,而不使用Matrix.orthoM(..)
or Matrix.frustum(..)
:
public static final float[] topLeftMatrix(int width, int height){
float matrix[] = new float[16];
// This is inverse of viewPort matrix
matrix[0] = 2.0f/width;
matrix[1] = 0;
matrix[2] = 0;
matrix[3] = 0;
matrix[4] = 0;
matrix[5] = -2.0f/height;
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 0;
matrix[9] = 0;
matrix[10] = 1;
matrix[11] = 0;
matrix[12] = -1;
matrix[13] = 1;
matrix[14] = 0;
matrix[15] = 1;
return matrix;
}
上面的这个矩阵非常适合处理像素上的对象(例如用户界面)。
为了充分理解,我建议您阅读这篇文章:使用 OpenGL 的 3D 图形。它对我理解 opengl 的魔力帮助很大。
P.S:您的着色器有错误。将矩阵 4x4 乘以向量 4x1 的正确方法是:
gl_Position = uMVPMatrix * aPosition;