16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-20 05:39:18 +02:00

use openal-soft extensions to pause sounds and defer updates

This commit is contained in:
milek7
2017-08-25 22:02:31 +02:00
parent 9d91b19841
commit 83c0f4b8e2
4 changed files with 76 additions and 35 deletions

View File

@@ -41,6 +41,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#pragma comment (lib, "dbghelp.lib")
#pragma comment (lib, "version.lib")
std::unique_ptr<sound_manager> sound_man;
TWorld World;
namespace input {
@@ -346,11 +347,7 @@ int main(int argc, char *argv[])
|| (false == UILayer.init(window)))
return -1;
if (!(sound_man = new sound_manager()))
{
ErrorLog("Sound subsystem setup failed");
return -1;
}
sound_man = std::make_unique<sound_manager>();
input::Keyboard.init();
input::Mouse.init();
@@ -415,9 +412,6 @@ int main(int argc, char *argv[])
#endif
}
//m7todo: restore
//delete sound_man;
TPythonInterpreter::killInstance();
#ifdef _WIN32
delete pConsole;

View File

@@ -1108,6 +1108,18 @@ bool TWorld::Update()
Ground.Update_Lights();
{
glm::dmat4 cam_matrix;
Camera.SetMatrix(cam_matrix);
glm::vec3 pos(Camera.Pos.x, Camera.Pos.y, Camera.Pos.z);
glm::vec3 at = glm::vec3(0.0, 0.0, -1.0) * glm::mat3(cam_matrix);
glm::vec3 up = glm::vec3(0.0, 1.0, 0.0) * glm::mat3(cam_matrix);
sound_man->set_listener(pos, at, up);
sound_man->update(dt);
}
// render time routines follow:
dt = Timer::GetDeltaRenderTime(); // nie uwzględnia pauzowania ani mnożenia czasu
@@ -1138,18 +1150,6 @@ bool TWorld::Update()
Update_Camera( dt );
{
glm::dmat4 cam_matrix;
Camera.SetMatrix(cam_matrix);
glm::vec3 pos(Camera.Pos.x, Camera.Pos.y, Camera.Pos.z);
glm::vec3 at = glm::vec3(0.0, 0.0, -1.0) * glm::mat3(cam_matrix);
glm::vec3 up = glm::vec3(0.0, 1.0, 0.0) * glm::mat3(cam_matrix);
sound_man->set_listener(pos, at, up);
sound_man->update(dt);
}
GfxRenderer.Update( dt );
ResourceSweep();

View File

@@ -18,6 +18,10 @@ load_error::load_error(std::string const &f) : std::runtime_error("sound: cannot
sound_manager::sound_manager()
{
if (created)
throw std::runtime_error("sound_manager can be instantinated only once");
created = true;
dev = alcOpenDevice(0);
if (!dev)
throw std::runtime_error("sound: cannot open device");
@@ -35,6 +39,22 @@ sound_manager::sound_manager()
if (!alcMakeContextCurrent(ctx))
throw std::runtime_error("sound: cannot select context");
if (alIsExtensionPresent("AL_SOFT_deferred_updates"))
{
alDeferUpdatesSOFT = (void(*)())alGetProcAddress("alDeferUpdatesSOFT");
alProcessUpdatesSOFT = (void(*)())alGetProcAddress("alProcessUpdatesSOFT");
}
if (!alDeferUpdatesSOFT || !alProcessUpdatesSOFT)
WriteLog("sound: warning: extension AL_SOFT_deferred_updates not found");
if (alcIsExtensionPresent(dev, "ALC_SOFT_pause_device"))
{
alcDevicePauseSOFT = (void(*)(ALCdevice*))alcGetProcAddress(dev, "alcDevicePauseSOFT");
alcDeviceResumeSOFT = (void(*)(ALCdevice*))alcGetProcAddress(dev, "alcDeviceResumeSOFT");
}
if (!alcDevicePauseSOFT || !alcDeviceResumeSOFT)
WriteLog("sound: warning: extension ALC_SOFT_pause_device not found");
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
alGetError();
@@ -45,6 +65,8 @@ sound_manager::~sound_manager()
alcMakeContextCurrent(0);
alcDestroyContext(ctx);
alcCloseDevice(dev);
created = false;
}
sound_buffer* sound_manager::find_buffer(std::string name)
@@ -198,25 +220,43 @@ void sound_manager::update(float dt)
throw std::runtime_error("sound: al error: " + errname);
}
auto now = std::chrono::steady_clock::now();
auto it = buffers.begin();
while (it != buffers.end())
if (dt > 0.0f)
{
if (now - it->second->unused_since() > gc_time)
if (alcDeviceResumeSOFT)
alcDeviceResumeSOFT(dev);
auto now = std::chrono::steady_clock::now();
auto it = buffers.begin();
while (it != buffers.end())
{
delete it->second;
it = buffers.erase(it);
if (now - it->second->unused_since() > gc_time)
{
delete it->second;
it = buffers.erase(it);
}
else
it++;
}
else
it++;
glm::vec3 velocity = (pos - last_pos) / dt;
alListenerfv(AL_VELOCITY, glm::value_ptr(velocity));
last_pos = pos;
for (auto &s : sounds)
s->update(dt);
}
else
{
if (alcDevicePauseSOFT)
alcDevicePauseSOFT(dev);
}
glm::vec3 velocity = (pos - last_pos) / dt;
alListenerfv(AL_VELOCITY, glm::value_ptr(velocity));
last_pos = pos;
for (auto &s : sounds)
s->update(dt);
if (alProcessUpdatesSOFT)
{
alProcessUpdatesSOFT();
alDeferUpdatesSOFT();
}
}
void sound_manager::set_listener(glm::vec3 const &p, glm::vec3 const &at, glm::vec3 const &up)
@@ -613,4 +653,4 @@ std::chrono::time_point<std::chrono::steady_clock> sound_buffer::unused_since()
return last_unref;
}
sound_manager* sound_man;
bool sound_manager::created = false;

View File

@@ -134,9 +134,16 @@ public:
class sound_manager
{
static bool created;
ALCdevice *dev;
ALCcontext *ctx;
void (*alDeferUpdatesSOFT)() = nullptr;
void (*alProcessUpdatesSOFT)() = nullptr;
void (*alcDevicePauseSOFT)(ALCdevice*) = nullptr;
void (*alcDeviceResumeSOFT)(ALCdevice*) = nullptr;
const std::chrono::duration<float> gc_time = std::chrono::duration<float>(60.0f);
std::unordered_map<std::string, sound_buffer*> buffers;
std::unordered_set<sound*> sounds;
@@ -163,4 +170,4 @@ public:
void set_listener(Math3D::vector3 const &pos, Math3D::vector3 const &at, Math3D::vector3 const &up);
};
extern sound_manager* sound_man;
extern std::unique_ptr<sound_manager> sound_man;