QGLShaderProgram will not compile any shader since upgrading to Qt5

折月煮酒 提交于 2019-12-10 15:08:53

问题


I am finding that QGLShaderProgram is consistently failing to compile any shader and providing no error log. Here are the symptoms:

  • QGLShaderProgram reports that it failed to compile but produces an empty error log. If I try to bind the shader an exception is thrown.
  • I can compile a shader using glCompileShader without problem. However, the first time I try to compile this way after QGLShaderProgram has failed, fails with this error log:

    ERROR: error(#270) Internal error: Wrong symbol table level
    ERROR: 0:2: error(#232) Function declarations cannot occur inside of functions:
    main
    ERROR: error(#273) 2 compilation errors. No code generated

    Following that one failure, the next time I try to compile using glCompileShader works fine.

  • The problem has arisen only since upgrading from Qt 4.8 to 5.2. Nothing else has changed on this machine.

  • I have tested on two PCs, one with an ATI Radeon HD 5700, the other with an AMD FirePro V7900. The problem only appears on the Radeon PC.

Here is my test code demonstrating the problem:

main.cpp

#include <QApplication>
#include "Test.h"

int main(int argc, char* argv[])
{
    QApplication* app = new QApplication(argc, argv);
    Drawer* drawer = new Drawer;
    return app->exec();
}

Test.h

#pragma once
#include <qobject>
#include <QTimer>
#include <QWindow>
#include <QOpenGLContext>
#include <QOpenGLFunctions>

class Drawer : public QWindow, protected QOpenGLFunctions
{
    Q_OBJECT;

public:
    Drawer();

    QTimer* mTimer;
    QOpenGLContext* mContext;
    int frame;

public Q_SLOTS:
    void draw();
};

Test.cpp

#include "Test.h"
#include <QGLShaderProgram>
#include <iostream>
#include <ostream>

using namespace std;

Drawer::Drawer()
    : mTimer(new QTimer)
    , mContext(new QOpenGLContext)
    , frame(0)
{
    mContext->create();
    setSurfaceType(OpenGLSurface);
    mTimer->setInterval(40);
    connect(mTimer, SIGNAL(timeout()), this, SLOT(draw()));
    mTimer->start();
    show();
}

const char* vertex = "#version 110 \n void main() { gl_Position = gl_Vertex; }";
const char* fragment = "#version 110 \n void main() { gl_FragColor = vec4(0.0,0.0,0.0,0.0); }";

void Drawer::draw()
{
    mContext->makeCurrent(this);
    if (frame==0) {
        initializeOpenGLFunctions();
    }
    // Compile using QGLShaderProgram. This always fails
    if (frame < 5)
    {
        QGLShaderProgram* prog = new QGLShaderProgram;
        bool f = prog->addShaderFromSourceCode(QGLShader::Fragment, fragment);
        cout << "fragment "<<f<<endl;
        bool v = prog->addShaderFromSourceCode(QGLShader::Vertex, vertex);
        cout << "vertex "<<v<<endl;
        bool link = prog->link();
        cout << "link "<<link<<endl;
    }
    // Manual compile using OpenGL direct. This works except for the first time it
    // follows the above block
    {
        GLuint prog = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(prog, 1, &fragment, 0);
        glCompileShader(prog);
        GLint success = 0;
        glGetShaderiv(prog, GL_COMPILE_STATUS, &success);
        GLint logSize = 0;
        glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &logSize);
        GLchar* log = new char[8192];
        glGetShaderInfoLog(prog, 8192, 0, log);
        cout << "manual compile " << success << endl << log << endl;
        delete[] log;
    }
    glClearColor(1,1,0,1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    mContext->swapBuffers(this);
    frame++;
}

Elsewhere, I have tested using QGLWidget, and on a project that uses GLEW instead of QOpenGLFunctions with exactly the same results.

The version of Qt I'm linking against was built with the following configuration:

configure -developer-build -opensource -nomake examples -nomake tests -mp -opengl desktop -icu -confirm-license

Any suggestions? Or shall I just send this in as a bug report?

Update

In response to peppe's comments:

1) What does QOpenGLDebugLogger says?

The only thing I can get from QOpenGLDebugLogger is

QWindowsGLContext::getProcAddress: Unable to resolve 'glGetPointerv'

This is printed when I initialize it (and not as a debug event firing, but just to console). It happens even though mContext->hasExtension(QByteArrayLiteral("GL_KHR_debug")) returns true and I'm initializing it within the first frame's draw() function.

2) Can you print the compile log of the QOGLShaders even if they compile successfully?

I cannot successfully compile QOpenGLShader or QGLShader at any point so I'm not able to test this. However, when compiling successfully using plain GL functions, the log returns blank.

3) Which GL version did you get from the context? (Check with QSurfaceFormat).

I've tried with versions 3.0, 3.2, 4.2, all with the same result.

4) Please set the same QSurfaceFormat on both the context and the window before creating them 5) Remember to create() the window

I've implemented both of these now and the result is the same.

I've just tested on a third PC and that has no issues. So it is this specific computer which, incidentally, happens to be a Mac Pro running Windows in bootcamp. It has had absolutely no trouble in any other context running the latest ATI drivers but I can only really conclude that there is a bug somewhere between the ATI drivers, this computer's graphics chip and QOpenGLShaderProgram.

I think I'm unlikely to find a solution, so giving up. Thank you for all your input!

来源:https://stackoverflow.com/questions/20996146/qglshaderprogram-will-not-compile-any-shader-since-upgrading-to-qt5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!