在OpenGL ES 2.0的简单纹理四转(Simple textured quad rotatio

2019-08-18 00:15发布

编辑6 -完全重新编写有关的意见/正在进行的研究

编辑7 -增加投影/观察矩阵.....

由于我没有这个越来越远,我添加了来自谷歌演示视图/投影矩阵 - 请参见下面的代码:如果有人能指出我要去哪里错了,它真的将不胜感激,因为我仍然得到一个黑屏当我把“” GL_POSITION = a_position * uMVPMatrix;” +到我的顶点着色器(用‘= GL_POSITION a_position;’+我的四至少显示.......)

在类级别声明:(四课)

    private final float[] rotationMat = new float[16];
    private FloatBuffer flotRotBuf;
    ByteBuffer rotBuf;
    private int muRotationHandle = -1;              // Handle to the rotation matrix in the vertex shader called "uRotate"

在类杠杆宣称:(渲染器类)

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

例程集质感和做(或应该做的事),旋转(这是我四班

public void setTexture(GLSurfaceView view, Bitmap imgTexture, float[] mvpMatrix){
        this.imgTexture=imgTexture;

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

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

//      Matrix.setRotateM(rotationMat, 0, 45f, 0, 0, 1.0f);    //Set rotation matrix with angle and (z) axis

//       rotBuf = ByteBuffer.allocateDirect(rotationMat.length * 4);
         // use the device hardware's native byte order
//       rotBuf.order(ByteOrder.nativeOrder());
         // create a floating point buffer from the ByteBuffer
//       flotRotBuf = rotBuf.asFloatBuffer();
         // add the coordinates to the FloatBuffer
//       flotRotBuf.put(rotationMat);
         // set the buffer to read the first coordinate
//       flotRotBuf.position(0);

//       muRotationHandle = GLES20.glGetUniformLocation(iProgId, "uRotation");  // grab the variable from the shader
//       GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, flotRotBuf); //Pass floatbuffer contraining rotation matrix info into vertex shader
         //GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, rotationMat, 1); //Also tried this ,not use floatbuffer

        //Vertex shader
        String strVShader =  
            //    "uniform mat4 uRotation;" +
                  "uniform mat4 uMVPMatrix;" +
                  "attribute vec4 a_position;\n"+
                  "attribute vec2 a_texCoords;" +
                  "varying vec2 v_texCoords;" +
                  "void main()\n" +
                  "{\n" +
                  "gl_Position = a_Position * uMVPMatrix;"+  //This is where it all goes wrong....         
                  "v_texCoords = a_texCoords;" +
                  "}";

        //Fragment shader

        String strFShader =
            "precision mediump float;" +
            "varying vec2 v_texCoords;" +
            "uniform sampler2D u_baseMap;" +
            "void main()" +
            "{" +
            "gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
            "}";


        iProgId = Utils.LoadProgram(strVShader, strFShader);
        iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap");
        iPosition = GLES20.glGetAttribLocation(iProgId, "a_position");
        iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords");
        texID = Utils.LoadTexture(view, imgTexture);

    }

从我的渲染器类:

public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub

    //Set viewport size based on screen dimensions      
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

}

    public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub

    //Paint the screen the colour defined in onSurfaceCreated
    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);

    quad1.setTexture(curView, myBitmap, mMVPMatrix);  //SetTexture now modified to take a float array (See above) - Note I know it's not a good idea to have this in my onDrawFrame method - will move it once I have it working!

    quad1.drawBackground(); 
}

现在我已经删除了所有的旋转相关的东西,我现在只是试图获得静态四在顶点着色器应用uMVPMatrix后显示。 但仍没有:-(

如果我只是更改了该行回“默认”:

    "gl_Position = a_position;\n"+

然后,我至少得到我的纹理四显示(显然没有旋转,我会期望)。

也只是想指出,这是mvpMatrix肯定接收完整地进入的SetTexture方法是有效的(包含相同的数据,当我从谷歌开发者代码登录mvpMatrix的内容出现)。 我不知道如何检查着色器接收它的完整? 我没有理由相信它是不是虽然。

真的欣赏和所有帮助 - 我必须去的地方非常错误的,但我无法发现它。 谢谢!

编辑2:已经增加了悬赏这个问题,我只是想知道如何如何旋转我的纹理四精灵(2D)保持我必须以使其作为基础代码。 (即我需要什么要添加到它,以旋转和原因)。 谢谢!

EDIT 3 N / A

EDIT 4重新措辞/简化问题

EDIT 5中添加错误截图

Answer 1:

编辑 :编辑支持Java使用Android SDK。

如托拜厄斯所示,惯用的溶液以任何顶点变换在OpenGL是通过使用矩阵运算来完成的。 如果您打算继续与OpenGL的发展,重要的是你(最终)了解所涉及的矩阵运算的基本线性代数,但它往往是最好地利用数学库,用于提取线性代数计算成为一个更可读的格式。 在android的环境中,应该操控浮标阵与[矩阵] [1]类来创建一个旋转矩阵是这样的:

// initialize rotation matrix
float[16] rotationMat; 
Matrix.setIdentityM(rotationMat,0); 

// angle in degrees to rotate
float angle = 90;

// axis to rotate about (z axis in your case)
float[3] axis = { 0.0,0.0,1.0};

// For your case, rotate angle (in degrees) about the z axis. 
Matrix.rotateM(rotationMat,0,angle,axis[0],axis[1],axis[2]);

然后,你可以绑定旋转矩阵,以这样的着色器程序:

// assuming shader program is currently bound ...
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(shaderProgramID, "uRotation"), 1, GL_FALSE, rotationMat);

凡(正在传递的程序您顶点着色器rotationMat )看起来是这样的:

precision mediump float;
uniform mat4 uMVPMatrix;
uniform mat4 uRotation;
attribute vec2 a_texCoords;
attribute vec3 a_position;
varying v_texCoord;

void main(void)
{
    v_texCoord = a_texCoords;
    gl_Position = uMVPMatrix* uRotation * vec4(a_position,1.0f);
}

或者,你可以预乘uMVPMatrix* uRotation这个着色器程序之外,并将结果传递到您的着色器程序,以避免过多的重复计算。

一旦你使用这个更高级别的API,用于矩阵操作很舒服,你可以研究如何对内部操作是通过读取执行该书面梦幻般的教程尼科尔流星锤 。



Answer 2:

周边的Z轴旋转的旋转矩阵:

cos a -sin a 0
sin a  cos a 0
    0      0 1

如何记得如何构建它:
一个是在弧度的角度,对于α= 0的矩阵产生的同一性矩阵。 COS必须是在对角线上。 必须有一个罪恶的前一个符号,开关标志逆旋转的方向。

同样地围绕x和y的旋转可以被构造:

1      0     0
0  cos a sin a
0 -sin a cos a

 cos a 0 sin a
     0 1     0
-sin a 0 cos a

如果你不熟悉矩阵运算,这里是一些代码:

for (int i=0; i<4; i++) {
    vertices_new[i*5+0] = cos(a) * vertices[i*5+0] - sin(a) * vertices[i*5+1]; // cos(a) * v[i].x - sin(a) * v[i].y + 0 * v[i].z
    vertices_new[i*5+1] = sin(a) * vertices[i*5+0] + cos(a) * vertices[i*5+1]; // sin(a) * v[i].x + cos(a) * v[i].y + 0 * v[i].z
    vertices_new[i*5+2] = vertices[i*5+2]; // 0 * v[i].x + 0 * v[i].y + 1 * v[i].z
    vertices_new[i*5+3] = vertices[i*5+3]; // copy texture u
    vertices_new[i*5+4] = vertices[i*5+4]; // copy texture v
}


文章来源: Simple textured quad rotation in OpenGL ES 2.0