Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Patched openFrameworks 0071 for the QNX platform (BlackBerry PlayBook & BB10) #1587

Closed
wants to merge 3 commits into from

5 participants

@falcon4ever

This patch adds support for the QNX platforms (BlackBerry PlayBook & BB10) to openFrameworks.

The code is based of the developPlayBook branch (https://github.com/falcon4ever/openFrameworks/tree/developPlayBook) that has been used for the NodeBeat project (http://nodebeat.com/). However, I have updated the code for compatibility with openFrameworks 0071 (develop branch)

The current code has been tested using the following SDKs

  • BlackBerry PlayBook Native SDK 2.1.0 beta 1
  • BlackBerry 10 Native SDK 10.0.06 beta 2

To develop for QNX or run the examples, you will need to download the ofxQNX add-on and place it in the addon folder of openFrameworks.

For now, ofxQNX resides in a different repository for the following reasons:

  • Because I include pre-compiled libraries, the current size of the repository is about 100 MB.
  • Pre-compiled libraries are used because of the complexity involved with building them from scratch. Most of them need to be patched for the QNX compiler and Poco for QNX can't be build on Windows platforms.
  • Another reason for the size (mostly due Poco) is because it supports multiple QNX architectures and build modes. The devices all use an ARMv7 cpu, the simulator uses x86.
  • > PlayBook device (ARMv7) - Release
  • > PlayBook device (ARMv7) - Debug
  • > PlayBook simulator (X86) - Debug
  • > BB10 device (ARMv7) - Release
  • > BB10 device (ARMv7) - Debug
  • > BB10 simulator (X86) - Debug

Additional info on ofxQNX:

falcon4ever added some commits
@falcon4ever falcon4ever Patched openFrameworks 0071 for the QNX platform (BlackBerry PlayBook…
… and BlackBerry 10)

To develop for the BlackBerry PlayBook and BlackBerry 10 platform:
- Download ofxQNX (https://github.com/falcon4ever/ofxQNX) and install it into the addon folder.
1652c0d
@falcon4ever falcon4ever Enabled QNX output log cec0279
@falcon4ever falcon4ever use absolute path on QNX platform 3d75860
@kylemcdonald

i'd like to ask the core how they feel about this -- it's been sitting here for a bit. @ofZach @ofTheo @arturoc

it's awesome to see people contributing to OF in a way that opens it up to more platforms, but my feeling is that QNX is not popular enough to warrant merging into the OF core. if there is a way to make this work without requiring QNX-specific changes to the core, that would be really cool.

for now i'm going to close this PR unless zach/theo/arturo have a plan for incorporating this kind of work.

@falcon4ever

@kylemcdonald: Just a small update on this PR, this one was done quite a while ago with an older version (0071). The patches for 0.7.4 are now in https://github.com/falcon4ever/openFrameworks/commits/openframeworks-v0.7.4-stable

@kylemcdonald

cool -- good to know it's still possible to get OF working on QNX :) i hope there's something we can incorporate from all this work!

@bilderbuchi
Owner

@kylemcdonald judging from this PR, it seems the necessary changes are primarily a bunch of finer-grained ifdefs, so not too invasive I think. Maybe we can do some kind of "unofficial" support, i.e. just have the ifdefs in Core, everything else is in the addon anyway? I guess it depends how committed @falcon4ever is to maintaining QNX support? Alternatively, @falcon4ever could just keep maintaining a patched OF branch in his repo like currently.

@ofTheo
Owner

it doesn't seem too invasive: falcon4ever@93598c7

@falcon4ever - what could we do on our end to make it easier to keep it working for QNX?
Is it similar to iOS where there are some #ifdefs in the core and then the rest in an addon?

@falcon4ever

@ofTheo Yep, pretty much like iOS or Android. I have only patched a handful of files in openFrameworks to add QNX support. Since the BB Native SDK doesn't have the tr1 memory/shared_ptr implementations, I borrowed them from boost. For poco I'm using the same version (1.4.3) as in the repo. It works fine with the poco you guys patched ( 8a59e32 )

The rest is all handled in the addon ofxQNX (https://github.com/falcon4ever/ofxQNX/blob/develop/README.md). The readme contains the changelog and details about the libraries that I include.

Since this pull request is 9 months old and was made for 0071, I think it would be easier to just create a new pull request based on the latest dev branch / v0.8.0. The rest of the add-on can stay in https://github.com/falcon4ever/ofxQNX which I will maintain.

@ofTheo
Owner
@arturoc
Owner

sounds good to me too, everything opengles related is now properly ifdef'd for opengles instead of iOS and i guess there's little more that need ifdefs since i think this should be pretty similar to android or arm linux.

also we can avoid using boost by typedefing ofPtr to poco SharedPtr instead.

i would add the libraries in the official OF repo so it's easier to generate official packages?

@arturoc
Owner

also, i've heard that there's a tool from RIM to convert android apps to their new OS. have you tried that? it could be an option too but not sure how well it works

@bilderbuchi
Owner

i would add the libraries in the official OF repo so it's easier to generate official packages?

the thing is, when we do that, we'd have to maintain it in the future, too. do we even have devs who use BB devices (except @falcon4ever)?

@falcon4ever

I personally would prefer to keep the libs in the ofxQNX repo as they are updated quite frequently. Blackberry is working quite hard to update its platform so in the couple of months they did a few major upgrades (10.0.09, 10.0.10 and now 10.1.x). ( http://developer.blackberry.com/native/downloads/bb10/releasenotes_nativesdk.html )
Besides that, the libs folder is quite big (70+ MB) so that might pollute the openFrameworks repo quite a bit (perhaps make it an optional submodule in the addons folder?).

@arturoc The tool from RIM only allows you to convert Android apps that are implemented in Java only. It checks all the API calls that the app will make and gives you a report. Native libs are not supported (well officially that is, its disabled on purpose) so you can't just create an *.apk and then convert it to a *.bar and expect it to run.

About boost, yea if that is a possibility I could probably drop the boost dependency in ofxQNX.

@bilderbuchi I dont know how many people are using it, probably a handful of indie devs. I've used it for Nodebeat and Super Hexagon but I believe Breakeroids from Simon is using it as well.

@arturoc
Owner

I personally would prefer to keep the libs in the ofxQNX repo as ...

sounds good, i would try to look into using SharedPtr for ofPtr to avoid having boost, let me know if you need help

@falcon4ever falcon4ever deleted the branch
@falcon4ever falcon4ever restored the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 11, 2012
  1. @falcon4ever

    Patched openFrameworks 0071 for the QNX platform (BlackBerry PlayBook…

    falcon4ever authored
    … and BlackBerry 10)
    
    To develop for the BlackBerry PlayBook and BlackBerry 10 platform:
    - Download ofxQNX (https://github.com/falcon4ever/ofxQNX) and install it into the addon folder.
Commits on Jan 23, 2013
  1. @falcon4ever

    Enabled QNX output log

    falcon4ever authored
Commits on Feb 15, 2013
  1. @falcon4ever
This page is out of date. Refresh to see the latest.
View
20 libs/openFrameworks/3d/ofMesh.cpp
@@ -348,7 +348,7 @@ int ofPrimitive::getNumIndicesWire(){
//--------------------------------------------------------------
ofVec3f* ofMesh::getVerticesPointer(){
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &vertices[0];
#else
return vertices.data();
@@ -357,7 +357,7 @@ ofVec3f* ofMesh::getVerticesPointer(){
//--------------------------------------------------------------
ofFloatColor* ofMesh::getColorsPointer(){
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &colors[0];
#else
return colors.data();
@@ -366,7 +366,7 @@ ofFloatColor* ofMesh::getColorsPointer(){
//--------------------------------------------------------------
ofVec3f* ofMesh::getNormalsPointer(){
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &normals[0];
#else
return normals.data();
@@ -375,7 +375,7 @@ ofVec3f* ofMesh::getNormalsPointer(){
//--------------------------------------------------------------
ofVec2f* ofMesh::getTexCoordsPointer(){
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &texCoords[0];
#else
return texCoords.data();
@@ -384,7 +384,7 @@ ofVec2f* ofMesh::getTexCoordsPointer(){
//--------------------------------------------------------------
ofIndexType* ofMesh::getIndexPointer(){
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &indices[0];
#else
return indices.data();
@@ -394,7 +394,7 @@ ofIndexType* ofMesh::getIndexPointer(){
//--------------------------------------------------------------
const ofVec3f* ofMesh::getVerticesPointer() const{
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &vertices[0];
#else
return vertices.data();
@@ -403,7 +403,7 @@ const ofVec3f* ofMesh::getVerticesPointer() const{
//--------------------------------------------------------------
const ofFloatColor* ofMesh::getColorsPointer() const{
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &colors[0];
#else
return colors.data();
@@ -412,7 +412,7 @@ const ofFloatColor* ofMesh::getColorsPointer() const{
//--------------------------------------------------------------
const ofVec3f* ofMesh::getNormalsPointer() const{
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &normals[0];
#else
return normals.data();
@@ -421,7 +421,7 @@ const ofVec3f* ofMesh::getNormalsPointer() const{
//--------------------------------------------------------------
const ofVec2f* ofMesh::getTexCoordsPointer() const{
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &texCoords[0];
#else
return texCoords.data();
@@ -430,7 +430,7 @@ const ofVec2f* ofMesh::getTexCoordsPointer() const{
//--------------------------------------------------------------
const ofIndexType * ofMesh::getIndexPointer() const{
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(TARGET_QNX)
return &indices[0];
#else
return indices.data();
View
4 libs/openFrameworks/app/ofAppRunner.cpp
@@ -30,6 +30,8 @@ static ofPtr<ofAppBaseWindow> window;
#include "ofAppiPhoneWindow.h"
#elif defined TARGET_ANDROID
#include "ofAppAndroidWindow.h"
+#elif defined TARGET_QNX
+ #include "ofAppQNXWindow.h"
#else
#include "ofAppGlutWindow.h"
#endif
@@ -104,6 +106,8 @@ void ofSetupOpenGL(int w, int h, int screenMode){
window = ofPtr<ofAppBaseWindow>(new ofAppiPhoneWindow());
#elif defined TARGET_ANDROID
window = ofPtr<ofAppBaseWindow>(new ofAppAndroidWindow());
+ #elif defined TARGET_QNX
+ window = ofPtr<ofAppBaseWindow>(new ofAppQNXWindow());
#else
window = ofPtr<ofAppBaseWindow>(new ofAppGlutWindow());
#endif
View
2  libs/openFrameworks/math/ofMatrix4x4.h
@@ -422,7 +422,7 @@ class ofMatrix4x4 {
inline bool ofMatrix4x4::isNaN() const {
-#if (_MSC_VER) || defined (TARGET_ANDROID)
+#if (_MSC_VER) || defined (TARGET_ANDROID) || defined (TARGET_QNX)
#ifndef isnan
#define isnan(a) ((a) != (a))
#endif
View
2  libs/openFrameworks/ofMain.h
@@ -25,7 +25,7 @@
//--------------------------
// communication
-#if !defined( TARGET_OF_IPHONE ) & !defined(TARGET_ANDROID)
+#if !defined( TARGET_OF_IPHONE ) & !defined(TARGET_ANDROID) & !defined(TARGET_QNX)
#include "ofSerial.h"
#include "ofArduino.h"
#endif
View
5 libs/openFrameworks/sound/ofSoundPlayer.h
@@ -44,6 +44,11 @@ void ofSoundShutdown();
inline void ofSoundShutdown(){}
#endif
+#ifdef TARGET_QNX
+#include "ofxQNXSoundPlayer.h"
+#define OF_SOUND_PLAYER_TYPE ofxQNXSoundPlayer
+#endif
+
//---------------------------------------------
class ofSoundPlayer : public ofBaseSoundPlayer {
View
3  libs/openFrameworks/sound/ofSoundStream.h
@@ -18,6 +18,9 @@
#elif defined(OF_SOUNDSTREAM_IPHONE)
#include "ofxiPhoneSoundStream.h"
#define OF_SOUND_STREAM_TYPE ofxiPhoneSoundStream
+#elif defined(OF_SOUNDSTREAM_QNX)
+ #include "ofxQNXSoundStream.h"
+ #define OF_SOUND_STREAM_TYPE ofxQNXSoundStream
#endif
void ofSoundStreamSetup(int nOutputChannels, int nInputChannels, ofBaseApp * appPtr = NULL);
View
12 libs/openFrameworks/types/ofTypes.h
@@ -5,6 +5,9 @@
#if (_MSC_VER)
#include <memory>
+#elif defined(TARGET_QNX)
+#include <boost/tr1/memory.hpp>
+#include <boost/shared_ptr.hpp>
#else
#include <tr1/memory>
#endif
@@ -146,6 +149,10 @@ class ofPtr: public std::tr1::shared_ptr<T>
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::tr1::_Dynamic_tag)
: std::tr1::shared_ptr<T>(__r, std::tr1::_Dynamic_tag()) { }
+#elif defined(TARGET_QNX)
+ template<typename Tp1>
+ ofPtr(const ofPtr<Tp1>& __r, boost::detail::dynamic_cast_tag)
+ : std::tr1::shared_ptr<T>(__r, boost::detail::dynamic_cast_tag()) { }
#else
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::tr1::__dynamic_cast_tag)
@@ -167,6 +174,11 @@ template<typename _Tp, typename _Tp1>
ofPtr<_Tp>
dynamic_pointer_cast(const ofPtr<_Tp1>& __r)
{ return ofPtr<_Tp>(__r, std::tr1::_Dynamic_tag()); }
+#elif defined(TARGET_QNX)
+template<typename _Tp, typename _Tp1>
+ofPtr<_Tp>
+ dynamic_pointer_cast(const ofPtr<_Tp1>& __r)
+{ return ofPtr<_Tp>(__r, boost::detail::dynamic_cast_tag()); }
#else
template<typename _Tp, typename _Tp1>
ofPtr<_Tp>
View
40 libs/openFrameworks/utils/ofConstants.h
@@ -18,7 +18,8 @@ enum ofTargetPlatform{
OF_TARGET_IPHONE,
OF_TARGET_ANDROID,
OF_TARGET_LINUX,
- OF_TARGET_LINUX64
+ OF_TARGET_LINUX64,
+ OF_TARGET_QNX
};
// Cross-platform deprecation warning
@@ -60,6 +61,9 @@ enum ofTargetPlatform{
#elif defined (ANDROID)
#define TARGET_ANDROID
#define TARGET_OPENGLES
+#elif defined (__QNX__)
+ #define TARGET_QNX
+ #define TARGET_OPENGLES
#else
#define TARGET_LINUX
#endif
@@ -176,9 +180,29 @@ enum ofTargetPlatform{
#define TARGET_LITTLE_ENDIAN
#endif
+#ifdef TARGET_QNX
+ #define GL_GLEXT_PROTOTYPES
+
+ #include <EGL/egl.h>
+ #ifdef USING_GL11
+ #include <GLES/gl.h>
+ #include <GLES/glext.h>
+ #elif defined(USING_GL20)
+ #include <GLES2/gl2.h>
+ #else
+ #error openFrameworks QNX must be compiled with either USING_GL11 or USING_GL20 flags
+ #endif
+
+ #define TARGET_LITTLE_ENDIAN
+#endif
+
#ifdef TARGET_OPENGLES
- #include "glu.h"
- //typedef GLushort ofIndexType ;
+ #if defined(TARGET_QNX)
+ #include "glues.h"
+ #else
+ #include "glu.h"
+ //typedef GLushort ofIndexType ;
+ #endif
#else
//typedef GLuint ofIndexType;
#endif
@@ -231,6 +255,10 @@ typedef TESSindex ofIndexType;
#define OF_VIDEO_CAPTURE_ANDROID
+ #elif defined(TARGET_QNX)
+
+ #define OF_VIDEO_CAPTURE_QNX
+
#elif defined(TARGET_OF_IPHONE)
#define OF_VIDEO_CAPTURE_IPHONE
@@ -248,7 +276,7 @@ typedef TESSindex ofIndexType;
#define OF_VIDEO_PLAYER_IPHONE
#elif defined(TARGET_OSX)
#define OF_VIDEO_PLAYER_QTKIT
- #elif !defined(TARGET_ANDROID)
+ #elif !defined(TARGET_ANDROID) && !defined(TARGET_QNX)
#define OF_VIDEO_PLAYER_QUICKTIME
#endif
#endif
@@ -263,6 +291,8 @@ typedef TESSindex ofIndexType;
#define OF_SOUNDSTREAM_RTAUDIO
#elif defined(TARGET_ANDROID)
#define OF_SOUNDSTREAM_ANDROID
+ #elif defined(TARGET_QNX)
+ #define OF_SOUNDSTREAM_QNX
#else
#define OF_SOUNDSTREAM_IPHONE
#endif
@@ -275,7 +305,7 @@ typedef TESSindex ofIndexType;
#define OF_SOUND_PLAYER_IPHONE
#elif defined TARGET_LINUX
#define OF_SOUND_PLAYER_OPENAL
- #elif !defined(TARGET_ANDROID)
+ #elif !defined(TARGET_ANDROID) && !defined(TARGET_QNX)
#define OF_SOUND_PLAYER_FMOD
#endif
#endif
View
5 libs/openFrameworks/utils/ofLog.cpp
@@ -14,9 +14,12 @@ static map<string,ofLogLevel> & getModules(){
}
static void noopDeleter(ofBaseLoggerChannel*){}
-#ifdef TARGET_ANDROID
+#if defined(TARGET_ANDROID)
#include "ofxAndroidLogChannel.h"
ofPtr<ofBaseLoggerChannel> ofLog::channel = ofPtr<ofxAndroidLogChannel>(new ofxAndroidLogChannel,std::ptr_fun(noopDeleter));
+#elif defined(TARGET_QNX)
+ #include "ofxQNXLogChannel.h"
+ ofPtr<ofBaseLoggerChannel> ofLog::channel = ofPtr<ofxQNXLogChannel>(new ofxQNXLogChannel,std::ptr_fun(noopDeleter));
#else
ofPtr<ofBaseLoggerChannel> ofLog::channel = ofPtr<ofConsoleLoggerChannel>(new ofConsoleLoggerChannel,std::ptr_fun(noopDeleter));
#endif
View
26 libs/openFrameworks/utils/ofUtils.cpp
@@ -20,7 +20,7 @@
#endif
-#if defined(TARGET_OF_IPHONE) || defined(TARGET_OSX ) || defined(TARGET_LINUX)
+#if defined(TARGET_OF_IPHONE) || defined(TARGET_OSX ) || defined(TARGET_LINUX) || defined(TARGET_QNX)
#include <sys/time.h>
#endif
@@ -205,6 +205,8 @@ static string & dataPathRoot(){
static string * dataPathRoot = new string("../../../data/");
#elif defined TARGET_ANDROID
static string * dataPathRoot = new string("sdcard/");
+#elif defined TARGET_QNX
+ static string * dataPathRoot = new string("");
#elif defined(TARGET_LINUX)
static string * dataPathRoot = new string(ofFilePath::join(ofFilePath::getCurrentExeDir(), "data/"));
#else
@@ -272,8 +274,18 @@ string ofToDataPath(string path, bool makeAbsolute){
path = dataPathRoot()+path;
}
+ #if defined(TARGET_QNX)
+ // Always use absolute path on QNX platform
+ char fullpath[1024];
+ char appPath[1024];
+
+ getcwd(appPath, 1024);
+ snprintf(fullpath, 1024, "%s/%s", appPath, path.c_str());
+ path = fullpath;
+ #endif
+
if(makeAbsolute && (path.length()==0 || path.substr(0,1) != "/")){
- #if !defined( TARGET_OF_IPHONE) & !defined(TARGET_ANDROID)
+ #if !defined( TARGET_OF_IPHONE) & !defined(TARGET_ANDROID) & !defined(TARGET_QNX)
#ifndef TARGET_WIN32
char currDir[1024];
@@ -531,14 +543,22 @@ bool ofIsStringInString(string haystack, string needle){
//--------------------------------------------------
string ofToLower(const string & src){
string dst(src);
+#if defined TARGET_QNX
+ transform(src.begin(),src.end(),dst.begin(),tolower);
+#else
transform(src.begin(),src.end(),dst.begin(),::tolower);
+#endif
return dst;
}
//--------------------------------------------------
string ofToUpper(const string & src){
string dst(src);
+#if defined TARGET_QNX
+ transform(src.begin(),src.end(),dst.begin(),toupper);
+#else
transform(src.begin(),src.end(),dst.begin(),::toupper);
+#endif
return dst;
}
@@ -728,6 +748,8 @@ ofTargetPlatform ofGetTargetPlatform(){
#endif
#elif defined(TARGET_ANDROID)
return OF_TARGET_ANDROID;
+#elif defined(TARGET_QNX)
+ return OF_TARGET_QNX;
#elif defined(TARGET_OF_IPHONE)
return OF_TARGET_IPHONE;
#endif
View
2  libs/tess2/include/tesselator.h
@@ -69,7 +69,7 @@ enum TessElementType
typedef float TESSreal;
//note this shouldn't be defined(TARGET_OS_IPHONE) as its always defined either 0 or 1
-#if TARGET_OS_IPHONE || defined(ANDROID)
+#if TARGET_OS_IPHONE || defined(ANDROID) || defined(__QNX__)
typedef unsigned short TESSindex;
#else
typedef unsigned int TESSindex;
Something went wrong with that request. Please try again.