Beginning DirectX9 Dch bi TransTeam din đàn Gamedev.VN
40
Sau đây là mt ví d đơn gin gi ti hàm D3DLoadSurfaceFromFile, nó thc hin ti
nh bitmap t tp tin test.bmp vào trong vùng đệm offscreen surface. Chú ý là bn phi
to đối tượng surface lưu tr bng hàm CreateSurfaceFromFile trước khi gi ti hàm này.
IDirect3DSurface9* surface;
hResult = D3DXLoadSurfaceFromFile( surface,
NULL,
NULL,
“test.bmp”,
NULL,
D3DX_DEFAULT,
0,
NULL );
if ( FAILED( hResult ) )
return NULL;
Sau li gi trên đây, d liu toàn b nh bitmap trong tp tin test.bmp s được ti vào b
nh và sn sàng để bn s dng.
S dng DirectX để th hin mt hình nh
Chúng ta đã hc cách to mt surface cũng như làm thế nào để ti mt nh bitmap vào
trong nó, bây gi là lúc chúng ta s th hin nó. Để làm được điu này, bn phi to mt
s thay đổi trong hàm Render mà chúng ta đã to trước đó
Trong phn trước, chúng ta đã xây dng hàm Render như đon mã minh ho dưới đây:
/*********************************************************************
* Render(void)
*********************************************************************/
void Render(void)
{
// Kim tra xem đối tượng Direct3D device đã thc s được khi to hay chưa.
if( NULL == pd3dDevice )
return;
// Xoá b đệm màn hình (back buffer) bng màu xanh nước bin
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Th hin hình nh t d liu trên b nh đệm màn hình
pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
Để hin th nh bitmap đó lên màn hình, bn cn phi s dng hàm StretchRect, hàm này
s thc hin vic sao chép và kéo dãn, thay đổi t lnh nh nếu 2 vùng ch nht lưu tr
nh gc và nh đích có kích thước khác nhau.
Hàm StretchRect này đưc định nghĩa như sau:
HRESULT StretchRect(
IDirect3DSurface9 *pSourceSurface,
CONST RECT *pSourceRect,
IDirect3DSurface9 *pDestSurface,
CONST RECT *pDestRect,
D3DTEXTUREFILTERTYPE Filter
);
Các tham s đầu vào ca hàm StretchRect này bao gm:
pSourceSurface. Con tr đối tượng surface qun lý các nh bitmap đưc ti vào.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Beginning DirectX9 Dch bi TransTeam din đàn Gamedev.VN
41
pSourceRect. Con tr kiu RECT cha d liu vùng đưc sao chép. Néu tham s
này là NULL, toàn b d liu surface gc s được sao chép.
pDestSurface. Con tr cha đối tượng surface đích. Trong hu hết các trường hp,
nó là con tr ca b đệm ph back buffer.
pDestRect. Con tr kiu RECT cha d liu vùng th hin đối tượng được sao
chép lên surface đích. Tham s này có th là NULL nếu bn kô mun xác lp vùng
kết xut.
Filter. Kiu lc s dng trong quá trình sao chép. Bn có th xác lp giá tr này là
D3DTEXF_NONE nếu không mun xác lp kiu lc.
Có l bn s t hi làm thế nào đế có th ly được con tr cha d liu ca b đệm back
buffer surface. Hàm để thc hin chc năng này có tên là GetBackBuffer, cu trúc ca nó
có dng như sau:
GetBackBuffer( 0, // giá tr th hin kiu cháo đổi
0, // ch s ca b đệm
// 0 nếu ch có mt b đệm được s dng
D3DBACKBUFFER_TYPE_MONO, // mt đối s định kiu
&backbuffer); // đối tượng tr v có kiu IDirect3DSurface9
Kết hp thêm các li gi ti hàm StretchRectGetBackBuffer, hàm Render ca chúng
ta lúc này s có dng tương t dưới đây:
/*********************************************************************
* Render
*********************************************************************/
void Render(void)
{
// Con tr b đệm back buffer
IDirect3DSurface9* backbuffer = NULL;
// Kim tra đối tượng Direct3D device đã tn ti
if( NULL == pd3dDevice )
return;
// Xoá toàn b b đệm v màu xanh nước bin
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Ly con tr b đệm back buffer
pd3dDevice->GetBackBuffer( 0,
0,
D3DBACKBUFFER_TYPE_MONO,
&backbuffer );
// Sao chép toàn b d liu offscreen surface vào b đệm
pd3dDevice->StretchRect( srcSurface,
NULL,
backbuffer,
NULL,
D3DTEXF_NONE );
// Th hin hình nh t b đệm lên màn hình
pd3dDevice->Present ( NULL, NULL, NULL, NULL );
}
Bn có th tìm thy mã ngun ca ví d này trong thư mc chapter3\example1 trên CD-
ROM. Biên dch và chy ng dng, mt ca s chương trình s xut hin có dng sau:
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Beginning DirectX9 Dch bi TransTeam din đàn Gamedev.VN
42
Hình 3.2 Hin th nh nn cho ca s ng dng
Xem xét li hàm StretchRect
Trong phn trước, chúng ta đã s dng hàm StretchRect để sao chép toàn b nh
offscreen surface vào b đệm, nhưng đó không phi là toàn b chc năng hu dng nht
ca hàm này. StretchRect còn cho phép bn sao cheo mt hoc nhiu khung hình nh ca
nh offscreen surface, nó cho phép mt surface có th to nn t nhiu hình nh hơn. Ví
d, mt nh offscreen surface có th cha rt nhiu khung hình chuyn động nh ca mt
nhân vt, hoc các hình nh nh để to nên mt puzzle game. Hàm StretchRect có 2 tham
s - pSourceRect và pDesRect – dùng để xác định vùng d liu s copy t đâu đến đâu.
Hình 3.3 s minh ho vic s dng chc năng này.
Hình 3.3 nh bên tay trái là nh gc và hình ch nht miêu t vùng
d liu s được sao chép. nh bên phi mô t v trí và vùng
nh được sao chép lên b đệm.
Trong ví d tiếp theo chúng ta s s dng chc năng này để th hin mt thông đip lên
màn hình t d liu nh gc cha toàn b các ch trong bng ch cái. Hình 3.4 minh ho
nh d liu gc này, như bn có th thy tt c các ch cái được lưu trong các vùng ch
nht có kích thước ging nhau. Vic xác lp lưu các ch cái vi cùng mt kích c s giúp
chúng ta tin li hơn rt nhiu trong quá trình x lý và tìm ti ch cái cn thiết mt cách
nhanh nht.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Beginning DirectX9 Dch bi TransTeam din đàn Gamedev.VN
43
Bi vì chúng ta s phi sao chép nhiu khung hình nên chúng ta s phi gi ti hàm
StretchRect nhiu ln. Để mi th tr nên đơn gin, chúng ta s đặt tt c nhng li gi
đó vào trong mt vòng lp bên trong hàm Render.
/*********************************************************************
* Render
*********************************************************************/
void Render(void)
{
int letterWidth=48; // Thông s b ngang mc đinh ca mt ô ch cái
int letterHeight=48; // chiu cao mc định ca mt ô ch cái
int destx = 48; // To độ X ca đểm trên cùng phía bên trái ca ch cái đầu tiên
int desty = 96; // To độ Y ca đểm trên cùng phía bên trái ca ch cái đầu tiên
// Biến cha con tr b đệm
IDirect3DSurface9* backbuffer = NULL;
// Kim tra đối tượng Direct3D device
if( NULL == pd3dDevice )
return;
// Xoá b đệm bng màu xanh nước bin
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Ly con tr ca b đệm
pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &backbuffer);
// Xác lp biến cha v trí ch cái đang được xem xét
int count=0;
// Thc hin vòng lp trên tng ký t ca chui thông đip đầu vào
for ( char *c = message; c != “ “; c++ )
{
RECT src; // D liu vùng ch nht gc và kết xut
RECT dest;
int srcY = ( ( ( *c - ‘A’ ) / 6 ) ) * letterHeight; // Tìm to độ vùng d liu sao chép gc
int srcX = ( ( ( *c - ‘A’ ) %7 ) * letterWidth );
src.top = srcY ;
src.left = srcX;
src.right = src.left + letterWidth;
src.bottom = src.top + letterHeight;
// Tìm to độ vùng d liu s được sao chép ti
dest.top = desty;
dest.left = destx + ( letterWidth * count );
dest.right = dest.left + letterWidth;
dest.bottom = dest.top + letterHeight;
// Tăng biến đếm lên 1
count++;
// sao chép d liu vào b đệm
pd3dDevice->StretchRect( srcSurface, // D liu surface gc
src, // Vùng d liu muôn sao chép
backbuffer, // D liu được sao chép vào
dest, // vùng d liu được sao chép
D3DTEXF_NONE); // kiu b lc s dng
}
// Th hin d liu t b đệm lên màn hình
pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
Kết qu ca ví d trên là th hin dòng ch “HELLO WORLD” và đem li cho người
dùng cm giác ca mt bc thư tng tin :). Hình 3.5 minh ho kết qu kết xut ca
chương trình. Bn có th tìm mã ngun đầy đủ trong thư mc chapter3\example2.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Beginning DirectX9 Dch bi TransTeam din đàn Gamedev.VN
44
Trước khi vòng lp đưc thc hin đọc tng ch cái ca thông đip, nó phi được định
nghĩa trước bên ngoài hàm render có dng như sau:
char *message = “HELLO WORLD”;
Trong mi bước nhy ca vòng lp, chúng ta s tiến hành lc trên tng ch cái mt. Ví
d, trong ln lp đầu tiên, chúng ta s ch làm vic vi ch cái H trong t “HELLO”.
Đon mã tiếp theo s tính toán vùng ch nht gc bao gm to độ X và Y ca đỉnh trên
cùng góc bên trái ca hình.
int srcY = ( ( ( *c - ‘A’ ) / 6 ) ) * letterHeight;
int srcX = ( ( ( *c - ‘A’ ) %7 ) * letterWidth);
Sau khi chúng ta đã có to độ ca đim này, chúng ta s biết được đo độ đim dưới cùng
bên phi ca hình ch nht cha ch cái đó thông qua chiu cao và chiu rng ca nó.
src.top = srcY ;
src.left = srcX;
src.right = src.left + letterWidth;
src.bottom = src.top + letterHeight;
Tiếp đến chúng ta s phi xác định v trí mà ch cái s được đặt trên b đệm.
dest.top = desty;
dest.left = destx + ( letterWidth * count );
dest.right = dest.left + letterWidth;
dest.bottom = dest.top + letterHeight;
Chúng ta đã xác lp biến cout dùng để kim tra xem bao nhiêu ch cái đã được v trên
màn hình. Thông qua biến count này, chúng ta s tính toán được to độ đim ca các ch
cái cn chèn.
Hình 3.5 Hình minh ho s dng nh bitmap các
ch cái để th hin chui, Hello world.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com