| ||
| ||
안녕하세요~ 이준곤(LeeChen) 입니다. 요즘에 게임을 제작하는데 있어 도스용과 윈도우즈용이라는 분야로 나누어져 있더군요. 요즘 국산 게임은 워낙 뛰어난 것들이 많아서 게임 시장에 나가서 어떤 게임을 사야 할지 모르겠더군요~ 게임은 만드는 재미도 있지만 실제로 제작되어 있는 게임을 즐길줄 아는 게임 메이커들이 되었으면 합니다. 사실 94년도에 썼던 스크립터에 관한 글을 계속 이어나가야 하는데 제가 시간이 없다보니(핑계인가?) 대신 다이렉트에 관한 글로 대신 하려고 합니다. 얼마전에 DirectX 5.0이 나왔죠? 3D기능이 엄청나게 좋아 졌더군요 기능향상이 이젠 3차원 게임을 게임 메이커라면 누구나 할수 있는 수준이니까요~ 일단 다이렉트 엑스라는 개발툴을 사용하려면 비쥬얼 2.0이상이 있어야 합니다. (당연 32비트 개발툴을 뜻하는 것이겠죠~) 또는 볼랜드의 빌더라는 것을 쓰시면 됩니다. 일단 다이렉트(이하 편의상 다이렉트라고만 표시하겠음)를 설치하 고 나면 샘플이라는 디렉토리로 가서 갔가지 데모를 보십시요? 아니 이럴수가? 또는 이게뭐야? 이것 밖에 안되? 하는 등등의 여 러가지 표현을 하실텐데... 우선 Foxbear라는 프로그램에는 2D에서 표현되는 모든 기법들이 들어 있다고 할수 있더군요~ (많은 예제를 참고 하심이 좋을 듯...) 먼저 참고 서적을 보시려면... 1. 자체 온라인 메뉴얼 (당연 영문이죠~ 번역 가능한자만...^^;) 2. Windows 95 Game 개발자 가이드 - 도서출판 에프원 3. 윈도우 95용 Game SDK 전략 가이드 - 정보문화사 4. 윈도우 API 바이블 I, II - 생각안남 5. 윈도우 함수 레퍼런스 상,중,하 (2만8천원 짜리 3권인가? - 역시 기억안남) 6. Inside Visual C++ 7. MFC 관련 책자 8. 기타 윈도우즈 관련 책자및 참고 할만한 책들 우와~ 많죠? 전 위에서 모든 책을 읽어 보진 못했지만...^^; 참고는 항시 하고 있습니다. 책을 파는 사람이 아니므로 도서관이나 서점에서 잠시 보시거나 참고 하기 위해 복사나 참조 하세요~ 굳이 사실 분은 사시구요~ (프로그래머라면 책에 쓰는 돈은 아까워 하면 안되겠죠~) 본론으로 들어가죠~ 괜히 책에 관한 이야기만 많이 늘어 놓은듯..--; 1. 비트맵을 출력하는 모식도 ┌──────────────────┐ │ 윈도우 생성, 초기화 한다. │ └─────────┬────────┘ ┌─────────┴────────┐ │ DirectDraw의 인터페이스 │ └─────────┬────────┘ ┌─────────┴────────┐ │ Off Screen으로 비트맵 복사 │ └────┬─────────┬───┘ ┌────┴───┐ ┌───┴───┐ │ 스프라이트 Blt │ │ 배경 Blt │ < - 후면 버퍼로 └────┬───┘ └───┬───┘ 보내는 과정 ┌────┴─────────┴───┐ │ 실제 보이는 화면으로 Fliping │ └──────────────────┘ 그림 1 : 다이렉트 액스 출력 과정 모식도 위에서 보면 인터페이스 하는 부분외에는 도스에서 게임을 제작하는 과정과 흡사하다고 볼수 있죠~ 사실 인터페이스 부분은 자신의 라이브러리를 사용하는 부분이라고 생각해도 될겁니다. 2. DirectDraw의 데이터 스트럭쳐 다이렉트를 사용하기 위해선 큰지막한 구조체들을 알아야 한다. 이번에는 그 구조를 알기 위해 분석을 해보자. 자세하게는 하지 않고 대강 이렇다고 정의만 하겠다. ────────────────────────── DDCAPS ────────────────────────── 비디오 카드의 상태를 확인및 체크한다. 예) 메모리의 양, 하드웨어의 능력(3D) ────────────────────────── DDRVAL ────────────────────────── DirectDraw 함수들이 반환하는 값을 뜻한다. ────────────────────────── DDSCAPS ────────────────────────── DDCAPS와 거의 비슷한데 DDCAPS는 하드웨어의 기능을 체크하는 것이라면 이것은 소프트웨어의 기능을 체크한다. 즉, DirectDrawSurface의 능력을 체크한다. ────────────────────────── DDSURFACEDESC ────────────────────────── 생성한 각각의 표면(또는 버퍼)에 대한 Off Screen을 뜻한다. 잉? 이것이 전부인가? 일단 Draw에 관한 것을 다루도록하 기로 하고 이것이 여기서 마치고... 3. DirectDraw의 생성 그럼 실제로 DirectDraw를 어떻게 인터페이스 하고 초기화 하는지 알아 봅시다. ────────────────────────── HRESULT DirectDrawCreate(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter) ────────────────────────── 윈도우즈 관련 함수를 보면 Create관련 함수를 많이볼수 있습니다. 다이렉트도 비슷한 방식을 쓰는데 데부분 초기화 또는 생성등을 할때 쓰이는 함수들이 Create라는 부분이 명시되어 있습니다. 그럼 위의 함수의 인자들은 무엇을 뜻할까요? lpGUID는 디스플레이 디바이스를 뜻합니다. 이것이 무슨 뜻 이냐구요? 화면에 나타나기 위한 장치를 뜻한다는 이야기죠 보통 이값이 NULL이면 GDI에 공유된 디스플레이를 뜻합니다 lpDD는 DirectDraw 인터페이스를 위한 포인터를 가리키고, 마지막 인자는 향후 사용되기 위해 예약해둔 것이라고 합니 다. 보통 NULL이라고 하면 됩니다. LPDIRECTDRAW lpDD; HRESULT ddrval; ddrval = DirectDrawCreate(NULL, &lpDD, NULL); if(ddrval != DD_OK) { return FALSE; } 아주 간단하죠? OLE COM에서 반환되는 형은 HRESULT를 사용 합니다. 오류가 발생하면 신속한 처리를 위해서 HRESULT를 사용합니다. 위의 예제는 생성하고자 하는 DirectDraw 객체를 선언하는 간단한 예제 입니다. /////////////////////////////////////////////////////////////// 일단 오늘은 여기까지 입니다. 곧 (조만간) 두번째 글을 올리 도록 하겠습니다. 많은 분들께 참고가 되었으면 하는 바램으로 적어보았습니다. 성남에서 외로움을 달래며.... 이준곤(LeeChen) 드림. #1384 서성칠 (ssc7 ) [강좌] < LeeChen> 윈도우 게임제작 [2] 09/02 22:37 183 line 안녕하세요~ 이준곤(LeeChen) 입니다. 지난번에 어디까지 했더라....^^; 이곳에 가끔씩 들려 보지만 요즘 공모전때문에 그런지 무척이나 활기 있어 보입니다. 오늘은 윈도우즈로 게임을 제작해 보는 두번째 시간 즐겁게 제 작해 봅시다. 보통 도스용 게임을 제작할때는 하드웨어적인 것을 개발해야 하 거나 (속도 문제로...) 상업적인 라이브러리를 사서 제작하는 경우가 다수였을 겁니다. 그리고, 멀티 테스킹을 하기 위한 자구책을 내놓기도 하였죠~ 당연 이것을 얍삽한 프로그램방식이라고들 일부에서는 표현하면 서 사용을 했죠~ 윈도우즈는 어떨까요? 사실 멀티테스킹, 네트워크상의 플레이, 사운드의 다양한 제어, 거기다 3차원 방법까지 쉽게 신경쓰지 않고 표현할수 있는 시대인것 같습니다. 잉? 자꾸 삼천포로 빠지는 군요~ 1. 프로세서를 독점하기 일단 게임을 위해서는 프로세서를 독점할 필요성이 있겠다 고 생각하시죠? 당연 다이렉트로 이것을 사용자가 만들기 바라지 않고 자체 에서 지원합니다. 바로 SetCooperativeLevel()이라는 대표적인 함수가 있습니다. ───────────────────────────── HRESULT SetCooperativeLevel(LPDIRECTDRAW lpDD, HWND hWnd, DWORD dwFlags) ───────────────────────────── lpDD는 앞에서 생성된 DirectDraw 객체에 대한 포인터를 뜻합니다. 두번째것은 당연 윈도우즈 핸들러겠죠? 보통 이헨들러는 작업전환(ALT+TAB)에 관한 메세지를 보낼 때 사용되어 집니다. 마지막 dwFlags에 관한건 다음의 내용을 보시면 설명보다 쉽게 이해가... -------------------------------------------------------------- DDSCL_ALLOWMODEX ModeX를 지원한다. DirectDraw는 저해상도인 320x200, 3200x400의 X모드를 지원합니다. DDSCL_ALLOWREBOOT 전체 화면을 사용할때 Ctrl+Alt+Del을 가능하 합니다. DDSCL_EXCLUSIVE 해상도를 바꾸거나 플리핑 작업을 위해서 exclusive level 상태로 한다. DDSCL_FULLSCREEN GDI를 사용하지 않는 전체화면 모드를 사용 가능하게 한다. DDSCL_NORMAL 일반적인 윈도우즈 창에서 프로그램을 가능 하게 합니다. DDSCL_NOWINDOWCHANGES 활성화 상태에 있는 프로그램을 minimize 할수 없게 합니다. -------------------------------------------------------------- 와우 무슨 옵션이 이렇게 많은가? 보통 프로그램에서는 위의 코드를 조합해서 사용합니다. 여기서 조합이란것은 OR, AND를 한다는 뜻입니다. 간단한 예를 보죠~ ddrval=lpDD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); 아주 간단해 보이시죠? 2. 비디오 모드 설정 앞서 배운 것은 단지 프로세서(CPU)자원의 독점하는 것을 배워 보았습니다. 이번에는 비디오 모드를 설정하는 방법을 알아 봅시다. 물론 관련책자를 보시면 자세히 알수 있지만, 그래도... 혹시나... 책이 없이 이글로 배움을 시작하는 분을 위해 다이렉트는 320x200, 320x400 640x480의 해상도를 지원합 니다. 256칼라를 기본으로 하지만 투루칼라까지 지원이 됩니다. 보통 640x480x256에서 가장 효율적인 기능을 제공한다고 메뉴얼에 나와 있더군요! ───────────────────────────── HRESULT SetDisplayMode(LPDIRECTDRAW lpDD, DWORD dwWidth, DWORD dwHeight, DWORD dwBpp) ───────────────────────────── 역시 첫번째 인자는 DirectDraw를 뜻하는 것이겠죠~ dwWidth와 dwHeight는 가로 세로 해상도를 뜻하는 것이구요 마지막 dwBpp는 컬러수를 뜻합니다. 그럼 예제를 보죠~ ddrval=lpDD->SetDisplayMode(640, 480, 8); 위의 예제는 바로 640*480*256을 뜻합니다. 아주 쉽죠~ ^^; 자~ 여기까지 정리해 보죠~ 첫번째 두번째 글을 읽어 보셔도 아직 이해가 되지 않죠~ 당연히 아직은 그리 중요하지는 않은 내용인듯합니다. (당연한 내용이므로...^^;) //우선 사용될 다이렉트 변수들을 선언해야 겠죠~ LPDIRECTDRAW lpDD; LPDIRECTDRAWSURFACE lpDDSPrimary; LPDIRECTDRAWSURFACE lpDDSBack; DDSCAPS ddscaps; DDSURFACEDESC ddsd; HRESULT hr; //그다음에 다이렉트 드로우에 관한 생성자를 생성했죠~ hr = DirectDrawCreate(NULL, &lpDD, NULL); if(hr != DD_OK) { // 에러 관련 처리를 해야 겠죠? // 보통 에러라고 표시를 하고 빠져 나갑니다. } // 자~ 그럼 이번에는 프로세서를 독점해야 겠죠~ hr = lpDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX); if(hr != DD_OK) { // 동일한 에러 처리를 하면 되겠죠~ } // 여기서 해상도를 설정해야 겠죠! hr = lpDD->SetDisplayMode(640, 480, 8); if( hr != DD_OK) { // 당연 에러 처리겠죠~ } // 여기까지.... /////////////////////////////////////////////////////////////// 일단 오늘은 여기까지 입니다. 쉽죠? 아닌가?......(끄적끄적) 세번째 글을 써야 겠는데.....잉? ...눈에....핏기가.... 다음에는 버퍼의 생성관해서 장편의 글을 써보도록 해보겠습니다. 그리고 페이지 플리핑에 관해서다루어 보구요~ 다음과 같이 연재해 나가도록 하겠습니다. *1. 다이렉트 전반에 관해서... *2. 다이렉트 생성과 프로세서 독점, 모드 셋팅 3. 다이렉트 버퍼 생성 전반에 관해 4. 면의 생성과 플리핑, 비트맵 복사 5. 다이렉트 팔레트 관리 6. Lock과 Unlock, Blt, BltFast 7. 다이렉트 사운드 처리 8. 조이스틱 9. 간단한 2D 게임을 제작 일단 여기까지가 1편..... 2편은 가능할지 모르지만.... 10. 다이렉트 3D전반에 관해서... 11. 오버레이 표면과 Z버퍼, 이미지 회전, 알파 혼합기능 12. 다이렉트를 이용해 3D 텍스쳐 입히기 13. 다이렉트를 이용한 실시간 랜더링 14. 다이렉트 엑스에 OpenGL을 이용하자. 15. 3DS 분석과 오브젝 읽어 표현하기 15. 퀘이크를 흉내내자. 16. 버?괵と?이터를 만들자. 17. 기타 등등. 2편은 아직 제가 앞으로 시간이 어찌 될지? 싶어 장담은 할수 없어서 .... --; 그러나 1편은 확실히 연재해 나가 겠습니다. 현재 작업을 진행중이라서 글을 빨리 올리지 못하는 것에 대해 죄송하게 생각합니다. 3차원에 들어가면 내용이 1편에 배로 증가하겠군요... 음...타이핑 칠 시간이 있으려나? ^^; 많은 분들께 참고가 되었으면 하는 바램으로 적어보았습니다. 성남에서 외로움을 달래며.... 이준곤(LeeChen) 드림. #1385 서성칠 (ssc7 ) [강좌] < LeeChen> 윈도우 게임제작 [3] 09/08 08:14 254 line 안녕하세요~ 이준곤(LeeChen) 입니다. ------------------------------------------------------------ [LeeChen과 함께 - 윈도우즈편 목차] *1. 다이렉트 전반에 관해서... *2. 다이렉트 생성과 프로세서 독점, 모드 셋팅 *3. 다이렉트 버퍼 생성 전반에 관해 4. 면의 생성과 플리핑, 비트맵 복사 5. 다이렉트 팔레트 관리 6. Lock과 Unlock, Blt, BltFast 7. 다이렉트 사운드 처리 8. 조이스틱 9. 간단한 2D 게임을 제작 ------------------------------------------------------------ 지난번까지 모드 셋팅에 관한것 까지 배웠습니다. 자세한글을 올리지 못하는 것에 대해서 진심으로 죄송하게 생각합니다. 워낙 초보다보니....^^; 이번에는 다이렉트 버퍼 생성과 비트맵에 관해서 알아 봅시다. 그전에 지난번에 했던 것에 대하여 잠시 살펴 보고 갑시다. // 1차 표면(Primary Surface)만 생성하기 LPDIRECTDRAWSURFACE lpPrimary; DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; lpDD->CreateSurface(&ddsd, &lpPrimary, NULL); 잉? 지난번거와는 다른데....--; 다른것 어보이예요~ 단지 함수 하나가 있죠? 메모리를 클리어 해주는 함수밖에... LPDIRECTDRAWSURFACE는 IDirectDrawSurface의 포인터 형입니다. 쩝~ DDSURFACEDESC는 생성될 표면의 특성을 알려주는 구초체입 니다. 음... 뭐~다른것은 어뵤이죠~ 지난번에 빼먹은 것이 있죠~ 뭘까요? 뭘까? 뭘까.....(끄적~끄적~) 지끔까지 생성시킨 것을 종료시켜야 겠죠~ 제거하는 방법은... lpPrimary->Release(); lpDD->Release(); 요거...바로 요거랍니다. 음...간단하죠~ 언제인가? 질문란을 통해 한글이나 문자를 어떻게 찍냐고 하시더 군요~ 보통 윈도우즈 API를 배우지 않고 그냥 윈도우즈 프로그램 을 하시겠다고 한다면 당연 이런쪽의 방법을 알수가 없을 겁니다. 다음 예제를 먼저 보죠~ < 예제 : 다이렉트에서 글자찍기 > HDC hdc; if(lpDDSPrimary->GetDC(&hdc) == DD_OK) { Rectangle(hdc, ....); SetTextColor(hdc, ....); SetBkCOlor(hdc, ....); TextOut(hdc, ....); lpPrimary->ReleaseDC(hdc); } GDI를 사용하는 것이데, 이것이 무언지는 윈도우 강좌란을 참고 해서 이해를 하셨으면 합니다. 다이렉트 드로우 표면은 DC를 얻 어 GDI 함수를 사용하게 해주므로 프라머리에서 간단히 GDI함수 를 사용할수 있는 것이죠~ 위 예제 함수에 대해서는 윈도우즈 API바이블을 참조 해주세요~ < 소스: 위의 예제 전체 소스> #include < windows.h> #include < ddraw.h> BOOL initDirectDraw(HWND hWnd); void closeDirectDraw(); void Draw(); LPDIRECTDRAW lpDD = NULL; LPDIRECTDRAWSURFACE lpPrimary = NULL; . . // 윈도우 프로시져와 메인 함수는 생략 --; // 공통부분이므로... . . BOOL initDirectDraw(HWND hWnd) { HRESULT hr; // 생성과 모드 설정 hr = DirectDrawCreate(NULL, &lpDD, NULL); if(hr != DD_OK) return FALSE; hr = lpDD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if(hr != DD_OK) return FALSE; hr = lpDD->SetDisplayMode(640, 480, 8); //640*480*256 Mode if(hr != DD_OK) return FALSE; // 1차 표면 생성 DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; lpDD->CreateSurface(&ddsd, &lpPrimary, NULL); return TRUE; } // DirectDraw Primary 를 소멸시킴. void closeDirectDraw() { if(lpPrimary != NULL) lpPrimary->Release(); if(lpDD != NULL) lpDD->Release(); } void Draw() { LPSTR str = "Hello!, 나에 이름은 준곤이야~"; HRESULT hr; HDC hDC; hr = lpDDSPrimary->GetDC(&hDC); if(hr == DD_OK) { TextOut(hDC, 300, 200, str, strlen(str)); lpPrimary->ReleaseDC(hDC); } } 3. 비트맵 게임을 만든다면 PCX를 많이 사용했을 겁니다. 제작과 사용하기 편하다는 이유만으로....음... 그런데 윈도우즈에서는 비트맵이 존재 한다는 것은 이미 페이트 브러쉬를 통해 알고 계시죠? 윈도우즈는 비트맵 기본으로 사용하고 있습니다. 그럼...도대체 어떤 구조를 하고 있기에 비트맵을 사용할까요~ < DIB 구조 > +-------------------+ | BITMAPFILEHEADER | +-------------------+ | BITMAPINFOHEADER | --+--> BITMAPINFO +-------------------+ | | RGBQUAD | --+ +-------------------+ | Image Data | +-------------------+ 윈도우즈는 의존적 비트맵(DDB)과 장치 독립적 비트맵 (DIB) 두가지를 제공합니다. 의존적 비트맵은 일반적으로 사용하는 비트맵을 의미합니다. // BITMAPFILEHEADER typedef struct tagBITMAPFILEHEADER { WORD bfType; // ASCII 값 "BM" DWORD bfSize; // 파일 사이즈 WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; // 파일 처음부터 bitmap까지 바이트 수 } BITMAPFILEHEADER; BITMAPFILEHEADER는 위와 같이 선언 되어 있습니다. 잉? 이것이 전부 필요 한것은 아니여요~ 여기서 필요한 것은 bfType와 bfSize인데..bfType는 이 파일이 비트맵인지를 나타냅니다. 비트맵은 16진수로 4d42이고 WORD로 "BM"을 나타냅니다. 그리구 bfSize는 파일 사이즈 인데..비트맵 파일에서 BITMAPINFOHEADER부터의 포인터를 계산하는데 사용합니다. BITMAPFILEHEADER bmfh; dwDibSize = bmfh.bfSize - sizeof(BITMAPFILEHEADER); // BITMAPINFO typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; 보다시피 BITMAPINFOHEADER와 RGBQUAD로 구성 되어 있습니다. // BITMAPINFOHEADER typedef struct tagBITMAPINFOHEADER{ // bmih DWORD biSize; LONG biWidth; // X 크기 LONG biHeight; // Y 크기 WORD biPlanes; // Plane수 인데 항상 1 WORD biBitCount; DWORD biCompression; // 압축 형태. DWORD biSizeImage; // 바이트 단위로 비트맵의 크기. LONG biXPelsPerMeter; // 미터당 수평 픽셀 수 LONG biYPelsPerMeter; // 미터당 수직 픽셀 수 DWORD biClrUsed; DWORD biClrImportant; // 중요한 컬러수 } BITMAPINFOHEADER; biSize는 BITMAPINFOHEADER구조의 크기 biBitCount는 픽셀당 비트 수 biClrUsed는 사용된 칼러 수를 뜻하며 값이 0이면 비트맵은 biBitCount에 대하는 최대의 컬러수를 사용합니다. // RGBQUAD typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; DIB의 칼런는 이 구조로 표현 되는데.. 16칼러 비트맵은 16 RGBQUAD구조,256칼러는 256 RGBQUAD구조, 예외적으로 24비트 칼러는 칼러 테이블이 없답니다. 현재 DIB가 가지고 있는 칼러수를 계산하려면.... BITMAPINFO lpBi; ... ... if(lpBi->bmiHeader.biClrUsed != 0) nColor = lpBi->bmiHeader.biClrUsed; else switch(lpBi->bmiHeader.biBitCount) { case 1: nColor = 2; break; case 4: nColor = 16; break; case 8: nColor = 256; break; case 24: nColor = 0; break; } 간단하죠..음..여기서 칼러 수를 계산하는 이유는 나중에 설명할 Palette생성에 필요하기 때문입니다. (참고로 저장되는 방식은 bottom-up방식으로 저장 됩니다.) // 이미지 데이터를 얻는 방법 lpBi + lpBi->bmiHeader.biSize + (nColor * sizeof(RGBQUAD)); 으악~....출근 시간이....팔레트 부분은 생략...다음 기회에.. 하도록 하죠...무려 한시간동안...궁리 끝에 끄적이는데... 다음에 강좌에 있기전에...다이렉트 엑스의 예제중에 SDK\SAMPLES\MISC\의 DDUTIL.CPP를 한번씩 분석해주세요~ 많은 분들께 참고가 되었으면 하는 바램으로 적어보았습니다. 성남에서 외로움을 달래며.... 이준곤(LeeChen) 드림. | ||
|
'- 음악과 나 - > 『 짬 통 』' 카테고리의 다른 글
5월 9일 겜 프로그래밍 시간 (0) | 2006.05.09 |
---|---|
DirectX 9.0 SDK Update - summer 2004 (0) | 2006.05.08 |
슈팅게임 (0) | 2006.05.06 |
네모네모 로직 (0) | 2006.05.06 |
저수준 제어를 이용한 WAVE 재생 (0) | 2006.05.06 |