Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QOpenGLWidget Problem
Forum Updated to NodeBB v4.3 + New Features

QOpenGLWidget Problem

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 352 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NanJofish
    wrote on last edited by
    #1

    Hi,Why does my QOpenGLWidget's drawn model disappear after using update(), but the background color is still displayed.
    Here is my code:

    void OpenGLWidget::initializeGL()
    {
        initializeOpenGLFunctions();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        f = QOpenGLContext::currentContext()->functions(); 
        f->glEnable(GL_DEPTH_TEST);
     
        this->initializeShaders();
     
    }
     
    void OpenGLWidget::initializeShaders()
    {
        this->m_ModelShader = new QOpenGLShaderProgram(this);
    
        /*--------m_ModelShader------------*/
        if (!m_ModelShader->addShaderFromSourceFile(QOpenGLShader::Vertex, \
            ModelvertexShaderPath))
                qDebug() << "Failed to load Vert shader:" << m_ModelShader->log();
        if (!m_ModelShader->addShaderFromSourceFile(QOpenGLShader::Fragment, \
            ModelfragmentShaderPath))
                qDebug() << "Failed to load fragment shader:" << m_ModelShader->log();
        if (!m_ModelShader->link())
            std::cout << "ERROR: failed to link: " << m_ModelShader->log().toStdString();
     
    }
     
    void OpenGLWidget::resizeGL(int w, int h)
    {
        this->SCR_WIDTH = w;
        this->SCR_HEIGHT = h;
        this->SelectProjection(this->operatePro);
    }
     
    void OpenGLWidget::paintGL()
    {
        f = QOpenGLContext::currentContext()->functions();
        f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        f->glClearColor(0.0f, 0.5f, 0.7f, 1.0f);
        if (isValid())
            switch (RenderModel)
            {
                case Model:
                {
                    makeCurrent();
                    m_VAO = new QOpenGLVertexArrayObject(this);
                    m_VBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
                    m_EBO = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
     
                    this->DrawModelData();
     
                    m_ModelShader->bind();
                    {
                        m_VAO->bind();
                        m_EBO->bind();
                        this->setModelShaderMatrix();
                      
                        f->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
                    }
                    m_ModelShader->release();
                    break;
                }
                case Line:
                {
                    break;
                }
                case Points:
                {
                    break;
                }
            }
    }
     
     
    void OpenGLWidget::DrawModelData()
    {
     
        this->m_ModelShader->bind();
        if (!m_VAO->create())
            std::cerr << "ERROR: faild to create vertex array object" << std::endl;
        if (!m_VBO->create())
            std::cerr << "ERROR: failed to create vertex buffer object" << std::endl;
        if (!m_EBO->create())
            std::cerr << "ERROR: failed to create index buffer object" << std::endl;
     
        m_VAO->bind();
        if (!m_VBO->bind())
        {
            std::cerr << "ERROR: failed to bind vertex buffer object" << std::endl;
     
        }
        m_VBO->allocate(&meshes[0], meshes.size() * sizeof(Vertex));
     
        if (!m_EBO->bind())
        {
            std::cerr << "ERROR: failed to bind index buffer object" << std::endl;
        }
        m_EBO->allocate(&indices[0], sizeof(unsigned int) * indices.size());
     
        int vertexLocation = m_ModelShader->attributeLocation("aPos"); /
        int normalLocation = m_ModelShader->attributeLocation("aNormal"); 
        glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Position));
        glEnableVertexAttribArray(vertexLocation);
        
        glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
        glEnableVertexAttribArray(normalLocation);
        m_VBO->release();
        m_EBO->release();
        m_VAO->release();
        m_ModelShader->release();
    }
     
    void OpenGLWidget::setModelShaderMatrix()
    {
        // DirLight
        GLint ViewPos = glGetUniformLocation(m_ModelShader->programId(), "viewPos");
        GLint lightDir = glGetUniformLocation(m_ModelShader->programId(), "dirLight.direction");
        GLint lightAmb = glGetUniformLocation(m_ModelShader->programId(), "dirLight.ambient");
        GLint lightDif = glGetUniformLocation(m_ModelShader->programId(), "dirLight.diffuse");
        GLint lightSpe = glGetUniformLocation(m_ModelShader->programId(), "dirLight.specular");
        // Material变量
        GLint materAmb = glGetUniformLocation(m_ModelShader->programId(), "material.ambient");
        GLint materDif = glGetUniformLocation(m_ModelShader->programId(), "material.diffuse");
        GLint materSpe = glGetUniformLocation(m_ModelShader->programId(), "material.specular");
        GLint materShi = glGetUniformLocation(m_ModelShader->programId(), "material.shininess");
        GLint alpha = glGetUniformLocation(m_ModelShader->programId(), "alpha");
     
        GLint Model_model = glGetUniformLocation(m_ModelShader->programId(), "model");
        GLint Model_view = glGetUniformLocation(m_ModelShader->programId(), "view");
        GLint Model_proj = glGetUniformLocation(m_ModelShader->programId(), "projection");
        m_ModelShader->setUniformValue(ViewPos, m_Camera->getPosition());
        m_ModelShader->setUniformValue(lightAmb, Light_ambient);
        m_ModelShader->setUniformValue(lightDir, Light_direction);
        m_ModelShader->setUniformValue(lightDif, Light_diffuse);
        m_ModelShader->setUniformValue(lightSpe, Light_specular);
     
        m_ModelShader->setUniformValue(materAmb, Model_ambient);
        m_ModelShader->setUniformValue(materDif, Model_diffuse);
        m_ModelShader->setUniformValue(materSpe, Model_specular);
        m_ModelShader->setUniformValue(materShi, Model_shininess);
        m_ModelShader->setUniformValue(alpha, 1.0f);
    
        this->m_view = m_Camera->GetViewMatrix();
    
        m_ModelShader->setUniformValue(Model_view, m_view);
        m_ModelShader->setUniformValue(Model_proj, m_projection);
     
    
        m_scale_rate = max(0.75f / max_len, m_scale_rate);
        this->m_model.scale(m_scale_rate);
        this->m_model = m_scale * m_model;
        this->m_middle = QVector3D(this->bbox.centerPoint.x, this->bbox.centerPoint.y, this->bbox.centerPoint.z);
        this->m_model.translate(-m_middle);
        this->m_model = m_move * m_rotate * m_model;
        m_ModelShader->setUniformValue(Model_model, m_model);
    }
     
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      Your code is incomplete so it's not easy to fully grasp what you are doing.

      In any case, why are you allocating your buffer objects possibly on every call of paintGL ?

      That is pretty strange. Also you see to have derived from QOpenGLFunctions yet you retrieve the function from the current context although the context will be current when the xxxGL methods are called.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      N 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi and welcome to devnet,

        Your code is incomplete so it's not easy to fully grasp what you are doing.

        In any case, why are you allocating your buffer objects possibly on every call of paintGL ?

        That is pretty strange. Also you see to have derived from QOpenGLFunctions yet you retrieve the function from the current context although the context will be current when the xxxGL methods are called.

        N Offline
        N Offline
        NanJofish
        wrote on last edited by
        #3

        @SGaist
        Before that my code looked like this,it doesn't allocating buffer objects repeatedly.
        But to do that would just show the background and not draw the model.

        struct Vertex
        {
            QVector3D Position;
            QVector3D Normal;
        };
        
        OpenGLWidget::OpenGLWidget(QWidget* parent) : QOpenGLWidget(parent)
        {
            this->m_Camera = new QCamera(this, QVector3D(0.0f, 0.0f, 3.0f));
            this->m_scale.setToIdentity();
            this->m_move.setToIdentity();
            this->m_model.setToIdentity();
            this->m_scale.setToIdentity();
            this->m_rotate.rotate(-90.0f, QVector3D(1.0f, 0.0f, 0.0f));
            this->m_rotate.rotate(45.0f, QVector3D(0.0f, 0.0f, 1.0f));
            this->m_middle.setX(0.0f);this->m_middle.setY(0.0f);this->m_middle.setZ(0.0f);
            this->m_projection.perspective(45.0f, static_cast<float>(SCR_WIDTH) / static_cast<float>(SCR_HEIGHT), 0.1f, 100.0f);
            this->m_view.lookAt(QVector3D(2.0f, 0.0f, 2.0f), QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f));  
        }
        
        void OpenGLWidget::initializeGL()
        {
            initializeOpenGLFunctions();
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glEnable(GL_DEPTH_TEST); 
        
            m_VAO = new QOpenGLVertexArrayObject(this);
            m_VBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
            m_EBO = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
        
            this->initializeShaders();
        }
        
        void OpenGLWidget::initializeShaders()
        {
            this->m_ModelShader = new QOpenGLShaderProgram(this);
            /*--------m_ModelShader------------*/
            if (!m_ModelShader->addShaderFromSourceFile(QOpenGLShader::Vertex, \
                ModelvertexShaderPath))
                    qDebug() << "Failed to load Vert shader:" << m_ModelShader->log();
            if (!m_ModelShader->addShaderFromSourceFile(QOpenGLShader::Fragment, \
                ModelfragmentShaderPath))
                    qDebug() << "Failed to load fragment shader:" << m_ModelShader->log();
            if (!m_ModelShader->link())
                std::cout << "ERROR: failed to link: " << m_ModelShader->log().toStdString();
        }
        void OpenGLWidget::LoadModel(GeoStruct::TriModel<>* curModel)
        {
            this->meshes.clear();
            this->meshes.resize(curModel->vertices.size());
        #pragma parallel for
            for (int i = 0; i < curModel->vertices.size(); ++i)
            {
                this->meshes[i].Position = QVector3D(curModel->vertices[i].x, curModel->vertices[i].y, curModel->vertices[i].z);
                this->meshes[i].Normal = QVector3D(curModel->PointNormals[i].x, curModel->PointNormals[i].y, curModel->PointNormals[i].z);
            }
            this->indices.resize(curModel->faces.size() * 3);
        #pragma parallel for
            for (int i = 0; i < curModel->faces.size(); ++i)
            {
                this->indices[3 * i] = curModel->faces[i][0];
                this->indices[3 * i + 1] = curModel->faces[i][1];
                this->indices[3 * i + 2] = curModel->faces[i][2];
            }
            this->max_len = max(max(curModel->Bounding.a, curModel->Bounding.b), curModel->Bounding.c);
            this->bbox = curModel->Bounding;
            this->DrawModelData();
        }
        void OpenGLWidget::DrawModelData()
        {
            this->m_ModelShader->bind();
            /*--------------------initial------------------*/
            if (!m_VAO->create())
                std::cerr << "ERROR: faild to create vertex array object" << std::endl;
            if (!m_VBO->create())
                std::cerr << "ERROR: failed to create vertex buffer object" << std::endl;
            if (!m_EBO->create())
                std::cerr << "ERROR: failed to create index buffer object" << std::endl;
            /*-------------------bind------------------*/
            m_VAO->bind();
            if (!m_VBO->bind())
            {
                std::cerr << "ERROR: failed to bind vertex buffer object" << std::endl;
        
            }
            m_VBO->allocate(&meshes[0], meshes.size() * sizeof(Vertex));
        
            if (!m_EBO->bind())
            {
                std::cerr << "ERROR: failed to bind index buffer object" << std::endl;
            }
            m_EBO->allocate(&indices[0], sizeof(unsigned int) * indices.size());
        
            int vertexLocation = m_ModelShader->attributeLocation("aPos"); 
            int normalLocation = m_ModelShader->attributeLocation("aNormal"); 
            glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Position));
            glEnableVertexAttribArray(vertexLocation);
            
            glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
            glEnableVertexAttribArray(normalLocation);
        
            m_VBO->release();
            m_EBO->release();
            m_VAO->release();
            m_ModelShader->release();
        }
        
        void OpenGLWidget::resizeGL(int w, int h)
        {
            this->SCR_WIDTH = w;
            this->SCR_HEIGHT = h;
            this->SelectProjection(this->operatePro);
        }
        
        void OpenGLWidget::SelectProjection(Projection ProjectionModel)
        {
            switch (ProjectionModel)
            {
            case ORTHO:
                {
                    m_projection.setToIdentity();
                    float left = -(float)SCR_WIDTH / (float)SCR_WIDTH * 2.0f;
                    float right = (float)SCR_WIDTH / (float)SCR_WIDTH * 2.0f;
                    float bottom = -(float)SCR_HEIGHT / (float)SCR_WIDTH * 2.0f;
                    float top = (float)SCR_HEIGHT / (float)SCR_WIDTH * 2.0f;
                    float nearVal = 0.1f;
                    float farVal = 100.0f;
                    this->m_projection.ortho(left, right, bottom, top, nearVal, farVal);
                    break;
                }
            case PERSPECTIVE:
                {
                    m_projection.setToIdentity();
                    m_projection.perspective(45.0f, static_cast<float>(SCR_WIDTH) / SCR_HEIGHT, 0.1f, 100.0f);
                
                    break;
                }
            default:
                {
                    m_projection.setToIdentity();
                    float left = -(float)SCR_WIDTH / (float)SCR_WIDTH * 2.0f;
                    float right = (float)SCR_WIDTH / (float)SCR_WIDTH * 2.0f;
                    float bottom = -(float)SCR_HEIGHT / (float)SCR_WIDTH * 2.0f;
                    float top = (float)SCR_HEIGHT / (float)SCR_WIDTH * 2.0f;
                    float nearVal = 0.1f;
                    float farVal = 100.0f;
                    this->m_projection.ortho(left, right, bottom, top, nearVal, farVal);          
                    break;
                }
            }
        }
        void OpenGLWidget::paintGL()
        {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glClearColor(0.0f, 0.5f, 0.7f, 1.0f);
            switch (RenderModel)
            {
                case Model:
                {
                    m_ModelShader->bind();
                    {
                        m_VAO->bind();
                        m_EBO->bind();
                        this->setModelShaderMatrix();
                        // render
                        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
                    }
                    m_ModelShader->release();
                    break;
                }
                case Line:
                {
                    break;
                }
                case Points:
                {
                    break;
                }
            }
        }
        

        This is called in QMainWindow :

        STLViewer::STLViewer(QWidget *parent)
            : QMainWindow(parent)
        {
            ui.setupUi(this);
            resize(1024, 768);
        
        
            this->pixmap = new QPixmap(file_name);
            QIcon icon(*pixmap);
            setWindowIcon(icon);
        
            connectSlots();
        }
        void STLViewer::connectSlots()
        {
            connect(ui.action_LoadSTL,
                &QAction::triggered,
                this,
                &STLViewer_BasedQT::LoadSTLdoc);
        }
        void STLViewer::LoadSTLdoc()
        {
        
            QString qs_FilePath = QFileDialog::getOpenFileName(this, QStringLiteral("ChooseSTL"), "", QStringLiteral(" (*.stl)"));
        
            QFileInfo fileinfo = QFileInfo(qs_FilePath);
            QString FileName = fileinfo.fileName();
        
            QByteArray qba = qs_FilePath.toLocal8Bit();
            const char* chFilename = qba.data(); 
            std::string s_FilePath(chFilename); 
            GeoStruct::TriModel<>* CurModel = new GeoStruct::TriModel<>();
            bool state = ImportModel(CurModel,s_FilePath);
            if (state&& CurModel->vertices.size()!=0)
            {
                Model_Library.emplace_back(CurModel);
                ++Model_Index;
                CurModel->need_normals();
                CurModel->computeVolume();
                ui.openGLWidget->LoadModel(CurModel);
                ui.openGLWidget->LoadPoint(CurModel->vertices);
                ui.openGLWidget->RenderModel = Model;
            }
        }
        

        I still can't see what's causing the failure to draw.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          With the code you posted, there's no way to know what RenderModel is so it might just be a value that does not do anything in your switch statement.

          You should start by simplifying your code and strip away all the complexity.

          Then start by adding the minimal amount of stuff to actually show something on the widget and only then add the loading of your file.

          On a side note, please use a clean style when writing your code. You are mixing TitleCase, camelCase and snake_case is the same code base which makes it quite painful to go through. Same goes for your variable naming.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved