完整代码(工作正常):
#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
函数中再次调用它们?
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);