Android 带有 MVP 矩阵的原生 GLES 2.0 空白屏幕

Android Native GLES 2.0 Blank Screen With MVP Matrix

我正在使用 c++ 中的 gles2.0 绘制一个简单的四边形。如果我用基本的顶点着色器绘制它就没有问题,这就是结果

uniform mat4 u_mvp;
attribute vec4 a_Position;
void main(){
   gl_Position = a_Position;
}

如果我添加 MVP 矩阵

gl_Position = u_mvp * a_Position;

然后屏幕上什么也没有。

这是透视矩阵:

Matrix4 Matrix4::getPerspective(float angle, float ratio, float near, float far) {
    // angle = 45; ratio = 1.438; near = 1; far = 100
    Matrix4 matrix;

    float top = (float)(near * Math::tangentDegrees(angle / 2.0f));
    float bottom = -top;

    float right = top * ratio;
    float left = -right;

    matrix.m[0] = (2 * near) / (right - left);
    matrix.m[1] = 0.0f;
    matrix.m[2] = (right + left) / (right - left);
    matrix.m[3] = 0.0f;

    matrix.m[4] = 0.0f;
    matrix.m[5] = (2 * near) / (top - bottom);
    matrix.m[6] = (top + bottom) / (top - bottom);
    matrix.m[7] = 0.0f;

    matrix.m[8] = 0.0f;
    matrix.m[9] = 0.0f;
    matrix.m[10] = -(far + near) / (far - near);
    matrix.m[11] = -(2 * far * near) / (far - near);

    matrix.m[12] = 0.0f;
    matrix.m[13] = 0.0f;
    matrix.m[14] = -1.0f;
    matrix.m[15] = 0.0f;

    return matrix;
}

得到modelView矩阵如下:

modelView = translation * rotation * scale
mvp = perspective * modelView

这个乘法的每个元素都是按照这个例子得到的 http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/ 并且所有这些都在单位矩阵中初始化。

通过这个命令我获得了句柄

transformUniformHandle = (GLuint)glGetUniformLocation(getProgramId(), "u_mvp");

使用此命令我在着色器中设置了 mvp 矩阵(尝试了 GL_FALSE、GL_TRUE)

glUniformMatrix4fv(transformUniformHandle, 1, GL_TRUE, modelViewProjection.m);

鉴于您没有展示完整的代码,我不能确定,但​​可能是您在调用 glUniformMatrix4fv 之前没有调用 glUseProgram。也可能是您的三角形被投影矩阵剪掉了。确保点在裁剪范围内。如果这不能解决问题,您应该从 glGetError 中得到错误。此页面将解释其用法:OpenGL error checking

OpenGL 使用列优先存储矩阵,而您的投影矩阵是按行优先顺序设置的。所以需要转置矩阵元素的顺序:

matrix.m[0] = (2 * near) / (right - left);
matrix.m[4] = 0.0f;
matrix.m[8] = (right + left) / (right - left);
matrix.m[12] = 0.0f;

matrix.m[1] = 0.0f;
matrix.m[5] = (2 * near) / (top - bottom);
matrix.m[9] = (top + bottom) / (top - bottom);
matrix.m[13] = 0.0f;

matrix.m[2] = 0.0f;
matrix.m[6] = 0.0f;
matrix.m[10] = -(far + near) / (far - near);
matrix.m[14] = -(2 * far * near) / (far - near);

matrix.m[3] = 0.0f;
matrix.m[7] = 0.0f;
matrix.m[11] = -1.0f;
matrix.m[15] = 0.0f;

您试图通过将 GL_TRUE 作为此处的第三个参数传递来转置矩阵:

glUniformMatrix4fv(transformUniformHandle, 1, GL_TRUE, modelViewProjection.m);

这在 ES 2.0 中不受支持,唯一有效的参数值是 GL_FALSE。在此之后调用 glGetError() 时,您将看到 GL_INVALID_VALUE 错误。如果您的 OpenGL 代码有任何问题,调用 glGetError() 应该是例行公事。

如果你真的愿意,你可以保持矩阵行优先,并通过乘以右边的向量相应地更改着色器代码:

gl_Position = a_Position * u_mvp;

但最好只对矩阵使用列优先顺序。

此外,您没有显示模型视图矩阵。您必须确保视图变换沿负 z 方向平移几何体,以便将其放置在您正在使用的投影变换的近平面和远平面之间。