OpenGL ES的Andr​​oid的矩阵变换 [英] OpenGL ES Android Matrix Transformations

查看:245
本文介绍了OpenGL ES的Andr​​oid的矩阵变换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个渲染器实现GLSurfaceView.Renderer接口; GLSurfaceView的子类,有的班级重新presenting我的对象,我想提请。我从 http://developer.android.com/training的code /graphics/opengl/motion.html 我想扩大这一点,并沿轴添加一些运动,不能管理它。的对象仅旋转。 这里是我的code:

 公共类NotMyCoolRenderer实现GLSurfaceView.Renderer {

公共GLShip mTriangle;
私人GLBackgroundStar mSquare;

私人最终浮动[] mMVPMatrix =新的浮动[16];
私人最终浮动[] mProjMatrix =新的浮动[16];
私人最终浮动[] mVMatrix =新的浮动[16];
私人最终浮动[] mModelMatrix =新的浮动[16];
私人最终浮动[] tempMatrix =新的浮动[16];

公共无效onDrawFrame(GL10未使用){
    //绘制背景颜色
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    //设置相机位置(视图矩阵)
    Matrix.setLookAtM(mVMatrix,0,0,0,-3,0F,0F,0F,0F,1.0F,0.0);
    //计算投影和视图变换
    Matrix.multiplyMM(mMVPMatrix,0,mProjMatrix,0,mVMatrix,0);
    //绘制方
    mSquare.draw(mMVPMatrix);
    //现在移动到三角形又名船
    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);

    //绘制三角形
    mTriangle.draw(mMVPMatrix);
}
公共无效onSurfaceChanged(GL10未使用的,诠释的宽度,高度INT){
    基于几何变化//调整视口,
    //如屏幕旋转
    GLES20.glViewport(0,0,宽度,高度);

    浮动率=(浮点)宽/高;

    //这个投影矩阵应用到对象的坐标
    //在onDrawFrame()方法
    Matrix.frustumM(mProjMatrix,0,-ratio,比率,-1,1,3,7);

}

公共类GLShip {
    公众持股量波动裂伤;
    私人最终字符串vertexShader code =
        //这个矩阵成员变量提供了一个钩来操作
        //使用该顶点着色器中的对象的坐标
        统一mat4 uMVPMatrix; +

        属性vec4 vPosition; +
        无效的主要(){+
        //矩阵必须作为GL_POSITION的改性剂
        GL_POSITION = uMVPMatrix * vPosition; +
        };


    公共无效平局(浮动[] mvpMatrix){
        //添加程序的OpenGL环境
        GLES20.glUseProgram(mProgram);

        //得到处理到顶点着色器的vPosition成员
        mPositionHandle = GLES20.glGetAttribLocation(mProgramvPosition);

        //启用句柄三角形顶点
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // prepare三角坐标数据
        GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT,假的,
                                     vertexStride,vertexBuffer);

        //得到处理,以片段着色器的vColor成员
        mColorHandle = GLES20.glGetUniformLocation(mProgramvColor);

        //设置颜色绘制三角形
        GLES20.glUniform4fv(mColorHandle,1,颜色,0);

        //获取手柄形状的变换矩阵
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramuMVPMatrix);
        NotMyCoolRenderer.checkGlError(glGetUniformLocation);

        //应用投影和视图变换
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,假的,mvpMatrix,0);
        NotMyCoolRenderer.checkGlError(glUniformMatrix4fv);

        //绘制三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,vertexCount);

        //禁用顶点数组
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
 

我的期望是在每个重画该对象会被轧液机转动,由1F沿Y轴traslated。我只能看到旋转(有点太突出),虽然。 事实上,我对于一些问题: 如何申请我的翻译矩阵 什么是分割的OpenGL功能的最佳实践?不应将modelMatrix被存储在对象本身,而不是在渲染?应该是在渲染器类进行矩阵操作? 我已经组合在一起,因为我想,他们是所有相关的。

解决方案

从来就一直与Android的训练例如,下面的方法终于为我工作。 (基于安卓培训>显示与图形​​的OpenGL ES>添加动态

  1. 使用正确的顶点着色器:

     私有最终字符串vertexShader code =
    //这个矩阵成员变量提供了一个钩来操作
    //使用该顶点着色器中的对象的坐标
    统一mat4 uMVPMatrix; +
    属性vec4 vPosition; +
    无效的主要(){+
    //矩阵必须作为GL_POSITION的改性剂
    GL_POSITION = uMVPMatrix * vPosition; +
    };
     

  2. 在渲染器类:

     公共类MyGL20Renderer实现GLSurfaceView.Renderer {
    [...]
    //创建为三角形模型矩阵
    私人最终浮动[] mModelMatrix =新的浮动[16];
    //创建一个临时矩阵计算的目的,
    //避免multiplyMM的右侧的相同矩阵和左侧后
    // 看到http://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364
    私人浮法[] mTempMatrix =新的浮动[16];
    [...]
     

  3. 应用中的 onDrawFrame 的转换,开始的翻译的:

     公共无效onDrawFrame(GL10未使用){
    [...]
    Matrix.setIdentityM(mModelMatrix,0); //初始化为单位矩阵
    Matrix.translateM(mModelMatrix,0,-0.5f,0,0); //翻译向左
     

  4. 随后的旋转的:

      //创建三角形旋转变换
    很长一段时间= SystemClock.uptimeMillis()%4000L;
    浮裂伤= 0.090f *((int)的时间);
    Matrix.setRotateM(mRotationMatrix,0,裂伤,0,0,-1.0F);
     

  5. 联合旋转和平移,避免使用的 mModelMatrix

      

    为在右侧和左侧multiplyMM相同矩阵(见<一href="http://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364">2)

      //联合旋转和移动矩阵
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix,0,mTempMatrix,0,mRotationMatrix,0);
     

  6. 联合模型矩阵的投影和相机视图; 避免再次使用的 mModelMatrix

      

    为在右侧和左侧multiplyMM相同矩阵(见<一href="http://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364">2)

      //结合了投影和相机视图模型矩阵
    mTempMatrix = mMVPMatrix.clone();
    Matrix.multiplyMM(mMVPMatrix,0,mTempMatrix,0,mModelMatrix,0);
     

  7. 绘制形状

      //绘制形状
    mTriangle.draw(mMVPMatrix);
     

感谢大家,所有有用的投入,我可以借鉴这一主题。

I have a renderer implementing GLSurfaceView.Renderer interface; a subclass of GLSurfaceView and some classes representing my objects I want to draw. I have the code from http://developer.android.com/training/graphics/opengl/motion.html I want to expand this and add some moving along axes and can't manage it. The object is only rotated. and here is my code:

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);
    }
}

My expectations are that on each redrawing the object would be rotated by mAngle and traslated along Y-Axis by 1f. I can see only rotating (a bit projected too) though. I actually got some questions regarding that: how do I apply my translation matrix and what is the best practice of dividing the opengl functionality? Should not the modelMatrix be stored in the object itself rather than in renderer? Should the matrix operations be performed in the renderer-class? I have grouped them together since I guess that they are all related.

解决方案

I´ve been working with the example from the Android Training, the following approach finally works for me. (Based on Android Training > Displaying Graphics with OpenGL ES > Adding Motion)

  1. Use the correct vertex shader:

    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;" +
    "}";
    

  2. In the renderer class:

    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 http://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364
    private float[] mTempMatrix = new float[16];
    [...]
    

  3. Apply transformations in onDrawFrame, start with translation:

    public void onDrawFrame(GL10 unused) {
    [...]
    Matrix.setIdentityM(mModelMatrix, 0); // initialize to identity matrix
    Matrix.translateM(mModelMatrix, 0, -0.5f, 0, 0); // translation to the left
    

  4. Then rotation:

    // 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);
    

  5. Combine rotation and translation, avoid using mModelMatrix

    "as the same matrix on the right and left side of multiplyMM" (see 2)

    // Combine Rotation and Translation matrices 
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0);
    

  6. Combine the model matrix with the projection and camera view; again avoid using mModelMatrix

    "as the same matrix on the right and left side of multiplyMM" (see 2)

    // Combine the model matrix with the projection and camera view
    mTempMatrix = mMVPMatrix.clone();
    Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0);
    

  7. Draw the shape

    // Draw shape
    mTriangle.draw(mMVPMatrix);
    

Thank you all, for all the useful input I could draw from this thread.

这篇关于OpenGL ES的Andr​​oid的矩阵变换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆