We're trying to port our program to Qt 5.4 -opengl dynamic implementation.
Before Qt 5.4, we used separate Desktop OpenGL/DX9-ANGLE builds and ifdefs like this:
#ifdef USE_GLES
binf = new QOpenGLExtension_OES_get_program_binary();
binf->initializeOpenGLFunctions();
#else
bingl = new QOpenGLExtension_ARB_get_program_binary();
bingl->initializeOpenGLFunctions();
#endif
USE_GLES is defined in my .pro (qmake) file, based on opengl implementation set on build Qt.
For -opengl dynamic, QOpenGLExtension_OES_get_program_binary extension is not available even if Qt::AA_UseOpenGLES is used, because it hides under #ifdef in QOpenGLExtensions.h
What should we do? Re-implement all ARB/OES extensions in our code (i.e. declare entry points and do function resolve on runtime, depending of available extensions list)? Is this problem already resolved by the Qt team?
Related
I'm building a Qt project using g++ and debugging with gdb. Recently, I noticed that class info about QObject and all Qt types that derive from it, seem to be absent from my debug symbols. For example, the gdb command ptype QObject results in No symbol "QObject" in current context. Similarly I can't call methods, examine the d_ptr of an instance, or downcast a derived pointer to QObject* inside the debugger. info types does not list any contents from qobject.h.
For derived classes of QObject defined in my own code, I can see my own members just fine but where the base class is listed, it just says <QObject> = {<No data fields>}
Other Qt classes that are declared in public headers, for example QString, are present in the debug symbols. I can't see anything about the declaration of QObject that would make it different.
I've got a minimalist project that I've been using to examine this problem:
//main.cpp
#include <iostream>
#include <QObject>
int main()
{
QObject* spiff = new QObject();
spiff->setObjectName("Foo");
std::cout << qPrintable(spiff->objectName()) << std::endl;
return 0;
}
#project.pro
QT -= gui
CONFIG += debug
SOURCES += main.cpp
Nothing here seems squirrely to me. There are no build errors, and the code executes quite as expected.
This seems to be unaffected by debug level or optimization flags, any debug symbol format, whether I use g++ vs. clang++ or gdb vs lldb, distro (tried on Arch, Ubuntu, and minGW-w64), or whether pretty-printing is enabled.
I've had a hard time finding any info about gdb's features for examining classes (which makes sense: why would you use a debugger to examine static code) but since this is preventing me from calling methods, it's a major inconvenience. Nothing I've found seems to indicate a reason only some classes would be omitted from debug symbols, or what could be peculiar to Qt about this.
Edit: I had mistakenly believed I was linking against a version of Qt that had debug symbols when I was actually still using the release build. Now, the debugger does recognize QObject, but the question still remains to me of why is QObject different in this regard from other Qt classes like QString and QVariant?
Qt libraries don't ship with debug symbols
Qt libraries are built-in release, and don't have debug symbols. When building your application in Debug, only your application's code has debug symbols, but you still link to the same Qt libraries. This means you need to build Qt libraries with Debug symbols!
Build Qt from source takes some time, but will let you debug or step-in Qt (and QObject) code. Note that Meta object code moced from your classes (from moc_<yourclass>.cpp files) can be debugged without a needing a debug version of Qt, because this is compiled as part of your application.
When building Qt, you can add the -force-debug-info flag when invoking configure command to add debug symbols. If using Qt Creator, you will then have to add this new version of Qt in Qt Creator, and create a new kit for it.
The official documentation to build Qt from sources can be found at https://doc.qt.io/qt-5/build-sources.html
You can also have a look at the QObject class implementation only, conveniently hosted there: https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qobject.cpp.html
As I know, CUDA supports C and C++. But I can't' use C++ in my kernel.
I try a simple example like this
__global__ void simple(){
cout<<"abc";
}
That is error. But if I change to printf("abc"); it is right.
Can you explain for me? Thank you very much!
From CUDA 7.5 nvidia slides:
C++11 Supported features:
auto
lambdas
std::initializer_list
variadic templates
static_asserts
constexpr
rvalue references
range based for loops
C++ Not supported features
thread_local
Standard libraries: std::*
std::cout is defined in the C++ standard library which is not supported by CUDA. Use C printf
From CUDA 6.5, the ‘compute_11′, ‘compute_12′, ‘compute_13′, ‘sm_11′, ‘sm_12′, and ‘sm_13′ architectures are deprecated. So nvcc will compile by default to CC 2.0 enabling printf support.
More info here and here
CUDA doesn't link the libraries & header files that are required to use the cout function. However, you can enable the use of printf()
This answer explains the process which enables this feature:
printing from cuda kernels
quoted here for easier access:
To enable use of plain printf() on devices of Compute Capability >= 2.0, it's important to compile for CC of at least CC 2.0 and disable the default, which includes a build for CC 1.0.
Right-click the .cu file in your project, select Properties, select Configuration Properties | CUDA C/C++ | Device. Click on the Code Generation line, click the triangle, select Edit. In the Code Generation dialog box, uncheck Inherit from parent or project defaults, type compute_20,sm_20 in the top window, click OK.
I want to make sure that my application conforms to OpenGL 2.1.
How can I check this?
Because my computer supports GL4.4, even if I use, for example, glGenVertexArrays(), it will work successfully. But glGenVertexArrays() is only available with GL3+.
So, I want to verify that my app only uses GL2.1 functionality.
One way is to run it on my old PC that support only GL2.1, but I'm looking for an easier way.
If you find an extension loader that supports generating version specific headers, as described by #datenwolf, that's probably your easiest solution. There's another options you can try if necessary.
The official OpenGL headers you can find at https://www.opengl.org/registry contain the definitions grouped by version, and enclosed in preprocessor conditions. The layout looks like this:
...
#ifndef GL_VERSION_2_1
#define GL_VERSION_2_1 1
// GL 2.1 definitions
#endif
#ifndef GL_VERSION_3_0
#define GL_VERSION_3_0 1
// GL 3.0 definitions
#endif
#ifndef GL_VERSION_3_1
#define GL_VERSION_3_1 1
// GL 3.1 definitions
#endif
...
You should be able to include the official header at least for a version test. If you disable the versions you do not want to use by defining the corresponding pre-processor symbol, you will get compile errors if you are trying to use features from those versions. For example for GL 2.1:
#define GL_VERSION_3_0 1
#define GL_VERSION_3_1 1
#define GL_VERSION_3_2 1
#define GL_VERSION_3_3 1
#define GL_VERSION_4_0 1
#define GL_VERSION_4_1 1
#define GL_VERSION_4_2 1
#define GL_VERSION_4_3 1
#define GL_VERSION_4_4 1
#define GL_VERSION_4_5 1
#include <GL/glext.h>
// your code
Try https://github.com/cginternals/glbinding. It's an OpenGL wrapper library which supports exactly what you ask for:
Feature-Centered Header Design
The OpenGL API is iteratively developed and released in versions,
internally (for the API specification) named features. The latest
feature/version of OpenGL is 4.5. The previous version are 1.0, 1.1,
1.2, 1.3, 1.4, 1.5, 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0, 4.1, 4.2, 4.3, and 4.4. OpenGL uses a deprecation model for removing outdated parts
of its API which results in compatibility (with deprecated API) and
core (without deprecated API) usage that is manifested in the targeted
OpenGL context. On top of that, new API concepts are suggested as
extensions (often vendor specific) that might be integrated into
future versions. All this results in many possible specific
manifestations of the OpenGL API you can use in your program.
One tough task is to adhere to one agreed set of functions in your own
OpenGL program (e.g., OpenGL 3.2 Core if you want to develop for every
Windows, macOS, and Linux released in the last 4 years). glbinding
facilitates this by providing per-feature headers by means of
well-defined/generated subsets of the OpenGL API.
All-Features OpenGL Headers
If you do not use per-feature headers the OpenGL program can look like
this:
#include <glbinding/gl/gl.h>
// draw code
gl::glClear(gl::GL_COLOR_BUFFER_BIT | gl::GL_DEPTH_BUFFER_BIT);
gl::glUniform1i(u_numcubes, m_numcubes);
gl::glDrawElementsInstanced(gl::GL_TRIANGLES, 18, gl::GL_UNSIGNED_BYTE, 0, m_numcubes * m_numcubes);
Single-Feature OpenGL Headers
When developing your code on Windows with latest drivers installed,
the code above is likely to compile and run. But if you want to port
it to systems with less mature driver support (e.g., macOS or Linux
using open source drivers), you may wonder if glDrawElementsInstanced
is available. In this case, just switch to per-feature headers of
glbinding and choose the OpenGL 3.2 Core headers (as you know that at
least this version is available on all target platforms):
#include <glbinding/gl32core/gl.h>
// draw code
gl32core::glClear(gl32core::GL_COLOR_BUFFER_BIT | gl32core::GL_DEPTH_BUFFER_BIT);
gl32core::glUniform1i(u_numcubes, m_numcubes);
gl32core::glDrawElementsInstanced(gl32core::GL_TRIANGLES, 18, gl32core::GL_UNSIGNED_BYTE, 0, m_numcubes * m_numcubes);
If the code compiles than you can be sure it is OpenGL 3.2 Core
compliant. Using functions that are not yet available or relying on
deprecated functionality is prevented.
You can compile it in an environment in which only the OpenGL-2.1 symbols are available. Depending on which extension wrapper / loader you use this can be easy or hard.
For example if you use the glloadgen OpenGL loader generator you can generate a header file and compilation unit that will cover only exactly the OpenGL-2.1 symbols and tokens. If you then compile your project using this, the compiler will error out on anything that's not covered.
I have a C++ application using GTKmm version 3.
From one version of the library to another, some method definition change so I would like to handle them in order to allow my sources to compile with a previous and actual version of GTKmm.
When I have written a kernel module, I did the same thing using conditional operators like the following:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
// Something is done when kernel version is 3.6 or higher
#else
// Something else is done for older versions
#endif
So the question is: is this possible in C++ and GTKMM ?
Yes - gtkmm has the defines GTKMM_MAJOR_VERSION, GTKMM_MINOR_VERSION, and GTKMM_MICRO_VERSION.
I have problems with including QArray module to my qt project. I include it like this:
#include < QArray >
and IDE send me response: file or catalog couldn't be found (I translate it for myself - because I have other language compiler - so in english compiler resulting info might be slightly different).
I know that this might be connected with not adding proper value to .pro file, but I cannot find anywhere what should I add in it. (Like QT += core).
Which version of Qt are you using?
There is no QArray in recent Qt versions. Use QVector instead.
QArray is deprecated migrating from Qt2 to Qt3. And changed to QMemArray.
Also, QMemArray is deprecated from Qt3 to Qt4. Read this :
In Qt 3, the QMemArray class is used as a simple array container for
simple data types. This class is deprecated in Qt 4 in favor of the
QVector...