This topic is now archived and is closed to further replies.


Drawing 2D bitmaps in screen space using DX8

Recommended Posts

rcode    122
Is there a good tutorial somewhere that shows how to draw 2D bitmaps in screenspace using DX8? I looked at the following article and tried to implement it, however it doesn''t seem to work with my 3D models. Either the 3D models appear or the 2D bitmaps appear depending on which projection matrix is used. I think the project matrix affects everything in the scene after EndScene() is called and not just the currently rendered primitive. Is that correct? I also tried drawing the 3D stuff within one Begin/EndScene() along with the appropriate projection matrix in that block, and then 2D stuff within another Begin/EndScene() block with an orthogonal projection. However, that didn''t work. E.g.: HRESULT CMyD3DApplication::Render() { m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(89,135,179), 1.0f, 0 ); if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) { Set3DProjectionMatrix(); // .... Draw 3D stuff here .... m_pd3dDevice->EndScene(); } if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) { SetOrthogonalProjectionMatrix(); // .... Draw 2D stuff here .... m_pd3dDevice->EndScene(); } return S_OK; } Any help on this is greatly appreciated thanks!

Share this post

Link to post
Share on other sites
CrazedGenius    156
You should be able to switch matrices as often as you want:

Set 3D Matrix
Draw 3D Stuff
Set Ortho Matrix
Draw 2D Stuff

Yes, matrices affect all primitives rendered until you change it. No need to have separate Scenes.

Share this post

Link to post
Share on other sites
Mark Duffill    156
You can use 2D verts as follows:

// sprite vert structure
f32 x, y, z, rhw; // The transformed position for the vertex.
u32 ARGB; // The vertex color.
f32 tu, tv; // tex coords

Create a vert buffer somewhere as follows: -

// vert buffer
IDirect3DVertexBuffer8 *SpriteBuff=NULL;

// create sprite buffer

if( NULL == SpriteBuff )
if( FAILED( DXDisplay->CreateVertexBuffer( 4*sizeof(SPRITE_VERTEX),
D3DPOOL_MANAGED, &SpriteBuff ) ) )
return((Warning = "Fatal: Failed To Create Sprite Buffer"));

Then have a draw sprite function similar to below:-
[sx,sy,sw,sh are screen x,y, and width height of image.
tu,tv,tw,th are texture x,y, width and height [0.. 1f]

void DrawSprite( LPDIRECT3DTEXTURE8 Texture, u32 ARGB,
f32 sx, f32 sy, f32 sw, f32 sh,
f32 tu, f32 tv, f32 tw, f32 th )
//// Lock and copy data, unlock

if( (NULL == SpriteBuff ) || FAILED( SpriteBuff->Lock( 0, 0, (BYTE**)&ASprite, 0 ) ) )

// bilinear fixup
sx+=0.5f; sy+=0.5f;
ASprite[0].x = sx; ASprite[0].y = sy; ASprite[0].rhw = 0.5f; ASprite[0].ARGB = ARGB; ASprite[0].tu = tu; ASprite[0].tv = tv;
ASprite[1].x = sx+sw; ASprite[1].y = sy; ASprite[1].rhw = 0.5f; ASprite[1].ARGB = ARGB; ASprite[1].tu = tu+tw; ASprite[1].tv = tv;
ASprite[2].x = sx; ASprite[2].y = sy+sh; ASprite[2].rhw = 0.5f; ASprite[2].ARGB = ARGB; ASprite[2].tu = tu; ASprite[2].tv = tv+th;
ASprite[3].x = sx+sw; ASprite[3].y = sy+sh; ASprite[3].rhw = 0.5f; ASprite[3].ARGB = ARGB; ASprite[3].tu = tu+tw; ASprite[3].tv = tv+th;


// set shader and stream
DXDisplay->SetVertexShader( D3DFVF_SPRITEVERTEX );
DXDisplay->SetStreamSource( 0, SpriteBuff, sizeof(SPRITE_VERTEX) );
DXDisplay->SetTexture( 0, TexHandle)
DXDisplay->DrawPrimitive( D3DPT_TRIANGLESTRIP , 0, 2 );

Note You don''t have to set up the view/model matrices at all, and dont forget to set the shader back to your 3D definition before drawing 3D objects.

PS: Having one vert buffer and (un)locking many times in a single frame might cause some stalls in the render pipeline. An optiization would to be have several buffers and cycle through them.

[The views stated herein do not necessarily represent the view of the company Eurocom ]

Eurocom Entertainment Software

The Jackal

Share this post

Link to post
Share on other sites