【问题标题】:OpenGL - rotate own vision?OpenGL - 旋转自己的视野?
【发布时间】:2014-01-23 13:15:19
【问题描述】:

我正在尝试处理一些 OpenGL 的东西。我现在得到的是一个视口,我在其中使用 GL_LINES 绘制了一些假想的“边界”。看起来是这样的,setLookAt 设置如下:

Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0);

我的截锥体已设置:Matrix.frustumM(mProjectionMatrix, 0, -2, 2, -2, 2, 1, 11);,所以我位于“立方体”内的某个位置。

现在我想要实现的是让用户环顾四周。我正在捕获 onTouchEvents,将 x/y 方向的任何运动传递给渲染器。我接下来要做的是旋转从触摸侦听器接收到的特定角度绘制的所有线条。

然后看起来像这样:

所以立方体不是围绕观察者或眼睛中心旋转,而是围绕某个我不知道它来自哪里的点旋转。

我的问题是:如何围绕查看者的中心/位置旋转对象?我是否必须旋转来自 setLookAtM 的mViewMatrix?如果是,只需使用Matrix.setRotateM(mViewMatrix, ...)?

Line的绘制方法如下:

  public void draw(float[] mViewMatrix, float[] mProjectionMatrix) {
    Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
    GLES20.glUseProgram(iProgId);
    lineBuffer.position(0);
    GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, lineBuffer);
    GLES20.glEnableVertexAttribArray(iPosition);

    colorBuffer.position(0);
    GLES20.glVertexAttribPointer(iColor, 3, GLES20.GL_FLOAT, false, 0, colorBuffer);
    GLES20.glEnableVertexAttribArray(iColor);

    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.rotateM(mModelMatrix, 0, rotX, 1, 0, 0);
    Matrix.rotateM(mModelMatrix, 0, -rotY, 0, 1, 0);
    Matrix.setIdentityM(mViewProjectionMatrix, 0);
    Matrix.multiplyMM(mViewProjectionMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
    //GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, mMVPMatrix, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewProjectionMatrix, 0);
    GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, mMVPMatrix, 0);


    //GLES20.glDrawElements(GLES20.GL_LINES, mVertices.length/2, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    GLES20.glDrawArrays(GLES20.GL_LINES, 0, mVertices.length / 2);
}

【问题讨论】:

  • 如果你想“环顾四周”,你应该旋转你的视图矩阵。

标签: android opengl-es rotation


【解决方案1】:

look at 函数需要 3 个顶点,眼睛位置、目标位置和向上向量。基本上它会生成一个矩阵来移动场景以渲染场景,就像您从眼睛位置到目标位置一样。在您的示例中,您位于 0,0,0 并查看 5,0,0(因此您正在查看 +x 方向,向上定义为 0,1,0(较高的 y 值意味着对象将位于窗口顶部) .)

首先定义一个相机位置,而不是使用这些常量。

float cameraX, cameraY, cameraY;

使用目标向量比较困难,因此请改用一个角度来定义您正在查看的方向

float angle;

并使用这个角度来计算 targetVector。

float targetX = cameraX + cos(angle);
float targetY = cameraY;
float targetZ = cameraZ + sin(angle);

现在要移动相机,您必须修改相机X-Y-Z。如果你想向前移动,你应该将你的相机移向目标矢量。例如向前移动 10 个单位。

targetX += cos(angle)*10;
targetY += sin(angle)*10;

你还需要重新计算目标向量,因为目标位置也应该移动。

如果要向后移动,请改用 -= 运算符。如果要移动边,则必须在这些计算中添加或删除角度 PI/2。

要旋转相机,只需增加/减少角度并重新计算目标矢量。

这是一个非常基本的相机,您将无法向上或向下看。您必须使用俯仰/偏航相机才能上下查看。

【讨论】:

  • 感谢您的帮助!但我有点无法让它正常工作。在我的 onTouch 方法中,我对其进行了调整以给我一个角度(起初它是位置差): ACTION_DOWN: 保存 X/Y 位置,ACTION_MOVE: angle = atan2(newX - oldX, newY - oldY);并试图用 +cos(angle) 和 +sin(angle) 来调整你的 sn-p,但是值太高了,它立即上升到 +1000 或其他东西,并且旋转被卡住了。目前我不知道如何根据屏幕上的触摸移动来移动目标矢量..
猜你喜欢
  • 2016-02-20
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
相关资源
最近更新 更多