本文整理了常用的opengl緩沖區對象并安排了使用示例
1. 頂點數組對象(Vertex Array Object, VAO)
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>int main() {// 初始化 GLFWif (!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);// 初始化 GLEWif (glewInit() != GLEW_OK) {glfwTerminate();std::cerr << "GLEW 初始化失敗" << std::endl;return -1;}// 創建 VAOGLuint VAO;glGenVertexArrays(1, &VAO);// 綁定 VAOglBindVertexArray(VAO);// 這里可以進行 VBO 和 EBO 的綁定與設置// 解綁 VAOglBindVertexArray(0);// 主循環while (!glfwWindowShouldClose(window)) {// 處理事件glfwPollEvents();// 綁定 VAOglBindVertexArray(VAO);// 繪制操作// glDrawArrays(GL_TRIANGLES, 0, 3);// 解綁 VAOglBindVertexArray(0);// 交換緩沖區glfwSwapBuffers(window);}// 清理 VAOglDeleteVertexArrays(1, &VAO);// 終止 GLFWglfwTerminate();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};// 創建 VBOGLuint VBO;glGenBuffers(1, &VBO);// 綁定 VBOglBindBuffer(GL_ARRAY_BUFFER, VBO);// 填充數據glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 解綁 VBOglBindBuffer(GL_ARRAY_BUFFER, 0);glfwTerminate();// 清理 VBOglDeleteBuffers(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};// 創建 EBOGLuint EBO;glGenBuffers(1, &EBO);// 綁定 EBOglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);// 填充數據glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// 解綁 EBOglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);glfwTerminate();// 清理 EBOglDeleteBuffers(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();// 創建 UBOGLuint UBO;glGenBuffers(1, &UBO);// 綁定 UBOglBindBuffer(GL_UNIFORM_BUFFER, UBO);// 分配內存glBufferData(GL_UNIFORM_BUFFER, 16 * sizeof(float), nullptr, GL_STATIC_DRAW);// 綁定到指定綁定點glBindBufferBase(GL_UNIFORM_BUFFER, UBO_BINDING_POINT, UBO);// 解綁 UBOglBindBuffer(GL_UNIFORM_BUFFER, 0);glfwTerminate();// 清理 UBOglDeleteBuffers(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};// 創建 SSBOGLuint SSBO;glGenBuffers(1, &SSBO);// 綁定 SSBOglBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);// 填充數據glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_STATIC_DRAW);// 綁定到指定綁定點glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, SSBO);// 解綁 SSBOglBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);glfwTerminate();// 清理 SSBOglDeleteBuffers(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();// 創建 PBOGLuint PBO;glGenBuffers(1, &PBO);// 綁定 PBOglBindBuffer(GL_PIXEL_UNPACK_BUFFER, PBO);// 分配內存glBufferData(GL_PIXEL_UNPACK_BUFFER, 800 * 600 * 4, nullptr, GL_STREAM_DRAW);// 解綁 PBOglBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);glfwTerminate();// 清理 PBOglDeleteBuffers(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();// 創建 TFBOGLuint TFBO;glGenBuffers(1, &TFBO);// 綁定 TFBOglBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, TFBO);// 分配內存glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, nullptr, GL_STATIC_DRAW);// 綁定到變換反饋綁定點glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TFBO);// 解綁 TFBOglBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);glfwTerminate();// 清理 TFBOglDeleteBuffers(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();// 創建 ACBOGLuint ACBO;glGenBuffers(1, &ACBO);// 綁定 ACBOglBindBuffer(GL_ATOMIC_COUNTER_BUFFER, ACBO);// 分配內存glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), nullptr, GL_DYNAMIC_DRAW);// 綁定到指定綁定點glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, ACBO);// 解綁 ACBOglBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);glfwTerminate();// 清理 ACBOglDeleteBuffers(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};// 創建 TBOGLuint TBO;glGenBuffers(1, &TBO);// 綁定 TBOglBindBuffer(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();// 創建 FBOGLuint FBO;glGenFramebuffers(1, &FBO);// 綁定 FBOglBindFramebuffer(GL_FRAMEBUFFER, FBO);// 這里可以創建并附加紋理或渲染緩沖區// 檢查 FBO 是否完整if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)std::cerr << "FBO 不完整" << std::endl;// 解綁 FBOglBindFramebuffer(GL_FRAMEBUFFER, 0);glfwTerminate();// 清理 FBOglDeleteFramebuffers(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();// 創建 RBOGLuint RBO;glGenRenderbuffers(1, &RBO);// 綁定 RBOglBindRenderbuffer(GL_RENDERBUFFER, RBO);// 分配內存glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);// 解綁 RBOglBindRenderbuffer(GL_RENDERBUFFER, 0);glfwTerminate();// 清理 RBOglDeleteRenderbuffers(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() {// 初始化 GLFWif (!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);// 初始化 GLEWif (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() {// 初始化 GLFWif (!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);// 初始化 GLEWif (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() {// 初始化 GLFWif (!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);// 初始化 GLEWif (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;
}