Archived

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

rcode

Drawing 2D bitmaps in screen space using DX8

Recommended Posts

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. http://www.gamedev.net/reference/articles/article1434.asp 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
You should be able to switch matrices as often as you want:

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

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
You can use 2D verts as follows:

/////////////////////////////////////////
// sprite vert structure
#define D3DFVF_SPRITEVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
struct SPRITE_VERTEX
{
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),
0 /* Usage */, D3DFVF_SPRITEVERTEX,
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
SPRITE_VERTEX *ASprite;

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

////////////////////////////////////////
// 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;

SpriteBuff->Unlock();

/////////////////////////////////////////
// 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
www.Eurocom.co.uk

The Jackal

Share this post


Link to post
Share on other sites