OF BlackBerry PlayBook

Hi there!

I was wondering if there were any plans to support the BlackBerry PlayBook platform?

While the PlayBook supports apps made with the Android SDK, it doesn’t support apps that use the Android NDK. Fortunately RIM recently released the BlackBerry Native SDK that allows you to develop apps in c/c++ for the PlayBook Tablet. ( https://bdsc.webapps.blackberry.com/native/download )

Since the system runs on QNX, it should not be too different from how you would build the app in Linux (its probably even easier than Android since there is no JNI involved). Actually, a lot of projects have already been ported/modified: https://bdsc.webapps.blackberry.com/native/documentation/oss.html

On this page:
https://bdsc.webapps.blackberry.com/native/documentation/porting-overview-1970891-11.html

They give some hints about porting and which libraries are already available. Unfortunately I don’t know the openFrameworks core/design enough to give it a shot (although it looks like you can use normal Linux Makefiles).

If I would like to attempt to make a port/addon, were would I start? What would I need for example to build the bare minimum (like only to render ofImage objects, but not openCV or other complex addons). Would I also need to find an alternative for GLUT? All I currently know is that the device is capable of running OpenGL ES 1.0 (or 2.0 if needed).

I don’t really have much knowledge of the entire openFrameworks codebase, but the Android interface (the only one I’ve spent time with) is fairly self-contained and small. Specifically, look at the code in addons/ofxAndroid/src. It might be a good place to start learning how to write a Blackberry QNX interface. AFAIK it doesn’t use GLUT at all.

Thanks for your response noisecapella, I think you’re right.

I’ve taken a look at ofxAndroid\src and the emptyExample from OF, and it seems that to get the basics working, I would need to implement my own class based on ofBaseApp and ofAppBaseWindow (e.g. ofxQNXApp and ofAppQNXWindow). Sound, camera and sensor data might come later.

I’ll let you guys know how it goes

A small update of my progress.

I’ve managed to patch the OF sourcecode and created a handful of new classes for the ofxQNX addon. While it compiles most of the code now, I’m stuck with the dependencies part.

The minimal set requires the following libs:

  1. Freeimage
  • http://freeimage.sourceforge.net/
  • I’ve downloaded 3.15.2 and modified the Makefiles to use the QNX compiler. After removing TIFF and EXR support, it will compile just fine.
  1. Tess2
  • Used the files from openFrameworks\libs\tess2\Sources
  • Import it to a “New BlackBerry OS C/C++ Project” and choose C, Managed Build, Static Lib (empty archive). After that just put in all the files from Sources and hit build.
  1. GLU
  • Unfortunately, there is no GLU included in the BlackBerry native SDK, so you will need to download one from example: http://code.google.com/p/glues/
  • This requires some patching (adding missing definitions).
  • Can be compiled in the same way as Tess2
  1. Boost
  • http://www.boost.org/
    Just download 1.49, these are required because “std::tr1::shared_ptr” and “std::tr1::weak_ptr” are not available from the native SDK (#include <boost/tr1/memory.hpp>). Boost provides these implementations (its not needed to compile Boost)
  1. Poco
  • http://pocoproject.org/
  • While Poco provides sample build files for the QNX target system, I’m having some issues compiling this into a working library. After a few attempts, I managed to build it, however, when using it in my example OF project, I’m getting the following errors:
  
  
E:\porting\pocoplaybook\lib\libPocoFoundation.a(Environment.o): In function `Poco::EnvironmentImpl::nodeIdImpl(unsigned char (&) [6])':  
Environment.cpp:(.text+0x190): undefined reference to `getifaddrs'  
Environment.cpp:(.text+0x1fc): undefined reference to `freeifaddrs'  
E:\porting\pocoplaybook\lib\libPocoNet.a(HTTPResponse.o): In function `Poco::Net::HTTPResponse::getDate() const':  
HTTPResponse.cpp:(.text+0x514): undefined reference to `Poco::DateTimeParser::parse(std::string const&, int&)'  
E:\porting\pocoplaybook\lib\libPocoNet.a(HTTPCookie.o): In function `Poco::Net::HTTPCookie::HTTPCookie(Poco::Net::NameValueCollection const&)':  
HTTPCookie.cpp:(.text+0x1234): undefined reference to `Poco::DateTimeParser::parse(std::string const&, int&)'  
E:\porting\pocoplaybook\lib\libPocoNet.a(HTTPCookie.o): In function `Poco::Net::HTTPCookie::HTTPCookie(Poco::Net::NameValueCollection const&)':  
  

To build Poco, I’ve used the following settings:

Configure:

  
./configure --config=QNX --omit=NetSSL_OpenSSL,Crypto,Data/ODBC,Data/MySQL --no-tests --no-samples --static --prefix=/home/falcon4ever/pocoplaybook  

And modified the QNX file to this:

  
#  
# $Id: //poco/1.4/build/config/QNX#3 $  
#  
# QNX  
#  
# Make settings for QNX Neutrino 6.3.2 or later.  
# For cross-builds, or if the default compiler version  
# selected by the script is wrong, the make variable  
# CCVER can be overridden:  
# make CCVER=4.2.4,gcc_ntox86  
#  
  
#  
# General Settings  
#  
#LINKMODE ?= SHARED  
LINKMODE ?= STATIC  
#  
# Define Tools  
#  
#ifndef CCVER  
#QNXREL = $(shell uname -r)  
#ifeq ($(QNXREL),6.3.2)  
#CCVER   = 3.3.5,gcc_ntox86  
#else  
#ifeq ($(QNXREL),6.4.0)  
#CCVER   = 4.2.4,gcc_ntox86  
#else  
#ifeq ($(QNXREL),6.4.1)  
#CCVER   = 4.3.3,gcc_ntox86  
#else  
#CCVER   = 4.4.2,gcc_ntox86  
#endif  
#endif  
#endif  
#endif  
#CC      = qcc -V$(CCVER)  
#CXX     = QCC -V$(CCVER)  
#LINK    = $(CXX) -V$(CCVER)  
#LIB     = ar -cr  
#RANLIB  = ranlib  
  
CCVER	= 4.4.2,gcc_ntoarmv7le_cpp  
CC  	= $(QNX_HOST)/usr/bin/qcc -V4.4.2,gcc_ntoarmv7le  
CXX  	= $(QNX_HOST)/usr/bin/qcc -V4.4.2,gcc_ntoarmv7le_cpp  
LINK    = $(CXX) -V$(CCVER)  
#LD	= $(QNX_HOST)/usr/bin/ntoarmv7-ld  
AS	= $(QNX_HOST)/usr/bin/qcc -V4.4.2,gcc_ntoarmv7le_cpp  
LD	= $(QNX_HOST)/usr/bin/qcc -V4.4.2,gcc_ntoarmv7le_cpp  
LIB	= $(QNX_HOST)/usr/bin/ntoarmv7-ar -cr  
RANLIB  = $(QNX_HOST)/usr/bin/ntoarmv7-ranlib  
  
SHLIB   = $(CXX) -shared -Wl,-soname,$(notdir $@) -o $@  
SHLIBLN = $(POCO_BASE)/build/script/shlibln  
STRIP   = $(CROSSENV)-strip  
DEP     = $(POCO_BASE)/build/script/makedepend.qcc   
SHELL   = sh  
RM      = rm -rf  
CP      = cp  
MKDIR   = mkdir -p  
  
#  
# Extension for Shared Libraries  
#  
SHAREDLIBEXT     = .so.$(target_version)  
SHAREDLIBLINKEXT = .so  
  
#  
# Compiler and Linker Flags  
#  
CFLAGS          =   
CFLAGS32        =  
CFLAGS64        =  
CXXFLAGS        = -D__PLAYBOOK__ -D__QNXNTO__  
CXXFLAGS32      =  
CXXFLAGS64      =  
LINKFLAGS       =  
LINKFLAGS32     =  
LINKFLAGS64     =  
STATICOPT_CC    =  
STATICOPT_CXX   =  
STATICOPT_LINK  = -static  
SHAREDOPT_CC    = -fpic  
SHAREDOPT_CXX   = -fpic  
SHAREDOPT_LINK  = -Wl,-rpath,$(LIBPATH)  
DEBUGOPT_CC     = -D_FORTIFY_SOURCE=2 -DUSING_GL11 -c -O0 -g -fstack-protector-all -D_DEBUG  
DEBUGOPT_CXX    = -D_FORTIFY_SOURCE=2 -DUSING_GL11 -c -O0 -g -fstack-protector-all -D_DEBUG  
DEBUGOPT_LINK   = -g  
RELEASEOPT_CC   = -D_FORTIFY_SOURCE=2 -c -O2 -fstack-protector-all -fPIE -frecord-gcc-switches -DNDEBUG  
RELEASEOPT_CXX  = -D_FORTIFY_SOURCE=2 -c -O2 -fstack-protector-all -fPIE -frecord-gcc-switches -DNDEBUG  
RELEASEOPT_LINK = -O2  
  
#DEBUGOPT_CC     = -g -D_DEBUG  
#DEBUGOPT_CXX    = -g -D_DEBUG  
#DEBUGOPT_LINK   = -g  
#RELEASEOPT_CC   = -O2 -DNDEBUG  
#RELEASEOPT_CXX  = -O2 -DNDEBUG  
#RELEASEOPT_LINK = -O2  
  
#  
# System Specific Flags  
#  
SYSFLAGS = -D_QNX_SOURCE  
  
#  
# System Specific Libraries  
#  
SYSLIBS  = -lm -lsocket  

The original:

  
  
#  
# $Id: //poco/1.4/build/config/QNX#3 $  
#  
# QNX  
#  
# Make settings for QNX Neutrino 6.3.2 or later.  
# For cross-builds, or if the default compiler version  
# selected by the script is wrong, the make variable  
# CCVER can be overridden:  
# make CCVER=4.2.4,gcc_ntox86  
#  
  
#  
# General Settings  
#  
LINKMODE ?= SHARED  
  
#  
# Define Tools  
#  
ifndef CCVER  
QNXREL = $(shell uname -r)  
ifeq ($(QNXREL),6.3.2)  
CCVER   = 3.3.5,gcc_ntox86  
else  
ifeq ($(QNXREL),6.4.0)  
CCVER   = 4.2.4,gcc_ntox86  
else  
ifeq ($(QNXREL),6.4.1)  
CCVER   = 4.3.3,gcc_ntox86  
else  
CCVER   = 4.4.2,gcc_ntox86  
endif  
endif  
endif  
endif  
CC      = qcc -V$(CCVER)  
CXX     = QCC -V$(CCVER)  
LINK    = $(CXX) -V$(CCVER)  
LIB     = ar -cr  
RANLIB  = ranlib  
SHLIB   = $(CXX) -shared -Wl,-soname,$(notdir $@) -o $@  
SHLIBLN = $(POCO_BASE)/build/script/shlibln  
STRIP   =   
DEP     = $(POCO_BASE)/build/script/makedepend.qcc   
SHELL   = sh  
RM      = rm -rf  
CP      = cp  
MKDIR   = mkdir -p  
  
#  
# Extension for Shared Libraries  
#  
SHAREDLIBEXT     = .so.$(target_version)  
SHAREDLIBLINKEXT = .so  
  
#  
# Compiler and Linker Flags  
#  
CFLAGS          =   
CFLAGS32        =  
CFLAGS64        =  
CXXFLAGS        =  
CXXFLAGS32      =  
CXXFLAGS64      =  
LINKFLAGS       =  
LINKFLAGS32     =  
LINKFLAGS64     =  
STATICOPT_CC    =  
STATICOPT_CXX   =  
STATICOPT_LINK  = -static  
SHAREDOPT_CC    = -fpic  
SHAREDOPT_CXX   = -fpic  
SHAREDOPT_LINK  = -Wl,-rpath,$(LIBPATH)  
DEBUGOPT_CC     = -g -D_DEBUG  
DEBUGOPT_CXX    = -g -D_DEBUG  
DEBUGOPT_LINK   = -g  
RELEASEOPT_CC   = -O2 -DNDEBUG  
RELEASEOPT_CXX  = -O2 -DNDEBUG  
RELEASEOPT_LINK = -O2  
  
#  
# System Specific Flags  
#  
SYSFLAGS = -D_QNX_SOURCE  
  
#  
# System Specific Libraries  
#  
SYSLIBS  = -lm -lsocket  
  
  

Any clues what I can do to make POCO compile properly for use with openFrameworks?

Note: For Poco I’m building the files on an Ubuntu (11.10) system + The BlackBerry Native SDK.

With help from the Poco forums, I finally managed to compile OF :)! Here is ofxQNX running the graphicsExample on my BlackBerry Playbook:

This is awesome! Great work! :smiley:

good job

Nice! Congrats and awesome work!

Hi there,

here is a brief update of my status.

So far multitouch input (4 points) and graphics are working. The only part I’m struggling with is the audio streaming support. I started by creating a new class called ofxQNXSoundStream and by looking on how this was implemented on other platforms.

As far as I see on the iPhone, Win/Mac (rtAudio) and Linux (portaudio), those implementations rely on a callback which periodically calls:

  • soundOutputPtr->audioOut(pcm_buf, int bufferSize, int nChannels);

On Android however, there isnt really a callback. From what I see, a new thread is created on the Java part of the application which calls a some method over JNI that calls the method above.

Since rtAudio and portaudio unfortunately dont support the PlayBook/QNX architecture, the only option is to use the QNX Sound Architecture (QSA) which is in some way similar to ALSA.

In a standalone sandbox app, I am able to play some noise on my playbook (I just filled the buffer with random values just like the audioOutputExample). In the code samples below I’ve already started to import some of the code into 3 methods:

  • int openQNXAudio();
  • void updateQNXAudio();
  • void closeQNXAudio();

On setup, it will call openQNXAudio(). This will take care of opening the audio device and setting up the parameters. So my only issue is how I would call updateQNXAudio() for every update loop? Is there some clean way to do it in oF? Or should I try to call it manually in testApp::update()

The source code so far:

ofxQNXSoundStream.h

  
  
class ofxQNXSoundStream : public ofBaseSoundStream {  
	public:  
		ofxQNXSoundStream();  
		virtual ~ofxQNXSoundStream();		  
		  
		void listDevices();  
		void setDeviceID(int deviceID);  
  
		bool setup(int outChannels, int inChannels, int sampleRate, int bufferSize, int nBuffers);  
		bool setup(ofBaseApp * app, int outChannels, int inChannels, int sampleRate, int bufferSize, int nBuffers);  
  
		void setInput(ofBaseSoundInput * soundInput);  
		void setOutput(ofBaseSoundOutput * soundOutput);  
		  
		void start();  
		void stop();  
		void close();  
  
		long unsigned long getTickCount();  
  
		int getNumInputChannels();  
		int getNumOutputChannels();  
  
		int openQNXAudio();  
		void updateQNXAudio();  
		void closeQNXAudio();  
  
	private:  
		long unsigned long	tickCount;  
		int				nInputChannels;  
		int				nOutputChannels;  
		int				sampleRate;  
  
		// Playbook specific  
		snd_pcm_t *pcm_handle;  
		snd_mixer_t *mixer_handle;  
};  
  

ofxQNXSoundStream.cpp

  
  
#include "ofSoundStream.h"  
#include "ofMath.h"  
#include "ofUtils.h"  
  
#include "ofxQNXSoundStream.h"  
  
static bool							isSetup			= false;  
static bool							isRunning		= false;  
static ofBaseSoundInput *			soundInputPtr	= NULL;  
static ofBaseSoundOutput *			soundOutputPtr	= NULL;  
  
ofxQNXSoundStream::ofxQNXSoundStream()  
{  
	fprintf(stderr, "ofxQNXSoundStream::ofxQNXSoundStream()\n");  
}  
  
ofxQNXSoundStream::~ofxQNXSoundStream()  
{  
	fprintf(stderr, "ofxQNXSoundStream::~ofxQNXSoundStream()\n");  
}  
  
void ofxQNXSoundStream::listDevices()  
{  
	fprintf(stderr, "ofxQNXSoundStream::listDevices()\n");  
}  
void ofxQNXSoundStream::setDeviceID(int deviceID)  
{  
	fprintf(stderr, "ofxQNXSoundStream::setDeviceID()\n");  
}  
  
void ofxQNXSoundStream::setInput(ofBaseSoundInput * soundInput)  
{  
	fprintf(stderr, "ofxQNXSoundStream::setInput(ofBaseSoundInput)\n");  
	soundInputPtr = soundInput;  
}  
void ofxQNXSoundStream::setOutput(ofBaseSoundOutput * soundOutput)  
{  
	fprintf(stderr, "ofxQNXSoundStream::setInput(ofBaseSoundOutput)\n");  
	soundOutputPtr = soundOutput;  
}  
  
bool ofxQNXSoundStream::setup(int outChannels, int inChannels, int _sampleRate, int bufferSize, int nBuffers)  
{  
	fprintf(stderr, "ofxQNXSoundStream::setup(outChannels %d, inChannels %d, sampleRate %d, bufferSize %d, nBuffers %d)\n", outChannels, inChannels, _sampleRate, bufferSize, nBuffers);  
  
	nInputChannels = inChannels;  
	nOutputChannels = outChannels;  
	tickCount = 0;  
	sampleRate = _sampleRate;  
  
	//nBuffers = 1;  
  
	// Setup QNX  
	openQNXAudio();  
  
	// TODO   
	// Setup callback?  
  
	// ?  
	if(isRunning) {  
		stop();  
		close();  
	}  
  
	isSetup = true;  
	ofSoundStreamStart();  
}  
bool ofxQNXSoundStream::setup(ofBaseApp * app, int outChannels, int inChannels, int sampleRate, int bufferSize, int nBuffers)  
{  
	fprintf(stderr, "ofxQNXSoundStream::setup(ofBaseApp)\n");  
	setInput(app);  
	setOutput(app);  
	setup(outChannels, inChannels, sampleRate, bufferSize, nBuffers);  
}  
  
void ofxQNXSoundStream::start()  
{  
	fprintf(stderr, "ofxQNXSoundStream::start\n");  
	// TODO  
	if(isRunning)  
		ofSoundStreamStop();  
}  
void ofxQNXSoundStream::stop()  
{  
	fprintf(stderr, "ofxQNXSoundStream::stop\n");  
	// TODO  
}  
void ofxQNXSoundStream::close()  
{  
	fprintf(stderr, "ofxQNXSoundStream::close\n");  
	// TODO  
	//closeQNXAudio();  
}  
  
long unsigned long ofxQNXSoundStream::getTickCount()  
{  
	fprintf(stderr, "ofxQNXSoundStream::getTickCount\n");  
	return tickCount;  
}  
//------------------------------------------------------------------------------  
int ofxQNXSoundStream::getNumInputChannels(){  
	return nInputChannels;  
}  
  
//------------------------------------------------------------------------------  
int ofxQNXSoundStream::getNumOutputChannels(){  
	return nOutputChannels;  
}  
  
  
int ofxQNXSoundStream::openQNXAudio(){  
	fprintf(stderr, "ofxQNXSoundStream::openQNXAudio\n");  
  
	int     rtn;  
	int     card = -1;  
	int     dev = 0;  
  
	snd_pcm_channel_info_t pi;  
	snd_pcm_channel_params_t pp;  
	snd_mixer_group_t group;  
	snd_pcm_channel_setup_t setup;  
  
	int     fragsize = -1;  
	int     num_frags = -1;  
	int     bsize;  
  
// Open PCM  
	if ((rtn = snd_pcm_open_preferred (&pcm_handle, &card, &dev, SND_PCM_OPEN_PLAYBACK)) < 0)  
	{  
		fprintf(stderr, "device open");  
		return -1;  
	}  
  
// disabling mmap is not actually required in this example but it is included to  
// demonstrate how it is used when it is required.  
  
	if ((rtn = snd_pcm_plugin_set_disable (pcm_handle, PLUGIN_DISABLE_MMAP)) < 0)  
	{  
		fprintf(stderr, "snd_pcm_plugin_set_disable failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
// get pcm info  
	memset (&pi, 0, sizeof (pi));  
	pi.channel = SND_PCM_CHANNEL_PLAYBACK;  
	if ((rtn = snd_pcm_plugin_info (pcm_handle, &pi)) < 0)  
	{  
		fprintf(stderr, "snd_pcm_plugin_info failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
// setup pcm channel  
	memset (&pp, 0, sizeof (pp));  
	pp.mode = SND_PCM_MODE_BLOCK;  
	pp.channel = SND_PCM_CHANNEL_PLAYBACK;  
	pp.start_mode = SND_PCM_START_FULL;  
	pp.stop_mode = SND_PCM_STOP_STOP;  
	pp.buf.block.frag_size = pi.max_fragment_size;  
  
	if (fragsize != -1)  
	{  
		pp.buf.block.frag_size = fragsize;  
	}  
	pp.buf.block.frags_max = num_frags;  
	pp.buf.block.frags_min = 1;  
  
	pp.format.interleave = 1;  
	pp.format.rate = sampleRate;  
	pp.format.voices = nOutputChannels;  
	pp.format.format = SND_PCM_SFMT_S16_LE;	// Signed 16-bit Little Endian  
  
	strcpy (pp.sw_mixer_subchn_name, "Wave playback channel");  
	if ((rtn = snd_pcm_plugin_params (pcm_handle, &pp)) < 0)  
	{  
		fprintf(stderr, "snd_pcm_plugin_params failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
	if ((rtn = snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {  
		fprintf(stderr, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
	memset (&setup, 0, sizeof (setup));  
	memset (&group, 0, sizeof (group));  
	setup.channel = SND_PCM_CHANNEL_PLAYBACK;  
	setup.mixer_gid = &group.gid;  
  
	if ((rtn = snd_pcm_plugin_setup (pcm_handle, &setup)) < 0)  
	{  
		fprintf(stderr, "snd_pcm_plugin_setup failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
	if (group.gid.name[0] == 0)  
	{  
		fprintf(stderr, "Mixer Pcm Group [%s] Not Set \n", group.gid.name);  
		return -1;  
	}  
  
	if ((rtn = snd_mixer_open (&mixer_handle, card, setup.mixer_device)) < 0)  
	{  
		fprintf(stderr, "snd_mixer_open failed: %s\n", snd_strerror (rtn));  
		return -1;  
	}  
  
	fprintf(stderr, "Format %s \n", snd_pcm_get_format_name (setup.format.format));  
	fprintf(stderr, "Frag Size %d \n", setup.buf.block.frag_size);  
	fprintf(stderr, "Total Frags %d \n", setup.buf.block.frags);  
	fprintf(stderr, "Rate %d \n", setup.format.rate);  
	fprintf(stderr, "Voices %d \n", setup.format.voices);  
	fprintf(stderr, "Mixer Pcm Group [%s]\n", group.gid.name);  
  
  
	bsize = setup.buf.block.frag_size;  
	//pcm_buf = malloc (bsize);  
	// Still need to allocate PCM_BUFFER  
}  
  
void ofxQNXSoundStream::updateQNXAudio() {  
	fprintf(stderr, "ofxQNXSoundStream::updateQNXAudio\n");  
	  
	// get floats from app  
	// soundOutputPtr->audioOut(pcm_buf, int bufferSize, int nChannels);  
  
	// write pcm_buf to to device  
	// snd_pcm_plugin_write (pcm_handle, pcm_buf, n);  
}  
  
void ofxQNXSoundStream::closeQNXAudio(){  
	fprintf(stderr, "ofxQNXSoundStream::closeQNXAudio\n");  
  
	snd_pcm_plugin_flush (pcm_handle, SND_PCM_CHANNEL_PLAYBACK);  
	snd_mixer_close (mixer_handle);  
	snd_pcm_close (pcm_handle);  
}  

Output info

Format Signed 16-bit Little Endian
Frag Size 2820
Total Frags 85
Rate 44100
Voices 2
Mixer Pcm Group [Wave playback channel]

I got some basic audio working now in openFrameworks but for some reason it dies after a few seconds.
I’ve currently moved the code from the audio example to a standalone app as posted on http://supportforums.blackberry.com/t5/Native-SDK-for-BlackBerry-Tablet/Porting-openFrameworks-need-help-with-the-audio-QSA-part/td-p/1641151

A small update:
I’ve got some good feedback from RIM developers, so hopefully I’ll be able to solve the audio issues soon.

I have placed the source code of the addon (licensed under BSD) and a handful examples on GitHub under my fork developPlayBook:
https://github.com/falcon4ever/openFrameworks/tree/developPlayBook

Addon:
https://github.com/falcon4ever/openFrameworks/tree/developPlayBook/addons/ofxQNX

Examples:
https://github.com/falcon4ever/openFrameworks/tree/developPlayBook/examples/qnx

In the addon directory the README.txt explains some details on how to import the project.

Another update, ofxQNX is almost working perfectly on the PlayBook platform. I still have to fix the issues with the audio, but all graphics related examples are fully working.

Photos of the result:

qnxAudioOutputExample (audio is a bit broken for the moment)

qnxFontsExample

qnxGraphicsExample

qnxImageExample

qnxInputExample (4 touches max)

qnxPolygonExample

qnxTouchExample (accelerometer is fully working)

qnxVBOExample (runs at 60fps)

Real multitasking on the playbook


this is awesome! congratulations on your progress, and this is a super well documented account of the kind of problems and solutions that come up when porting something.

Congrats and thanks so much for all the hard work you’ve put into this, it’s much appreciated! Oddly, just Friday I had someone ask whether I knew anything about this platform and the answer was “nope”, today it’s “well, maybe a little” :slight_smile:

Thanks for keeping up with this Laurence! We’re going to have some fun with it! :smiley:

Thanks for the kind comments guys :).

@Kyle: I’m surprised by how nice its working out so far, it shows how well designed openFramework is as a portable framework. I guess Poco was the most difficult one though, since its using custom build files and for some reason didnt want to build on windows. Fortunately, the compiler builds libraries that I can use on any platform. Also a big thanks to Arturo for pointing out the issue with the polygon winding (libtess2), it fixed the issues I had earlier on with the polygonExample

@Joshua: Yea, Friday it was still barely running. I spend quite some time this weekend to clean up the code and work on the samples. I’d say it’s in a reasonable state right now, if you don’t need audio. Only the AudioPlayer and AudioStreamer class need quite some work.

@Seth: No doubt about that ;).

Just a quick post. falcon4ever and I are getting closer on the audio side of things. We’re still having some troubles, but making baby steps. :wink:

Here’s a test of ofxPd running on the simulator. It’s really great that the simulator can run at a full 60fps. There’s some audio latency in the video, but i’ve gotten it much better since capturing the recording. I can make a quick video of some of the examples soon.

http://www.youtube.com/watch?v=D36SPB7-s1c

As a side note, overall it’s been fairly simple to get the BlackBerry simulator/IDE setup (mostly thanks to falcon4ever). It’s much easier to setup than Android since BlackBerry provides the eclipse IDE and everything necessary to get running. The simulator runs in a VM and is really fast which makes it easy to test.

Here’s a quick video of all the base OF examples running on the PlayBook.

There’s still some weird issues with the audio example that we haven’t figured out. Buffer underrun maybe?

http://www.youtube.com/watch?v=4FuC9AEg1LQ

Small update, major thanks to Seth for implementing the SoundStreamer class with SDL!

I received my PlayBook back from servicing, so here is the NodeBeat Beta running on real hardware (its very responsive compared to Android):
http://www.youtube.com/watch?v=xhZ46PpccGQ

and all the demos:
http://www.youtube.com/watch?v=JLE3v-QRa74

hey falcon4ever - can you give me some insight to where in the Poco forums you found this solution? I am currently getting the errors you were getting while trying to do a port on ARM5