How to send multiple MVP matrices to a vertex shader in OpenGL ES 2.0
- by Carbon Crystal
I'm working my way through optimizing the rendering of sprites in a 2D game using OpenGL ES and I've hit the limit of my knowledge when it comes to GLSL and vertex shaders.
I have two large float buffers containing my vertex coordinates and texture coordinates (eventually this will be one buffer) for multiple sprites in order to perform a single glDrawArrays call. This works but I've hit a snag when it comes to passing the transformation matrix into the vertex shader.
My shader code is:
uniform mat4 u_MVPMatrix;
attribute vec4 a_Position;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
void main()
{
v_TexCoordinate = a_TexCoordinate;
gl_Position = u_MVPMatrix * a_Position;
}
In Java (Android) I am using a FloatBuffer to store the vertex/texture data and this is provided to the shader like so:
mGlEs20.glVertexAttribPointer(mVertexHandle, Globals.GL_POSITION_VERTEX_COUNT, GLES20.GL_FLOAT, false, 0, mVertexCoordinates);
mGlEs20.glVertexAttribPointer(mTextureCoordinateHandle, Globals.GL_TEXTURE_VERTEX_COUNT, GLES20.GL_FLOAT, false, 0, mTextureCoordinates);
(The Globals.GL_POSITION_VERTEX_COUNT etc are just integers with the value of 2 right now)
And I'm passing the MVP (Model/View/Projection) matrix buffer like this:
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mModelCoordinates);
(mModelCoordinates is a FloatBuffer containing 16-float sequences representing the MVP matrix for each sprite)
This renders my scene but all the sprites share the same transformation, so it's obviously only picking the first 16 elements from the buffer which makes sense since I am passing in "1" as the second parameter. The documentation for this method says:
"This should be 1 if the targeted uniform variable is not an array of matrices, and 1 or more if it is an array of matrices."
So I tried modifying the shader with a fixed size array large enough to accomodate most of my scenarios:
uniform mat4 u_MVPMatrix[1000];
But this lead to an error in the shader:
cannot convert from 'uniform array of 4X4 matrix of float' to 'Position 4-component vector of float'
This just seems wrong anyway as it's not clear to me how the shader would know when to transition to the next matrix anyway.
Anyone have an idea how I can get my shader to pick up a different MVP matrix (i.e. the NEXT 16 floats) from my MVP buffer for every 4 vertices it encounters? (I am using GL_TRIANGLE_STRIP so each sprite has 4 vertices).
Thanks!