mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Simplify manual sound rolloff handling
This commit is contained in:
parent
93f023db80
commit
51adcd45e6
1 changed files with 33 additions and 62 deletions
|
@ -1304,7 +1304,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
if(AL.EXT_source_distance_model)
|
if(AL.EXT_source_distance_model)
|
||||||
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, rolloff->MinDistance/distscale);
|
alSourcef(source, AL_REFERENCE_DISTANCE, rolloff->MinDistance/distscale);
|
||||||
alSourcef(source, AL_MAX_DISTANCE, (1000.f+rolloff->MinDistance)/distscale);
|
alSourcef(source, AL_MAX_DISTANCE, std::numeric_limits<float>::max());
|
||||||
alSourcef(source, AL_ROLLOFF_FACTOR, rolloff->RolloffFactor);
|
alSourcef(source, AL_ROLLOFF_FACTOR, rolloff->RolloffFactor);
|
||||||
manualRolloff = false;
|
manualRolloff = false;
|
||||||
}
|
}
|
||||||
|
@ -1324,62 +1324,33 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
// when AL_EXT_source_distance_model is not supported, we have to play
|
// when AL_EXT_source_distance_model is not supported, we have to play
|
||||||
// around a bit to get appropriate distance attenation. What we do is
|
// around a bit to get appropriate distance attenation. What we do is
|
||||||
// calculate the attenuation that should be applied, then given an
|
// calculate the attenuation that should be applied, then given an
|
||||||
// Inverse Distance rolloff model with OpenAL, reverse the calculation
|
// Inverse Distance rolloff model with OpenAL, calculate the reference
|
||||||
// to get the distance needed for that much attenuation. The Inverse
|
// distance that will achieve that much attenuation with the current
|
||||||
// Distance calculation is:
|
// distance. The Inverse Distance calculation is:
|
||||||
//
|
//
|
||||||
// Gain = MinDist / (MinDist + RolloffFactor*(Distance - MinDist))
|
// Gain = MinDist / (MinDist + RolloffFactor*(Distance - MinDist))
|
||||||
//
|
//
|
||||||
// Thus, the reverse is:
|
// Simplifying for RolloffFactor=1, it can be broken down by:
|
||||||
//
|
//
|
||||||
// Distance = (MinDist/Gain - MinDist)/RolloffFactor + MinDist
|
// Gain = MinDist / (MinDist + (Distance - MinDist))
|
||||||
|
// Gain = MinDist / Distance
|
||||||
|
// Gain * Distance = MinDist
|
||||||
//
|
//
|
||||||
// This can be simplified by using a MinDist and RolloffFactor of 1,
|
// The source's reference distance is then set according to the desired
|
||||||
// which makes it:
|
// gain and effective distance from the listener, and OpenAL takes care
|
||||||
//
|
// of the rest.
|
||||||
// Distance = 1.0f/Gain;
|
|
||||||
//
|
|
||||||
// The source position is then set that many units away from the
|
|
||||||
// listener position, and OpenAL takes care of the rest.
|
|
||||||
if(AL.EXT_source_distance_model)
|
if(AL.EXT_source_distance_model)
|
||||||
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, 1.f);
|
|
||||||
alSourcef(source, AL_MAX_DISTANCE, 100000.f);
|
float dist = sqrtf(dist_sqr);
|
||||||
|
float gain = GetRolloff(rolloff, dist * distscale);
|
||||||
|
// Don't let the ref distance go to 0, or else distance attenuation is
|
||||||
|
// lost with the inverse distance model.
|
||||||
|
alSourcef(source, AL_REFERENCE_DISTANCE, std::max<float>(gain*dist, 0.0004f));
|
||||||
|
alSourcef(source, AL_MAX_DISTANCE, std::numeric_limits<float>::max());
|
||||||
alSourcef(source, AL_ROLLOFF_FACTOR, 1.f);
|
alSourcef(source, AL_ROLLOFF_FACTOR, 1.f);
|
||||||
|
|
||||||
if(AL.EXT_SOURCE_RADIUS)
|
|
||||||
{
|
|
||||||
/* Since the OpenAL distance is decoupled from the sound's distance, get the OpenAL
|
|
||||||
* distance that corresponds to the area radius. */
|
|
||||||
float gain = GetRolloff(rolloff, AREA_SOUND_RADIUS);
|
|
||||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ?
|
|
||||||
// Clamp in case the max distance is <= the area radius
|
|
||||||
((gain > 0.00001f) ? 1.f/gain : 100000.f) : 0.f
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dist_sqr < (0.0004f*0.0004f))
|
|
||||||
{
|
|
||||||
// Head relative
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
|
||||||
alSource3f(source, AL_POSITION, 0.f, 0.f, 0.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
|
|
||||||
FVector3 dir = pos - listener->position;
|
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
|
||||||
dir += listener->position;
|
|
||||||
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(AL.EXT_SOURCE_RADIUS)
|
|
||||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
|
||||||
|
|
||||||
if(dist_sqr < (0.0004f*0.0004f))
|
if(dist_sqr < (0.0004f*0.0004f))
|
||||||
{
|
{
|
||||||
// Head relative
|
// Head relative
|
||||||
|
@ -1391,10 +1362,11 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||||
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
||||||
alSourcef(source, AL_DOPPLER_FACTOR, 0.f);
|
alSourcef(source, AL_DOPPLER_FACTOR, 0.f);
|
||||||
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
|
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
||||||
|
|
||||||
alSourcei(source, AL_LOOPING, (chanflags&SNDF_LOOP) ? AL_TRUE : AL_FALSE);
|
alSourcei(source, AL_LOOPING, (chanflags&SNDF_LOOP) ? AL_TRUE : AL_FALSE);
|
||||||
|
|
||||||
|
@ -1633,8 +1605,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
if(chan == NULL || chan->SysChannel == NULL)
|
if(chan == NULL || chan->SysChannel == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FVector3 dir = pos - listener->position;
|
float dist_sqr = (float)(pos - listener->position).LengthSquared();
|
||||||
float dist_sqr = (float)dir.LengthSquared();
|
|
||||||
chan->DistanceSqr = dist_sqr;
|
chan->DistanceSqr = dist_sqr;
|
||||||
|
|
||||||
alDeferUpdatesSOFT();
|
alDeferUpdatesSOFT();
|
||||||
|
@ -1649,13 +1620,13 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
{
|
{
|
||||||
if(chan->ManualRolloff)
|
if(chan->ManualRolloff)
|
||||||
{
|
{
|
||||||
float gain = GetRolloff(&chan->Rolloff, sqrtf(dist_sqr)*chan->DistanceScale);
|
float dist = sqrtf(dist_sqr);
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
float gain = GetRolloff(&chan->Rolloff, dist * chan->DistanceScale);
|
||||||
|
alSourcef(source, AL_REFERENCE_DISTANCE, std::max<float>(gain*dist, 0.0004f));
|
||||||
}
|
}
|
||||||
dir += listener->position;
|
|
||||||
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
||||||
}
|
}
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
getALError();
|
getALError();
|
||||||
|
|
Loading…
Reference in a new issue