首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VAO与glDrawElements的结合

VAO与glDrawElements的结合
EN

Stack Overflow用户
提问于 2018-04-20 19:22:34
回答 2查看 829关注 0票数 1

我第一次尝试使用OpenGL 3.2在屏幕上画一些精灵。我在试着建立一个VAO,但它不起作用。我接到EXC_BAD_ACCESS的电话打给glDrawElements。

VAO设置:

代码语言:javascript
复制
// setting up VAO

glGenVertexArrays(1, &vao_);

glBindVertexArray(vao_);

glGenBuffers(1, &indices_id_);

glGenBuffers(1, &attributes_id_);

glBindBuffer(GL_ARRAY_BUFFER, attributes_id_);

constexpr GLfloat* ptr = 0;

::glVertexAttribPointer(attribute_position_, 2, GL_FLOAT, false, STRIDE, ptr);
::glVertexAttribPointer(attribute_region_, 2, GL_FLOAT, false, STRIDE, ptr + 2);
::glVertexAttribPointer(attribute_color_, 4, GL_FLOAT, false, STRIDE, ptr + 4);

::glEnableVertexAttribArray(attribute_position_);
::glEnableVertexAttribArray(attribute_region_);
::glEnableVertexAttribArray(attribute_color_);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_id_);

{
    auto data = std::make_unique<short[]>(BATCH_SIZE * 6);

    short j = 0;

    for (std::size_t i = 0; i < BATCH_SIZE * 6; i += 6, j += 4)
    {
        data[i] = j;
        data[i + 1] = (short)(j + 1);
        data[i + 2] = (short)(j + 2);
        data[i + 3] = (short)(j + 2);
        data[i + 4] = (short)(j + 3);
        data[i + 5] = j;
    }

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(BATCH_SIZE * 6 * sizeof(short)), data.get(), GL_STATIC_DRAW);
}

glBindVertexArray(0);

然后在绘图循环的其他地方:

代码语言:javascript
复制
// drawing

glBindVertexArray(vao_);

glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(float) * buffer_index_), attributes_.data(), GL_DYNAMIC_DRAW);

glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(6 * number_of_sprites_), GL_UNSIGNED_SHORT, 0);

glBindVertexArray(0);

有人能看出我做错了什么吗?

更新

我已经添加了建议的修改(非常感谢这些)。但是,我现在发现,在绘制glBindBuffer(GL_ARRAY_BUFFER, attributes_id_);时,需要在glBindVertexArray(vao_);之前添加一个对EXC_BAD_ACCESS的调用,以消除EXC_BAD_ACCESS错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-20 19:39:18

OpenGL 4.6API核心配置文件规范;10.3。顶点数组.第347页

通过将GenVertexArrays返回的名称与命令绑定来创建顶点数组对象。 BindVertexArray( uint数组); 数组是顶点数组对象名。生成的顶点数组对象是一个新的状态向量,它包含所有状态并具有表23.4-23.7中列出的相同初始值。

表23.4包含ELEMENT_ARRAY_BUFFER_BINDING

这意味着绑定ELEMENT_ARRAY_BUFFER的状态存储在顶点阵列对象中。

在您的示例中,indices_id_存储在vao_的状态向量中,因为

代码语言:javascript
复制
glBindVertexArray(vao_);

.....

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_id_);

当你打电话的时候

代码语言:javascript
复制
glBindVertexArray(0);

indices_id_不再处于当前状态向量中。

您必须更改指令的顺序:

代码语言:javascript
复制
glBindVertexArray(vao_);

.....

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_id_);
{
    .....
    glBufferData(indices_id_, static_cast<GLsizeiptr>(BATCH_SIZE * 6), data.get(), GL_STATIC_DRAW);
}
glBindVertexArray(0);
票数 1
EN

Stack Overflow用户

发布于 2018-04-20 19:29:18

glBufferData()期望目标缓冲区作为第一个参数。这里的命名有点混乱,但这意味着您告诉OpenGL您指的是哪个绑定缓冲区,而不是缓冲区的name。下面是一个示例:

代码语言:javascript
复制
glBindBuffer(GL_ARRAY_BUFFER, foo); // Binds the buffer named foo to the GL_ARRAY_BUFFER target

glBufferData(GL_ARRAY_BUFFER, ...); // Tells GL you mean the buffer bound to the GL_ARRAY_BUFFER target
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49948449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档