OpenGL ES 2.0 - Matrix.looktAtM与glOrtho的交互方式究竟如何?

时间:2013-02-14 11:39:20

标签: android opengl-es

我正在编写我的第一个opengl es 2.0 app,我对Matrix.setLookAt的目的感到困惑。

我有一些代码正在运行,它绘制了一些物体,我的视图中心设置为0,0但我想平移视图,以便中心位于世界坐标的不同位置,例如5,5。 / p>

我需要在glOrtho和setLookAt中传递什么来实现这一目标?如果我将视图的中心设置为0,0并在视口上绘制线条,则可以正常工作。如果我将中心设置为0.25,0那么左边的线条就像下面的screendump一样。这些线应该延伸到视口。

我做错了什么?

我的代码: 着色器代码:

private static final String vertexShader =
        "uniform mat4 uMVPMatrix;\n"
        + "attribute vec4 aPosition;\n"
        + "attribute vec4 aColor;\n"
        + "varying vec4 vColor;\n"
        + "vec4 temp;"
        + "void main() {\n"
        + "  temp = aPosition;\n"
        + "  gl_Position = uMVPMatrix * temp;\n"
        + "  vColor = aColor;\n"
        + "}\n";

private static final String fragmentShader =
        "precision mediump float;\n"
        + "varying vec4 vColor;\n"
        + "void main() {\n"
        + "  gl_FragColor = vColor;\n"
        + "}\n";

有效的onDraw代码(这实际上分散在几个地方)

    // center of view should be at 0.25, 0. Height of view 1.0, width determined by ratio of viewport

    Matrix.orthoM(mProjMatrix, 0, -0.126471, 0.626471, -0.5, 0.5, -1, 7);
    Matrix.setLookAtM(mVMatrix, 0, 0.25, 0.0, -5, 0.25, 0.0, 0f, 0f, 1.0f, 0.0f);
    Matrix.setIdentityM(mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, MVPMatrix, 0);
    GLES20.glVertexAttrib4f(aColorHandle, 0f, 0f, 0f, 1f);      // constant color
    lineVertices.position(0);
    GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT, false, 0, lineVertices);
    GLES20.glEnableVertexAttribArray(aPositionHandle);
    GLES20.glDrawArrays(GLES20.GL_LINES, 0, lineCount*2);

LineVertices正在使用x:y坐标绘制线条:

从-0.126474行:-0.250000到0.626474:-0.250000

-0.126471之间的行:0.000000至0.626471:0.000000

从-0.126474开始的行:0.250000到0.626474:0.250000

enter image description here

2 个答案:

答案 0 :(得分:2)

这是预期的行为。

  1. 投影矩阵占用一部分空间并将其映射到NDC立方体。对于正交的,这只是一个块(没有视锥体)。代码定义的块跨越[-0.126471, 0.626471][-0.5, 0.5][-1, 7]。如果它不会改变源空间,则从左到右精确绘制线条。

  2. 现在考虑一下setLookAtM的作用:按照惯例,在应用模型视图后,查看器位于[0,0,0]并查看方向[0,0,-1]。观众在x方向上踩到0.25(尝试设想这个;它与将所有线向左移动一样)。如果你想像以前一样绘制线条,代码也必须移动它们的x坐标(+0.25)。

  3. 阅读here,了解gluLookat的技术说明;它实际上是一个翻译后跟一个轮换。请务必在songho或其他地方查看OpenGL的空格。

答案 1 :(得分:0)

您不使用look-at作为正交矩阵。这是透视矩阵

您甚至不能调用Matrix.orthoM。如果是这样,opengl世界是(-1,1)宽度和(-1,1)高度。如果从(-0.25,0)到(0.25,0)绘制线,它将位于屏幕的中心和屏幕的一半宽度。 (假设您的视口是0,0,screenWidth,screenHeight)

您只需要一个矩阵进行平移,旋转和缩放,并将其传递给着色器。