当 glVertexAttribPointer() 和 glEnableVertexAttribArray() 调用被移动到另一个函数时没有绘制?

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

完整代码(工作正常):

#include "shapes.h"

// ...

GLuint vao;
GLuint ebo;

// Creates and binds the EBO and the VAO buffers
// Should call this function before any drawing
void PrepareShapes()
{
    glGenVertexArrays(1, &vao);

    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices, GL_STATIC_DRAW);
}

Paddle::Paddle(float x, float y, float width, float height)
{
    const float paddleVertices[] =
    {
        0, 0,
        width, 0,
        width, height,
        0, height
    };
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(paddleVertices), &paddleVertices, GL_STATIC_DRAW);
    glm::mat4 proj = glm::ortho(0.0, 640.0, 360.0, 0.0, 0.0, 1.0);
    model = glm::mat4(1.0);
    model *= glm::translate(model, glm::vec3(x, y, 0));
    model = proj * model;
}

void Paddle::Draw()
{
    glBindVertexArray(vao);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glUniformMatrix4fv(glGetUniformLocation(GetShader(), "model"), 1, GL_FALSE, &model[0][0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

这个程序画了一个“桨”。在绘制之前,您应该调用函数

PrepareShapes
来创建和绑定所需的缓冲区(EBO 和 VAO)。它的用法是这样的:

PrepareShapes();
Paddle pad(0, 0, 8, 80);
pad.Draw();

到目前为止一切正常。当我尝试将这两个调用从

Draw
函数移动到
PrepareShapes
函数时,没有绘制任何内容。为什么?这之后的
PrepareShapes
函数:

void PrepareShapes()
{
    glGenVertexArrays(1, &vao);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);
    glEnableVertexAttribArray(0);
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices, GL_STATIC_DRAW);
}

还有一个问题。我已经在

glBind*
函数中调用了
Draw
函数,为什么还要在
PrepareShapes
函数中再次调用它们?

c++ opengl glm-math
1个回答
0
投票

glVertexAttribPointer
被调用时,当前绑定到
ARRAY_BUFFER
目标的缓冲区,关联到指定的属性索引,对象的ID存储在当前绑定的VAO的状态向量中。因此,必须在指定属性之前绑定缓冲对象和VAO:

glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);
© www.soinside.com 2019 - 2024. All rights reserved.