glDrawElements抛出GL_INVALID_VALUE错误 [英] glDrawElements throw GL_INVALID_VALUE error

查看:609
本文介绍了glDrawElements抛出GL_INVALID_VALUE错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制部分平铺图像,但是调用glDrawElements函数时出现GL_INVALID_VALUE错误.当我使用glDrawArrays更改此函数时,没有问题.问题是索引计数参数不是负数.

I am trying to draw part of my tile image but I am getting GL_INVALID_VALUE error when I call glDrawElements function. There is no problem when I change this function with glDrawArrays. The problem is that the indices count parameter is not negative number.

有一个代码:

#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
 #define VERTEX_ATTR_PTR(loc, count, member, type) \
    glEnableVertexAttribArray(loc); \
    glVertexAttribPointer(loc, count, GL_FLOAT, GL_FALSE, sizeof(type),  BUFFER_OFFSET(offsetof(struct type, member)))
// ---------- TextRenderer
void TextRenderer::setText(const string& text) {
    vector<Vertex2f> vertex_buffer;
    vector<GLuint> index_buffer;

    GLfloat cursor = 0.f;
    FPoint2D cell_size = font->getCellSize();

    for (char c : text) {
        TILE_ITER iter = font->getCharacter(c);
        {
            // UV
            for (GLuint i = 0; i < 4; ++i) {
                TILE_ITER _v = iter + i;
                vertex_buffer.push_back( {
                        {
                                _v->pos[0]  + cursor,
                                _v->pos[1],
                                _v->pos[2]
                        },
                        { _v->uv[0], _v->uv[1] }
                });
            }
            // Index
            for (GLuint i = 0; i < 6; ++i)
                index_buffer.push_back(
                        Tile::indices[i] + vertex_buffer.size() - 4);
        }
        cursor += cell_size.X;
    }

    vertices_count = vertex_buffer.size();
    indices_count = index_buffer.size();

    glBindVertexArray(vao);
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                0,
                indices_count * sizeof(GLuint),
                &index_buffer[0]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferSubData(GL_ARRAY_BUFFER,
                0,
                vertices_count * sizeof(Vertex2f),
                &vertex_buffer[0]);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
    glBindVertexArray(0);
}
void TextRenderer::create() {
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    {
        indices = genGLBuffer( {
                nullptr,
                BUFFER_SIZE / 2 * sizeof(GLuint),
                GL_ELEMENT_ARRAY_BUFFER
        }, true, GL_DYNAMIC_DRAW);

        vbo = genGLBuffer( {
                nullptr,
                BUFFER_SIZE * sizeof(Vertex2f),
                GL_ARRAY_BUFFER
        }, true, GL_DYNAMIC_DRAW);

        VERTEX_ATTR_PTR(0, 3, pos, Vertex2f); // Vertex
        VERTEX_ATTR_PTR(1, 2, uv, Vertex2f); // UV
    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setText("DUPA");
}
void TextRenderer::draw(MatrixStack& matrix, GLint) {
    static Shader shader(
            getFileContents("shaders/text_frag.glsl"),
            getFileContents("shaders/text_vert.glsl"),
            "");

    shader.begin();
    shader.setUniform(GL_TEXTURE_2D, "texture", 0,
            font->getHandle());
    shader.setUniform("matrix.mvp", matrix.vp_matrix * matrix.model);
    shader.setUniform("col", col);
    {
        glBindVertexArray(vao);
        //glDrawArrays(GL_LINE_STRIP, 0, vertices_count);
        glDrawElements(GL_LINES, indices_count, GL_UNSIGNED_INT,
                nullptr);
        glBindVertexArray(0);
        showGLErrors();
    }
    shader.end();
}

推荐答案

问题出在setText()方法中的以下(缩短的)调用序列:

The problem is with the following (shortened) call sequence in your setText() method:

glBindVertexArray(vao);
{
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ...);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    ...
}
glBindVertexArray(0);

GL_ELEMENT_ARRAY_BUFFER的绑定是VAO状态的一部分.因此,在绑定VAO时拨打此电话:

The binding of the GL_ELEMENT_ARRAY_BUFFER is part of the VAO state. So by making this call while the VAO is bound:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

您正在将VAO状态设置为具有0的元素数组缓冲区绑定.因此,当您以后在draw()方法中绑定VAO时,就没有GL_ELEMENT_ARRAY_BUFFER的绑定.

you're setting the VAO state to have an element array buffer binding of 0. So when you later bind the VAO in your draw() method, you won't have a binding for GL_ELEMENT_ARRAY_BUFFER.

为避免这种情况,最简单的解决方案是仅删除该呼叫.如果您由于担心绑定它而明确地取消绑定,可能会对其他代码产生不良影响,则需要在解除绑定VAO之后将其移动:

To avoid this, the simplest solution is to just remove that call. If you want to explicitly unbind it because you're worried that having it bound might have undesired side effects on other code, you need to move it after unbinding the VAO:

glBindVertexArray(vao);
{
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ...);

    ...
}
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

这篇关于glDrawElements抛出GL_INVALID_VALUE错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆