Designing a Cross-Platform 3D Application Engine to Support Windows 8

How to use OpenGL and friends to write an app that targets mobile and desktop platforms.

Introduction

Hi there, I'm a bit of a cross platform development nerd. I love writing apps and games in my spare time to support as many different platforms as possible. In this article, I'll introduce you to the cross-platform 3D application engine that I wrote which I tend to base my apps and games from. I'll then explain how the code is architected to support both mobile and desktop platforms. In doing so, you should be able to either re-use the engine, or simply be inspired to re-use as much code as possible when creating your own apps or games which target multiple platforms.

App Innovation Contest

This article is in entry towards the Ultrabook App Innovation Contest, where I plan on porting and releasing three of my apps and games to the Intel AppUp store. If there is interest, I would be happy to write up a follow up article to explain how the engine was ported over to support the Windows 8 platform and the code was structured to support additional Ultrabook features such as a gyroscope and touch screen interaction.

In this section, I'll describe the apps and games I'd like to port and the Ultrabook features I'd like to use to improve them.

FacePlayer - Originally called FaceStalker, this app goes through your FaceBook photo galleries and caches all the photos. It also allows you to navigate the photos in beautiful 3D. The source code is available here (Apache 2 license), and runs on iOS, Android, Windows and Mac. I plan on again adding some gyroscope and touchscreen support for the Windows 8 Ultrabook version.

iGrapher 3D - 3D stockmarket visualizer. I created this originally as a webapp a few years ago, however when I managed to get my hands on an iPhone, I ported it over to iOS in funky 3D. Then when I got my hands on an Android, I ported the engine to work on that platform too. I'd like to simply add in some gyroscope and touchscreen support for the Windows 8 Ultrabook version.

Phone Wars - This is an online MMO shooter game that's available in three editions, Phone Wars, Tank Legends and Food Fighters. The source for the Android and iOS demo version is available here. Again, I'd love to add gyroscope sensors and touch screen support for the Windows 8 Ultrabook version.

Background

I named the engine 2c for several reasons. The first comes from the challenge of creating applications which feature 3D gaming elements. The problem with creating these type of apps is that the user interaction tends to suffer from the unconstrained camera angles that a 3D projection provides. Text is no longer easy to read and the movement and user interaction motions can come off as unnatural. The best solution would be to always try to limit the 3Dness of an application, but use 3D in gaining performance and for extra value transitions and animations, that have been inspired by the mobile operating systems we've come to know and love today. So in result, the idea is that while it's still using 3D, it's trying to hide the potential crazyness that you get from 3D, it's more 3D-1 = (3-1)(D-1) = ( 2c ).

The second and perhaps cooler reason is that if you say 2c, to sounds like to see, which emphasises the vision of trying to make apps and games that you want to see.(OK, disclaimer, I'm a bit of an obsessive over thinker, so these reasons may come off as strange.)

The source code is written in C++ and the different platforms are available to load using different IDEs.

The Android version uses the Eclipse IDE to import the Android, App, Engine and External projects.

The PC, Mac, Linux version uses the Qt IDE and framework whose project file can be found inside the Qt/Project folder.

The iOS version uses the xCode IDE whose project file can be found in the iOS folder.

The source code is structured with wrappers to allow for cross-platform functionality. The way this works is by providing device level code, engine level code and app level code.

Here, we see that we can abstract the iOS and Qt specific renderer and control system into our own Engine renderer and controls structure, which can be used from the application specific code we write.

For example, if take the rendering operation of loading a shader and dig into the codebase we find that. Inside the Engine level renderer CCRenderer.h.

We find a pure virtual function called loadShader(CCShader *shader);

Inside the Qt version, we find an inherited class called CCDeviceRenderer, which implements the loading of the shader using the Qt library tools which builds on OpenGL and the Windows/Linux/Mac file systems.

Inside the iOS version, we find an inherited class called CCDeviceRenderer, which implements the loading using Objective C, OpenGL ES and iOS specific libraries.

Other systems are wrapped this way too, for example, the CCFileManager handles file system operations, the CCURLManager handles making http connections.

As most of the code is written inside the Engine layer and only calls inside Engine wrapper functions, most of the code base inside the App specific level can be written to run the same across platforms. However, in some cases we may want to diverge our platforms depending on certain situations. For this, we define keywords (#IOS, #ANDROID, #QT) to identify the platform we're running on.

Using the Code

Taking the iOS version for example, if you go into the Dev/iOS folder and load the 2c.xcodeproj with xCode. The SceneSample1.cpp file would be the best starting point for experimentation.

Here, we're inheriting from CCSceneAppUI, which provides a camera and touch controls to allow us to create objects in a world that interacts as a list view with 3D mechanics when multiple touches are used.

The constructor creates our 3D application camera and sets it to use our entire screen.

The setup function is called by the Engine once the Scene is added to its update and rendering loops. This uses the CCTile3DButton class which is a 3D button tile that allows for text and images to be inserted on and renders itself in 3D providing 3D touch detection from different camera angles. Here, we set up three buttons, one for the background, one for text and one for an image.

While this may be a basic sample to get you up and running creating buttons and text in 3D, you can then look into the SocialPoetry project which goes ahead to extend this view, to support drawing of photos it downloads from FaceBook.

Wrapping Up

Hopefully, the very least take away from this article is perhaps some motivation towards structuring your code base with wrappers to support multiple platforms. While I regard my codebase to be still immature, it does serve me well, but I'd honestly love your feedback in order to develop it further to ensure it's easier to pick up and play with.

"If there is interest, I would be happy to write up a follow up article to explain how the engine was ported over to support the Windows 8 platform and the code was structured to support additional Ultrabook features such as a gyroscope and touch screen interaction"

Hi Chris, I finished porting my apps (just waiting on a code signing certificate before submitting). I'd like to write an update targeting how to interact with the WinRT sensor APIs whilst still maintaining compatibility with Windows XP. Would you suggest I update this article, or to post the follow up as a separate article targeting that area solely?