OpenGL ES 2.0:在Android上使物体绕自身旋转

3

我想要旋转一个移动的物体,但它会围绕坐标系中心旋转。如何让它在移动时围绕自身旋转?以下是代码:

Matrix.translateM(mMMatrix, 0, 0, -y, 0);
Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f);
y += speed;
Matrix.translateM(mMMatrix, 0, 0, y, 0); 

可能是 [如何在OpenGL中绕本地轴旋转对象?] 的重复问题(http://stackoverflow.com/questions/1671210/how-to-rotate-object-around-local-axis-in-opengl)。该问题(及其答案)可能使用了旧的GL固定功能,但其背后的数学原理与您正在做的完全等效。 - Nicol Bolas
我实际上无法从那个问题中找到解决方案。 - nifuki
3个回答

2

不要使用视图矩阵来旋转对象,该矩阵用作整个场景的相机。要转换一个对象,您应该使用模型矩阵。要使其围绕自身中心旋转,可以使用以下方法:

public void transform(float[] mModelMatrix) {
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0, y, 0);
    Matrix.rotateM(mModelMatrix, 0, mAngle, 0.0f, 0.0f, 1.0f); 
}

不要忘记在每个循环中使用单位矩阵来重置变换。

我认为您的代码是错误的。在应用任何变换之前,您应该先更新“y”的值。

public void onDrawFrame(GL10 gl) {
    ...
    y += speed;
    transform(mModelMatrix);
    updateMVP(mModelMatrix, mViewMatrix, mProjectionMatrix, mMVPMatrix);
    renderObject(mMVPMatrix);
    ...
}

更新MVP方法将结合模型、视图和投影矩阵:
private void updateMVP( 
        float[] mModelMatrix, 
        float[] mViewMatrix, 
        float[] mProjectionMatrix,
        float[] mMVPMatrix) {

    // combine the model with the view matrix
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // combine the model-view with the projection matrix
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix,   0);
}

最后,render方法会执行着色器来绘制对象。
public void renderObject(float[] mMVPMatrix) {

    GLES20.glUseProgram(mProgram);

    ...

    // Pass the MVP data into the shader
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Draw the shape
    GLES20.glDrawElements (...);
}

我希望这能对你有所帮助。


0

我刚刚使用了视图矩阵而不是模型矩阵,一切都正常了。有关模型、视图和投影矩阵的详细信息请参见


0

你在哪里进行对象绘制?

我想应该是在你放置在这里的代码之后,类似于:

Matrix.translateM(mMMatrix, 0, 0, -y, 0);
Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f);
y += speed;
Matrix.translateM(mMMatrix, 0, 0, y, 0); 
drawHere();//<<<<<<<<<<<<<<<<<<<

然后,第二个翻译调用是问题所在。 你应该将绘制调用移动到第二个翻译之前。 或者 更好的方法是:

Matrix.setIdentityM(mMMatrix, 0);//<<<<<<<<added
Matrix.translateM(mMMatrix, 0, 0, -y, 0);
Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f);
y += speed;
//Matrix.translateM(mMMatrix, 0, 0, y, 0); //<<<<<<<<<removed
drawHere();

创建表面时,我设置了单位矩阵。为什么第二次转换会出问题?我只是将其移动到原点,旋转,然后将其转换为新坐标。 - nifuki
我已经测试了你的代码,它确实存在你所说的问题。我已经按照我的回答进行了修复。现在,请问你正在哪里进行对象绘制? - CuriousChettai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接