Qt OpenGL程序在Windows下正常,但在Linux下无显示问题【已解决】
- 引言
- 一、问题描述
- 二、解决方案
- 三、解决过程记录
- 3.1 定位问题
- 3.2 解决问题,深入分析
引言
在Windows上正常运行的OpenGL程序,到Linux下正常编译…但是没有任何显示(只有背景颜色)
。解决过程略曲折,特此记录问题以及解决方案,顺便留下解决过程方便复盘…
一、问题描述
在Windows上正常运行的OpenGL程序,在Linux下无任何显示… 人都傻了
- 同步在Windows和Linux调试,发现
透视投影矩阵的值不同
- 进一步测试,发现
painter.beginNativePainting();
会改变透视投影矩阵
二、解决方案
在painter.beginNativePainting();
语句之后重新设置透视投影矩阵即可:
-
- 在
void QopenGLDemo::resizeGL(int w, int h)
中增加:
- 在
this->aspect = double(w) / h; //备份 方便在paintGL重新建立透视投影矩阵
-
- 在
void QopenGLDemo::paintGL()
中,painter.beginNativePainting();
语句之后重新建立透视投影矩阵
- 在
QPainter painter(this);
painter.beginNativePainting();
// 在Linux下较为特殊,需在painter.beginNativePainting(); 后重新设置透视投影矩阵
glMatrixMode(GL_PROJECTION); //选择投影矩阵
glLoadIdentity(); //重置投影矩阵 为 单位矩阵
gluPerspective(45.0, this->aspect, 0.1, 1000.0); //建立透视投影
// --------------------------- OpenGL start----------------------------------
-
- 需要注意一点,如果后续代码有
glLoadIdentity
,记得选择模型矩阵,而不是投影矩阵 (如果不选择,默认还是重置投影矩阵)。完整修复bug代码如下所示:
- 需要注意一点,如果后续代码有
void QopenGLDemo::paintGL(){
QPainter painter(this);
painter.beginNativePainting();
// 在Linux下较为特殊,需在painter.beginNativePainting(); 后重新设置透视投影矩阵
glMatrixMode(GL_PROJECTION); //选择投影矩阵
glLoadIdentity(); //重置投影矩阵 为 单位矩阵
gluPerspective(45.0, this->aspect, 0.1, 1000.0); //建立透视投影
// --------------------------- OpenGL start----------------------------------
// 初始化
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
glMatrixMode(GL_MODELVIEW); //选择模型矩阵
glLoadIdentity();
三、解决过程记录
3.1 定位问题
- 同步在Windows和Linux调试,发现
透视投影矩阵的值不同
。左边是Linux下的,值明显有问题
- 不同系统下,同一句代码 产生了不同的矩阵?Linux下
resizeGL(int w, int h)
中使用如下代码获取设定的矩阵值,没问题
GLdouble projmatrix[16];
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
- 继续Debug,怀疑是运行到某个语句,矩阵值被改变了…在
paintGL()
中很多语句后增加投影矩阵值的打印,直接放结果 (在painter.beginNativePainting()
后值被改变):
与 painter.beginNativePainting();冲突?
3.2 解决问题,深入分析
- 在
painter.beginNativePainting();
后重新赋值投影矩阵即可… 详情看之前的解决方案
- 但是
painter.beginNativePainting()
究竟干了什么? 将原点设置到了窗口左上角吗?之前Linux下OpenGL程序窗口左上角好像真的有闪烁
如何使原始坐标(0,0)位于QGLWIdget的左上角?http://cn.voidcc.com/question/p-ncxvwltv-bau.html
- 查看官方文档,也未曾提及… 看到这句
The states we reset may change from release to release.
也可能这个版本真的重置了投影矩阵…
翻译:
刷新绘制管道,并为用户直接向底层图形上下文发出命令做准备。必须后跟endNativePainting()的调用。
请注意,只有基础绘制引擎更改的状态才会重置为各自的默认状态。我们重置的状态可能会随着发布而变化。以下状态当前在OpenGL 2引擎中重置:
- 禁用混合
- 深度、模板和剪刀测试被禁用
- 活动纹理单位重置为0
- 深度遮罩、深度函数和清除深度将重置为默认值
- 模具掩码、模具操作和模具函数将重置为默认值
- 当前颜色重置为纯白色
例如,如果用户在beginNativePaint() / endNativePainting() 块内更改OpenGL多边形模式,则endNativePaiuting() 不会将其重置为默认状态。
- 也有可能是Linux下OpenGL版本问题… 或者是Qt版本问题… 未曾更换版本,也未曾看过源码,不确定