读书人

关于 FMOD 在 Ogre 中的使用!(急)解

发布时间: 2012-02-14 19:19:19 作者: rapoo

关于 FMOD 在 Ogre 中的使用!(急)
我的意图是要在 space 中建立一个固定的点声源,根据听众与该声源相对位置的不同,传到听众耳朵里的声音也会不同!(比如,听众在点声源的右侧,则左耳的声音比较强;听众离点声源越远,听到的声音越小)。
我参照 FMOD 里面那个3d的例子写了一个例子,只是有声音,但是没有上述效果,用的是Ogre里的SkyBox的那个demo
请哪位高手帮忙指点一下,或给我个小例子!
代码如下:
#include "../../api/inc/fmod.hpp"
#include "../../api/inc/fmod_errors.h"

#include "ExampleApplication.h"

ParticleSystem *pThrusters;

const int INTERFACE_UPDATETIME = 50; // 50ms update for interface
const float DISTANCEFACTOR = 1.0f;
FMOD::System *p_system;
FMOD_VECTOR lastpos = { 0.0f, 0.0f, 0.0f };
FMOD_VECTOR pos = { -10.0f * DISTANCEFACTOR, 0.0f, 0.0f };
FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f };
FMOD_VECTOR listenerpos = { 0.0f, 0.0f, -1.0f * DISTANCEFACTOR };
FMOD_VECTOR forward = { 0.0f, 0.0f, 1.0f };
FMOD_VECTOR up = { 0.0f, 1.0f, 0.0f };
FMOD::Sound *sound1, *sound2, *sound3;
FMOD::Channel *channel1 = 0, *channel2 = 0, *channel3 = 0;
FMOD_RESULT result;
int key, numdrivers;
bool listenerflag = true;
unsigned int version;
FMOD_SPEAKERMODE speakermode;
FMOD_CAPS caps;
char name[256];

class SkyBoxFrameListener : public ExampleFrameListener
{
private:
static float fDefDim;
static float fDefVel;

public:
SkyBoxFrameListener(RenderWindow* win, Camera* cam) : ExampleFrameListener( win, cam )
{
}

bool frameRenderingQueued( const FrameEvent& evt )
{
if( ExampleFrameListener::frameRenderingQueued( evt ) == false )
return false;

if( mKeyboard->isKeyDown( OIS::KC_N ) )
{
pThrusters->setDefaultDimensions( fDefDim + 0.25, fDefDim + 0.25 );
fDefDim += 0.25;
}

if( mKeyboard->isKeyDown( OIS::KC_M ) )
{
pThrusters->setDefaultDimensions( fDefDim - 0.25, fDefDim - 0.25 );
fDefDim -= 0.25;
}

if( mKeyboard->isKeyDown( OIS::KC_H ) )
{
pThrusters->getEmitter( 0 )->setParticleVelocity( fDefVel + 1 );
pThrusters->getEmitter( 1 )->setParticleVelocity( fDefVel + 1 );
fDefVel += 1;
}

if( mKeyboard->isKeyDown( OIS::KC_J ) && !( fDefVel < 0.0f ) )
{
pThrusters->getEmitter( 0 )->setParticleVelocity( fDefVel - 1 );
pThrusters->getEmitter( 1 )->setParticleVelocity( fDefVel - 1 );
fDefVel -= 1;
}

listenerpos.x = mCamera->getPosition().x;
listenerpos.y = mCamera->getPosition().y;
listenerpos.z = mCamera->getPosition().z;
vel.x = (listenerpos.x - lastpos.x)*1000;
vel.y = (listenerpos.x - lastpos.y)*1000;
vel.z = (listenerpos.x - lastpos.z)*1000;
lastpos = listenerpos;
result = p_system->set3DListenerAttributes(1, &listenerpos, &vel, &forward, &up);
p_system->update();

return true;
}
};

float SkyBoxFrameListener::fDefDim = 25.0f;
float SkyBoxFrameListener::fDefVel = 50.0f;

class SkyBoxApplication : public ExampleApplication
{
public:
SkyBoxApplication() {}

protected:
virtual void createFrameListener(void)
{
mFrameListener= new SkyBoxFrameListener(mWindow, mCamera);
mRoot->addFrameListener(mFrameListener);
}

void ERRCHECK(FMOD_RESULT result)


{
if (result != FMOD_OK)
{
printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
exit(-1);
}
}

// Just override the mandatory create scene method
void createScene(void)
{
// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

// Create a skybox
mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 50 );

// Create a light
Light* l = mSceneMgr->createLight("MainLight");
// Accept default settings: point light, white diffuse, just set position
// NB I could attach the light to a SceneNode if I wanted it to move automatically with
// other objects, but I don't
l->setPosition(20,80,50);

// Also add a nice starship in
Entity *ent = mSceneMgr->createEntity( "razor", "razor.mesh" );
mSceneMgr->getRootSceneNode()->attachObject( ent );

pThrusters = mSceneMgr->createParticleSystem( "ParticleSys1", 200 );

pThrusters ->setMaterialName( "Examples/Flare" );
pThrusters ->setDefaultDimensions( 25, 25 );

ParticleEmitter *pEmit1 = pThrusters ->addEmitter( "Point" );
ParticleEmitter *pEmit2 = pThrusters ->addEmitter( "Point" );

// Thruster 1
pEmit1->setAngle( Degree(3) );
pEmit1->setTimeToLive( 0.2 );
pEmit1->setEmissionRate( 70 );

pEmit1->setParticleVelocity( 50 );

pEmit1->setDirection(- Vector3::UNIT_Z);
pEmit1->setColour( ColourValue::White, ColourValue::Red);

// Thruster 2
pEmit2->setAngle( Degree(3) );
pEmit2->setTimeToLive( 0.2 );
pEmit2->setEmissionRate( 70 );

pEmit2->setParticleVelocity( 50 );

pEmit2->setDirection( -Vector3::UNIT_Z );
pEmit2->setColour( ColourValue::White, ColourValue::Red );

// Set the position of the thrusters
pEmit1->setPosition( Vector3( 5.7f, 0.0f, 0.0f ) );
pEmit2->setPosition( Vector3( -18.0f, 0.0f, 0.0f ) );

mSceneMgr->getRootSceneNode()->createChildSceneNode( Vector3( 0.0f, 6.5f, -67.0f ) )//飞机尾部火焰
->attachObject(pThrusters);

//------------------- 将声源与节点绑定 ---------------------


result = FMOD::System_Create(&p_system);
ERRCHECK(result);

result = p_system->getDriverCaps(0, &caps, 0, 0, &speakermode);
ERRCHECK(result);

result = p_system->setSpeakerMode(speakermode); /* Set the user selected speaker mode. */
ERRCHECK(result);

if (caps & FMOD_CAPS_HARDWARE_EMULATED) /* The user has the 'Acceleration' slider set to off! This is really bad for latency!. */
{ /* You might want to warn the user about this. */
result = p_system->setDSPBufferSize(1024, 10);
ERRCHECK(result);
}

if (strstr(name, "SigmaTel")) /* Sigmatel sound devices crackle for some reason if the format is PCM 16bit. PCM floating point output seems to solve it. */
{
result = p_system->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0,0, FMOD_DSP_RESAMPLER_LINEAR);
ERRCHECK(result);
}

result = p_system->init(100, FMOD_INIT_NORMAL, 0);


ERRCHECK(result);
if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) /* Ok, the speaker mode selected isn't supported by this soundcard. Switch it back to stereo... */
{
result = p_system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
ERRCHECK(result);

result = p_system->init(100, FMOD_INIT_NORMAL, 0);/* ... and re-init. */
ERRCHECK(result);
}
result = p_system->set3DSettings(1.0, DISTANCEFACTOR, 1.0f);//声音的传播参数,一般设成(1.0, 1.0, 1.0)
ERRCHECK(result);



result = p_system->createSound("d:\\swish.wav", FMOD_3D, 0, &sound1);
ERRCHECK(result);
result = sound1->set3DMinMaxDistance(0.5f * DISTANCEFACTOR, 5000.0f * DISTANCEFACTOR);
ERRCHECK(result);
result = sound1->setMode(FMOD_LOOP_NORMAL);
ERRCHECK(result);

{
result = p_system->playSound(FMOD_CHANNEL_FREE, sound1, true, &channel1);
ERRCHECK(result);

result = channel1->set3DAttributes(&pos, &vel);
ERRCHECK(result);
result = channel1->set3DSpread(90);
ERRCHECK(result);
result = channel1->setPaused(false);
ERRCHECK(result);
result = p_system->set3DListenerAttributes(1, &listenerpos, &vel, &forward, &up);
ERRCHECK(result);
p_system->update();
}
}

};

[解决办法]

C/C++ code
 p_system->init(100, FMOD_INIT_NORMAL, 0); p_system->init(100, FMOD_INIT_DSOUND_HRTFNONE, 0);
[解决办法]
探讨
C/C++ code
p_system->init(100, FMOD_INIT_NORMAL,0);
p_system->init(100, FMOD_INIT_DSOUND_HRTFNONE,0);

仔细查查头文件里的注释先!

读书人网 >网络游戏

热点推荐