在OS X上更改Qt 4.8.6中QGLWidgets的OpenGL上下文版本

Changing the OpenGL Context Version for QGLWidgets in Qt 4.8.6 on OS X

本文关键字:QGLWidgets OpenGL 版本 上下文 OS Qt      更新时间:2023-10-16

我想使用Qt 4.8.6用QGLWidget渲染OpenGL内容。我正在使用的是一台安装了OS X 10.9.4的macbook pro。

QGLWidget是通过传递一个带有3.2核心概要文件请求格式版本的QGLFormat对象来创建的。我遇到的问题是,无论我指定什么GLFormat, QGLContext报告的OpenGL版本仍然是1.0。

在研究了这个主题之后,我找到了Qt OpenGL核心配置文件教程。然而,示例源代码报告了与之前相同的OpenGL 1.0版本。奇怪的是,调用

qDebug() << "Widget OpenGl: " << format().majorVersion() << "." << format().minorVersion();
qDebug() << "Context valid: " << context()->isValid();
qDebug() << "Really used OpenGl: " << context()->format().majorVersion() << "." << context()->format().minorVersion();
qDebug() << "OpenGl information: VENDOR:       " << (const char*)glGetString(GL_VENDOR);
qDebug() << "                    RENDERDER:    " << (const char*)glGetString(GL_RENDERER);
qDebug() << "                    VERSION:      " << (const char*)glGetString(GL_VERSION);
qDebug() << "                    GLSL VERSION: " << (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);

报告版本字符串为2.1

Widget OpenGl:  1 . 0 
Context valid:  true 
Really used OpenGl:  1 . 0 
OpenGl information: VENDOR:        NVIDIA Corporation 
                    RENDERDER:     NVIDIA GeForce GT 750M OpenGL Engine 
                    VERSION:       2.1 NVIDIA-8.26.26 310.40.45f01 
                    GLSL VERSION:  1.20 

使用2011年OS X opengl上下文讨论中建议的Cocoa代码,版本号的输出更改为

Widget OpenGl:  1 . 0 
Context valid:  true 
Really used OpenGl:  1 . 0
OpenGl information: VENDOR:        NVIDIA Corporation 
                    RENDERDER:     NVIDIA GeForce GT 750M OpenGL Engine 
                    VERSION:       4.1 NVIDIA-8.26.26 310.40.45f01 
                    GLSL VERSION:  4.10 

虽然驱动程序现在报告预期的OpenGL版本号,但我仍然只能获得1.0 QGLWidget上下文。传递给QGLWidget构造函数的QGLFormat对象是使用

设置的
QGLFormat fmt;
fmt.setProfile(QGLFormat::CoreProfile);
fmt.setVersion(3, 2);
fmt.setSampleBuffers(true);

我有点不知所措,为什么我仍然只得到1.0版本的上下文。即使没有Cocoa框架生成的OpenGL上下文,也应该可以将上下文版本增加到2.1,但无论传递给构造函数的QGLFormat如何,它仍然固定在1.0。

任何关于为什么QGLWidget上下文保持在1.0版本的指针都非常感谢。

更新1

进一步的实验表明,代码在Ubuntu 13.04 Linux上返回所请求的OpenGL版本。这个问题似乎是OS x特有的。

更新2

我构建了一个最小的非/工作示例

#include <QtOpenGL/QGLFormat>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QApplication>
#include <QtCore/QDebug>
int main(int argc, char **argv) {
    QApplication app(argc, argv);
    QGLFormat fmt = QGLFormat::defaultFormat();
    fmt.setVersion(3,2);
    fmt.setProfile(QGLFormat::CoreProfile);
    fmt.setSampleBuffers(true);
    QGLWidget c(fmt);
    c.show();
    qDebug() << c.context()->requestedFormat();
    qDebug() << c.context()->format();
    return app.exec();
}

可以在Ubuntu中使用

构建
g++ main.cpp -I/usr/include/qt4 -lQtGui -lQtCore -lQtOpenGL -lGL -o test

或OS X

g++ main.cpp -framework OpenGL -framework QtGui -framework QtCore -framework QtOpenGL -o test

输出两行QGLFormat调试输出。第一行是请求的格式,第二行是实际的上下文格式。两者都应该显示专业。次要版本号为3.2。它似乎在Ubuntu Linux下工作,但在使用OS x时失败。

3

更新

有趣的时代。这可能是Qt4.8.6中的一个错误,因为在针对Qt5.3.1编译示例时不会发生此问题。已经提交了一个bug报告。

其他人可以验证这个行为吗?

是。这是平台特有的。请在这里找到解决方法。

覆盖qglcontext::chooseMacVisual指定平台特定的初始化。

CustomGLContext.hpp:

#ifdef Q_WS_MAC
void* select_3_2_mac_visual(GDHandle handle);
#endif // Q_WS_MAC
class CustomGLContext : public QGlContext {
  ...
#ifdef Q_WS_MAC
  void* chooseMacVisual(GDHandle handle) override {
    return select_3_2_mac_visual(handle); // call cocoa code
  }
#endif // Q_WS_MAC
};

gl_mac_specific.mm:

void* select_3_2_mac_visual(GDHandle handle)
{
static const int Max = 40;
NSOpenGLPixelFormatAttribute attribs[Max];
int cnt = 0;
attribs[cnt++] = NSOpenGLPFAOpenGLProfile;
attribs[cnt++] = NSOpenGLProfileVersion3_2Core;
attribs[cnt++] = NSOpenGLPFADoubleBuffer;
attribs[cnt++] = NSOpenGLPFADepthSize;
attribs[cnt++] = (NSOpenGLPixelFormatAttribute)16;
attribs[cnt] = 0;
Q_ASSERT(cnt < Max);

return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
}