CrossTalk3D Tutorial 1 : Simple cube

In my last post I introduced the 3D framework I’m currently working on to give an overview of what it does and what the plans are. This time I’d like to give a quick tutorial in getting started using the framework to produce a simple spinning cube with a textured surface and illuminated by a simple point light.

The idea here is to quickly show how scene creation occurs and how we can very easily add objects to a scene.

You can find the full source code for the demo on github in the SimpleCube folder which can be executed on different platforms using the lime command, eg:

> lime test html5

A little word of warning, as I mentioned in my previous post: xt3d is still work in progress and so the API will probably change over time. At least, for now, this post gives you an idea of the principals of xt3d and even if the underlying framework has changes, the current code should be valid for a while!

Let’s have a look at the demo in action: click on the image below to see the demo in it’s HTML5 form.

SimpleCube Demo

Before we look at the code, here a few concepts of xt3d which we’ll see in action below.

  • Application: Each application that uses xt3d has an Application class which provides the main entry point to your code. This actually is part of the Lime framework and not specific to xt3d. Your main Application is specified in the project.xml file used to build your project. xt3d provides a helper class called BasicApplication which is used to do some initialisation specific to xt3d.
  • Director: Each xt3d application uses a Director to initialise, manage and control all the xt3d components. For example it’ll build a renderer using an OpenGL context and handle the render loop, it organises the scheduling of events such as updating the scenes and animations, it manages the event handling from user input devices, etc. Currently only one Director exists per application.
  • View: A View is essentially a window to a graphical scene. It is composed of a camera, a scene and a viewport. Views are added to the Director which then, for each active scene, ensures they are rendered and updated at every frame.
  • Scene: A Scene is the root of the scene graph for a particular view. A hierarchy of child objects, called Nodes, are added to the scene which may or may not be renderable objects. A Scene may be used by different View objects to observe a scene from different angles.
  • Camera: To view a scene, a Camera is used to observe it from a specific position and angle. Cameras can be part of the scene graph too and manipulated like all other Nodes.

Now we have some knowledge of the basic concepts, let’s have a look at the full code used to produce the demo to see how them in action.

There’s really not much to this but let’s break it down to explain what’s happening at different stages.

What you’ll notice is that there are actually two classes in this code snippet: SimpleCube which is the Application class and SimpleCubeView, a View subclass, which is used to construct make the visible scene.

The SimpleCube class, the main entry point to the application is shown below:

Inheriting from the BasicApplication class, all that is needed is to implement the onApplicationReady function. He we simply set the background color of the application by modifying the backgroundColor property of the Director (which has been conveniently created for us and accessed via a property). Here we create a dark grey color, the default background color being black.

Then, all we need to do is create a View, in this case a subclass called SimpleCubeView, and add it to the Director. By default views take up the full window produced by the Application.

The SimpleCubeView object is responsible for constructing the scene elements with lights, camera… and action!

The view object is constructed and initialised using a static creator function. You’ll see this kind of thing in almost every xt3d class.

It’s kind of a habit that came around from working with Objective-C and the Cocos2d-x frameworks: its a concise way of constructing and initialising an object in a single line of code while keeping any potentially exception-prone code out of a constructor. Different classes may have multiple creators too: each one explicitly indicates how the object is being created.

The main scene construction comes in the init function where we start off by using an helper-initialiser from the View super class:

The initBasic3D method essentially just creates a Scene object and a Camera object with a default perspective matrix. Both of these are added to the View (note that for a View to be valid it must have both a Scene and a Camera).

Once we have our Scene object we can go about constructing the scene contents. In this demo the star is a textured Cube which is constructed from a Cube geometry and a TextureMaterial. The Geometry provides the mesh of vertices (containing positions, normals and UVs) which are configured in the creator method. The TextureMaterial provides a simple way of loading an image file and converting it into an OpenGL texture which will be mapped to the geometry vertices. In this case we want to add lighting to the scene so we indicate that the material is to have lighting effects too.

Just a quick side not, the TextureMaterial can be created with a MaterialOptions configuration object allowing you to add lighting and other behavioural options immediately during construction.

With a Material and a Geometry we can now create a MeshNode which is added to the scene. All nodes have transformation matrices containing information on rotation, translation and scale of  the node: in the case shown here we make no modification to this matrix so the cube is positioned at the origin with no scaling or rotation applied.

Having added the cube we go about adding lighting effects. Here we create a point light (also a Node3D allowing it to be transformed easily within the scene) object and position it relative to the it’s scene parent.

At the same time we specify a global scene ambient light color. Being observant, you’ll notice how we’ve used the Color object twice with two different creators: the first time for the Director background color we used RGB components (being between 0 and 1), and we specify the ambient light color as a hex RGB value.

As well as positioning the Camera, we add some user interaction by adding a CameraController object to the scene:

The CameraController automatically listens to user gestures coming from either the mouse or touch screen depending on the target device. This class provide simple orbiting functionality around a target, which by default is the origin.

You may be asking why do we add the controller to the scene? It’s true that it doesn’t feel like a it should belong to a hierarchy but it does allow us to take advantage of a couple of key functions in the Node3D class, notably onEnter and onExit which are called when a Scene starts and finishes in a Director. In the case of the CameraController it allows us enable the user gesture handling only when the scene is visible.

Finally, to enable us to perform the action, we specify that our View should be updated every frame.

This ensures that the following update function is called. In this case we simply modify the y-rotation of the cube by a certain amount each frame, calculated using the time since the last update (dt) to maintain a constant rotation rate.

And there we have it! That’s all that’s needed to build a simple scene in xt3d! Ok, granted, it’s not a complicated scene but the aim here has been to illustrate one of the main objectives of the framework: essentially that it provides a very simple API to construct 3D scenes. Over the coming months I’ll add more tutorials here while developing extra features for the framework.

If you feel motivated, please try constructing your own scenes (and applications for the really adventurous!) and I’d be very happy to have your feedback. CrossTalk3D is still in the early stages of development so all feedback is welcome :)

 

Presenting CrossTalk3D: a cross platform 3D graphics framework

Introduction

In this post I would like to present the project I’ve been working on over the last few months: CrossTalk3D.

CrossTalk3D (or xt3d for short) is an open-source, cross-platform 3D graphics and game development framework built using Haxe and Lime.

It’s aim is to provide a simple API to build 3D scene-graphs with a wide range of features for rendering, modelling and animation. The features and APIs are heavily influenced by the iOS framework, iSGL3D, that I developed a few years ago but several other factors influenced its design:

  • Cross platform support for OpenGL, OpenGL ES and WebGL with a single development language
  • Ease of customisation with weak dependence on framework shaders
  • Optimised rendering

Cross platform

The first of these points is handled by producing a framework using the Haxe language and the Lime framework which provides low-level windowing, rendering and input support (amongst other features). For more information on these, take a look at my previous post.

The current targets for xt3d are

  • Mac
  • HTML5
  • iOS
  • Neko

It should also be possible to run on Android, Windows, Linux and other platforms supported by Lime. If anyone gets a chance to test on other platforms then please let me know :)

Customisation

I really wanted xt3d to be as open as possible for graphics developers too. Integrating custom shaders is really easy with a minimal dependence on the framework – only model, view and projection matrices have specific uniform types and names that should (if needed) be used by the shader, all other uniforms and vertex attributes can be user defined.

The shader framework is extensible too allowing shaders to be made by combining different elements. For example you can develop your own shader that is extended by the xt3d Phong lighting extension.

Of course, xt3d comes with pre-defined shaders which are used to create Materials that can be configured and wrapped around mesh geometries. These can be extended by your own custom extensions or rapidly used out-of-the-box to fulfil standard rendering requirements.

xt3d mesh geometries are also flexible and can be created using custom vertex attributes that can be interleaved or indexed as you desire.

The standard render pass of xt3d is also customisable and the aim is that it can be modified to produce other visual effects with pre- and post-rendering passes. Rendering to textures is also supported to assist with this.

The aim really is to have a framework that provides a solid base of rendering features for developers getting started in 3D graphics and give freedom for more experienced developers to take advantage of the cross-platform capabilities.

Optimised rendering

A leading force in the design of the graphics motor has also been to achieve a high level of efficiency with OpenGL. xt3d is state-aware only makes calls to OpenGL when really necessary. This means that changing rendering options, modifying shader uniforms, updating geometry buffers, etc only lead to calls to the GPU if something has changed.

The cross-platform nature of the project doesn’t necessarily mean that it is always easy to develop the best code that runs optimally on all platforms, but whenever possible, this has been integrated into the 3D motor.

Future development

Currently CrossTalk3D is really in its infancy but is now off the crawling stage… many features still need to be developed but the heart of the motor and some of the base 3D features are now in place. Currently xt3d is offering:

  • Scene-graph with 3D object transformations
  • Dynamic lighting from multiple light sources
  • Texture mapping
  • Built-in and custom shader support
  • Object and geometry-face picking
  • Gesture handlers (mouse and touch events)

There is no fixed roadmap but the main objectives over the next few months include:

  • Scene and model importers and exporters
  • More primitive geometries
  • Action-based animation
  • Skeleton-based animation and skinning
  • Text rendering
  • Particle systems
  • Shadow rendering
  • Bump mapping

A lot of things still to do! But, I feel happy now that minimal features currently available are enough to make it publicly available and let people play around with it! If you feel motivated, please do so and I’d be happy to hear from you. The future isn’t set in stone and the current API can, and probably will, change in the future so be aware that this is far from a final product! If you have ideas, requests or comments both technically and feature-wise then please let me know!

The CrossTalk3D framework can be obtained from github and you can get sample code there too (currently not much there, but should be added to shortly!). Over time I’ll push both of these projects to Haxelib.

In the next post I’ll give a quick tutorial covering the basics of the framework and an example to get started. For now there’s just a little demo (click on the image below) to give you a quick preview of the xt3d running in HTML5.

xt3d-preview

Getting started with Haxe and OpenFl

As I mentioned in my last post, this year I’ve started work on a new cross-platform 3D graphics engine. My language of choice is Haxe as it provides access to desktop, mobile and web development using a single, object-oriented, code base. This article explains a little bit of the architecture of Haxe applications and about how to get started with Haxe development.

About Haxe

Haxe, as it says on their website, is “an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform’s native capabilities“. Sounds good to me.

Development of the Haxe language started in 2005 by Nicholas Cannasse with the original goals to achieve better performance than ActionScript3, easily port AS3 application and provide both client (javascript) and server-side (php or java) development capabilities. To achieve the goal of easily porting AS3 applications, it is not surprising that it closely resembles this language…

To achieve the goals of providing client and server-side development as well as better performance, Haxe is not directly compiled into machine code, rather it is compiled into different languages for different purposes. For example, for a web client,  Haxe is translated into Javascript and for a server target Haxe can be translated into C++. This compilation process automatically verifies syntax and expressions so compilation of the final target (in theory) occurs without compilation errors.

Currently Haxe supports the following targets:

  • Flash byte code
  • Neko bytecode (Neko is a virtual machine project of Nicholas Cannasse)
  • AS3
  • C++
  • Javascript
  • C#
  • Java
  • PHP
  • Python

That’s a pretty impressive list of targets! Amazing that a single language can be run on any machine that supports one of these.

Personally I like the syntax of AS3 so I find Haxe pleasant to use. Why? For one thing it is an uncluttered object-oriented, language. You can get started with Haxe simply by knowing other object-oriented languages. It does have its own specific syntax for some operations but for the most part it’s just plain and simple.

Installation of Haxe and use of haxelib

Haxe is easily installed on Mac, Windows and Linux platforms from dedicated binaries on their download page. I’m a Mac user so I can’t give much advice and feedback on the other platforms, but the install will give you the Haxe compiler and the haxelib library management tool.

The haxelib library manager is a means of installing third-party Haxe libraries and managing their dependencies, similar to npm for Node.js and cocoapods for iOS development. Connected to a central repository it provides access to a multitude of libraries.

haxelib will, once setup, provide a local repository of Haxe libraries that can be easily included in any of your Haxe projects.

Some useful haxelib commands are for example,

Install a libarary:

> haxelib install <library>

Update a library:

> haxelib update <library>

List currently available local libraries:

> haxelib list

IDE integration

The Haxe site provides a useful page on IDE and editor integration for Haxe. I’m an Intellij IDEA user and have found the intellij-Haxe plugin perfect (or close to) for my needs. It provides syntax highlighting, code completion, navigation and compilation and execution support.

To be honest, when I started there used to be problems executing code with the plugin but I got so used to compiling with the command line that I now just use it mainly as an editor. It’s very possible that today the plugin compiles and runs codes correctly too as the development of it remains very active.

It’s very easy to install and this article provides more information.

OpenFl, Lime and other high level frameworks

OpenFl aims to produce a cross-platform, open-source Flash API (and does exceedingly well at this) to produce games and applications for wide range of targets. As it says on its home page “Build games and applications for almost every platform imaginable — Windows, Mac, Linux, iOS, Android, BlackBerry, Firefox OS, Tizen, Flash and even HTML5“. It’s an impressive list, and given the ubiquity of AS3 developers, it’s not surprising that that it is the most popular haxelib library! Although OpenFl is not developed by the same people as Haxe, I think the success of Haxe is also dependent on the success of OpenFl. Personally, without OpenFl I certainly wouldn’t have pursued Haxe development over the last 9 months.

So how do Haxe and OpenFl fit together and, the question which was of most importance to me when I started, how do we render OpenGL (or more generally any graphics) on multiple platforms?

In fact there is an additional layer between OpenFl and Haxe called Lime (Light Media Engine) which provides low-level capabilities including graphics, audio and user events.

The following illustrating the relationship between Haxe, OpenFl and Lime comes from the blog post introducing OpenFl 3:

openfl3architecture

As we can see, Lime provides all the glue to the different platforms enabling audio, keyboard, mouse, joystick and graphics hardware. OpenFl provides the Flash API and much of the Flash functionality. This table provides a list of  Flash features provides by OpenFl.

Lime and OpenFl appear to be developed in parallel and updates are often released at the same time.

Installation of OpenFl is performed easily with haxelib as shown here. Essentially this involves using haxelib to do:

> haxelib install openfl
> haxelib run openfl setup

This gives you the openfl command line allowing you to create empty or demo projects, compile for different targets and run the applications. For example to create a HelloWorld project you do:

> openfl create project HelloWorld

This creates a basic project in the HelloWorld folder. If you navigate to this folder you can test the application, for example in javascript, by running:

> openfl test html5

You can also choose neko, mac, windows, ios and android targets for example.

The installation of OpenFl will also install Lime. You can alternatively install Lime on its own :

> haxelib install lime
> haxelib run lime setup

This gives you virtually identical command line tools, eg:

> lime test html5

In fact this command can also be used to compile and run OpenFl applications – the two frameworks are very closely linked.

This has been a very quick introduction to OpenFl and Lime – there are a few more links at the bottom of the page to find out more about them, but really the OpenFl site provides a lot of information on getting started.

A few other libraries I’ve come across and are available by haxelib are worthy of mentioning:

  • away3d for OpenFl provides a port of the away3d AS3 3D framework to OpenFl/Haxe. This seems to be fairly actively maintained.
  • HaxeFlixel which ports the popular Flash game engine Flixel to Haxe – again using the OpenFl framework.

Debugging

I’d be happy to hear from other people about their thoughts on this… the only way I’ve successfully managed to debug Haxe/OpenFl applications is to run them on the html5 target and use the Chrome debugger:

> lime test html5 -debug

It’s easy to provide source mappings so that you can breakpoint you’re Haxe code rather than the generated Javascript and this works efficiently for 95% of the time. However there are some behavioural differences between platforms so there are cases when debugging can be frustrating.

I think that the IntelliJ plugin provides C++ debugging but when I tried this a few months ago it wasn’t working.

I would love to be able to debug the Neko target and it’s kind of surprising that there are no debuggers available for this seeing as it is so closely connected with Haxe (same author). Neko is actually a really nice target to run on as it compiles extremely quickly (compared to C++ for example) and gives a virtually identical desktop/native experience.

If anyone knows of a better way to debug Haxe code please let me know :)

Some useful links

To finish off with here are a few links for reference material or introductions to Haxe and OpenFl.

Summing up

This has been a very rapid introduction to the world of Haxe… too short probably to be of any real use – sorry! Hopefully it’s given some insights into, in my opinion, a good candidate for cross-platform development.

It seems clear to me that Haxe and especially OpenFl and Lime are still not fully matured, but it also seems very clear that they are being very actively developed and have a strong community behind them. I’m not sure how many other open-source, cross-platform solutions (or even commercial ones) can say they provide natively running code on so many platforms.

Having developed with it for the past 9 months I can honestly say that it’s been overall a good experience and I haven’t come across any major obstacles – I’m as motivated today as I was when I started this project, if not more so! For web development, given the language choice between Javascript and Haxe, I’d choose the object-oriented one any day!

Give it a try – its so easy to start running OpenFl examples it’d be a shame not too ;)

 

Cross-platform development

Around Christmas time 2014 I started thinking about the problem of cross-platform development. More specifically about development of graphics applications based on OpenGL for mobile, desktop and web.

I think it’s a common question for the development of most applications today. During the game development at KoolFing we had the same problem but without the web aspect. We needed to develop for both iOS and Windows (and potentially Android too). To tackle this we used Cocos2d-x with various hacks for our own purposes. Cocos2d-x is a great framework that started as a multi-platform C++ port of the Objective-C iPhone library, Cocos2d-iphone (a really great 2D games library, now named Cocos2d-ObjC). and now Cocos2d-x follows the same development cycle as other members of the Cocos2d family, versions for different targets.

Being based on C++ it has a language base that is common to many platforms. Cocos2d-x wraps all the rendering contexts and input sources allowing for common code to run on many devices.

However, this solution does not allow for development of common code that can be used for web-based applications too. Cocos2d-JS is another member of the Cocos2d family written in Javascript and having the same API. However two separate developments are still necessary.

My personal opinion is that applications will be more and more developed for the mobile (iOS and Android) market as well as for the web. It seems that cross-platform App development is nicely covered by a number of increasingly popular frameworks (PhoneGap, Marmalade, appcelerator, Xamarin, Corona SDK, etc to name but a few). Desktop solutions are often provided by these cross-platform frameworks. However cross-platforms frameworks that include web solutions seem, to me, to be lacking, especially considering that today applications are becoming increasingly accessible through our browsers.

As I said, it was around Christmas when I was wondering about this and, as I mentioned in my previous post, I finally had some free time to devote to personal development. I’ve often used the antlr parser-generator in the past to write and started thinking about writing a language that could be translated easily into C++, JavaScript, Java etc (I want my apps to run natively)… a language that was a simple, pure object-oriented language without specific paradigms… a language similar to ActionScript3…

… and then I remembered a fairly obscure language that I’d come across almost ten years ago called HaXe that is based on the same syntax as AS3 and does exactly what I was thinking about doing: ie it translates into different native languages for different platforms! Now why didn’t I think about it immediately?

I remember when I was using HaXe before that I thought it was a nice idea but that is was lacking in documentation, community support and no guarantee that it would be around for long. When I started looking at it again I was happily surprised to see that it had grown and flourished, that documentation was better and was now supported by other frameworks (notably OpenFl) that make cross platform development much easier.

Today, my question is why don’t we hear more about Haxe (nowadays with a lower-case ‘x’). It has a mature language and a huge range of supported platforms including mobile, web, desktop and console. It can be integrated into native developments, has a growing community and has IDE integrations.

I think the fact that is it still fairly obscure is still my main concern. Debugging tools could also be improved, however the JS target provides language mappings that can be used effectively with Chrome. Anyway, when I started, it ticked all the boxes on my development checklist… so I thought I’d give it a try.

Today, several months later I’m still happily working with it, am impressed how common code runs of multiple platforms and am using it for my latest 3D framework… but I’ll leave that for later!

In my next post I’ll write about getting started with Haxe. I’d definitely recommend trying Haxe out. Maybe it doesn’t suit everyone, but in terms of cross-platform development, I think it has a lot going for it.

Back again… it’s been a while

Hello, I’m back.

Sorry for the lack of posts, if anyone even noticed, but finally, almost five years since the last post, I’ve got the bug to chatter again about some tech stuff that I’m doing. Maybe it’s useful for other people (I hope so), maybe its just a way to archive what I’m doing and maybe it’s just kind of nice to blah blah about what I like.

Some history, since you’ll notice, this is the first post and, rather confusingly, I started by staying “I’m back”. Actually this is a revamped blog. The old blog.tartiflop, started in 2008, was mainly focussed on ActionScript3 and provided a series of tutorials for developing 3D applications using Papervision3D (sadly now defunct I think) and Away3D (now very much alive and kicking, good on ’em !). I loved writing the tutorials and developing using both frameworks – 3D is my passion and both of these had a great influence on me. I was honoured to play a small part of the team of Away3D for a short time, while I still had some time to contribute…

… but after a year or so, with the increasing popularity of the iPhone 3G and the Apple AppStore (to be honest I was a little slow off the band waggon), I started developing my own 3D framework using Objective-C. I’ll be honest that the inspiration came notably from Away3D – the ease of developing 3D scenes was so wonderful that it became my goal for an iOS framework. There’s also a hint of cocos2d in there too (another framework I love and makes animation and game-play such a pleasure to code). I love the low-level OpenGL stuff too and getting the best out of, let’s be honest, pretty crappy processors and GPUs that those phones had! After a lot of time and hard work, the result was isgl3d, released as open-source at the end of 2010. I’m still really happy with this framework. A number of other developers around the world picked it up and used it in their apps which made it all worthwhile! Unfortunately, again, life changes and a lack of time to maintain it has meant that since the end of 2011 it hasn’t evolved.

Isgl3d was left to fend for itself because I decided to chuck in my comfy day job (which honestly gave me lots of free time too) to create a games company with a couple of other motivated guys, including a very talented, long-time friend: KoolFing was extremely fun, exciting and a positive, rewarding experience in many aspects but at the same time draining and not the best career decision I ever made! Funny when thinking about it, but that’s just reminded me how the opening paragraph of A Tale of Two Cities for me says everything about the two year period:

“It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us…” Charles Dickens

Sorry, that probably sounds a bit pompous, but really the creation of a startup and all the emotions that went with it are, for me, summed up in this sentence. Well, in brief, it didn’t work financially, but the experience was certainly worth it. Two games, Crazy Escape and Turbolab Pursuit were the result of this endeavour – both of which I’m technically very happy with.

Still working with the same friend, we managed to find enough spare time over the next 18 months or so to develop another iOS application. This time an elegant tool called PlasticImage to create objects from photos that can be 3D-printed. But the majority of time during this period was a matter of gaining some career stability… and having found that, since December 2014 I’ve finally managed to get back to doing what I like to do so much: 3D geeking in my free-time! And now, I think, I finally have something to talk about again…