Spritebatch только рисование первого спрайта

0

Я реализовал OpenGL spritebatch, но только рисовал первый спрайт при использовании одной и той же текстуры для нескольких спрайтов. Например: если я использую его для отображения глифов для строки "Hello", он отображает только "H".

Мои шейдеры очень просты:

Фрагмент:

#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);
}

И они компилируют, связывают и проверяют без каких-либо ошибок.

Мой спрайт-код также довольно прост. Вот как я инициализирую пакет Sprite:

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
    Выложенный код выглядит хорошо. Я думаю, что нам нужно увидеть хотя бы код, который устанавливает indices и массивы vertices .
  • 0
    @derhass Я добавил этот код. Надеюсь, это не так уж и много. Первая часть просто устанавливает вершины и координаты текстуры, затем преобразует вершины в систему координат пространства клипа OpenGL.
Теги:
opengl
sprite

1 ответ

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);
}
  • 1
    Благодарю. Только одно замечание: это должно быть +4 * i потому что на глиф приходится 4 вершины. Это исправило это.
  • 0
    @RaptorDotCpp: Да, может плохо. Вы абсолютно правы. Спасибо, что заметили это, я исправил ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню