Почему OpenGL неправильно рисует прямоугольник - PullRequest
0 голосов
/ 06 июня 2019

Я пытаюсь создать игровой движок и хотел сделать его кроссплатформенным, насколько это возможно, но абстракция BufferLayout может быть подозрительной

Я пытался его отладить, но все числа верны. Я также пытался обернуть вызовы OpenGL вокруг кода проверки ошибок, но не обнаружил ошибок.

void OpenGLVertexArray::AddBuffers(const std::vector<std::shared_ptr<Buffer>>& buffers, const BufferLayout& layout)
{
    BZ_CORE_ASSERT(layout.GetElements().size() == buffers.size(), "Error, buffers and layout elements are not same size!");

    Enable();

    const auto& elements = layout.GetElements();
    uint32 offset = 0;
    for (size_t i = 0; i < buffers.size(); ++i)
    {
        buffers[i]->Bind();
        const auto& element = elements[i];
        GLCall(glEnableVertexAttribArray(i));
        GLCall(glVertexAttribPointer(i, element.count, element.type, element.normalized ? GL_TRUE : GL_FALSE, layout.GetStride(), (const void*)offset));
        offset += BufferElement::GetSize(element.type) * element.count;
        buffers[i]->Unbind();
    }

    Disable();
}

Если вам нужно больше кода, я опубликовал весь код на GitHub. https://github.com/WhoseTheNerd/MinecraftPi

Я ожидал, что прямоугольник будет отображаться на экране, но он отображает странный треугольник. https://i.imgur.com/yOIZcsu.png

1 Ответ

1 голос
/ 06 июня 2019

Ваша обработка смещения кажется мне немного странной? Сначала вы приводите 32-битный тип int в тип указателя. Это будет беспокоить, если вы используете 64-битную ОС. Если вы измените смещение на ptr uint8_t, это устранит одну из проблем (и устранит необходимость в приведении).

const uint8_t* offset = 0;

Еще одна проблема, которую я вижу, заключается в том, что ваши вычисления смещения кажутся несколько запутанными. Вы уверены, что не просто хотели передать 0 для каждого смещения?

    // bind an entirely new buffer
    buffers[i]->Bind();

    /* snip */

    // ok, so if buffers[0] contains the vertices. The offset for the next 
    // buffer will be (numVertices * sizeof(float) * 3) ?
    // So then I bind buffers[1] (let's say they contain vertex colours)
    // The array itself is (numVertices * sizeof(float) * 3) in size,
    // however the offset from the previous iteration is going to point
    // past the end of the buffer. That seems wrong to my eyes?
    offset += BufferElement::GetSize(element.type) * element.count;

Похоже, что код вычисления смещения предполагает, что все данные будут поступать из одного буфера. Однако вы, кажется, связываете другой буфер для каждого элемента, который, как вы предполагаете, указывает на нулевое смещение для каждого буфера. Что-то подсказывает мне, что вам вообще не нужно вычислять смещение, а вместо этого следует добавить его в качестве переменной var к структуре вашего элемента (т.е. вы будете указывать вручную для каждого элемента - что позволит вам использовать как отдельные буферы, так и несколько элементов хранятся в одном буфере)

Последняя проблема, если element.type отличается от GL_FLOAT или GL_HALF_FLOAT, у вас есть ошибка. Для целочисленных типов вы должны использовать glVertexAttribIPointer, а для GL_DOUBLE вам нужно использовать glVertexAttribLPointer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...