1

it seems i cannot use glBindBuffer, glGenBuffer in the inherited-class of QQuickPaintedItem.

I already try to include , but it doesn't work and I also try to use GLEW in QQuickPaintedItem. It looks like Qt would undefined those functions in QQuickPaintedItem.

My Qt version is 5.1 msvc-opengl and the system operates on win7 desktop.

compiler msg:

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

some code

class MyQuickGLPanel :public QQuickPaintedItem 
{

Q_OBJECT

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

main

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
        }
    }           
}

UPDATE

List some way to avoid this issue in Window platform.

  1. Retrieve the entry point of OpenGL via

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

  2. Use customized context creation in your 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();
      ....
    }
    

    REF

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

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

Community
  • 1
  • 1
tirth
  • 813
  • 1
  • 8
  • 16
  • QQuickPaintedItem is supposed to be painted using a QPainter. What are you using `glBindBuffer` for? – peppe Apr 14 '14 at 22:21
  • I'm using some sort of mixed OpenGL drawing, which can be done by connecting the signal beforeRendering and afterRendering. (so I have another 3d drawing function.) The idea is to utilize the QtQuick ui scripting as well as supporting some 3d rendering requirement. – tirth Apr 15 '14 at 02:16

1 Answers1

2

Qt tries to wrap a lot of OpenGL functionality into a single class that contains all of the (extended) shared functions between GL and GL ES 2.0, called QGLFunctions.

Rather than using GLEW, you should consider QGLFunctions::glBindBuffer (...). If you call QGLFunctions::initializeGLFunctions (...) it does a lot of the same things as GLEW.

In fact, you would probably go ahead and inherit this class so that any call to glBindBuffer (...) is automatically handled through inheritance of QGLFunctions.


The following description is taken from the Qt SDK documentation for QGLFunctions:

QGLFunctions provides a guaranteed API that is available on all OpenGL systems and takes care of function resolution on systems that need it. The recommended way to use QGLFunctions is by direct inheritance:

class MyGLWidget : public QGLWidget, protected QGLFunctions
{
  Q_OBJECT
public:
  MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) {}

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

void MyGLWidget::initializeGL()
{
  initializeGLFunctions();
}
Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Thanks Andon. This method does work for QWidget, but I'm working on QtQuick based application. Inherit QGLFunctions in customized QQuickPaintedItem would trigger assertion. I guess this is because whole QQuickWindow shares same OGL context. – tirth Apr 12 '14 at 07:32
  • 1
    @tirth - there is nothing wrong with borrowing the context. You can do custom GL painting both "under" and "over" QtQuick, go to youtube and watch this video on QML and GL integration: https://www.youtube.com/watch?v=GYa5DLV6ADQ – dtech Apr 12 '14 at 07:47
  • @tirth: This was only the example from the documentation, you can initialize an instance of this class from anywhere. You don't have to inherit it by some class that inherits `QGLWidget`, another use case is to insantiate a `QGLFunctions` object from *any* OpenGL context and then qualify all of your GL calls as `gl_functions.glBindBuffer (...)`. On some platforms, GL extension functions are specific to a context so you may need a context active in your calling thread before you can do this - GLX is a bit of an oddball in that you can legitimately load function pointers without a context. – Andon M. Coleman Apr 12 '14 at 14:48
  • @tirth: To put this another way, on a platform like Windows, your instance of `QGLFunctions` can only safely be used with the OpenGL context that was active when you initialized it. On Linux, you can initialize it and use it with any context. Since this is Qt and your focus should be portability, you should cater to the more restrictive requirements of Windows (WGL) rather than Linux (GLX). – Andon M. Coleman Apr 12 '14 at 14:56
  • 1
    This answer is almost there: you can't just use *glBindBuffer*, as it's not a GL 1.1 call (you're on Windows!). You must resolve it at runtime. 1) **Do not use QGLFunctions**, use QOpenGLFunctions (via QOpenGLContext::functions or similar) instead, see [here for some reasons](http://stackoverflow.com/questions/21722852/difference-in-opengl-speed-between-qt-4-5-and-opengl-api/21742003#21742003). In this case you have a QQ2 app, not a widgets-based ones, and you don't want to use QtOpenGL. 2) Consider just using QOpenGLBuffer for wrapping your buffer objects. – peppe Apr 14 '14 at 22:02
  • The whole point of QGLFunctions is to load the necessary fuctions from parts of the OpenGL API that require run-time extension on some platforms. Calling its init method is supposed to take care of entry-point resolution for all of the functions newer than GL 1.1 (Windows). – Andon M. Coleman Apr 14 '14 at 22:06
  • And that's what I just said. **But you're still supposed to be using QOpenGLFunctions instead.** Downsides of using QGLFunctions include: 1) QGLFunctions requires QtOpenGL, which in turn requires QtWidgets. That's an extra 15-25MB of unnecessary libraries if your app is only QQ2. 2) The QQ2 APIs are written in terms of the QOpenGL* types, living in QtGui. No reason for going through the QGL* ones 3) QtOpenGL is "done" and QGL* types will not see bugfixes and feature enhancements. QOpenGL* types will. – peppe Apr 14 '14 at 22:20
  • thanks @peppe . This solve my question about the different interface between QGL and QOpenGL. – tirth Apr 15 '14 at 03:10