mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Implement a basic underwater sound environment
This commit is contained in:
parent
575474ff69
commit
cbf6c0404a
5 changed files with 72 additions and 14 deletions
|
@ -260,7 +260,16 @@ bool OpenAL_SoundStream::isPlaying()
|
||||||
|
|
||||||
void OpenAL_SoundStream::update()
|
void OpenAL_SoundStream::update()
|
||||||
{
|
{
|
||||||
alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume);
|
ALfloat gain = mVolume*mBaseVolume;
|
||||||
|
ALfloat pitch = 1.0f;
|
||||||
|
if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
|
||||||
|
{
|
||||||
|
gain *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
alSourcef(mSource, AL_GAIN, gain);
|
||||||
|
alSourcef(mSource, AL_PITCH, pitch);
|
||||||
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
||||||
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||||
|
@ -388,7 +397,16 @@ bool OpenAL_Sound::isPlaying()
|
||||||
|
|
||||||
void OpenAL_Sound::update()
|
void OpenAL_Sound::update()
|
||||||
{
|
{
|
||||||
alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume);
|
ALfloat gain = mVolume*mBaseVolume;
|
||||||
|
ALfloat pitch = 1.0f;
|
||||||
|
if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
|
||||||
|
{
|
||||||
|
gain *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
alSourcef(mSource, AL_GAIN, gain);
|
||||||
|
alSourcef(mSource, AL_PITCH, pitch);
|
||||||
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
||||||
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||||
|
@ -397,10 +415,18 @@ void OpenAL_Sound::update()
|
||||||
|
|
||||||
void OpenAL_Sound3D::update()
|
void OpenAL_Sound3D::update()
|
||||||
{
|
{
|
||||||
|
ALfloat gain = mVolume*mBaseVolume;
|
||||||
|
ALfloat pitch = 1.0f;
|
||||||
if(mPos.squaredDistance(mOutput.mPos) > mMaxDistance*mMaxDistance)
|
if(mPos.squaredDistance(mOutput.mPos) > mMaxDistance*mMaxDistance)
|
||||||
alSourcef(mSource, AL_GAIN, 0.0f);
|
gain = 0.0f;
|
||||||
else
|
else if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
|
||||||
alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume);
|
{
|
||||||
|
gain *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
alSourcef(mSource, AL_GAIN, gain);
|
||||||
|
alSourcef(mSource, AL_PITCH, pitch);
|
||||||
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]);
|
||||||
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||||
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||||
|
@ -638,6 +664,11 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float
|
||||||
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
|
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
|
||||||
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
|
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
|
||||||
|
|
||||||
|
if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater)
|
||||||
|
{
|
||||||
|
volume *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
alSourcef(src, AL_GAIN, volume);
|
alSourcef(src, AL_GAIN, volume);
|
||||||
alSourcef(src, AL_PITCH, pitch);
|
alSourcef(src, AL_PITCH, pitch);
|
||||||
|
|
||||||
|
@ -685,6 +716,11 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector
|
||||||
alSourcef(src, AL_MAX_DISTANCE, max);
|
alSourcef(src, AL_MAX_DISTANCE, max);
|
||||||
alSourcef(src, AL_ROLLOFF_FACTOR, 1.0f);
|
alSourcef(src, AL_ROLLOFF_FACTOR, 1.0f);
|
||||||
|
|
||||||
|
if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater)
|
||||||
|
{
|
||||||
|
volume *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
alSourcef(src, AL_GAIN, (pos.squaredDistance(mPos) > max*max) ?
|
alSourcef(src, AL_GAIN, (pos.squaredDistance(mPos) > max*max) ?
|
||||||
0.0f : volume);
|
0.0f : volume);
|
||||||
alSourcef(src, AL_PITCH, pitch);
|
alSourcef(src, AL_PITCH, pitch);
|
||||||
|
@ -701,7 +737,7 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch)
|
SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch, int flags)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<OpenAL_SoundStream> sound;
|
boost::shared_ptr<OpenAL_SoundStream> sound;
|
||||||
ALuint src;
|
ALuint src;
|
||||||
|
@ -713,6 +749,8 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if((flags&Play_Loop))
|
||||||
|
std::cout <<"Warning: cannot loop stream "<<fname<< std::endl;
|
||||||
DecoderPtr decoder = mManager.getDecoder();
|
DecoderPtr decoder = mManager.getDecoder();
|
||||||
decoder->open(fname);
|
decoder->open(fname);
|
||||||
sound.reset(new OpenAL_SoundStream(*this, src, decoder));
|
sound.reset(new OpenAL_SoundStream(*this, src, decoder));
|
||||||
|
@ -731,6 +769,11 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa
|
||||||
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
|
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
|
||||||
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
|
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
|
||||||
|
|
||||||
|
if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater)
|
||||||
|
{
|
||||||
|
volume *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
alSourcef(src, AL_GAIN, volume);
|
alSourcef(src, AL_GAIN, volume);
|
||||||
alSourcef(src, AL_PITCH, pitch);
|
alSourcef(src, AL_PITCH, pitch);
|
||||||
|
|
||||||
|
@ -743,9 +786,10 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir)
|
void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env)
|
||||||
{
|
{
|
||||||
mPos = pos;
|
mPos = pos;
|
||||||
|
mLastEnvironment = env;
|
||||||
|
|
||||||
if(mContext)
|
if(mContext)
|
||||||
{
|
{
|
||||||
|
@ -762,7 +806,7 @@ void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3
|
||||||
|
|
||||||
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
||||||
: Sound_Output(mgr), mDevice(0), mContext(0), mBufferCacheMemSize(0),
|
: Sound_Output(mgr), mDevice(0), mContext(0), mBufferCacheMemSize(0),
|
||||||
mStreamThread(new StreamThread)
|
mLastEnvironment(Env_Normal), mStreamThread(new StreamThread)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace MWSound
|
||||||
ALuint getBuffer(const std::string &fname);
|
ALuint getBuffer(const std::string &fname);
|
||||||
void bufferFinished(ALuint buffer);
|
void bufferFinished(ALuint buffer);
|
||||||
|
|
||||||
|
Environment mLastEnvironment;
|
||||||
|
|
||||||
virtual std::vector<std::string> enumerate();
|
virtual std::vector<std::string> enumerate();
|
||||||
virtual void init(const std::string &devname="");
|
virtual void init(const std::string &devname="");
|
||||||
virtual void deinit();
|
virtual void deinit();
|
||||||
|
@ -43,9 +45,9 @@ namespace MWSound
|
||||||
virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags);
|
virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags);
|
||||||
virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
|
virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
|
||||||
float volume, float pitch, float min, float max, int flags);
|
float volume, float pitch, float min, float max, int flags);
|
||||||
virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch);
|
virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags);
|
||||||
|
|
||||||
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir);
|
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env);
|
||||||
|
|
||||||
OpenAL_Output& operator=(const OpenAL_Output &rhs);
|
OpenAL_Output& operator=(const OpenAL_Output &rhs);
|
||||||
OpenAL_Output(const OpenAL_Output &rhs);
|
OpenAL_Output(const OpenAL_Output &rhs);
|
||||||
|
|
|
@ -27,9 +27,9 @@ namespace MWSound
|
||||||
virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0;
|
virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0;
|
||||||
virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
|
virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
|
||||||
float volume, float pitch, float min, float max, int flags) = 0;
|
float volume, float pitch, float min, float max, int flags) = 0;
|
||||||
virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch) = 0;
|
virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags) = 0;
|
||||||
|
|
||||||
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir) = 0;
|
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0;
|
||||||
|
|
||||||
Sound_Output& operator=(const Sound_Output &rhs);
|
Sound_Output& operator=(const Sound_Output &rhs);
|
||||||
Sound_Output(const Sound_Output &rhs);
|
Sound_Output(const Sound_Output &rhs);
|
||||||
|
|
|
@ -137,8 +137,9 @@ namespace MWSound
|
||||||
{
|
{
|
||||||
if(mMusic)
|
if(mMusic)
|
||||||
mMusic->stop();
|
mMusic->stop();
|
||||||
mMusic = mOutput->streamSound(filename, 0.4f, 1.0f);
|
mMusic = mOutput->streamSound(filename, 0.4f, 1.0f, Play_NoEnv);
|
||||||
mMusic->mBaseVolume = 0.4f;
|
mMusic->mBaseVolume = 0.4f;
|
||||||
|
mMusic->mFlags = Play_NoEnv;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
|
@ -408,19 +409,25 @@ namespace MWSound
|
||||||
if(!isMusicPlaying())
|
if(!isMusicPlaying())
|
||||||
startRandomTitle();
|
startRandomTitle();
|
||||||
|
|
||||||
|
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
||||||
Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera();
|
Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera();
|
||||||
Ogre::Vector3 nPos, nDir, nUp;
|
Ogre::Vector3 nPos, nDir, nUp;
|
||||||
nPos = cam->getRealPosition();
|
nPos = cam->getRealPosition();
|
||||||
nDir = cam->getRealDirection();
|
nDir = cam->getRealDirection();
|
||||||
nUp = cam->getRealUp();
|
nUp = cam->getRealUp();
|
||||||
|
|
||||||
|
Environment env = Env_Normal;
|
||||||
|
if(nPos.y < current->cell->water)
|
||||||
|
env = Env_Underwater;
|
||||||
|
|
||||||
// The output handler is expecting vectors oriented like the game
|
// The output handler is expecting vectors oriented like the game
|
||||||
// (that is, -Z goes down, +Y goes forward), but that's not what we
|
// (that is, -Z goes down, +Y goes forward), but that's not what we
|
||||||
// get from Ogre's camera, so we have to convert.
|
// get from Ogre's camera, so we have to convert.
|
||||||
const Ogre::Vector3 pos(nPos[0], -nPos[2], nPos[1]);
|
const Ogre::Vector3 pos(nPos[0], -nPos[2], nPos[1]);
|
||||||
const Ogre::Vector3 at(nDir[0], -nDir[2], nDir[1]);
|
const Ogre::Vector3 at(nDir[0], -nDir[2], nDir[1]);
|
||||||
const Ogre::Vector3 up(nUp[0], -nUp[2], nUp[1]);
|
const Ogre::Vector3 up(nUp[0], -nUp[2], nUp[1]);
|
||||||
mOutput->updateListener(pos, at, up);
|
|
||||||
|
mOutput->updateListener(pos, at, up, env);
|
||||||
|
|
||||||
// Check if any sounds are finished playing, and trash them
|
// Check if any sounds are finished playing, and trash them
|
||||||
SoundMap::iterator snditer = mActiveSounds.begin();
|
SoundMap::iterator snditer = mActiveSounds.begin();
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace MWSound
|
||||||
static inline int operator&(const PlayMode &a, const PlayMode &b)
|
static inline int operator&(const PlayMode &a, const PlayMode &b)
|
||||||
{ return (int)a & (int)b; }
|
{ return (int)a & (int)b; }
|
||||||
|
|
||||||
|
enum Environment {
|
||||||
|
Env_Normal,
|
||||||
|
Env_Underwater,
|
||||||
|
};
|
||||||
|
|
||||||
class SoundManager
|
class SoundManager
|
||||||
{
|
{
|
||||||
Ogre::ResourceGroupManager& mResourceMgr;
|
Ogre::ResourceGroupManager& mResourceMgr;
|
||||||
|
|
Loading…
Reference in a new issue