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?