|
|||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
|
|
4. ���� ������ �ø���
4-1. ���� ����
���⼭ ���ϴ� ���̶� 2�� ���� �̾߱� �ϴ°��̴�.
����
������ �����ߴ� ����̶�� ���ذ� ���� �ٵ�, ������
���ϸ��̼��� �����ϱ� ���ؼ��� ���̴� �������� ����
������ �������� ����� ���� �˰��Դϴ�. �̰��� ������
�� ������ ���� ��� �Ǹ� ��ŭ�� �����̷� �Ͼ��
�����̶�� �մϴ�. ���� ������ ���� ���ϳ��� ������
�� ��� �������Ͱ� ������ ���ÿ� ������ ���� ����~
�ϸ� �������� ������ �ʽ��ϴ�.
�ٷ� �̿����� ���������� ������ �ְڽ��ϱ�? ����
��
ǻ�ͱ�踦 ����ϰ� �ְ� ���� OS��� �ü������ �ٲ�
���ٴ� �� �ۿ��� ���̰� �����ϴ�.
�����̵� ���̷�Ʈ�� 2��° ��(2�� ǥ��)�� ����� �ø���
�� �Ҽ� �ְ� ����� �س��ҽ���.
���� ���̴� ��(1�� ǥ��)�� ������ �ʴ� ��(2�� ǥ��)��
������ �صξ�� ����Ҽ��� �ִµ� ������������ 1����
���� �����ϰ� ����߾����ϴ�.
�̹����ʹ� ��° �ҽ��� ��� �����մϴ�. �� �ҽ���
������ �м��� �ϴ� �������� �����?
LPDIRECTDRAWSURFACE lpPrimary;
LPDIRECTDRAWSURFACE lpBack;
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE
|
DDSCAPS_FLIP
| DDSCAPS_COMPLEX;
hr = lpDD->CreateSurface(&ddsd,
&lpPrimary, NULL);
if(hr != DD_OK) return;
DDSCAPS ddscaps;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = lpFrontBuffer->GetAttachedSurface(&ddscaps,
&lpBack);
if(hr != DD_OK) return;
�������� �ٸ� ���� ������ �������? ��...(����~����~)
DDSCAPS ddscaps;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = lpFrontBuffer->GetAttachedSurface(&ddscaps,
&lpBack);
if(hr != DD_OK) return;
�� �κ��� �߰� �Ǿ�����~ ���⼭ Ư���� ���� ddscaps.dwCaps
=
DDSCAPS_BACKBUFFER; �Դϴ�. �ɼ��� �׳� ���⸸ �ص�
���ذ� ��
����?
DDSURFACEDESC����ü ������� dwFlags�� DDSD_BACKBUFFERCOUNT��
BackBuffer�� ����ڴٴ� ���� ��Ÿ���� dwBackBufferCount��
BackBuffer�� �� �� ������ΰ��� �����ϰ� �˴ϴ�.
�ϴ� ������ �ϳ��� ��������ϴ�. ddsCaps�� dwCaps�����
DDSCAPS_FLIP �� DDSCAPS_COMPLEX�� �ø��ΰ� ����ǥ����
�̿��ϰ�
�ٴ� ���� ��Ÿ���ϴ�.
4-2. ���� �ø���
����ǥ���̶� lpBack �̿ܿ� �ϳ� �̻��� ǥ���� ���մϴ�.
�̷���
�ϸ� ǥ���� ������ ������. BackBuffer ǥ���� ��巹����
���
���ؼ� DDSCAPS����ü�� �����ϰ� IDirectDrawSurface��
�����
GetAttachedSurface�� ȣ���մϴ�. GetAttachedSurface��
DDSCAPS���� �䱸�ϴ� Ư���� ǥ���� ���� �� �ְ� ���ݴϴ�.
��������� ���� ǥ�� ��, 2�� ǥ�� ������ ������ �����ϴ�.
�� ���⼭ ��������? �ƴ���~ �翬 2�� ���� ���������
���ϸ��̼��� ������ �ø����� �غ��� ����~
����������������������������������������������������������
HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurface,
LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,
DDWORD dwFlags)
����������������������������������������������������������
����: �ø��� ����� ����Ͽ� �ִϸ��̼��� ���
������
��ĵ ����
��巹���� ��� ���� ���߿� ɵ?���� ��ȯ��
�� ȭ����
������ �ǹǷ� Flip()�Լ��� ������� �ֻ�
���� ����
�� �ֻ� �ÿ� ȭ���� �����մϴ�.
ù ��° ������
lpDDSurface�� �ø��� ǥ���� ��巹����
�䱸�ϴµ�
NULL�� �����ϸ� ������� �ø��˴ϴ�.
�� ��°��
�÷����ε� DDFLIP_WAIT���� ��Ʈ���ָ� �ø���
�Ͼ ��
���� ��ٸ��ϴ�. ��Ʈ������ ������ �ٷ�
DERR_WASSTILLDRAWING
������ �����մϴ�.
�ٷ� �̰��� �̿��ϸ� �Ǵ� ������~ ���� ���� �ϰԸ�
���̽���
�� ����� ��� ����?
hr = lpPrimary->Flip(NULL, DDFLIP_WAIT);
\\ ������ũ�� ǥ�� �����ϱ�
LPDIRECTDRAWSURFACE lpDDBackOff;
DDSURFACEDESC ddsd;
HRESULT hr;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT
| DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = height;
ddsd.dwWidth = width;
hr = lpDD->CreateSurface(&ddsd,
&lpDDBackOff, NULL);
����(height),��(width)�� �ش��� ũ���� ���� ��ũ����
����
�ϴ� ���ε� ���ݱ��� �ؿԴ��Ͱ� �����̰� ���� �̴ϴ�.
������ GDI���� ���ٸ� �ϳ��� ��DC�� ����°Ͱ� �����
�ϴ�.
IDirectDrawSurface�� ǥ���� �Ϲ����� ��Ʈ���� ����
���ؼ�
Blt��� �Լ��� �����մϴ�. �̰Ϳ� ���ؼ��� ���� 3��°
���¿��� ��Ʈ�ʿ� ���� �ٷ�����Ƿ� 3��° ���¸� ������
�ּ���~
DDBLTFX ddBltfx;
HRESULT hr;
ddbltfx.dwSize = sizeof(ddBltfx);
ddbltfx.dwFillColor = color;
hr = lpSurface->Blt(lpBackOffRect,
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
�� �ڵ�� ȭ�鿡 color�� Į���� lpSurface�� lpBackOffRect��
���õ� ������ ä��� ������ �մϴ�.
Blt�� �Ķ���ͺ��� ���캸��. ù ��°�� ����� lpSurface��
����(RECT����ü�� ��巹��)�� ��Ÿ���ϴ�. �� ��°��
�ҽ���
ǥ���� ��巹���̰� �� ������ �ҽ��� ���� ����, ������
Blt��
�÷��� ���������� ����ü�� Blt�� ������ �����ִ� DDBLTFX����
ü�� ��巹���Դϴ�.
���⼭ DDBLT_COLORFILL �� ȭ���� DDBLTFX ����ü�� ���õ�
��
���� ĥ���ֶ�� �̾߱�~
�翬�� lpSurface�� ä���� ���� lprect�� �ʿ�� �ϰ�
�˴ϴ�.
Blt�� �ٸ� ������ �ؼ� �ٷ� ������� �ʾ��� �� Ȥ��
��������
�� DDERR_WASSTILLDRAWING������ ���ϴ� �� DDBLT_WAIT��
��
������ ������ �� �ٽ� �õ��մϴ�.
�� ���� �ڵ忡 ���� ó���� ��� �ұ��~
while(1)
{
hr = lpBackOff->Blt(.....);
if(hr != DDERR_WASSTILLDRAWING)
break;
}
�Ϳ�~ ����~
�� ������ lpBackOff�� �ٸ� lpBackOffSrc�� �����ϴ�
����
�˾� ����~
lpBackOff->Blt(lpBackRect,
// NULL�̸� ��ü ����.
lpBackOffSrc,
// �ҽ� ǥ��.
lpBackSrcRect,
// NULL�̸� ��ü ����.
DDBLT_WAIT,
NULL);
lpBackOffSrc�� lpBackSrcRect�� ������ ������ �ҽ���
lpBackRect�� ���õ� ������ �����մϴ�.
BltFast ���� ����մϴ�. ���⼭�� �Լ��� ��������
�Ѿ� ���ڽ��ϴ�. (��� ������ ���ؼ� �˰� ���״�...)
������������������������������������������������������
HRESULT BltFast(LPDIRECTDRAWSURFACE lpDDSurface,
DWORD
dwX, DWORD dwY,
LPDIRECTDRAWSUFACE
lpDDSrcSurface,
LPRECT
lpSrcRect, DWORD dwTrans )
������������������������������������������������������
lpDDSurface : BltFast �Լ��� ����Ͽ� ��Ʈ���� bit����
������
������
dwX, dwY : ������ ��ǥ
lpDDScrSurface : ������ ��Ʈ��
lpSrcRect : ������ ��Ʈ���� ����
dwTrans : ������ ��Ʈ���� Ư���� �����ϴ� �Ű� ������
���Լ��� Blt�Լ��� ���� 10%������ ���� ȿ���� ����
�� �ֽ�
�ϴٸ� Ŭ������ ����ҽ� �ӵ����� ȿ���� �����ϴ�.
4-3. �ȷ�Ʈ ó��
���̷�Ʈ������ �Ϲ� ���� �������ۿ����� ���� Į��Ű��
������
�� �ֽ��ϴ�. ��, �������� �����Ͽ� ��Ÿ���� �ʰ� �ϴ�
ȿ����
���̷�Ʈ�� �Ҽ� �ֽ��ϴ�. (�翬 ���� ������ �ǰ���~
^^;)
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue =
255;// �Ǵ� 16������ 0xff
ddck.dwColorSpaceHighValue =
255; // ��
lpSurface->SetColorKey(DDCKEY_SRCBLT,
&ddck);
���� ����������� 256Į���߿��� �տ� 10���� �ڿ�
5����
������� �ʽ��ϴ�. ���� �������� ����ϰ�쿡�� �̰���
����
�ؼ� ������ �����ؾ� ����~ �㳪 ���� Ǯ��ũ�� ����
���ӿ���
�� ���� 255��°�� ���(255, 255, 255)�� ���� �÷���
����մϴ�.
���� �̰��� ����ϴ� ������� �� ���� ���� �ټ� �ֽ��ϴ�.
���� ������ ���������� blt�Լ���255�� ����� �����÷���
����ϱ...
�� ���� ��������Ʈ �Լ��� ����� �ְ���?
���������� �ҽ��� ��â �Ѹ��鼭 4��° ���¸� ���ϱ�
�մϴ�.
�� �ҽ��� �м��� ������~ �� ��� ���� �ſ���~ ^^;
�̼ҽ��� ����(ozzy96)������
�ۼ��Ͻ� ���ε� �׳� �̰���
�÷� ���ϴ�. (����~ ���� �����Զ���...^^;)
//==============================================================
#include <windows.h>
#include <ddraw.h>
#define BALLSIZE 40
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
BOOL InitDDraw(HWND hwnd); //
IDirectDraw������ ǥ�� ����
void DestroyDDraw();
BOOL FillBuffer(LPDIRECTDRAWSURFACE lpSurface, LPRECT lprect, DWORD color);
//
������ ������ color�� ä���ش�.
void Test(HWND hwnd);
void CreateBall(); //
lpOffscreen�� ���� ���� ���ش�.
char szWinName[]="Test";
LPDIRECTDRAW lpDD =
NULL;
LPDIRECTDRAWSURFACE lpFrontBuffer = NULL;
LPDIRECTDRAWSURFACE lpBackBuffer = NULL;
LPDIRECTDRAWSURFACE lpOffscreen = NULL;
POINT CirclePoint; //
���� ��ǥ
int cx, cy; //
�� ��ǥ�� ����ġ
int WINAPI WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,
LPSTR
lpszArgs,int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASS WndClass;
WndClass.hInstance=hThisInst;
WndClass.lpszClassName=szWinName;
WndClass.lpfnWndProc=WindowFunc;
WndClass.style=0;
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.lpszMenuName=NULL;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
if(!RegisterClass(&WndClass)) return 0;
hwnd=CreateWindow(
szWinName,
"Direct Draw Demo",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL);
ShowWindow(hwnd,nWinMode);
UpdateWindow(hwnd);
// ���̷�Ʈ �ʱ�ȭ
if(!InitDDraw(hwnd)) return 0;
Test(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message,
WPARAM
wParam,LPARAM lParam)
{
RECT rcDes;
switch(message)
{
case WM_KEYDOWN:
switch(wParam)
{
case
VK_ESCAPE:
PostMessage(hwnd,
WM_CLOSE, 0, 0);
return
0;
}
break;
case WM_TIMER:
cx
= (CirclePoint.x >= 0 &&
CirclePoint.x
<= 680 - BALLSIZE)?
cx
: ~cx;
cy
= (CirclePoint.y >= 0 &&
CirclePoint.y
<= 440 - BALLSIZE)?
cy
: ~cy;
CirclePoint.x
+= cx;
CirclePoint.y
+= cy;
SetRect(&rcDes,
CirclePoint.x, CirclePoint.y,
CirclePoint.x
+ B
ALLSIZE, ptCurBall.y + BALLSIZE);
//
BackBuffer�� ������(0�� Į��)���� �����.
FillBuffer(lpBackBuffer,
NULL, 0);
//
Source Color Key�� ����� ���� ����.
lpBackBuffer->Blt(&rcDes,
lpOffscreen, NULL,
DDBLT_WAIT
| DDBLT_KEYSRC, NULL);
lpFrontBuffer->Flip(NULL,
DDFLIP_WAIT);
break;
case WM_DESTROY:
KillTimer(hwnd,
1);
DestroyDDraw();
PostQuitMessage(0);
break;
default:
return
DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
BOOL InitDDraw(HWND hwnd)
{
HRESULT hr;
// IDirectDraw��������� ����
hr = DirectDrawCreate(NULL,
&lpDD, NULL);
if(hr != DD_OK) return FALSE;
hr = lpDD->SetCooperativeLevel(hwnd,
DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN);
if(hr != DD_OK) return FALSE;
hr = lpDD->SetDisplayMode(640,
480, 8);
if(hr != DD_OK) return FALSE;
// FrontBuffer�� BackBuffer��
����
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE
|
DDSCAPS_FLIP
| DDS
CAPS_COMPLEX;
hr = lpDD->CreateSurface(&ddsd,
&lpFrontBuffer, NULL);
if(hr != DD_OK) return FALSE;
// Back buffer�� ������ ����
DDSCAPS ddscaps;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = lpFrontBuffer->GetAttachedSurface(&ddscaps,
&lpBackBuffer);
if(hr != DD_OK) return FALSE;
// ������ũ�� ����
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT
| DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = BALLSIZE;
ddsd.dwWidth = BALLSIZE;
hr = lpDD->CreateSurface(&ddsd,
&lpOffscreen, NULL);
if(hr != DD_OK) return FALSE;
return TRUE;
}
// ������ũ���� ���� �� ���� ���� Į��Ű�� ����
voidCreateBall()
{
FillBuffer(lpOffscreen, NULL,
0xff);
HBRUSH hbrush, hold;
HDC hdc;
HRESULT hr;
if(hr = lpOffscreen->GetDC(&hdc)
== DD_OK)
{
hbrush
= CreateSolidBrush(RGB(255, 0, 0));
hold
= SelectObject(hdc, hbrush);
Ellipse(hdc,
0, 0, BALLSIZE, BALLSIZE);
SelectObject(hdc,
hold);
lpOffscreen->ReleaseDC(hdc);
}
// Set Color key
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue =
0xff;
ddck.dwColorSpaceHighValue =
0xff;
lpOffscreen->SetColorKey(DDCKEY_SRCBLT,
&ddck);
}
void Test(HWND hwnd)
{
SetTimer(hwnd, 1, 10, NULL);
ptCurBall.x = 300;
ptCurBall.y = 200;
xcin = cy = 2;
CreateBall();
}
BOOL FillBuffer(LPDIRECTDRAWSURFACE lpSurface, LPRECT lprect,
DWORD
color)
{
DDBLTFX ddbltfx;
HRESULT hr;
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = color;
hr = lpSurface->Blt(lprect,
NULL, NULL,
DDBLT_COLORFILL
| DDBLT_WAIT,
&ddbltfx);
return hr == DD_OK;
}
void DestroyDDraw()
{
if(lpBackBuffer != NULL) lpBackBuffer->Release();
if(lpFrontBuffer != NULL) lpFrontBuffer->Release();
if(lpOffscreen != NULL) lpOffscreen->Release();
if(lpDD != NULL) lpDD->Release();
}