Color Keying in DirectX 8 Graphics

Home | Up | Search | X-Zone News | Services | Book Support | Links | Feedback | Smalltalk MT | The Scrapyard | FAQ | Technical Articles

 

Written by Robert Dunlop
Microsoft DirectX MVP

Related Articles of Interest:

A Simple Blit Function for DirectX 8

Introduction

The conversion to DirectX 8 Graphics from DirectDraw poses a few challenges, and one apparent stumbling block is the lack of direct support for color keys.  The use of source color keying in DirectDraw was commonly used to draw sprites with transparent regions, by not drawing pixels of an application specified color when blitting a bitmap.

Rather than supporting color keys, DirectX 8 Graphics relies on the use of a separate alpha channel in the source image to specify the amount of opacity / transparency of each pixel.  This provides a much finer level of control, allowing for translucent objects and finely feathered edges.

If the simple on/off control provided by color keys is what you need, though, this is easily simulated in DirectX 8 Graphics.  This article will cover the basics required for simulating source color keys.

Loading the Image

To render with transparency, you will need to generate a texture which has an alpha layer, with pixels of the desired key color set to transparent.  This can be performed automatically by the D3DXCreateTextureFromFileEx() function, by setting the ColorKey parameter to the desired key color.  For example, the following loads a bitmap and sets all magenta pixels transparent:

D3DXCreateTextureFromFileEx(m_pd3dDevice,
                            "test.bmp",
                            D3DX_DEFAULT,
                            D3DX_DEFAULT,
                            1,
                            0,
                            D3DFMT_UNKNOWN,
                            D3DPOOL_DEFAULT,
                            D3DX_FILTER_LINEAR,
                            D3DX_FILTER_LINEAR,
ColorKey ->                 0xffff00ff,
                            NULL,
                            NULL,
                            &m_texture);

Note that the alpha portion of the value specified for ColorKey must be 255, to denote an opaque color.  This is because the image being loaded has no alpha, and thus all pixels are considered opaque.  Failing to do this will cause no pixels to be set as transparent.

Rendering the Image

Simply having an alpha channel does not cause a texture to be rendered with transparency.  Alpha blending must be enabled (it is off by default), and the proper blending factors must be applied.  To do this, set the following render states prior to drawing with the texture:

m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

This causes the texture to be multiplied by its alpha component, and the current surface being rendered to to be multiplied by the inverse of the textures alpha component.  The results are then added to determine the resulting pixel color.

At this point you are ready to render the texture to the screen.  If you need information on performing a simple 2D blit with the loaded texture, check out A Simple Blit Function for Direct3D.

After you are finished rendering textures containing transparency, restore the render states back to their defaults:

m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO);

Related Articles of Interest:

A Simple Blit Function for DirectX 8

This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers.

Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000: Hit Counter
Last updated: 07/26/05.