4
votes

I'm trying to create an OpenGL vertex shader that has an additional transformation matrix for each vertex. My shader code looks like this:

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

Whenever I execute this in the android emulator, the emulator crashes.

I tried to isolate the problem and found that it happens, whenever I access the vertexTransformation attribute. The following code also results in a crash, even if there are no further matrix operations involved.

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

I'm using glBufferData to pass the data:

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

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

and then bind the attributes with

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

What am I doing wrong? Is there any way to provide matrix attributes to a vertex and use them in the vertex shader?

1
how do you pass the attribute in the shader?ratchet freak
ByteBuffer vertexData = ...; vertexData.position( 0 ); GLES20.glBufferData( GLES20.GL_ARRAY_BUFFER, vertexData.remaining(), vertexData, GLES20.GL_STATIC_DRAW );Ramopolo Baig
I mean the glVertexAttribPointer calls (add them to the post)ratchet freak
How many vertex attribute arrays do you have setup? A mat4 vertex attribute is equivalent to 4 vec4s and should have 4 separate attribute pointers (N,N+1,N+2,N+3) where N is the attribute location for "vertexTransformation". It is quite possible that you don't have the other 3 arrays (N+1 through N+3) setup with a valid state.Andon M. Coleman

1 Answers

5
votes

This blurb of code is wrong:

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

Vertex attributes in OpenGL are always 4-component, thus a mat4 vertex attribute is actually 4 sequential 4-component arrays.

This is the proper way of handling a mat4 vertex attribute:

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

Notice how it requires 4 vertex attribute pointers? The vertex attribute "vertexTransformation" actually occupies locations handle through handle+3.