I'm working on a Qt project on Windows that heavily uses OpenGL. It was originally configured to use OpenGL version 2.1, and everything worked fine. Recently, I upgraded the OpenGL version in the code to 3.0. Now, the project crashes very early during initialization with the following error:
QML debugging is enabled. Only use this in a safe environment.
ASSERT: "qGuiApp" in file kernel\qopenglcontext.cpp, line 1238
Debug Error!
Program: C:\Qt\5.7\msvc2015_64\bin\Qt5Cored.dll
Module: 5.7.0
File: global\qglobal.cpp
Line: 3063
ASSERT: "qGuiApp" in file kernel\qopenglcontext.cpp, line 1238
... and this is the line that the debugger stops on:
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
In global.cpp, it's failing at the end of this block. Specifically, the line number given in the error message corresponds to the #endif line:
#ifndef QT_NO_EXCEPTIONS
/*
\internal
Allows you to call std::terminate() without including <exception>.
Called internally from QT_TERMINATE_ON_EXCEPTION
*/
Q_NORETURN void qTerminate() Q_DECL_NOTHROW
{
std::terminate();
}
#endif
Looking at qopenglcontext.cpp, line 1238 is actually within a large comment block. Here is the code that directly follows, which is almost certainly the right place based on the error message above (the Q_ASSERT(qGuiApp) line):
QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType()
{
#if defined(QT_OPENGL_DYNAMIC)
Q_ASSERT(qGuiApp);
return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType();
#elif defined(QT_OPENGL_ES_2)
return LibGLES;
#else
return LibGL;
#endif
}
Keep in mind these are standard Qt files and this is code I have never touched.
Here is a summary of what I've tried so far. Of course, none of these worked:
Tried setting my environment variables like the following page suggests: http://doc.qt.io/qt-5/windows-requirements.html. Specifically, I set my QT_OPENGL var to desktop, angle, and then software, and nothing worked.
As the same page suggested, I tried adding the following lines to my .pro file: "LIBS += opengl32.lib" and "LIBS += -lopengl32" (I added one line, tested it, removed it, then added the second line.)
Tried un-setting the QT_OPENGL_DYNAMIC variable.
Downloaded and ran OpenGL Extensions Viewer 4.1 and confirmed that my OpenGL exists and is setup just fine. The Render Test functionality proves that OpenGL is otherwise working on my system.
Also successfully ran the HelloWorld OpenGL example that's built-in to Qt. This ran fine, confirming that Qt is otherwise able to run OpenGL.
I'm out of ideas here. Any suggestions or knowledge would be welcome. Also, if you need more information please ask and I will respond promptly.
EDIT : Here is the beginning of main:
int main(int argc, char* argv[])
{
// setup OpenGL before application initialization
GLFunctions::setupOpenGL();
QApplication app(argc, argv);
....
}
And here is the setup function:
static void setupOpenGL()
{
QSurfaceFormat fmt;
fmt.setDepthBufferSize( 24 );
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL)
{
fmt.setVersion(3, 3);
fmt.setProfile(QSurfaceFormat::CoreProfile);
//fmt.setRenderableType(QSurfaceFormat::OpenGL);
}
else
{
fmt.setVersion(3, 0);
}
}
From the documentation of QOpenGLContext::openGLModuleType():
Note: This function requires that the QGuiApplication instance is already created.
You may set your desired version regardless of the openGLModuleType (remove the check) and check later if you got your requested version or not.
Related
I got stuck with the problem that my application on some PCs loads the processor very heavily, and does not load the video card at all. When I went to figure it out, I came across this article: https://www.qt.io/blog/2017/01/18/opengl-implementation-qt-quick-app-using-today
It describes the method of debugging, and says that it is necessary to set the value of the environment QSG_INFO = 1. Current I do not quite understand where it needs to be done.
To set an environment variable you can use qputenv():
#include <QtGlobal>
int main(int argc, char *argv[]) {
qputenv("QSG_INFO", "1");
QGuiApplication a(argv, argc);
// ...
or you can set when launching the executable:
QSG_INFO=1 ./your_executable
If you are running your application from Qt Creator you can add/overwrite environment variables from the Project tab:
Look at this Qt doc for more info.
I am currently having issues with getting a debug context with Qt 5.8 on Windows.
I am using Qt 5.8 to write a small OpenGL application, using a viewer class declared like this
class GLViewer3DModel : public QOpenGLWidget, protected QOpenGLFunctions
{
//...
};
My main.cppfile uses this code, before QApplication is initialized:
QSurfaceFormat format;
format.setOption(QSurfaceFormat::DebugContext);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
In the 3D viewer's constructor, the QSurfaceFormat::DebugContext option seems to be properly set. However, if I test this again within my initializeGL override, the following code
void GLViewer3DModel::initializeGL()
{
initializeOpenGLFunctions();
QSurfaceFormat fmt = format();
bool hasDebug = fmt.testOption(QSurfaceFormat::DebugContext);
std::cout << "STILL DEBUG? " << hasDebug << std::endl;
}
prints "STILL DEBUG? 0", so for some reason the format has changed.
Can I do anything to make the debug context work? I would love to use QOpenGLDebugLogger to see where something might go wrong.
FWIW, the GL_KHR_debug extension is supported on my system.
Try setting a OpenGL version greater then 4.1 as I think that's when the debug was made core. The default constructed QSurfaceFormat requests GL 2.0 which doesn't support debug. See what you get then.
Also try initialising the logger and see what it spits back at you
I tried to build a program using glfw + glew on Fedora 25.
part of it is:
int main()
{
glfwInit();
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_ANY_PROFILE);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
mainWindow = glfwCreateWindow(1024,768,"NONE",nullptr,nullptr);
if(mainWindow == nullptr)
{
std::cout<<"Creating window ERROR.\n"<<std::endl;
glfwTerminate();
return 1;
}
.....
}
If I use glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); to get the version 3.3, it'll be unable to create window though.
My hardware supports openGL 4.1.
upd: got the answer....
Just uncomment glfwWindowHint(GLFW_CONTEXT_VERSION_*,*) there.
While using core profile with glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE),
the explicit version needs to be requested.
Thanks to the comment of Dietrich Epp.
By the way, can anyone tell me how to get such information?
I have a GUI application written using Qt Widgets. I've added versioning and I'm planning to write an update manager too. In order this to work the update manager must be able to determine the version of my app. I thought of implementing this by running my app with a version switch then parsing it's output. I did a research and I found out that Qt has some kind of built in solution for this.
Here is an example:
#include "mainwindow.h"
#include <QApplication>
#include <QCommandLineParser>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setApplicationVersion("1.0.0");
QCommandLineParser parser;
auto versionOption = parser.addVersionOption();
parser.process(app);
if (parser.isSet(versionOption))
{
MainWindow w;
w.show();
return app.exec();
}
return 0;
}
If I launch this app with a -v or --version command line switch, I get a message box containing the version information.
I need to achieve the same, only the information should be printed to standard output. If the app is launched with the version switch it should only display the version in the console then close.
How could I print the version information to the standard console output with a GUI app?
As we cleared some points in comments let's move on. ;)
Take a look at the documentation (http://doc.qt.io/qt-5/qapplication.html#details). In the detail section you see a sane way how to properly parse and handle command line options.
And here (https://stackoverflow.com/a/3886128/6385043) you can see a possibility for writing to standard output. Notice the QDebug caveat.
In my opinion, stick to the text file. You may generate it during build with qmake using the variable VERSION, which you can also use with QApplication::setApplicationVersion(QString).
I am facing an odd problem with the OpenGL function glGenBuffers().
I'm writing a fairly simple application in which I use a VBO declared in the following way:
#include <QGLFunctions>
#include <QGLWidget>
class MyClass : public QGLWidget, protected QGLFunctions {
GLuint vertexBufferObject;
// ...
GLuint makeBufferList(void);
}
GLuint MyClass::makeBufferList(void) {
vertexBufferObject = 0;
glGenBuffers(1, &vertexBufferObject); // <-- Here it crashes
// ... load data and render
return vertexBufferList;
}
MyClass::MyClass(QWidget* parent)
: QGLWidget(parent),
vertexBufferObject(0)
{
QGLContext* context = new QGLContext(this->format());
initializeGLFunctions(context);
glInit();
}
MyClass::~MyClass() {
glDeleteBuffers(1, &vertexBufferObject);
}
This all works perfectly fine in the Debug Build. The data is rendered nicely and all and the programme finishes correctly in the end.
However, in Release Build, the glGenBuffers() crashes the programme. It doesn't just return 0 or do nothing, it crashes right at the function call. But since the problem only occurs in Release mode, I can't use the debugger to find out what's going wrong.
I'm working on a Windows 7 system and developing in Qt 4.8.1. The compiler is the MSVC 2010 (Qt SDK) compiler.
Does anyone have any suggestions that I might try?
// Edit:
Maybe useful to know: I tried to compile exactly the same code on a Mac, using the GCC (Qt SDK) compiler, and both the Debug and Release Build work perfectly fine. But on Windows 7, the problem persists.
Found the the trouble (thanks to #MahmoudFayez): the problem comes from a bug in the Qt API, which makes the glGenBuffers() function (and possibly others as well) crash. The question is directly equivalent to the issue discussed here:
Unhandled Exception using glGenBuffer on Release mode only - QT
http://qt-project.org/forums/viewthread/12794
The solution is relatively simple although not very elegant: use GLEW instead of QGLFunctions. I fixed my problem in the following way:
#include "glew.h"
#include <QGLWidget>
class MyClass : public QGLWidget {
// ...same as the above
}
MyClass::MyClass(QWidget* parent)
: QGLWidget(parent),
vertexBufferObject(0)
{
makeCurrent();
glewInit();
}
This solved everything. A disadvantage is that this involves using an extra external dependency, whereas using Qt is all about being as compatible as possible, with as few external dependencies as you possibly can. However, it seems that we need to wait until Qt 5.0 is released before this bug may be fixed.
As a final comment: I have not been able to figure out which part in this bug makes only the Release Build that crashes, but not the Debug mode.