DirectDraw의 생성
1. DierctX는 COM 을 근간으로 하고 있다!
DirectDraw 객체는 MS의 COM 기술에 기반하여 제작되어 졌습니다. (COM에 대한 자세한 내용은 본 사이트의 관련 기사 부분을 참조하세요)
간략하게 COM을 설명하자면 함수들의 덩어리로 보시면 됩니다.
함수의 덩어리면 클래스나 라이브러리와 뭐가 다르냐? 라고 질문하실수도 있겠군요.
그럼 말을 약간 바꾸죠…COM은 가상함수의 덩어리이다.
포인터함수 아시죠? 함수의 호출 시작주소를 포인터로 갖게되는 함수를 포인터 함수라고 하잖아요. COM은 이러한 함수를 포인터로 기억하고 이 포인터들을 덩어리로 묶어 처리하도록 하는 기술입니다. 이렇게하면 포인터 값을 바꾸어주는 것만으로 C++에서 이야기하는 상속성/다형성 등을 구현할 수 있다는게 COM 기술의 근간이고, 이러한 포인터 함수들을 적절히 관리해주는 방식까지 규격화하여서 프로그래밍 방식의 표준으로 만든 것입니다.
각설하고 DirectX 는 COM을 근간으로 만들어졌습니다.
DirectX 개체를 통해 서비스를 호출하려면 COM 개체를 활용하는 방식을 따라야 합니다.
관련 글에서도 과도 일치합니다.
이하, “COM 개체” 및 “인터페이스” 등의 용어를 직접 쓰겠습니다. 잘 이해가 안되는 분들은 COM 관련기사를 미리 읽어서 참조해주세요..
2. 그러면, DirectX 라는 COM 개체를 어떻게 초기화 하는가?
COM 개체를 생성하는 방법은 아래와 같습니다. (자꾸 COM 이야기네요)
1. COM 라이브러리를 초기화
2. 특정 개체의 ID(고유번호표)를 입력하면서 개체 생성
3. 개체에서 지원하는 인터페이스 포인터를 해당 인터페이스 ID를가지고 획득!
4. 인터페이스 메서드(함수)들을 호출! 호출! 호출!
5. 사용후 메모리 해제와 관련된 함수로 인터페이스 및 개체를 해제!
잘 이해가 안되나요? 그러면 COM 관련기사를 읽어보심이 좋을듯..^^; (아래 글을 가지고 COM을 이해해도 무방하겠지만, 제가 독자들의 수준을 미리 설정하는 것입니다. 이정도는 이해해야 된다… 뭐 그런식 ^^;)
그렇다면 위의 순서대로 아래와 같이 DirectX 개체의 생성과정을 살펴보겠습니다.
1. DierctDraw 객체는 먼저 선언을 통하여서 얻어 진다.
LPDIRECTDRAW pDD; 라고 선언을 함을 통해서 우리는 DirectDraw의 객체를 받아올 변수를 선언합니다. 여기서 눈치 빠른 사람은 LPXXXX에서 LP는 보통 long pointer를 의미하므로 단순히 포인터 변수를 선언하는구나 생각하실수 있겠지요. 맞습니다, DirectX 개체는 운영체제에서 지원하는 것이고, 개체 자체는 운영체제가 관리해주므로 우리는 해당 개체의 “포인터“만을 받아서 사용하는 형태입니다.
2. DierctDraw의 생성 및 버전업된 Interfcae로 버전업
이 버전업 부분은 COM의 다형성을 볼 수 있는 부분입니다. 최초로 획득한 DirectDraw 개체는 쉽게말해 DirectDraw 1.0 개체라고 보시면 되겠고요… DirectDraw 3.0 이나 DirectDraw 8.0 을 사용하시려면 QueryInterface 를 통해 업그레이드된 인터페이스를 구해야 합니다.
3. 초기화 소스코드는 어떻게 되는가?
DirectDraw 개체를 생성하려면(실제로는 받아오려면^^;) DirectDrawCreate() 함수를 통하여서 이루어지고, 버전업된 인터페이스를 구하는 함수는 QueryInterface() 를 이용합니다.
아래에 코드를 나타내었습니다.
LPDIRECTDRAW pDD;
LPDIRECTDRAW4 g_pDD;
hRet = DirectDrawCreate(NULL, &pDD, NULL);
if (hRet != DD_OK)
InitFail( hRet, “DirectDrawCreate FAILED”);
// Fetch DirectDraw4 interface
hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *) & g_pDD);
if (hRet != DD_OK)
InitFail( hRet, “QueryInterface FAILED”);
|
위의 코드에서 하이라으트 된것을 보면 그다지 어렵지는 않아 보이는 것을 알 수 있을겁니다.
. Create()하는 것을 근데, LPDIRECTDRAW4는 무엇인가? DirectDraw가 버전업을 한 것이지요. 먼저 만들은 DirectDraw는 모체가 되고 그의 기능을 더욱 향상시킨 것이 LPDIRECTDRAW4가 됩니다. 우리는 최신의 것을 다루어 보겠는데, 4가 현재는 최신이지요... 이는 현재 자기가 가지고 있는 ddraw.lib와 dxguid.lib의 버전이 얼마인지 알아야 하는데, 가지고계신 ddraw.h의 버전을 보면 알 수 있을 것입니다. QueryInterface()를 통해서 DirectDraw를 상위버전으로 교체한다. (인터페이스 “포인터” 라고 했으니 대입만 하면 바뀔껍니다.^^)
이런 작업은 하나의 셋팅으로 보시면 되겠습니다. 이렇게하면 우리는 최신 DirectDraw4를 가지고 코딩을 할 수 있습니다. 간단하겠지요?
4. C++ 의 클래스로 만들어볼까?
생성 뿐만 아니라 기타 초기화를 위한 클래스를 만들어서 쓴다면 좋을것이다…(왜? 몰라요 ㅜㅜ)
세팅화 되어있는 과정을 클래스로 만들어, DirectX 로 그리게될 메인 윈도우가 생성된후, 간단히 Create 함수를 호출하는 것으로 처리할 수 있을 것이다. 아래에 클래스 소스를 만들어 보았다.
#include <ddraw.h>
class CDirectDraw
{
private :
LPDIRECTDRAW4 g_pDD;
public :
void Create( HWND hWnd );
CDirectDraw();
virtual ~CDirectDraw();
}
void CDirectDraw::Create( HWND hWnd )
{
DDSURFACEDESC2 ddsd;
DDSCAPS2 ddscaps;
HRESULT hRet;
LPDIRECTDRAW pDD;
///////////////////////////////////////////////////////////////////////////
// Create the main DirectDraw object
///////////////////////////////////////////////////////////////////////////
hRet = DirectDrawCreate(NULL, &pDD, NULL);
if (hRet != DD_OK)
InitFail( hRet, “DirectDrawCreate FAILED”);
// Fetch DirectDraw4 interface
hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *) & g_pDD);
if (hRet != DD_OK)
InitFail( hRet, “QueryInterface FAILED”);
// 기타 추가적인 초기화 과정….어쩌구 저쩌구 ………
} |
이제부터 시작이다. 위의 소스는 DierctSDK의 샘블과 똑같을 것이다. 바꿀 필요가 없다. 셋팅이니까…………
주의 깊게 봐야할 것은 LPDIRECTDRAW가 지역 변수로 되어 있다는 것이고, 일단 생성을 시키고 그 포인터를 LPDIRECTDRAW4가 페치하여서 가져간다는 것이다. 이로서 세대 교체 작업은 이루어진 것이라고 보면 된다.
이런 코드를 만들고 컴파일을 해보면 pDD->QueryInterface(IID_IDirectDraw4,
(LPVOID *) & g_pDD); 에서 IID_IDirectDraw4에서 에러가 나는 경우가 있다.
이것은 Visual C++의 Project의 Setting에서 Link부분에 dxguid.lib가 빠져 있기 때문이다.
이를 꼭 첨가 해주기 바란다. 나는 이 부분이 ddraw.lib문제인가하여서 아주 고생을 많이 했다.
dxguid.lib에는 최신 Interface의 정보가 들어 있다. ddraw.lib 와 dxguid.lib를 첨가하기 바란다.
// :script –>
새로운 천년이 되었어도 강좌는 계속되어야 한다.
안녕하세요~ 이준곤(LeeChen) 입니다.
아래 글은 같이 공유하고자 타사이트에서 가져온 글을 옮겨다 놓았습니다.
다이렉트 엑스에 관해 개괄적인 설명과 초보자 분들께 어떤 것들이 있구나 하는 정도와
다이렉트 엑스가 어떤식으로 움직이는가에 관한 내용을 서술하고 있습니다.
주로 도움말을 기초로 해서 번역또는 설명을 해놓은 자료인 것 같습니다.
많은 분들께 도움 되시길 바라면서….
DirectX 전반적인 내용
이곳에는 Direct X에대한 전반적인 내용을 설명하는 곳이다.처음 Direct X가 나왔을 때는 Assembly, C언어등을 사용하던 게임 개발자들이 Direct X를 별로 사용하지 않았다. 그러나 시간이 지나면서 Direct X를 사용하던 개발자들이 속도, 프로그램 제작등의 이점을 발견하게 되어 점차 Direct X의 사용이 증가하기 시작했다.
다음은 Direct X SDK 6.1 Version에 포함된 내용을 정리하였다.
- Direct Draw
- Direct Input
- Drect Play
- Direct Sound
- Direct Music
- Direct Setup
- Direct Show
- Direct Animation
- Direct 3D
|
⊙ DirectX의 역사 |
처음 DirectX는 게임 SDK(또는 GDK)라는 이름으로 세상에 출시됐다. WindG나 WaveMix등으로 게임 개발자들을 위도우 시장으로 끌어들이려던 MS의 전략은 수포로 돌아갔고, MS는 결국 GDK라는 것을 내놓게 된 것이다. GDK는 게임을 위한 전용 SDK로 도스용 게임 개발자가 윈도우로 개발환경을 옮기면서 발생한 많은 문제들을 해결해 주었다.
특히 Windows 게임으 최대 걸림돌인 느린 화면 출력 속도를 극적으로 빠르게 해주는 것이 관심의 대상이었다. 이를 위해 GDK는 최근 출시되는 비디오 카드의 기본 기능인 Windows 가속 기능을 사용하였다. Windows 가속 기능을 사용하기 위해서는 Windows system에 대한 이해가 필요하다. Windows는 그림에서 보이는 것처럼 GDI(Graphic Device Interface)라고 하는 일관된 Interface를 통해 어떠한 비디오 카드에서도 항상 같은 화면을 보여줄 수 있다는 장치 독립성을 확보했다. 그러나 이런 경로를 통한 출력 속도는 게임을 하는 사용자에게는 너무 느린 느낌을 주기에 충분했다. 그러나 DirectX는 GDI를 경유하지 않고 바로 하드웨어를 접근할 수 있는 방법을 제시하였다. 처음 DirectX가 발표되었을 때는 4개의 API(Application Programming Interface) – 즉 DirectDraw, DirectSound, DirectInput, DirectPlay – 가 지원되었지만, 업그레이드된 DirectX에서는 Direct3D가 추가되어 게임 라이브러리의 기능이 더욱 막강해졌다. 현재 DirectX 버전은 6.1a 까지 나와있으며, 계속 업그레이드가 진행중이다. 이에 대한 site는 DirectX 관련 site 를 참고하면 된다.
|
|
⊙ DirectX란 무엇인가 ? |
DirectX는 윈도우 기반의 컴퓨터에서 그래픽, 비디오, 3차원 애니메이션, 서라운드등 멀티미디어 관련 프로그램을 실행시키기 위한 기반이 되는 기술들의 집합체라 할 수 있다. DirectX는 Windows O/S 및 Internet Explorer 내부에 포함된 한 부분이기도 하다. DirectX가 개발된 배경은 개발자에게 게임 개발에 기반이 되는 교육과 Component들을 제공해 그들로 하여금 쉬운 개발 환경을 만들 수 있도록 하는데 있다. 우선 DirectX는 개발자들이 이를 이용해 개발한 모든 프로그램이 어떠한 Windows 기반의 운영체제에서도 돌아가는 것은 물론 Hardware의 성능을 최대한으로 이끌어 낼 수 있게 한다. 이러한 것들은 DirectX의 기반층(Foundation Layer)에 의해 이루어지며, DirectX의 미디어층(Media Layer)은 개발자들이 더욱 쉽게 멀티미디어 관련 개발을 할 수 있도록 해준다.
|
|
|
⊙ DirectX의 구성요소 |
|
|
|
기반층(Basic Layer) : 개발자로 하여금 3차원 가속보드나 사운드 카드 등 고성능 H/W의 진보된 기능들을 사용할 수 있는 일관된 API를 제공한다. 이들 API는 저 수준 함수(Low-Level Function)로서 DirectDraw, Direct3D, DirectInput, DirectSound등 4개의 콤포넌트(Component)로 구성되어 있다. 가능한 최상의 성능을 낼수 있도록 하기 위해 자동으로 H/W의 능력을 감지한다.
|
미디어 층 (Media Layer) : 애니메이션과 미디어 스트림(인터넷을 통한 오디오, 비디오 등의 다운로드)을 지원하는 고수준의 서비스를 제공한다. 미디어 층을 구성하는 API(Application Programming Interface)로는 DirectShow, DirectAnimation, Direct3D Retained Mode, DireectPlay 등이 있다. 또한 개발자들이 Windows 기반의 시스템에서 게임을 개발할 때 경험하게 되는 여러 문제 – 서로 다른 종류의 멀티미디어 효과를 조화시키는 것 – 들을 해결 할 수 있게 하였다
|
DirectX 기반층 |
HAL(Hardware Abstraction Layer) |
HEL(Hardware Emulation Layer) |
특징 |
H/W의 가속 기능과 프로그램간의 통신을 담당해 개발자로 하여금 다양한 하드웨어의 가속 기능을 사용할 수 있도록 하고 있다. |
H/W가 지원하지 못하는 기능을 시뮬레이션(Simulation : 모의조작) 함으로써 특정 시스템에서 작동되지 않을 수 있는 비호환성 문제를 해결한다. |
|
|
* 이글은 게임 전문 잡지에 기고된 글을 게시한 것입니다.
- Direct X : Direct X가 무엇인지 모르는 게임 플레이어라도 이것이 게임과 관련이 있다는 것을 알 것이다. 게임을 설치하거나 실행할 때 Direct X와 관계된 메시지가 나타나기 때문이다. 또한 이것 때문에 게임 실행에 어려움을 겪는 경우도 있다. Direct X가 윈도 게임을 하는데 필요하다는 정도는 알고 있는데 어떤 역할을 하는지 궁금해 하는 게이머도 있을 것이다.
- 다이렉트X? : Direct X를 굳이 영문으로 표기한데는 이유가 있다. 발음 때문인데 어떤 이가 먼저 부르기 시작했는지 모르겠지만 우리 나라의 관련 서적들을 비롯한 여러 출판 매체나 PC 통신 게시판 등에서는 ‘다이렉트X’로 표기하고 있다. 즉, Direct를 ‘다이렉트’로 발음을 한다. 그러나 이 단어가 ‘다이렉트’로만 발음되는 것이 아니다. 일례로 유명한 멀티미디어 저작도구인 Director가 있다. 이 소프트웨어 명칭은 서적이나 신문 등에서 ‘다이렉터’라고 하지 않고 ‘디렉터’라고 표기하고 있고 사용자들도 모두 ‘디렉터’로 발음하고 있다. DirectX가 탄생하기까지 게임은 빠른 화면 전환과 동작이 필요하며 화면에 따라 음향효과도 일치해야 한다. 그리고 키보드나 조이스틱으로 조작했을 때 재빠른 처리가 필요하다. IBM 호환 기종의 도스 시절에 게임이 크게 발전하였던 것은 바로 이러한 빠른 처리가 가능했기 때문이다. 유닉스 등의 운영체제는 한번에 여러 작업을 할 수 있는 멀티태스킹과 다중 사용자들이 함께 사용할 수 있도록 하는 특성 때문에 시스템 전체를 장악해야 하는 게임은 크게 발전하지 못했다 (현재의 윈도95/98과 윈도 NT도 이러한 특성을 갖고 있지만 게임 기반으로 발전 시키기 위해 노력해 온 마이크로소프트의 결실이 DirectX로 나타난 것이다). 도스에서는 한 사용자가 독점적으로 하나의 작업을 위해 사용하기 때문에 프로그램을 통하여 하드웨어 시스템을 조작하기가 쉬웠다. 마이크로소프트가 윈도3.1을 발표한 후에도 역시 기반은 도스였고 게임도 주로 도스에서 실행되었다. 그런데 윈도 95를 발표하면서 상황은 달라졌다. 윈도 95는 윈도 3.1과는 달리 도스 위에서 실행되는 것이 아니라 내부에 도스를 포함하였기 때문에 DOS게임을 실행하기가 까다로웠다. DOS 모드로 부팅할 수 있는 여지를 남겼지만 쉬운 사용법과 간편함을 주장한 마이크로소프트에게는 여전히 옥의 티로 여겨졌다. 윈도95는 다른 그래픽 사용자 환경처럼 카드놀이, 핀볼 등의 고만고만한 게임만 할 수 있는 듯했다. 하지만 이미 윈도3.1에서부터 여러 가지를 시도한 끝에 윈도95에서도 하드웨어 시스템을 바로 이용할 수 있는 통로를 개발하였다. 그것이 바로 DirectX이다. DirectX라는 명칭도 곧장(direct)시스템을 다룰 수 있도록 했다는 의미에서 나온 것이다.
- DirectX의 시초 : DirectX가 시스템을 바로 통제할 수 있는 통로 구실을 하지만 정확하게 게임에서 어떠한 일을 할까? 이것을 알아보기 위해 DirectX의 발전 과정을 간략히 알아보자. DirectX는 버 전1부터 시작하여 현재 7.0 버전까지 발표되었다. DirectX 6.1a 버전부터 DirectMusic이라는 새로운 Component를 추가하였는데, 이는 게임에 사용되는 사운드를 편집하여, 현재 제작하고 있는 게임에 사용하기 위한것이 하나의 목적이고, 또 하나는 현재 인터넷 상에서 벌어지고 있는 각종 온라인 게임등에서 데이터 전송이 늦어서 발생하는 불협화음(?)-즉, 게이머가 총을 쏘았는데 소리는 한참 후에 난다든가 하는..-을 최대한 줄이기 위해 고안된 것이다. DirectMusic을 사용하면, 여러가지 장점이 있지만 아직 기술적인 보완이 있어야 할 것으로 생각한다.
- 처음 발표된 DirectX 1.0 버전은 다음과 같은 4가지 기능을 지원하였고 게임 개발사들은 앞 다투어 DirectX 지원 게임을 내놓기 시작하여 게이머들의 관심을 증폭시켰다.
- Direct3D의 등장 : DirectX 2.0 버전에서는 Direct3가 추가되어 3D(3차원) 게임의 새 장을 열었다. 이전까지는 2차원 게임이 주류를 이루었고 도스에서도 3차원 게임인 DOOM이 성공을 거두기는 했지만 2차원을 3차원처럼 보이도록 했을 뿐이지 정확한 의미의 3D 게임이 아니었다. 3차원 이란 광원과 그림자를 바탕으로 입체감을 느낄 수 있도록 한 것이다. 당시의 게이머에게는 3D 게임 이 놀라움과 반가움 그 자체였다. 그러나 이때 이미 몇몇 게임 개발 업체에서는 3D 게임 개발을 위해서 OpenGL 기술을 채택하고 있었다(OpenGL은 캐드 등의 고가 컴퓨 터 장비를 요구하는 고급 3D 그래픽 처리 기술임). 그래서 Direct3D를 테스트해 본 해당 업 체로써는 3D 그래픽 품질이 떨어지는 Direct3D보다 OpenGL을 윈도95에서 지원할 수 있게 해 달라고 요청한다. 이 후에 발표된 윈도NT나 윈도98에서는 운영체제 차원에서 기본적으로 OpenGL을 지원하기는 했지만 형식적인 차원에서 이루어졌다. 그 이유는 자사의 3D 기술을 포기할 수 없었고 (OpenGL은 실리콘 그래픽스의 기술임) 윈도 사용자가 특정 하드웨 어에 구애됨이 없이 게임을 즐길 수 있도록 하자는 마이크로소프트의 방침 때문이었다. OpenGL을 제대로 구현하기 위해서는 그 당시 값비싼 그래픽 카드나 아직 시장이 제대로 형성되지 않은 3D카드가 필요했었다. Direct3D의 장점 중 한가지가 값싼 VGA 그래픽 카 드에서도 3D 게임을 즐길 수 있다는 점이었다. (Direct3D 품질이 OpenGL에 비해서 떨어 지는 것은 어쩔 수 없었다). 지금은 3D 그래픽 가속 카드의 가격이 워낙 낮아져서 그런 장 점도 없어졌지만 마이크로 소프트는 꾸준히 Direct3D에 대한 업그레이드를 계속하여 OpenGL과 비슷한 수준으로 이끌고 있다. 사실 3D 게임 매니아가 아니라면 Direct3D와 OpenGL에 대하여 민감해 할 것까지는 없다.
- DirecDraw: 드디어 윈도95에서 도스 시절의 역동적이고 빠른 게임화면을 볼 수 있게 한다.
- DirectSound : 사운드가 시간 지연 없이 출력되도록 한다.
- DirectInput : 입력 장치(키보드, 마우스, 조이스틱등)를 설정하는 부분이다.
|
|