Hello. I am working on a 2D c++ game project. I am trying to improve the graphics system by reducing the number of draw calls. So I basically copied the Sprite class I had, and tweaked it into a new class: ISprite. And while I can create ISprites without any errors, they do not actually draw on the screen. Sprites and debug lines still display normally. So basically I’m trying to find out what is wrong with my instanced sprite system and would appreciate some help.
Here is some relevant code:
Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;
layout (location = 2) in vec3 colorSource;
layout (location = 3) in mat4 transform;
out vec2 TexCoords;
out vec4 Color;
uniform mat4 uniformView;
uniform mat4 uniformProjection;
void main()
{
gl_Position = uniformProjection * uniformView * transform * vec4(position, 1.0f);
TexCoords = texCoords;
Color = vec4(colorSource, 1.0f);
}
Fragment Shader
#version 330 core
in vec2 TexCoords;
in vec4 Color;
out vec4 color;
uniform sampler2D Texture;
uniform vec4 uniformColor;
void main()
{
vec4 texColor = texture(Texture, TexCoords) * Color;
if(texColor.a < 0.1)
discard;
color = texColor;
}
Load, does preparations required for drawing every sprite
void ISprite::Load(Shader spriteShader)
{
GLfloat vertices[] = {
//X Y Z
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
glGenVertexArrays(1, &vertexArray);
glGenBuffers(1, &positionBuffer);
glGenBuffers(1, &texCoordsBuffer);
glGenBuffers(1, &colorBuffer);
glGenBuffers(1, &matrixBuffer);
glBindVertexArray(vertexArray);
//For vertex Position
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
//The vertex data will never change, so send that data now.
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//For texture coordinates
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texCoordsBuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
//For Color
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
//For Transformation Matrix
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, matrixBuffer);
glVertexAttribPointer(3, 1, GL_MATRIX4_ARB, GL_FALSE, 0, (GLvoid*)0);
//Unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//Sets up support for instancing
glVertexAttribDivisor(0, 0);
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
ISprite::shader = &spriteShader;
}
And the two drawing functions:
Prepare Draw
void ISprite::prepareDraw(void)
{
//Adds their personal data to vectors shared by class
transformMatrices.push_back(calculateTransorm());
for (int i = 0; i < 6; i += 2)
{
texture.updateAnimation();
ISprite::textureCoordinatesAll.push_back(texture.textureCoordinates[i]);
ISprite::textureCoordinatesAll.push_back(texture.textureCoordinates[i + i]);
}
ISprite::colorValues.push_back(color.x);
ISprite::colorValues.push_back(color.y);
ISprite::colorValues.push_back(color.z);
}
drawSprites
void ISprite::drawSprites(Texture testTexture)
{
shader->Use();
glBindTexture(GL_TEXTURE_2D, testTexture.ID);
for (std::vector<ISprite*>::iterator it = Isprites.begin(); it != Isprites.end(); ++it)
(*it)->prepareDraw();
glBindVertexArray(vertexArray);
//Bind texture here if you want textures to work. if not, a single texture atlas will be bound
glBindBuffer(GL_ARRAY_BUFFER, texCoordsBuffer);
glBufferData(GL_ARRAY_BUFFER, textureCoordinatesAll.size() * sizeof(GLfloat),
NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, textureCoordinatesAll.size() * sizeof(GLfloat),
textureCoordinatesAll.data());
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, colorValues.size() * sizeof(GLfloat),
NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, colorValues.size() * sizeof(GLfloat),
colorValues.data());
glBindBuffer(GL_ARRAY_BUFFER, matrixBuffer);
glBufferData(GL_ARRAY_BUFFER, transformMatrices.size() * sizeof(glm::mat4),
NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, transformMatrices.size() * sizeof(glm::mat4),
transformMatrices.data());
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, Isprites.size());
textureCoordinatesAll.clear();
colorValues.clear();
transformMatrices.clear();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}