home lecture link bbs blame

◈Game Media Programming◈


Game Media Programming은 미디어의 라이브러리에 따라 뮤직, 사운드, 동영상 등으로
분류할 수 있습니다.
사운드에 대한 프로그램은 마이크로소프트의 다이렉트 사운드(Direct Sound)를 이용해서
만드는데 웨이브 파일을 가지고, 3D 음향, 배경음악, 효과 음향 등에 주로 사용이 됩니다.
또한 OpenAL이나 OGG등을 이용해서 게임관련 사운드를 연출하는데 마이크로소프트와
OpenAL, OGG는 공통으로 라이브러리 사용에 대한 라이센스에 대한 비용지불을 하지 않고
사용할 수 있도록 허가가 되어 있습니다.

뮤직은 윈도우의 미디 연주를 생각하면 편합니다. 사운드와 뮤직의 차이를 종종 혼돈하는
경우가 있는데 아날로그 음원을 디지털로 변환한 것이 사운드고 뮤직은 음을 재생하는
방법을 적어놓은 일종의 디지털 악보라 할 수 있습니다. 따라서 사운드는 원음에 가깝게
재생이 되지만 뮤직은 연주하는 기계에 따라 다른 음향을 만들어 낼 수 있기 때문에 둘의
차이가 분명한 것입니다.

사운드가 뮤직보다 음질이 좋아 음향에 대해서 모든 것을 사운드로 사용하는 것이 좋아
보이지만 뮤직은 사운드 보다 월등히 저장 공간을 적게 차지 합니다. 따라서 재생에
대해서 프로그램에 큰 부담이 없습니다. 또한 뮤직은 다양하고 세세한 제어를 지원하고
있습니다. 그리고 Direct Sound로 삼차원 효과음을 만들기 어렵다면 뮤직을 통해서 쉽게
만들 수도 있고 일반 음향도 뮤직에서 재생이 가능합니다. 이처럼 뮤직의 기능과 성능이
막강해서 아직도 뮤직의 사용은 무시할 수 없습니다.

동영상은 다이렉트 쇼(Direct Show, 디쇼)를 이용합니다. 디쇼는 미디어의 종합 선물
세트라고 볼 수 있습니다. 동영상을 재생하는 것 이외에 사운드 등 미디어의 모든 것들을
재생할 수 있습니다. 특히 용량의 문제로 만약 mp3를 사용하는 경우라면 이를 재생하기
위해서는 디쇼를 사용해야 합니다. 또한 디쇼는 재생하는 화면을 텍스처에 실시간으로
저장이 가능해서 동영상을 입히는 재미있는 일들을 할 수가 있습니다.

설명은 이 정도로 간단히 하고 실전으로 들어가 프로그램을 만들어 봅시다. 실전에 들어가기
앞서서 모든 프로그램은 실제 게임 환경과 유사한 Direct3D가 동작하는 화면을 배경으로
작성한 다음코드를 이용하겠습니다.

mp00_Base.zip






1. Direct Music


1.1 뮤직 로더(Music Loader) 초기화 해제


뮤직은 사운드 프로그래밍에서 가장 쉽습니다. 뮤직은 로더, 퍼포먼스, 세그먼트 객체로
분리되어 음을 재생합니다. 다이렉트 뮤직을 사용하기 위해서 다음과 같이 헤더파일과
라이브러리 파일을 포함해야 합니다.
	#include < dmusicc.h>	// DirectMusic includes
	#include < dmusici.h>

	// For CLSID_DirectMusicLoader and IID_IDirectMusicLoader8...
	#pragma comment(lib, "dxguid.lib")

로더는 단어 그대로 뮤직 파일을 재생이 가능하도록 적재 하는 역할을 합니다. 로더 객체를
얻기 위해 프로그램은 IDirectMusicLoader8 의 인스턴스를 만들어야 합니다. 로더의
인스턴스는 CoCreateInstance() 함수를 통해서 만들어지는데 이 함수를 사용하기 위해서는
반드시 컴(COM)객체가 초기화되어 있어야 합니다. 프로그램은 다음과 같이 구현합니다.
	// COM 초기화
	if (FAILED(CoInitialize(NULL)))
		return -1;


	// 로더 생성
	if (FAILED(CoCreateInstance(CLSID_DirectMusicLoader
		, NULL, CLSCTX_INPROC
		, IID_IDirectMusicLoader8
		, (void**)&m_pLoader))
		)
	{
		MessageBox(GetActiveWindow()
			, "Create IDirectMusicLoader8 Failed", "Err"
			, MB_ICONEXCLAMATION);

		return -1;
	}

뮤직과 더불어 DirectX의 모든 객체들은 COM을 상속 받습니다. COM은 Release() 함수를
통해 해제합니다.
	// 로더 해제
	if(m_pLoader)
	{
		m_pLoader->Release();
		m_pLoader = NULL;
	}

이렇게 로더를 해제하고 나서 CoUninitialize()함수를 통해서 COM을 해제해야 합니다.
	// COM을 해제 한다.
	CoUninitialize();

로더가 파일을 좀 더 빨리 찾을 수 있도록 기본 디렉터리를 SetSearchDirectory() 함수를
이용해서 설정할 수 있습니다. 이 함수를 사용하려면 파일의 이름을 유니코드로 변환해서
사용해야 합니다. 이러한 이유로 이 함수를 사용할 때에는 반드시 폴더 이름을 Wide
캐릭터로 바꿔주어야 합니다.
	char pathStr[MAX_PATH];		// path for audio file
	WCHAR wsFile[MAX_PATH];

	// 프로그램이 동작하는 위치 얻기
	GetCurrentDirectory(MAX_PATH, pathStr);

	// 유니코드 문자열로 변환
	MultiByteToWideChar(CP_ACP, 0, pathStr, -1, wsFile, MAX_PATH);

	// 로더에 찾기 폴더 설정.
	m_pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wsFile, FALSE);

좀 더 자세한 코드의 내용은 다음 예제를 참고하기 바랍니다.

mp01_Music1.zip






1.2 퍼포먼스와 세그먼트


파일을 로더를 통해서 메모리에 적재 했다면 이 적재된 파일을 재생하고 위해서 퍼포먼스와
세그먼트를 이용합니다. 퍼포먼스는 뮤직의 행위, 즉 재생, 멈춤 등에 대한 내용을 담고
있으며 세그먼트는 퍼포먼스에 대한 설정 값이라고 생각하면 됩니다. 앞의 코드를 연장해서
퍼포먼스와 세그먼트를 가지고 미디 파일을 연주해 봅시다.

먼저 퍼포먼스를 만들고 오디오 경로를 설정합니다.
	// 퍼포 먼스 생성
	if (FAILED(CoCreateInstance(CLSID_DirectMusicPerformance
				, NULL
				, CLSCTX_INPROC
				, IID_IDirectMusicPerformance8
				, (void**)&m_pPerform)))
		return -1;

	// 퍼포먼스 오디오 경로 설정
	if(FAILED(m_pPerform->InitAudio(NULL
				, NULL
				, GetActiveWindow()
				, DMUS_APATH_SHARED_STEREOPLUSREVERB
				, 128
				, DMUS_AUDIOF_ALL
				, NULL)))
		return -1;

다음으로 파일의 이름을 유니코드로 변경해서 재생을 위해 퍼포먼스에 올립니다.
	// 유니코드로 파일이름 변경
	MultiByteToWideChar(CP_ACP, 0, "Sound/Canyon.mid", -1, wsFile, MAX_PATH);

	// 미디 파일 로드
	if (FAILED(m_pLoader->LoadObjectFromFile(CLSID_DirectMusicSegment
				, IID_IDirectMusicSegment8
				, wsFile
				, (void**)&m_pSegment)))
	{
		MessageBox(GetActiveWindow()
			, "Load Music File Failed", "Err"
			, MB_ICONEXCLAMATION);
		return -1;
	}


뮤직의 제어는 세그먼트를 이용하므로 신서사이저에 대해서 세그먼트의 연주악기를
다운로드 합니다.
	m_pSegment->Download(m_pPerform);

연주가 남았는데 재생은 다음과 같이 합니다.
	// 재생
	m_pSegment->SetStartPoint(0);
	m_pPerform->PlaySegmentEx(m_pSegment, NULL, NULL, 0, 0, NULL, NULL, NULL);

	// 중간 멈춤
	//if(S_OK == m_pPerform->IsPlaying(m_pSegment, NULL))
	//	m_pPerform->StopEx(m_pSegment, 0, 0);


좀 더 자세한 코드는 다음 예제를 살펴보기 바랍니다.

mp01_Music2.zip






1.3 오디오패스


퍼포먼스와 세그먼트만 가지고도 뮤직을 동작할 수 있지만 정교하게 볼륨을 조절하거나
삼차원 음원을 만들고자 할 때에는 반드시 오디오패스가 필요합니다. 오디오 패스는
다음과 같이 퍼포먼스를 통해서 만듭니다.
	// 퍼포먼스를 통해서 오디오 패스 생성
	if (FAILED(m_pPerform->CreateStandardAudioPath(
				DMUS_APATH_SHARED_STEREOPLUSREVERB
				, 128
				, TRUE
				, &m_pAudioPath)))
		return -1;

	…

그리고 다음과 같이 연주를 시작할 때 연결해 주어야 오디오 패스를 사용할 수 있습니다.
	m_pSegment->SetStartPoint(0);
	m_pPerform->PlaySegmentEx(m_pSegment
				, NULL
				, NULL
				, DMUS_SEGF_DEFAULT
				, 0
				, NULL
				, NULL
				, m_pAudioPath);

이렇게 오디오 패스를 세그먼트와 연결하면 볼륨을 조절할 수 있습니다. 볼륨 조절에서
주의해야 할 것은 볼륨의 크기는 데시벨(dB)로 표기하며 [-9600, 0] 범위의 값을 이용하고
다음과 같이 설정합니다.
	m_pAudioPath->SetVolume(m_dVolume, 0);

좀 더 자세한 내용은 다음 코드를 활용하기 바랍니다.

mp01_Music3.zip






1.4 뮤직클래스


지금까지 뮤직에 대한 기본적인 내용을 살펴보았습니다. 이 코드들 만으로도 충분히 게임에서
활용할 수 있지만 좀 더 확장성과 편리성을 위해 뮤직 클래스와 뮤직 관리자 클래스를
만들어 봅시다.
뮤직 관리자 클래스는 뮤직을 관리하고 뮤직클래스의 인스턴스를 만듭니다. 뮤직 클래스는
앞의 기본적인 뮤직의 코드에 재생, 정지, 일시 정지, 반복 기능 등을 멤버 함수로
구현하도록 합시다.
이러한 내용을 다음의 예제에 구현 되어 있으며 몇 가지 기능은 MSDN과 인터넷을 참고
해서 만들었습니다. 코드의 자세한 내용은 굳이 설명하지 않겠습니다.

mp01_Music4.zip






2. Direct Sound


다이렉트 사운드는 웨이브파일 사용하거나 삼차원 음원을 다룰 때 주로 이용합니다. 웨이브
파일은 마이크로소프트에서 만든 파일 형식으로 라이센스 비용이 없고, 파일을 해석하는
루틴이 복잡하지 않아서 게임에서 많이 응용합니다.
웨이브 파일의 단점이라면 그래픽에서의 BMP파일과 비슷하게 압축이 안되어 있습니다.
압축은 양날의 검으로 저장 공간은 줄어 들지만 재생하려면 압축을 풀어야 하기 때문에
로딩에 시간이 더 걸립니다. 반대로 압축이 안되어 있으면 로딩은 빠르지만 저장공간을
많이 차지하게 됩니다.
그런데 대부분의 상용게임들은 자체 압축루틴이 있기 때문에 오히려 압축이 안되어 있는
상태가 유리할 수 있으므로 웨이브 파일의 사용은 그리 큰 문제나 걱정거리가 되지 않습니다.






2.1 저 수준 Sound


다이렉트 사운드는 게임에서 웨이브 파일을 편리하게 사용할 수 있도록 만든 라이브러리로
이 것을 사용하면 저 수준으로 wave 파일을 다루지 않아도 되지만 간혹 PDA와 같이
Direct Sound를 쓸 수 없는 경우에는 wave 파일의 저 수준 사용에 대해서도 꼭 알아두어야
합니다.
저 수준 사용에 대한 많은 내용이 있지만 그 중에서도 반드시 기억해야 할 것은 입출력에서
쓰레드를 통해서 wave의 사용이 종료가 되는 점입니다.

다음과 같이 wave 파일을 읽은 후에 입출력에 대한 이벤트를 얻기 위해서 callback 함수를
연결합니다.
	if(MMSYSERR_NOERROR != waveOutOpen(
					&m_WavOut
					, WAVE_MAPPER
					, &m_WavFMT
					, (DWORD)CMpSnd::WaveOutProc
					, 0
					, CALLBACK_FUNCTION))
		return -1;

윈도우 프로그램의 메시지 처리와 유사한 방식으로 wave에 대한 사용에 대해서 이벤트가
통보되고 다음과 같이 처리하면 됩니다.
	void CALLBACK CMpSnd::WaveOutProc(HWAVEOUT hWavOut
					, UINT uMsg
					, DWORD dwInstance
					, DWORD dwParam1
					, DWORD dwParam2)
	{
		switch(uMsg)
		{
			case WOM_OPEN:
				…
				break;

			case WOM_DONE:
				…
				break;
			}

			case WOM_CLOSE:
				…
				break;
		}
	}

사운드에 재생 기능은 waveOutPrepareHeader(), waveOutWrite(), waveOutRestart(m_WavOut)
함수들을 이용해서 작성합니다.
정지 기능과 리셋은 waveOutUnprepareHeader()와 waveOutReset() 함수들을 적절히 사용해서
만들고 볼륨의 조절을 waveOutSetVolume()을 이용합니다. 이외의 기능은 저 수준 함수들을
이용하면 되므로 이에 대한 활용은 다음 코드를 활용하기 바랍니다.

mp02_Sound1.zip






2.2 Direct Sound


다이렉트 사운드는 wave 파일의 저 수준 입출력을 편리하게 사용하기 위해 IDirectSound8,
IDirectSoundBuffer8, IDirectSound3DBuffer8, IDirectSound3DListenr8, IDirectSoundCapture8
으로 구성되어 있습니다. 만약 3D Sound 사용을 안 한다면 IDirectSound8, IDirectSoundBuffer8의
객체만 가지고 있어도 됩니다.

IDirectSound8 의 객체는 DirectSoundCreate8() 함수를 통해서 만듭니다. 이 객체를 만들고
나서 협력수준을 설정하고 주 사운드 버퍼를 설정해야 합니다.
	// IDirectSound 객체 생성
	if( FAILED(DirectSoundCreate8( NULL, &m_pDS, NULL ) ) )
		return -1;

	// 협력레벨 설정
	if( FAILED(m_pDS->SetCooperativeLevel( m_hWnd, DSSCL_PRIORITY ) ) )
		return -1;


	HRESULT	hr;
	LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

	// 주 사운드 버퍼를 위한 변수 설정
	DWORD dwPrimaryChannels	= 2;		// 스테레오
	DWORD dwPrimaryFreq	= 22050;	// 가청주파수 22KHz
	DWORD dwPrimaryBitRate	= 16;		// 사운드 비트 16


	// 주 사운드 버퍼 만들기
	DSBUFFERDESC dsbd;
	ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
	dsbd.dwSize        = sizeof(DSBUFFERDESC);
	dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
	dsbd.dwBufferBytes = 0;
	dsbd.lpwfxFormat   = NULL;


	if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
		return hr;


	WAVEFORMATEX wfx;
	ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
	wfx.wFormatTag      = (WORD) WAVE_FORMAT_PCM;
	wfx.nChannels       = (WORD) dwPrimaryChannels;
	wfx.nSamplesPerSec  = (DWORD) dwPrimaryFreq;
	wfx.wBitsPerSample  = (WORD) dwPrimaryBitRate;
	wfx.nBlockAlign     = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels);
	wfx.nAvgBytesPerSec = (DWORD) (wfx.nSamplesPerSec * wfx.nBlockAlign);


	// 주 사운드 버퍼 설정
	if( FAILED( pDSBPrimary->SetFormat(&wfx) ) )
		return -1;

Direct Sound 객체들도 COM을 상속받으므로 소멸은 Release() 함수를 통해서 이루어 집니다.
다음 예제를 보면서 IDirectSound8 객체의 생성과 소멸에 대한 부분을 참고 하기 바랍니다.

mp02_Sound2.zip






2.3 IDirectSoundBuffer8


IDirectSoundBuffer8객체를 얻기 위해서 Wave파일을 해석하고, 객체를 설정하는 일이 그리
녹녹하지 않습니다. 다행히도 DirectX SDK 안에는 Direct Sound를 처리하는 코드와 더불어
위저드로 쉽게 이를 생성할 수 있도록 도와 주고 있습니다. 사운드의 전문가 아니고 게임에서
응용이라면 이 위저드 코드를 활용하는 것이 좋습니다. 위저드를 실행하면 사운드매니저,
사운드 객체, 웨이브파일 클래스가 들어있습니다. 좀 더 상황에 맞게 이를 수정하면 되고
여기서는 빠져 있는 볼륨 조절을 추가해 보도록 합시다.

볼륨 조절을 위해서 DxSound 객체를 생성하는 부분에 dwCreationFlags |= DSBCAPS_CTRLVOLUME;
코드를 중간에 넣습니다.
	HRESULT CSoundManager::CreateFromMemory(…)
	…

		dwCreationFlags |= DSBCAPS_CTRLVOLUME;
		apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];

	…

볼륨 조절에 대한 멤버 함수를 다음과 같이 추가하면 됩니다.
	void CDxSound::SetVolume(LONG lVal)
	{
		for( DWORD i=0; i< m_dwNumBuffers; ++i)
		{
			if( m_apDSBuffer[i] )
			{
				m_apDSBuffer[i]->SetVolume( lVal);
			}
		}

	}

	LONG CDxSound::GetVolume()
	{
		LONG	lVal=0;
		if(m_apDSBuffer)
			m_apDSBuffer[0]->GetVolume(&lVal);

		return lVal;
	}

좀 더 자세한 위저드 코드 변경은 다음 예제를 참고 하기 바랍니다.

mp02_Sound3.zip

mp02_Sound4.zip






3. 3D Sound


3D 사운드는 음원과 소리를 듣는 청취자를 가지고 만드는데 이를 구현하는 것이 복잡합니다.
DirectX의 3D Sound 는 음원에 대한 3D Sound Buffer와 이를 감지하는 3D Sound Listener 를
제공하고 있어서 초보자들도 쉽게 3D 사운드를 연출할 수 있습니다.
3DBuffer는 음원이 이동한다면 이 때 발생하는 도플러 효과를 만들어 낼 수 있고 이를
위해서 위치와 속도 등등을 설정 할 수 있습니다. 3D Sound Listener 도 정취 위치와 청취
방향이 있어 청취자가 회전할 때나 이동할 때 음의 변화를 만들 수 있도록 이들의 값들을
설정할 수 있도록 구성되어 있습니다.
삼차원 사운드를 만드는 방법은 Direct Sound 또는 Direct Music을 통해서 만들어 낼 수
있는데 Sound 를 통해서 만드는 경우라면 wave 파일이 Stereo 사운드가 아닌 이들은
Mono 사운드 이어야만 합니다.
3D Sound Buffer부분에서 버퍼의 dwMode를 반드시 DS3DMODE_NORMAL 으로 설정해야 하고
DS3DMODE_HEADRELATIVE 값으로 설정하면 설정 값이 버퍼에만 적용이 되고 Listener에게는
적용이 안 된다는 점을 기억하기 바랍니다.






3.1 Music을 통한 3D 사운드 만들기


3D 사운드를 뮤직을 통해서 만들고자 한다면 반드시 필요한 것이 Audio Path 입니다. 앞서
오디오 패스를 자신의 코드에 적용했다면 3D 사운드를 만드는 것은 그리 어렵지 않습니다.
다음 예제의 DxSnd3D::Create() 함수를 살펴보면 다음과 같이 오디오 패스를 통해서 음원에
대한 3D buffer 와 청취자에 대한 3D Listener 를 만들 수 있음을 볼 수 있습니다.
	INT DxSnd3D::Create(…)
	…
		// 3D buffer
		if (FAILED(hr = pMusic->pOdioPth->GetObjectInPath(0
						, DMUS_PATH_BUFFER
						, 0
						, GUID_NULL
						, 0
						, IID_IDirectSound3DBuffer
						, (void**)&pD3Buff)))
			return -1;


		// listener
		if (FAILED(hr = pMusic->pOdioPth->GetObjectInPath(0
						, DMUS_PATH_PRIMARY_BUFFER
						, 0
						, GUID_NULL
						, 0
						, IID_IDirectSound3DListener
						, (void**)&pD3Lstn)))
			return -1;

		// 3D Buffer Listener Parameters Setup
		memset( &DsBuff, 0, sizeof DsBuff);
		memset( &DsLstn, 0, sizeof DsLstn);

		DsBuff.dwSize = sizeof DsBuff;
		DsBuff.dwMode = DS3DMODE_NORMAL;
		DsBuff.flMinDistance = 0;
		DsBuff.flMaxDistance = 50.f;
		pD3Buff->SetAllParameters(&DsBuff, DS3D_IMMEDIATE);

		DsLstn.dwSize = sizeof DsLstn;
		DsLstn.flDopplerFactor = 0;
		DsLstn.flRolloffFactor = 0.1f;
		pD3Lstn->SetAllParameters(&DsLstn, DS3D_IMMEDIATE);
	…

좀 더 구체적인 코드는 다음 예제를 참고 하기 바랍니다.

mp03_3Dmusic.zip






3.1 Direct Sound 통한 3D 사운드 만들기


앞서 Direct Sound를 위저드 코드를 이용했는데 이 위저드를 활용하면 3D 사운드를
어렵지 않게 구현 할 수 있습니다.
앞서 이야기 했듯이 먼저 wave 파일은 Mono 사운드 이어야 합니다. 다음으로 위저드
코드 중에서 Sound 생성에서 DSBUFFERDESC 구조체를 채우는 부분이 있습니다. 이 구조체의
dwFlags 값을 DSBCAPS_CTRL3D 으로 설정해주어야 하고, DirectSound3D algorithm 을
DS3DALG_NO_VIRTUALIZATION, DS3DALG_HRTF_FULL, DS3DALG_HRTF_LIGHT중에서 하나를 선택해야
3D 사운드가 만들어 집니다.
	HRESULT CSoundManager::Create3D(…)
	…
		DWORD dCreationFlag = dwCreationFlags | DSBCAPS_CTRL3D;

		if(FAILED(this->Create(ppSound
					, strWaveFileName
					, dCreationFlag
					, guid3DAlgorithm
					, dwNumBuffers)))
			return -1;
	…

	HRESULT LnDms_Get3DListener(…)
	…
		// Obtain primary buffer, asking it for 3D control
		ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
		dsbdesc.dwSize = sizeof(DSBUFFERDESC);
		dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
	…

좀 더 구체적인 코드는 다음 예제를 참고 하기 바랍니다.

mp03_3Dsound.zip






4. Direct Show


4.1 MP3 플레이어


다이렉트 쇼(Direct Show)는 마이크로소프트에서 제공하는 음향과 영상 재생을 위한
멀티미디어의 종합선물세트 SDK 입니다. 쇼를 이용하게 되면 음향 영상에 대해서 각각
조절하지 않고 통합적으로 관리되어 자유자제로 표현할 수 있습니다.
다음 예제의 CMiMp3 클래스의 멤버 변수들을 보면 IGraphBuilder, IMediaControl,
IMediaSeeking, IBaseFilter, IBasicAudio, IMediaEventEx 들에 대한 객체 포인터가
정의 되어 있습니다. 이 객체들은 음향 뿐만 아니라 동영상에서도 사용되는 만큼 활용 법을
알아 두는 것이 좋습니다.

디쇼는 동작에 대한 결과를 이벤트로 얻을 수 있는데 IMediaEventEx 객체의
SetNotifyWindow() 함수를 통해서 이벤트 발생을 처리할 윈도우를 연결합니다. 만약 게임에서
배경음악을 무한 재생을 설정하는 경우라면 메인 프로그램의 윈도우 핸들을 전달해서 메인
메시지 처리 함수에서 처리가 가능하도록 하는 것이 좋습니다.

디쇼의 내용은 시중의 다른 책들을 참고하기 바라고 사용은 다음 예제의 CMiMp3 클래스의
인스턴스가 이용되는 방법을 살펴보기 바랍니다.

mp04_Show1_mp3.zip






4.2 동영상 플레이


게임에서는 시작화면이나 게임 중간 이벤트의 연출을 위해 동영상을 이용하는 경우가
있습니다. Direct Show를 사용하면 쉽게 처리할 수 있는데 디쇼는 단순하게 동영상을
재생하는 것이 아니라 실시간 텍스처에 재생할 수 있는 기능을 제공하고 있습니다.
따라서 게임 프로그래머는 디쇼에서 만든 실시간 텍스처를 이용해서 3차원 폴리곤에
입힐 수 있어서 재미있는 화면을 만들어 낼 수도 있습니다.
다음 예제는 CMcDShow 클래스 내부에서 디쇼를 구현하고 이 클래스의 인스턴스를 이용해서
디쇼가 만든 텍스처를 2D 스프라이트에 렌더링 예제입니다.

mp04_Show2_av.zip






4.3 MCI


뮤직, 사운드, 디쇼, 이외에 Microsoft의 Media Control Interface(MCI)를 이용한 방법도
있습니다. 이 것은 사용하기 편리하지만 정교한 제어는 사운드나 뮤직을 따라갈 수는
없습니다. 하지만 간단하게 배경 음악 정도를 출력한다면 사용해도 괜찮아 보입니다.

MCI는 mciSendCommand() 함수를 통해서 미디어에 대한 생성, 재생, 멈춤 등 모든 제어가
가능하다고 봐도 됩니다. 사용에 대한 내용이 그리 어렵이 않아 다음 예제를 참고해도
충분합니다.

mp05_mci.zip


Sp05_puzzle_complete.zip

Copyright (c) 2004 3dapi.com All rights reserved.

Creative Commons License