正确的顶点着色器代码? OpenGL ES 2.0

时间:2013-04-05 14:36:48

标签: android rotation opengl-es-2.0 translate-animation skew

修改已添加代码,请参阅下文

编辑2 - 底部包含的设备的屏幕截图以及说明

修改3 - 添加新代码

我有两个课程,一个是渲染的,一个是自定义的' quad'类。

我在我的渲染器类的类级别声明了这些:

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

在我的onSurfaceChanged方法中,我有:

@覆盖     public void onSurfaceChanged(GL10 gl,int width,int height){

    GLES20.glViewport(0, 0, width, height);

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

}

和....

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // TODO Auto-generated method stub

    myBitmap = BitmapFactory.decodeResource(curView.getResources(), R.drawable.box);

        //Create new Dot objects

        dot1 = new Quad();
        dot1.setTexture(curView, myBitmap);
        dot1.setSize(300,187);    //These numbers are the size but are redundant/not used at the moment.

        myBitmap.recycle();


           //Set colour to black
           GLES20.glClearColor(0, 0, 0, 1);

}

最后来自这个类,onDrawFrame:

@Override
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) so looking from the front
   Matrix.setLookAtM(mVMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Combine
   Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    dot1.rotateQuad(0,0,45, mMVPMatrix); //x,y,angle and matrix passed in

}

然后,在我的四年级中:

这在班级宣布:

        private float[] mRotationMatrix = new float[16];        
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjMatrix = new float[16];
    private final float[] mVMatrix = new float[16];
    private int mMVPMatrixHandle;
    private int mPositionHandle;
    private int mRotationHandle;
//Create our vertex shader
    String strVShader =  
              "uniform mat4 uMVPMatrix;" +
              "uniform mat4 uRotate;" +
              "attribute vec4 a_position;\n"+
              "attribute vec2 a_texCoords;" +
              "varying vec2 v_texCoords;" +
              "void main()\n" +
              "{\n" +
         //     "gl_Position = a_position * uRotate;\n"+
         //          "gl_Position = uRotate * a_position;\n"+
               "gl_Position = a_position * uMVPMatrix;\n"+  
        //        "gl_Position = uMVPMatrix * a_position;\n"+  
                  "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);" +
        "}";

然后设置纹理的方法(不要认为这与这个问题有关!!)

    public void setTexture(GLSurfaceView view, Bitmap imgTexture){
        this.imgTexture=imgTexture;

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

    }

最后,我的' rotateQuad'方法(当前应该绘制和旋转四边形)。

public void rotateQuad(float x, float y, int angle, float[] mvpMatrix){

Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, 0.1f);

//  Matrix.translateM(mRotationMatrix, 0, 0, 0, 0);  //Removed temporarily

// Combine the rotation matrix with the projection and camera view
   Matrix.multiplyMM(mvpMatrix, 0, mRotationMatrix, 0, mvpMatrix, 0);

float[] vertices = {

        -.5f,.5f,0, 0,0,
        .5f,.5f,0, 1,0,
        -.5f,-.5f,0, 0,1,
        .5f,-.5f,0, 1,1

        };

 vertexBuf = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
 vertexBuf.put(vertices).position(0);

//Bind the correct texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texID);      
//Use program
GLES20.glUseProgram(iProgId);
// 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);
    // get handle to shape's rotation matrix
mRotationHandle = GLES20.glGetUniformLocation(iProgId, "uRotate");
  // Apply the projection and view transformation
  GLES20.glUniformMatrix4fv(mRotationHandle, 1, false, mRotationMatrix, 0);

//Set starting position for vertices
vertexBuf.position(0);
//Specify attributes for vertex
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute for position
GLES20.glEnableVertexAttribArray(iPosition);
//Set starting position for texture
vertexBuf.position(3);
//Specify attributes for vertex
GLES20.glVertexAttribPointer(iTexCoords, 2, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute for texture
GLES20.glEnableVertexAttribArray(iTexCoords);
//Draw it
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
编辑2

这是我在屏幕中央绘制的四边形。没有轮换。

enter image description here

这是用+​​ 45度旋转的相同四边形代码" gl_Position = a_position * uMVPMatrix;" +在我的顶点着色器中(它现在来自不同的项目,因此着色器变量是a_position而不是vPosition),它看起来是正确的!

enter image description here

然而,这是相同的四边形旋转+45度,切换了两个着色器变量(因此他们读取" gl_Position = uMVPMatrix * a_position;" - 正如您所看到的,它是' s不太对劲。

另外只是旁注,你不能在这里看到它,因为quare是对称的,但是每个方法也在与另一个方向相反的方向旋转....

enter image description here

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:1)

这真的无法分辨,因为我们不知道你传递给这两个变量的是什么。

OpenGL是列主格式,因此如果vPosition实际上是一个向量,而uMVPMatrix是一个矩阵,那么第一个选项是正确的,如果它在你的着色器中。

如果这不在您的着色器中,而是在您的程序代码中,那么就没有足够的信息。

如果您使用第一个选项但获得意外结果,则可能无法正确计算矩阵或未传递正确的顶点。

答案 1 :(得分:0)

通常在顶点着色器中,您应该通过MVP多次定位,即

gl_Position = uMVPMatrix * vPosition;

当您更改订单时,这应该有效......

答案 2 :(得分:0)

感谢所有人的帮助。

我设法追查问题(大部分时间)。我会展示我的所作所为。

这是以下一行:

Matrix.multiplyMM(mvpMatrix, 0, mvpMatrix, 0, mRotationMatrix, 0);

正如你所看到的,我正在将矩阵相乘并将它们存储到我在乘法中使用的矩阵中。

所以我创建了一个名为mvpMatrix2的新矩阵并将结果存储在其中。然后将它传递给我的顶点着色器。

//Multiply matrices
Matrix.multiplyMM(mvpMatrix2, 0, mvpMatrix, 0, mRotationMatrix, 0);

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

//Give to vertex shader variable
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix2, 0);

应用此之后,没有失真(此外,关于我在这里的另一个问题Using Matrix. Rotate in OpenGL ES 2.0我能够翻译四边形的中心)。我说'大部分'因为然而,当我旋转它时,它会向后旋转(所以如果我说旋转+45度,(顺时针),它实际上将四边形旋转-45度(顺时针方向)。

但希望这将有助于将来遇到类似问题的任何人。