1

我正在编写我的第一个 opengl es 2.0 应用程序,但我对 Matrix.setLookAt 的用途感到困惑。

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

我需要在 glOrtho 和 setLookAt 中传递什么来实现这一点?如果我将视图的中心设置为 0,0 并在视口上画线,那效果很好。如果我将中心设置为 0.25, 0,那么线条会出现在左侧,如下面的屏幕转储中所示。这些线应该延伸穿过视口。

我究竟做错了什么?

我的代码:着色器代码:

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 的线

在此处输入图像描述

4

2 回答 2

2

这是预期的行为。

  1. 投影矩阵占用一部分空间并将其映射到 NDC 立方体。对于正交的,这只是一个块(没有平截头体)。代码定义的块 spans [-0.126471, 0.626471][-0.5, 0.5][-1, 7]。如果它不会改变源空间,那么这些线会完全从左到右绘制。

  2. 现在考虑它的setLookAtM作用:按照惯例,在应用模型视图之后,查看器位于[0,0,0]并朝方向看[0,0,-1]。观看者正在向 x 方向靠边0.25(尝试设想这一点;这与将所有行向左移动相同)。如果您想像以前一样绘制线条,则代码还必须移动它们的 x 坐标(+0.25)。

阅读此处以获取有关 ; 的技术说明gluLookat。它实际上是一个平移,然后是一个旋转。请务必在Songho或其他地方查看 OpenGL 的空间。

于 2013-02-15T03:51:41.963 回答
0

您不使用查看正交矩阵。用于透视矩阵

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

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

于 2013-02-19T14:11:35.340 回答