Opengl 利用FBO实现物体移动轨迹变淡的效果
2015-09-03 10:07
701 查看
本文代码在Windows下编写,用到了GLUT和GLEW库。
实现了一个点沿圆周运动,移动轨迹逐渐变淡消失的效果。
基本思路是在每帧刷新时,利用FBO先将图形渲染到一张贴图(纹理),然后再将纹理渲染到屏幕上。其中将图形渲染到贴图时,利用混合绘制透明的黑色背景,再绘制移动的圆点,这样每帧更新时会有新的黑背景叠加,之前位置的圆点会被逐渐覆盖并慢慢消失。
然后上代码
我将圆点在一个圆心在(0,0),半径为1的圆周上运动,计算圆点位置的代码如下(将圆周平分为CIRCLE_POINT_NUM个点)
该段代码首先创建一个空纹理,然后创建一个帧缓存对象(fbo),再把纹理挂接到该fbo上,glCheckFramebufferStatus会检查fbo状态。
然后是绘制的代码
该段代码将在fbo挂接的纹理上绘制,将glClear(GL_COLOR_BUFFER_BIT)注释掉是很有必要的,否则将看不到圆点移动的尾迹。
这段代码执行完毕后,就可以像操作普通的纹理对象一样 绘制之前创建的纹理。
效果如图
附上代码链接
实现了一个点沿圆周运动,移动轨迹逐渐变淡消失的效果。
基本思路是在每帧刷新时,利用FBO先将图形渲染到一张贴图(纹理),然后再将纹理渲染到屏幕上。其中将图形渲染到贴图时,利用混合绘制透明的黑色背景,再绘制移动的圆点,这样每帧更新时会有新的黑背景叠加,之前位置的圆点会被逐渐覆盖并慢慢消失。
然后上代码
我将圆点在一个圆心在(0,0),半径为1的圆周上运动,计算圆点位置的代码如下(将圆周平分为CIRCLE_POINT_NUM个点)
void CalculatePoints() { circlepoints.clear(); float angle = 360.0f/CIRCLE_POINTS_NUM; for (int i=0; i<CIRCLE_POINTS_NUM; i++) { XY xy; xy.x = cos(angle*i*Pi/180); xy.y = sin(angle*i*Pi/180); circlepoints.push_back(xy); } }创建FBO的代码
bool CreateFBO() { glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WindowWidth, WindowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_FRAMEBUFFER, fboID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_COMPLETE: break;; default: cout << "create fbo failed!" << endl; return false; } glBindFramebuffer(GL_FRAMEBUFFER, 0); return true; }
该段代码首先创建一个空纹理,然后创建一个帧缓存对象(fbo),再把纹理挂接到该fbo上,glCheckFramebufferStatus会检查fbo状态。
然后是绘制的代码
//render to texture glBindFramebuffer(GL_FRAMEBUFFER, fboID); //glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(0, 0, 0, 0.1); glBegin(GL_QUADS); { glVertex2f(-2.0f, -2.0f); glVertex2f(2.0f, -2.0f); glVertex2f(2.0f, 2.0f); glVertex2f(-2.0f, 2.0f); } glEnd(); glDisable(GL_BLEND); glPointSize(5.0); glColor4f(1, 0, 0, 0); glBegin(GL_POINTS); { glVertex2f(circlepoints[index].x, circlepoints[index].y); index = index++%(CIRCLE_POINTS_NUM-1); } glEnd(); glBindFramebuffer(GL_FRAMEBUFFER, 0);
该段代码将在fbo挂接的纹理上绘制,将glClear(GL_COLOR_BUFFER_BIT)注释掉是很有必要的,否则将看不到圆点移动的尾迹。
这段代码执行完毕后,就可以像操作普通的纹理对象一样 绘制之前创建的纹理。
//render to window glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textureID); glBegin(GL_QUADS); { glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); } glEnd(); glBindTexture(GL_TEXTURE_2D, 0); glFlush();该段代码将纹理渲染到屏幕上。
效果如图
附上代码链接
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 解决Vista系统OpenGL驱动问题的方法整理
- Delphi下OpenGL2d绘图之画四边形的方法
- Delphi下OpenGL2d绘图之画点的方法
- Delphi下OpenGL2d绘图之初始化流程详解
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例