Tuesday, 6 September 2016

xygine featured on Push Button, Receive Code and Lunar Mooner update

I happened to discover that the lovely chap over at Push Button, Receive Code has a tutorial series which uses xygine. This makes me really happy that someone else is finding xygine useful to the point that they want to create a good quality tutorial series with it - something I've never managed to do myself. I highly recommend you go read the series, which covers making a top-down shooter not unlike classics such as SmashTV. I'd like to point out though that it's 'xygine' with a small 'x'. I don't know why, I'm just odd like that...

On a xygine related note I've been working more on Lunar Mooner (working title), adding 3D models using xygine's mesh renderer, and a new mini-mode transitioning between levels of the game:

I have a second mini-game planned although the 'Planet Hopper' mode needs a fair amount of polish before I start on that. As usual you can keep track of the updates (along with all the fresh new bugs...) via the repository.

Wednesday, 10 August 2016

Tiled map support in xygine

To expand the list of features of xygine (and because I needed it for a project I was working on) I have added support for Tiled tmx maps to xygine. xygine is, of course, my SFML based 2D framework which collects together all the boilerplate code required to create an entity component based scene graph, and tmx support is a handy addition. Unlike the SFML tmx loader of old xygine completely separates the parsing of tmx XML files and the rendering of maps. This means that while xygine has complete parsing support for all current (as of time of writing) tmx features, it is renderer agnostic, and drawing a specific map type can be implemented independently. Currently xygine features a component for rendering orthogonal maps, which is the most common usage, using a special shader to render the tiles *without* tearing. It also has a set of utility functions which can be used to convert map objects into xygine's physics components, so loading collision data and dynamic objects is quick and easy. The example project contained in the xygine repository now has a tilemap state which demonstrates loading a simple platform style map. As the parser is completely independent to the renderer it is also easy for any user to create a custom set (or subset) of rendering components for any map style, including the hexagonal, isometric and staggered maps. Here's a short video of a project I've been working on using xygine, which is now open source:

I've also recently updated the minimum requirements of xygine to meet the newest 2.4 release of SFML. To read more about tmx support in xygine, check out the wiki page as well as the example application. If anybody wants to submit a custom renderer to xygine pull requests are welcome!

Friday, 24 June 2016

xygine Feature: 3D Model Component

xygine is, at its heart, a 2D framework. While working on Lunar Mooner, however, it occurred to me that attaching 3D models as components may look better than creating 2D sprite sheets by pre-rendering 3D models. A lot of work is needed to create a sprite sheet, particularly when updating one after tweaking a model, so it seemed to make sense to provide the ability to render the 3D models directly in a scene. Don't get me wrong, xygine isn't going to become xyzgine at any point (geddit?) – the scene itself remains entirely 2D and any model attached to an entity remains firmly rooted in two dimensional space. It does mean, however, that 3D rendered models reap the benefits of using raw OpenGL, such as real time lighting and dynamic shadow casting. xygine already contained a lighting system which implemented point lights and a single directional light so building on this was an obvious choice. It means that 3D rendered objects are lit in exactly the same way as any of the traditional drawables, making everything blend together nicely. Rendering 3D models directly also means that once a model is animated it can be used right away, without the laborious task of stitching together sprite sheets.

Actually implementing what became the MeshRenderer wasn't trivial, however. Thankfully the task was made much easier by the existing SFML Texture and Shader classes which provide the ability to obtain the underlying OpenGL handle - this gives access to all the flexibility of raw OpenGL calls, while still being able to use the SFML interface. One of the biggest problems was the fact that the MeshRenderer relies on OpenGL 3.2 as a minimum, while SFML works with GL 2.0. This can cause some compatibility problems, particularly on OS X and macs with integrated Intel GPUs. The MeshRenderer class is a completely independent part of xygine though, and if it is not needed then never instantiating it means compatibility problems aren't an issue. The MeshRenderer works by watching a scene and maintaining its own view based on the current active camera. It then makes sure any model components, created via the MeshRenderer's factory function, are correctly aligned with the two dimensional scene. This does mean that the 3D world units are measured in SFML units, approximately in pixels, which can be a bit confusing at first. Often 3D models have units which are much larger such as inches, feet or metres. This can make models appear very small when initially loaded into xygine. The easiest solution to this is to set a scale on the model's parent entity, however the currently the supported model format of choice is *.iqm – an open binary model format developed by one of the Sauerbraten guys, Lee Salzman. There is an exporter written for Blender which, while not totally intuitive to use right off the bat (for me at least), provides a good clean and feature rich output of IQM model files. It has the benefit of not needing an intermediate format (although it also provides IQE, an ascii based output) and one of the features is the ability to scale models on export, so you can make sure they'll fit xygine perfectly. Currently xygine will load an IQM mesh file and any animations which are compiled within it. It also reads material data, but as yet does not parse it and materials have to be loaded by hand. I also plan on supporting animation only files which can be loaded on to a mesh separately.

The MeshRenderer takes a deferred rendering approach, so currently does not support transparent materials, but it does mean lighting calculations are efficient and even with multiple shadow maps a good (~200fps) frame rate can be maintained at 1080p on my old 2.1 GHz Intel machine with an nvidia GTS450 GPU. Performance can vary of course, mostly due to the number of active shadow maps which can be a maximum of nine, eight of which are point lights. Point lights can have shadow casting disabled, however, allowing some fine tuning per application. As the MeshRenderer is drawn over the top of a xygine scene the scene itself generally appears behind everything rendered in 3D. It is entirely possible, on the other hand, to render the scene to its own texture and use that with a quad which can be placed in the MeshRenderer. This gives proper z-ordering results, as well as meaning that 2D objects will receive shadows, for some interesting effects. Quad and cube meshes are readily available because the interface for model loading is designed to be flexible enough that loaders can be created for other model formats with minimal effort. For example as long as the MeshBuilder class is inherited, a loader for *.obj, *.mdl or any other type of model can easily be implemented. This also means it is trivial for xygine to provide such MeshBuilders for cubes and quads. I've completed as much of the doxygen documentation as possible, although I've yet to fully update the wiki as some aforementioned features are yet to be implemented or finalised. The xygine example application includes a MeshRenderer in the 'Platform Demo', a video of which can be seen here:

The menu on the side appears in debug mode and allows switching the output between the various deferred renderer stages as well as the active shadow maps (black shadow maps are inactive or non-existent shadow casters). The release build of xygine completely omits this menu for the sake of performance. There are also a series of console commands available for the MeshRenderer, which can be found by typing 'list_all' into the console while a MeshRenderer instance is active. These mostly mirror the function of the debug menu.

As always the full source is on Github, released under the zlib license. I'm currently looking for OS X testers, so contributions via the Githuib page are gratefully accepted.


Batcat model supplied by my talented friend Josh

Saturday, 28 May 2016

Explicit function parameters in C++ 11 (and a lesson in cross platform data types...)

A slight detour from the normal content this post, but I recently discovered a neat trick in C++ which I'd really like to share. When working on xygine recently I blundered into a bug when using the following function in the MultiRenderTexture class:

create(sf::Uint32 width, sf::Uint32 height, std::size_t count, bool depthBuffer = false);

What this particular function actually does isn't important, so much as what I was doing wrong. (If you're interested it creates a new render target sized width * height with count textures). In my code I mistakingly missed out the count parameter:

create(w, h, true);

The problem with this is that the boolean value implicitly converts to an integer without even a warning, and because of the default value supplied in the signature of the function what the compiler saw was:

create(w, h, 1, false);

The bug right here was that I couldn't fathom why a depth buffer wasn't being created on my render target (due to the 'false' parameter). Once I finally figured out what exactly the bug was, it got me thinking about how class constructors can be labelled 'explicit' to prevent this sort of thing from happening, and how it'd be useful to do the same for normal (and member) functions. The explicit keyword cannot be applied to functions in the same way as constructors, but a short trip on the googlemobile revealed this, in my opinion, much underrated answer on stackoverflow. The idea is this: using the C++11 delete feature (you've probably seen it applied to default copy constructors and assignment operators) which *can* be applied to functions, you can create a deleted template function so that all but the explicitly stated overloads are deleted. These signatures are then implicitly explicit, if you will. The modified create function then looked like this:

create(sf::Uint32 width, sf::Uint32 height, std::size_t count, bool depthBuffer = false);
template <typename T>
create(sf::Uint32 width, sf::Uint32 height, T count, bool depthBuffer = false) = delete;

Now with anything but a size_t as the count value the compiler would throw an error. Perfect. Or was it? What followed next was a little lesson in typedefs, and cross platform implementations of the STL.

Eagerly I tried my modified source on linux. On windows I had been working with a 32-bit build, and with the explicit function parameters in place I needed to state '1u' as the count value. Not even '1' but '1u' as std:size_t is a typedef for an unsigned int, and the signature had to match exactly. Unfortunately when compiling the source on xubuntu with g++5.1 I was presented with an error claiming no matching signature was found. Hm.
Being the patient and open minded soul that I am I immediately wrote it off as 'a bug in g++', cursed linux a little bit, then went away disappointed my new found trick wasn't going to work everywhere. Of course I was wrong. Later that day a discussion on IRC about how std::time_t was a 64bit value in 64bit builds but only 32 bits in size on 32bit builds got me thinking... to which other typedefs does this apply? Quickly I realised that, unlike my current windows build, my linux build was 64bit and, indeed, std::size_t was a 64bit typedef. To get a matching signature g++ was expecting '1ul' not '1u'. Hoist by my own explicit petard! Simply changing the type from std::size_t to sf::Uint32 (SFML has its own set of nice cross-platform typedefs, we'll ignore the fact that any of these types are hugely overkill when representing any value less than 5...) ensured that the deleted template method now worked across all builds. Fantastic!

 And not one, but two lessons learned.

Wednesday, 25 May 2016

xygine Feature: Deferred Rendering

Although I claimed that I wouldn't be posting a lot about xygine outside the wiki, I also have to admit that every once in a while I like to give my own horn a damned good toot. One of my favourite features of xygine is the MultiRenderTexture. This class inherits the sf::RenderTarget class from SFML, making it a compatible drawing target that behaves not unlike a regular sf::RenderTexture. The main difference is that it contains up to 4 textures which are all drawn on at the same time. This is ideal for effects such as deferred rendering, where normal map, colour and mask data are all drawn to seperate textures, then blended in a single call which performs all the lighting calculations at once. This gives rather pleasing results when combined with the lighting and default normal map renderer provided with xygine (the banding is an unfortunate side-effect of video compression):

It is of course also flexible enough that user defined shaders can be implemented easily for any effect desired. The source for the demo is now included as part of the example project in the xygine repo. The textures were created from a 3D model made by a good friend of mine, whose other, rather beautful, creations for Dota2 can be found here.

There is one small caveat however: due to the inverse Y coordinates of SFML the output of the MultiRenderTexture can appear upside-down when drawn with a regular sf::Sprite. SFML works around this internally by flipping its textures, but unfornately xygine does not have access to this. It can be easily worked around when using an sf::Sprite, however, by setting the sprite's Y scale to -1. VertexArrays can simply invert their texture coordinates, and, when feeding the output to a shader uniform (as one would, when combining the textures in to a final image), the inversion doesn't matter at all because it is as OpenGL natively expects it to be.

Of course the MultiRenderTexture isn't limited to deferred rendering - other tricks can be performed if you're feeling creative. For example this scene is rendered to one texture normally, but on the second texture a faux 'depth' value of the drawable is used to set the pixel colour. Blurring a copy of the scene and then blending it using the faked depth texture can provide an interesting depth-of-field effect:

uniform sampler2D u_texture;
uniform float u_depth;

void main()
    gl_FragData[0] = texure2D(u_texture, gl_TexCoord[0].xy);
    gl_FragData[1] = vec4(vec3(depth), 1.0);

MRT Textures

uniform sampler2D u_colourTexture;
uniform sampler2D u_blurredTexture;
uniform sampler2D u_depthTexture;

void main()
    float mix = texture2D(u_depthTexture, gl_TexCoord[0].xy).r; //all channels are the same so pick one
    vec4 colour = texture2D(u_colourTexture, gl_TexCoord[0].xy);
    vec4 blurredColour = texture2D(u_blurredTexture, gl_TexCoord[0].xy);
    gl_FragColor = mix(colour, blurredColour, mix);

Output of blended textures

This is but one of the many features xygine has to offer. To find out more about what you can do with xygine take a look at the wiki.

Wednesday, 18 May 2016

SFML TMX Map loader 2.0.0

...is being worked on. No it's not out yet so don't get too excited. I thought I ought to post a status update, however. The popularity of the map loader still surprises me - after all it was a learning project which I started 3 years ago now (a long time in the world of programming) because I wanted to load TMX files from Tiled for a project I was working on. While the map loader has certainly come a long way since, and supports some features of which I am very proud, it is, ultimately, a buggy, poorly designed mess. A few months back I set out to address this, and created a new branch on the github repository. I've even worked on it a bit. So far I've taken the peculiar naming scheme I used at the time and replaced it with something that regular SFML users will be used to. I've paid serious attention to the build system too - the CMake file is much improved and compatible with KDevelop and QtCreator. There's also an included Visual Studio project for the library and example files. On top of this I've made sure the interface is properly exported so that the library can be built as a shared library, either a .dll, .so or even a .dylib. I've worked on a few issues from the tracker too, including vastly improving the MapObject class, making the most of SFML classes such as sf::Transformable. Unfortunately there's still some way to go before a full release, I've updated the issue tracker where I can with bugs and features tagged for the 2.0.0 milestone which I'd like to fix and implement eventually. Time, as ever, is the enemy unfotunately and I just don't have enough of it to work on all those issues right now. I'm not abandoning the project, but I would like to put it out there that I, and all the other users of the library, would certainly be grateful for any contributions (as well as to all the existing contributers). Hopefully a community driven version 2.0.0 will prove to be a vast improvement over the current version. You can preview the already superior version of the map loader by checking out the 'next' branch of the repository.

Monday, 9 May 2016

Introducing xygine

I have briefly mentioned xygine in previous posts, and now that it's further along in development I'd like to talk about it in a little more detail. Over the last few years, working on various game-oriented projects, I started to build up quite a large reusable codebase of features often used in development. These are features such as an entity-component system with renderable scene graph, post process effects, networking connections and configurable animation systems. I eventually collected all of these into a single library to which any SFML based project can be linked in order that game prototyping can be done quickly and easily, as well as remaining flexible. Boiler plate code such as reading/writing preferences to disk or creating a state stack are all provided so that combining stock components with custom component data can quickly create game entities and ideas can be tried out in a relatively short amount of time. This library I have dubbed xygine - simply xy because of its 2D nature, along with 'gine' - short for engine. Strictly speaking xygine is a framework and not an engine, but xyfram wasn't as catchy...

    xygine is open source under the liberal zlib license and so can be used freely in any project. It works on most supported SFML platforms; Windows, Linux and OS X, although is not tested on mobile platforms. Currently it is very usable, I'm developing Lunar Mooner (working title) a space themed rescue game with it, although xygine receives frequent updates as I uncover bugs throughout development or decide to add new features. Because of this it hasn't warranted a 1.0 release... yet. Ideally I'd like to post various tutorial type topics on this blog about it, but that may not happen as the xygine wiki already has a decent amount of content, and I'd like to keep information as centralised as possible, so any tutorial based stuff will most likely appear there. I've also gone to some lengths to try and document xygine as completely as possible, including full doxygen compatible comments. The documentation can be generated directly from source, and I maintain copy online here, although it may occasionally fall behind the current revision. As a quick demo here's a work in progress video of Lunar Mooner:

There is a list of other games (including pseuthe!) which are based on earlier versions of xygine on the wiki. The xygine repository also includes an example project which demonstrates how to build and link to the library, as well as some of its features such as particle systems, the physics binding to Box2D and a networked (online!) version of pong.

Dynamic lighting and particle systems

Physics with Box2D

While I hope that other people may find xygine to be useful I'd also like to point out that it is part of a learning process, for me, personally. There are certainly flaws in certain aspects of the design as well as in the codebase itself, so while I'd love to hear of other people using xygine I'll not tout it as an all dancing game-dev magic bullet. On the other hand, if not via xygine itself, I'm confident that it'll provide a great platform for good things to come.