自升级到Qt5以来,QGLShaderProgram将不会编译任何着色器

Tim*_* MB 5 c++ opengl shader qt qt5

我发现QGLShaderProgram始终无法编译任何着色器,并且没有提供错误日志。以下是症状:

  • QGLShaderProgram报告它编译失败,但是产生了一个空的错误日志。如果我尝试绑定着色器,则会引发异常。
  • 我可以glCompileShader毫无问题地编译着色器。但是,我第一次尝试以这种方式 QGLShaderProgram失败进行编译时,失败,并显示以下错误日志:

    错误:错误(#270)内部错误:符号表级别
    错误错误:0:2:错误(#232)函数声明不能​​在函数内部发生:

    错误:错误(#273)2个编译错误。没有生成代码

    在那一次失败之后,下一次我尝试使用进行编译时glCompileShader效果很好。

  • 仅从Qt 4.8升级到5.2后才出现问题。在这台机器上没有其他改变。

  • 我已经在两台PC上进行了测试,一台使用ATI Radeon HD 5700,另一台使用AMD FirePro V7900。该问题仅出现在Radeon PC上。

这是证明问题的我的测试代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

测试

#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();
};
Run Code Online (Sandbox Code Playgroud)

测试文件

#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++;
}
Run Code Online (Sandbox Code Playgroud)

在其他地方,我已经使用QGLWidget进行了测试,并且在使用GLEW而不是QOpenGLFunctions的项目中进行了测试,结果完全相同。

我要链接的Qt版本是使用以下配置构建的:

configure -developer-build -opensource -nomake examples -nomake tests -mp -opengl desktop -icu -confirm-license
Run Code Online (Sandbox Code Playgroud)

有什么建议么?还是将其作为错误报告发送给我?

更新资料

针对peppe的评论:

1)QOpenGLDebugLogger说什么?

我从QOpenGLDebugLogger可以得到的唯一东西是

QWindowsGLContext::getProcAddress: Unable to resolve 'glGetPointerv'
Run Code Online (Sandbox Code Playgroud)

当我初始化它时,它会被打印出来(不是作为调试事件触发,而是只是为了控制台)。即使mContext->hasExtension(QByteArrayLiteral("GL_KHR_debug"))返回true,它也会发生,而我正在第一帧的draw()函数中对其进行初始化。

2)即使QOGLShaders编译成功,您也可以打印它们的编译日志吗?

我无法在任何时候成功编译QOpenGLShader或QGLShader,因此我无法对其进行测试。但是,当使用普通GL函数成功编译时,日志返回空白。

3)您从上下文中获得了哪个GL版本?(使用QSurfaceFormat检查)。

我已经尝试过3.0、3.2、4.2版本,所有结果都相同。

4)在创建上下文和窗口之前,请在上下文和窗口上设置相同的QSurfaceFormat。5)记住要创建()窗口

我现在已经实现了这两个,结果是相同的。

我刚刚在第三台PC上进行了测试,没有问题。因此,正是这台特定的计算机碰巧是在训练营中运行Windows的Mac Pro。在运行最新的ATI驱动程序的任何其他情况下,它绝对没有问题,但我只能得出结论,ATI驱动程序,此计算机的图形芯片和QOpenGLShaderProgram之间存在错误。

我认为我不太可能找到解决方案,所以放弃。感谢您的所有投入!