OpenGL--帧缓冲区
2016-05-03 18:30
846 查看
理论基础
1,帧缓冲区(显存):是由像素组成的二维数组,每一个存储单元对应屏幕上的一个像素,整个帧缓冲对应一帧图像即当前屏幕画面。帧缓冲通常包括:颜色缓冲,深度缓冲,模板缓冲和累积缓冲。这些缓冲区可能是在一块内存区域,也可能单独分开,看硬件。而像素数据在进入帧缓冲之前(称为片段)必须通过一系列测试才能写入帧缓冲,如果片段在其中某个测试没有通过,后面的测试或操作都将不再进行。这些测试或操作流程是:开始(片段)-裁剪测试-alpha测试-模板测试-深度测试-混合-抖动-逻辑操作-结束(写入帧缓冲).
2,创建帧缓冲区对象:前面章节讲过OpenGL一般的缓冲区对象,主要是优化性能。而帧缓冲区对象除了优化性能还增加了一些功能,类似GDI中的辅助DC,和系统的帧缓冲区一样也是保存当前屏幕图像,只是它是后台保存看不见。具体它可以关联纹理对象(即颜色缓冲区)和渲染缓冲对象(Renderbuffer有深度缓冲和模板缓冲)来组成自己后台的帧缓冲区。例如,渲染动态纹理,多屏实现等。
注释:帧缓冲可能是GPU专属内存,也可能是GPU和CPU共享内存,看硬件。手机一般是共享内存,PC独立显卡一般是专属内存,集成显卡是共享内存。
1,创建帧缓冲区对象
2,使用帧或纹理渲染
1,帧缓冲区(显存):是由像素组成的二维数组,每一个存储单元对应屏幕上的一个像素,整个帧缓冲对应一帧图像即当前屏幕画面。帧缓冲通常包括:颜色缓冲,深度缓冲,模板缓冲和累积缓冲。这些缓冲区可能是在一块内存区域,也可能单独分开,看硬件。而像素数据在进入帧缓冲之前(称为片段)必须通过一系列测试才能写入帧缓冲,如果片段在其中某个测试没有通过,后面的测试或操作都将不再进行。这些测试或操作流程是:开始(片段)-裁剪测试-alpha测试-模板测试-深度测试-混合-抖动-逻辑操作-结束(写入帧缓冲).
2,创建帧缓冲区对象:前面章节讲过OpenGL一般的缓冲区对象,主要是优化性能。而帧缓冲区对象除了优化性能还增加了一些功能,类似GDI中的辅助DC,和系统的帧缓冲区一样也是保存当前屏幕图像,只是它是后台保存看不见。具体它可以关联纹理对象(即颜色缓冲区)和渲染缓冲对象(Renderbuffer有深度缓冲和模板缓冲)来组成自己后台的帧缓冲区。例如,渲染动态纹理,多屏实现等。
注释:帧缓冲可能是GPU专属内存,也可能是GPU和CPU共享内存,看硬件。手机一般是共享内存,PC独立显卡一般是专属内存,集成显卡是共享内存。
1,创建帧缓冲区对象
void init() { // 创建纹理对象内存空间 glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);//开启多级纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0);//解除绑定(好的习惯:用完就关闭,哪里用哪里开) // 创建帧缓冲对象 glGenFramebuffers(1, &fboId);//没有空间的,需要关联纹理对象或渲染缓冲对象才有意义 glBindFramebuffer(GL_FRAMEBUFFER, fboId); //用渲染缓冲对象创建了一个深度缓冲区 glGenRenderbuffers(1, &rboId); glBindRenderbuffer(GL_RENDERBUFFER, rboId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0);//临时解绑 // 关联到纹理 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); // 关联到深度缓冲区 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); glBindFramebuffer(GL_FRAMEBUFFER, 0);//临时解绑 }
2,使用帧或纹理渲染
//动态纹理贴图:使用帧缓冲对象效率要明显提高 void displayCB() { //使用帧缓冲对象(直接渲染到绑定的纹理对象) if(fboUsed) { // 激活当前帧缓冲对象 glBindFramebuffer(GL_FRAMEBUFFER, fboId); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(angle*0.5f, 1, 0, 0); glRotatef(angle, 0, 1, 0); glRotatef(angle*0.7f, 0, 0, 1); glTranslatef(0, -1.575f, 0); drawTeapot();//绘制动态茶壶 glPopMatrix(); glBindFramebuffer(GL_FRAMEBUFFER, 0); // 用完解绑 } // 没有使用帧缓冲对象(先渲染到后天缓冲再copy到纹理) else { glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glPushMatrix(); glRotatef(angle*0.5f, 1, 0, 0); glRotatef(angle, 0, 1, 0); glRotatef(angle*0.7f, 0, 0, 1); glTranslatef(0, -1.575f, 0); drawTeapot(); glPopMatrix(); // copy缓冲区的像素到纹理 glBindTexture(GL_TEXTURE_2D, textureId); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT); glBindTexture(GL_TEXTURE_2D, 0); glPopAttrib(); } glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // 绘制立方体(纹理贴图) draw(); glutSwapBuffers(); }
相关文章推荐
- opacity在IE6~8下无效果,解决的办法
- 打包war包部署到Tomcat。调用接口时,pad端提示:连接服务器异常。但后台无任何异常抛出
- linux 同步IO: sync、fsync与fdatasync
- libevent源码安装及Linux自动编译功能总结
- Linux查看CPU和内存使用情况
- Apache Commons Codec 编码解码
- openGL函数列表
- linux crontab定时任务详解
- linux crontab定时任务详解
- linux基础之常用命令(2)
- 数据推荐系统系列 8种方法之零 简单方式 SlopeOne 方式 (补充简单的方式)
- linux删除文件未释放空间问题处理
- Centos安装php高版本
- Linux下php安装mcrypt扩展
- 高并发下的 Nginx 优化
- Nginx+Tomcat7+Mencached负载均衡集群部署笔记
- 为PPT架构师正名
- linux不知道账户密码,强制找回 和 WordPress 没有阅读量和 定时器发布失败的处理
- Tomcat Server.xml详解
- linux命令详解2-文件管理,查看文件命令