chapter 11 directdraw n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Chapter 11 DirectDraw 의 깊은 곳 : 보다 발전된 기능들 PowerPoint Presentation
Download Presentation
Chapter 11 DirectDraw 의 깊은 곳 : 보다 발전된 기능들

Loading in 2 Seconds...

play fullscreen
1 / 62

Chapter 11 DirectDraw 의 깊은 곳 : 보다 발전된 기능들 - PowerPoint PPT Presentation


  • 178 Views
  • Uploaded on

Chapter 11 DirectDraw 의 깊은 곳 : 보다 발전된 기능들. 이 장에서는. - 비트맵 그래픽으로 고급 작업 수행하기 - 오프스크린 표면 사용하기 - 색상 애니메이션 기법 알아보기 - DirectDraw 와 GDI 결합하기 - 윈도우 모드에서 DirectDraw 사용하기 - DirectDraw 에서 정보 얻어오기. 투명도. Black-transparent 8-bit version. // 32 x 32 bitmap 을 화면 (x,y) 에 뿌리는 예제

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Chapter 11 DirectDraw 의 깊은 곳 : 보다 발전된 기능들' - nessa


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide2
이 장에서는
  • - 비트맵 그래픽으로 고급 작업 수행하기
  • - 오프스크린 표면 사용하기
  • - 색상 애니메이션 기법 알아보기
  • - DirectDraw와 GDI 결합하기
  • - 윈도우 모드에서 DirectDraw 사용하기
  • - DirectDraw에서 정보 얻어오기
black transparent 8 bit version
Black-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

black transparent 16 bit version
Black-transparent 16-bit version

// these two loops blit a 32 x 32 bitmap

for (int index_y=0; index_y<32; index_y++)

{

// copy next row of pixels

for (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

black transparent 8 bit without multiply
Black-transparent 8-bit (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

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

source key example
Source 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(...);

source key
Source Key의 예

Y

Source Key = R

R

+

G

B

Blitting

Source

Destination

Y

G

B

Result

destination key
목적키(destination key)
  • 그려질 목적 표면에 색상키 범위를 설정
  • Dest key 와 같은 색이 먼저 깔려 있으면 그 곳에는 blitting 되지 않는다.

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

destination key1

B

Destination Key의 예

Y

Dest Key = B

R

+

G

B

Blitting

Source

Destination

Y

R

G

Result

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을 제거한다.

bob structure
BOB 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

dead bob live bob
죽은(dead) BOB와 살아있는(live) BOB
  • 살아있다는 것은 BOB가 게임 로직에 의해 처리되고 있음을 뜻한다.
  • BOB가 죽었다는 것은 게임 로직에 의해 처리되지 않는다는 것을 의미한다.
bob 1
BOB 생성 (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_SYSTEMMEMORY

DDSURFACEDESC2 ddsd; // used to create surface

// set state and attributes of BOB

bob->state = BOB_STATE_ALIVE;

bob->attr = attr;

bob->image = NULL;

// set position and velocity to 0

bob->x = bob->y = bob->xv = bob->yv = 0;

// set to access caps, width, and height

memset(&ddsd,0,sizeof(ddsd));

ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

bob 2
BOB 생성 (2)

// set dimensions of the new bitmap surface

ddsd.dwWidth = bob->width = width;

ddsd.dwHeight = bob->height = height;

// set surface to off-screen plain

ddsd.ddsCaps.dwCaps = DDSCAPS_OFF_SCREENPLAIN | flags;

// create the surface

if (lpdd->CreateSurface(&ddsd,&(bob->image),NULL)!=DD_OK)

return(0);

// set color key to color 0

DDCOLORKEY color_key; // used to set color key

color_key.dwColorSpaceLowValue = 0;

color_key.dwColorSpaceHighValue = 0;

// now set the color key for source blitting

(bob->image)->SetColorKey(DDCKEY_SRCBLT, &color_key);

// return success

return(1);

} // end Create_BOB

bob 11
비트맵 데이터로 BOB 로딩하기 (1)
  • 목적 BOB와 읽어올 원본 비트맵 파일을 인수로 받는다.
  • (cx, cy)와 mode에 의해서 읽어올 위치가 결정된다.
  • Cell Mode (0): (cx, cy)는 셀 좌표로 해석된다.
  • Absolute Mode (1): (cx, cy)는 원본 비트맵의 절대 좌표로 해석된다.
  • 읽을 비트맵의 크기는 BOB와 정확하게 맞으며, 이것은 bob->width와 bob->height에 정의된다.
bob 3
비트맵 데이터로 BOB 로딩하기 (3)

int Load_BOB(BITMAP_OBJ_PTR bob, // BOB to load with data

BITMAP_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 file

UCHAR *source_ptr, // working pointers

*dest_ptr;

DDSURFACEDESC2 ddsd; // DirectDraw surface description

// test the mode of extraction, cell-based or absolute

if (mode==0)

{

// re-compute x,y

cx = cx*(bob->width+1) + 1;

cy = cy*(bob->height+1) + 1;

} // end if

bob 4
비트맵 데이터로 BOB 로딩하기 (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;

bob 5
비트맵 데이터로 BOB 로딩하기 (5)

// iterate through each scanline and copy bitmap

for (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 loaded

bob->state |= BOB_STATE_LOADED;

// return success

return(1);

} // end Load_BOB

slide25
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 dest

RECT dest_rect, // the destination rectangle

source_rect; // the source rectangle

// fill in the destination rect

dest_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 rect

source_rect.left = 0;

source_rect.top = 0;

source_rect.right = bob->width;

source_rect.bottom = bob->height;

// blt to destination surface

dest->Blt(&dest_rect, bob->image,

&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),

NULL);

// return success

return(1);

} // end Draw_BOB

slide26
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

bob 16bit
BOB를 움직이게 하는 함수들 (16bit)

BITMAP_FILE bitmap; // working bitmap file

BITMAP_OBJ car; // the bitmapped object

// load the bitmap

Load_Bitmap_File(&bitmap,”cars16.bmp”);

// create a 32 x 32 VRAM BOB

Create_BOB16(&car,32,32,0,0,0);

// load the BOB with first cell of bitmap template image

Load_BOB16(&car,0,0,0);

// unload the bitmap; you’re done with it

Unload_Bitmap_File(&bitmap);

// set position of BOB

car.x = 100;

car.y = 200;

// draw BOB on primary surface

Draw_BOB16(&car, lppdsprimary);

// your game code goes here...

// delete the BOB

Destroy_BOB16(&car);

slide29
색상을 이용한 기술들
  • 게임 프로그래머는 기교(trick)를 써서
    • 그래픽 시스템이 실제보다 더 많은 색상이 있는 것처럼 보이게 하고,
    • 또한 기존 하드웨어로는 불가능한 것처럼 보이는 광원(lighting) 효과를 적용하기도 했다.
  • 요즘에는 이런 trick을 쓰지 않아도 된다.
  • 휴대폰이나 PDA 게임 프로그래밍에 여전히 적용 가능하다.
slide30
팔레트 애니메이션
  • 8비트 색상 모드에서만 적용
  • 하나 혹은 이상의 팔레트 항목을 실시간에 새로운 데이터로 갱신하는 것이다.
  • 이 방법으로 이들 색상으로 그려진 픽셀은 시간에 따라 변한다.
  • 깜빡이는 빛이나, 에너지 펄스, 폭발 등에 이 기법을 사용한다.
color rotation
색상 회전(color rotation)
  • 움직임을 잘 시뮬레이션 한다
  • 폭포수나 흐르는 샘물, 또는 컨베이어 벨트
clipping
클리핑(clipping)
  • 이미지에서 보이지 않는 부분을 그리지 않는 것을 의미
slide35
두가지 클리핑 방법
  • 이미지-공간(image-space) 클리핑
    • 픽셀 단위로 그리는 것처럼 클리핑하는 방법이다.
    • 시간이 많이 걸리고, 때로는 하드웨어 가속기능이 있을 때에만 잘 동작한다.
    • 물체의 각 픽셀을 그릴 때에 그것이 클리핑 영역에 그려지지 않는 것을 확인해야 한다는 것이다.
  • 오브젝트-공간(object-space) 클리핑
    • 매 픽셀마다 클리핑 영역과 비교하는 것이 아니라, 그려질 물체의 형태를 분석하여, 어느 정도의 부분을 그려야 하는지 계산
    • 이미지-공간 클리핑보다 조금 더 수학적이다.
slide37
오브젝트-공간 클리핑의 간단한 예

// 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 coords

if (x1 < MIN_X) x1 = MIN_X;

else if (x2 > MAX_X) x2 = MAX_X;

// now y coords

if (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...

directdrawclipper
DirectDrawClipper의 소개
  • DirectDraw는 블리트하고자 하는 어떤 표면에도 추가할 수 있는 DirectDrawClipper를 지원한다.
  • 클리퍼는 여러 개의 클리핑 영역을 가질 수 있다.
directdrawclipper1
DirectDrawClipper를 생성하는 단계

1. DirectDrawClipper 객체를 생성한다.

2. 클리핑 사각형의 목록을 생성하고 그것을 클리퍼(clipper)에 할당한다.

3. 클리퍼를 표면(surface)에 추가한다.

directdrawclipper2
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);

slide41
클리핑 목록 채우기 (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;

slide42
클리핑 목록 채우기 (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(&region_data, 0))!=DD_OK)

{ /* error */ }

slide43
클리퍼를 표면에 추가하기

if ((lpdds->SetClipper(lpddclipper))!=DD_OK)

{ /* error */ }

wrapper fn dd attach clipper 1
Wrapper Fn: DD_Attach_Clipper (1)

LPDIRECTDRAWCLIPPER

DD_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 surface

int index; // looping var

LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper

LPRGNDATA region_data; // pointer to the region data that contains

// the header and clip list

// first create the DirectDraw clipper

if ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK)

return(NULL);

// now create the clip list from the sent data

// first allocate memory for region data

region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + num_rects*sizeof(RECT));

// now copy the rects into region data

memcpy(region_data->Buffer, clip_list,

sizeof(RECT)*num_rects);

wrapper fn dd attach clipper 2
Wrapper Fn: DD_Attach_Clipper (2)

// set up fields of header

region_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 regions

for (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; ….

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 list

if ((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 surface

if ((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 clipper

free(region_data);

return(lpddclipper);

} // end DD_Attach_Clipper

slide47
클리핑 목록을 설정하는 방법

// 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);

gdi directdraw
GDI와 DirectDraw의 사용
  • 윈도우즈와 DirectDraw의 고수준(메시지 상자, 메뉴 등)과 저수준(물체 그리기, 텍스트 그리기) 혼합
directdraw gdi
DirectDraw에서 GDI를 사용하기 위해 세 가지 선택
  • 고수준 컨트롤의 경우
    • GDC(Graphics Device Context; 그래픽 장치 컨텍스트)를 이용하지 않고, GDI를 이용하는 가장 간단한 방법이다. 대신, 메시지 상자, 대화상자, 메뉴와 같은 고수준 컨트롤을 사용한다. GDC는 HDC(Handle to Device Context)의 특수한 경우이다.
  • GDC를 이용하는 경우
    • 임의의 표면에 그리기 위해 GDC(비디오 모드, 메모리, 해상도, 색상 공간 등의 기술)를 사용할 수 있다. IDIRECTDRAWSURFACE7의 함수를 이용하여 DirectDraw로부터 GDC를 요청한다.
  • 윈도우 모드의 경우
    • 표준 윈도우 모드를 이용하여 GDI와 함께 DirectDraw를 사용할 수 있다. 이 책에 나오는 대부분의 그래픽을 이용하는 코드는 전체 비디오 표면을 위임받고 그래픽 모드를 변경한다. 그러나 때때로 그렇게 하고 싶지 않을 수도 있고, 표준 윈도우 모드에서 DirectDraw를 이용하여 그릴 수도 있다.
slide51
연결하기
  • 목적 표면의 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

demo prog11 5
DEMO: PROG11_5
  • Press ‘M’ for showing Message Box
slide53
그리기 (1)
  • 그래픽 장치 컨텍스트(GDC)가 필요
  • GDC는 비디오 모드, 메모리, 해상도, 색상 공간 등의 기술(description)에 불과
  • 주표면이든, 보조표면이든 혹은 작은 오프스크린 표면이든지, 어느 표면에서든 GDC를 얻을 수 있다.
  • GDC를 얻은 다음에는 표준 GDI 함수들을 이용해서 그 표면에 어떤 것이든 그릴 수 있다.
slide54
그리기 (2)

HDC xdc; // a DirectX GDC handle

HPEN old_pen, hpen; // pens used to draw

lpddsback->GetDC(&xdc); // get the DirectDraw GDC handle from the surface

// draw some lines

for (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 GDC

lpddsback->ReleaseDC(xdc);

demo prog11 6
DEMO: PROG11_6
  • BOB 개체를 왼쪽에서 오른쪽으로 움직이고, 그리고 GDI를 써서 BOB 개체 위에 문자열을 그린다.
slide56
윈도우 모드의 사용 (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);

slide57
윈도우 모드의 사용 (2)
  • 윈도우의 좌표 얻기
slide58
윈도우 모드의 사용 (3)
  • 256색상 800x600인 윈도우 모드에서 돌아가는 DirectDraw 응용 프로그램이 있다고 하자.
  • 윈도우 클라이언트 영역에만 그리고자 할 때

RECT ddclient; // holds the client area of the window

// get the client rectangle of the DirectDraw window

GetWindowRect(main_window_handle, &ddclient);

// lock the primary buffer into primary_buffer....

// the starting address of the client area at pixel (0,0) is

primary_buffer[ddclient.left+

(ddclient.top*ddsd.lPitch)] = color;

// and the bottom-right corner is

primary_buffer[ddclient.right+

(ddclient.bottom*ddsd.lPitch)] = color;

// unlock primary surface....

demo prog11 7
DEMO: PROG11_7
  • 윈도우 모드 DirectDRaw 윈도우에 랜덤하게 픽셀을 그린다.
  • 이 프로그램은 8비트, 16비트, 24비트, 그리고 32비트 그래픽 모드를 자동으로 감지한다.
  • 각 비트 깊이에 대한 픽셀을 그리는 코드를 살펴보도록 한다.
directdraw
DirectDraw가 알려주는 것들
  • 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

directdraw getcaps
DirectDraw 표면 GetCaps() 사용하기

DDSCAPS2 primaryddscaps; // used to hold the capabilities

// get the data

lpddsprimary->GetCaps(&primaryddscaps);

  • 8장에서 표면을 기술하는 DDSCAP2 구조체에 대해서 언급했다.
directdraw getcaps1
DirectDraw 팔레트 객체에 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