前几天在学习unity的时候做的一个飞行器的尾焰的粒子效果还不错,如下图
于是乎想着能不能自己实现这种效果,查阅相关资料后根据NeHe的教程自己弄了个类似烟花的爆炸小程序,效果还看得过去,但是在最后想加入背景图的时候出现了一些问题,下面我将展示我的程序效果及主要问题。
一、在没有添加背景图的时候,背景被初始化为黑色,此处截图只能截取瞬时的画面,因此看上去很粗糙(看不出爆炸效果)。
程序控制:鼠标左键点击处会在点击处产生爆炸效果,点击右键会展示金属质感的字体及粒子;
上下键控制文字的上下翻转(3D纹理字)以及粒子的运动趋势;
Enter键进入彩虹模式即粒子颜色随机/单色模式,进入单色模式后按空格键切换粒子颜色。
整体效果还算正常,但在我加入背景图时由于是二维的显示需要设置其深度,而每次调用paintGL()函数时需要清除深度缓存和重置当前的模型观察矩阵,因为不这样的话粒子的纹理效果简直一团糟,结果就是背景图片不能正确绘制。
二、在网上试了一些方法后感觉这篇文章描述的方法还挺有意思的http://blog.youkuaiyun.com/gamesdev/article/details/8496140,于是重新调整了一下代码结构,不过运行结果如下所示
这个效果我就不评论了,而且3D纹理字也不能显示了。找了下原因,
为了让这OpenGL和QPainter都将图形绘制在一个渲染上下文中,需要手动关闭一些开关。下面两句代码意思就是关闭自动填充背景图片和自动交换缓存(缓冲区)。
setAutoBufferSwap( false ); setAutoFillBackground( false );
在用OpenGL绘制三维图形以及设置OpenGL的时候,如果不是在initializeGL()、resizeGL()、paintGL()函数内,那么需要使用makeCurrent()将渲染上下文转为OpenGL绘制。此外在初始化OpenGL或者使用OpenGL函数进行渲染的时候,一定要记住设置顺时针为正面。即
glFrontFace( GL_CW );
setAutoBufferSwap(false);这个函数帮助文档里粗略解释为使用双缓冲格式,在调用paintgl()函数后背景和前景的缓冲区会自动交换,不知道其到底是如何交换的导致程序有问题,在这里只能先将问题记录下来,待进一步学习后再回头改进。
工程下载地址:http://download.youkuaiyun.com/download/did_you/10244544
使用的qt版本为
Qt 5.2.0 (MSVC 2010, 32 bit) 欢迎各位大佬指出错误和不足之处~
好笑的是,在我刚把这篇文章发布还没通过审核的时候像是突然来了灵感一样,将这个问题完美解决了,而且还发现opengl的深度缓存还能识别二维图片中的颜色并加以改变,真的是太牛了!下面附上我的灵感之作,哈哈
更新后的工程以及演示视频下载地址:
http://download.youkuaiyun.com/download/did_you/10244603