【问题标题】:Changing the OpenGL Context Version for QGLWidgets in Qt 4.8.6 on OS X在 OS X 上的 Qt 4.8.6 中更改 QGLWidgets 的 OpenGL 上下文版本
【发布时间】:2014-07-21 19:52:57
【问题描述】:

我想使用 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 

使用 2011 年 this OS X opengl context discussion 中建议的 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 的 major.minor 版本号。它似乎在 Ubuntu Linux 下工作,但在使用 OS X 时失败。

更新 3

欢乐时光。这可能是 Qt4.8.6 中的一个错误,因为在再次编译 Qt5.3.1 时不会出现该问题。一个bug report has been filed.

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

【问题讨论】:

    标签: c++ macos qt opengl


    【解决方案1】:

    是的。那是平台特定的。请找到解决方案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];
    }
    

    【讨论】:

    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多