本文整理了常用的opengl缓冲区对象并安排了使用示例
1. 顶点数组对象(Vertex Array Object, VAO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
// 初始化 GLFW
if (!glfwInit()) {
std::cerr << "GLFW 初始化失败" << std::endl;
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(800, 600, "VAO 示例", nullptr, nullptr);
if (!window) {
glfwTerminate();
std::cerr << "窗口创建失败" << std::endl;
return -1;
}
glfwMakeContextCurrent(window);
// 初始化 GLEW
if (glewInit() != GLEW_OK) {
glfwTerminate();
std::cerr << "GLEW 初始化失败" << std::endl;
return -1;
}
// 创建 VAO
GLuint VAO;
glGenVertexArrays(1, &VAO);
// 绑定 VAO
glBindVertexArray(VAO);
// 这里可以进行 VBO 和 EBO 的绑定与设置
// 解绑 VAO
glBindVertexArray(0);
// 主循环
while (!glfwWindowShouldClose(window)) {
// 处理事件
glfwPollEvents();
// 绑定 VAO
glBindVertexArray(VAO);
// 绘制操作
// glDrawArrays(GL_TRIANGLES, 0, 3);
// 解绑 VAO
glBindVertexArray(0);
// 交换缓冲区
glfwSwapBuffers(window);
}
// 清理 VAO
glDeleteVertexArrays(1, &VAO);
// 终止 GLFW
glfwTerminate();
return 0;
}
2. 顶点缓冲区对象(Vertex Buffer Object, VBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "VBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 顶点数据
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// 创建 VBO
GLuint VBO;
glGenBuffers(1, &VBO);
// 绑定 VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 填充数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 解绑 VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glfwTerminate();
// 清理 VBO
glDeleteBuffers(1, &VBO);
return 0;
}
3. 索引缓冲区对象(Element Buffer Object, EBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "EBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 顶点数据
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// 索引数据
unsigned int indices[] = {
0, 1, 2
};
// 创建 EBO
GLuint EBO;
glGenBuffers(1, &EBO);
// 绑定 EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
// 填充数据
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 解绑 EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glfwTerminate();
// 清理 EBO
glDeleteBuffers(1, &EBO);
return 0;
}
4. 统一缓冲区对象(Uniform Buffer Object, UBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
const GLuint UBO_BINDING_POINT = 0;
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "UBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 UBO
GLuint UBO;
glGenBuffers(1, &UBO);
// 绑定 UBO
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
// 分配内存
glBufferData(GL_UNIFORM_BUFFER, 16 * sizeof(float), nullptr, GL_STATIC_DRAW);
// 绑定到指定绑定点
glBindBufferBase(GL_UNIFORM_BUFFER, UBO_BINDING_POINT, UBO);
// 解绑 UBO
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glfwTerminate();
// 清理 UBO
glDeleteBuffers(1, &UBO);
return 0;
}
5. 着色器存储缓冲区对象(Shader Storage Buffer Object, SSBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "SSBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 数据
float data[] = {1.0f, 2.0f, 3.0f, 4.0f};
// 创建 SSBO
GLuint SSBO;
glGenBuffers(1, &SSBO);
// 绑定 SSBO
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);
// 填充数据
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
// 绑定到指定绑定点
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, SSBO);
// 解绑 SSBO
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glfwTerminate();
// 清理 SSBO
glDeleteBuffers(1, &SSBO);
return 0;
}
6. 像素缓冲区对象(Pixel Buffer Object, PBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "PBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 PBO
GLuint PBO;
glGenBuffers(1, &PBO);
// 绑定 PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PBO);
// 分配内存
glBufferData(GL_PIXEL_UNPACK_BUFFER, 800 * 600 * 4, nullptr, GL_STREAM_DRAW);
// 解绑 PBO
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glfwTerminate();
// 清理 PBO
glDeleteBuffers(1, &PBO);
return 0;
}
7. 变换反馈缓冲区对象(Transform Feedback Buffer Object, TFBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "TFBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 TFBO
GLuint TFBO;
glGenBuffers(1, &TFBO);
// 绑定 TFBO
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, TFBO);
// 分配内存
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
// 绑定到变换反馈绑定点
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TFBO);
// 解绑 TFBO
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
glfwTerminate();
// 清理 TFBO
glDeleteBuffers(1, &TFBO);
return 0;
}
8. 原子计数器缓冲区对象(Atomic Counter Buffer Object, ACBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "ACBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 ACBO
GLuint ACBO;
glGenBuffers(1, &ACBO);
// 绑定 ACBO
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, ACBO);
// 分配内存
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), nullptr, GL_DYNAMIC_DRAW);
// 绑定到指定绑定点
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, ACBO);
// 解绑 ACBO
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
glfwTerminate();
// 清理 ACBO
glDeleteBuffers(1, &ACBO);
return 0;
}
9. 纹理缓冲区对象(Texture Buffer Object, TBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "TBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 数据
float data[] = {1.0f, 2.0f, 3.0f, 4.0f};
// 创建 TBO
GLuint TBO;
glGenBuffers(1, &TBO);
// 绑定 TBO
glBindBuffer(GL_TEXTURE_BUFFER, TBO);
// 填充数据
glBufferData(GL_TEXTURE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
// 创建纹理
GLuint texture;
glGenTextures(1, &texture);
// 绑定纹理
glBindTexture(GL_TEXTURE_BUFFER, texture);
// 将 TBO 关联到纹理
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, TBO);
// 解绑 TBO 和纹理
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glfwTerminate();
// 清理 TBO 和纹理
glDeleteBuffers(1, &TBO);
glDeleteTextures(1, &texture);
return 0;
}
10. 查询对象(Query Object)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "查询对象示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建查询对象
GLuint query;
glGenQueries(1, &query);
// 开始查询
glBeginQuery(GL_SAMPLES_PASSED, query);
// 这里进行绘制操作
// glDrawArrays(GL_TRIANGLES, 0, 3);
// 结束查询
glEndQuery(GL_SAMPLES_PASSED);
// 获取查询结果
GLuint result;
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
std::cout << "采样通过数量: " << result << std::endl;
// 清理查询对象
glDeleteQueries(1, &query);
glfwTerminate();
return 0;
}
11. 帧缓冲区对象(Framebuffer Object, FBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "FBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 FBO
GLuint FBO;
glGenFramebuffers(1, &FBO);
// 绑定 FBO
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
// 这里可以创建并附加纹理或渲染缓冲区
// 检查 FBO 是否完整
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cerr << "FBO 不完整" << std::endl;
// 解绑 FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glfwTerminate();
// 清理 FBO
glDeleteFramebuffers(1, &FBO);
return 0;
}
12. 渲染缓冲区对象(Renderbuffer Object, RBO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "RBO 示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
// 创建 RBO
GLuint RBO;
glGenRenderbuffers(1, &RBO);
// 绑定 RBO
glBindRenderbuffer(GL_RENDERBUFFER, RBO);
// 分配内存
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
// 解绑 RBO
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glfwTerminate();
// 清理 RBO
glDeleteRenderbuffers(1, &RBO);
return 0;
}
13. 命令缓冲区(Command Buffer)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
// 模拟命令结构体
struct Command {
enum Type { DRAW_ARRAYS } type;
GLenum mode;
GLint first;
GLsizei count;
};
int main() {
glfwInit();
GLFWwindow* window = glfwCreateWindow(800, 600, "命令缓冲区示例", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewInit();
std::vector<Command> commandBuffer;
// 添加命令到缓冲区
Command cmd;
cmd.type = Command::DRAW_ARRAYS;
cmd.mode = GL_TRIANGLES;
cmd.first = 0;
cmd.count = 3;
commandBuffer.push_back(cmd);
// 执行命令缓冲区中的命令
for (const auto& cmd : commandBuffer) {
if (cmd.type == Command::DRAW_ARRAYS) {
glDrawArrays(cmd.mode, cmd.first, cmd.count);
}
}
glfwTerminate();
return 0;
}
稀疏纹理(Sparse Texture)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
const int WIDTH = 800;
const int HEIGHT = 600;
int main() {
// 初始化 GLFW
if (!glfwInit()) {
std::cerr << "GLFW 初始化失败" << std::endl;
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Sparse Texture Example", nullptr, nullptr);
if (!window) {
glfwTerminate();
std::cerr << "窗口创建失败" << std::endl;
return -1;
}
glfwMakeContextCurrent(window);
// 初始化 GLEW
if (glewInit() != GLEW_OK) {
glfwTerminate();
std::cerr << "GLEW 初始化失败" << std::endl;
return -1;
}
// 检查是否支持稀疏纹理扩展
if (!GLEW_ARB_sparse_texture) {
std::cerr << "不支持 ARB_sparse_texture 扩展" << std::endl;
glfwTerminate();
return -1;
}
// 创建纹理对象
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 分配稀疏纹理存储
GLint alignment;
glGetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_TEXTURE_SPARSE_ARB, 1, &alignment);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, WIDTH, HEIGHT, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
// 定义一个稀疏纹理的子区域
GLint x = 0, y = 0, z = 0;
GLint width = WIDTH / 2, height = HEIGHT / 2, depth = 1;
GLint level = 0;
glTexPageCommitmentARB(GL_TEXTURE_2D, level, x, y, z, width, height, depth, GL_TRUE);
// 主循环
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// 清屏
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 这里可以进行纹理绘制操作
glfwSwapBuffers(window);
}
// 清理资源
glDeleteTextures(1, &texture);
glfwTerminate();
return 0;
}
采样器缓冲区对象(Sampler Buffer Object)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
const int WIDTH = 800;
const int HEIGHT = 600;
int main() {
// 初始化 GLFW
if (!glfwInit()) {
std::cerr << "GLFW 初始化失败" << std::endl;
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Sampler Buffer Object Example", nullptr, nullptr);
if (!window) {
glfwTerminate();
std::cerr << "窗口创建失败" << std::endl;
return -1;
}
glfwMakeContextCurrent(window);
// 初始化 GLEW
if (glewInit() != GLEW_OK) {
glfwTerminate();
std::cerr << "GLEW 初始化失败" << std::endl;
return -1;
}
// 创建缓冲区对象
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
// 分配缓冲区数据
const int bufferSize = 1024;
float* data = new float[bufferSize];
for (int i = 0; i < bufferSize; ++i) {
data[i] = static_cast<float>(i);
}
glBufferData(GL_TEXTURE_BUFFER, bufferSize * sizeof(float), data, GL_STATIC_DRAW);
delete[] data;
// 创建纹理对象并绑定到缓冲区
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_BUFFER, texture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
// 主循环
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// 清屏
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 这里可以在着色器中使用采样器缓冲区对象进行采样操作
glfwSwapBuffers(window);
}
// 清理资源
glDeleteTextures(1, &texture);
glDeleteBuffers(1, &buffer);
glfwTerminate();
return 0;
}
多视图帧缓冲区对象(Multiview Framebuffer Object)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
const int WIDTH = 800;
const int HEIGHT = 600;
int main() {
// 初始化 GLFW
if (!glfwInit()) {
std::cerr << "GLFW 初始化失败" << std::endl;
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Multiview Framebuffer Object Example", nullptr, nullptr);
if (!window) {
glfwTerminate();
std::cerr << "窗口创建失败" << std::endl;
return -1;
}
glfwMakeContextCurrent(window);
// 初始化 GLEW
if (glewInit() != GLEW_OK) {
glfwTerminate();
std::cerr << "GLEW 初始化失败" << std::endl;
return -1;
}
// 检查是否支持多视图扩展
if (!GLEW_NV_multiview) {
std::cerr << "不支持 NV_multiview 扩展" << std::endl;
glfwTerminate();
return -1;
}
// 创建帧缓冲区对象
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// 创建纹理附件
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, WIDTH, HEIGHT, 2); // 2 个视图
// 将纹理附件附加到帧缓冲区
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
// 设置多视图
GLuint views[] = {0, 1};
glNamedFramebufferMultiviewOVR(fbo, GL_COLOR_ATTACHMENT0, texture, 0, 0, 2, 2, views);
// 主循环
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// 清屏
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 这里可以进行多视图渲染操作
glfwSwapBuffers(window);
}
// 清理资源
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &fbo);
glfwTerminate();
return 0;
}