0

I have application where critical part of code are:

main.cpp

#include <QApplication>
#include <QSurfaceFormat>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //the same version of context for all GL widgets
    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);

    //creation and displaying main window
    MainWindow w(&argc, argv);
    w.show();

    return a.exec();
}

In MainWindow w there is used class GLRendWindow : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core which has such important parts:

void GLRendWindow::initializeGL()
{
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    initializeOpenGLFunctions();

    generateShaders();

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
}

void GLRendWindow::generateShaders()
{
    shaderPoint = Shader("../shader/point.vert", "../shader/point.frag");
    shaderCross = Shader("../shader/cross.vert", "../shader/cross.frag");
}

Shader.h is:

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <QOpenGLFunctions_3_3_Core>

class Shader: protected QOpenGLFunctions_3_3_Core
{
    public:
        Shader();
        Shader(const char *vertexPath, const char *fragmentPath);

        GLint getID();

    private:
        GLint ID;
        //QOpenGLFunctions_3_3_Core *fun;

    private:
        void checkCompilationStatus(GLuint compiled, bool shader = true);
};
#endif //SHADER_H

Shader.cpp part is:

Shader::Shader()
{
}

Shader::Shader(const char *vertexPath, const char *fragmentPath)
{
    //fun = new QOpenGLFunctions_3_3_Core();
    //fun->initializeOpenGLFunctions();

    std::string vertexCode;
    std::string fragmentCode;
    std::ifstream vShaderFile;
    std::ifstream fShaderFile;

    vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    try
    {
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        std::stringstream vShaderStream, fShaderStream;

        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();

        vShaderFile.close();
        fShaderFile.close();

        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
    }
    catch (std::ifstream::failure &e)
    {
        std::cout << "ERROR: Can't load shader! Path: " << vertexPath << "  " << fragmentPath << std::endl;
    }
    const char *vShaderCode = vertexCode.c_str();
    const char *fShaderCode = fragmentCode.c_str();

    GLint vertex, fragment;

    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, NULL);
    glCompileShader(vertex);
    checkCompilationStatus(vertex);

    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fShaderCode, NULL);
    glCompileShader(fragment);
    checkCompilationStatus(fragment);

    ID = glCreateProgram();
    glAttachShader(ID, vertex);
    glAttachShader(ID, fragment);
    glLinkProgram(ID);
    checkCompilationStatus(ID, false);

    glDeleteShader(vertex);
    glDeleteShader(fragment);
}

This code is compiled and build properly. I can run app with success, there is no error during shaders creations. It also display everything properly. Hovewer during closing of app I see segmentation fault after end of Shader destructor with stack:

libQt5Gui.so.5!QOpenGLContext::removeExternalFunctions(QAbstractOpenGLFunctions*) (Unknown Source:0)
libQt5Gui.so.5!QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions() (Unknown Source:0)
Shader::~Shader(Shader * const this) (/home/rom/repos/radarVis/shader/shader.h:10)
GLRendWindow::~GLRendWindow(GLRendWindow * const this) (/home/rom/repos/radarVis/src/gui/glrendwind.cpp:18)
GLRendWindow::~GLRendWindow(GLRendWindow * const this) (/home/rom/repos/radarVis/src/gui/glrendwind.cpp:22)
libQt5Core.so.5!QObjectPrivate::deleteChildren() (Unknown Source:0)
libQt5Widgets.so.5!QWidget::~QWidget() (Unknown Source:0)
libQt5Widgets.so.5!QWidget::~QWidget() (Unknown Source:0)
libQt5Core.so.5!QObjectPrivate::deleteChildren() (Unknown Source:0)
libQt5Widgets.so.5!QWidget::~QWidget() (Unknown Source:0)
MainWindow::~MainWindow(MainWindow * const this) (/home/rom/repos/radarVis/src/gui/mainwind.cpp:26)
main(int argc, char ** argv) (/home/rom/repos/radarVis/src/main.cpp:23)

This problem doesn't appear if Shader is no longer derived from QOpenGLFunctions_3_3_Core.

My question is why?
What in this case may be connection/dependency/other of class derived from QOpenGLFunctions_3_3_Core and calling destructor with segmentation fault.
Is it possible two mechanisms try to clean my shaders? Or may be there is mandatory way of cleaning all QOpenGLFunctions_3_3_Core that I missed in documentation?

rainbow
  • 1,161
  • 3
  • 14
  • 29
  • Why are you inheriting from `QOpenGLFunctions_3_3_Core`? – molbdnilo Nov 16 '20 at 11:01
  • For having easy access to glXXX() methods. I can of course create object and use f->glXXX() but first method seems to be more convenient. Unfortunatelly doesn't work as expected. Or probably I can't use it properly. – rainbow Nov 16 '20 at 11:22

0 Answers0