41
Chapter 10 Chapter 10 DirectDraw DirectDraw 활활 활활 : : 활활활활활활 활활활 활활활활활활 활활활

Chapter 10 DirectDraw 활용 : 애니메이션과 비트맵. Copyright by In-Kwon Lee 20032 In this Chapter… - 하드웨어 가속을 위한 DirectDraw 사용하기 - 애니메이션

Embed Size (px)

Citation preview

Chapter 10Chapter 10

DirectDraw DirectDraw 활용활용 : : 애니메이션과 비트맵애니메이션과 비트맵

Copyright by In-Kwon Lee 2003 2

In this Chapter…In this Chapter…

• - 하드웨어 가속을 위한 DirectDraw 사용하기• - 애니메이션• - 비트맵 불러오기• - 블리터 (blitter) 사용하기

Copyright by In-Kwon Lee 2003 3

부드러운 애니메이션 테크닉부드러운 애니메이션 테크닉

• 페이지 전환 ( 플리핑 ;flipping)• 더블 버퍼링 (double bufferin

g)

Copyright by In-Kwon Lee 2003 4

Double BufferingDouble Buffering

• 충분한 비디오 메모리가 없다면 DirectX 가 대신 페이지 전환을 시뮬레이트하여 double buffering 을 사용

• 우리들은 그 차이를 알지 못한다 .

Copyright by In-Kwon Lee 2003 5

DEMO: PROG10_1DEMO: PROG10_1

• Double buffering 을 프로그래머가 해 준 경우 . • Lpitch = screenwidth 인 경우와 아닌 경우를 달리

처리하였음 .

Copyright by In-Kwon Lee 2003 6

페이지 전환페이지 전환 (flipping) - 1 (flipping) - 1

• DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX 사용

• 후면버퍼 카운트를 1 로 DDSURFACEDESC2 ddsd;DDSCAPS2 ddscaps;LPDIRECTDRAWSURFACE7 lpddsprimary, // primary surface lpddssecondary; // secondary backbuffer surfacememset(ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_

COMPLEX;ddsd.dwBackBufferCount = 1;lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);

Copyright by In-Kwon Lee 2003 7

페이지 전환페이지 전환 (flipping) - 2(flipping) - 2

// query for the backbuffer or secondary surface

// notice the use of ddscaps to indicate what you’re requesting

ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

// get the surface

lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);

….

// flip the primary and secondary surfaces

while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);

Copyright by In-Kwon Lee 2003 8

DEMO PROG10_2DEMO PROG10_2

• PROG10_1 의 double buffering 에 비해 한결 간단하다 .

Copyright by In-Kwon Lee 2003 9

블리터블리터 (Blitter)(Blitter)

• 이미지를 한 곳에서 다른 곳으로 ( 보통 주표면 ) 비트맵 이미지를 복사하기 위해 비트 블리터 (bit blitter) 하드웨어를 사용 .

• 비트맵이 스케일 되고 회전되거나 , 혹은 다른 효과들을 처리하도록 요청할 수 있다 .

• 메모리의 일부분을 특정한 값으로 간단하게 채울 수 있다 .

Copyright by In-Kwon Lee 2003 10

Blitter Blitter 함수함수

• Blt(): 화면의 모서리에 클리핑되는 것을 고려하지 않을 때

• BltFast(): 화면의 모서리에 클리핑되는 것을 고려할 때

Copyright by In-Kwon Lee 2003 11

Blt()Blt()

HRESULT Blt(

LPRECT lpDestRect, // the destination rectangle

LPDIRECTDRAWSURFACE7 lpDDSrcSurf, // the source surface

LPRECT lpSrcRect, // the source rectangle

DWORD dwFlags, // control flags

LPDDBLTFX lpDDBltFx); // the special fx structure

Copyright by In-Kwon Lee 2003 12

Blitting source to destinationBlitting source to destination

Copyright by In-Kwon Lee 2003 13

Blt FlagsBlt FlagsValue Meaning

DDBLT_COLORFILL Uses the dwFillColor member of the DDBLTFX structure as the RGB color that fills the destination rectangle on the destination surface.

DDBLT_DDFX Uses the dwDDFX member of the DDBLTFX structure to specify the effects to use for this blit.

DDBLT_DDROPS Uses the dwDDROPS member of the DDBLTFX structure to specify the raster operations (ROPs) that are not part of the Win32 API.

DDBLT_KEYDEST Uses the color key associated with the destination surface.

DDBLT_KEYSRC Uses the color key associated with the source surface.

DDBLT_ROP Uses the dwROP member of the DDBLTFX structure for the ROP for this blit; these ROPs are the same as those defined in the Win32 API.

DDBLT_ROTATIONANGLE

Uses the dwRotationAngle member of the DDBLTFX structure as the rotation angle (specified in 1/100 of a degree) for the surface.

DDBLT_WAIT Instructs the blitter to keep trying the blit operation until the blit operation is successful; this way, you don’t get errors back if the blitter is busy.

Copyright by In-Kwon Lee 2003 14

DDBLTFX Structure (1)DDBLTFX Structure (1)

typedef struct _DDBLTFX{ DWORD dwSize; // the size of this structure in bytes DWORD dwDDFX; // type of blitter fx DWORD dwROP; // Win32 raster ops that are supported DWORD dwDDROP; // DirectDraw raster ops that are supported DWORD dwRotationAngle; // angle for rotations DWORD dwZBufferOpCode; // z-buffer fields used for 3D DWORD dwZBufferLow; // advanced parameter DWORD dwZBufferHigh; // advanced parameter DWORD dwZBufferBaseDest; // advanced DWORD dwZDestConstBitDepth; // advancedunion { DWORD dwZDestConst; // advanced... LPDIRECTDRAWSURFACE lpDDSZBufferDest; // advanced... }; DWORD dwZSrcConstBitDepth; // advanced...

Copyright by In-Kwon Lee 2003 15

DDBLTFX Structure (2)DDBLTFX Structure (2)

union { DWORD dwZSrcConst; // advanced... LPDIRECTDRAWSURFACE lpDDSZBufferSrc; // advanced... }; DWORD dwAlphaEdgeBlendBitDepth; // alpha stuff (advanced) DWORD dwAlphaEdgeBlend; // advanced... DWORD dwReserved; // advanced... DWORD dwAlphaDestConstBitDepth; // advanced... union { DWORD dwAlphaDestConst; // advanced... LPDIRECTDRAWSURFACE lpDDSAlphaDest; // advanced... }; DWORD dwAlphaSrcConstBitDepth; // advanced...

Copyright by In-Kwon Lee 2003 16

DDBLTFX Structure (3)DDBLTFX Structure (3)

union { DWORD dwAlphaSrcConst; // advanced... LPDIRECTDRAWSURFACE lpDDSAlphaSrc; // advanced... }; union // the following are very important{ DWORD dwFillColor; // color word used for fill DWORD dwFillDepth; // z filling (advanced) DWORD dwFillPixel; // color fill word for RGB(alpha) fillsLPDIRECTDRAWSURFACE lpDDSPattern; }; // the following are very importantDDCOLORKEY ddckDestColorkey; // destination color key DDCOLORKEY ddckSrcColorkey; // source color key} DDBLTFX,FAR* LPDDBLTFX;

Copyright by In-Kwon Lee 2003 17

한가지 한가지 colorcolor 로 칠하기로 칠하기

• DDBLT_COLORFILL • DDBLT_WAIT

– 블리터가 요청을 수행하지 못하면 계속 하도록 지시하는 일반적인 예방책을 둔다 .

Copyright by In-Kwon Lee 2003 18

ExampleExample

DDBLTFX ddbltfx; // this contains the DDBLTFX structureRECT fill_area; // this contains the destination rectanglememset(&ddbltfx,0,sizeof(DDBLTFX));ddbltfx.dwSize = sizeof(DDBLTFX);ddbltfx.dwFillColor = color; // your data 8,16,24 bit// fill in the destination-rectangle data (your data)fill_area.top = top;fill_area.left = left;fill_area.bottom = bottom;fill_area.right = right;// ready to blit to surface; in this case, blit to primarylpddsprimary->Blt(&fill_area, // pointer to dest rectangle NULL, // pointer to source surface, NA NULL, // pointer to source rectangle, NA DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait &ddbltfx); // pointer to DDBLTFX structure

Copyright by In-Kwon Lee 2003 19

DEMO: PROG10_3DEMO: PROG10_3

• 640x480 16 비트 모드 윈도우를 생성하고 주표면을 랜덤한 크기의 색깔 있는 사각형을 블리트로 채운다

Copyright by In-Kwon Lee 2003 20

벡터 디스플레이벡터 디스플레이

• 70 년대 후반과 80 년대 초반에는 테일거너 (Tail Gunner) 같은 많은 게임들은 디스플레이가 선으로 이루어지는 벡터 그래픽 디스플레이를 사용

Copyright by In-Kwon Lee 2003 21

BitmapBitmap

• 하나의 이미지를 나타내는 색깔 있는 픽셀의 2D 행렬(matrix)

Copyright by In-Kwon Lee 2003 22

Bitmap AnimationBitmap Animation

• 해골 애니메이션의 56x72 크기 비트맵들

Copyright by In-Kwon Lee 2003 23

Bitmap OperationsBitmap Operations

• 보조표면이나 주표면의 어디에든 비트맵을 불러와서 표시

• 비트맵을 애니메이션 • 움직이고 • 충돌 검사 • …

Copyright by In-Kwon Lee 2003 24

Bitmap CreationBitmap Creation

• 페인트 프로그램을 사용 • Template 사용

Copyright by In-Kwon Lee 2003 25

Bitmap Bitmap 생성시 주의할 점생성시 주의할 점

• 색상 : 비트맵이 얼마나 많은 색상을 사용할 것인지 결정해야 하며 , 그리고 모두 같은 색상 공간에서 그려야 한다 .

• 크기 : 모든 비트맵을 2 의 거듭제곱 크기로 그리도록 한다 . 즉 , 2x2, 4x4, 8x8, 16x16, 32,x32 와 같이 이다 . 이렇게 하면 , 블리터와 게임에서 수행하는 여러 최적화에 유리하다 . 정사각형이 되어야 하는 것은 아니다 . 그러나 각 축은 2 의 거듭제곱이 되도록 한다 . 8x16 은 좋지만 7x5 는 좋지 않다 .

• 하나의 이미지 페이지에 여러 비트맵 크기를 섞지 않도록 한다 .

• Bitmap color space 바꾸기 ! How?

Copyright by In-Kwon Lee 2003 26

Bitmap File (.BMP) Bitmap File (.BMP) 의 구조의 구조

Copyright by In-Kwon Lee 2003 27

BITMAPFILEHEADER structureBITMAPFILEHEADER structure

typedef struct tagBITMAPFILEHEADER { // bmfh

WORD bfType; // type of bitmap; 0x4D42 means .BMP

DWORD bfSize; // the total size of the file, in bytes

WORD bfReserved1; // always 0

WORD bfReserved2; // always 0

DWORD bfOffBits; // number of bytes from this structure to access the

// BITMAPINFO; basically an offset

} BITMAPFILEHEADER;

Copyright by In-Kwon Lee 2003 28

BITMAPINFOBITMAPINFO

Copyright by In-Kwon Lee 2003 29

BITMAPINFO structureBITMAPINFO structure

• 팔레트가 파일에 있다면 , bmiColors[] 배열은 팔레트를 포함하다 . 그렇지 않으면 bmiColors[] 배열은 비어있다 .

typedef struct tagBITMAPINFO

{

BITMAPINFOHEADER bmiHeader; // contains all the data field definitions of the

// .BMP file

RGBQUAD bmiColors[1]; // the color palette

} BITMAPINFO;

Copyright by In-Kwon Lee 2003 30

BITMAPINFOHEADER structureBITMAPINFOHEADER structure

typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // number of bytes in this structure LONG biWidth; // width of bitmap LONG biHeight; // height of bitmap WORD biPlanes; // number of color planes (always 1) WORD biBitCount // bits per pixel (1,4,8,16,24, or 32) DWORD biCompression; // type of compression; always BI_RGB for // noncompressed bitmaps DWORD biSizeImage; // size of image in bytes LONG biXPelsPerMeter; // x res of target display LONG biYPelsPerMeter; // y res of target display DWORD biClrUsed; // how many colors are used DWORD biClrImportant; // number of important colors; only for Windows a

pps} BITMAPINFOHEADER;

Copyright by In-Kwon Lee 2003 31

뒤집어진 뒤집어진 .BMP .BMP 데이터 데이터

Copyright by In-Kwon Lee 2003 32

Bitmap File StructureBitmap File Structure

typedef struct BITMAP_FILE_TAG

{

BITMAPFILEHEADER bitmapfileheader;

BITMAPINFOHEADER bitmapinfoheader;

PALETTEENTRY palette[256]; // the 256-color palette

UCHAR *buffer; // pointer to data

} BITMAP_FILE, *BITMAP_FILE_PTR;

Copyright by In-Kwon Lee 2003 33

비트맵을 불러오기 두 개의 함수 비트맵을 불러오기 두 개의 함수

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap,

char *filename)

int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)

Copyright by In-Kwon Lee 2003 34

DEMO: PROG10_4 DEMO: PROG10_4

• Bitmap file loading• 비트맵은 8 비트 . 16 비트 , 또는 24 비트 형식이 될 수

있다 . 그리고 그 함수는 24 비트 이미지를 16 비트 RGB 이미지로 변환한다 .

Copyright by In-Kwon Lee 2003 35

DEMO: PROG10_5DEMO: PROG10_5

• 16bit file 읽어와서 뿌리기 데모

Copyright by In-Kwon Lee 2003 36

블리터로 비트 채우기 블리터로 비트 채우기 (1)(1)

// create the primary surfacememset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;// you need to tell DirectDraw that you want a complex// flippable surface structure; set flags for thatddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_

COMPLEX;// set the backbuffer count to 1ddsd.dwBackBufferCount = 1;// create the primary surfacelpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);// query for the backbuffer; that is, the secondary surfaceddscaps.dwCaps = DDSCAPS_BACKBUFFER;lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);

Copyright by In-Kwon Lee 2003 37

블리터로 비트 채우기 블리터로 비트 채우기 (2)(2)

// load the bitmapLoad_Bitmap_File(&bitmap16bit, “ANDRE16.BMP”);// lock the secondary surfacememset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NUL

L);// get video pointersecondary_buffer = (UCHAR *)ddsd.lpSurface;// copy the bitmap data into secondary surface; this time, assume lin

ear memorymemcpy(secondary_buffer, bitmap16bit.buffer, 640*480);// unlock the secondary backbufferlpddsback->Unlock(NULL);

Copyright by In-Kwon Lee 2003 38

블리터로 비트 채우기 블리터로 비트 채우기 (3)(3)

// select source position to grab bitmap fromint source_x = rand()%640;int source_y = rand()%480;// select destination position to blit toint dest_x = rand()%640;int dest_y = rand()%480;// select width and height of rectangleint width = rand()%640;int height = rand()%480;// set up rectanglesRECT source_rect, dest_rect;source_rect.left = source_x;source_rect.top = source_y;source_rect.right = source_x + width;source_rect.bottom = source_y + height;dest_rect.left = dest_x;dest_rect.top = dest_y;dest_rect.right = dest_x + width;dest_rect.bottom = dest_y + height;

Copyright by In-Kwon Lee 2003 39

블리터로 비트 채우기 블리터로 비트 채우기 (4)(4)

// set up the color key so that color index 0 is transparent. If you’re using a

// 16/24 bit mode then you would build the actual RGB values for the transparent

// color and place the SAME value in both the low and high color key

DDCOLORKEY col_key;col_key.dwColorSpaceLowValue = 0; // RGB16BIT565(0,0,0) for

16 bitcol_key.dwColorSpaceHighValue = 0; // RGB16BIT565(0,0,0) for

16 bit// set the keylpddsback->SetColorKey(DDCKEY_SRCBLT, &col_key);// perform the blitlpddsprimary->Blt(&dest_rect, lpddsback, &source_rect, DDBLT_KE

YSRC | DDBLT_WAIT, NULL);

Copyright by In-Kwon Lee 2003 40

Page FlippingPage Flipping

Copyright by In-Kwon Lee 2003 41

DEMO: PROG10_7_16bDEMO: PROG10_7_16b