Tesla Content Pipeline Overview

6:50 am in Tesla Engine by Starnick

ISavable Serialization

 

 

 

 

 

 

 

 

 

 

Monday night document dump!

I have uploaded a (brief) introduction to the engine’s content pipeline on googlecode. The document discusses the content manager, types of assets, and gives an overview of ISavable serialization (as well as all the associated interfaces, and dives somewhat into the binary implementation). Hopefully it should give new-comers an idea of how everything is put together, at least at a high level. What it doesn’t contain is a tutorial on how to actually write your own loaders for your own custom objects though. That topic is for another day!

Material Parser v1.1

1:10 pm in Tesla Engine by Starnick

Just pushed a series of commits to the subversion repository, which bring many enhancements (mostly minor) notably changes to material parsing. I completely redesigned and rewrote the parser to be better organized, more stable, and more efficient. In addition, it supports just about all the items left on my TODO list:

1. Comment parsing is a lot less finicky now. No need to space them, put them on new lines, etc.

2. Multiple materials are now allowed in a single script file.

3. Renderstates now can be fully configured.

4. Added support for the Color data type (R G B A format, integer values that get clamped to the 0-255 byte range)

To support multiple materials, the old material loader has been separated into two distinct content loading paths. Loading a single material script, or the very first material in a multiple material script file is exactly the same as it was. In order to load multiple materials, you must use a MaterialCollection object:


MaterialCollection materials = ContentManager.Load<MaterialCollection>("Materials/MyMaterialScript.tem");

foreach(Material mat in materials) {

//Do something with the material

}

The MaterialCollection is cached inside the content manager, not the individual materials. You can also exclusively use this way of loading, as TEM files with a single material can be loaded into a MaterialCollection. The collection will simply contain a single material.

I have compiled a nice little (well it’s quite large and comprehensive actually :) ) PDF documentation that goes over the correct syntax and all the features of a material script here. It has quite a few examples that should make it very easy to get started with scripting!

The last piece of the puzzle holding back the release is serializing materials into TEM files. Currently, serializing the scene graph works beautifully, but you’ll have to recreate materials manually when de-serializing the scene from the binary file. I aim to have some sort of option or hook (most likely tied to the unimplemented “WriteExternal<T>” ISavableWriter methods) so you have the option to either write materials to binary files (TEBO) or the text-based TEM files. This also includes writing our effects and textures to their own TEBO files. So there’s a few moving pieces here that I want to make sure all mesh nicely in the system.

There really isn’t a point saving everything into one giant file (can’t re-use anything and end up wasting disk space). On the other hand, you have to make sure you don’t overwrite files and lose data! Most likely, writing multiple files will be ideal for individual models and not for large scenes. In the latter case, a single file may be ideal (or some other level format).

Some new effects

3:13 pm in Tesla Engine by Starnick

Thought I’d give the blog a spin for a change, since I’ve moved most of my updates to the twitter feed. Work on Tesla is a bit slow, but steady as I’m currently juggling three different projects. The past week I thought I’d take a break from the drudgery and actually do some cool graphics programming for a change! I’m also including these in the sample browser.

Glow Effect

This is an effect I’ve wanted to do for a while (especially after playing the X3 games), it’s essentially a bloom post-process effect. Instead of extracting the brightest parts of the scene however, you control how much geometry glow via a glow map. You render all your objects that self-illuminate to a render target, apply a gaussian blur filter and then composite that image with the final frame buffer contents. When rendering your objects normally, you also include the glow map to control the emissive lighting term (like a specular map, that way you can also tweak it with a material emissive parameter to change its intensity). That way your object looks right when the glow effect is applied to parts of it that are in darkness. Overall it’s a pretty cool effect, as these pictures can show.

There's always a glowing box for these sorts of things!

This is the model from the glow sample. It actually came with an emissive map that I colorized to use in the effect.

One of my favorites as the cool blue engine glow really looks good!

 

Thick Wireframes

The second effect is a familiar topic: wireframe drawing. Drawing thick lines is actually a widely asked topic in the D3D world, since unlike OpenGL there’s no easy/fast way of doing it. So you tend to end up with very thin, hard to see wireframes that are badly aliased and fight with the solid model underneath (usually applying a depth bias to the wireframe helps, but care needs to be taken in making sure that bias isn’t too large). I found an interesting technique on the web the other day that deals with drawing nice thick and smooth wireframes over solid objects:

http://www2.imm.dtu.dk/~jab/Wireframe/

It’s really an interesting idea – essentially the technique has you draw wireframes as solid triangles where you switch from fill color to wire color depending on the distance to the triangle edges. So it’s actually a single-pass technique, although you can have a transparent fill color and blend it with the object (actually that’s what I do in the sample, to preserve lighting). As you can see in the image below, it’s a pretty stark difference. The downside is you need to replicate data, since each vertex needs to know the other two vertices in the triangle, although the technique can also be done using geometry shaders (in fact Nvidia has such an implement here). Another interesting perk of this technique is you have complete control how the wireframe is drawn, so you can have interesting effects like a dotted edge or remove the interior of the polygon to get a halo-ed line (see the original link for images!).

Left: Teapot rendered with this technique. Right: Teapot wireframe rendered the naive way (no depth bias however).

 

Last but not least…

Shadow mapping! I’ve put off bringing shadows to Tesla for a while now. I hope to implement some helper classes/shadow managers in setting up scenes that require shadow map generation really easy too.

Shadows with the greek statue.

And some more shadows.

Sprite Batching

12:59 am in Tesla Engine by Starnick

So half a week ago I began experimenting with rendering Bitmap (or just BM) fonts. Bitmap fonts are nothing more than a texture atlas with all your characters and some file that contains each character’s UV coordinates, spacing values, and kerning pairs (to adjust spacing between specific characters). The engine has been sorely lacking any GUI capabilities, especially drawing text to the screen. I am personally using the BM Font generator that can be downloaded from www.AngleCode.com. They have a very nice generator utility that exports a texture (PNG, DDS, TGA – I’ve been using PNG) and an XML file that describes it.

Now when drawing BM Fonts, you’re essentially using a quad that’s projected directly onto the screen (so everything’s done in screen coordinates). However, this can get out of hand, performance wise, fast if you render a lot of text. The orthographic render bucket and quad shapes were out of the question, I needed batching capabilities. I needed something more in line with XNA’s SpriteBatch (or Direct3D’s sprite rendering period) functionality.

So I went off on a 4-day tangent and implemented my own sprite batch (very similar to the XNA SpriteBatch API). It allows you to flip, scale, and/or rotate your sprite. Additionally, you can crop the UV coordinates (needed by my BM Font rendering), and specify the destination rectangle (the rendered rectangle’s size). More importantly, you can specify sprite sorting to enable smart batching – that is, it renders sprites that use the same texture in order to reduce the amount of render state switching. In order to batch the sprites, it uses a wrap-around dynamic vertex buffer, so data won’t be written to areas of the buffer that are currently being used (to prevent pipeline stalls) and so we don’t have to keep recreating graphics resources.

Sprite sorting parallel’s the XNA capabilities, and which also resemble the render queue sorting methods:

  • Immediate – no sorting, no queuing, add to the vertex buffer and render (will be slow!). This is the least optimized mode, but was the easiest (and first) piece of the design I implemented in my prototype, so I kept it.
  • Deferred – queue sprites, at the end render them all in the order they were submitted (so no sorting). This is the default
  • Texture – queue sprites, sort by texture. So all sprites that use Texture A are rendered together, then all sprites that use Texture B, and so on.
  • BackToFront – queue sprites, sort by Z value (higher values are closer, lower values are farther).  This is so you can render transparent sprites correctly, if you don’t submit your work in the correct order.
  • FrontToBack – queue sprites, sort by Z value again. This can benefit opaque sprites, since pixels are rejected and overdraw is prevented.

Another reason why I mirrored the XNA SpriteBatch was it’s a very easy and useful tool to quickly build a cool App. Hopefully this will make the engine a bit friendlier to the XNA crowd, since the XNA SpriteBatch won’t be visible at the engine’s interface level. It’s not really a functionality that meshes with the design of the graphics library (e.g. Abstraction – Implementer bridge pattern), especially since SlimDX does not have something like SpriteBatch. Therefore my implementation is renderer agnostic, and will work with any renderer.

There’s still some left over pieces I need to polish up (API documentation for one), including flipping for text rendering, but you can see it in action in the screenshots below. Both of these shots show the very simple, but effective GUI I created for the sample browser (which I also pushed to the SVN today, at least partly – not all samples are in yet).

Effect Compiler Tool

1:12 pm in Tesla Engine by Starnick

Just added a tool to the SVN that I developed several months ago (cleaned it up a bit, added some additional user-friendly settings) to compile the engine’s shader libraries into the binary TEBO files found in the D3D10/XNA default content. As an added bonus, the source code for all the engine shader implementations are included.

The tool is useful for building your shaders in a large batch, and if there’s any errors you’ll be notified via a message box where the parsing error occurred. So it’s easy to make sure your shaders compile correctly before adding them to your application project. Also, the tool enables you to compile for all the available platforms (D3D10 windows, XNA Windows, XNA Xbox). Note that you will need XNA Gamestudio 4.0 installed to make use of the XNA effect compilation.