通过ID3DXSprite来实现DirectX 9.0C绘制2D动画
| |
| | 最近我一直在不停地问有关2D游戏制做的技术。继上一篇DirectX9中的二维图片的加载以后,我再发一篇关于通过ID3DXSprite来实现DirectX 9.0C绘制2D动画的帖子,希望对大家有所帮助。
在DirectX 8以前,2D都是DirectDraw来完成的,是Direct中非常重要的一个部分,但是到了DirectX 8以后,DirectDraw被合并到DirectX Graphics 当中了,所以在那以后就很少有人谈到如何用DirectX Graphics 实现2D效果。大多数需要2D的人都不辞辛苦用DirectDraw来实现了,毕竟用Direct 7的东西,后面的都是支持的。但是正如一个老外说的,喜欢用DirectDraw的人用用也无所谓,从Direct 8 以后学习的人再去学DirectDraw就不合适了,那么怎么实现自己需要的2D效果呢?我接触到了3种方法DirectX9中的二维图片的加载就是其中之一,这里我们要讲的是第二种通过ID3DXSprite来实现DirectX 9.0C绘制2D动画
前一种方法我们说过了,是单纯的图片加入,对于游戏而言没有太大的用处,游戏里面毕竟动态的东西比较多,怎么让他动起来呢?我们先看一下源代码。
(本帖子不分析代码,主要留作讨论。代码分析在《超级马里奥.net游戏代码完全分析》中,欢迎下载)
以下代码在 Microsoft DirectX 9.0 SDK Update (August 2005)环境运行通过,如果遇到编译不通过在下面留言。
把SDK中底个例子(纹理)中的banana.bmp(或者自己找一个不要太小的bmp文件)考到你的程序目录下。
//-----------------------------------------------------------------------------#include
//-----------------------------------------------------------------------------LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; LPDIRECT3DTEXTURE9 g_pTexture = NULL;LPD3DXSPRITE g_pSprite = NULL;
struct CUSTOMVERTEX{ FLOAT x, y, z, rhw; DWORD color; };
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
RECT rct; //-----------------------------------------------------------------------------HRESULT InitD3D( HWND hWnd ){ SetRect( &rct, 0,200, 100, 250 );
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; }
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
D3DXCreateSprite( g_pd3dDevice, &g_pSprite );
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp", &g_pTexture ) ) ) { if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "..\\banana.bmp", &g_pTexture ) ) ) { MessageBox(NULL, "Could not find banana.bmp", "Textures.exe", MB_OK); return E_FAIL; } }
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); return S_OK;}
//-----------------------------------------------------------------------------HRESULT InitVB(){ CUSTOMVERTEX vertices[] = { { 50.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color { 250.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, }, { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, }, { 250.0f, 250.0f, 0.5f,1.0f, 0xff00ffff, }, };
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ) { return E_FAIL; }
VOID* pVertices; if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, vertices, sizeof(vertices) ); g_pVB->Unlock();
return S_OK;}
//-----------------------------------------------------------------------------VOID Cleanup(){ if( g_pVB != NULL ) g_pVB->Release();
if( g_pd3dDevice != NULL ) g_pd3dDevice->Release();
if( g_pD3D != NULL ) g_pD3D->Release();}
VOID Render()
{ g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) {
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); if ( SUCCEEDED( g_pSprite->Begin(D3DXSPRITE_ALPHABLEND) ) ) { rct.right +=1; rct.left +=1;
g_pSprite->Draw(g_pTexture, &rct, NULL, NULL, 0xffffffff); g_pSprite->End(); }
g_pd3dDevice->EndScene(); }
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );}
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){ switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; }
return DefWindowProc( hWnd, msg, wParam, lParam );}
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ){ WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "D3D Tutorial", NULL }; RegisterClassEx( &wc );
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 02: Vertices", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL );
if( SUCCEEDED( InitD3D( hWnd ) ) ) { if( SUCCEEDED( InitVB() ) ) { ShowWindow( hWnd, SW_SHOWDEFAULT ); UpdateWindow( hWnd );
MSG msg; ZeroMemory( &msg, sizeof(msg) ); while( msg.message!=WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else Render(); } } }
UnregisterClass( "D3D Tutorial", wc.hInstance ); return 0;}
|
|
|
|