opengles之VBO和FBO的结合使用
来源:互联网 发布:mysql不能输入中文 编辑:程序博客网 时间:2024/05/14 19:21
FBO的理论详见:http://blog.csdn.net/xiajun07061225/article/details/7283929/
FBO的创建:
class FrameBufferId{public:FrameBufferId(){_width = 0;_height = 0;_FBOID = 0;_DEPTHID = 0;}public:unsigned _width;unsigned _height;unsigned _FBOID;unsigned _DEPTHID;public:/*** 创建一个缓冲区对象*/void create(int width, int height){_width = width;_height = height;//创建一个帧缓冲对象 第一个参数表示要创建的帧缓存的数目//第二个参数是保存创建的FBO的IDglGenFramebuffers(1, &_FBOID);//绑定glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);//创建一个深度缓存glGenRenderbuffers(1, &_DEPTHID);//绑定glBindRenderbuffer(GL_RENDERBUFFER, _DEPTHID);//分配指定的内存空间:分配一个_width*_height的深度缓冲区 第二个参数为GL_DEPTH_COMPONENT16,是//指定我们的空间用来保存深度值,除此之外还可以保存GL_RGB/GL_RFBA或者模板缓存的信息,具体见定义//第一个参数必须是GL_RENDERBUFFER 第二个参数是可以渲染的颜色格式,可渲染的深度格式,或者可渲染的模板格式//第三个和第四个是以像素为单位指定数据所要占用内存的大小glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _width, _height);//把深度缓存与FBO对象绑定在一起glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _DEPTHID);//解除绑定glBindFramebuffer(GL_FRAMEBUFFER, 0);}/*** 使用对象*/void begin(unsigned texId){glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);//把2D纹理图像关联到FBO 第一个参数必须是GL_FRAMEBUFFER 第二个参数是关联纹理图像的关联点//第三个参数一般都是GL_TEXTURE_2D,第四个参数是纹理对象的ID号,最后一个参数是要被关联的纹理的mipmap等级glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);}/*** 使用完,回复状态*/void end(){glBindFramebuffer(GL_FRAMEBUFFER, 0);}};
FBO的完整使用案例
#pragma once#include "CELLWinApp.hpp"//顶点结构体struct Vertex{float x, y, z;//顶点位置信息float u, v;//顶点纹理纹理坐标float r, g, b, a;//顶点颜色信息};//6个面共12个三角形Vertex g_cubeVertices[] ={// 第一个三角形{ -1.0f, -1.0f, 1.0f, 0, 1, 1.0f, 1.0f, 1.0f, 1.0f },{ 1.0f, -1.0f, 1.0f, 1, 1, 1.0f, 1.0f, 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 1.0f, 1.0f, 1.0f, 1.0f },{ -1.0f, -1.0f, 1.0f, 0, 1, 1.0f, 1.0f, 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 1.0f, 1.0f, 1.0f, 1.0f },{ -1.0f, 1.0f, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f, 1.0f },//{ -1.0f, -1.0f, -1.0f, 0, 1, 1.0f, 0.0f, 0.0f, 1.0f },{ -1.0f, 1.0f, -1.0f, 1, 1, 1.0f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, -1.0f, 1, 0, 1.0f, 0.0f, 0.0f, 1.0f },{ -1.0f, -1.0f, -1.0f, 0, 1, 1.0f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, -1.0f, 1, 0, 1.0f, 0.0f, 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f, 0, 0, 1.0f, 0.0f, 0.0f, 1.0f },//{ -1.0f, 1.0f, -1.0f, 0, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ -1.0f, 1.0f, 1.0f, 1, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 1.0f, 0.0f, 1.0f },{ -1.0f, 1.0f, -1.0f, 0, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, -1.0f, 0, 0, 0.0f, 1.0f, 0.0f, 1.0f },//{ -1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f, 1, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, -1.0f, 1.0f, 1, 0, 0.0f, 1.0f, 0.0f, 1.0f },{ -1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, -1.0f, 1.0f, 1, 0, 0.0f, 1.0f, 0.0f, 1.0f },{ -1.0f, -1.0f, 1.0f, 0, 0, 0.0f, 1.0f, 0.0f, 1.0f },// Quad 4{ 1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ 1.0f, 1.0f, -1.0f, 1, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 0.0f, 1.0f, 1.0f },{ 1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 0.0f, 1.0f, 1.0f },{ 1.0f, -1.0f, 1.0f, 0, 0, 0.0f, 0.0f, 1.0f, 1.0f },//{ -1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ -1.0f, -1.0f, 1.0f, 1, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ -1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 0.0f, 1.0f, 1.0f },{ -1.0f, -1.0f, -1.0f, 0, 1, 0.0f, 0.0f, 1.0f, 1.0f },{ -1.0f, 1.0f, 1.0f, 1, 0, 0.0f, 0.0f, 1.0f, 1.0f },{ -1.0f, 1.0f, -1.0f, 0, 0, 0.0f, 0.0f, 1.0f, 1.0f }};class FrameBufferId{public:FrameBufferId(){_width = 0;_height = 0;_FBOID = 0;_DEPTHID = 0;}public:unsigned _width;unsigned _height;unsigned _FBOID;unsigned _DEPTHID;public:/*** 创建一个缓冲区对象*/void create(int width, int height){_width = width;_height = height;//创建一个帧缓冲对象 第一个参数表示要创建的帧缓存的数目//第二个参数是保存创建的FBO的IDglGenFramebuffers(1, &_FBOID);//绑定glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);//创建一个深度缓存glGenRenderbuffers(1, &_DEPTHID);//绑定glBindRenderbuffer(GL_RENDERBUFFER, _DEPTHID);//分配指定的内存空间:分配一个_width*_height的深度缓冲区 第二个参数为GL_DEPTH_COMPONENT16,是//指定我们的空间用来保存深度值,除此之外还可以保存GL_RGB/GL_RFBA或者模板缓存的信息,具体见定义//第一个参数必须是GL_RENDERBUFFER 第二个参数是可以渲染的颜色格式,可渲染的深度格式,或者可渲染的模板格式//第三个和第四个是以像素为单位指定数据所要占用内存的大小glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _width, _height);//把深度缓存与FBO对象绑定在一起glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _DEPTHID);//解除绑定glBindFramebuffer(GL_FRAMEBUFFER, 0);}/*** 使用对象*/void begin(unsigned texId){glBindFramebuffer(GL_FRAMEBUFFER, _FBOID);//把2D纹理图像关联到FBO 第一个参数必须是GL_FRAMEBUFFER 第二个参数是关联纹理图像的关联点//第三个参数一般都是GL_TEXTURE_2D,第四个参数是纹理对象的ID号,最后一个参数是要被关联的纹理的mipmap等级glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);}/*** 使用完,回复状态*/void end(){glBindFramebuffer(GL_FRAMEBUFFER, 0);}};class OffscreenApp :public CELLWinApp{public:PROGRAM_P2_T2_C3 _shader;unsigned _textureId;//! 顶点缓冲区unsigned _vertexId;//! 创建一个FBO FameBufferObject对象FrameBufferId _fbo;//! 纹理对象unsigned _dynamicTexture;public:OffscreenApp(){_textureId = -1;}public:/*** 创建一个文理函数*/unsigned createTexture(int width, int height, unsigned inteFmt, unsigned dataFmt, void* data){unsigned texId = 0;/*** 产生一个纹理Id,可以认为是纹理句柄,后面的操作将书用这个纹理id*/glGenTextures(1, &texId);/*** 使用这个纹理id,或者叫绑定(关联)*/glBindTexture(GL_TEXTURE_2D, texId);/*** 指定纹理的放大,缩小滤波,使用线性方式,即当图片放大的时候插值方式*/glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);/*** 将图片的rgb数据上传给opengl.*/glTexImage2D(GL_TEXTURE_2D, //! 指定是二维图片0, //! 指定为第一级别,纹理可以做mipmap,即lod,离近的就采用级别大的,远则使用较小的纹理inteFmt, //! 纹理的使用的存储格式width, //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。height, //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。0, //! 是否的边dataFmt, //! 数据的格式GL_UNSIGNED_BYTE, //! 数据是8bit数据data);return texId;}//! 重写初始化函数virtual void onInit(){_shader.initialize();loadTexture();glEnable(GL_DEPTH_TEST);//! 创建顶点缓冲区glGenBuffers(1, &_vertexId);glBindBuffer(GL_ARRAY_BUFFER, _vertexId);//绑定//将顶点数据上传至显卡内存glBufferData(GL_ARRAY_BUFFER, sizeof(g_cubeVertices), g_cubeVertices, GL_STATIC_DRAW);//解除绑定glBindBuffer(GL_ARRAY_BUFFER, 0);//! 初始化FBO_fbo.create(_winWidth, _winHeight);_dynamicTexture = createTexture(_fbo._width, _fbo._height, GL_RGBA, GL_RGBA, 0);}virtual void loadTexture(){//1 获取图片格式FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType("Debug/data/image/smoke.tga", 0);//2 加载图片FIBITMAP *dib = FreeImage_Load(fifmt, "Debug/data/image/smoke.tga", 0);//3 转化为rgb 24色dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针BYTE *pixels = (BYTE*)FreeImage_GetBits(dib);int width = FreeImage_GetWidth(dib);int height = FreeImage_GetHeight(dib);_textureId = createTexture(width, height, GL_RGB, GL_RGB, pixels);/*** 释放内存*/FreeImage_Unload(dib);}void drawCube(int viewW, int viewH){static float x = 0;glBindBuffer(GL_ARRAY_BUFFER, _vertexId);_shader.begin();{glUniform1i(_shader._texture, 0);CELL::matrix4 matProj = CELL::perspective(45.0f, float(viewW) / float(viewH), 0.1f, 100.0f);CELL::matrix4 model(1);model.translate(0.0f, 0.0f, -10.0f);CELL::matrix4 matRot(1);matRot.rotateYXZ(x, x, x);x += 1.0f;CELL::matrix4 mvp = matProj * model * (matRot);glUniformMatrix4fv(_shader._MVP, 1, false, mvp.data());glVertexAttribPointer(_shader._positionAttr, 3, GL_FLOAT, false, sizeof(Vertex), 0);glVertexAttribPointer(_shader._uvAttr, 2, GL_FLOAT, false, sizeof(Vertex), (void*)12);glVertexAttribPointer(_shader._colorAttr, 4, GL_FLOAT, false, sizeof(Vertex), (void*)20);glDrawArrays(GL_TRIANGLES, 0, sizeof(g_cubeVertices) / sizeof(g_cubeVertices[0]));}_shader.end();glBindBuffer(GL_ARRAY_BUFFER, 0);}virtual void render(){_fbo.begin(_dynamicTexture);{glClearColor(1, 1, 1, 1);glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);glViewport(0, 0, _fbo._width, _fbo._height);glBindTexture(GL_TEXTURE_2D, _textureId);drawCube(_fbo._width, _fbo._height);}_fbo.end();glClearColor(0, 0, 0, 1);glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);glViewport(0, 0, _winWidth, _winHeight);//glBindTexture(GL_TEXTURE_2D,_textureId);glBindTexture(GL_TEXTURE_2D, _dynamicTexture);//! 绘制到窗口上drawCube(_winWidth, _winHeight);eglSwapBuffers(_display, _surface);}};
// 完整案例下载地址:http://download.csdn.net/detail/hb707934728/9844615
阅读全文
0 0
- opengles之VBO和FBO的结合使用
- vbo和fbo的结合使用
- opengles中VBO和IBO结合使用
- OPENGL VBO,FBO和PBO
- 顶点缓冲区VBO和索引缓冲区IBO的结合使用
- opengles 使用VBO:顶点缓存
- opengl入门系列- openglES 2.0 的 VBO 用法和例子
- OpenGL之VBO,PBO,FBO技术
- OpenGL之VBO,PBO,FBO技术
- iOS --- OpenGLES之顶点缓存对象VBO
- opengles中使用vbo(顶点缓冲区)
- OpenGLES demo - 10. DrawElements和VBO
- VBO,PBO,FBO
- VBO, PBO与FBO
- VAO, VBO, PBO, FBO
- VBO, PBO与FBO
- OpenGLES实战应用FBO
- OpenGLES实战应用VBO
- 清除浮动的方法
- STL系列之五 priority_queue 优先级队列
- Timer 的Timer schedule()方法
- 15 个 Android 通用流行框架大全
- Android好用的下拉图片放大效果
- opengles之VBO和FBO的结合使用
- STL系列之六 set与hash_set
- CSS选择器总结
- 图像分割的知识
- (function(x){ delete x; return x;//1})(1);
- 在JSP页面将时间戳转换成格式化日期的集中方法
- Bitmap的高效加载(Android开发艺术探索学习笔记)
- Linux 下用命令行自动安装 VirtualBox Extension Pack
- 悼文