设置VAO、VBO和EBO:
我们将顶点数据传递给GPU并配置相应的属性指针,以便着色器能够正确地处理它们。
- VAO(Vertex Array Object):用于存储顶点数组的状态,使我们能够更容易地管理顶点数据。
- VBO(Vertex Buffer Object):用于存储顶点数据,如位置和纹理坐标。
- EBO(Element Buffer Object):用于存储索引数据,这使我们能够通过索引的方式来绘制顶点。
见实例:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stb_image.h>
// 着色器源代码
const char *vertexShaderSource = "vertex shader source code";
const char *fragmentShaderSource = "fragment shader source code";
// 主函数
int main() {
// 初始化GLFW和GLAD
// 创建和编译着色器
// 设置VAO、VBO和EBO
float vertices[] = {
// 位置 // 纹理坐标
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO); //打开VAO,开始记录后面所有的操作,这点非常重要
glBindBuffer(GL_ARRAY_BUFFER, VBO);//打开VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//向VBO中传入数据
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//打开EBO
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//向EBO传入索引数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);//设置VBO属性指针
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 加载图像并创建纹理
int width, height, nrChannels;
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load("path/to/your/image.png", &width, &height, &nrChannels, 0);
if (data) {
GLenum format;
if (nrChannels == 1) {
format = GL_RED;
} else if (nrChannels == 3) {
format = GL_RGB;
} else if (nrChannels == 4) {
format = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
} else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 渲染循环
while (!glfwWindowShouldClose(window)) {
// 输入处理
// ...
// 渲染
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
//下面三句即可渲染图形,上面所做事情均包含在下面前二句中,最后一句是执行绘制
glBindVertexArray(VAO); //这里只需绑定VAO(或起用),一套前面进行的顶点及属性设置便不再需要,所有过程均保存在VAO中,这点很重要
// 绑定纹理
glBindTexture(GL_TEXTURE_2D, texture);
// 绘制图形
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// 交换缓冲区并处理事件
glfwSwapBuffers(window);
glfwPollEvents();
}
// 释放资源
glfwTerminate();
return 0;
}