Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL ES Android矩阵变换_Android_Opengl Es_Opengl Es 2.0 - Fatal编程技术网

OpenGL ES Android矩阵变换

OpenGL ES Android矩阵变换,android,opengl-es,opengl-es-2.0,Android,Opengl Es,Opengl Es 2.0,我有一个实现GLSurfaceView.renderer接口的渲染器;GLSURFACHEVIEW的一个子类和一些表示我要绘制的对象的类。我有你的密码 我想扩展这个功能,添加一些沿轴移动的功能,但无法管理它。对象仅旋转。 这是我的代码: public class NotMyCoolRenderer implements GLSurfaceView.Renderer { public GLShip mTriangle; private GLBackgroundStar mSquare; p

我有一个实现GLSurfaceView.renderer接口的渲染器;GLSURFACHEVIEW的一个子类和一些表示我要绘制的对象的类。我有你的密码 我想扩展这个功能,添加一些沿轴移动的功能,但无法管理它。对象仅旋转。 这是我的代码:

public class NotMyCoolRenderer implements GLSurfaceView.Renderer {

public GLShip mTriangle;
private GLBackgroundStar   mSquare;

private final float[] mMVPMatrix = new float[16];
private final float[] mProjMatrix = new float[16];
private final float[] mVMatrix = new float[16];
private final float[] mModelMatrix = new float[16];
private final float[] tempMatrix = new float[16];

public void onDrawFrame(GL10 unused) {
    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    // Set the camera position (View matrix)
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
    // Draw square
    mSquare.draw(mMVPMatrix);
    // Now moving on to triangle aka ship
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0.1f, 0f, 0);
    Matrix.rotateM(mModelMatrix, 0, mTriangle.mAngle, 0, 0, -1.0f);
    Matrix.multiplyMM(tempMatrix, 0, mVMatrix, 0, mProjMatrix, 0); 
    Matrix.multiplyMM(mMVPMatrix, 0, mModelMatrix , 0, tempMatrix , 0);  

    // Draw triangle
    mTriangle.draw(mMVPMatrix);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
    // Adjust the viewport based on geometry changes,
    // such as screen rotation
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

}

public class GLShip {
    public volatile float mAngle;
    private final String vertexShaderCode =
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;" +

        "attribute vec4 vPosition;" +
        "void main() {" +
        // the matrix must be included as a modifier of gl_Position
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";


    public void draw(float[] mvpMatrix) {
        // Add program to OpenGL environment
        GLES20.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT, false,
                                     vertexStride, vertexBuffer);

        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        // get handle to shape's transformation matrix
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        NotMyCoolRenderer.checkGlError("glGetUniformLocation");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        NotMyCoolRenderer.checkGlError("glUniformMatrix4fv");

        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
我的期望是,在每次重画时,对象都会被mAngle旋转,并沿Y轴平移1f。不过我只能看到旋转(也有一点投影)。 实际上,我有一些关于这方面的问题: 如何应用我的翻译矩阵和 划分opengl功能的最佳实践是什么?modelMatrix不应该存储在对象本身而不是渲染器中吗?矩阵操作应该在渲染器类中执行吗?
我将它们组合在一起,因为我猜它们都是相关的。

如果你想看到运动,你应该更新mTriangle.mAngle每个帧(最好是作为时间的函数,以消除速度差异或其他进程造成的延迟…)

注意Matrix.setIdentityM(mModelMatrix,0);将所有累积的旋转和平移恢复为“零”或实际恢复为单位矩阵。。。 同样的约定适用于所有set函数。 要积累所有的转换,必须

  • setIdentity(model)
  • 翻译(trans);//获取旋转原点的步骤
  • 旋转(旋转矩阵);//累积旋转
  • 翻译(t2);//要再次转换到更好的位置
还应该在每次调用之间保留对象转换向量[ox,oy,oz]的值,并将它们提供给Matrix.translateM(mModelMatrix,ox,oy,oz,0)

通常,其中一个会尽早连接所有“平移、旋转、缩放”矩阵,并按每个对象缓存它们,或按具有多个对象和边界框的复杂容器分层缓存它们,以便在摄影机后面(或通常在视锥体外部)启用时可以剔除多个对象

通常情况下,一个移动的摄像机保持在一个矩阵中,每帧将其与投影矩阵相乘

您可以从以下内容开始:

float Time = System.currentTimeMillis() * 0.01f;  // 10 radians / second == fast!
Matrix.translateM(mModelMatrix, Math.sin(Time)*2.0f, 0, 1f, 0);
...
正如Tim所注意到的,没有涉及到投影矩阵,这意味着所有的z值在代码中的行为都是精确的,即使更改x&y值会产生不同

我很想说,MVP矩阵意味着相乘
按M*V*P=(M*V)*P=M*(V*P)的顺序排列。

请注意,您没有将投影矩阵应用于正在绘制的三角形,这可能会导致问题

应该是:

Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mModelMatrix, 0);  
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix, 0); 

我一直在使用Android培训中的示例,下面的方法最终对我有效。(基于)

  • 使用正确的顶点着色器:

    private final String vertexShaderCode =
    // This matrix member variable provides a hook to manipulate
    // the coordinates of the objects that use this vertex shader
    "uniform mat4 uMVPMatrix;" +
    "attribute vec4 vPosition;" +
    "void main() {" +
    // the matrix must be included as a modifier of gl_Position
    "  gl_Position = uMVPMatrix * vPosition;" +
    "}";
    
  • 在渲染器类中:

    public class MyGL20Renderer implements GLSurfaceView.Renderer {
    [...]
    // create a model matrix for the triangle
    private final float[] mModelMatrix = new float[16];
    // create a temporary matrix for calculation purposes,
    // to avoid the same matrix on the right and left side of multiplyMM later
    // see https://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364
    private float[] mTempMatrix = new float[16];
    [...]
    
  • 在onDrawFrame中应用转换,从转换开始:

  • 然后轮换:

  • 结合旋转和平移,避免使用mModelMatrix

    “与multiplyMM左右两侧的相同矩阵相同”(参见)

  • 将模型矩阵与投影和相机视图相结合再次避免使用mModelMatrix

    “与multiplyMM左右两侧的相同矩阵相同”(参见)

  • 画形状

    // Draw shape
    mTriangle.draw(mMVPMatrix);
    

  • 谢谢大家,感谢所有我可以从这个线程中提取的有用输入。

    我忘了提到绘图方法是由我的EventListener触发的,所以我想,我还不需要时间函数。我的三角形按预期旋转。它只是不沿着轴移动,这是因为这里有一个setRotate而不是Matrix.rotateM。(或Android API中的任何内容)我现在有了
    Matrix.setIdentityM(mModelMatrix,0);矩阵setIdentityM(mMVPMatrix,0);矩阵。translateM(mModelMatrix,0,1f,0f,0);旋转矩阵(mModelMatrix,0,mTriangle.mAngle,0,0,-1.0f);矩阵。多重矩阵(tempMatrix,0,mVMatrix,0,mModelMatrix,0);多重矩阵(mMVPMatrix,0,mProjMatrix,0,tempMatrix,0)并且仍然只看到绕Z轴旋转,没有任何其他移动。感谢您提供的将对象转换为原点的技巧。在我设法将对象移出原点后,我将解决此问题。我看不出转换不起作用的原因(除非您的摄影机=mVMatrix跟随三角形…)mProjMatrix有什么功能?我已更新了问题中的代码示例。也许你可以看看。第一行不应该是
    Matrix.multiplyMM(mVMatrix,0,mVMatrix,0,mModelMatrix,0)
    ?如果是,我仍然只能看到旋转。No translation.AFAIK在multiplyMM的左右两侧不能有相同的矩阵:但是,如果结果元素与lhs或rhs元素重叠,则结果元素值未定义。。我在这里定义了一个新的矩阵,“ModelView”矩阵,用来保存视图*模型乘法的临时结果。做的和你一样-定义了一个临时矩阵。还是一样的问题,正如所料。仍然没有什么可以解释mProjMatrix是如何初始化的。这里是最后一个提示:尝试一步一步地复制从中得到的经验教训。它只涉及javascript,但差别几乎微乎其微。API和矩阵数学是一样的。祝你好运@另一个人建议AkiSuihkonen(针对同一教程的同一代码)使用
    gl_Position=uMVPMatrix*vpposition而不是
    gl_Position=vPosition*uMVPMatrix。如果我按照建议,我根本看不到我的三角形你也应该按M,V,P的顺序计算MVP矩阵。你现在按P,V的顺序计算,M@AkiSuihkonen这也不能解决问题。我根本看不到我和M*(V*P)的三角形。这是我遇到的唯一一个帮助我解决问题的教程。谢谢你的回答!如果这有助于任何其他人谁遇到了这个答案,部分
    
    // Create a rotation transformation for the triangle
    long time = SystemClock.uptimeMillis() % 4000L;
    float mAngle = 0.090f * ((int) time);
    Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
    
    // Combine Rotation and Translation matrices 
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0);
    
    // Combine the model matrix with the projection and camera view
    mTempMatrix = mMVPMatrix.clone();
    Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0);
    
    // Draw shape
    mTriangle.draw(mMVPMatrix);