Wednesday, 25 April 2007

Transparent textures with MDX

This is just a quick, late night writeup on how to draw transparent textures onto the screen using Managed DirectX.

Firstly, we load the texture in an initilisation routine:

public void Initialize()
{
tex = TextureLoader.FromFile(Form1.Device, ".\\test.png");
rect = new Rectangle(50, 50, 40, 40); // assuming our png is 40x40
}

Then we render the texture onto a 2-triangle trianglefan:

public void Render()
{
// device has been cleared and beginscene has been called

CustomVertex.TransformedTextured[] screenVertices =
new CustomVertex.TransformedTextured[4];
screenVertices[0] = new CustomVertex.TransformedTextured(
rect.X, rect.Y, 1.0f, 1.0f, 0.0f, 0.0f);
screenVertices[1] = new CustomVertex.TransformedTextured(
rect.X + rect.Width, rect.Y, 1.0f, 1.0f, 1.0f, 0.0f);
screenVertices[2] = new CustomVertex.TransformedTextured(
rect.X + rect.Width, rect.Y + rect.Height, 1.0f, 1.0f, 1.0f, 1.0f);
screenVertices[3] = new CustomVertex.TransformedTextured(
rect.X, rect.Y + rect.Height, 1.0f, 1.0f, 0.0f, 1.0f);

Form1.Device.RenderState.SourceBlend = Blend.SourceAlpha;
Form1.Device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
Form1.Device.SetRenderState(RenderStates.AlphaBlendEnable, true);
Form1.Device.SetTexture(0, tex);
Form1.Device.VertexFormat = CustomVertex.TransformedTextured.Format;
Form1.Device.DrawUserPrimitives(PrimitiveType.TriangleFan, 2, screenVertices);

// endscene and present will be called by main render loop
}

The important things to notice are:

  1. RenderState.SourceBlend = Blend.SourceAlpha
  2. RenderState.DestinationBlend = Blend.InvSourceAlpha
  3. SetRenderState(RenderStates.AlphaBlendEnable, true)

This is what the final product looks like:

No comments: