把数据的处理 放到循环里来,那么每次渲染时,都会得到不同的VAO数据,画出不同的东西。通常,绘制不变的已知的数据时,会放在循环的外面。
while (!glfwWindowShouldClose(window))
{
glPointSize(3.0f);
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
const int segment = 1000;
const float pi = 3.1415926;
for (int i = 0; i < segment; i++)
{
float circle_ver[] = {
cos(tmp)+0.5, sin(tmp)+0.5, 0.0
};
tmp = 2 * pi*i / segment;
glBindVertexArray(cVAO);
glBindBuffer(GL_ARRAY_BUFFER, cVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(circle_ver), circle_ver, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
circleShader->use();
glm::mat4 projection=glm::mat4(1.0f);
circleShader->setMat4("projection", projection);
glBindVertexArray(cVAO);
glDrawArrays(GL_POINTS, 0, 1);
}
...
}
我们可以一次提供一个顶点数据,但是这个方式效率太低。以前的opengl也有一个Display list 的概念,一次打包提供一组数据,这样效率高,但是由于数据是直接存储在了GPU端,数据一旦提供了就无法再调整了。后来又提供了VBO(vertex buffer object)的概念,也是一次收集/打包好一组数据,但相较于Display List,数据是收集在CPU端,每次渲染会再传递一次。所以这种方式相较于一次提供一个顶点数据,效率更高,但是相较于Display List方式,效率稍微低一点,不过灵活性提高了。
float vertices[] = {
-1.0f, -0.5f, 0.0f, // left
0.0f, -0.5f, 0.0f, // right
-0.5f, 0.5f, 0.0f // top
};
unsigned int VBO;
glGenBuffers(1, &VBO);
while{
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glUseProgram(shaderProgram);
…draw
}