Android 在场景中修改多个对象时出现 OpenGL es 2.0 错误

Android OpenGL es 2.0 error when modifying multiple objects on scene

我在使用 OpenGL ES 2.0 进行适当的场景操作时遇到了一些问题。在我的屏幕上我想画一个矩形和一个立方体。矩形应该移动到底部并缩放,而立方体应该移动到顶部并缩放。更重要的是,我想在所有 3 个轴上旋转这个立方体。

这是我到目前为止创建的内容:

@Override
    public void onDrawFrame(GL10 gl) {
        float[] scratch = new float[16];
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        Matrix.setLookAtM(viewMatrix, 0, 0, 0, -6, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
        Matrix.multiplyMM(MVPMatrix, 0, projectionMatrix, 0, viewMatrix, 0);

        Matrix.translateM(scratchMatrix1, 0, 0, -1.1f, 0);
        Matrix.scaleM(scratchMatrix3, 0, 0.5f, 0.5f, 0.5f);
        Matrix.multiplyMM(scratchMatrix2, 0, scratchMatrix1, 0, scratchMatrix3, 0);
        Matrix.multiplyMM(scratch, 0, scratchMatrix2, 0, MVPMatrix, 0);
        rectangle.draw(scratch);

        Matrix.setRotateM(scratchMatrix1, 0, angleXVal, 1.0f, 0, 0);
        Matrix.setRotateM(rotationMatrix, 0, angleYVal, 0, 1.0f, 0);
        Matrix.multiplyMM(scratchMatrix2, 0, rotationMatrix, 0, scratchMatrix1, 0);
        Matrix.setRotateM(rotationMatrix, 0, angleZVal, 0, 0, 1.0f);
        Matrix.multiplyMM(scratchMatrix3, 0, rotationMatrix, 0, scratchMatrix2, 0);

        Matrix.translateM(scratchMatrix1, 0, 0, 0.3f, 0);
        Matrix.multiplyMM(scratchMatrix2, 0, scratchMatrix3, 0, scratchMatrix1, 0);
        Matrix.scaleM(scratchMatrix1, 0, 0.8f, 0.8f, 0.8f);
        Matrix.multiplyMM(scratchMatrix3, 0, scratchMatrix2, 0, scratchMatrix1, 0);
        Matrix.multiplyMM(scratch, 0, scratchMatrix2, 0, MVPMatrix, 0);

        cube.draw(scratch);
    }

问题是当我旋转立方体时,矩形也在移动。这与立方体的缩放和平移相同 - 它正在拉动矩形。

对我来说,矩阵似乎在某处相连,但我看不到哪里,因为先绘制矩形,然后再覆盖划痕矩阵。

假设这是您完整的 onDrawFrame() 代码,scratchMatrix1 等 class 成员变量在帧与帧之间持续存在。

这意味着来自一帧的翻译将延续到下一帧,因为 Matrix.translateM() 通过添加到现有矩阵变换来应用翻译,而不是将矩阵设置为给定的翻译矩阵并覆盖以前的值。所以翻译会累积几帧。

这意味着当你平移立方体时,下一次调用 onDrawFrame 时平移仍会位于 scratchMatrix1 中,矩形平移将被添加到它而不是被设置重新.

Matrix.scaleM()也是如此。

您可以通过在函数开始时将所有临时矩阵初始化为恒等式来纠正此问题,并在开始计算立方体变换矩阵之前再次初始化:

 Matrix.setIdentityM(scratchMatrix1, 0);
 Matrix.setIdentityM(scratchMatrix2, 0);
 Matrix.setIdentityM(scratchMatrix3, 0);
 Matrix.setIdentityM(scratch, 0);