This example illustrates how bitmap texture files with an alpha channel or a key color transparency can be mapped onto managed Direct3D vertex buffers in C#. In this example, .png, .bmp, and .jpg files provide the textures.
MatrixStack class is also used to create a simple hierarchical "scene" of the three textured vertex planes, each having its position dependent on the previous one. This "stacking" of transformations is useful for creating 3D user interfaces, robot-arm type movements, or can be used anywhere where one object location depends on another.
How the Texture Mapping Works
To render a texture bitmap, there are two key mapping or "transform" steps. The first step maps the loaded texture coordinates to a set of vertex coordinates stored in a vertex buffer. The second step maps the vertex buffer local coordinates to the final window coordinates. In the sample the vertices are simply two triangle strips that form a square plane onto which the square bitmap textures are mapped.
The transformation of vertex to window coordinates is performed by matrix multiplications that the Direct3D device performs internally when rendering. Another way to think of transforms are as "dependencies", where the local position "depends" on the world position which in turn "depends" on the view position and so on.
Local vertex matrices can be "stacked" (multiplied) using the
MatrixStack class to have the position of one object depend on the position of the other. Intuitively, this happens in 2D every time a parent window is dragged and the child moves with it. Similarly, matrix stacks can be used to create 3D windowing systems by processing this chain of dependencies from a tree that has been pushed and popped from the stack during traversal.
Running the Sample
This code uses the managed DirectX 9 assemblies, so they need to be installed in the search path. A nice feature of managed DirectX is that assembly DLLs can be simply copied into the EXE directory.
To run the demo, unpack the Zip and run 3DAlphaTransparency.exe. When building the source from the solution, the executable assembly will be placed in the "BinariesAndBitmaps/" subdirectory. Three sample bitmap paths are hard coded inside the C#
MainForm, and the bitmaps are located in the same directory as the 3DAlphaTransparency.exe.
Explanation of the C# Source Code
There are two main classes: the
MainForm, and the
TDPanel creates a single visible texture and vertex buffer, and the
MainForm instantiates three
TDPanel objects, stores them in an array list, and renders them using the
MatrixStack and Direct3D Device onto the
Configuring the Device for Alpha Blending
Alpha blending is enabled in
MainForm on device reset:
public void OnResetDevice(object sender, EventArgs e)
device.RenderState.SourceBlend = Direct3D.Blend.SourceAlpha;
device.RenderState.DestinationBlend = Direct3D.Blend.InvSourceAlpha;
device.RenderState.AlphaBlendEnable = true;
Loading the Textures with a Transparency Key Color
TDPanel loads in the texture using the
TextureLoader, and a bitmap with any magenta colored pixels will be rendered as transparent:
public void CreateVertexBuffer()
PanelTexture = Direct3D.TextureLoader.FromFile(
Mapping the Texture to Two Triangle Strips
The corners of bitmap texture (u,v) are then mapped onto the vertices of the two triangle strips that form a square in local coordinates, using the
public void OnCreateVertexBuffer(object sender, EventArgs e)
Direct3D.CustomVertex.PositionTextured verts =
verts.Z=0.0f; verts.Tu = 0.0f; verts.Tv=0.0f;
verts.X=-1.0f; verts.Y=1.0f ; verts.Z=0.0f;
verts.Tu = 1.0f; verts.Tv=0.0f;
verts.X=1.0f; verts.Y=-1.0f; verts.Z=0.0f;
verts.Tu = 0.0f; verts.Tv=1.0f;
verts.X=1.0f; verts.Y=1.0f; verts.Z=0.0f;
verts.Tu = 1.0f; verts.Tv=1.0f;
Rendering using the MatrixStack Class
MainForm creates three
TDPanel objects and stores them in an
MainForm also performs the rendering by creating the
MatrixStack, looping through the
TDPanels, and sending the world matrix and vertex information to the device to render:
private void Render()
DirectX.MatrixStack matrixStack = new DirectX.MatrixStack();
foreach(TDPanel tdPanel in panelList)
this.device.VertexFormat = Direct3D.CustomVertex.PositionTextured.Format;
this.device.SetStreamSource(0, tdPanel.PanelVertexBuffer, 0);
this.device.Transform.World = matrixStack.Top;
this.device.DrawPrimitives(Direct3D.PrimitiveType.TriangleStrip, 0, 2);
Further Creative Ideas
The use of alpha channels, transparency, and matrix stacks can be extended to create custom user interfaces and controls. Managed Direct3D provides a host of very powerful and high level rendering capabilities with just a few lines of code, and the visualization possibilities are only limited by imagination!
This is my very first submission to The Code Project. I enjoy reading many of the articles, and I look forward to reading your feedback.