我实现了一个OpenGL spritebatch,但它只为多个sprite使用相同的纹理时绘制了第一个sprite。例如:如果我使用它来渲染字符串的字形" Hello",它只会渲染" H"。
我的着色器非常简单:
片段:
#version 150 core
uniform sampler2D tex;
in vec2 Texcoord;
out vec4 outColor;
void main()
{
outColor = texture(tex, Texcoord);
}
顶点:
#version 150 core
in vec3 position;
in vec2 texCoords;
out vec2 Texcoord;
void main()
{
Texcoord = texCoords;
gl_Position = vec4(position, 1.0f);
}
他们编译,链接和验证没有任何错误。
我的精灵批处理代码也很简单。以下是我如何初始化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)));
最后,我的绘画方式如下:
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不会抛出任何错误,vertices
和indices
包含正确的数据,据我所知。
我很抱歉代码的数量,但由于我没有任何错误,我没有迹象表明它出错了。当我调试代码时,我看不到任何不合适或错误的值。
修改
我用来设置顶点和索引向量的代码是:
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]);
}
}
答案 0 :(得分:2)
我认为问题是你的索引缓冲区。您正在将所有字形的顶点批处理到同一个VBO中,并使用一个绘制调用绘制它们(这是一种很好的方法)。但是,对于每个glypgh,您要添加相同的 6个索引:
static GLuint _indices[6] =
{
0, 1, 3, 3, 1, 2
};
for(int index = 0; index < 6; ++index)
{
indices.push_back(_indices[index]);
}
因此,实际上,您的代码会反复绘制第一个四边形,从不使用之后添加的任何顶点。
您需要偏移正在绘制的每个字形的索引,例如:
for(int index = 0; index < 6; ++index)
{
indices.push_back(_indices[index] + 4*i);
}