I am working on implementing a basic example program that uses instance rendering with the “glDrawElementsInstaced” call. I have created working examples on desktop OpenGL (330 core) but I have encountered an issue porting this to OpenGL ES 3. Specifically, I am using the Android NDK and SDL2. I have worked with these libraries before with OpenGL ES 3 and have created other OpenGL ES 3 programs (namely ones that use Vertex Array Objects and FrameBuffers).
The error that I get in logcat looks like this:
0-18 15:49:57.274 20996-21026/package I/SDL/APP: Program link failed: --From Vertex Shader:
10-18 15:49:57.274 20996-21026/packageI/SDL/APP: linker error: multiple attribute attempt to bind at same location
10-18 15:49:57.274 20996-21026/packageI/SDL/APP: --From Fragment Shader:
10-18 15:49:57.274 20996-21026/package I/SDL/APP: linker error: multiple attribute attempt to bind at same location
My vertex and indices are created like so (buffers have already been generated):
glBindVertexArray(mVAO_Handle);
glBindBuffer(GL_ARRAY_BUFFER, mVBO_Array[VBO_INDEX]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
// vertex position
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid*>(offsetof(Vertex, position)));
// vertex texture coordinate
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid*>(offsetof(Vertex, texCoord)));
// vertex normal
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid*>(offsetof(Vertex, normal)));
// indices data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBO_Array[VBO_INDEX]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mVBO_InstanceData);
glBufferData(GL_ARRAY_BUFFER, instanceData.size() * sizeof(glm::mat4), instanceData.data(), GL_STATIC_DRAW);
// instance data
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(0));
glVertexAttribDivisor(3, 1); // increment instance data by 1 each iteration
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(sizeof(glm::vec4)));
glVertexAttribDivisor(4, 1);
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(2 * sizeof(glm::vec4)));
glVertexAttribDivisor(5, 1);
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), reinterpret_cast<GLvoid*>(3 * sizeof(glm::vec4)));
glVertexAttribDivisor(6, 1);
And the vertex shader is simply:
#version 300 es
precision mediump float;
// attribute data
layout (location = 0) in vec3 aVertexPosition;
layout (location = 1) in vec2 aVertexTexCoord;
layout (location = 2) in vec3 aVertexNormal;
layout (location = 3) in mat4 aInstanceTransform;
// varying data
out vec3 vPosition;
out vec2 vTexCoord;
out vec3 vNormal;
// uniform data
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;
void main(void)
{
vec4 mvTransform = uModelViewMatrix * aInstanceTransform * vec4(aVertexPosition, 1.0);
vTexCoord = aVertexTexCoord;
vPosition = mvTransform.xyz;
vNormal = normalize(uNormalMatrix * aVertexNormal);
gl_Position = uProjectionMatrix * mvTransform;
}
I don’t know what’s causing the issue as of yet. I think it might have something to do with the “aInstanceTransform” attribute. If I comment it out in the main function then the program runs. I wonder if I need to use 2 vec4s instead?