I've implemented an OpenGL spritebatch, but it's only drawing the first sprite when using the same texture for multiple sprites. For example: if I use it to render glyphs for a string "Hello", it only renders the "H".
My shaders are very simple:
Fragment:
#version 150 core
uniform sampler2D tex;
in vec2 Texcoord;
out vec4 outColor;
void main()
{
outColor = texture(tex, Texcoord);
}
Vertex:
#version 150 core
in vec3 position;
in vec2 texCoords;
out vec2 Texcoord;
void main()
{
Texcoord = texCoords;
gl_Position = vec4(position, 1.0f);
}
And they compile, link and validate without any errors.
My sprite batching code is also quite simple. Here's how I initialize the Sprite Batch:
glGenVertexArrays(1, &mVao);
glBindVertexArray(mVao);
// INDEX BUFFER
glGenBuffers(1, &mEbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW);
// VERTEX BUFFER
glGenBuffers(1, &mVbo);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW);
// POS ATTRIB
GLint posAttrib;
posAttrib = glGetAttribLocation(mShader.getProgram(), "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
// TEX ATTRIB
GLint texAttrib;
texAttrib = glGetAttribLocation(mShader.getProgram(), "texCoords");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
And finally, here is how I draw:
glBindVertexArray(mVao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mVbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STREAM_DRAW);
glDrawElements(GL_TRIANGLES, (GLsizei)indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
OpenGL throws no errors, vertices and indices contain the correct data, as far as I can tell.
I'm sorry for the amount of code, but because I get no errors whatsoever, I have no indication of where it goes wrong. When I debug the code, I see no values that are out of place or wrong.
EDIT
The code I use to set up the vertices and indices vectors is this:
for(int i = 0; i < currentSprites.size(); ++i)
{
Sprite* current = currentSprites.at(i);
// 4 * (2 (pos) + 2 (tex))
float verticesArray[16] =
{
// TOP LEFT
current->x,
current->y,
(float)current->textureRect.x / (float)current->texture.w,
(float)current->textureRect.y / (float)current->texture.h,
// TOP RIGHT
current->x + current->w,
current->y,
(float)(current->textureRect.x + current->textureRect.w) / (float)current->texture.w,
(float)current->textureRect.y / (float)current->texture.h,
// BOTTOM RIGHT
current->x + current->w,
current->y + current->h,
(float)(current->textureRect.x + current->textureRect.w) / (float)current->texture.w,
(float)(current->textureRect.y + current->textureRect.h) / (float)current->texture.h,
// BOTTOM LEFT
current->x,
current->y + current->h,
(float)current->textureRect.x / (float)current->texture.w,
(float)(current->textureRect.y + current->textureRect.h) / (float)current->texture.h
};
for(int v = 0; v < 16; v += 4)
{
float zPos = -(float)current->layer / 100.0f;
// Projection matrix
glm::vec4 result = mCamera.getProjectionMatrix() * glm::vec4(verticesArray[v], verticesArray[v+1], zPos, 1.0f); // This is just an orthographic projection matrix
verticesArray[v] = result.x;
verticesArray[v+1] = result.y;
zPos = result.z;
vertices.push_back(Vertex(glm::vec3(verticesArray[v], verticesArray[v + 1], zPos),
glm::vec2(verticesArray[v + 2], verticesArray[v + 3])));
}
static GLuint _indices[6] =
{
0, 1, 3, 3, 1, 2
};
for(int index = 0; index < 6; ++index)
{
indices.push_back(_indices[index]);
}
}
indicesandverticesarrays. - derhass