为什么OpenGL无法正确绘制矩形

时间:2019-06-06 03:57:49

标签: c++ opengl

我正在尝试构建游戏引擎,我想使其尽可能跨平台,但是可能会怀疑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 个答案:

答案 0 :(得分:1)

您的胶印处理对我来说似乎有点奇怪?首先,您将32bit int转换为指针类型。如果您使用的是64位操作系统,那将引起麻烦。如果将偏移量更改为uint8_t ptr,则将消除问题之一(并消除对转换的需要)。

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;

偏移量计算代码几乎假设所有数据都来自单个缓冲区。但是,您似乎为每个元素绑定了一个不同的缓冲区,您将假定每个缓冲区的偏移量为零。某件事告诉我,您根本不应该计算偏移量,而应该将其作为变量添加到元素结构中(即,您将为每个元素手动指定-这将允许您使用两个单独的缓冲区,并且多个元素存储在单个缓冲区中)

最后一个问题,如果element.type是GL_FLOAT或GL_HALF_FLOAT以外的任何其他字符,则您有一个错误。对于整数类型,应使用glVertexAttribIPointer,而对于GL_DOUBLE,则需要使用glVertexAttribLPointer。