QT for OpenglEs on Desktop - qt

I have an existing project which uses openglEs library (libGLESv2.lib) on DESKTOP platform.
Now I want to use QT as its user interface by using QGLwidget. However after calling any OpenGL function in QGLwidget::initializeGL function I get Access violation executing location 0x00000000 error at the code below,
void MyGLWidget::initializeGL()
{
if (!context()->create())
throw std::exception("no context :)");
context()->makeCurrent();
glViewport(0, 0, 640, 480);
}
If I also include the library opengl32.lib then glviewport function works but when I hit to glGenFramebuffers then I get the same error.
Could you please let me know how can I configure my project to use QT with opengles on desktop platform.

If I also include the library opengl32.lib then glviewport function works but when I hit to glGenFramebuffers then I get the same error.
glViewport is a OpenGL function found in every OpenGL version and profile since version 1. As such it's immediately available simply by linking against the basic OpenGL interface library.
glGenFramebuffers is a function introduced only with OpenGL-3 (OpenGL-ES 2, BTW, OpenGL-ES is not natively supported on Windows) and before you can use it, you have to
check that it is actually supported
load the OpenGL context dependent function pointer at runtime into the variable symbol you're actually calling
Failing to do the second step will give you the error you encounter. Failing to do the first step you try to load it, but loading may fail leading to the same result as if you didn't do (2) at all.
Qt provides all the function loading checks and executions for you, so I suggest you use it: http://doc.qt.io/qt-4.8/qglfunctions.html
It's not perfect, but it gets the job done.
Update (from comments)
Most likely you already have some OpenGL loader library in your project, that actually resolves everything, but before using Qt you did properly initialize it. Now using Qt you've got a mix of statically resolved symbols through opengl32.lib and symbols provided by that loader, yet the loader is not initialized. Look through the code as it was before integrating Qt and look for some initializing call (called after creating the OpenGL context/window but before doing any OpenGL work).
My best guest would be, that the EGL bindings you use also implement the OpenGL-ES wrapper/loader. As I already explained, Windows doesn't natively support OpenGL-ES (only regular OpenGL) and some kind of compatibility layer is required. It is most likely this layer that's getting in your way now. The good news is, that since you're on Windows you can use regular native OpenGL-3 instead; for the most part OpenGL-ES is a subset of OpenGL-3. You'll still need to runtime load GL-3 functions, but as already said, Qt can do that for you.
What to do:
Replace all occurrences of #include <EGL/egl.h> with #include <GL/gl.h> – that should get rid of the symbol shadowing.
Next, for all classes in which use of OpenGL functions is made, add an inheritance of QGLFunctions so that in the classes' namespaces the dynamically loaded functions are used.
Note that every class that inherits QGLFunctions must be instanced only when the target OpenGL context is made current OR you call initializeFunctions on the instances from QGLWidget::initializeGL (or its derivatives). you have to do the function initialization once for each instance of the class inheriting QGLFunctions and the initialization function must be called when the OpenGL context that's to be used is currently active. Like I said, Qt's QGLFunctions is not perfect; if it were it would do the necessary function pointer loading on demand, cache the result and in case of a OpenGL context switch automatically reinitialize.

Related

Qt use of Class and CLassPrivate

When examining classes written by Qt, I discover many contain a class called "Class", and another called "ClassPrivate". For example QFile contains QFile and QFilePrivate, QIODevice contains QIODevice and QIODevicePrivate.
What is the purpose of this design?
This is a common design pattern called private implementation, or pimpl for short. Qt actually calls it d/q pointer, but it is the same thing.
The Q_D and Q_Q macros are part of a design pattern called the d-pointer (also called the opaque pointer) where the implementation details of a library may be hidden from its users and changes to the implementation can be made to a library without breaking binary compatibility.
The main reason for this in binary compatibility. Qt, unlike many other projects like boost, has had the guarantee of API (source) and ABI (binary) compatibility for the same major version.
So, the API and ABI would not break e.g. inside the Qt 5.x series. They would have to change the major version to break any of this.
Now, the private implementation really helps with this as the implementation details are no longer in the publicly available header file.
They can add further private members (method or variable) in the private implementation while the public interface would still online contain a private implementation pointer.
This makes the public interface completely opaque allowing flexibility in changing the implementation details without having to worry about the public interface.
Here is an example they give:
class Widget
{
// ...
private:
Rect m_geometry;
String m_stylesheet; // NEW in WidgetLib 1.1
};
class Label : public Widget
{
public:
// ...
String text() const
{
return m_text;
}
private:
String m_text;
};
This would break the client code using Widget causing a crash. However, if you hide the implementation details of the Widget class behind a private pointer, you can do anything with it since it is hidden. So, in the above example, you can add "m_stylesheet" without any risks and the client code using Label will not crash.
In case you wonder why binary compatibility is such a big deal: Qt has been a popular framework used by many applications, some really big. It would be a major pain in the neck to upgrade the Qt dependency for them if it did not offer binary compatibility.
When designing libraries like Qt, it is desirable that applications that dynamically link to Qt continue to run without recompiling even after the Qt library is upgraded/replaced with another version. For example, if your application CuteApp was based on Qt 4.5, you should be able to upgrade the Qt libraries (on Windows shipped with the application, on Linux often comes from package manager automatically!) from version 4.5 to Qt 4.6 and your CuteApp that was built with Qt 4.5 should still be able to run.
Basically, when you upgrade Qt in this way for your application, you can just drop in the new version without even having to recompile your application. And the features of your application will just keep working as before. This is great because you do not need to send a new version of your application to the customers. They can just upgrade Qt on their side and benefit from performance improvements in Qt or bug fixes indeed, etc.
And as a matter of convention, these private implementation are written in Qt inside files with the _p.h suffix.
You can also refer to this page for further binary compatibility examples.
In Qt 4.8, we see this structure please look at this doc
But in Qt6 we don't have QFilePrivate or ClassPrivate classes. look at this
If you see in Qt 4.8 Structure of classes has one QObjectData and one QObject
for more detail, you can compare this source which was for Qt 4.8 and now the new version of QObject class.
QFile inherits QObject and QFilePrivate inherits QObjectData
What is the purpose of this design?
I guess they want to provide very strong encapsulationYou cannot access the d pointer as a user of the API, which is the whole point of encapsulation.
d_ptr is a pointer in QObject class in Qt 4.8
Look at D-Pointer document.
The trick is to keep the size of all public classes of a library
constant by only storing a single pointer. This pointer points to a
private/internal data structure that contains all the data. The size
of this internal structure can shrink or grow without having any
side-effect on the application because the pointer is accessed only in
the library code and from the application's point of view the size of
the object never changes - it's always the size of the pointer. This
pointer is called the d-pointer.
The spirit of this pattern is outlined in the code below (all code in
this article doesn't have destructors, of course you should add them
in real code).

QML Module not found with registered types

I have the following Issue:
In main.qml I get these errors. Although I can use these types perfectly in the code. It looks like it is just an intellisense issue.
These types are registered in main.cpp:
Thse classes are defined in the include folder:
My folder structure looks like this:
Do I have to modify QML_IMPORT_PATH in the pro file? I added src and include folder but it does not work:
QML_IMPORT_PATH += src
QML_IMPORT_PATH += include
The code itself runs fine. It is just an Intellisense issue.
I assume this is simply a Qt Creator bug. Take a look at this one. qmlRegisterSingletonInstance was added to the Qt library in version Qt 5.14. Even though Qt Creator 4.13.3 was built with Qt 5.15.2, the QML code model it uses has apparently still not been updated.
You need to run this code. QtCreator is notorious for flagging errors that don't exist or won't exist. It flags header files for .ui files because you haven't run a build yet so they haven't been generated. Many developers paint their UI files then do a fake build just to generate those files so QtCreator shuts up.
The other thing you need to do is provide the full source code for one of those classes. (I will assume they all have the same issue.)
The example Qt gives here isn't a good one. You should never be able to "new" a Singleton. The constructor should be protected and the Instance() method should construct one and only one if the internal pointer is null.
Do you actually have a method named get() in each of those classes? Does it actually return a pointer? Many return a reference, that is why I'm asking. If we overlook the glaring error of being able to "new" a Singleton, there is one good thing in this example.
QScopedPointer<SingletonTypeExample> example(new SingletonTypeExample);
They used a QScopedPointer to the class.
qmlRegisterSingletonInstance("Qt.example.qobjectSingleton", 1, 0, "MyApi", example.get());
Once you actually build you will have all of the MOC information where it needs to be. This may well make QtCreator happy. Honestly, I've stopped looking at what QtCreator flags anymore because there are so many false alarms.

Using 'raw' OpenGLES2.0-3.0 API in Qt

I have the following situation.I have a renderer based on OpenGLES 2.0-3.0 APIs.I need to embed it into Qt based desktop widget app.I have read about Qt GL wrappers ,which is one way to use GL ES API in Qt App.But in my case I cannot afford rewriting the whole engine rendering code to use Qt's GL wrappers not only because of the scope, but mostly because of portability issues.So I tried to include GL/GLES3.0/gl3.h headers which are exposed in Qt SDK. Doing this I am getting all sort of header collision errors, for example like this one:
D:\Qt\5.8\msvc2015\include\QtANGLE\GLES3\gl3.h:73: error: C2371:
'GLsizeiptr': redefinition; different basic types
So how can I use just raw OpenGL ES API in Qt?
For Desktop OpenGL I know I should build the SDK with desktop opengl flag on,and then use some GL loader lib like GLEW to init all the GL func pointers.Does it mean I must do something similar for GLES? For example ,building the SDK without ANGLE,then link with ANGLE lib explicitly?
I have asked this question also on Qt's forums.Received no answer.
UPDATE:
I examined some Qt headers to see where the above mentioned collision happens.So Qt has qopengl.h header which declares GL functions and types.But it also has ANGLE's gl headers,which I try to include and which declare the same stuff.So this causes the collision.I don't understand why they allow both headers into the SDK.How to get rid of qopengl.h and run with ANGLE headers only?

Livereload after save but keep some objects

Livereload for development purposes: after save the application should reload the GUI entirely.
But there are some C++ objects (used in QML code) that should stay and find themselves in the new version of the GUI.
Possible approach is to add to such object a string property that will be the same in the newely-loaded QML code, so it'll attach to that. Obviously, the object has two parts: the QObject and Qt-independent implementation.
There is a problem with that: the other bindings need such object to be already attached. These signals/properties mustn't arrive earlier.
I'm thinking about setting that 'persist' property in the Component.onCompleted, so it'll be like atomic with the C++ constructor. Will it work? Other suggestions? How do you do it?

How can I write a shared library with Qt that wraps another library?

I'm trying to create a Qt shared library that wraps a lower level C library, meaning that I don't want that C library's header file to be accessed by the calling code that links to the library.
I'm following the steps here, which seem to be straightforward. I've constructed a SUBDIRS project in QtCreator. The library project builds fine, all classes and C functions are marked with the macro that expands to Q_DECL_EXPORT. The library defines a some headers that I want to include in the app project. The problem here is that when I include one of those headers, the chain is followed down to the C library header that is included, and at which point the application project fails to build since it can't find that header.
Qt's documentation specifically points out this issue, but is kind of vague about how to solve it.
#include <footronics/device.h>
class MyDevice {
private:
FOOTRONICS_DEVICE_HANDLE handle;
};
When deploying the library, there should be no dependency to the internal headers footronics/device.h or ui_widget.h.
So, how can I avoid the headers that I'm including from the library, from implicitly including the headers from the C library that I'm wrapping?
If you only use pointers or references to classes of the shared library you can use Forward Declarations:
class FooTronicsDevice;
class MyDevice {
private:
FooTronicsDevice* _device;
}
The compiler doesn't need to know the structure of the class in order to define a pointer (or a reference).
If this isn't possible, you can use the Pointer to Implementation idiom which is suggested in the Qt Documentation.
This basically means you separate the implementation from your public interface.

Resources