I am targeting GL Core Profile on Linux. When I directly use the system GL headers like so:
#include <GL/glcorearb.h>
...then everything works as expected, and I can use GL extensions too, e.g. glPushGroupMarkerEXT() calls.
But since I've integrated imgui, I have been forced to go through a GL Loader (I was not able to make imgui work without a loader.)
So I have followed the imgui examples, and now use gl3w.
Now that I go through gl3w, I can no longer use those GL extensions:
src/wld.cpp:373:2: error: use of undeclared identifier 'glPushGroupMarkerEXT'
I looked, but gl3w does not seem to come with a separate header for extension, like glew does: the glxew.h file.
Does this mean that I cannot use glPushGroupMarkerEXT() if I use gl3w as a GL loader?
Ok, so it wasn't mentioned in the README before (it is now, I created a pull rq) but there is a command line option to gl3w's generator script:
gl3w_gen.py --ext
When using the --ext flag, the extensions will be available in the generated GL/glcorearb.h header.
The gl3w packed with the imgui repository was generated without this flag, hence the extensions were not available.
Related
The doc shows I can use QML_ELEMENT macro to create QML types from C++ by adding some variables in qmake's .pro file. But I'm using cmake
Update (Qt 6.2+)
As of Qt 6.2, qt_add_qml_module is a single command for building qml modules that should take care of virtually everything, replacing amongst others the old qt6_qml_type_registration command.
Old answer (Qt 6.0/6.1)
Now that Qt 6.0 is out this is supported, albeit poorly documented. What you need now is:
set_target_properties(foo PROPERTIES
QT_QML_MODULE_VERSION 1.0
QT_QML_MODULE_URI Foo
)
qt6_qml_type_registration(foo)
you can then do in qml:
import Foo
and you'll have access to types that have QML_ELEMENT and friends. Notes:
Two files are created in the build output folder, <project>_qmltyperegistrations.cpp and <project>.qmltypes, if your imports are failing you can look at those to see which types are missing. I found that I needed to do full recompiles sometimes after adding/removing registered types.
Qt examples have been migrated to cmake, so take a look at e.g. Examples/Qt-6.0.0/quick/tableview/gameoflife to see it in action
There are now pro2cmake.py and run_pro2cmake.py files in the Qt sources at Qt/6.0.0/Src/qtbase/util/cmake. They are mentioned on this Readme page, you can find them here, haven't tried it myself.
Edit (Qt 6.x)
This answer was originally posted for Qt 5.15. Now that Qt 6 is available, and if you are using Qt 6, refer to the answer from #Adversus.
Original answer (Qt 5.x)
From what I can see, CONFIG += qmltypes, which is required to use QML_ELEMENT, is not yet supported in CMake by looking at the documentation, even for the master branch.
And the efforts to provide a python .pro to cmake converter are for Qt6, not merged, and not functional as far as I can tell, by testing them from util on the wip/cmake branch (the CMakeLists.txt didn't have relevant information).
You can see that the actual conversion script does test for qmltypes presence in CONFIG, but it doesn't seem to map to anything usable for CMake.
Solution
Instead of using QML_ELEMENT and CONFIG += qmltypes, which is brand new from Qt 5.15 (latest when writing this), and not supported at this time with CMake, use the good old qmlRegisterType from C++:
#include "YouCustomCppClass.h"
int main(int argc, char** argv) {
// Let you import it with "import ModuleName 1.0" on the QML side
qmlRegisterType<YouCustomCppClass>("ModuleName", 1, 0, "YourQmlComponent");
//Create your QML view or engine
}
This won't require anything specific on the project file side, as long as your code/plugin executes qmlRegisterType statement.
You can refer to Qt's documentation, same page as yours, but for Qt 5.14 instead of latest, which describes exactly that: Writting QML extensions for C++ | Qt 5.14
I'm trying to get Flycheck to correctly see where OpenGL is on my Mac, but it can't seem to find it. I've tried adding the following lines to my .clang_complete file, but nothing seems to work. I keep getting the error OpenGL/gl.h could not be found:
-framework OpenGL
-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers
This doesn't happen during compilation, it's just messing up static analysis and compilation by Irony. The directory I listed has gl.h and glu.h in it directly, which is probably why it didn't help to add, but I can't figure out how to get Irony to see the files correctly.
Edit: Using Flycheck for syntax checking, not Irony
Edit: macOS X Framework directory:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/
OpenGL.framework/
Headers/
Modules/
OpenGL.tbd/
Versions/
Well, since no one seems to have an answer on this, I'll post my workaround. By symlinking /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers to /usr/local/include/OpenGL, you can give the checker the file path it wants, fixing the issue. Not the best solution, but a decent workaround nonetheless.
I'm compiling Linux libraries (for Android, using NDK's g++, but I bet my question makes sense for any Linux system). When delivering those libraries to partners, I need to mark them with a version number. I must also be able to access the version number programatically (to show it in an "About" dialog or a GetVersion function for instance).
I first compile the libraries with an unversioned flag (version 0.0) and need to change this version to a real one when I'm done testing just before sending it to the partner. I know it would be easier to modify the source and recompile, but we don't want to do that (because we should then test everything again if we recompile the code, we feel like it would be less error prone, see comments to this post and finally because our development environment works this way: we do this process for Windows binaries: we set a 0.0 resources version string (.rc) and we later change it by using verpatch...we'd like to work with the same kind of process when shipping Linux binaries).
What would be the best strategy here?
To summarize, requirements are:
Compile binaries with "unset" version (0.0 or anything else)
Be able to modify this "unset" version to a specific one without having to recompile the binary (ideally, run a 3rd party tool command, as we do with verpatch under Windows)
Be able to have the library code retrieve it's version information at runtime
If your answer is "rename the .so", then please provide a solution for 3.: how to retrieve version name (i.e.: file name) at runtime.
I was thinking of some solutions but have no idea if they could work and how to achieve them.
Have a version variable (one string or 3 int) in the code and have a way to change it in the binary file later? Using a binary sed...?
Have a version variable within a resource and have a way to change it in the binary file later? (as we do for win32/win64)
Use a field of the .so (like SONAME) dedicated to this and have a tool allowing to change it...and make it accessible from C++ code.
Rename the lib + change SONAME (did not find how this can be achieved)...and find a way to retrieve it from C++ code.
...
Note that we use QtCreator to compile the Android .so files, but they may not rely on Qt. So using Qt resources is not an ideal solution.
I am afraid you started to solve your problem from the end. First of all SONAME is provided at link time as a parameter of linker, so in the beginning you need to find a way to get version from source and pass to the linker. One of the possible solutions - use ident utility and supply a version string in your binary, for example:
const char version[] = "$Revision:1.2$"
this string should appear in binary and ident utility will detect it. Or you can parse source file directly with grep or something alike instead. If there is possibility of conflicts put additional marker, that you can use later to detect this string, for example:
const char version[] = "VERSION_1.2_VERSION"
So you detect version number either from source file or from .o file and just pass it to linker. This should work.
As for debug version to have version 0.0 it is easy - just avoid detection when you build debug and just use 0.0 as version unconditionally.
For 3rd party build system I would recommend to use cmake, but this is just my personal preference. Solution can be easily implemented in standard Makefile as well. I am not sure about qmake though.
Discussion with Slava made me realize that any const char* was actually visible in the binary file and could then be easily patched to anything else.
So here is a nice way to fix my own problem:
Create a library with:
a definition of const char version[] = "VERSIONSTRING:00000.00000.00000.00000"; (we need it long enough as we can later safely modify the binary file content but not extend it...)
a GetVersion function that would clean the version variable above (remove VERSIONSTRING: and useless 0). It would return:
0.0 if version is VERSIONSTRING:00000.00000.00000.00000
2.3 if version is VERSIONSTRING:00002.00003.00000.00000
2.3.40 if version is VERSIONSTRING:00002.00003.00040.00000
...
Compile the library, let's name it mylib.so
Load it from a program, ask its version (call GetVersion), it returns 0.0, no surprise
Create a little program (did it in C++, but could be done in Python or any other languauge) that will:
load a whole binary file content in memory (using std::fstream with std::ios_base::binary)
find VERSIONSTRING:00000.00000.00000.00000 in it
confirms it appears once only (to be sure we don't modify something we did not mean to, that's why I prefix the string with VERSIONSTRING, to make it more unic...)
patch it to VERSIONSTRING:00002.00003.00040.00000 if expected binary number is 2.3.40
save the binary file back from patched content
Patch mylib.so using the above tool (requesting version 2.3 for instance)
Run the same program as step 3., it now reports 2.3!
No recompilation nor linking, you patched the binary version!
I'm quite new to OCaml and to the js_of_ocaml compiler in particular.
Did someone manage to compile the application which uses Jane Street Core with js_of_ocaml? I get lots of "missing primitives" warnings during the compilation, and then when I try to run it with node they turn into an actual exceptions.
I understand that those are primitives which can't be ported from OCaml to JS and that their implementation should depend on the application, but for core there is literally thousands of them, whereas my program only uses output to stdout.
On a side note, I had trouble even compiling a simple "hello world" project, as IO functions weren't implemented in JS. Is there a "standard" JS file somewhere which could be used for this purpose? e.g. replacing caml_ml_output_char with console.log and other things, so that modules can be compiled to something useful without writing any custom javascript?
Yes, it is possible to compile Core_kernel with js_of_ocaml, OCamlPro did a version of Try-OCaml with it. It requires to patch a few of its dependencies (sexplib, ounit, etc.) and to use the latest version of js_of_ocaml from the repository, that includes a bigarray implementation.
as of today, core_kernel version 0.9, it works.
after compile to bytecode.
run js_of_ocaml
js_of_ocaml +weak.js +nat.js +base/runtime.js +core_kernel/runtime.js +bin_prot/runtime.js main.bc
or add the js_of_ocaml in jbuilder directly.
(js_of_ocaml (
(flags (+weak.js +nat.js +base/runtime.js +core_kernel/runtime.js +bin_prot/runtime.js))))
Yeah, missing primitives are the issue when using Core with js_of_ocaml. There is core_kernel library. It is a subset of Core which contains basic functions. UNIX-related functions from core are not included to Core_kernel. If I remember correctly, the main reason for extracting Core_kernel from Core is your issue.
Update.
I have failed. It seems that developers have tried to allow using Core_kernel with js_of_ocaml but without success. It seems that you can't do it now. They are waiting for OCaml namespaces.
I've been using OpenGL extensions on Windows the painful way. Is GLEW the easier way to go? How do I get started with it?
Yes, the OpenGL Extension Wrangler Library (GLEW) is a painless way to use OpenGL extensions on Windows. Here's how to get started on it:
Identify the OpenGL extension and the extension APIs you wish to use. OpenGL extensions are listed in the OpenGL Extension Registry.
Check if your graphic card supports the extensions you wish to use. Download and install the latest drivers and SDKs for your graphics card.
Recent versions of NVIDIA OpenGL SDK ship with GLEW. If you're using this, then you don't need to do some of the following steps.
Download GLEW and unzip it.
Add the GLEW bin path to your Windows PATH environment variable. Alternatively, you can also place the glew32.dll in a directory where Windows picks up its DLLs.
Add the GLEW include path to your compiler's include directory list.
Add the GLEW lib path to your compiler's library directory list.
Instruct your compiler to use glew32.lib during linking. If you're using Visual C++ compilers then one way to do this is by adding the following line to your code:
#pragma comment(lib, "glew32.lib")
Add a #include <GL/glew.h> line to your code. Ensure that this is placed above the includes of other GL header files. (You may actually not need the GL header files includes if you include glew.h.)
Initialize GLEW using glewInit() after you've initialized GLUT or GL. If it fails, then something is wrong with your setup.
if (GLEW_OK != glewInit())
{
// GLEW failed!
exit(1);
}
Check if the extension(s) you wish to use are now available through GLEW. You do this by checking a boolean variable named GLEW_your_extension_name which is exposed by GLEW.
Example:
if (!GLEW_EXT_framebuffer_object)
{
exit(1);
}
That's it! You can now use the OpenGL extension calls in your code just as if they existed naturally for Windows.
Personally I wouldn't use an exit command.
I would throw an exception so you can clear any other initialisation up at the end of the function.
ie:
try
{
// init opengl/directx
// init directaudio
// init directinput
if (GLEW_OK != glewInit())
{
throw std::exception("glewInit failed");
}
}
catch ( const std::exception& ex )
{
// message to screen using ex.what()
// clear up
}
And I agree with OJ - if you want to write tutorials for others, then this is really the wrong place for it. There are already a load of good places for opengl tutorials. Try this one for instance.
I lost some time, but finally I managed to get GLEW working.
I'm using Windows7 (x64), Eclipse CDT and MinGW, and the way is that:
Download MSYS (for MinGW) and rember to have MinGW installed correctly (PATH enviroinment variable set correctly):
http://sourceforge.net/projects/mingw/files/MSYS/Base/msys-core/msys-1.0.10/MSYS-1.0.10.exe/download?use_mirror=freefr&download=
Once MSYS installed, go to:
http://glew.sourceforge.net/
and download the TGZ package, which is intended to use with UNIX systems
Then open the package (you can use 7zip as well) and find the "Makefile".
Open it and with a text editor (Notepad should work fine) find the row which contains "GLEW_DEST" and replace it with something like "GLEW_DEST ?= C:/MinGW"
Now you are ready to go, open MSYS (C:\MinGW\msys\1.0\msys.bat in my case) and in the shell opened, go to the folder where the "Makefile" is.
Then write a simple: "make install" and the work is done (at least for me it worked)
PS: I also copy-pasted glew-1.10.0-win32\glew-1.10.0\bin\Release\Win32 file's into my System32 folder, and in Eclipse CDT I added the library "glew32" in the linker option and added a #include <GL/glew.h> before #include <GL/glut.h>