2D Game Programming -...

51
한국산업기술대학교 게임공학과 정내훈 2D Game Programming

Transcript of 2D Game Programming -...

Page 1: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

한국산업기술대학교

게임공학과

정 내 훈

2D Game Programming

Page 2: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

개요

2

표면

– 표시 가능한 메모리

팔레트

DirectDraw로 그리기

Page 3: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

3

정의 : 실제 그래픽이 그려지는 장소

– 모니터로 나오는 것은 주표면 하나 뿐

위치 : 메모리 영역

– 한 프로그램에서 여러 개의 표면을 다룰 수있다.

주표면

– 비디오 스크린 자체

Page 4: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

4

메모리

메인메모리

비데오메모리

표면

표면

표면

표면

표면

표면

표면

표면

Page 5: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

5

성질

– 표면은 임의의 크기를 가질 수 있다.

• 예외) 주표면 : 화면해상도와 일치해야 한다.

– 비디오 메모리와 시스템 메모리에 작성할 수있다.

• 비디오 메모리가 빠르다.

– 비트 깊이와 색상 공간으로 속성 정의

• 같은 속성을 갖는 경우 데이터를 교환할 수 있다.

Page 6: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

6

종류– 주표면

• Primary Display Surface

• 모니터에 표시되는 표면

• 한 개만 존재

– 보조 표면

• Secondary Display Surface

• 후면버퍼 (back buffer)라고도 불린다.

• 주표면과 같은 속성 (, 크기 )

• 애니메이션을 위한 다음 준비 표면

– 오프스크린 표면

• 실제 모니터와 연결되는 일이 없음

• 하드웨어 가속을 위해 이미지를 저장하는 표면

Page 7: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

DirectDraw에서의 표면

– 표면 자체의 포인터

• LPDIRECTDRAWSURFACE7

– 표면 속성 자료구조

• LPDDSURFACEDESC2

– 표면 생성 API

• 성공시 DD_OK

7

HRESULT CreateSurface(

LPDDSURFACE2 lpDDSurfaceDesc,

LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface,

Iunknown FAR *pUnkOuter);

Page 8: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

DirectDraw 표면 기술자 구조체

– Surface descriptor structure

8

typedef struct _DDSURFACEDESC2

{

DWORD dwSize; // size of the DDSURFACEDESC structure

DWORD dwFlags; // determines what fields are valid

DWORD dwHeight; // height of surface to be created

DWORD dwWidth; // width of input surface

union

{

LONG lPitch; // distance to start of next line (return value only)

DWORD dwLinearSize; // Formless late-allocated optimized surface size

} DUMMYUNIONNAMEN(1);

union

{

DWORD dwBackBufferCount; // number of back buffers requested

DWORD dwDepth; // the depth if this is a volume texture

} DUMMYUNIONNAMEN(5);

union

{

DWORD dwMipMapCount; // number of mip-map levels requestde

// dwZBufferBitDepth removed, use ddpfPixelFormat one instead

DWORD dwRefreshRate; // refresh rate (used when display mode is described)

DWORD dwSrcVBHandle; // The source used in VB::Optimize

} DUMMYUNIONNAMEN(2);

DWORD dwAlphaBitDepth; // depth of alpha buffer requested

DWORD dwReserved; // reserved

LPVOID lpSurface; // pointer to the associated surface memory

...

Page 9: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

DirectDraw 표면 기술자 구조체

– Surface descriptor structure

9

typedef struct _DDSURFACEDESC2

{

. . . . . . .

union

{

DDCOLORKEY ddckCKDestOverlay; // color key for destination overlay use

DWORD dwEmptyFaceColor; // Physical color for empty cubemap faces

} DUMMYUNIONNAMEN(3);

DDCOLORKEY ddckCKDestBlt; // color key for destination blt use

DDCOLORKEY ddckCKSrcOverlay; // color key for source overlay use

DDCOLORKEY ddckCKSrcBlt; // color key for source blt use

union

{

DDPIXELFORMAT ddpfPixelFormat; // pixel format description of the surface

DWORD dwFVF; // vertex format description of vertex buffers

} DUMMYUNIONNAMEN(4);

DDSCAPS2 ddsCaps; // direct draw surface capabilities

DWORD dwTextureStage; // stage in multitexture cascade

} DDSURFACEDESC2;

Page 10: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

DDSURFACEDESC2의 용도

– 표면의 속성을 정의하거나 수정할 때 사용

– 모든 멤버를 다 정의해야 할 필요는 없음

– 필요한 멤버를 정의하고 정의된 멤버를dwFlags에 지정하면 됨

– dwSize를 지정하는 것을 잊으면 안됨

10

Page 11: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

dwFlag의 설정들

11

값 의미

DDSD_ALL 모든 멤버가 유효

DDSD_HEIGHT dwHeight가 유효

DDSD_WIDTH dwWidth가 유효

DDSD_PITCH lpitch가 유효

DDSD_PIXELFORMAT ddpfPixelFormat이 유효

DDSD_LPSURFACE lpSurface가 유효

DDSD_CAPS ddsCaps가 유효

DDSD_ALPHABITDEPTH dwAlphaBitDept가 유효

Page 12: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

ddCaps란?

– 화면에 부가적인 속성을 지정할 때 사용

– dwCaps만 사용

• dwCaps2, dwCaps3, dwCaps4는 3D용

12

typedef struct _DDSCAPS2

{

DWORD dwCaps; // capabilities of surface wanted

DWORD dwCaps2;

DWORD dwCaps3;

union

{

DWORD dwCaps4;

DWORD dwVolumeDepth;

} DUMMYUNIONNAMEN(1);

} DDSCAPS2;

Page 13: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

DwCaps의 설정들

13

값 의미

DDSCAPS_BACKBUFFER 표면이 후면 버퍼가 된다.

DDSCAPS_FLIP 플립이 가능하다.

DDSCAPS_FRONTBUFFER 표면이 전면 버퍼가 된다.

DDSCAPS_OFFSCREENPLAIN 표면이 오버레이, 텍스쳐, z-버퍼,

전면버퍼, 후면버퍼가 아닌 오프스크린 버퍼이다

DDSCAPS_OWNDC DC를 갖는다

DDSCAPS_PRIMARYSURFACE 주표면이다

DDSCAPS_SYSTEMMEORY 주메모리에 할당된다.

Page 14: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

주 표면 생성하기

14

LPDIRECTDRAW7 lpdd = NULL; // dd object

LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface

DDSURFACEDESC2 ddsd; // a direct draw surface description struct

if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)

return(0);

// set cooperation level to windowed mode normal

if (lpdd->SetCooperativeLevel(main_window_handle,

DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |

DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)

return(0);

// set the display mode

if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)

return(0);

// Create the primary surface

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

ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

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

return(0);

Page 15: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

표면 (Surface)

주 표면 생성하기

– 잊지 말 것

15

if (lpddsprimary!=NULL)

lpddsprimary->Release();

// release the directdraw object

if (lpdd!=NULL)

lpdd->Release();

Page 16: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

실습

프로그램

– Prog9_1.cpp

16

Page 17: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

메모리 주소와 픽셀의 위치

메모리와 픽셀의 대응

– 가로세로 w, h의 크기를 갖는 표면

17

(w-1, h-1)

(0,0)

메모리 주소 증가 방향 (dwBPP / 8 만큼 증가)

메모리 주소 증가 방향 (lPitch만큼 증가)

Page 18: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

메모리 주소와 픽셀의 위치

선형 vs 비선형 메모리

– dwBPP / 8 * w = lPitch????

• 선형 메모리 : YES

• 비선형 메모리 : NO

– 하나의 가로줄의 메모리크기가 2^n형태로표현되지 않을때 lPitch가 2^n이 되면서 비선형 메모리가 될 수 있다.

• 2^n이 되면 곱하기가 아닌 shift연산으로 좌표를계산할 수 있다.

– 1024 * x = x << 10

Page 19: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

메모리 주소와 픽셀의 위치

비선형 메모리

19

(w-1, h-1)

2^n - 1

메모리 주소 증가 방향 (dwBPP / 8 만큼 증가)

메모리 주소 증가 방향 (lPitch만큼 증가)

화면에표시되지

않는

영역

(0,0)

dwBPP / 8 * (w – 1)

2^n

0

2^n * 2

Page 20: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

메모리 주소와 픽셀의 위치

픽셀 좌표 계산

– 픽셀의 메모리 주소• 표면의 주소 + X 좌표 * dwBPP / 8 + Y 좌표 * dwWidth *

dwBPP / 8

– 선형 메모리일 경우 만 옳음

• 표면의 주소 + X 좌표 * dwBPP / 8 + Y 좌표 * lPitch

– 픽셀의 Color 변환법

20

UCHAR *video_buffer;

// 8 BPP

// Width가 1024인 경우

video_buffer[x + 1024*y] = color;

UINT *video_buffer;

// 32 BPP

// Width가 1024인 경우

video_buffer[x + 1024*y] = color;

Page 21: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

DirectDraw의 그래픽 API

DirectDraw는 가장 기본적인 API만 제공한다.

– 색상 설정

– 표면 메모리 접근

– HW 가속 : 채움(Filling), 블리팅 (BitBlt)

그러면 선? 원? 다각형?

– 위의 API로 각자 제작해야 한다!

Page 22: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

팔레트 모드

과거 메모리 절약을 위해 사용하던 color

간접 지정 방식

사용할 color의 리스트를 테이블에 저장하고 실제 표면에는 리스트의 index를 저장

일반적으로 256크기의 테이블 사용

– BPP가 8이 됨

자세한 내용은 생략

Page 23: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

그리기 위해 필요한 사항

– 표면의 주소

– BPP, width

표면의 주소

– DDSD의 lpSurface

– lpSurface를 얻는 API : Lock

23

HRESULT Lock(LPRECT lpDestRecct,

LPDDSURFACEDESC2 lpDDSD,

DWORD dwFlags,

HANDLE hEvent);

Page 24: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

Lock

– 표면의 위치는 DirectX가 관리, 언제든지 이동 가능

• 따라서 사용하기 위해서는 움직이지 않게 고정(lock)시킬 필요가 있음.

24

HRESULT Lock(LPRECT lpDestRecct, // 변경하고자 하는 영역

LPDDSURFACEDESC2 lpDDSD, // 얻는 표면의 속성

DWORD dwFlags, // 얻고자 하는 속성

HANDLE hEvent); // 사용되지 않음, 반드시 NULL

Page 25: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

Lock의 플랙– DDLOCK_READONLY The surface locked is

readable only.

– DDLOCK_SURFACEMEMORYPTR The

surface locked returns a memory pointer to the

surface memory in lpSurface. This default action

takes place if you don’t send any flags.

– DDLOCK_WAIT If the surface can’t be locked,

wait until it can be.

– DDLOCK_WRITEONLY The surface being

locked is written to only.

25

Page 26: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

Unlock

– 다 그린 이후에는 반드시 Unlock을 해야 한다.

26

HRESULT Unlock(

LPRECT lpRect // pointer to rectangle to unlock

);

Page 27: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

픽셀을 화면에 찍는 법

– 1. 표면을 잠근다.

– 2. 디스플레이 표면의 포인터를 얻는다.

– 3. 픽셀 주소를 계산한다.

– 4. 주소에 쓴다.

– 5. 표면 잠금을 푼다.

27

Page 28: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

픽셀 그리기

픽셀을 화면에 찍는 법

28

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

ddsd.dwSize = sizeof(ddsd);

// lock the primary surface

lpddsprimary->Lock(NULL,&ddsd,

DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer

video_buffer = (UCHAR *)ddsd.lpSurface;

//.. use video pointer to write to memory

// notice the use of lPitch (linear pitch)

video_buffer[x + y*ddsd.lPitch] = col;

// unlock the surface

lpddsprimary->Unlock(NULL);

Page 29: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

실습

프로그램

– Prog9_2.cpp

29

Page 30: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

Color

16Bit

– 1.5.5.5 형식

• alpha 1 bit

• red, green, blue 각각 5 bits

– 5.6.5 형식

• red 5 bits

• green 6 bits (사람의 눈은 green에 가장 민감)

• blue 5 bits

– 일반적으로 99% 이상의 video card들은5.6.5 형식을 사용한다.

30

Page 31: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

31

Color

16비트 Color 매크로

// 5.5.5 format

#define _RGB16BIT(r,g,b) ((b%32)+((g%64)<<5)+((r%32)<<11))

example)

UCHAR red = 0x08 // 0000 1000

UCHAR green = 0x05 // 0000 0101

UCHAR blue = 0x1b // 0001 1011

Result = _RGB16BIT565(red,green,blue)– (blue % 32) = 0001 1011

– (green % 64) << 5 = (0000 0101) << 5 = 1010 0000

– (red % 32) << 11 = (0000 1000) << 11 = 0100 0000 0000 0000

Result = 0100 0000 1011 1011 = (01000) (000101) (11011)

Page 32: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

32

Color

// this builds a 16 bit color value in 1.5.5.5 format (1-bit alpha mode)

#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) <<

10))

example)

UCHAR red = 0x08 // 0000 1000

UCHAR green = 0x05 // 0000 0101

UCHAR blue = 0x1b // 0001 1011

Result = _RGB16BIT555(red,green,blue)– (blue & 31) = (0001 1011) & (0001 1111) = 0001 1011

– (green & 31) << 5 = (0000 0101) << 5 = 1010 0000

– (red & 31) << 10 = (0001 1000) << 10 = 0110 0000 0000 0000

Result = 0110 0000 1011 1011 = 0 (11000) (00101) (11011)

Page 33: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

33

16bit Mode로 그리기

640x480x16 모드에서 (x, y) 위치에 (r, g, b) 색상으로 그리는 예제

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

ddsd.dwSize = sizeof(ddsd);

// lock the primary surface

lpddsprimary->Lock(NULL,&ddsd,

DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer

video_buffer = (USHORT *)ddsd.lpSurface;

// use video pointer to write to memory..

// notice the use of lPitch (linear pitch) and the division by 2 (>>1);

// this is needed to keep the addressing correct because you’re using USHORT

// pointers and lPitch is always in bytes

video_buffer[x + (y*ddsd.lPitch >> 1)]=

(USHORT)_RGB16BIT565(r,g,b);

// unlock the surface

lpddsprimary->Unlock(NULL);

Page 34: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

34

Why lPitch >> 1

// pointers and lPitch is always in bytes

video_buffer[x + (y*ddsd.lPitch >> 1)]=

(USHORT)_RGB16BIT565(r,g,b);

USHORT를 사용할 때 모든 포인터 연산은 16비트로 이루어지지만, lPitch는 항상바이트로 표현되기 때문이다.

Page 35: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

35

DEMO: PROG9_3.CPP

PROG9_2_16.cpp 와 다른 점은 무엇인가?

Page 36: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

36

24비트나 32비트 표면

#define _RGB24BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) )

24bit 는 32bit 중 최상위 8bit가 사용되지 않을 뿐이다.

따라서 bpp를 32로 하는 것이 좋다.

Page 37: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

37

24, 32bit 이용 (1)

In Game_Init()

if (lpdd->SetDisplayMode(SCREEN_WIDTH,

SCREEN_HEIGHT,32,0,0)!=DD_OK) return(0);

Page 38: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

38

24, 32bit 이용 (2)

Game_Main()

UINT *video_buffer = NULL;

video_buffer = (UINT *)ddsd.lpSurface;

int words_per_line = (ddsd.lPitch >> 2);

UCHAR red = rand()%256;

UCHAR green = rand()%256;

UCHAR blue = rand()%256;

video_buffer[x + (y*words_per_line)] = _RGB24BIT(red,green,blue);

Page 39: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

39

보조표면(Secondary Surface)

보조 표면(또는 후면버퍼) 의 사용

– 부드러운 애니메이션

– 1. 주표면을 생성하고, 주표면으로부터 하나의 보조표면을 생성한다.

– 2. 주표면이 보여지는 동안 보조표면에 그린다.

– 3. 순간적으로 표면을 바꾸어서(switch or

flip), 보조표면이 주표면이 되게 하여, (그 반대로도 마찬가지) 부드러운 애니메이션을 만든다.

Page 40: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

40

Page Flipping

Page 41: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

41

보조표면의 생성 (1)

// DirectDraw surface description

DDSURFACEDESC2 ddsd;

// device capabilities structure, used to query for

// secondary backbuffer, among other things

DDSCAPS2 ddscaps;

LPDIRECTDRAWSURFACE7 lpddsprimary, // primary surface

lpddssecondary; // secondary backbuffer surface

// prepare to create primary surface with one backbuffer

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

ddsd.dwSize = sizeof(ddsd); // DDSURFACEDESC would work, too

// set the flags to validate both the capabilities

// field and the backbuffer count field

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// you need to let dd know that you want a complex flippable surface

structure;

Page 42: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

42

보조표면의 생성 (2)

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

Page 43: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

43

주표면과 부표면

Page 44: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

44

Rendering Backbuffer

// used to access secondary video buffer

UCHAR *video_buffer;

// lock the secondary surface

lpddsback->Lock(NULL,&ddsd,

DDLOCK_SURFACEMEMORYPTR |

DDLOCK_WAIT,NULL);

// draw on the surface: ddsd.lpSurface and

// ddsd.lPitch are valid as before

video_buffer = (UCHAR *)ddsd.lpSurface;

// unlock the surface

lpddsback->Unlock(NULL);

Page 45: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

45

Flipping

HRESULT Flip(

LPDIRECTDRAWSURFACE7 lpDDSurfaceOverride, // always NULL

DWORD dwFlags); // always DDFLIP_WAIT

// flip the primary and secondary surfaces

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

Page 46: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

46

Flipping 전후

Page 47: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

47

오프스크린 표면(off-screen surface)

시스템 메모리나 VRAM에 모두 존재할 수 있음

주표면과 같은 색상깊이와 속성을 가지는 비트맵

하드웨어 가속 Blt()를 위해 사용

스프라이트

– 간단히 말해서 비디오 게임 화면에서 움직이는 작은물체를 뜻한다. 대부분의 경우, 스프라이트는 비트맵일 뿐

– 8비트 PC인 MSX에서 HW에서 사용된 용어

Page 48: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

48

VRAM에 오프스크린 표면 생성

// .. assume DirectDraw has been set up and so on

DDSURFACEDESC2 ddsd; // a DirectDraw surface descriptor

LPDIRECTDRAWSURFACE7 lpwork; // the working surface

// set the size parameter as always

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

ddsd.dwSize = sizeof(ddsd);

// set the flags; very important

// remember that you must set the flags of the fields that will be valid

ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

// set dimensions of the new surface

ddsd.dwWidth = width;

ddsd.dwHeight = height;

// what kind of offscreen surface, system memory, or VRAM

// default is VRAM

ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

// now create the surface and check for error

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

{ /* error */ }

Page 49: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

49

시스템 메모리에

// set flags for an offscreen plain system memory surface

ddsd.ddsCaps.dwCaps =

DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;

// now create the surface and check for error

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

{ /* error */ }

Page 50: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

50

팔레트…

생략.

Page 51: 2D Game Programming - blog.tcltk.co.krblog.tcltk.co.kr/wp-content/uploads/2009/06/2D게임프로그래밍.pdf · 게임공학과 정내훈 2D Game Programming ... –표면의위치는DirectX가관리,

51

질문