1 / 41

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

Chapter 10 DirectDraw 활용 : 애니메이션과 비트맵. In this Chapter…. - 하드웨어 가속을 위한 DirectDraw 사용하기 - 애니메이션 - 비트맵 불러오기 - 블리터 (blitter) 사용하기. 부드러운 애니메이션 테크닉. 페이지 전환 ( 플리핑 ;flipping) 더블 버퍼링 (double buffering) . Double Buffering.

rudolpho
Télécharger la présentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 10DirectDraw 활용: 애니메이션과 비트맵

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

  3. 부드러운 애니메이션 테크닉 • 페이지 전환(플리핑;flipping) • 더블 버퍼링(double buffering)

  4. Double Buffering • 충분한 비디오 메모리가 없다면 DirectX가 대신 페이지 전환을 시뮬레이트하여 double buffering을 사용 • 우리들은 그 차이를 알지 못한다.

  5. DEMO: PROG10_1 • Double buffering을 프로그래머가 해 준 경우. • Lpitch = screenwidth 인 경우와 아닌 경우를 달리 처리하였음.

  6. 페이지 전환(flipping) - 1 • DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX 사용 • 후면버퍼 카운트를 1로 DDSURFACEDESC2 ddsd; DDSCAPS2 ddscaps; LPDIRECTDRAWSURFACE7 lpddsprimary, // primary surface lpddssecondary; // secondary backbuffer surface memset(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);

  7. 페이지 전환(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);

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

  9. 블리터(Blitter) • 이미지를 한 곳에서 다른 곳으로 (보통 주표면) 비트맵 이미지를 복사하기 위해 비트 블리터(bit blitter) 하드웨어를 사용. • 비트맵이 스케일 되고 회전되거나, 혹은 다른 효과들을 처리하도록 요청할 수 있다. • 메모리의 일부분을 특정한 값으로 간단하게 채울 수 있다.

  10. Blitter 함수 • Blt(): 화면의 모서리에 클리핑되는 것을 고려하지 않을 때 • BltFast(): 화면의 모서리에 클리핑되는 것을 고려할 때

  11. 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

  12. Blitting source to destination

  13. Blt Flags

  14. 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; // advanced union { DWORD dwZDestConst; // advanced... LPDIRECTDRAWSURFACE lpDDSZBufferDest; // advanced... }; DWORD dwZSrcConstBitDepth; // advanced...

  15. 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...

  16. 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) fills LPDIRECTDRAWSURFACE lpDDSPattern; }; // the following are very important DDCOLORKEY ddckDestColorkey; // destination color key DDCOLORKEY ddckSrcColorkey; // source color key } DDBLTFX,FAR* LPDDBLTFX;

  17. 한가지 color로 칠하기 • DDBLT_COLORFILL • DDBLT_WAIT • 블리터가 요청을 수행하지 못하면 계속 하도록 지시하는 일반적인 예방책을 둔다.

  18. Example DDBLTFX ddbltfx; // this contains the DDBLTFX structure RECT fill_area; // this contains the destination rectangle memset(&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 primary lpddsprimary->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

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

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

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

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

  23. Bitmap Operations • 보조표면이나 주표면의 어디에든 비트맵을 불러와서 표시 • 비트맵을 애니메이션 • 움직이고 • 충돌 검사 • …

  24. Bitmap Creation • 페인트 프로그램을 사용 • Template 사용

  25. Bitmap 생성시 주의할 점 • 색상: 비트맵이 얼마나 많은 색상을 사용할 것인지 결정해야 하며, 그리고 모두 같은 색상 공간에서 그려야 한다. • 크기: 모든 비트맵을 2의 거듭제곱 크기로 그리도록 한다. 즉, 2x2, 4x4, 8x8, 16x16, 32,x32와 같이 이다. 이렇게 하면, 블리터와 게임에서 수행하는 여러 최적화에 유리하다. 정사각형이 되어야 하는 것은 아니다. 그러나 각 축은 2의 거듭제곱이 되도록 한다. 8x16은 좋지만 7x5는 좋지 않다. • 하나의 이미지 페이지에 여러 비트맵 크기를 섞지 않도록 한다. • Bitmap color space 바꾸기! How?

  26. Bitmap File (.BMP) 의 구조

  27. BITMAPFILEHEADER 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;

  28. BITMAPINFO

  29. BITMAPINFO 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;

  30. BITMAPINFOHEADER 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 apps } BITMAPINFOHEADER;

  31. 뒤집어진 .BMP 데이터

  32. Bitmap 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;

  33. 비트맵을 불러오기 두 개의 함수 int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename) int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)

  34. DEMO: PROG10_4 • Bitmap file loading • 비트맵은 8비트. 16비트, 또는 24비트 형식이 될 수 있다. 그리고 그 함수는 24비트 이미지를 16비트 RGB 이미지로 변환한다.

  35. DEMO: PROG10_5 • 16bit file 읽어와서 뿌리기 데모

  36. 블리터로 비트 채우기 (1) // create the primary surface memset(&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 that ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; // set the backbuffer count to 1 ddsd.dwBackBufferCount = 1; // create the primary surface lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL); // query for the backbuffer; that is, the secondary surface ddscaps.dwCaps = DDSCAPS_BACKBUFFER; lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);

  37. 블리터로 비트 채우기 (2) // load the bitmap Load_Bitmap_File(&bitmap16bit, “ANDRE16.BMP”); // lock the secondary surface memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // get video pointer secondary_buffer = (UCHAR *)ddsd.lpSurface; // copy the bitmap data into secondary surface; this time, assume linear memory memcpy(secondary_buffer, bitmap16bit.buffer, 640*480); // unlock the secondary backbuffer lpddsback->Unlock(NULL);

  38. 블리터로 비트 채우기 (3) // select source position to grab bitmap from int source_x = rand()%640; int source_y = rand()%480; // select destination position to blit to int dest_x = rand()%640; int dest_y = rand()%480; // select width and height of rectangle int width = rand()%640; int height = rand()%480; // set up rectangles RECT 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;

  39. 블리터로 비트 채우기 (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 bit col_key.dwColorSpaceHighValue = 0; // RGB16BIT565(0,0,0) for 16 bit // set the key lpddsback->SetColorKey(DDCKEY_SRCBLT, &col_key); // perform the blit lpddsprimary->Blt(&dest_rect, lpddsback, &source_rect, DDBLT_KEYSRC | DDBLT_WAIT, NULL);

  40. Page Flipping

  41. DEMO: PROG10_7_16b

More Related