Setting QSurfaceFormat has no effect - c++

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

Related

Get context used by Qt/QML 5.X in WebAssembly build

Lately I've been trying to build a Qt/QML WebAssembly using Qt 5.15.2 ( compiled with -opengl es2 ) and Emscripten 1.39.7 with C++ on Windows.
This works as intended. I'm using a simple QML ApplicationWindow and it displays
just fine. From this point I assume that if QML is able to draw something, there must be
a context associated with it.
The next step for me is to grab the said context used by Qt to draw the QML Scene Graph.
I then proceed to create a simple QQuickItem of my own to test that.
From what I gathered from examples all around, I set this item handleWindowChanged signal to connect the beforeSynchronizing of the new Window in charge of the said item.
Long story short, I think I am now able to query whatever is at hand for the current context, the first thing I try is to get the the current display, context and surface like so :
EGLDisplay display = eglGetCurrentDisplay();
EGLContext context = eglGetCurrentContext();
EGLSurface surface = eglGetCurrentSurface (EGL_DRAW);
But to no avail, they all return null pointers.
I do not know much about Qt WebGL implementation, so at this point I think that perhaps I must query those by other means.
QOpenGLContext
I stumble upon QOpenGLContext which I found can be retrieved from my Window ( QQuickWindow ) for instance, so in my custom item :
QOpenGLContext* qtcontext = this->window()->openglContext();
qDebug() << "openGlModuleType : " << qtcontext->openGLModuleType();
qDebug() << "openGlModuleHandle : " << qtcontext->openGLModuleHandle();
qDebug() << "shared context openGlModuleHandle ? : " << qtcontext->shareContext()->openGLModuleHandle();
Output :
openGlModuleType : 1
openGlModuleHandle : 0x0
shared context openGlModuleHandle ? : 0x0
From this I gather that the context is of type QOpenGLContext::LibGLES ( OpenGL ES 2.0 or higher ) but can't retrieve the handle apparently either way ( own or shared one ).
QEGLNativeContext
Then, I tried another shot at QEGLNativeContext which can be made available by using the
private header ( QtPlatformHeaders/QEGLNativeContext ), only to find that nativeHandle was also returning a null value :
if(qtcontext->nativeHandle() == QVariant()) qDebug() << "null native handle";
QEGLNativeContext qteglcontext = qvariant_cast<QEGLNativeContext>(qtcontext->nativeHandle());
Emscripten
I found out that I can query the WebGL current context by Emscripten too :
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE emcontext = emscripten_webgl_get_current_context();
This seems to return a non-null value, yet I found no way to retrieve the context, display or surface handle from this.
My goal here is to retrieve a valid EGLDisplay, EGLContext and EGLSurface.
I am not really familiar with WebGL, OpenGL ES, so I think I must be doing wrong calls or simply missing the point here.
Can someone share their experience on this matter ? Or point me in the right direction ?
That'd be nice.
Have a good day all.

OpenGL 3.0 Not working with Qt on Windows

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.

opengl on Linux : unable to use a correct version

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?

glGenBuffers crashes in Release Build

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.

Problem with Gtk::TextView::modify_font when moving from GTKMM 2.4 to GTK3.0

I have an application that uses gtkmm 2.4 which has worked fine until I recently changed over to gtkmm 3.0. I am having a problem with g++ (version 4.6.1) where it keeps spitting out the error "error: ‘class Gtk::TextView’ has no member named ‘modify_font’". This isn't the case when I revert my build includes back to gtkmm 2.4 (by changing pkg-config gtkmm-3.0 --cflags --libs back to gtkmm-2.4).
I followed the headers back (from within code::blocks) and the function header is definitely there. It doesn't look like Gtk::Widget::modify_font was depreciated either.
An example of what my class hierarchy looks like in respect to that Gtk::TextView:
// The parent of the offending TextView
class popupWindow : public Gtk::Window
{
public:
popupWindow();
private:
Gtk::TextView theView;
Gtk::ScrolledWindow scrollView;
Gtk::VBox layoutBox;
Glib::RefPtr<Gtk::TextBuffer> textBuffer;
};
// The main window class
class mainWindow : public Gtk::Window
{
private:
popupWindow foo;
};
// Part of the header where I try and set the modified font
popupWindow::popupwindow() : layoutBox(false, 8)
{
// Modify the font styling of the TextView
{
Pango::FontDescription fdesc;
fdesc.set_family("monospace");
fdesc.set_size(10 * PANGO_SCALE);
theView.modify_font(fdesc);
}
// Make a new text buffer
textBuffer = Gtk::TextBuffer::create();
add(layoutBox);
layoutBox.pack_start(scrollView);
scrollView.add(theView);
theView.set_buffer(textBuffer);
}
gtkmm 3.0 has override_font() instead of modify_font().
The documentation is indeed somewhat lacking on the details of what has changed in 3.0, and some symbols were renamed without being deprecated in 2.4. I am sure the gtkmm developers would be interested in some help getting the documentation in a better shape, if you have time to help out with that.