Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to make QDockWidget and QOpenGLWidget combination?



  • Hello, everyone. My mother tongue is not English, but I will try my best to describe question clearly.

    I want to use OpenGL render something(for example spin box or an easy triangle) in QDockWidget.
    I learn that OpenGL can be used by QDockWidget, and QDockWidget can make the floating or dock subwidow in window(like visual studio or 3dmax)
    After search I reference to https://learnopengl.com/Getting-started/Hello-Triangle and tutorial and Qt Assistant to write below code:

    #include "mainwindow.h"
    #include <QDockWidget>
    #include <QApplication>
    #include "core3dockwidget.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        QDockWidget view3d2("3DView2", &w,Qt::Widget);
        view3d2.show();
        w.show();
        w.resize(800,600);
        Core3DockWidget view3d;
        view3d2.setWidget(&view3d);
        view3d2.show();
        view3d2.resize(400,300);
        return a.exec();
    }
    
    class Core3DockWidget : public QOpenGLWidget , protected QOpenGLFunctions_3_3_Core{
    {
        Q_OBJECT          
    public:
        explicit Core3DockWidget(QWidget *parent = nullptr);
        //..................
    }
    
    #include "core3dockwidget.h"
    #include <QDebug>
    #include <QDockWidget>
    
    static GLuint VBO, VAO, EBO;
    
    Core3DockWidget::Core3DockWidget(QWidget *parent):QOpenGLWidget(parent)
    {
        //view3dp = parent;
        //parent->setFeatures(QDockWidget::AllDockWidgetFeatures);
    }
    
    Core3DockWidget::~Core3DockWidget()
    {
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    //    glDeleteBuffers(1, &EBO);
    }
    
    QDockWidget* Core3DockWidget::returnParent(){
        return view3dp;
    }
    void Core3DockWidget::initializeGL(){
        this->initializeOpenGLFunctions();
    
        bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/triangle.vert");
        if (!success) {
            qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();
            return;
        }
    
        success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/triangle.frag");
        if (!success) {
            qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();
            return;
        }
    
        success = shaderProgram.link();
        if(!success) {
            qDebug() << "shaderProgram link failed!" << shaderProgram.log();
        }
    
        float vertices[] = {
            0.5f,  0.5f, 0.0f,  // top right
             0.5f, -0.5f, 0.0f,  // bottom right
            -0.5f, -0.5f, 0.0f,  // bottom left
            -0.5f,  0.5f, 0.0f   // top left
        };
        unsigned int indices[] = {  // note that we start from 0!
            0, 1, 3,  // first Triangle
            1, 2, 3   // second Triangle
        };
    
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  
    
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);/
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0); 
    }
    
    
    void Core3DockWidget::resizeGL(int w, int h){
        glViewport(0, 0, w, h);
    }
    
    
    void Core3DockWidget::paintGL(){
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        shaderProgram.bind();
        glBindVertexArray(VAO); 
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    
        shaderProgram.release();
    }
    
    

    After I build and run, there is the window within 1/4 size window titled '3DView2' in which is right render context.
    However, when I drag '3DView2' floating(there is black '3DView2') or switch to dock (there is a white rectangle without color but have glClearColor(0.2f, 0.3f, 0.3f, 1.0f)), there is:
    shaderProgram link failed! "ERROR: Duplicate function definitions for \"main\"; prototype: \"main()\" found.\n"
    when i resize '3DView2' dock in mainwindow, there is:

    QOpenGLShader::link: ERROR: Duplicate function definitions for "main"; prototype: "main()" found.
    QOpenGLShader::link: ERROR: Duplicate function definitions for "main"; prototype: "main()" found.
    QOpenGLShader::link: ERROR: Duplicate function definitions for "main"; prototype: "main()" found.
    

    I search google and still no solution.
    Should I use QDockWidget and QOpenGLWidget combination to render?
    if yes what I need to learn about QDockWidget and QOpenGLWidget?
    if no what technology I can use....

    Finally, thanks for reading, please give me some advice.
    thanks again.


Log in to reply