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.
Related
So I am reading up on some OpenGL and I want to use the QOpenGLWidget for drawing to maybe create some other helpful UI elements later. I am using glad for resolving the function pointers to OpenGL but I have no idea how to use Qt's getProcAddress function!
Inside my QOpenGLWidget subclass' initializeGL() function I have tried:
if(gladLoadGLloader((GLADloadproc) currentContext()->getProcAddress) {}
but that did not work out since Qt's function is overloaded. When I use
if(gladLoadGL()) {}
it doesn't work either. My includes are:
#include <glad\glad.h>
#include "OpenGLViewport.h"
#include <QDebug>
#include <QOpenGLContext>
I have searched Mr. Google and I've had a diligent look through the Qt documentation and found nothing. I want to use GLAD just so my rendering code is not bound to Qt too tightly, in case I want to switch later.
EDIT: I am aiming to use the noninstanced OpenGL functions with Qt (though the documentation recommends otherwise if I recall correctly). Because then I'd be able to seemlessly switch to GLFW for providing a window etc.
Moved solution from question to answer:
ANSWER: So it turns out I just had some things mixed up, this is how I got it to work, in case anyone has the same problem:
add glad.c in your project
add the necessary headers to your include directory
the .cpp file of your QOpenGLWidget subclass should have following components:
// Subclass.cpp
#include <glad/glad.h>
// important, subclass header file after glad!!
// otherwise glad won't "hook"
#include "Subclass.h"
void Subclass::initializeGL()
{
if(gladLoadGL()) initialized = true; // initialized is a class member here
else; // handle errors
}
void Subclass::paintGL()
{
if(initialized); // render here
}
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.
I just want to know more about cross-platfrom programming. I create game in SFML 2.1 and C++. And I have a problem. This code works under Linux, but it doesn't work under Windows (MinGW). There is no error, but nothing is drawn.
Shop::Shop(): shop_texts() {}
//...
void Shop::draw(App* app)
{
app->window.draw(shop_texts.getText("btn_playerskins"));
}
shop_texts returns an sf::Drawable object.
And then in App:
shop.draw(this);
shop_texts exists, because I can check e.g position or text (this object contains sf::Text field). What is difference?
I have been trying to make an asteroids clone using openGL and have gotten totally stuck on a segmentation error I am unsure how to fix. It seems to happen on the usage of the function glGenBuffersARB(). If I comment out the lines using the vertexbuffer, the program compiles and runs fine (but obviously with nothing rendered). I am using the minGW compiler on eclipse with the gdb debugger and trying to use extensions so I can support versions of OpenGL earlier than 1.5.
glGenBuffers(1, &_VertexBufferObject);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, _VertexBufferObject ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB, U8VertexCount*3*sizeof(GLfloat), quad,GL_STATIC_DRAW_ARB );
GLuints are declared as private in a header like this:
GLuint _VertexArrayObject;
GLuint _VertexBufferObject;
int U8VertexStride;
int U8VertexCount;
gdb traces are here: gdb trace
I have found a solution to the problem. It would appear that declaring and using an object was not working the way I had intended. I was declaring the objects as:
CObj Obj;
and calling draw like this:
Obj.Draw();
when I switched to declaring it as a pointer:
CObj * Obj;
and initialising it like this:
Obj = new CObj();
then using:
Obj->Draw();
started to work as i thought it should. I am unsure why this is the case and would appreciate it if anyone is able to clear this up for me.
My MFC application using the "ESRI MapObjects LT2" ActiveX plugin throws an ASSERT at me when closing it.
The error occurs in cmdtarg.cpp:
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect();
ASSERT(m_dwRef <= 1); //<--- Fails because m_dwRef is 3
#endif
m_pModuleState = NULL;
}
I built the (native C++) application with VC9.
When I compile the application with VC6, it behaves nicely.
What could be the reason for this?
That looks like a reference count. Could this "target" be referenced by something else, something that's not releasing it?
You can trace the Addref and Release calls defining _ATL_DEBUG_INTERFACES
from http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx
_ATL_DEBUG_INTERFACES
Define this macro before including any ATL header files to trace all AddRef and Release calls on your components' interfaces to the output window.
Using _ATL_DEBUG_INTERFACES did not yield any additional output...
I defined it on the first line of stdafx.h, directly after #pragma once so I guess this is early enough.
Maybe the reason is how I am using the ActiveX control:
I'm not calling AddRef() or Release() by myself.
The MapObjects Installer comes with sample code with lots of wrapper classes which must have been generated by VC6 or something earlier.
I tried to generate wrapper classes myself with VC9 but there occured errors which I wasn't able to fix.
I use the control by letting one of my windows have a member of type CMap1 (derived from CWnd), which is one of those generated wrapper classes. In CMyWnd::OnCreate() I also call CMap1::Create() and that's it, I'm finished: I can add a layer and the control displays a world map.
I have pretty much no idea what the reference-count stuff is about as I have not added or released any references. At least not knowingly...
The control is pretty old: The .OCX file has the year 2000 in its version information.
It's also not officially supported anymore but I don't have any substitue.
The following solved it for me:
In the window that contains the control, add an OnDestroy() handler:
void CMyWnd::OnDestroy()
{
// Apparently we have to disconnect the (ActiveX) Map control manually
// with this undocumented method.
COleControlSite* pSite = GetOleControlSite(MY_DIALOG_CONTROL_ID);
if(NULL != pSite)
{
pSite->ExternalDisconnect();
}
CWnd::OnDestroy();
}