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. [SOLVED] QOpenGLShaderProgram segfault

[SOLVED] QOpenGLShaderProgram segfault

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 2.4k Views
  • 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.
  • D Offline
    D Offline
    Dorian
    wrote on last edited by Dorian
    #1

    I wanna write some app that use QOpenGLWidget and QOpenGLFunctions. And I have problem when I try to use any of functions from QOpenGLShaderProgram in other function that initializeGL or paintGL. Exactly when I even try to use program->log() i have segmentation fault. In that function I have makeCurrent(). When I create new QOpenGLShaderProgram in that function there's no problem, but when not (and I'm sure that object of QOpenGLShaderProgram exists at the time) i have segfault. Have you had problem like this?

    D 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome
      I have

      class GLRender : public QOpenGLWidget, protected QOpenGLFunctions
      {
          Q_OBJECT
          QOpenGLShaderProgram* m_program;
      ..
      

      and tried from

       void mousePressEvent(QMouseEvent *)
          {
              qDebug () << m_program->log();
              emit  RenderSelected(this);
          }
      

      And no crashes.

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

        Hi,

        To add to @mrjj, where are you initializing your QOpenGLShaderProgram ? And also when are you initializing it ?

        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
        0
        • mrjjM mrjj

          Hi and welcome
          I have

          class GLRender : public QOpenGLWidget, protected QOpenGLFunctions
          {
              Q_OBJECT
              QOpenGLShaderProgram* m_program;
          ..
          

          and tried from

           void mousePressEvent(QMouseEvent *)
              {
                  qDebug () << m_program->log();
                  emit  RenderSelected(this);
              }
          

          And no crashes.

          D Offline
          D Offline
          Dorian
          wrote on last edited by
          #4

          Hey, thanks for your answers. It looks exactly like this:

          #include "openglcontroller.h"
          #include "global.h"
          
          #include <cmath>
          #include <QWidget>
          #include <QMouseEvent>
          #include <QWheelEvent>
          #include <QOpenGLShaderProgram>
          #include <QDebug>
          
          OpenGLController::OpenGLController(QWidget * parent) :
              QOpenGLWidget(parent),
              m_parent(parent),
              m_f(nullptr),
              m_wheelMesh(parent),
              m_camAngleX(0.0f),
              m_camAngleY(0.0f),
              m_camFar(3.0f),
              m_camYPos(0.5f)
          {
              m_objectMesh = nullptr;
          }
          
          OpenGLController::~OpenGLController()
          {
              clean();
          }
          
          void OpenGLController::initializeGL()
          {
              bool ok = true;
              makeCurrent();
              m_f = QOpenGLContext::currentContext()->functions();
              initializeOpenGLFunctions();
              connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &OpenGLController::clean);
          
              glClearColor(g_bgColor.x(), g_bgColor.y(), g_bgColor.z(), g_bgColor.w());
          
              m_colorShader = new QOpenGLShaderProgram/*(QOpenGLContext::currentContext())*/;
              ok &= m_colorShader->addShaderFromSourceFile(QOpenGLShader::Vertex, "shaders/colorS.vs");
              ok &= m_colorShader->addShaderFromSourceFile(QOpenGLShader::Fragment, "shaders/colorS.fs");
              if(ok)
              {
                  m_colorShader->bindAttributeLocation("vVertex",0);
                  m_colorShader->link();
                  m_colorShader->bind();
          
                  m_projMatInfo.id = m_colorShader->uniformLocation(m_projMatInfo.name = "Mproj");
                  m_moveMatInfo.id = m_colorShader->uniformLocation(m_moveMatInfo.name = "Mmove");
                  m_colorInfo.id = m_colorShader->uniformLocation(m_colorInfo.name = "materialColor");
          
                  setWheelGrid();
          
                  m_colorShader->release();
              }
              else
              {
                  emit sendLog(Log(log_critical,tr("Nie znaleziono zawartości w katalogu shaders lub nie udało się uruchomić programów cieniujących"),
                                   -1,"OpenGLController","initializeGL"));
              }
              doneCurrent();
          }
          
          void OpenGLController::resizeGL(int w, int h)
          {
              m_projMat.setToIdentity();
              m_projMat.perspective(80.0f,(float)(w)/(float)h,0.1f,20.0f);
          }
          
          void OpenGLController::paintGL()
          {
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
              glEnable(GL_DEPTH_TEST);
          
              m_moveMat.setToIdentity();
              m_moveMat.translate(0.0f, 0.0f, -m_camFar);
              m_moveMat.rotate(m_camAngleX,1.0f,0.0f,0.0f);
              m_moveMat.rotate(m_camAngleY,0.0f,1.0f,0.0f);
              m_moveMat.translate(0.0f, -m_camYPos, 0.0f);
          
          
              m_colorShader->bind();
              m_colorShader->setUniformValue(m_projMatInfo.id, m_projMat);
              m_colorShader->setUniformValue(m_moveMatInfo.id, m_moveMat);
              m_colorShader->setUniformValue(m_colorInfo.id, m_wheelColor);
          
              m_wheelMesh.vao.bind();
              m_f->glEnable(GL_LINE_SMOOTH);
              m_f->glLineWidth(g_gridBold);
              m_f->glDrawArrays(GL_LINES, 0, m_wheelMesh.vCount);
              m_f->glDisable(GL_LINE_SMOOTH);
          
              if(m_objectMesh != nullptr)
              {
                  m_objectMesh->vao.bind();
                  m_colorShader->bind();
                  m_colorShader->setUniformValue(m_projMatInfo.id, m_projMat);
                  m_colorShader->setUniformValue(m_moveMatInfo.id, m_moveMat);
                  m_colorShader->setUniformValue(m_colorInfo.id, m_wheelColor);
          
                  m_f->glDrawArrays(GL_POINTS, 0, m_objectMesh->vCount);
              }
          
              m_colorShader->release();
          }
          
          // Funkcję można poprawić poprzez uwzględnienie rozmiaru renderowanego obszaru
          void OpenGLController::mouseMoveEvent(QMouseEvent * event)
          {
             // ... here is some code
          }
          
          void OpenGLController::wheelEvent(QWheelEvent * event)
          {
              //.... Here is some code
          }
          
          void OpenGLController::createObjectsMesh(unsigned horizontalPts, unsigned verticalPts)
          {
              delete m_objectMesh;
              m_objectMesh = new OGLCMesh(m_parent);
              m_objectMesh->vao.create();
              m_objectMesh->vao.bind();
              m_objectMesh->vbo.create();
              m_objectMesh->vbo.bind();
              m_objectMesh->vbo.allocate(horizontalPts * verticalPts * 4 * sizeof(GLfloat));
          
              //m_colorShader->log();  HERE IS SEGFAULT
          }
          
          void OpenGLController::addObjectsSubMesh(unsigned vertsCount, double * vertices)
          {
              makeCurrent();
              GLfloat * vConverted = new GLfloat[vertsCount * 4];
              for(unsigned i=0; i < vertsCount * 4; i++)
                  vConverted[i] = vertices[i];
          
              m_objectMesh->vbo.write(m_objectMesh->vCount * 4, vConverted, vertsCount * 4);
              m_objectMesh->vCount += vertsCount;
              delete [] vConverted;
          
              update();
              doneCurrent();
          }
          
          void OpenGLController::setWheelGrid(float radius, unsigned rings, unsigned diameters)
          {
              float angleStep = 360.0f / diameters;
              float radStep = radius / rings;
              unsigned edgesCount = (rings + 1) * diameters;
              unsigned vertsCount = edgesCount * 2;
              if(m_wheelMesh.vTab != nullptr)
              {
                  delete [] m_wheelMesh.vTab;
                  m_wheelMesh.vTab = nullptr;
              }
              m_wheelMesh.vCount = vertsCount;
              m_wheelMesh.vTab = new GLfloat[vertsCount * 4];
          
              unsigned index = 0;
              //Najpierw promienie
              for(unsigned i = 0; i < diameters; i++)
              {
                  double currentAngle = (double)angleStep * i * g_pi / 180.0;
                  double nextAngle = (double)angleStep * (i+1) * g_pi / 180.0;
                  m_wheelMesh.vTab[index++] = 0.0f;
                  m_wheelMesh.vTab[index++] = 0.0f;
                  m_wheelMesh.vTab[index++] = 0.0f;
                  m_wheelMesh.vTab[index++] = 1.0f;       //Współrzędne środka
                  m_wheelMesh.vTab[index++] = radius * cos(currentAngle);
                  m_wheelMesh.vTab[index++] = 0.0f;
                  m_wheelMesh.vTab[index++] = radius * sin(currentAngle);
                  m_wheelMesh.vTab[index++] = 1.0f;
                  //Następnie kolejne okręgi
                  for(unsigned j = 0; j < rings; j++)
                  {
                      m_wheelMesh.vTab[index++] = radStep * (j+1) * cos(currentAngle);
                      m_wheelMesh.vTab[index++] = 0.0f;
                      m_wheelMesh.vTab[index++] = radStep * (j+1) * sin(currentAngle);
                      m_wheelMesh.vTab[index++] = 1.0f;
                      m_wheelMesh.vTab[index++] = radStep * (j+1) * cos(nextAngle);
                      m_wheelMesh.vTab[index++] = 0.0f;
                      m_wheelMesh.vTab[index++] = radStep * (j+1) * sin(nextAngle);
                      m_wheelMesh.vTab[index++] = 1.0f;
                  }
              }
          
              if(!m_wheelMesh.vao.isCreated())
                  m_wheelMesh.vao.create();
              m_wheelMesh.vao.bind();
              if(!m_wheelMesh.vbo.isCreated())
                  m_wheelMesh.vbo.create();
              m_wheelMesh.vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
              m_wheelMesh.vbo.bind();
              m_wheelMesh.vbo.allocate(m_wheelMesh.vTab, m_wheelMesh.vCount*4*sizeof(GLfloat));
          
              m_colorShader->enableAttributeArray(0);
              m_colorShader->setAttributeArray(0,GL_FLOAT,0,4);
          }
          
          void OpenGLController::clean()
          {
              makeCurrent();
              m_wheelMesh.vao.destroy();
              m_wheelMesh.vbo.destroy();
              if(m_objectMesh != nullptr)
              {
                  m_objectMesh->vao.destroy();
                  m_objectMesh->vbo.destroy();
              }
              delete m_colorShader;
              m_colorShader = 0;
             // delete m_f;
              doneCurrent();
          }
          

          And the problem is in function createObjectsMesh. When I will create QOpenGLShaderProgram again in this function there will be no problem, but if I do like this I have segmentation fault.

          m_colorShader is QOpenGLShaderProgram with which i have problem.

          1 Reply Last reply
          0
          • D Dorian

            I wanna write some app that use QOpenGLWidget and QOpenGLFunctions. And I have problem when I try to use any of functions from QOpenGLShaderProgram in other function that initializeGL or paintGL. Exactly when I even try to use program->log() i have segmentation fault. In that function I have makeCurrent(). When I create new QOpenGLShaderProgram in that function there's no problem, but when not (and I'm sure that object of QOpenGLShaderProgram exists at the time) i have segfault. Have you had problem like this?

            D Offline
            D Offline
            Dorian
            wrote on last edited by Dorian
            #5

            Ok, I found solution. Well, i have made mistake in class MainWindow.
            Now this is part from MainWindow:

            namespace Ui {
            class MainWindow;
            }
            
            class MainWindow : public QMainWindow
            {
                Q_OBJECT
            
            public:
                explicit MainWindow(QWidget *parent = 0);
                ~MainWindow();
            private:
                Ui::MainWindow *ui;
                OpenGLController * m_glController;  // Here I had: OpenGLController m_glController
            };
            

            And in MainWindow.cpp constructor:

            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
                m_glController = ui->openGLWidget;   // I did not wrote this line earlier 
            }
            

            And how I execute function createObjectsMesh(...) :

            m_glController->createObjectsMesh(ui->sb_pointsHorizontal->value(), 480);
            // Earlier it was just object, not pointer - like this:
            // m_glController.createObjectsMesh(ui->sb_pointsHorizontal->value(), 480);
            

            So in my app I had 2 objects of QOpenGLWidget - one that is made in GUI (Qt Form) and one which I had in my MainWindow class. And when I executed function createObjectsMesh(...) I did it for second of them, not first which were actually drawn in GUI.
            I should just not to create another QOpenGLWidget in MainWindow class, but only get pointer to this one from GUI, like this:

            m_glController = ui->openGLWidget;
            

            So now I have only one QOpenGLWidget - this one that is drawn in GUI.

            Anyway - thanks for your help :D

            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              ahh, tricky one :)

              1 Reply Last reply
              0

              • Login

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