I am using OpenGL3.2 Core Profile on OSX. And I want to do instanced drawing (glDrawArraysInstanced), where I pass a matrix for each instance.
My vertex shader builds just fine:
#version 150
in mediump vec4 position;
in mediump mat4 trf;
in lowp vec4 rgb;
out lowp vec4 colour;
uniform highp mat4 modelcamviewprojmat;
void main()
{
mediump vec4 tpos = trf * position;
gl_Position = modelcamviewprojmat * tpos;
colour = rgb;
}
The binding of 'trf' went fine:
glBindAttribLocation(program, ATTRIB_TRF, "trf" );
But how can I pass in my data? glVertexAttribPointer can not pass values larger than 4 floats. So this call fails:
glVertexAttribPointer( ATTRIB_TRF, 16, GL_FLOAT, 0, 16 * sizeof(float), ... );
I suspect that I need to replace it with 4 calls to glVertexAttribPointer, each passing 4 floats. But what value could I use for 'index' (first parm)? Do I need to use 4 vector attributes instead, and assemble the four vectors in GLSL vertex shader? If so, what kind of GLSL code accomplishes this? Or can I use the return value from BindAttribLocation and use val+0, val+1, val+2 and val+3 for all the rows?
A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.
A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.
If you're not using VAOs, then you would usually call glVertexAttribPointer (and the corresponding glEnableVertexAttribArray ) right before rendering to setup the state properly.
Vertex shaders manipulate coordinates in a 3D space and are called once per vertex. The purpose of the vertex shader is to set up the gl_Position variable — this is a special, global, and built-in GLSL variable. gl_Position is used to store the position of the current vertex.
According to this page and my current implementation of hardware instancing in my game, the proper way it's done is that a mat4
attribute takes up 4 attribute locations. The one you bind and the 3 following.
int pos = glGetAttribLocation(shader_instancedarrays.program, "transformmatrix");
int pos1 = pos + 0;
int pos2 = pos + 1;
int pos3 = pos + 2;
int pos4 = pos + 3;
glEnableVertexAttribArray(pos1);
glEnableVertexAttribArray(pos2);
glEnableVertexAttribArray(pos3);
glEnableVertexAttribArray(pos4);
glBindBuffer(GL_ARRAY_BUFFER, VBO_containing_matrices);
glVertexAttribPointer(pos1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(0));
glVertexAttribPointer(pos2, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 4));
glVertexAttribPointer(pos3, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 8));
glVertexAttribPointer(pos4, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 12));
glVertexAttribDivisor(pos1, 1);
glVertexAttribDivisor(pos2, 1);
glVertexAttribDivisor(pos3, 1);
glVertexAttribDivisor(pos4, 1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With