�����

 

 

��ũ���Ͷ�?

directX�� �Ұ�

 

 

direct����,���������,������

���̷�Ʈ���ۻ��� ���ݿ� ����

 

 

���� ������ �ø���,��Ʈ�ʺ���

���̷�Ʈ �ķ�Ʈ ����

 

 

Lock,unlock,Blt,BltFast

Direct Sound

 

 

 

 

 

 

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();
}