C++ code with OpenGL on OSX using CGL/NSOpenGL without XCode? - c++

I want to use CGL or NSOpenGL to create an OpenGL window without using XCode (compile with command line gcc). I am developing something that is cross platform, and I'd like to keep the code divergence to a minimum if I can! My codebase is fully C++ at the moment. Is this at all possible? I am new to OSX and I haven't touched objective C. I looked through the developer docs and grabbed some example files. They are all using xcode. I successfully compiled the source and linked with the right framework, but the whole app bundle, xib, and info.plist thing seems a bit over the top.

This is bare-bones as one can get:
// g++ glInfo.cpp -o glInfo.x -framework OpenGL
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl3.h>
#include <stdio.h>
int main(int argc, char **argv)
{
CGLContextObj ctx;
CGLPixelFormatObj pix;
GLint npix;
CGLPixelFormatAttribute attribs[] = {
(CGLPixelFormatAttribute) 0
};
CGLChoosePixelFormat( attribs, &pix, &npix );
CGLCreateContext( pix, NULL, &ctx );
CGLSetCurrentContext( ctx );
printf("Vendor: %s\n", glGetString(GL_VENDOR) );
printf("Renderer: %s\n", glGetString(GL_RENDERER) );
printf("Version: %s\n", glGetString(GL_VERSION) );
printf("GLSL: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
return 0;
}

Both fltk and SDL should have enough AGL/CGL code. I've built and run cmdline GL apps on OS X with fltk-1.3.0. It uses the AGL sub-system however, which is deprecated. SDL uses CGL and NSOpenGL for its Quartz video layer: ./src/video/quartz
Use the obj-c flags for the compiler, if you need to build a src.m, and let the native g++, llvm-g++, clang++, or whatever, take care of the linking. You might need to add -framework CGL -framework OpenGL as well as ApplicationServices and Cocoa. A lot of the answer depends on what you mean by 'code divergence'.

You can build apps without using Xcode, but if you want users who aren't sys admins to use them, you'll need an app bundle (and hence .plist) and (unless it's a game) a user interface beyond what OpenGL offers. You don't need to create a .xib for your UI. You can do it all programmatically, though using .xibs is far easier for most things. Why don't you want to use the tools designed to help you? I'm not saying they're the best, but they beat using only a command-line interface. (Once you have an Xcode project for your app, though, you can build it from the command-line and even automate building it.)

Well, you can do it "by hand" (I used to do it at NeXTStep times), but it is a pain before it works for the first time.
XCode uses makefiles under the hood. You can find and adopt the makefiles in
/Developer/Makefiles
(pre XCode 4.3)
or for XCode 4.3 in
/Applications/Xcode.app/Contents/Developer/Makefiles
Good luck!

For the build system, I recommend CMake/CPack which will help you to keep it cross-platform and to build app bundles. For NSGL, it's possible using Obj-C++, but I don't have any code at hand.

Related

Build ICU for iOS

I need ICU library for iPhone. I have tried to build it from souce, however, I am getting this erros:
clang++ ... /Users/petr/Development/icu-cross-compile-master/icu-60-2/source/tools/pkgdata/pkgdata.cpp
/Users/petr/Development/icu-cross-compile-master/icu-60-2/source/tools/pkgdata/pkgdata.cpp:544:18: error: call to unavailable function 'system': not available on iOS
int result = system(cmd);
^~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.2.sdk/usr/include/stdlib.h:195:6: note: candidate function has been explicitly made unavailable
int system(const char *) __DARWIN_ALIAS_C(system);
sh ${ICU_SOURCE}/configure --host=arm-apple-darwin --with-cross-build=${PREBUILD_DIR} ${PREFIX}
My PREFIX configuration is as:
--enable-extras=yes
--enable-tools=yes
--enable-icuio=yes
--enable-strict=no
--enable-static
--enable-shared=no
--enable-tests=yes
--disable-renaming
--enable-samples=no
--enable-dyload=no
--with-data-packaging=static
Or is there any other way, how to generate libicudata.a? The similar build script works OK for Android, Mac and Win. Only iPhone is problem.
The problem is that system() is deprecated for iOS 11.
I think quick fix for you will be in using Xcode 6, instead of Xcode 9, so you can compile for iOS 7 as a target, where system() wasn't deprecated.
Or, if you really need iOS full compatible solution, you need to re-write ICU source code to use posix spawn functionality instead of system(). Check this answer for more details: How do you use posix_spawn to replace the deprecated 'system' to launch opendiff in Objective-C?
Another solution to successfully build ICU on iOS as a library is to build without tools with the configure flag --build-tools=no. The following is the complete set of configure flags I'm using to build for various platforms, android and ICU included.
--enable-static=yes
--enable-shared=no
--enable-extras=no
--enable-strict=no
--enable-icuio=no
--enable-layout=no
--enable-layoutex=no
--enable-tests=no
--enable-samples=no
--enable-tools=no
--enable-dyload=no
--with-data-packaging=archive
I've just made a makefile which will download the ICU source and create a universal framework for Mac, Catalyst, iOS Simulator and iOS. This can then just be drag-and-dropped into your project.
https://github.com/dbquarrel/icu4c-xcframework
Might help you (though many years late).
My use was to enable the icu tokenizer in sqlite for iOS.

use of undeclared identifier 'MPI' when using C++ syntax for OpenMPI on MacOS

I have my OpenMPI and gcc installed on my MacOS. C syntax for OpenMPI could run perfectly. However, the c++ syntax for OpenMPI are always not recognized. For example, line with void MPI::Init(int &argc, char**&argv); shows error of use of undeclared identifier 'MPI'.
Could anybody give some detailed procedure to fix this problem?
#include "mpi.h"
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
void MPI::Init(int &argc, char**&argv);
// Get the number of processes
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
//int Comm::Get_size() const
// Get the rank of the process
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world from processor %s, rank %d out of %d processors\n",
processor_name, world_rank, world_size);
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
I had the same issue when installing open-mpi using homebrew in Mac OS X (I am a newbie in Mac OS X coming from Debian/Ubuntu Linux). Fortunately, I solved it. As Zulan said, your open-mpi installation was built without C++ bindings. However, I think the best solution is to rebuild it directly from the source code. I downloaded the .tar files directly from its homepage, and if you look closer you will see that the C++ bindings are by default disabled (do the following inside the untar folder):
$ ./configure -help
--enable-mpi-cxx enable C++ MPI bindings (default: disabled)
So, basically I rebuilt open-mpi directly adding that flag, as follow:
$ ./configure --enable-mpi-cxx
Then, just make sure you know where you have installed it (if you used --prefix= or the default) to link it to your makefile properly.
for more information about this issue look here: https://github.com/open-mpi/ompi/issues/3173.
It seems your OpenMPI installation was built without C++ bindings. While OpenMPI still contains the C++ bindings, they actually have been removed from the standard years ago. You will probably have to rebuild OpenMPI to enable the C++ bindings, that depends on how you installed it in the first place.
Since they are not part of the standard, the recommendation is to not the C++ bindings in the first place. Instead the most common recommendation is to use Boost.MPI.
Unfortunately it appears that Boost.MPI is no longer actively developed (last bug closed 2 years ago), and there are some really nasty open issues,
so I cannot recommend Boost.MPI. There are some cool MPI type-traits approaches, but I do not know of a widely accepted / actively developed wrapper.
If you installed OpenMPI using homebrew, you need to first uninstall it:
brew uninstall openmpi
And then reinstall it, enabling C++ bindings:
brew install openmpi --with-cxx-bindings
See brew info openmpi for a full list of options. Note that since you're not using the default build of OpenMPI, brew will need to build it from source instead of using a precompiled bottle so it will take longer than usual to install.

How to use LibVLC with Qt 5

I'm trying to use LibVLC in a Qt 5 program to open a VLC instance and play a video.
The following code comes from https://wiki.videolan.org/LibVLC_Tutorial/
I'm using Linux.
.pro :
TEMPLATE = app
TARGET = projectLoic
INCLUDEPATH += . vlc
QT += widgets
# Input
HEADERS +=
SOURCES += main.cpp
LIBS +=-lvlc
main :
#include <vlc/vlc.h>
#include <QApplication>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
libvlc_instance_t * inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
// Load the VLC engine
inst = libvlc_new(0, NULL);
// Create a new item
m = libvlc_media_new_path (inst, "/home/........mp3");
// Create a media player playing environement
mp = libvlc_media_player_new_from_media (m);
// play the media_player
libvlc_media_player_play (mp);
return app.exec();
}
The compilation is fine. But the program immediatly crashes when I build it (with Qt Creator). Any idea?
Many thanks
Many things could cause this crash. The best is to get VLC source code to trace back the issue. Passing the option '--verbose=2' when initializing libVLC can help as well.
In my case the cause of the crash was due to this bug in the ubuntu package of vlc:
https://bugs.launchpad.net/ubuntu/+source/vlc/+bug/1328466
When calling libvlc_new() vlc modules and their dependent libraries are loaded into memory. The qt module of LibVLC was searching for Qt4 shared objects instead of Qt5 (manually installed).
The solution was to rebuild the module cache which was outdated an pointing to Qt4 binaries. You can reset it on the command line:
sudo /usr/lib/vlc/vlc-cache-gen -f /usr/lib/vlc/plugins/
Or pass to vlc the option:
--reset-plugins-cache
I have never used this library, but Are you using exactly this code?
m = libvlc_media_new_path (inst, "/home/........mp3");
This path may be the problem.
What distribution of Linux are you using?
I ran into this same problem with Qt5 and LibVLC, and the primary cause (Ubuntu 12.04 LTS and 14.04 LTS), was that LibVLC was loading the qt4 interface plugin, which conflicted with Qt5. If you check your call stack, you'll most likely see that at a Qt4 library was being loaded, causing the crash.
If this is the problem, there are only 3 options (tested with LibVLC 2.2 and Qt5 on Ubuntu 12.04 and 14.04 LTS 64 bit).
The first (worst) is to delete the qt4 user interface plugin. You can test this is the problem by moving and running and then setting it back. Deleting will break your regular VLC player most likely.
Second option is to create a copy of the plugins directory and set that in your runtime path using VLC_PLUGIN_PATH, environment variable. but I've had trouble getting that to work without changing the original plugin path folder also (which will break your VLC player unless you modify your shortcuts, etc. to also set VLC_PLUGIN_PATH.
The third option, and what I ended up doing, was to custom build my own static LibVLC binary with a few edits to the source code so that it will not load the qt4 interface plugin installed with VLC. You can follow these steps to do this.
1) Download VLC Source Code for your platforms distribution.
http://download.videolan.org/pub/videolan/vlc/
Make sure you download the version matching your distribution. For
example, match the VLC version to what is installed with Ubuntu.
2) Extract source code to folder
3) Install dependencies for the OS distribution
sudo apt-get build-dep vlc
4) Modify src/modules/bank.c
Edit the module_InitDynamic function
Add the following code at the top of the function:
// HACK TO DISABLE QT4 PLUGIN
if(strstr(path, "qt4") != NULL)
return NULL;
// END HACK
3) From terminal
./bootstrap
./configure --disable-qt --disable-skins2 --enable-xcb --prefix=/home/$USER/vlc-custom_build_output_folder_name
./make
./make install
4) Copy/Save the resulting files in the install folder.
Then just link against this library instead.

The SDL library I built from source crashes!

I've successfully built SDL from source using bcc 5.5.1 but any SDL test application using it crashes right away at startup. I'm looking for some help and/or guidance on how to resolve this issue.
Just to fill in some info, SDL-1.2.14 was used. The project's compiled as a dll with multithreading enabled and linked to C runtime dynamically. I've also rebuilt it with debugging info. When I step through with a debugger up to the point of crash it seems to be coming from redirect_stdout in the sdlmain. If I remove sdlmain.lib and use the source file sdl_win32_main.c directly in the SDL test project then that doesn't crash anymore. Instead it just crashes later on at SDL_Init routine.
I've already checked the calling conventions used and they all seem to match up -- everything is using cdecl. I've also checked and made sure the compiled sdl.dll and the test application was using the same dynamic c runtime instead of statically linked.
The SDL wiki under Borland section mentions to use the -b to make sure enum's are same size as int but that option is enabled by the compiler by default unless explicitly turned off. I did rebuild SDL with that compiler/linker switch just to be sure though.
When it crashes, it's always a access violation in trying to write to some address(c000005). Like for example during a typical SDL init attempt like this:
// initialize SDL video
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "Unable to init SDL: %s\n", SDL_GetError() );
return 1;
}
After the call into SDL_Init(), control doesn't flow back into the test application. Instead it crashes somewhere bizarre like somewhere in ntdll.dll with something having to do with NTDLL.RtlEnterCriticalSection. When I inspect the stack trace at that point I usually get something like this:
:77982269
:0044A04C
:0043F02B
:0043F7C4
:0043EF25
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
SDL_CreateMutex()
SDL_CreateSemaphore(1)
//and it keeps recursing... looks like a stackover? :P
I'm not sure whatelse to try at this point as I'm pretty stumped. If anyone have any suggestions or need me to provide more info please feel free to add it to the comments.
Thanks
Alright, I finally found out what the issue was a couple days ago. The reason for the crash was because the wrong source file was compiled for the given platform.
The project file I used kept compiling SDL_sysmutex.c from threads\generic. The correct SDL_sysmutex.c to use under win32 should have been from threads\win32. I found this out when I was tracing the test programs side by side and the threading modules had different lines of code!
With this little oversight fixed the crashing problems have all but disappeared and all the test demos are running as they should :)

Opengl version trouble glew.h

I am developing an OpenGL application and need to use the glew library. I am using Visual Studio C++ 2008 Express.
I compiled a program using gl.h, glu.h, and glut.h just fine and it does what it's supposed to do. But after including glew.h it still compiles just fine, but when I try:
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
}
It keeps printing:
"OpenGL 2.0 not supported".
I tried to change it to glewIsSupported("GL_VERSION_1_3") or even glewIsSupported("GL_VERSION_1_0") and it still returns false meaning that it does not support OpenGL version whatever.
I have a Radeon HD 5750 so, it should support OpenGL 3.1 and some of the features of 3.2. I know that all the device drivers are installed properly since I was able to run all the programs in the Radeon sdk provided by ATI.
I also installed Opengl Extensions Viewer 3.15 and it says OpenGL Version 3.1 Ati Driver 6.14.10.9116. I tired all of them GLEW_VERSION_1_1, GLEW_VERSION_1_2, GLEW_VERSION_1_3, GLEW_VERSION_2_0, GLEW_VERSION_2_1, GLEW_VERSION_3_0 and all of these return false.
Any other suggestioms? I even tried GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader and this is returning false as well.
glewIsSupported is meant to check and see if the specific features are supported. You want something more like...
if (GLEW_VERSION_1_3)
{
/* Yay! OpenGL 1.3 is supported! */
}
there may be some lack of necessary initialization. I encounter the same question. And here is how I solve the question: you need to include the glCreateWindow() ahead. Include this function and try again.
Firstly, you should check whether glew has initialized properly:
if(glewInit() != GLEW_OK)
{ // something is wrong };
Secondly, you need to create the context before calling glewInit()
Thirdly, you can also try:
glewExperimental=true;
Before calling glewInit()
I encountered the same problem when running a program through windows RDP, then I noticed that my video card may not working properly when using RDP, so I tried teamviewer instead, both glewinfo.exe and my program start to work normally then.
The OP's problem may be solved for a long time, just for others' infomation.