将Cocos2dx渲染到Qt的QOpenGLWidget,在mac上黑屏

简介: 将Cocos2dx渲染到Qt的QOpenGLWidget,在mac上黑屏

今天尝试着使用QOpenGLWidget从零绘制一个三角形,发现始终黑屏。

经过反复摸索,最终可以了,这里是DEMO

总结需要注意的几点:

  • 必须在paintGL回调里面draw,不然qt也就没有必要提供这个回调。
  • 继承QOpenGLExtraFunctions/QOpenGLFunctions,并在initializeGL中进行OpenGL函数寻址
void QOpenGLWidget::initializeGL(){
    this->initializeOpenGLFunctions();
    // ...
}
复制代码
class OpenGL ES 最直观的区别
QOpenGLExtraFunctions 3.0/3.1/3.2 可以使用glBindVertexArray
QOpenGLFunctions 2.0 无法使用glBindVertexArray
  • shader报错: version '330' is not supported
    这里的报错问题其实是和OpenGL的版本有关系,每个OpenGL版本之间是存在差异的。正因为存在不同的OpenGL版本,所以shader里面才有了

#version 330 core

  • 解决办法:
#include <qsurfaceformat.h>
QSurfaceFormat fmt;
fmt.setVersion(3, 3);
fmt.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(fmt);
复制代码
  • 当然配套的shader也得同步修改

shader编译失败导致的黑屏

首先你需要确认是debug模式,否则你看不到任何的cocos engine log,也就看不到shader编译的报错,当然也就不会怀疑是shader导致的问题。

glCompileShader如果出现问题,只有在debug模式下能看到报错,其实我感觉这种问题是无论如何都要log的,不然会增加排查难度,坑了我好几天的时间!

例如这个shader

uniform mat4 CC_PMatrix;
uniform mat4 CC_MultiViewPMatrix[4];
uniform mat4 CC_MVMatrix;
uniform mat4 CC_MVPMatrix;
uniform mat4 CC_MultiViewMVPMatrix[4];
uniform mat3 CC_NormalMatrix;
uniform vec4 CC_Time;
uniform vec4 CC_SinTime;
uniform vec4 CC_CosTime;
uniform vec4 CC_Random01;
uniform sampler2D CC_Texture0;
uniform sampler2D CC_Texture1;
uniform sampler2D CC_Texture2;
uniform sampler2D CC_Texture3;
//CC INCLUDES END
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
    gl_Position = CC_MVPMatrix * a_position;
    v_fragmentColor = a_color;
    v_texCoord = a_texCoord;
}
复制代码

报错信息如下:

cocos2d: ERROR: 0:1: '' :  #version required and missing.
ERROR: 0:18: 'attribute' : syntax error: syntax error
复制代码

那很明显就是OpenGL的版本导致的问题,修改shader是不可能的,我们只能调整OpenGL版本,那么这种shader写法应该是哪个版本的呢?

查询当前使用的OpenGL相关信息:

QSurfaceFormat fmt = QSurfaceFormat::defaultFormat();
auto version = fmt.version();
qDebug() << "use surface version: " << version.first << "." << version.second; // 返回的是2.0
const GLubyte* versionString = glGetString(GL_VERSION);
qDebug() << "use opengl version: " << QString(QLatin1String((char*)versionString)); // 返回的是4.1
复制代码

QSurfaceFormat::setVersion()默认值就是2.0

glGetString(GL_VERSION)可能获取的和surface不太一致,至于为啥,我就没有再深究了。

#version必须写是opengl3.3之后规定的,所以这里我直接设置QOpenGLWidget使用的版本,注意必须放在QOpenGLWidget的构造函数之前,我是放在了main入口

QSurfaceFormat fmt;
fmt.setVersion(2, 1);
fmt.setProfile(QSurfaceFormat::NoProfile);
QSurfaceFormat::setDefaultFormat(fmt);
复制代码

3个模式,后续有时间再慢慢了解:

  • NoProfile
  • CompatibilityProfile
  • CoreProfile

至此,shader就能正常通过编译了

framebuffer导致的黑屏

FrameBuffer Status Error 33305,

OpenGL error 0x0506 in cocos2d-x/cocos/renderer/CCRenderer.cpp saveRenderState 155

第二个错误是因为第一个错误导致的,这里我们需要重点关注第一个错误即可

glCheckFramebufferStatus返回值33305(0X8219)的含义是GL_FRAMEBUFFER_UNDEFINED,也就是没有framebuffer

产生原因

不同于OpenGL,Qt中的QOpenGLWidget类的对象不存在默认的Framebuffer,即当前Framebuffer的id不一定是0。

通过context()->defaultFramebufferObject()可以获取当前Framebuffer的id。

经过实验发现,在initializeGL()中的Framebuffer初始为0,而paintGL()中则默认新创建了一个Framebuffer

因此,需要在paintGL()中通过context()->defaultFramebufferObject()获取id,之后才能进行glBindFramebuffer()等操作。

cocos2dx 使用的glfw版本为3.2,glfw会默认创建一个有效的framebuffer,所以默认的cocos xcode工程没有问题。

解决办法

在paintGL中进行初始化engine,这样frameBuffer就正常了,engine也就正常了。

其实在这个项目中就提到了这个问题,刚好曾经看过,有印象,所以我也就这么做了

OpenGL版本对应的GLSL版本

OpenGL版本号 GLSL版本号 发布时间
2.0 110 2004年9月7日
2.1 120 2006年7月2日
3.0 130 2008年8月11日
3.1 140 2009年3月24日
3.2 150 2009年8月3日
3.3 330 2010年3月11日
4.0 400 2010年3月11日
4.1 410 2010年7月26日
4.2 420 2011年8月8日
4.3 430 2012年8月6日
4.4 440 2013年7月23日
4.5 450 2014年7月
4.6 460 2017年7月
OpenGL ES 版本号 GLSL ES版本号
2.0 100
3.0 300
3.1 310
3.2 320

每个GLSL版本之间的差异



目录
相关文章
|
2天前
QT 5.14.2版本 MAC环境安装部署流程
QT 5.14.2版本 MAC环境安装部署流程
|
7月前
Qt-获取计算机信息(MAC、IP、CPU、主机名等等)
Qt-获取计算机信息(MAC、IP、CPU、主机名等等)
252 0
|
9月前
|
网络协议
Qt获取本机IP、MAC、IPV6子网掩码等网络信息
Qt获取本机IP、MAC、IPV6子网掩码等网络信息
138 0
|
编解码 Windows
案例分享:Qt出版社书籍配套U盘资源播放器软件定制(脚本关联播放器与资源文件,播放器,兼容win7,win10和mac)
案例分享:Qt出版社书籍配套U盘资源播放器软件定制(脚本关联播放器与资源文件,播放器,兼容win7,win10和mac)
案例分享:Qt出版社书籍配套U盘资源播放器软件定制(脚本关联播放器与资源文件,播放器,兼容win7,win10和mac)
关于 Qt使用QOpenGLWidget运行时崩溃 的解决方法
关于 Qt使用QOpenGLWidget运行时崩溃 的解决方法
关于 Qt使用QOpenGLWidget运行时崩溃 的解决方法
|
安全 API 调度
Qt开发笔记:QGLWidget、QOpenGLWidget详解及区别
Qt开发笔记:QGLWidget、QOpenGLWidget详解及区别
Qt开发笔记:QGLWidget、QOpenGLWidget详解及区别

推荐镜像

更多