The Cross-Platform Challenge
The late 1980s marked the end of the home computer era and the beginning of the unique success story of the IBM PC and Microsoft Windows*. A crowded computer landscape with various different computer systems, architectures and operating systems was replaced by the uniform personal computer. For a long time developers could ship their applications just on Windows and reach more than 95 percent of their mainstream customers. The introduction of the iPhone* and other new mobile devices disrupted this dominant position and substantially changed the computer landscape.
In 2012 smartphones outsold PCs two to one, and it is expected that in 2014 the number will increase to four to one . The adoption of new mobile devices is happening ten times faster than the PC boom . The tremendous success of smartphones and tablets has led again to a fragmented market with a lot of different devices and different form factors. For the foreseeable future there will be no dominant mainstream platform, and companies need to prepare themselves for this challenge.
Almost every industry is to some degree affected by this rapid technology shift. Companies are forced to react quickly and adjust their strategies and products to the changing market in order not to fall behind their competitors. Software developers are required to support multiple operating systems like Android*, iOS*, Windows, and OS X* and different processor architectures like Intel® architecture (IA-32/x86) and ARM* to just cover the most popular notebooks, smartphones, and tablets.
Supporting multiple platforms is a challenging task. Each platform has its own API, preferred programming language, and, even, quirks. If done naively by implementing separate apps for each platform, development and maintenance costs become prohibitively expensive. Maintaining three or four code bases can result in feature skew where different features are supported on different platforms and multiple bug databases are necessary. Development teams with expertise in different languages and other redundancies are required.
It is therefore not a surprise that cross-platform tools are booming nowadays. However, selecting the right tool is not easy. A lot of tools with different approaches are available on the market. Obviously not every tool is suitable for every purpose. Depending on the type of application, one cross-platform solution may be a better fit or may not fit at all. Additionally many tools offer great promises that don’t hold true, and it is difficult to filter the actual important features from the marketing buzz. In the end, every team has to define their own tool requirements and choose wisely. In our view, two indispensable quality characteristics deserve special attention and these are flexibility and controllability.
Most tools have a steep learning curve so you want a tool flexible enough to use for most projects. Project requirements often change and new features are requested; hence, your tool must be flexible enough to add new features. Additionally it is crucial that you keep full control over your project. You don’t want to lose ownership and be at the mercy of a third-party tool. If these qualities are important to you, you may want to take a closer look at Spraylight’s Murl Engine. It was designed with portability, efficiency, flexibility, and controllability as its topmost design goals.
Murl Engine Primer
The Murl Engine is a fresh and free solution for cross-platform development. It is focused on games and multimedia applications and is currently supporting Android, iOS, Windows, OS X and Linux* platforms. The intention, when designing it, was to create a tool set that enables developers to develop rich multimedia applications fast and easy without limiting or restricting them.
The Murl Engine is not a typical WYSIWYG game engine, but instead a flexible coders’ framework. It is slightly more low level and offers more flexibility and control. The framework provides an abstraction API, a powerful scene graph framework, optional add-on components, and a set of tools. The source code is provided for large parts of the framework so you can extend and adapt it as needed. Licensing the full source code is possible too. The application code compiles directly to pure native binaries, so VMs and runtime environments are not necessary, providing raw native performance.
When deciding the basic technology, C++ was a natural choice. Inexperienced users are sometimes afraid of C++ and deem it complicated and outdated, but it’s definitely not. C++ is a modern and efficient programming language and the primary language used in professional game development. It is a proven technology and the only way to create really portable native code.
C++ enables you to write efficient code with a modern, object-oriented language. Additionally it allows you to always open the hood and take control over more advanced features like memory layouts, processor instructions, optimizations, etc. when needed. Most of the time it is not needed, but it’s good to know, that you can if wanted or forced to. This is especially important on mobile platforms where you need to do more with less hardware and less power and for multimedia applications and games where power and performance are paramount.
Probably the most important feature of C++ is portability. It is the only modern language where you can write a single source code base for any kind of demanding app and be able to natively target all platforms. Every platform has a C++ compiler and new upcoming platforms will have it too. Therefore this approach is not only portable but also future proof.
It was obvious to choose C++ as the main programming language for the Murl Engine, and we never regretted our choice. Only the platform abstraction layer had to be developed in other programming languages.
It is worth noting that some of today’s most successful cross-platform apps like Dropbox, MS Office*, King games, etc. are built using the same approach with a common C++ code base and platform-specific adoption layers.
Murl Engine Architecture
As shown in Figure 1, the Murl Engine’s architecture is divided into different layers. The lowest layer is the platform abstraction layer which, as the name implies, performs the platform abstraction. One individual platform abstraction module exists for each platform. Depending on the platform requirements the platform code has been written in C, C++, Objective-C*, and Java*. This layer provides a homogenous C++ interface that can be used by higher layers.
The framework layer provides all the features that are needed to develop decent multimedia applications and has been developed in portable C++. Basically it is a time-based scene graph framework including support for 2D and 3D rendering, OpenGL ES*, and DirectX* graphic APIs, resource management, input handling, physics, audio, networking, scripting, fast container classes, etc. A detailed feature list can be found here. Optional add-ons like the Vuforia* augmented reality toolkit, the Facebook* add-on, or custom add-ons can be used to enlarge the feature set.
Application development (“user code”) is usually written in C++. Additionally Lua*, a popular scripting language, can be used for development.
The Murl Engine comes with a set of useful tools, like the Dashboard, to manage projects and the Atlas Generator to create texture atlases. Another tool, called “Werkbank” (Figure 2), to be released shortly, is a graphical scene editor with live preview that can be used to create and edit scene graphs and resource packages. Another very nice feature is an integrated shader editor that allows you to develop and preview vertex and fragment shaders for OpenGL ES (GLSL) and DirectX 11.1 (HLSL).
Werkbank utilizes the cross-platform widget toolkit Qt for the user interface and is running several instances of the Murl Engine as preview widgets. This is another good example of Murl Engine’s flexibility.
Developing with the Murl Engine
To start developing simply download the Murl Engine from the website https://murlengine.com. It’s free and no registration is required. There’s only one version and it comes with all features. The download package also has the source code and the project files for the tutorials included.
The provided Dashboard (Figure 3) is a convenient tool for managing your project files and creating builds for the Android platform. It can be used to easily open a tutorial project or to create a new project.
Basically any available C++ IDE can be used for application development. However, the framework's support for project creation and maintenance is currently only provided for Microsoft Visual Studio*, Apple Xcode*, and the Android SDK/NDK toolset. Development and testing can largely be done in a desktop environment using familiar tools. This guarantees fast edit-build-test iteration cycles and minimizes cumbersome work with emulators and target devices.
The first beta build of the Murl Engine was released on March 3, 2013. Even in beta status, Murl Engine is ready for professional application development. The very successful, top grossing app, “Slots - Pharaoh’s Way” with more than 10 million downloads, more than 10 billion games played, and few technical complaints, is a good example of the stability and the maturity of the Murl Engine.
Android x86 Support
The best thing when owning a highly portable C++ code base is that supporting new architectures or new platforms is a piece of cake. Providing support for Android x86 was a breeze.
As mentioned above, we are using the Android SDK/NDK toolset for Android builds. The NDK already provides support for Android x86 via the APP_ABI attribute. So we just had to add the right parameter and recompile the whole framework. You can find a more detailed discussion about adding Android x86 support and performance improvements in this blog post.
To enable Android x86 support for a Murl Engine-based app, the parameter MURL_ANDROID_CPUS in the common Makefile needs to be set accordingly, e.g.:
1 MURL_ANDROID_CPUS := armeabi
2 MURL_ANDROID_CPUS += armeabi-v7a
3 MURL_ANDROID_CPUS += x86
The specified values correspond to the values of the APP_ABI parameter of the Android NDK build environment (ABI is short for "Application Binary Interface").
1 armeabi ARM-based CPUs that support at least the ARMv5TE instruction set
2 armeabi-v7a ARM-based CPUs that support ARM Architecture v7-a instruction set
3 with Thumb-2 instructions und VFPv3-D16 hardware FPU.
4 x86 x86-based CPUs. The NDK build uses the following gcc flags:
5 -march=i686 -mtune=atom -mstackrealign -msse3 -mfpmath=sse -m32
You can directly edit the common Makefile in a text editor, or it’s probably more convenient to use the Android -> Configure Project command on the Dashboard (see Figure 4).
Cross-platform application development is more important than ever. Good cross-platform solutions like the one presented here, Murl Engine, can massively lower the burden of development and reduce development costs. Adding native support for x86-powered Android devices to the Murl Engine was easy due to the highly portable code base and the already available x86 support of the Android NDK. Using this feature in Murl Engine-based apps is hassle-free and leads to a substantial performance gain on Android devices powered with Intel® Atom™ processors.
For more such Android resources and tools from Intel, please visit the Intel® Developer Zone