Logo of the Nuclex Framework, the text "Nuclex" with three green dots on a blue ring

Nuclex Framework R1404 Released!

The word 'Nuclex' in a stylish font framed by an elliptical ring with three dots

A few hours ago, I uploaded a new release of the Nuclex Framework to CodePlex. There has been an intermediate release, R1323, which I didn’t announce here because it was more or less just a stop-gap measure to stop reports for issues in the old (old, old) R1242 release where my Nuclex.Input library was still subclassing XNA’s Window.

This is what changed from R1242 to R1404:

  • Thanks to a generous contribution by Adrian Tsai, the TrueType importer now accepts standard Windows font names – this is a big step towards being a drop-in replacement for XNA’s own sprite font importer.
  • The TrueType importer now lets users choose different hinting algorithms. No hinting will result in MacOSish blurred text that stays true to the font’s metrics. The auto hinter from FreeType is a nice compromise between forcing strokes into a pixel raster for sharpness and retaining the font’s look (and imho the best option). Native will produce a perfect match with Windows’ font rendering, producing sharp letters that may deviate from the font’s actual metrics a bit.
  • You can now decide whether SpriteFonts imported by the TrueType importer are centered on their baseline or on their upper end (like XNA). This, together with the improved font name lookup turns the Nuclex TrueType importer into a 100% drop-in replacement for XNA’s font processor.
  • Nuclex.Input’s game pads now provide a method .GetExtendedState() with which you can access all of DirectInput’s 128 possible buttons, 24 axes and 8 sliders. I designed this so that there’s zero overhead if you don’t use the .GetExtendedState() method. The ExtendedGamePadState already normalizes axes for you (from -1.0 to +1.0 for axes and 0.0 to 1.0 for sliders) and in general is much nicer to work with than using DirectInput directly!
  • Nuclex.Input now supports TouchPanel input. That includes mocking TouchPanel input: You can easily simulate the TouchPanel in your unit tests:
    var m = new MockInputManager();
    m.GetTouchPanel().Press(42, 10.0f, 10.0f);
    m.GetTouchPanel().Move(42, 20.0f, 10.0f);
    m.GetTouchPanel().Release(42);
  • The GUI is now based on the Nuclex.Input library. That will allow me to soon implement TouchPanel input and make the GUI usable on Windows Phone 7. Note that you can easily hack Windows Phone 7 support into a project by converting touch input into mouse input. Due to the modular design of Nuclex.Input, you don’t have to touch a single line of code, simple create your own IInputCapturer!
  • The game state manager has undergone a redesign. Existing projects shouldn’t be in trouble, the redesign gets rid of the GameStateManager reference (you can remember the Reference yourself if you want your states to initiate a transition themselves). Pop-up game states similar to XNA’s game state management example are now supported.
  • Upgraded to NMock 3.0. This is mostly an internal change but it really helps being refactoring-friendly as my unit tests no longer contain method names hardcoded in strings anymore.
  • All assemblies in the Nuclex Framework are now signed with a strong name, this no longer preventing you from signing your own assemblies.
  • And of course, all issues that were reporting through various channels have been fixed — excluding two possible problems I can’t yet reproduce, but will mention here for honesty: the AffineThreadPool might sometimes be skipping a task under heavy load and there might be a problem in the PrimitiveBatch when it is handed large amounts of vertices. I couldn’t reproduce these issues and they’re not occurring in my own game, but if anyone notices such an issue, please contact me!
Comparison of SpriteFont rendering quality

XNA Sprite Font Quality

Screenshot of fonts in XNA 3.1, XNA 4.0 and the Nuclex font processor There has been a discussion on the XNA forums regarding a slight decrease in the visual quality of SpriteFonts from XNA 3.1 to XNA 4.0: XNA 4.0 renders SpriteFont differently (and not for the better).

There are two changes that might have impacted visual quality: XNA 4.0 uses premultiplied alpha everywhere (whereas XNA 3.1 processed the alpha channel as-is) and, as revealed by "Krome Studios", The FontDescriptionProcessor in XNA 4.0 generates a texture with DXT3 (a form of compression that limits each block of 4×4 pixels to contain only 4 different colors and reduces the alpha channel to 4 bits of precision or 16 levels, see Wikipedia).

Because I’ve written a custom FontDescriptionProcessor for XNA 4.0 which outputs compatible SpriteFonts but uses FreeType instead of Windows’ GDI font API, I decided to do a little comparison.

Read More
Chart showing the PrimitiveBatch benchmark results in XNA 4.0, clipped to 500 FPS

DynamicVertexBuffer versus DrawUserPrimitives, Round 2

More than a year ago, I did some benchmarking in XNA 3.1, comparing the vertex throughput I could achieve on my GeForce 8800 via XNA’s DynamicVertexBuffer class versus just calling GraphicsDevice.DrawUserPrimitives(). Here’s my earlier benchmark: Efficiently Rendering Dynamic Vertices.

In all cases, DrawUserPrimitives() was marginally faster than the DynmicVertexBuffer, but it appeared to be a very bad idea to use a DynamicVertexBuffer on the Xbox 360. I had a really nice discussion with Shawn Hargreaves on the XNA forums where he provided a lot of in-depth information about how things work on the Xbox 360: .

One of today’s threads on the AppHub forums reminded me if my earlier benchmarks, so I decided to dig out my old benchmark and redo it in XNA 4.0. The benchmark uses my Nuclex Framework‘s PrimitiveBatch class, which underwent some changes since then, so I repeated the XNA 3.1 benchmarks in addition to getting the new data for XNA 4.0.

Read More
Logo of the Nuclex Framework, the text "Nuclex" with three green dots on a blue ring

Nuclex Framework R1242 Released!

The word 'Nuclex' in a stylish font framed by an elliptical ring with three dots

There’s a new release of the Nuclex Framework available on CodePlex!

The new release adds a new library, Nuclex.Input, which is a very lightweight library that adds seamless support for DirectInput game pads and joysticks, well-behaving keyboard text input, event-based input and the ability to mock any kind of input in your unit tests. Instead of firing up your XBox 360 each time, you can now write simple tests that simulate controllers being attached and detached.

Also new is full support for XNA 4.0 on x86 and XBox 360. Windows Phone 7 is also supported by most of the libraries. The PC builds all target the .NET Client Profile, allowing you to reduce the footprint of your installer. Special .NET 4.0 client profile builds of the third-party libraries (LZMA, NUnit, NMock, log4net and SlimDX).

Of course, all bugs reported since the last release have been fixed!

Logo of the Nuclex Framework, the text "Nuclex" with three green dots on a blue ring

New Component: Nuclex.Input

The word 'Nuclex' in a stylish font framed by an elliptical ring with three dots

Developers following my twitter feed may already know that in the past few days, I’ve been working on a new component for the Nuclex Framework: Nuclex.Input. This component aims to solve all problems I ever had with input devices in XNA :)

It’s a very simple library that provides input device classes similar to the ones in XNA (Keyboard, Mouse, GamePad), but instead of 4 game pads, there are 8 (with indexes 5-8 for DirectInput-based controllers). All input devices provide events (like KeyPressed and CharacterEntered on the keyboard or MouseWheelRotated on the mouse, for example). Here’s a quick run down of the features:

  • Well-behaving keyboard text input

    • Honors keyboard layout and system locale
    • Supports XBox 360 chat pads
    • Very easy to use: just subscribe to an event
  • Support for standard PC game controllers

    • Works with any DirectInput-compatible controller
  • Mouse movement with sub-pixel accuracy (postponed)

    • Finally put those expensive high-dpi mice to use ;-)
  • Allows event-based input handling

    • Fully type-safe: events instead of message objects
    • Only compares states if events have subscribers
    • Mouse and keyboard don’t have to compare states at all
  • Zero garbage: doesn’t feed the garbage collector

    • During usage, the library produces zero garbage

Curious? Click on “Read More” to view some code samples!

Download

This component will be in the next release of the Nuclex Framework!
If you want it now: Nightly builds, Source code (svn)
Read More

Quo Vadis, Input System?

I’ve spent some time thinking about how input is handled by my GUI library. One issue I didn’t cover in its initial design is that people might want to use the GUI library at the same time as their game is running (think of a command palette in a strategy game). I’ve already got some requests on the CodePlex forums (How to determine if a screen-position (i.e. mouseclick) is on any gui-control ? and Unfocusing from GUI) and it’s about time I did something about this.

In the old design, an IInputReceiver was fed by one of two classes: one was the XnaInputCapturer which relied completely on XNA’s input device classes (Keyboard, Mouse, GamePad) to track the status of any input devices, the other was the WindowInputCapturer which intercepted incoming window message for XNA’s main window to obtain the status of input devices:

UML diagram showing the input system with two distinct classes for XBox and Windows input

This wasn’t even nearly an ideal solution because now I would have to copy & paste the game pad polling code from the XnaInputCapturer to the WindowInputCapturer if I wanted game pad input on Windows. The new design should fix this, but still follow the concept of routing all input through a single interface (IInputReceiver) to allow users to easily attach the GUI to their own input handling code.

Read More
Logo of the Nuclex Framework, the text "Nuclex" with three green dots on a blue ring

Nuclex Framework R984 Released!

The word 'Nuclex' with a stylish font framed by an elliptical ring with three dots

I just uploaded a new release of the Nuclex Framework on CodePlex!

It has been a lot of work getting the GUI library finalized. For once, I really wanted to have 100% unit test coverage on the whole library, which meant a lot of work ensuring the design allowed for this and thinking of all the test cases. But hey, what other GUI library can provide that level of unit tests! :)

Another feature I didn’t want to let go of was control navigation with the game pad and cursor keys. The idea is that you, the developer, just throw some controls on the screen and the GUI will automatically figure out which control to change focus to when the player uses the thumb stick on his game pad. This means you can just add four buttons labeled “New Game”, “Options”, “Credits” and “Quit” to your screen and voilà, you’ve got a main menu the user can interact with using his mouse, keyboard or game pad.

Read More
Logo of the Nuclex Framework, the text "Nuclex" with three green dots on a blue ring

Nuclex Framework on CodePlex

The Nuclex Framework has been released to CodePlex today!

The word 'Nuclex' with a stylish font framed by an elliptical ring with three dots

Instead of only writing about all the cool stuff and then pointing people at my Subversion repository whenever someone asks for the source code, I finally sat down and published the entire Nuclex Framework on CodePlex, together with lots of examples, documentation and screen shots.

The Nuclex Framework consists of small isolated building blocks that you can pick from, so you can easily use just the things you require and ignore the rest (or even create your own trimmed-down edition of the framework if you’re not worried about doing it all again when a new version is out).

All the highlights I wrote about in this blog (and quite a lot that I didn’t write about) are neatly organized in there. And the code’s quality should hopefully speak for itself :)

Just to list some of the more interesting things, there’s a Deque collection (faster than List<> and LinkedList<> and much less garbage), 3D vector font rendering code, 7-Zip content compression, a 3D SpriteBatch equivalent, rectangle packing algorithms for texture atlas creation, a flexible multi-threaded particle system, a work-in-progress GUI library with skin support, a cleaner game state management system, a debug overlay renderer and some helpers that allow you to automatically create VertexDeclarations from a structure without listing the VertexElements by hand.

So what are you waiting for, check it out! :D

Efficiently Rendering Dynamic Vertices

Sometimes, games have to render highly dynamic geometry such as sparks, bullet trails, muzzle flashes and lightning arcs. Sometimes it’s possible to off-load the work of simulating these things to the GPU, but there are effects than can’t be done by the GPU alone.

These cases usually occur when effects require heavy interaction with level geometry or when they require lots of conditionals to mutate a persistent effect state. And sometimes, the effort of simulating an effect on the GPU is just not worth the results. If you have maybe a hundred instances of a bullet trail at once, letting the GPU orient the constrained billboards for the trails instead of generating the vertices on the CPU might just not yield any tangible benefits.

However, there are still a lot of traps you can run into. A typical mistake of the unknowing developer is to render the primitives one-by-one either using one Draw[Indexed]UserPrimitives() call per spark/trail/arc.

This is not a good idea because modern GPUs are optimized for rendering large numbers of polygons at once. When you call Draw[Indexed]UserPrimitives(), XNA will call into Direct3D, which will cause a call into driver (which means a call from code running in user mode to code running in kernel mode, which is especially slow). Then the vertices are added to the GPU’s processing queue.

By sending single primitives to the GPU, this per-call overhead is multiplied and can become a real bottleneck. To demonstrate the effects of making lots of small drawing calls, I wrote a small benchmark and measured the results on my GeForce 8800 GTS 512 and on whatever the XBox 360 uses as its GPU.

Chart showing a drastic performance bottleneck for excessive DrawPrimitive() calls

Read More