A Simple Blit Function for Direct3D

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

Demo w/ Source Code for this article

Target Version: DirectX 8.x
may require adaptation for other versions

Related Articles of Interest:

Rendering Full Screen Images from Textures
Using a Blit Queue

For those of you looking to perform 2D blits using DirectX Graphics under DX8, here is a quick function to perform the equivalent of a blit by rendering two pre-transformed polygons.  First, we will need to define a custom vertex that will contain screen coordinates, color, and texture coordinates.

#define D3DFVF_TLVERTEX D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1

typedef struct _D3DTLVERTEX {
    float sx; /* Screen coordinates */
    float sy;
    float sz;
    float rhw; /* Reciprocal of homogeneous w */
    D3DCOLOR color; /* Vertex color */
    float tu; /* Texture coordinates */
    float tv;
    _D3DTLVERTEX() { }
    _D3DTLVERTEX(const D3DVECTOR& v, float _rhw,
                 D3DCOLOR _color, 
                 float _tu, float _tv)
    { sx = v.x; sy = v.y; sz = v.z; rhw = _rhw;
      color = _color; 
      tu = _tu; tv = _tv;
    }
} D3DTLVERTEX, *LPD3DTLVERTEX;

Now we are ready for the rendering function.  Some notes on the function shown below :

  1. lpDevice is a pointer to an IDirect3DDevice8 interface.
  2. The z parameter passed is in the range of 0.0 (near) to 1.0 (far).  This represents the depth of the rectangle, and can be used to set the z-order of rendered images. 
  3. The first line of the function calculates an rhw based on the assumption that the projection matrix is set for a near plane of 10.0 and a far plane of 1000.0.
  4. lpSrc points to a previously loaded texture.
  5. The whole source image is rendered to the rectangle defined by the (left,top)->(right,bottom) coordinates
  6. Alpha or color blended transparency can be applied by setting the appropriate render states prior to calling this function, and passing a texture with an alpha channel if source alpha is used.
  7. Update! The function below has been updated to compensate for the texel alignment rules of Direct3D.  The vertices of the target rectangle are offset by -0.5 to allow proper mapping of texels to pixels.  Note that the last row and column, specified by the right and bottom parameters are not drawn, in accordance with the behavior of the blitting functions of DirectDraw.
  8. Important Note: Prior to using this method, D3D lighting must be turned off by setting the render state D3DRS_LIGHTING to FALSE.  This is because we are providing the lighting values for the vertices, not D3D.  Set this state back to TRUE afterwards, if you need to render other objects that use D3D lighting.

Without further adieu, here it is :

void BlitRect(LPDIRECT3DDEVICE8 lpDevice,
              LPDIRECT3DTEXTURE8 lpSrc,
              float left, float top,
              float right, float bottom,
              D3DCOLOR col,float z)
{
    // calculate rhw

    float rhw=1.0f/(z*990.0f+10.0f);

    // set up rectangle

    D3DTLVERTEX verts[4];
    verts[0]=D3DTLVERTEX(D3DXVECTOR3(left-0.5f,  top-0.5f,    z),rhw,col,0.0f,0.0f); 
    verts[1]=D3DTLVERTEX(D3DXVECTOR3(right-0.5f, top-0.5f,    z),rhw,col,1.0f,0.0f);
    verts[2]=D3DTLVERTEX(D3DXVECTOR3(right-0.5f, bottom-0.5f, z),rhw,col,1.0f,1.0f); 
    verts[3]=D3DTLVERTEX(D3DXVECTOR3(left-0.5f,  bottom-0.5f, z),rhw,col,0.0f,1.0f);

    // set the texture

    lpDevice->SetTexture(0,lpSrc);

    // configure shader for vertex type

    lpDevice->SetVertexShader(D3DFVF_TLVERTEX);

    // draw the rectangle

    lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,verts,sizeof(D3DTLVERTEX));
}

The demo provided below implements a simple image viewer application using the technique shown in this article.  The application will load and display files in TGA, BMP, PNG, JPEG, and DDS formats, scaling the image to fit if its dimensions are larger than the client area of the application.

Download Demo
blit3d.zip
237KB

Requires DirectX 8.0 Runtimes or Later

Related Articles of Interest:

Rendering Full Screen Images from Textures
Using a Blit Queue

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.