Upload
gerald-miles
View
235
Download
7
Embed Size (px)
Citation preview
Chapter 12Chapter 12
GPDUMB GPDUMB 게임 엔진게임 엔진 , , 파트 파트 1 1
2
이 장에서는이 장에서는
• - GPDUMB 8 비트 또는 16 비트 엔진 디자인• - 간단한 DirectDraw 인터페이스 생성하기• - 기본요소 (primitive) 그래픽 포함하기• - 색상 다루기• - 윈도우즈 GDI 지원 받기• - 비트맵 그래픽 사용하기• - 진보된 BOB 엔진 탐험하기• - 게임 시간 추적하기
3
GPDUMB GPDUMB 엔진의 구조엔진의 구조
4
File File 설명설명
• .CPP 파일 (GPDUMB1.CPP) 과 헤더 (GPDUM1.H) • 8 비트와 16 비트 그래픽 모두를 지원 • 16 비트 함수는 파일이름에 "16" 이 추가 • 게임 작성
– 프로그램에 헤더를 추가– GPDUMB1.CPP 를 확실히 프로젝트에 추가– 응용 프로그램이 윈도우를 생성– Game_Init(), Game_Main(), Game_Shutdown() 의 코드를
작성
• 게임 작성의 예
5
WinX WinX 와 와 GPDUMB EngineGPDUMB Engine
6
#define #define
• // default screen size• #define SCREEN_WIDTH 640 // size of screen• #define SCREEN_HEIGHT 480• #define SCREEN_BPP 8 // bits per pixel• // bitmap defines• #define BITMAP_ID 0x4D42 // universal id for a bitmap• #define BITMAP_STATE_DEAD 0 // states of bitmaps• #define BITMAP_STATE_ALIVE 1• #define BITMAP_STATE_DYING 2• #define BITMAP_ATTR_LOADED 128• #define BITMAP_EXTRACT_MODE_CELL 0• #define BITMAP_EXTRACT_MODE_ABS 1• // defines for BOBs• #define BOB_STATE_DEAD 0 // this is a dead bob• #define BOB_STATE_ALIVE 1 // this is a live bob• #define BOB_STATE_DYING 2 // this BOB is dying• #define BOB_STATE_ANIM_DONE 1 // done animation state• #define MAX_BOB_FRAMES 64 // max BOB frames• #define MAX_BOB_ANIMATIONS 16 // max anim sequences• #define BOB_ATTR_SINGLE_FRAME 1 // BOB has single frame• #define BOB_ATTR_MULTI_FRAME 2 // multiple frames• #define BOB_ATTR_MULTI_ANIM 4 // multiple animations• #define BOB_ATTR_ANIM_ONE_SHOT 8 // perform animation once• #define BOB_ATTR_VISIBLE 16 // BOB is visible• #define BOB_ATTR_BOUNCE 32 // BOB bounces off edges• #define BOB_ATTR_WRAPAROUND 64 // BOB wraps around edges• #define BOB_ATTR_LOADED 128 // the BOB has been loaded
7
Object Status and PropertyObject Status and Property
• 상태 (Status)– 예를 들어 , BOB 이 살았음 , 죽었음 , 또는 죽어감 중에서 어디에
해당하는지를 나타낸다 .
• 속성 (Property)– 생성된 후에 객체가 가질 수 있는 기능을 정의한다 .
8
BOB Types (1)BOB Types (1)
• 단일 프레임– BOB 는 하나의 프레임만을 갖는다 . BOB 는 바위와 같은 것들이다 .
• 다중 프레임– BOB 는 다중 프레임을 갖는다 . 그러나 선형적인 순서로
애니메이션 된다 .
9
BOB Types (2)BOB Types (2)
• 다중 애니메이션
Frame 1 Frame 2 Frame 3
Frame 4 ….
Animation 1
1, 3, 1, 3, 4
Animation 2
4, 1, 2, 4, 1, 2 …
Animation 3
1, 2, 3, 1, 2, 3
10
매크로 매크로 (1)(1)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// if (KEY_DOWN(‘A’)) {/* do it */ }
11
매크로 매크로 (2)(2)
// builds 16 bit value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
// builds 16 bit value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
// builds a 24bit color value in 8.8.8 format
#define _RGB24BIT(r,g,b) ((b) + ((g) << 8) + ((r) << 16) )
// builds 32bit value in A.8.8.8 format (8-bit alpha mode)
// this is the most common format of all new video cards
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
12
매크로 매크로 (3)(3)
#define SET_BIT(word,bit_flag) ((word)=((word) | (bit_flag)))
#define RESET_BIT(word,bit_flag) (word)=((word) & (~bit_flag)))
13
매크로 매크로 (4)(4)
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct));
ddstruct.dwSize=sizeof(ddstruct); }
DDSURFACEDESC2 ddsd; // any DirectDraw data structure
// call macro
DD_INIT_STRUCT(ddsd);
14
간단한 간단한 TypeType 과 과 Bitmap File TypeBitmap File Type
// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
// container structure for bitmaps .BMP file
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; // bitmapfile header
BITMAPINFOHEADER bitmapinfoheader; // all info defining bitmap
PALETTEENTRY palette[256]; // copy of palette is stored here
UCHAR *buffer; // pointer to data
} BITMAP_FILE, *BITMAP_FILE_PTR;
15
Bitmap Image TypeBitmap Image Type
• 배경과 애니메이션이 필요 없는 물체에 적합 • 시스템 메모리에 만들어지며 , DirectDraw 고 아무
관계도 없는 그래픽 객체 // the simple bitmap image
typedef struct BITMAP_IMAGE_TYP
{
int state; // state of bitmap
int attr; // attributes of bitmap
float x,y; // position of bitmap
int bpp; // bits per pixel
int width, height; // size of bitmap
int num_bytes; // total bytes of bitmap
UCHAR *buffer; // pixels of bitmap
} BITMAP_IMAGE, *BITMAP_IMAGE_PTR;
16
BOB Type (1)BOB Type (1)
typedef struct BOB_TYP
{
int state; // the state of the object (general)
int anim_state; // an animation state variable (up to you)
int attr; // attributes of BOB object (general)
float x,y; // position at which BOB is displayed
float xv,yv; // velocity of BOB
int bpp; // bits per pixel
int width, height; // size of the BOB
int width_fill; // used to force 8*x wide surfaces
int counter_1; // general counters
int counter_2;
int max_count_1; // general threshold values;
int max_count_2;
17
BOB Type (2)BOB Type (2)
int varsI[16]; // stack of 16 integers
float varsF[16]; // stack of 16 floats
int curr_frame; // current animation frame
int num_frames; // total number of animation frames
int curr_animation; // index of current animation
int anim_counter; // used to time animation transitions
int anim_index; // animation element index
int anim_count_max; // number of cycles before animation
int *animations[MAX_BOB_ANIMATIONS]; // animation sequences
LPDIRECTDRAWSURFACE7 images[MAX_BOB_FRAMES]; // the bitmap images DD surfaces
} BOB, *BOB_PTR;
18
전역변수들 전역변수들 (Global Variables) (1)(Global Variables) (1)
LPDIRECTDRAW7 lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // primary surface
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // back surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
PALETTEENTRY save_palette[256]; // copy of palette
DDSURFACEDESC2 ddsd; // a dd surface desc. struct
DDBLTFX ddbltfx; // used for filling
DDSCAPS2 ddscaps; // dd surface caps struct
HRESULT ddrval; // result from dd calls
UCHAR *primary_buffer = NULL; // primary video buffer
UCHAR *back_buffer = NULL; // secondary backbuffer
int primary_lpitch = 0; // memory line pitch
int back_lpitch = 0; // memory line pitch
19
전역변수들 전역변수들 (Global Variables) (2)(Global Variables) (2)
BITMAP_FILE bitmap16bit; // a 16-bit bitmap file
BITMAP_FILE bitmap8bit; // an 8-bit bitmap file
DWORD start_clock_count = 0; // used for timing
// these defined the general clipping rectangle
int min_clip_x = 0, // clipping rectangle
max_clip_x = SCREEN_WIDTH-1,
min_clip_y = 0,
max_clip_y = SCREEN_HEIGHT-1;
// these are overwritten globally by DD_Init()
int screen_width = SCREEN_WIDTH, // width of screen
screen_height = SCREEN_HEIGHT, // height of screen
screen_bpp = SCREEN_BPP; // bits per pixel
FILE *fp_error = NULL; // general error file
20
간단한 간단한 DirectDraw DirectDraw 인터페이스 인터페이스
• DirectDraw 초기화하기• DirectDraw 종료하기• 오프스크린 평면 표면 생성하기• 애니메이션을 위한 표면 페이지 전환• DirectDraw 표면에 색상 채우기• DirectDrawClipper 를 표면에 추가하기• 수직 깜빡임 주기 기다리기• 주표면과 보조표면 잠그기
21
DD_INIT(...) DD_INIT(...)
int DD_Init(int width, // width of fullscreen videomode
int height, // height of fullscreen videomode
int bpp); // bits per pixel of mode
전체 DirectDraw 시스템을 초기화한다 . DirectDraw 객체 lpdd 를 생성하고 , 협력 수준을 설정하고 , 비디오 모드를 설정하고 , lpddpal 로 접근할 수 있는 팔레트를 생성하고 , 그리고 lpddsprimary 와 lpddsback 이 가리키는 주표면과 보조표면을 생성한다 .
if (!DD_Init(800,600,8)) { /* error */ }
22
DD_Shutdown DD_Shutdown
int DD_Shutdown(void);
DD_Init(640,480,16); // start up DirectDraw in 16-bit mode
// .. do whatever
DD_Shutdown(); // shut down directdraw
23
DD_Create_Surface DD_Create_Surface
LPDIRECTDRAWSURFACE7 DD_Create_Surface(
int width, // width of surface
int height, // height of surface
int bpp, // bits per pixel
int mem_flags); // memory flags
• 오프스크린 평면 표면을 생성 • 메모리 플래그는 기본적으로 DDSCAPS_OFFSCREENPLAIN 으로 , VR
AM 에 표면을 생성한다 . DDSCAPS_SYSTEMMORY 와 같은 플래그를 추가하여 시스템 메모리에 생성하도록 요청할 수도 있다 .
LPDIRECTDRAWSURFACE7 lpddsplayer; // surface holding player
// create surface 64x64 with 8 bits per pixel
if (!(lpddsplayer = DD_Create_Surface(64,64,8,0)))
{ /* error */ }
24
DD_Flip DD_Flip
int DD_Flip(void);
// draw the next frame in lpdds_back....
// flip the surfaces
if (!DD_Flip()) { /* error - serious problem!!! */}
25
DD_Fill_SurfaceDD_Fill_Surface
int DD_Fill_Surface(
LPDIRECTDRAWSURFACE7 lpdds, // surface to fill
int color); // color to fill surface with
// Clearing surface example
if (!DD_Fill_Surface(lpddsplayer,0)) { /* error */ }
26
DD_Atach_Clipper DD_Atach_Clipper
LPDIRECTDRAWCLIPPER DD_Attach_Clipper(
LPDIRECTDRAWSURFACE7 lpdds, // surface to attach clipper to
int num_rects, // number of rectangles in clipping list
LPRECT clip_list); // a list of RECTs making up the clipping list
// define screen rectangle for 640x480 video mode
RECT screen_rect = {0,0,640,480};
// create and attach the clipper to the secondary back surface
if (!(lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect)))
{ /* error */ }
// all blitter operations to the secondary surface lpddsback will be clipped
27
DD_Wait_For_Vsync (1)DD_Wait_For_Vsync (1)
28
DD_Wait_For_Vsync (2)DD_Wait_For_Vsync (2)
• 수직 깜빡임이 시작할 때까지 기다린다 . • 컴퓨터 화면상의 이미지는 전자총에 의해서 선 단위
로 , 왼쪽에서 오른쪽으로 위에서 아래로 그려진다 . • 이미지가 그려진 후에는 전자총은 다시 좌측 상단
모서리로 가서 다시 그리기 시작한다 . • 이 과정을 수직 리트레이스 (vertical retrace) 라고
부른다 . • 전자총이 좌측 상단 모서리로 이동하는 시점이 ,
이미지가 그려지지 않기 때문에 , 화면을 갱신하기에 가장 좋은 시간이다 .
• DD_Wait_For_Vsync 는 이 과정을 할 수 있게 도와준다 .
29
DD_Wait_For_Vsync (3)DD_Wait_For_Vsync (3)
• 그래픽 루프의 끝부분에 DD_Flip() 를 호출하기 바로 전에 , 우선 DD_Wait_For_Vsync() 를 호출하여 수직 리트레이스가 시작할 때까지 기다린 다음 , DD_Flip()을 호출한다 . 이 방법은 비틀어지거나 깜빡임 없이 안정적인 화면을 줄 수 있다 . 다음은 예제이다 .
DD_Wait_For_Vsync(); // wait for vsync
DD_Flip(); // flip pages
30
Lock and Unlock SurfacesLock and Unlock Surfaces
UCHAR *DD_Lock_Primary_Surface(void);
int DD_Unlock_Primary_Surface(void);
UCHAR *DD_Lock_Back_Surface(void);
int DD_Unlock_Back_Surface(void);
UCHAR *DD_Lock_Surface(
LPDIRECTDRAWSURFACE7 lpdds, // surface to lock
int *lpitch); // pitch of locked surface
int DD_Unlock_Surface(LPDIRECTDRAWSURFACE
lpdds, // pointer to surface
UCHAR *surface_buffer); // pointer to surface memory
31
GDIGDI
• Get DC
HDC xdc;
// get the device context that is compatible with windows from DirectDraw
xdc = lpdds->GetDC(&xdc);
// use xdc here ....
lpdds->ReleaseDC(xdc); // release the device context back to Windows
32
GDI Text (1)GDI Text (1)
// Overloaded, 2 versions (because we use C++)
int Draw_Text_GDI(char *text, // text to draw
int x,int y, // position of text
COLORREF color, // RGB color of text
LPDIRECTDRAWSURFACE7 lpdds); // surface to draw on
int Draw_Text_GDI(char *text, // text to draw
int x,int y, // position of text
int color, // RGB color of text
LPDIRECTDRAWSURFACE7 lpdds); // surface to draw on
33
GDI Text (2)GDI Text (2)
if (!Draw_Text_GDI(“Hello Dumb World”,10,20,6,lpddsprimary))
{ /* error */ }
if (!Draw_Text_GDI(“Hello Dumb World”, 10, 20, RGB(0,255,0),lpddsprimary))
{ /* error */ }
34
Bitmap File Load/UnloadBitmap File Load/Unload
int Load_Bitmap_File(
BITMAP_FILE_PTR bitmap, // bitmap file obj to store data
char *filename); // filename of .BMP file to load
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap); // bitmap object to unload
35
Create_BitmapCreate_Bitmap
int Create_Bitmap*(
BITMAP_IMAGE_PTR image, // pointer to object to create
int x, int y, // initial position of bitmap object
int width, int height); // size of object
BITMAP_IMAGE monster; // the monster
if (!Create_Bitmap16(&monster, 100,100, 32,32)) // create the object
{ /* error */ }
36
Destroy BitmapDestroy Bitmap
int Destroy_Bitmap*(BITMAP_IMAGE_PTR image); // bitmap image to destroy
if (!Destroy_Bitmap(&monster)) { /* error, object wasn’t valid */ }
37
Load_Image_BitmapLoad_Image_Bitmap
int Load_Image_Bitmap*(
BITMAP_IMAGE_PTR image, // bitmap image object to load
BITMAP_FILE_PTR bitmap, // bitmap file to load data from
int cx,int cy,// cell or absolute coords to load image data from
int mode); // loading mode (cell or absolute)
// if equal to BITMAP_EXTRACT_MODE_CELL
// then cx,cy are cell coords
// if equal to BITMAP_EXTRACT_MODE_ABS
// then cx,cy are absolute coords
38
Load_Bitmap_Image Load_Bitmap_Image 의 원리의 원리
39
ExampleExample
BITMAP_IMAGE monster; // image of a monster
if (!Load_Bitmap_File(&bitmap8bit, “TREK.BMP”)) { /* error */ }
// create the object
if (!Create_Bitmap(&monster, 0,0, 32,32)) { /* error */ }
// load the image
if (!Load_Image_Bitmap(&monster, &bitmap8bit,0,0,BITMAP_EXTRACT_MODE_CELL ))
{ /* error */ }
// unload bitmap8bit now that you are done with it
Unload_Bitmap_File(&bitmap8bit);
// .. do whatever with the object
if (!Destroy_Bitmap(&monster)) { /* error */ }
40
Draw_BitmapDraw_Bitmap
int Draw_Bitmap*(BITMAP_IMAGE_PTR source_bitmap, // pointer to bitmap object
UCHAR *dest_buffer, // destination buffer to draw to
int lpitch, // horizontal memory pitch
int trans); // if 1 then draw with color 0 transparent; else draw opaque
monster.x = x; // set position
monster.y = y;
Draw_Bitmap(&monster,back_buffer, back_lpitch,1); // draw bitmap
41
정리정리 : BMP File : BMP File Surface Surface
BMP
File
BITMAP_FILE
Structure
Load_Bitmap_File
function BITMAP_IMAGE
Structure
Load_Image_Bitmap
function
SurfaceDraw_Bitmap
function
Create_Bitmap
function
42
차세대 차세대 BOB(Bitmapped Object Bitmap)BOB(Bitmapped Object Bitmap)
• 다중 프레임 애니메이션을 지원
43
Create_BOB Create_BOB
int Create_BOB*(BOB_PTR bob, // pointer to BOB to create
float x, float y, // initial position of BOB
int width, int height, // size of BOB
int num_frames, // total number of frames for BOB
int attr, // attributes of BOB
int mem_flags); // surface memory flags, 0 is VRAM
44
Create_BOB AttributeCreate_BOB Attribute
Value Meaning
BOB_ATTR_SINGLE_FRAME Create BOB with a single frame.
BOB_ATTR_MULTI_FRAME Create BOB with multiple frames, but the animation of the BOB will be a linear sequence through the frames 0 . . .n.
BOB_ATTR_MULTI_ANIM Create a multiple-frame BOB that supports animation sequences.
BOB_ATTR_ANIM_ONE_SHOT Set an animation sequence to play only once and then stop. At this point, the internal variable anim_state is set. To play the animation again, reset this variable.
BOB_ATTR_BOUNCE Make the BOB bounce off the screen boundaries like a ball. This value only works if you use Move_BOB*().
BOB_ATTR_WRAPAROUND Make the BOB wrap around to the other side of the screen as it moves. This value only works if you use Move_BOB*().
45
Create_BOB ExamplesCreate_BOB Examples
BOB car; // a car BOB
// create the BOB
if (!Create_BOB(&car, 50,100,96,64,1,BOB_ATTR_SINGLE_FRAME,0))
{ /* error */ }
BOB ship; // a spaceship BOB
// create the BOB
if (!Create_BOB16(&ship, 0,0,32,32,8,BOB_ATTR_MULTI_FRAME,0))
{ /* error */ }
BOB greeny; // a little green man BOB
// create the BOB
if (!Create_BOB(&greeny, 0,0,32,32,32,BOB_ATTR_MULTI_ANIM,0))
{ /* error */ }
46
Destroy BOBDestroy BOB
int Destroy_BOB*(BOB_PTR bob);
47
Draw_BOBDraw_BOB
int Draw_BOB*(BOB_PTR bob, // pointer of BOB to draw
LPDIRECTDRAWSURFACE7 dest); // dest surface to draw on
BOB ship; // a spaceship BOB
// create the 8-bit bob
if (!Create_BOB(&ship, 0,0,32,32,8,BOB_ATTR_MULTI_FRAME,0))
// load the BOB images in (see Load_Frame_BOB())
ship.x = 50; // set the position and frame of BOB
ship.y = 50;
ship.curr_frame = 0; // this contains the frame to draw
Draw_BOB(&ship, lpddsback); // draw BOB
48
Draw_Scaled_BOBDraw_Scaled_BOB
int Draw_Scaled_BOB*(BOB_PTR bob, // pointer of BOB to draw
int swidth, int sheight, // new width and height of BOB
LPDIRECTDRAWSURFACE7 dest); // dest surface to draw on
Draw_Scaled_BOB(&ship, 128,128,lpddsback);
49
Load_Frame_BOBLoad_Frame_BOB
int Load_Frame_BOB*(
BOB_PTR bob, // pointer of BOB to load frame into
BITMAP_FILE_PTR bitmap, // pointer of file to scan data
int frame, // frame number to place image into (0,1,...)
int cx,int cy, // cell position or absolute position to scan from
int mode); // scan mode, same as Load_Frame_Bitmap()
BOB ship; // the BOB; call create_bob after of course..
// ..loads frames 0,1,2,3 from cell position (0,0), (1,0),
// (2,0), (3,0)
// from bitmap8bit bitmap file; assume it has been loaded
for (int index=0; index<4; index++)
Load_Frame_BOB16(&ship,&bitmap16bit, index, index,0,
BITMAP_EXTRACT_MODE_CELL );
50
Load_Animation_BOB (1) Load_Animation_BOB (1)
int Load_Animation_BOB*(
BOB_PTR bob, // BOB to load animation into
int anim_index, // which animation to load (0 to 15)
int num_frames, // number of frames of animation
int *sequence); // pointer to array holding sequence
// Example
int anim_walk[] = {0,1,2,1,0};
int anim_fire[] = {5,6,0};
int anim_die[] = {3,4};
int anim_sleep[] = {0,0,7,0,0};
51
Load_Animation_BOB (2)Load_Animation_BOB (2)
// create a multi-animation BOB
if (!Create_BOB(&alien, 0,0,32,32,8,BOB_ATTR_MULTI_ANIM,0))
{ /* error */ }
// load in the BOB frames here...
// load walk into animation 0
Load_Animation_BOB(&alien, 0,5,anim_walk);
// load fire into animation 1
Load_Animation_BOB(&alien, 1,3,anim_fire);
// load die into animation 2
Load_Animation_BOB(&alien, 2,2,anim_die);
// load sleep into animation 3
Load_Animation_BOB(&alien, 3,5,anim_sleep);
52
SetSet
int Set_Pos_BOB*(BOB_PTR bob, // pointer to BOB to set position
int x, int y); // new position of BOB
int Set_Vel_BOB*(BOB_PTR BOB, // pointer to BOB to set velocity
int xv, int yv); // new x,y velocity
int Set_Anim_Speed_BOB*(BOB_PTR bob, // pointer to BOB
int speed); // speed of animation
int Set_Animation_BOB(
BOB_PTR bob, // pointer of BOB to set animation
int anim_index); // index of animation to set
53
Animation, etc…Animation, etc…
int Animate_BOB*(BOB_PTR bob); // pointer to BOB to animate
int Move_BOB*(BOB_PTR bob);
int Hide_BOB*(BOB_PTR bob); // pointer to BOB to hide
int Show_BOB(BOB_PTR bob); // pointer to BOB to show
// GDI Call Example (occlusion 을 방지 )
Hide_BOB(&alien); // hide 8-bit BOB
// make calls to Draw_BOB and GDI etc.
Show_BOB(&alien);
54
Collision_BOBS Collision_BOBS
int Collision_BOBS*(BOB_PTR bob1, // pointer to first BOB
BOB_PTR bob2); // pointer to second BOB
if (Collision_BOBS16(&missile, &player)) { /* make explosion sound */ }
See Code!
55
TimingTiming
• 루프의 처음에 시간을 기록하고 , 그리고 루프의 끝에서 현재 시간을 살펴보고 33 밀리세컨드가 지날 때까지 기다리는 것이다 .
• 만약 33 밀리세컨드가 이미 지났다면 , 루프를 벗어나고 그렇지 않으면 계속 기다린다 .
while(1)
{
// start the clock here; the current clock count is recorded
Start_Clock();
// do whatever..game logic etc.
Wait_Clock(100); // force it to wait 100
}// end while
56
Get_ClockGet_Clock
DWORD count = Get_Clock();
57
STARFERR.CPP STARFERR.CPP
58
기본적인 그래픽스 기본적인 그래픽스
• 선이나 사각형 , 혹은 점
59
Draw_PixelDraw_Pixel
int Draw_Pixel*(int x, int y, // position of pixel
int color, // color of pixel
UCHAR *video_buffer, // pointer to memory buffer
int lpitch); // horizontal memory pitch
DD_Lock_Primary_Surface(); // lock primary surface
Draw_Pixel(100,100,20, primary_buffer, primary_lpitch); // draw the pixel
DD_Unlock_Primary_Surface(); // unlock the primary surface
60
Drawing Lines - 1Drawing Lines - 1
• Rasterization 의 개념
61
Drawing Lines - 2Drawing Lines - 2
• Simple Approach: for drawing line (x0,y0) ~ (x1,y1)– Compute the slope m = dy / dx = (y1 – y0) / (x1 – x0) – The line equation is: y = mx + b
• Where y0 = m x0 + b, thus b = (y0 - m x0)
– Plot (x0, y0)– Plot (x0 + 1, m(x0 + 1) + b)– Plot (x0 + 2, m(x0 + 2) + b) – … – Until x = x1 – 띄엄띄엄 그려지게 된다 . (m > 1 인 경우 ) – 매 step 마다 floating point 곱셈이 사용됨
62
Drawing Lines - 3Drawing Lines - 3
• Bresenham’s Algorithm: p0: (x0,y0) ~ p1: (x1,y1)
– X-dominate line (m < 1) 인 경우만 가정
– x1 > x0, y1 > y0 인 경우만 가정– Line equation 이 y = mx + b 라고 가정
• (x_k, y_k) 일 때 다음 point 는 (x_k + 1, y_k) 일까 아니면 (x_k +1, y_k +1) 일까 ?
실제 line 의 y 값과의 차이를 계산해 본다 .
실제 y 값 y = m(x_k + 1) + b
d1 = y – y_k = m(x_k + 1) + b – y_k
d2 = (y_k + 1) – y = y_k + 1 – m(x_k + 1) – b
d1 – d2 = 2m(x_k + 1) – 2y_k + 2b – 1
만일 d1 – d2 > 0 이라면 d1 이 더 큰 것이므로 (x_k + 1, y_k + 1) 을 선택해야 할 것이다 .
만일 d1 – d2 < 0 이라면 d2 가 더 큰 것이므로 (x_k + 1, y_k) 를 선택해야 할 것이다 .
x_k x_k +1
y_k
y_k + 1 d_2
d_1
63
Drawing Lines - 4Drawing Lines - 4
• d1 – d2 = 2m(x_k + 1) – 2y_k + 2b - 1
• p_k = dx (d1 – d2) 로 하고 , m = dy/dx 로 나타내면 ,
• p_k = 2dy x_k – 2dx y_k + c, c = 2dy + dx(2b – 1)
• p_0 = 2dy x_0 – 2dx y_0 + 2dy + dx(2b – 1)
• y_0 = m x_0 + b, b = y_0 – m x_0 이므로 • p_0 = 2dy – dx
• 게다가 ,
• p_(k+1) = p_k + 2 dy – 2 dx (y_(k+1) – y_k) 이므로 • y_(k+1) = y_k 이면 p_(k+1) = p_k + 2 dy 이고 • y_(k+1) = y_k + 1 이면 p_(k+1) = p_k + 2 dy – 2 dx 이다 .
• DrawLine procedure: p_k 를 error 라는 variable 로 표시
64
Drawing Lines - 5Drawing Lines - 5
• Bresenham’s Algorithm: (x0,y0) ~ (x1,y1)– X-dominate line (m < 1) 인 경우만 가정– x1 > x0, y1 > y0 인 경우만 가정
x = x0; y = y0; dx = x1 – x0; dy = y1 – y0; dx2 = dx << 1; dy2 = dy << 1; error = dy2 – dx;
for (int index = 0; index <= dx; index++) { Plot_Pixel(x, y, color); if (error >= 0) { error -=dx2; y++; } error += dy2; x++; }
(1, 1) ~ (4, 3) 의 예 dx = 4 – 1 = 3 dy = 3 – 1 = 2dx2 = 3 * 2 = 6 dy2 = 2 * 2 = 4
index x y error
0 1 1 e = dy2 – dx = 4 – 3 = 1
e = 1 – dx2 = 1 – 6 = -5
y = y + 1 = 2
e = -5 + dy2 = -5 + 4 = -1
1 2 2 e = -1 + dy2 = -1 + 4 = 3
2 3 2 e = 3 – dx2 = 3 – 6 = 3
y = y + 1 = 3
e = 3 – dy2 = 3 – 6 = -3
3 4 3 …
65
Draw_Line Draw_Line
int Draw_Line*(int x0, int y0, // starting point
int x1,int y1, // ending point
int color, // color of line
UCHAR *vb_start, // destination memory
int lpitch); // memory pitch of dest memory
See the Code!
66
Draw_Clip_Line*() Draw_Clip_Line*()
min_clip_x, min_clip_y, max_clip_x, max_clip_y 에 의해 정의된 클리핑 사각형으로 선을 클리핑
67
Clipping the LineClipping the Line
• Simple Calculation
68
Cohen-Sutherland Clipping Cohen-Sutherland Clipping AlgorithmAlgorithm
• (x1, y1), (x2, y2) 이 각각 어느 영역에 속하는지를 알아낸다 p1code, p2code 라 함
• 각 경우마다 clipping point 를 계산
69
Draw_Clip_Line*() Draw_Clip_Line*()
int Draw_Clip_Line*(int x0,int y0, // starting point
int x1, int y1, // ending point
int color, // color of line
UCHAR *dest_buffer, // destination memory
int lpitch); // memory pitch of destination memory
See the Code!