QtQuick 2 是不是支持 glBindBuffer?

Posted

技术标签:

【中文标题】QtQuick 2 是不是支持 glBindBuffer?【英文标题】:Does QtQuick 2 support glBindBuffer?QtQuick 2 是否支持 glBindBuffer? 【发布时间】:2014-04-11 18:42:21 【问题描述】:

我好像不能在QQuickPaintedItem的继承类中使用glBindBuffer、glGenBuffer。

我已经尝试包含,但它不起作用,我也尝试在 QQuickPaintedItem 中使用 GLEW。看起来 Qt 会在 QQuickPaintedItem 中取消定义这些函数。

我的Qt版本是5.1 msvc-opengl,系统在win7桌面上运行。

编译器消息:

fcglpanel.cpp(254): error C3861: 'glBindBuffer': identifier not found

一些代码

class MyQuickGLPanel :public QQuickPaintedItem 


Q_OBJECT

    //-------------------------------------------------------------------------
    public: 
        FCGLPanel(QQuickItem  * parent=0);
        ~FCGLPanel(); 
        virtual void paint(QPainter * painter);
    ...

主要

int main(int argc, char *argv[])

    QApplication app(argc, argv); 

    qmlRegisterType<MyQucikGLPanel>("MyQucikGLPanel", 1, 0, "MyPanel"); 

    QQmlApplicationEngine engine(QUrl::fromLocalFile("../qml/main.qml")); 

    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    return qmlMode(argc, argv);

main.qml

import QtQuick 2.1
import QtQuick.Controls 1.0 
import QtQuick.Layouts 1.0
import QtQuick.Dialogs 1.0
import QtQuick.Window 2.1

import "./MyUI" 1.0 as MyUI
import MyQucikGLPanel 1.0

ApplicationWindow 
    id: appwindow

    property int zGLPanel : 4;

    SplitView 

        x: 32
        y: 8
        anchors.rightMargin: 5
        anchors.bottomMargin: 5
        anchors.leftMargin: 0
        anchors.topMargin: 0
        anchors.fill: parent

        // [EMBEDDING C++ object]
        MyPanel
            id: mylogicPanel
            anchors.fill: parent
            width: 640
            height: 480
            z : appwindow.zGLPanel
        
               


更新

列出一些在 Window 平台中避免此问题的方法。

    通过

    获取OpenGL的入口点

    QOpenGLFunctions* oglEntry = window()->openglContext()->functions();

    在您的 QWindow 中使用自定义上下文创建。

    
    Window::Window( QScreen* screen )
    : QWindow( screen )
    // Tell Qt we will use OpenGL for this window
    setSurfaceType( OpenGLSurface );
    
    // Specify the format and create platform-specific surface
    QSurfaceFormat format; 
    format.setMajorVersion( 4 );
    format.setMinorVersion( 3 ); 
    format.setProfile( QSurfaceFormat::CoreProfile );
    setFormat( format );
    create();
    
    // Create an OpenGL context
    m_context = new QOpenGLContext;
    m_context->setFormat( format );
    m_context->create();
      ....
    
    

    参考

    http://www.kdab.com/opengl-in-qt-5-1-part-1/

    Difference in opengl speed between Qt 4/5 and Opengl API

【问题讨论】:

QQuickPaintedItem 应该使用 QPainter 进行绘制。你用glBindBuffer 做什么? 我正在使用某种混合的 OpenGL 绘图,可以通过连接信号 beforeRendering 和 afterRendering 来完成。 (所以我有另一个 3d 绘图功能。)这个想法是利用 QtQuick ui 脚本以及支持一些 3d 渲染要求。 【参考方案1】:

Qt 尝试将大量 OpenGL 功能封装到一个类中,该类包含 GL 和 GL ES 2.0 之间的所有(扩展)共享函数,称为 QGLFunctions

您应该考虑QGLFunctions::glBindBuffer (...),而不是使用 GLEW。如果你打电话给QGLFunctions::initializeGLFunctions (...),它会做很多很多与 GLEW 相同的事情。

事实上,您可能会继续继承这个类,以便通过QGLFunctions 的继承自动处理对glBindBuffer (...) 的任何调用。


以下描述取自QGLFunctions的Qt SDK文档:

QGLFunctions 提供了一个在所有 OpenGL 系统上都可用的保证 API,并负责处理需要它的系统上的函数解析。使用 QGLFunctions 的推荐方式是直接继承:

class MyGLWidget : public QGLWidget, protected QGLFunctions

  Q_OBJECT
public:
  MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) 

protected:
  void initializeGL();
  void paintGL();
;

void MyGLWidget::initializeGL()

  initializeGLFunctions();

【讨论】:

谢谢安东。此方法适用于 QWidget,但我正在开发基于 QtQuick 的应用程序。在自定义的 QQuickPaintedItem 中继承 QGLFunctions 将触发断言。我猜这是因为整个 QQuickWindow 共享相同的 OGL 上下文。 @tirth - 借用上下文没有错。您可以在 QtQuick 的“下方”和“上方”进行自定义 GL 绘制,转到 youtube 并观看有关 QML 和 GL 集成的视频:youtube.com/watch?v=GYa5DLV6ADQ @tirth:这只是文档中的示例,您可以从任何地方初始化此类的实例。您不必通过某些继承 QGLWidget 的类来继承它,另一个用例是从 any OpenGL 上下文中实例化 QGLFunctions 对象,然后将所有 GL 调用限定为 @987654334 @。在某些平台上,GL 扩展函数是特定于上下文的,因此您可能需要在调用线程中激活上下文才能执行此操作 - GLX 有点奇怪,因为您可以在没有上下文的情况下合法地加载函数指针。跨度> @tirth:换句话说,在像 Windows 这样的平台上,QGLFunctions 的实例只能安全地与初始化时处于活动状态的 OpenGL 上下文一起使用。在 Linux 上,您可以初始化它并在任何上下文中使用它。由于这是 Qt 并且您的重点应该是可移植性,因此您应该满足 Windows (WGL) 而不是 Linux (GLX) 的更严格的要求。 这个答案几乎就在那里:你不能只使用 glBindBuffer,因为它不是 GL 1.1 调用(你在 Windows 上!)。您必须在运行时解决它。 1) 不要使用 QGLFunctions,改用 QOpenGLFunctions(通过 QOpenGLContext::functions 或类似方法),请参阅here for some reasons。在这种情况下,您有一个 QQ2 应用程序,而不是基于小部件的应用程序,并且您不想使用 QtOpenGL。 2) 考虑只使用 QOpenGLBuffer 来包装缓冲区对象。

以上是关于QtQuick 2 是不是支持 glBindBuffer?的主要内容,如果未能解决你的问题,请参考以下文章

QML/QtQuick:使图像在 ColumnLayout 中仅占用可用高度

如何更改 QtQuick 2 窗口的标题?

使用 SVG 插件部署 QtQuick 2.0 应用程序

为啥 RangeSlider 在 QtQuick 中可用,而不是作为标准 Widget

Qt、QtQuick、QML 和 QtMobility 可以针对的移动操作系统

无法锚定到不是父项或同级 QML QtQuick 的项目