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

failing to create QOpenGLShaderProgram object



  • It seems very simple, and I've done this in the past using classes derived from QWindow and from QOpenGLWindow.

    This time I'm deriving my displayed window class from QOpenGLWidget. Everything else seems the same as previous code. However, I am getting an assert error in my initializeGL() function.

    Note that this is all in my main.cpp file, there are no other header or source files.

    Here's the relevant code, in the order that it is in the .cpp file:

    static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    " col = colAttr;\n"
    " gl_Position = matrix * posAttr;\n"
    "}\n";

    static const char *fragmentShaderSource =
    "varying lowp vec4 col;\n"
    "void main() {\n"
    " gl_FragColor = col;\n"
    "}\n";

    class MyGLWidget : public QOpenGLWidget
    {
    public:
    MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) {}

    public:
    GLint m_posAttr = 0;
    GLint m_colAttr = 0;
    GLint m_matrixUniform = 0;

    void resizeGL(int w, int h) override;
    void paintGL() override;
    void initializeGL() override;
    void initialize();
    

    public:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram *m_program;
    QOpenGLShader *m_shader;
    QOpenGLTexture *m_texture;

    int m_frame = 0;
    

    };

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

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 2);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);
    
    MyGLWidget widget(nullptr);
    widget.show();
    
    return app.exec();
    

    }

    void MyGLWidget::initializeGL()
    {
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();

    m_program = new QOpenGLShaderProgram(this);
    bool vert = m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    Q_ASSERT(vert = false);
    

    }


  • Lifetime Qt Champion

    Hi,

    Rather than just asserting, you should print what QOpenGLShaderProgram::log returns in case of failure.



  • Yes, thank you. Good idea, rookie mistake.

    The indication now, from the log, is that I need to add the version # as the first line in my shader code. In previous code using OpenGLWindow, I have not had to do this. I've looked at examples on the web, so have added this as the first line in my shader as follows;

    static const char *vertexShaderSource =
    "#version 460"
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    " col = colAttr;\n"
    " gl_Position = matrix * posAttr;\n"
    "}\n";

    It's now saying that there is a syntax error: unexpected tokens following #version directive.

    Can you help me correct my syntax in the shader?


  • Lifetime Qt Champion

    You are missing a line break after your first line.



  • Yes, thank you, I have tried that, still got errors. Based on your suggestion, I tried again, found that the trick was to add the line break, but not the semicolon, as follows;

    "#version 460\n"

    This is progress. However, I'm now getting another error, as follows;

    ERROR: 3:1: 'attribute' : not available in current GLSL version 12
    ERROR: 3:2: 'attribute' : not available in current GLSL version 12

    It doesn't like the attribute keyword.

    Does this imply that the system is using GLSL1.2? I have verified that my Qt environment is using OpenGL 4.6.0, I assumed that the GLSL version would be of similar vintage.

    Can you help me understand this error and suggest a solution?



  • Success, answered my own question, with help from the Qt folks, thanks!

    It probably seems obvious to you, but I changed my format line to:

    format.setVersion(1, 2);

    On this PC, I have an older video card, 5-10 years old, it's possible that is only capable of running GLSL 1.2.

    I was perplexed that this same code was running in other apps where I'm using QWindow, and QOpenGLWindow classes. When I looked at the other code, I realized that I didn't have the format line in my other code.

    This code also ran without fault when I commented out this line, makes perfect sense.

    So mystery solved. I'm running this on a pc with a newer video card in a few minutes, will add a comment later to let you know if my issue with video cards and OpenGSL 4.6.0 was correct.

    Thank you all for pointing me in the right direction.



  • Running it on the newer pc with more up to date graphic card had no effect. I have the following in my main.cpp file;

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(1, 5);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);
    

    My code works if I set the version to 1.2 or 1.5, anything higher gives me the error that I described before;

    ERROR: 3:1: 'attribute' : not available in current GLSL version 12
    ERROR: 3:2: 'attribute' : not available in current GLSL version 12

    I can make my code work, and I'm happy with that. However, I would like to wait to click 'problem solved' until I can get an explanation of the incompatibility that I'm seeing, related to the OpenGL and the GLSL versions that I am running, and the effects that different graphics cards will have on this.


Log in to reply