使用矩阵作为顶点着色器属性时崩溃

时间:2014-11-23 16:53:19

标签: android opengl-es vertex-shader

我试图创建一个OpenGL顶点着色器,每个顶点都有一个额外的变换矩阵。我的着色器代码如下所示:

uniform mat4 mvpMatrix;

attribute vec3 coordinates;
attribute mat4 vertexTransformation;
attribute vec4 vertexColor;

varying vec4 v_color;

void main() 
{
    vec4 pos = vec4( coordinates, 1 );

    pos = vertexTransformation * pos;
    pos = mvpMatrix * pos;
    gl_Position = pos;

    v_color = color;
}

每当我在android模拟器中执行此操作时,模拟器崩溃。

我尝试隔离问题并发现只要我访问vertexTransformation属性就会发生这种情况。即使没有涉及进一步的矩阵操作,以下代码也会导致崩溃。

uniform mat4 mvpMatrix;

attribute vec3 coordinates;
attribute mat4 vertexTransformation;
attribute vec4 vertexColor;

varying vec4 v_color;

void main() 
{
    vec4 pos = vec4( coordinates, 1 );

    pos = mvpMatrix * pos;
    gl_Position = pos;

    vec4 col = vec4( 0,0,0,1 );
    if ( vertexTransformation[0][0] == 0.5 )
        v_color = color;
    else
        v_color = vec4( 1, 1, 1, 1 );    
}    

我使用glBufferData传递数据:

ByteBuffer vertexData = ...;
vertexData.position( 0 );

GLES20.glBufferData( GLES20.GL_ARRAY_BUFFER, vertexData.remaining(), vertexData, GLES20.GL_STATIC_DRAW );

然后使用

绑定属性
int handle = GLES20.glGetAttribLocation( programId, "vertexTransformation" );
GLES20.glEnableVertexAttribArray( handle );
GLES20.glVertexAttribPointer( handle, 16, GLES20.GL_FLOAT, false, 92, 28 );

我做错了什么?有没有办法为顶点提供矩阵属性并在顶点着色器中使用它们?

1 个答案:

答案 0 :(得分:5)

这段代码错误:

int handle = GLES20.glGetAttribLocation( programId, "vertexTransformation" );
GLES20.glEnableVertexAttribArray( handle );
GLES20.glVertexAttribPointer( handle, 16, GLES20.GL_FLOAT, false, 92, 28 );

OpenGL中的顶点属性始终为4分量,因此mat4顶点属性实际上是4个连续的4分量数组。

这是处理mat4顶点属性的正确方法:

int handle = GLES20.glGetAttribLocation( programId, "vertexTransformation" );

GLES20.glEnableVertexAttribArray( handle );
GLES20.glVertexAttribPointer( handle, 4, GLES20.GL_FLOAT, false, 92, 28 );

GLES20.glEnableVertexAttribArray( handle + 1 );
GLES20.glVertexAttribPointer( handle + 1, 4, GLES20.GL_FLOAT, false, 92, 28+16 );

GLES20.glEnableVertexAttribArray( handle + 2 );
GLES20.glVertexAttribPointer( handle + 2, 4, GLES20.GL_FLOAT, false, 92, 28+32 );

GLES20.glEnableVertexAttribArray( handle + 3 );
GLES20.glVertexAttribPointer( handle + 3, 4, GLES20.GL_FLOAT, false, 92, 28+48 );

注意它需要4个顶点属性指针?顶点属性" vertexTransformation"实际上占据了handlehandle+3的位置。