【QT + ANGLE】关于QT在Windows下使用Angle版GL API 时glClear 等函数使用无效的错误解决办法。 10

最近使用QT+OpenGL 编写了一个跨平台的小demo,分别使用vs和qtCreator等IDE,均遇到一些莫名其妙的问题描述一下,希望对可能遇到的你有所帮助。

由于demo使用GLES2.0的API编写的,而Windows对于OpenGL的支持并不是特别友好,并且很多PC机使用的Intel的集成显卡虽然对OpenGL支持得不好,不支持GLSL或者Frame Buffer,但却支持HLSL以及相关功能,而Google有一个Angle Project就做了一件事:使用DX的API 封装出 GLES2.0的调用接口。

而QT的Windows版本默认就使用的带Angle这个版本。其他平台则是原生的OpenGL

 

首先是 Angle 库的问题

经过真机测试,OpenGL ES2.0 本身是支持在shader中使用循环,使用uniform变量作为循环算子的。而Angle库下的GLSL代码则必须使用固定次数的循环,不知道是不是因为HLSL不支持这种做法。

控制循环终止条件变量必须是const或者常数,如:

const int n = 100;

for(int i = 0; i < n; ++i)   …;

还有一点就是, 上面标注红色的 “i < n” 在使用Angle 库时,绝对不能写作 “i != n”, 否则不只是shader编译失败,整个程序在运行时编译这一段shader代码时会直接崩溃。

由于个人习惯问题,写这种从小到大的循环时喜欢写 != (C++ Primer中讲到迭代器时,建议对于迭代器的循环使用!=,因为并不是所有迭代器都支持 < 操作,如list,这个习惯一直保留下来了),所以遇到这个问题还纠结了一段时间。

如果你遇到shader一直使得整个程序crash,并且你使用了Angle库封装的GLES2.0 API,检查一下你的代码吧。

顺带一提的是,在Windows下,Chrome等浏览器的WebGL 实现均依赖于Angle库。

 

然后是QT+Angle在vs2012上的奇葩问题

使用QT + Angle编写OpenGL代码时,OpenGL的环境在程序一开始就是已经创建好的,你可以在程序最开始写一句

qDebug() << glGetString(GL_VERSION);

如果能够成功输出你的GL Version,那么这个项目才算创建成功。如果是直接使用OpenGL的版本,则不能这么做。

当然,这个时候调用GLES里面的(如 glCreateProgram() 这样的)函数。 需要手动创建一个 QGLContext 并且绑定或者直接创建一个 QGLWidget 之后调用才正确。

然后就是最最最奇葩的问题,我搜了很久也在某些网站上提问了,但是没有人知道,我感觉他们也不可能知道。

那就是: 我的demo可以正确运行(因为我的demo绘图时,每一帧都是绘满全屏的),但是,glClear 函数却毫无效果。

是的, glDrawArrays 函数都可以把图形绘制上去了,但是glClear 却没用。打个比方,我有如下代码:

glDrawArrays(…);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

程序运行起来后,我照样可以看到结果,glClear 写了跟没写一样。别跟我扯glClearColor 啊,framebuffer绑定啊什么的j8玩意,我会不懂这些?

我反反复复地确认,什么都是对的。最后无奈导出了一个QT Creator的版本,使用QT Creator来编译运行。QT Creator实际使用的应该也是vs的compiler和linker,但是构建出来的可执行文件运行出来却是正确的。然后我把QT Creator版本的demo放到mac机上构建出一个app,结果也是正确的。

但是vs那个版本死活不对。而QT Creator作为IDE与vs比起来差距实在太大而且在Windows上调试相当不便。所以这个问题还是必须解决的。

我找到QT自带的 GLES example,导入vs2012, 经测试glClear 有效,然后把工程文件拷贝出来,把demo的代码copy进example的项目中去,重新配置,修改文件名,重新构建,发现demo正常了! MLGB,什么玩意嘛。

拿出diff工具,一行一行地比较,删除不同代码,构建,再比较,删除不同代码再比较……

我终于找到原因所在,问题出在 vcxproj 文件,而且,就tmd一行配置不一样:

tttttttt

我又仔细对比了这一行,这一行是链接库里面的依赖项,里面的lib文件全部一样,只不过写上去的顺序不一样!

我翻开vs,发现在vs里面写的顺序明明是一样的。因为我先前修改的时候就在工程配置里面直接复制挨个改了的,敢情是vs觉得两次“结果一样”,就没有把修改更新到vcxproj文件里面去。

然后我找到我的demo的vcxproj文件,按照这个顺序把lib文件顺序改了,清新构建,运行……glClear 终于有效了。

这种问题真是蛋疼,耗费人力,浪费脑细胞。如果你遇到了,并且看到这篇文章,希望能节省你的时间。

 

  1. NBA直播吧www.seozhanwang.com NBA直播游戏MOD 汉化补丁www.zhanzhangzhiwang.com 游戏修改器青娱乐www.144n.com NBA直播双色球开奖结果www.caipiaodian.com.cn 时时彩环球网www.banshouseo.net 环球时报