第六章 OpenGL ES 基础-FBO、VBO理解与运用
第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标
第二章 OpenGL ES 基础-GLSL语法简单总结
第三章 OpenGL ES 基础-GLSL渲染纹理
第四章 OpenGL ES 基础-位移、缩放、旋转原理
第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵
第六章 OpenGL ES 基础-FBO、VBO理解与运用
第七章 OpenGL ES 基础-输入输出框架思维
第八章 OpenGL ES 基础-MVP矩阵理解
第九章 OpenGL ES 基础-高斯模糊原理
第十章 OpenGL ES 基础-图像USM锐化
第十一章 OpenGL ES 基础-基础光照
第十二章 OpenGL ES 基础-色温、色调、亮度、对比度、饱和度、高光
第十三章 OpenGL ES-RGB、HSV、HSL模型介绍
第十四章 OpenGL ES-方框模糊(均值模糊)
第十五章 OpenGL ES-VR 全景模式原理
第十六章 OpenGL ES-桶形畸变算法-常用VR
FBO的介绍
在 OpenGL 中,FBO 是 Framebuffer Object 的缩写,用于渲染到纹理或者多重渲染目标的技术。FBO 允许将渲染结果输出到一个纹理或者多个纹理上,而不是直接输出到屏幕上。这种机制允许实现更复杂的图形效果,例如后期处理、阴影映射、抗锯齿等。
使用 FBO 的基本步骤:
-
创建 FBO:
- 使用
glGenFramebuffers()
创建一个 FBO 对象。 - 使用
glBindFramebuffer(GL_FRAMEBUFFER, framebufferID)
绑定 FBO 对象,告诉 OpenGL 后续操作会针对这个 FBO。
- 使用
-
附加纹理:
- 使用
glGenTextures()
创建一个纹理对象并配置它。 - 使用
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, textureID, 0)
将纹理附加到 FBO 上。
- 使用
-
检查 FBO 完整性:
- 使用
glCheckFramebufferStatus(GL_FRAMEBUFFER)
检查 FBO 是否完整。
- 使用
-
渲染到 FBO:
- 在渲染过程中,将 FBO 绑定为当前渲染目标。
- 进行渲染操作,结果将输出到附加的纹理。
-
解绑 FBO:
- 在完成渲染后,使用
glBindFramebuffer(GL_FRAMEBUFFER, 0)
解绑 FBO。
- 在完成渲染后,使用
-
清理资源:
- 当 FBO 不再需要时,记得删除 FBO 对象和相关的纹理。
示例代码片段:
// 创建 FBO
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// 创建纹理并附加到 FBO
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// 检查 FBO 完整性
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
// 处理错误
}
// 渲染到 FBO
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// 进行渲染操作
// 解绑 FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// 删除 FBO 和纹理
glDeleteFramebuffers(1, &framebuffer);
glDeleteTextures(1, &texture);
通过使用 FBO,可以有效地实现高级的渲染技术和后期处理效果,并提高渲染质量和灵活性。
VBO的介绍
在 OpenGL 中,VBO 是 Vertex Buffer Object 的缩写,用于存储顶点数据(如位置、颜色、法线等)在显存中的缓冲区对象。使用 VBO 可以提高性能并减少 CPU 到 GPU 之间的数据传输。
使用 VBO 的基本步骤:
-
创建 VBO:
- 使用
glGenBuffers()
创建一个 VBO 对象。 - 使用
glBindBuffer(GL_ARRAY_BUFFER, vboID)
绑定 VBO 对象为顶点数组缓冲区。
- 使用
-
填充数据到 VBO:
- 使用
glBufferData(GL_ARRAY_BUFFER, size, data, usage)
将顶点数据传输到 VBO 中。size
:数据大小data
:指向要上传的数据的指针usage
:指定数据如何被使用(GL_STATIC_DRAW、GL_DYNAMIC_DRAW 等)
- 使用
-
绘制顶点数据:
- 在渲染过程中,使用 VBO 存储的顶点数据进行绘制。
- 使用
glDrawArrays()
或glDrawElements()
等函数指定绘制方式和顶点范围。
-
解绑 VBO:
- 在结束使用 VBO 后,使用
glBindBuffer(GL_ARRAY_BUFFER, 0)
解绑 VBO。
- 在结束使用 VBO 后,使用
-
清理资源:
- 当 VBO 不再需要时,记得删除 VBO 对象。
示例代码片段:
// 创建 VBO
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// 填充数据到 VBO
GLfloat vertices[] = { /* 顶点数据 */ };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 在渲染循环中绘制数据
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// 设置顶点属性指针
glVertexAttribPointer(attributeIndex, size, type, normalized, stride, offset);
// 启用顶点属性数组
glEnableVertexAttribArray(attributeIndex);
// 绘制顶点数据
glDrawArrays(GL_TRIANGLES, 0, numVertices);
// 解绑 VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
// 删除 VBO
glDeleteBuffers(1, &vbo);
通过使用 VBO,可以有效地管理顶点数据,并在显存中存储大量的渲染数据,从而加速渲染过程。这种技术可以提高性能,减少数据传输带来的开销,并支持更复杂的图形效果。
以下是一个示例代码片段,展示如何使用 VBO 来渲染包含位置和纹理坐标的顶点数据:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
float VERTEX_TEXTURE[16] = {
-1.0f, -1.0f, /* 左下角坐标 */ 0.0f, 0.0f,//左下角
1.0f, -1.0f, /* 右下角坐标 */ 1.0f, 0.0f,//右下角
-1.0f, 1.0f, /* 左上角坐标 */ 0.0f, 1.0f,//左上角
1.0f, 1.0f, /* 右上角坐标 */ 1.0f, 1.0f,//右上角
};
GLuint vbo;
void initVBO() {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, VERTEX_TEXTURE, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void render() {
//计算步长
GLsizei stride = sizeof(float) * 4;
// 渲染循环中绘制数据
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// 设置顶点属性指针
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, stride, (void*)0); // 每个顶点包括两个浮点数,跳过四个浮点数得到下一个坐标
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, (void*)(2 * sizeof(float))); // 纹理坐标在每个顶点的第三个和第四个浮点数
// 绘制四边形
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// 禁用顶点属性数组
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
在这段代码中,我们首先定义了包含位置坐标和纹理坐标的顶点数据数组VERTEX_TEXTURE
。然后,在initVBO()
函数中初始化了 VBO,并将顶点数据传输到 VBO 中。在渲染循环中,通过设置顶点属性指针和绘制四边形来渲染 VBO 中的数据。