android opengl es 2.0 glm 投影不工作

android opengl es 2.0 glm projection not working

我正在使用 c/c++ (NDK) for android 在 opengl es 2.0 中编程。由于 android 没有官方的 C++ 库,我使用的是 GLM 库 !

到目前为止,我可以在黑色背景上绘制一个白色三角形,而无需应用任何 projection/frustum 或 camera/view 矩阵。当然,这会导致三角形沿屏幕宽度缩放。

然而,一旦我应用相机和投影变换,三角形就会从场景中消失,只出现背景颜色。

这是相关代码:

float triangleCoords[] = {   // in counterclockwise order:
           0,  1, 0, // top
          -1, 0, 0, // bottom left
           1, 0, 0  // bottom right
  };

std::string vertexShaderCode =
        "attribute vec4 vPosition; "
        "uniform mat4 uMVPMatrix;  "
        "void main() {"
        "  gl_Position = uMVPMatrix*vPosition;"
        "}";

    std::string fragmentShaderCode =
        "precision mediump float;"
        "uniform vec4 vColor;"
        "void main() {"
        "  gl_FragColor = vColor;"
        "}";

    mvpMatrix=glm::translate(mvpMatrix,vec3(0,-0.5,0));

    mvpMatrix*=glm::lookAt(vec3(0,0,-3),vec3(0,0,0),vec3(0,1,0));

    mvpMatrix*=glm::frustum(-1.0f,1.0f,-ratio,ratio,3.0f,7.0f);

其中 vec3 是 "typedef glm::vec3" 并且 mvpMatrix 是 "glm::mat4x4"

我已经尝试了很多方法,例如在截锥体之前乘以 lookAt 并改变截锥体的近远值等。

我也试过改变三角形坐标看它是否被剪裁但无济于事

但是,如果未应用 lookAt 和 frustum,则 0.5 单位的转换可以正常工作,这意味着从矩阵到着色器的值传递是正确的。

帮我解决这个问题

您对 glm 库的使用不当。

您在着色器中使用的约定(匹配旧的固定功能管道的默认约定以及 glm 的约定)是 matrix * vector

当您将多个变换组合到一个矩阵时,您会得到以下结果:M=A*B*C 并将其应用于某个向量 v 作为 v' = M * v。但是这个和v' = A * ( B * ( C * v))是一样的,所以C其实是先应用。在你的情况下,你有 M * V * P,但正确的 "ModelViewProjection" 转换首先应用模型转换(到达世界 space),然后是视图转换(到达眼睛 space) 最后投影转换到剪辑 space,所以你需要 P * V * M.

请注意,根据您选择的数字,三角形最终会恰好位于近平面 - 但由于数值不精确,它可能仍会被剔除。