Beginning Game Audio Programming [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Beginning Game Audio Programming [Electronic resources] - نسخه متنی

Mason McCuskey

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید





THE DEEP SPACE SAMPLE PROGRAM

For this chapter, I wanted to create a sample program that demonstrated sound in an actual 3D world. Sure, I could have just provided a console app, but that doesn't really show you how to integrate 3D sound into your game. To fully understand 3D sound, you need to see the code in its native habit—working hand-in-hand with the 3D graphics code to create a convincing reality.

So, I stole from myself. Ch13p1 is based on a sample program I created for my last book, Special Effects Game Programming Using DirectX 8.0. Readers of that book will recognize it as a slightly modified version of the Ch20p3_ComplexExplosion sample program of Chapter 20.

I'm not going to spend time explaining how the 3D graphics principles of this sample program work, but to properly understand what's going on in the sample, you should know about things like skyboxes, world transform matrices, and X file meshes. By the way, if you happen to need a good book on special effects, my book… wait, what's that? You're right! You didn't BUY MY BOOK to hear a sales pitch, much less be assaulted with subliminal advertising! Okay, never mind, I'll keep going.

Run the app, and you'll see something resembling that of Figure 13.4.


Figure 13.4: A screenshot of this chapter's sample program.

Essentially, you're in deep space, and you can move around freely in all directions. There's a spaceship in front of you that's emanating two 3D sounds: an engine sound (engine.wav) that loops continuously, and a beep sound (beep.wav) played periodically.

Use the W, A, S, and D keys to move forward, rotate left, move backward, and rotate right, respectively. The Q and Z keys will move you up and down, the B key will toggle the ship's beeping (it gets irritating), and the G key will toggle your warp drive (allowing you to move faster and more easily hear the Doppler effect).

If you fly around in this sample program, you can hear 3D sound in all its glory. For starters, notice that as you get closer to the ship, the sound volume increases, and that it pans and appears to really be coming from the spaceship. Notice also the Doppler effects; you should hear the spaceship's beep and engine sounds change pitch as you fly toward it, past it, and away from it.

The Ch13p1_3DSound sample program is based on the D3D sample application framework, which means all of the action occurs inside a CMyD3DApplication object. The various members of this object are called at the right times by the D3D sample application framework.


Loading the Sounds


In the OneTimeSceneInit method of CMyD3DApplication, there's some code to load the wave files off disk and set up their default behavior:


m_Beep = GetAudioManager()->Load3DSound("beep.wav");
m_Engine = GetAudioManager()->Load3DSound("engine.wav");
CDirectMusicSegment *engineseg =
dynamic_cast<CDirectMusicSegment *>(m_Engine.Get());
engineseg->SetRepeats(DMUS_SEG_REPEAT_INFINITE);
// set range on our engine and our beep
C3DSoundEffect *beep =
dynamic_cast<C3DSoundEffect *>(m_Beep.Get());
C3DSoundEffect *engine =
dynamic_cast<C3DSoundEffect *>(m_Engine.Get());
if (beep) {
beep->SetMaxDistance(100);
beep->SetMinDistance(10);
}
if (engine) {
engine->SetMaxDistance(80);
engine->SetMinDistance(10);
}
GetAudioManager()->Commit3DSoundParameters();

This chunk of code loads the two wave files into two 3D sound effects: m_Engine and m_Beep. It then sets some 3D sound parameters on both objects—notice that the code sets things up so that the engine sound effect goes away completely when you're 80 units away, but that the beep sticks around for another 20 units. Both sounds reach full intensity when you're within 10 units of the spaceship.

Notice also that the code casts m_Engine to a CDirectMusicSegment pointer, and then calls a new method, SetRepeats, to make the engine sound loop infinitely. SetRepeats is just a wrapper function for the IDirectMusicSegment method of the same name.

Once the parameters are set, the code tells the audio manager to commit them, and everything's ready for the game loop to be started.


Updating the Buffers and the Listener


Every frame, the positions of the buffer and the listener must be updated, along with some other properties. Here's that code, taken from the FrameMove method of CMyD3DApplication:


m_BeepTimer += m_fElapsedTime;
if (m_BeepActive && m_BeepTimer > BEEPINTERVAL) {
m_Beep->Play();
m_BeepTimer = 0;
}
// set beep position to spaceship position
C3DSoundEffect *beep = dynamic_cast<C3DSoundEffect *>(m_Beep.Get());
if (beep) {
D3DVECTOR v;
v.x = 0;
v.y = 4;
v.z = 0;
beep->SetPosition(v);
}
// set listener position to camera position
C3DSoundListener &listener = GetAudioManager()->GetListener();
listener.SetPosition(m_Camera.GetPosition());
// set listener orientation
D3DXVECTOR3 lookat = D3DXVECTOR3(
m_Camera.GetViewMatrix()._13,
m_Camera.GetViewMatrix()._23,
m_Camera.GetViewMatrix()._33);
D3DXVECTOR3 up = D3DXVECTOR3(
m_Camera.GetViewMatrix()._12,
m_Camera.GetViewMatrix()._22,
m_Camera.GetViewMatrix()._32);
D3DXVECTOR3 nlookat, nup;
D3DXVec3Normalize(&nlookat, &lookat);
D3DXVec3Normalize(&nup, &up);
if (nup == nlookat) { nup = D3DXVECTOR3(0,1,0); }
listener.SetOrient(nup, nlookat);
// set listener velocity based on previous frame position and
// current position
m_ListenerVelocity.x =
m_Camera.GetPosition().x - m_LastListenerPosition.x;

m_ListenerVelocity.y =
m_Camera.GetPosition().y - m_LastListenerPosition.y;
m_ListenerVelocity.z =
m_Camera.GetPosition().z - m_LastListenerPosition.z;
listener.SetVelocity(m_ListenerVelocity);
m_LastListenerPosition = m_Camera.GetPosition();
listener.SetDopplerFactor(DS3D_MAXDOPPLERFACTOR);
listener.SetDistanceFactor(10);
GetAudioManager()->Commit3DSoundParameters();

This code's doing a lot of tasks, but none of them are terribly complex. It starts by incrementing a timer value and determining if it's time to play the beep sound. Next, it moves the beep 3D sound buffer to the spaceship's current position (which is hard-coded at (0,4,0)). It does the same thing for the listener, and then turns its attention to setting the listener's orientation.

Fortunately, the camera class contains a view matrix, so it's a simple matter of extracting the up and lookat vectors, normalizing them, and then calling SetOrient to make them the up and front vectors of our listener. Next, the code calculates the listener's velocity by looking at the current camera position, and subtracting from that the position of the camera on the last frame.

Finally, there's some fudging. The code sets the Doppler factor to maximum, and scales the distance by a factor of 10, in order to make the Doppler effects stand out (so you can hear them). You should experiment with different values for these two factors to get a feel for how to create a particular aural environment for your own game.

The code finishes by committing all of the parameters it's changed. Nothing to it!

/ 127