A progress update – The terrain rendering has been improved to the point where I can stand to look at it – it’s now lit, is multi-textured and has some grass clutter. I created a robot model which replaces the old zombie, so now it’s a game with legit robots.
Legume 0.5
I’ve updated legume to version 0.5 which contains few changes but importantly now works in OSX. The [google code project page] contains the installers, and the source repository has been migrated over to [bitbucket] purely because I like it more google code, which hasn’t aged particularly well.
Pre-multiplied alpha
Pre-multiplied alpha is alpha blending done correctly. It involves changing your alpha blending states, and ensuring your texture colour channels (R, G, B) are pre-multiplied (hence the name) with the alpha channel (A).
Firstly the alpha blending operations will have to be changed:
- Set your source alpha blend to ONE (probably instead of SRCALPHA) – How solid our source texture appears depends on our alpha value alone (pre-multiplied colour channels at work here).
- Set your destination blend to INVSRCALPHA – The more solid our texture appears, the less light we should let through from behind
// Standard fare alpha texture operations Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture); Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse); Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate); // Important Device.SetRenderState(RenderState.AlphaBlendEnable, True); // New alpha blending render states Device.SetRenderState(RenderState.SourceBlend, Blend.One); Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
The next part is loading the texture data and calculating the new colour channel values – below is a C# snippet for reading a 32-bit bitmap and performing this calculation. We take a bitmap that has been loaded into memory, iterate over each pixel in the image, calculate our new R, G and B values and save them back into the bitmap. Using SetPixel and GetPixel would be far too slow so this example locks the bitmap data and accesses the colour values directly.
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct RgbaColor
{
// Huh?! turns out PixelFormat.Format32bppArgb should
// actually be called Format32bppBgra.
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
public unsafe static class DangerousTextureLoader
{
private static Texture LoadFromBitmap(Bitmap bitmap)
{
// Lock the entire bitmap for Read/Write access as we'll be reading the pixel
// colour values and altering them in-place.
var bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite, bitmap.PixelFormat);
// This code only works with 32bit argb images
Debug.Assert(bmlock.PixelFormat == PixelFormat.Format32bppArgb);
var ptr = (byte*) bmlock.Scan0.ToPointer();
for (var y = 0; y < bmlock.Height; y++)
{
for (var x = 0; x < bmlock.Width; x++)
{
// Obtain the memory location where our pixel data resides and cast it
// into a struct to improve sanity.
var color = (RgbaColor*)(ptr + (y * bmlock.Stride) + (x * sizeof(RgbaColor)));
var alphaFloat = (*color).Alpha/255.0f;
(*color).Red = Convert.ToByte(alphaFloat * (*color).Red);
(*color).Green = Convert.ToByte(alphaFloat * (*color).Green);
(*color).Blue = Convert.ToByte(alphaFloat * (*color).Blue);
}
}
// SlimDX specific stuff here
var newTexture = new Texture(_device, bitmap.Width, bitmap.Height, 0,
Usage.None, GetD3DFormat(bitmap.PixelFormat), Pool.Managed);
// SlimDX specific stuff
var textureLock = newTexture.LockRectangle(0, LockFlags.None);
textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride);
// The bitmap lock is freed here
bitmap.UnlockBits(bmlock);
// SlimDX specific stuff
newTexture.UnlockRectangle(0);
newTexture.FilterTexture(0, Filter.Default);
return newTexture;
}
}
You can read a better explanation and a link to a research paper at TomF’s tech blog. He also highlights how pre-multiplied alpha will help compress your textures using DXTn formats.
Daybreak
I’ve been spending the past few months working on a top-down zombie survival co-op game, it’s still very much still in the workshed.
This game, whilst rather rudimentary in it’s presentation, is actually designed to be a realistic zombie apocalypse survival simulator. We used a team of zombie survival experts* to plan situations that would call for coordination, teamwork and an assortment of firearms and melee weapons.
* they watched Dawn of the Dead once or twice. We did try and use somebody who’d watched Resident Evil 2, but he was past saving.
Microsoft certification
Last month I finished my second exam [70-562] – this means I’m now an MCTS in developing ASP.net Web Applications(hurrah!), unfortunately I have to print my own certificate (boo!).
I got quite a lot out of reading through the self paced training kits – though they’re DULL AS HELL, and full of errata. Lots of little unknown unknowns in my knowledge of C# and ASP.net got patched, and I learnt quite a bit about stuff I have never come across in my job or in my spare time.
The big downside to taking the examinations is the interface you’re forced with using – it’s bloody awful. Lack of mouse-wheel enabled scrolling of the question and answers, 800×600 resolution, no option to switch mouse buttons for lefties (minor point but still, it was a bit frustrating), and a strange UI behaviour where, if you click a radio button of a selected answer, it deselects it! – so my belt&braces OCD make-sure-I’ve-clicked-my-correct-answer method caught me out a few times. Despite the unnecessary hurdles, I made it through – seriously Microsoft, fix the interface.
Project-wise, I’m currently working on a top-down multiplay zombie shooter – Its in it’s infancy at the moment but you can find some early screen-shots on the Daybreak project webpage.
Legume is on hold for the meantime – it’s not dead – unlike zombies – which are.
Legume 0.2
Yup version 0.2 is available – obtain it via googlecode or pypi. I’ve made substantial changes to the API and the guts so it’s completely incompatible with version 0.1.
Legume – documentation
The API documentation for Legume 0.1 is now available, and will be updated regularly as more is added.
Version 0.2?
The work on the documentation and removing the bugs listed on the google-code page is towards the next release of Legume, which in all probability will be in the new-year. Stay tuned




