Upload
merilyn-hampton
View
232
Download
0
Embed Size (px)
Citation preview
Chapter 11Chapter 11
DirectDrawDirectDraw 의 깊은 곳의 깊은 곳 : : 보다 발전된 기능들보다 발전된 기능들
2
이 장에서는이 장에서는
• - 비트맵 그래픽으로 고급 작업 수행하기• - 오프스크린 표면 사용하기• - 색상 애니메이션 기법 알아보기• - DirectDraw 와 GDI 결합하기• - 윈도우 모드에서 DirectDraw 사용하기• - DirectDraw 에서 정보 얻어오기
3
투명도투명도
4
Black-transparent 8-bit versionBlack-transparent 8-bit version
// 32 x 32 bitmap 을 화면 (x,y) 에 뿌리는 예제// (x, y) 는 bitmap 의 왼쪽 위 꼭지점이 된다 . // (index_x, index_y) 는 32x32 bitmap 을 따라간다 .
for (int index_y=0; index_y<32; index_y++) { for (int index_x=0; index_x<32; index_x++) { UCHAR pixel = image[index_x+index_y*32]; if (pixel!=0) primary_buffer[x+index_x+(y+index_y)*ddsd.lPitch] = pixel; } // end for index_x} // end for index_y
5
Black-transparent 16-bit versionBlack-transparent 16-bit version
// these two loops blit a 32 x 32 bitmapfor (int index_y=0; index_y<32; index_y++){// copy next row of pixelsfor (int index_x=0; index_x<32; index_x++) { // get the next pixel USHORT pixel = image[index_x+index_y*32]; // test if pixel is transparent if (pixel!=_RGB16BIT565(0,0,0)) primary_buffer[x+index_x+(y+index_y)*(ddsd.lPitch/2)] = pixel; // else do nothing } // end for index_x} // end for index_y
6
Black-transparent 8-bit Black-transparent 8-bit (without multiply)(without multiply)UCHAR *src_ptr = image;UCHAR *dest_ptr = primary_buffer + x + y * ddsd.lPitch;
for (int index_y=0; index_y<32; index_y++) { for (int index_x=0; index_x<32; index_x++) { UCHAR pixel = *src_ptr; if (pixel!=0) *dest_ptr = pixel; src_ptr++; dest_ptr++; } // end for index_x // move destination pointer to start of next line dest_ptr+=(ddsd.lPitch - 32); } // end for index_y
7
Black-transparent 16-bit Black-transparent 16-bit (without multiply)(without multiply)
• Try it !
8
Multiplication/Division by shift Multiplication/Division by shift
• player_x*64 = player_x <<6
• player_x*96 = player_x*64 + player_x*32 = (player_x << 6) + (player_x << 5)
9
색상키색상키 (color keying)(color keying)
• 원본키 (source key)– 투명한 색상의 범위를 설정하고 , 블리터에게 이 범위를
복사하지 말도록 지시
HRESULT SetColorKey(DWORD dwFlags, // what kind of key
LPDDCOLORKEY lpDDColorKey); // range of key
typedef struct _DDCOLORKEY {
DWORD dwColorSpaceLowValue; // starting color (inclusive)
DWORD dwColorSpaceHighValue;// ending color (inclusive)
} DDCOLORKEY,FAR* LPDDCOLORKEY;
10
Source Key ExampleSource Key Example
DDCOLORKEY key; // color key
// set transparent color range to 0
key.dwColorSpaceLowValue = 0;
key.dwColorSpaceHighValue = 0;
// set color key now on the source surface, which is usually the backbuffer
lpddsback->SetColorKey(DDCKEY_SRCBLT, &key);
// perform the blit from backbuffer to primary buffer
lppddsprimary->Blt(...);
11
Source KeySource Key 의 예의 예
+Blitting
Source Key = R
Source
Destination
Result
R
GB
Y
Y
B G
12
목적키목적키 (destination key)(destination key)
• 그려질 목적 표면에 색상키 범위를 설정 • Dest key 와 같은 색이 먼저 깔려 있으면 그 곳에는 bli
tting 되지 않는다 .
DDCOLORKEY key; // color key
// set writable values from 0 to 249
key.dwColorSpaceLowValue = 0;
key.dwColorSpaceHighValue = 249;
// set color key now on the destination surface
lpddsprimary->SetColorKey(DDCKEY_DESTCBLT, &key);
// perform the blit from backbuffer to primary buffer
// or whatever is the source surface...
lppddsprimary->Blt(...);
13
Destination KeyDestination Key 의 예의 예
+Blitting
Dest Key = B
Source
Destination
Result
R
GB
Y
Y
G
R
B
14
템플릿으로부터 비트맵 추출 템플릿으로부터 비트맵 추출
15
BOB(Bitmapped Object Bitmap) BOB(Bitmapped Object Bitmap) 사용사용
1. DirectDraw 를 설정한다 .
2. 10 장에서처럼 8 비트 또는 16 비트 색상의 비트맵 이미지에 객체들을 불러온다 .
3. Create_BOB() 또는 Create_BOB16() 으로 BOB 를 생성한다 .
4. Load_BOB() 또는 Load_BOB16() 으로 이미지를 BOB 에 불러온다 .
5. Draw_BOB() 또는 Draw_BOB16() 으로 BOB 를 그린다 .
6. 완료하면 , Destroy_BOB() 또는 Destroy_BOB16()으로 BOB 을 제거한다 .
16
BOB StructureBOB Structure
typedef struct BITMAP_OBJ_TYP
{
int state; // the state of the object (general)
int attr; // attributes pertaining to the object (general)
int x,y; // position bitmap will be displayed at
int xv,yv; // velocity of object
int width, height; // the width and height of the bitmap
LPDIRECTDRAWSURFACE7 image; // the bitmap surface itself
} BITMAP_OBJ, *BITMAP_OBJ_PTR;
#define BOB_STATE_DEAD 0 // this is a dead BOB
#define BOB_STATE_ALIVE 1 // this is a live BOB
#define BOB_STATE_LOADED 2 // the BOB has been loaded
17
죽은죽은 (dead) BOB(dead) BOB 와 살아있는와 살아있는 (live) BOB (live) BOB
• 살아있다는 것은 BOB 가 게임 로직에 의해 처리되고 있음을 뜻한다 .
• BOB 가 죽었다는 것은 게임 로직에 의해 처리되지 않는다는 것을 의미한다 .
18
BOB BOB 생성 생성 (1)(1)
int Create_BOB(BITMAP_OBJ_PTR bob, // the BOB to create int width, int height, // size of BOB int attr, // attrs int flags = 0) // memory flag{// create the BOB object; note that all BOBs are created as off-screen// surfaces in VRAM as the default; if you want to use system memory,// set flags equal to DDSCAPS_SYSTEMMEMORYDDSURFACEDESC2 ddsd; // used to create surface// set state and attributes of BOBbob->state = BOB_STATE_ALIVE;bob->attr = attr;bob->image = NULL;// set position and velocity to 0bob->x = bob->y = bob->xv = bob->yv = 0;// set to access caps, width, and heightmemset(&ddsd,0,sizeof(ddsd));ddsd.dwSize = sizeof(ddsd);ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
19
BOB BOB 생성 생성 (2)(2)
// set dimensions of the new bitmap surfaceddsd.dwWidth = bob->width = width;ddsd.dwHeight = bob->height = height;// set surface to off-screen plainddsd.ddsCaps.dwCaps = DDSCAPS_OFF_SCREENPLAIN | flags;// create the surfaceif (lpdd->CreateSurface(&ddsd,&(bob->image),NULL)!=DD_OK) return(0);// set color key to color 0DDCOLORKEY color_key; // used to set color keycolor_key.dwColorSpaceLowValue = 0;color_key.dwColorSpaceHighValue = 0;// now set the color key for source blitting(bob->image)->SetColorKey(DDCKEY_SRCBLT, &color_key);// return successreturn(1);} // end Create_BOB
20
비트맵 데이터로 비트맵 데이터로 BOB BOB 로딩하기 로딩하기 (1) (1)
• 목적 BOB 와 읽어올 원본 비트맵 파일을 인수로 받는다 .
• (cx, cy) 와 mode 에 의해서 읽어올 위치가 결정된다 . • Cell Mode (0): (cx, cy) 는 셀 좌표로 해석된다 . • Absolute Mode (1): (cx, cy) 는 원본 비트맵의 절대
좌표로 해석된다 . • 읽을 비트맵의 크기는 BOB 와 정확하게 맞으며 ,
이것은 bob->width 와 bob->height 에 정의된다 .
21
비트맵 데이터로 비트맵 데이터로 BOB BOB 로딩하기 로딩하기 (2)(2)
22
비트맵 데이터로 비트맵 데이터로 BOB BOB 로딩하기 로딩하기 (3)(3)
int Load_BOB(BITMAP_OBJ_PTR bob, // BOB to load with dataBITMAP_FILE_PTR bitmap, // bitmap to scan image data from int cx,int cy, // cell or absolute pos to scan image from int mode) // if 0, then cx,cy is cell position; else // cx,cy are absolute coordinates{// this function extracts a bitmap out of a bitmap fileUCHAR *source_ptr, // working pointers *dest_ptr;DDSURFACEDESC2 ddsd; // DirectDraw surface description// test the mode of extraction, cell-based or absoluteif (mode==0) { // re-compute x,y cx = cx*(bob->width+1) + 1; cy = cy*(bob->height+1) + 1; } // end if
23
비트맵 데이터로 비트맵 데이터로 BOB BOB 로딩하기 로딩하기 (4)(4)
// extract bitmap data
source_ptr = bitmap->buffer +
cy*bitmap->bitmapinfoheader.biWidth+cx;
// get the addr to destination surface memory
// set size of the structure
ddsd.dwSize = sizeof(ddsd);
// lock the display surface
(bob->image)->Lock(NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
// assign a pointer to the memory surface for manipulation
dest_ptr = (UCHAR *)ddsd.lpSurface;
24
비트맵 데이터로 비트맵 데이터로 BOB BOB 로딩하기 로딩하기 (5)(5)
// iterate through each scanline and copy bitmapfor (int index_y=0; index_y<bob->height; index_y++) { // copy next line of data to destination memcpy(dest_ptr, source_ptr,bob->width); // advance pointers dest_ptr += (ddsd.lPitch); source_ptr += bitmap->bitmapinfoheader.biWidth; } // end for index_y// unlock the surface(bob->image)->Unlock(NULL);// set state to loadedbob->state |= BOB_STATE_LOADED;// return successreturn(1);} // end Load_BOB
25
BOB BOB 그리기그리기int Draw_BOB(BITMAP_OBJ_PTR bob, // BOB to draw LPDIRECTDRAWSURFACE7 dest) // surface to draw the BOB on{// draw a BOB at the x,y defined in the BOB// on the destination surface defined in destRECT dest_rect, // the destination rectangle source_rect; // the source rectangle// fill in the destination rectdest_rect.left = bob->x;dest_rect.top = bob->y;dest_rect.right = bob->x+bob->width;dest_rect.bottom = bob->y+bob->height;// fill in the source rectsource_rect.left = 0;source_rect.top = 0;source_rect.right = bob->width;source_rect.bottom = bob->height;// blt to destination surfacedest->Blt(&dest_rect, bob->image, &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC), NULL);// return successreturn(1);} // end Draw_BOB
26
BOB BOB 소멸하기 소멸하기
int Destroy_BOB(BITMAP_OBJ_PTR bob)
{
// destroy the BOB; simply release the surface
if (bob->image)
(bob->image)->Release();
else
return(0);
// return success
return(1);
} // end Destroy_BOB
27
BOBBOB 를 움직이게 하는 함수들 를 움직이게 하는 함수들 (16bit)(16bit)
BITMAP_FILE bitmap; // working bitmap fileBITMAP_OBJ car; // the bitmapped object// load the bitmapLoad_Bitmap_File(&bitmap,”cars16.bmp”);// create a 32 x 32 VRAM BOBCreate_BOB16(&car,32,32,0,0,0);// load the BOB with first cell of bitmap template imageLoad_BOB16(&car,0,0,0);// unload the bitmap; you’re done with itUnload_Bitmap_File(&bitmap);// set position of BOBcar.x = 100;car.y = 200;// draw BOB on primary surfaceDraw_BOB16(&car, lppdsprimary);// your game code goes here...// delete the BOBDestroy_BOB16(&car);
28
DEMO: PROG11_1_16DEMO: PROG11_1_16
29
색상을 이용한 기술들 색상을 이용한 기술들
• 게임 프로그래머는 기교 (trick) 를 써서 – 그래픽 시스템이 실제보다 더 많은 색상이 있는 것처럼 보이게 하고 , – 또한 기존 하드웨어로는 불가능한 것처럼 보이는 광원 (lighting)
효과를 적용하기도 했다 .
• 요즘에는 이런 trick 을 쓰지 않아도 된다 . • 휴대폰이나 PDA 게임 프로그래밍에 여전히 적용 가능하다 .
30
팔레트 애니메이션팔레트 애니메이션
• 8 비트 색상 모드에서만 적용 • 하나 혹은 이상의 팔레트 항목을 실시간에 새로운 데이터로
갱신하는 것이다 . • 이 방법으로 이들 색상으로 그려진 픽셀은 시간에 따라
변한다 . • 깜빡이는 빛이나 , 에너지 펄스 , 폭발 등에 이 기법을
사용한다 .
31
DEMO: PROG11_2DEMO: PROG11_2
32
색상 회전색상 회전 (color rotation) (color rotation)
• 움직임을 잘 시뮬레이션 한다 • 폭포수나 흐르는 샘물 , 또는 컨베이어 벨트
33
DEMO: PROG11_3DEMO: PROG11_3
34
클리핑클리핑 (clipping) (clipping)
• 이미지에서 보이지 않는 부분을 그리지 않는 것을 의미
35
두가지 클리핑 방법두가지 클리핑 방법
• 이미지 - 공간 (image-space) 클리핑– 픽셀 단위로 그리는 것처럼 클리핑하는 방법이다 . – 시간이 많이 걸리고 , 때로는 하드웨어 가속기능이 있을
때에만 잘 동작한다 . – 물체의 각 픽셀을 그릴 때에 그것이 클리핑 영역에 그려지지
않는 것을 확인해야 한다는 것이다 .
• 오브젝트 - 공간 (object-space) 클리핑 – 매 픽셀마다 클리핑 영역과 비교하는 것이 아니라 , 그려질
물체의 형태를 분석하여 , 어느 정도의 부분을 그려야 하는지 계산
– 이미지 - 공간 클리핑보다 조금 더 수학적이다 .
36
Clipping CasesClipping Cases
37
오브젝트오브젝트 -- 공간 클리핑의 간단한 예 공간 클리핑의 간단한 예
// trivial rejections test first// is the rectangle totally off the screen?if (x1 > MAX_X || x2 < MIN_X || y1 > MAX_Y || y2 < MIN_Y) { /* totally clipped, do nothing */ }// check x coordsif (x1 < MIN_X) x1 = MIN_X;else if (x2 > MAX_X) x2 = MAX_X;// now y coordsif (y1 < MIN_Y) y1 = MIN_Y;else if (y2 > MAX_Y) y2 = MAX_Y;// at this point, (x1,y1) through (x2,y2) contain the clipped rectangle...
38
DirectDrawClipperDirectDrawClipper 의 소개 의 소개
• DirectDraw 는 블리트하고자 하는 어떤 표면에도 추가할 수 있는 DirectDrawClipper 를 지원한다 .
• 클리퍼는 여러 개의 클리핑 영역을 가질 수 있다 .
39
DirectDrawClipperDirectDrawClipper 를 생성하는 단계 를 생성하는 단계
1. DirectDrawClipper 객체를 생성한다 .
2. 클리핑 사각형의 목록을 생성하고 그것을 클리퍼 (clipper) 에 할당한다 .
3. 클리퍼를 표면 (surface) 에 추가한다 .
40
DirectDrawClipper DirectDrawClipper 생성 생성
// Prototype
HRESULT CreateClipper(DWORD dwFlags, // unused; make 0
LPDIRECTDRAWCLIPPER FAR *lplpDDClipper, // ptr to result
IUnknown FAR *pUnkOuter); // always NULL
// Example
LPDIRECTDRAWCLIPPER lpddclipper; // the clipper
if ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK)
return(NULL);
41
클리핑 목록 채우기 클리핑 목록 채우기 (1) (1)
• RGNDATA typedef struct _RGNDATA { // rgnd
RGNDATAHEADER rdh; // the header
char Buffer[1]; // a list of RECTs defining clipping
} RGNDATA;
typedef struct _RGNDATAHEADER { // rgndh
DWORD dwSize; // size of this header
DWORD iType; // must be RDH_RECTANGLES
DWORD nCount; // number of rectangles in buffer
DWORD nRgnSize; // size of the buffer
RECT rcBound; // a bounding box around all the rects
} RGNDATAHEADER;
42
클리핑 목록 채우기 클리핑 목록 채우기 (2) (2)
HRESULT SetClipList(
LPRGNDATA lpClipList, // ptr to RGNDATA
DWORD dwFlags); // unused; must be 0
RGNDATA region_data; // holds the RECTs and data header
// fill in region_data...
// set clipping list
if ((lpddclipper->SetClipList(®ion_data, 0))!=DD_OK)
{ /* error */ }
43
클리퍼를 표면에 추가하기 클리퍼를 표면에 추가하기
if ((lpdds->SetClipper(lpddclipper))!=DD_OK)
{ /* error */ }
44
Wrapper Fn: DD_Attach_Clipper (1)Wrapper Fn: DD_Attach_Clipper (1)
LPDIRECTDRAWCLIPPERDD_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, int num_rects, LPRECT clip_list){// this function creates a clipper from the sent clip list// and attaches it to the sent surfaceint index; // looping varLPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipperLPRGNDATA region_data; // pointer to the region data that contains // the header and clip list// first create the DirectDraw clipperif ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK) return(NULL);// now create the clip list from the sent data// first allocate memory for region dataregion_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + num_rects*sizeof
(RECT));// now copy the rects into region datamemcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);
45
Wrapper Fn: DD_Attach_Clipper (2)Wrapper Fn: DD_Attach_Clipper (2)
// set up fields of headerregion_data->rdh.dwSize = sizeof(RGNDATAHEADER);region_data->rdh.iType = RDH_RECTANGLES;region_data->rdh.nCount = num_rects;region_data->rdh.nRgnSize = num_rects*sizeof(RECT);region_data->rdh.rcBound.left = 64000;region_data->rdh.rcBound.top = 64000;region_data->rdh.rcBound.right = -64000;region_data->rdh.rcBound.bottom = -64000;// find bounds of all clipping regionsfor (index=0; index<num_rects; index++) { // test whether the next rectangle unioned with the current bound is larger if (clip_list[index].left < region_data->rdh.rcBound.left) region_data->rdh.rcBound.left = clip_list[index].left; if (clip_list[index].right > region_data->rdh.rcBound.right) region_data->rdh.rcBound.right = clip_list[index].right; ….
46
Wrapper Fn: DD_Attach_Clipper (3)Wrapper Fn: DD_Attach_Clipper (3)
// set up fields of header// you’ve computed the bounding rectangle region and// set up the data; now set the clipping listif ((lpddclipper->SetClipList(region_data, 0))!=DD_OK) { // release memory and return error free(region_data); return(NULL); } // end if// now attach the clipper to the surfaceif ((lpdds->SetClipper(lpddclipper))!=DD_OK) { // release memory and return error free(region_data); return(NULL); } // end if// all is well, so release memory and send back the pointer// to the new clipperfree(region_data);return(lpddclipper);} // end DD_Attach_Clipper
47
클리핑 목록을 설정하는 방법 클리핑 목록을 설정하는 방법
// create clip list (4) rectangles
RECT cliplist[4] = { {0,0,100,100}, {200,200,300,300},
{400,100,500,200}, {500,400,550,450}};
// attach clipper and save in lpddclipper
lpddclipper = DD_Attach_Clipper(lpddsprimary,4,cliplist);
48
DEMO: PROG11_4_16BDEMO: PROG11_4_16B
49
GDIGDI 와 와 DirectDrawDirectDraw 의 사용 의 사용
• 윈도우즈와 DirectDraw 의 고수준 ( 메시지 상자 , 메뉴 등 ) 과 저수준 ( 물체 그리기 , 텍스트 그리기 ) 혼합
50
DirectDrawDirectDraw 에서 에서 GDIGDI 를 사용하기 위해 를 사용하기 위해 세 가지 선택 세 가지 선택 • 고수준 컨트롤의 경우
– GDC(Graphics Device Context; 그래픽 장치 컨텍스트 ) 를 이용하지 않고 , GDI 를 이용하는 가장 간단한 방법이다 . 대신 , 메시지 상자 , 대화상자 , 메뉴와 같은 고수준 컨트롤을 사용한다 . GDC 는 HDC(Handle to Device Context) 의 특수한 경우이다 .
• GDC 를 이용하는 경우– 임의의 표면에 그리기 위해 GDC( 비디오 모드 , 메모리 ,
해상도 , 색상 공간 등의 기술 ) 를 사용할 수 있다 . IDIRECTDRAWSURFACE7 의 함수를 이용하여 DirectDraw 로부터 GDC 를 요청한다 .
• 윈도우 모드의 경우– 표준 윈도우 모드를 이용하여 GDI 와 함께 DirectDraw 를
사용할 수 있다 . 이 책에 나오는 대부분의 그래픽을 이용하는 코드는 전체 비디오 표면을 위임받고 그래픽 모드를 변경한다 . 그러나 때때로 그렇게 하고 싶지 않을 수도 있고 , 표준 윈도우 모드에서 DirectDraw 를 이용하여 그릴 수도 있다 .
51
연결하기연결하기
• 목적 표면의 GDI 작업을 위한 윈도우 핸들과 DirectDraw, 그리고 나머지를 해주는 윈도우즈가 필요하다 .
• 메시지 박스를 주표면의 비트맵 이미지 위에 표시하고 싶다면 // this will pop up a message box on top of the image
if (KEY_DOWN(‘M’))
{
// show the mouse cursor
ShowCursor(TRUE);
// display the GDI message box
MessageBox(main_window_handle,”What’s Up Baby!”,
“Message Box Test”,MB_OK);
// hide the mouse cursor
ShowCursor(FALSE);
} // end if
52
DEMO: PROG11_5DEMO: PROG11_5
• Press ‘M’ for showing Message Box
53
그리기 그리기 (1)(1)
• 그래픽 장치 컨텍스트 (GDC) 가 필요 • GDC 는 비디오 모드 , 메모리 , 해상도 , 색상 공간
등의 기술 (description) 에 불과 • 주표면이든 , 보조표면이든 혹은 작은 오프스크린
표면이든지 , 어느 표면에서든 GDC 를 얻을 수 있다 . • GDC 를 얻은 다음에는 표준 GDI 함수들을 이용해서
그 표면에 어떤 것이든 그릴 수 있다 .
54
그리기 그리기 (2)(2)
HDC xdc; // a DirectX GDC handleHPEN old_pen, hpen; // pens used to drawlpddsback->GetDC(&xdc); // get the DirectDraw GDC handle from the surface// draw some linesfor (int index=0; index<100; index++) { // create a random colored pen hpen = CreatePen(PS_SOLID,1, RGB(rand()%256,rand()%256,rand()%256)); // select the pen into context old_hpen = (HPEN)SelectObject(xdc,hpen); // move to a random position MoveToEx(xdc, rand()%WINDOW_WIDTH, rand()%WINDOW_HEIGHT, NULL); // draw a line LineTo(hdc,rand()%WINDOW_WIDTH, rand()%WINDOW_HEIGHT); // now delete the pen SelectObject(xdc,old_hpen); DeleteObject(hpen);} // end for index// release the DirectDraw-compatible GDClpddsback->ReleaseDC(xdc);
55
DEMO: PROG11_6DEMO: PROG11_6
• BOB 개체를 왼쪽에서 오른쪽으로 움직이고 , 그리고 GDI를 써서 BOB 개체 위에 문자열을 그린다 .
56
윈도우 모드의 사용 윈도우 모드의 사용 (1) (1)
• 그저 하나의 주표면을 생성하고 , 그리고 윈도우의 클라이언트 영역에만 그린다 .
// create DirectDraw object
DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL);
// set cooperation level to windowed mode normal
lpdd->SetCooperativeLevel(main_window_handle,DDSCL_NORMAL);
// create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;
lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
57
윈도우 모드의 사용 윈도우 모드의 사용 (2) (2)
• 윈도우의 좌표 얻기
58
윈도우 모드의 사용 윈도우 모드의 사용 (3)(3)
• 256 색상 800x600 인 윈도우 모드에서 돌아가는 DirectDraw 응용 프로그램이 있다고 하자 .
• 윈도우 클라이언트 영역에만 그리고자 할 때
RECT ddclient; // holds the client area of the window// get the client rectangle of the DirectDraw windowGetWindowRect(main_window_handle, &ddclient);// lock the primary buffer into primary_buffer....// the starting address of the client area at pixel (0,0) isprimary_buffer[ddclient.left+ (ddclient.top*ddsd.lPitch)] = color;// and the bottom-right corner isprimary_buffer[ddclient.right+ (ddclient.bottom*ddsd.lPitch)] = color;// unlock primary surface....
59
DEMO: PROG11_7DEMO: PROG11_7
• 윈도우 모드 DirectDRaw 윈도우에 랜덤하게 픽셀을 그린다 .
• 이 프로그램은 8 비트 , 16 비트 , 24 비트 , 그리고 32비트 그래픽 모드를 자동으로 감지한다 .
• 각 비트 깊이에 대한 픽셀을 그리는 코드를 살펴보도록 한다 .
60
DirectDrawDirectDraw 가 알려주는 것들가 알려주는 것들
• Get_ 함수들 : GetCaps(), …. • GetCaps()
– 거의 모든 DirectDraw 인터페이스와 객체에는 GetCaps() 가 있다 .
HRESULT GetCaps(
LPDDCAPS lpDDDriverCaps, // hardware capabilities
LPDDCAPS lpDDHELCaps); // software-emulation capabilities
// these variables will store all the capabilities
DDCAPS HELddcaps, HALddcaps;
// get the capabilities
lpdd->GetCaps(&HALddcaps, &HELddcaps);
HALddcaps.dwVidMemTotal // total video memory
HALddcaps.dwVidMemFree // video memory free
61
DirectDraw DirectDraw 표면 표면 GetCaps() GetCaps() 사용하기사용하기
DDSCAPS2 primaryddscaps; // used to hold the capabilities
// get the data
lpddsprimary->GetCaps(&primaryddscaps);
• 8 장에서 표면을 기술하는 DDSCAP2 구조체에 대해서 언급했다 .
62
DirectDraw DirectDraw 팔레트 객체에 팔레트 객체에 GetCaps() GetCaps()
DWORD pal_flags;
// make the call
lpddpal->GetCaps(&pal_flags);
// test the flags for 8-bit
if (pal_flags && DDPCAPS_8BIT)
{ /* do the dew */ }
Table 11-1: 팔레트 GetCaps Flags