你能持久映射 GL_ELEMENT_ARRAY_BUFFER,如果可以,为什么 glMultiDrawE;ementsIndirect 给出 GL_INVALID_OPERATION?

问题描述 投票:0回答:0

编辑:我曾尝试在调用绘制函数之前对 element_array_buffer 进行 glUnmapBuffer 调用,但这没有帮助,因此希望这与错误无关。

在阅读了一篇关于体素游戏“顶点池化”的文章后,在其中使用持久映射缓冲区我可以在一次调用 glMultiDrawElementsIndirect 中绘制我的整个世界,我开始在我自己的 WIP 体素引擎中实现它,我自己用 C++ 和OpenGL,但我有一些问题以及 GL_INVALID_OPERATION 错误我不知道如何解决。

首先,为什么要使顶点缓冲区持久映射,而用 glBufferData 填充索引/元素缓冲区?你必须这样做吗?我假设缓冲元素与缓冲网格顶点一样昂贵。所以,在我的实现中,我一直映射我的 vbo 和我的 ibo/ebo,但这似乎不起作用。

当我尝试绘制时,我得到 GL_INVALID_OPERATION。 glMultiDrawElementsIndirect 的维基页面给出了一些可能的原因,但我没有看到任何可以在这里应用的原因。

void Draw() {
        CheckGlErrors();
        glBindVertexArray(vao);  
        glBindBuffer(GL_ARRAY_BUFFER, vbo); 
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indbo); 
        glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0, draw_commands.size(), sizeof(IndirectDrawCommand));
        CheckGlErrors();
    };

我在这里创建我的缓冲区/vao: (顺便说一句,我必须像这样做我的 vao 吗?之前,我使用 glVertexAttribPointer。它们是等价的吗?

        auto flags = GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT|GL_MAP_WRITE_BIT;

        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferStorage(GL_ARRAY_BUFFER, MeshSize * PoolSize, nullptr, flags); 
// mesh size is #of vertices per mesh in the pool
// (meshes are padded up to this size to avoid memory fragmentation)
// pool size is # of meshes the pool can hold
        pool_vertices = (char*)glMapBufferRange(GL_ARRAY_BUFFER, 0,4, flags);

        glGenBuffers(1, &ibo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, IndexSize * PoolSize, nullptr, flags);
        pool_indices = (char*)(glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, IndexSize * PoolSize, flags));

        glEnableVertexAttribArray(0); 
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);

        glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
        glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
        glVertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 0);

        glVertexBindingDivisor(0, 0);
        glVertexBindingDivisor(1, 0);
        glVertexBindingDivisor(2, 0);

        glVertexAttribBinding(0, 0);
        glVertexAttribBinding(1, 1);
        glVertexAttribBinding(2, 2);

        glBindVertexBuffer(0, vbo, 0, 36);
        glBindVertexBuffer(1, vbo, 12, 36);
        glBindVertexBuffer(2, vbo, 24, 36);
c++ opengl voxel
© www.soinside.com 2019 - 2024. All rights reserved.