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

标签 c++ macos qt opengl

我想使用 Qt 4.8.6 通过 QGLWidget 渲染 OpenGL 内容。我正在使用的机器是装有 OS X 10.9.4 的 macbook pro。

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

研究主题后,我找到了 Qt OpenGL Core Profile Tutorial .然而,示例源代码报告了与之前相同的 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 

使用 this OS X opengl context discussion 中建议的 Cocoa 代码从 2011 年开始,版本号的输出更改为

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 report has been filed.

其他人可以验证此行为吗?

最佳答案

是的。那是特定于平台的。请寻找解决方案here .

覆盖 QGLContex::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];
}

关于c++ - 在 OS X 上的 Qt 4.8.6 中更改 QGLWidgets 的 OpenGL 上下文版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24873533/

相关文章:

c++ - 用于顺序内存访问的编译器嵌套循环优化。

database - 如何在 MacOS X 上卸载/删除 MarkLogic 7?

c++ - Qt - 在 Windows 上按下 Alt 后防止菜单栏获取焦点

qt - 尝试使用 Qt 应用程序将超过 600mb 的文件上传到服务器

QT4 Qtableview禁用行选择

c++ - typeid(复杂<double>(0.0,1.0)) != typeid(1.0i)

c++ - 编写新的 Eigen 表达式

c++ - std::map 中的容错键查找

iphone - 在 Interface Builder 中使用的自定义颜色模式

objective-c - 查找可用的 USB 设备 Mac OS X