我发现QGLShaderProgram始终无法编译任何着色器并且不提供错误日志。以下是症状:
我可以使用glCompileShader
编译着色器而没有问题。但是,我第一次尝试以这种方式编译在 QGLShaderProgram失败后,失败并出现此错误日志:
错误:错误(#270)内部错误:符号表级别错误
错误:0:2:错误(#232)函数内部不能发生函数声明:
主要
错误:错误(#273)2编译错误。没有生成代码
在一次失败之后,下次我尝试使用glCompileShader
进行编译时工作正常。
自从Qt 4.8升级到5.2后,问题才出现。这台机器上没有其他任何改变。
以下是我的测试代码,说明了问题:
的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++;
}
在其他地方,我已经使用QGLWidget进行了测试,并在使用GLEW而不是QOpenGLFunctions的项目上进行了测试,结果完全相同。
我链接的Qt版本是使用以下配置构建的:
configure -developer-build -opensource -nomake examples -nomake tests -mp -opengl desktop -icu -confirm-license
有什么建议吗?或者我只是将其作为错误报告发送出去?
回应佩佩的评论:
1)QOpenGLDebugLogger说了什么?
我唯一能从QOpenGLDebugLogger获得的是
QWindowsGLContext::getProcAddress: Unable to resolve 'glGetPointerv'
初始化时会打印出来(而不是作为调试事件触发,而只是控制台)。即使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之间的错误。
我想我不太可能找到解决方案,所以放弃。感谢您的所有投入!