From 4c99970b9d50a860829012aec212fb79d6e1accc Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 12 Sep 2017 04:00:01 +0300 Subject: [PATCH] #23 optimize reverberation effect; #22 fix sprites ambient lighting --- src/level.h | 10 +++-- src/platform/web/index.html | 2 +- src/sound.h | 90 +++++++++++++++++++++---------------- src/sprite.h | 7 --- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/level.h b/src/level.h index 578ae31..36802c4 100644 --- a/src/level.h +++ b/src/level.h @@ -195,7 +195,7 @@ struct Level : IGame { if (!stream) return; Level *level = (Level*)userData; - level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, 0); + level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, Sound::MUSIC); if (level->sndSoundtrack) level->sndSoundtrack->setVolume(1.0f, 0.2f); } @@ -385,7 +385,7 @@ struct Level : IGame { // init sounds //sndSoundtrack = Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), vec3(0.0f), 1, 1, Sound::Flags::LOOP); - sndUnderwater = lara->playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP); + sndUnderwater = lara->playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC); if (sndUnderwater) sndUnderwater->volume = sndUnderwater->volumeTarget = 0.0f; @@ -790,7 +790,11 @@ struct Level : IGame { if (entity.type == TR::Entity::CRYSTAL) type = Shader::MIRROR; - setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true); + if (type == Shader::SPRITE) { + float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0f; + setRoomParams(roomIndex, type, 0.5f, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true); + } else + setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true); if (isModel) { // model vec3 pos = controller->getPos(); diff --git a/src/platform/web/index.html b/src/platform/web/index.html index 72acbe7..e0d0410 100644 --- a/src/platform/web/index.html +++ b/src/platform/web/index.html @@ -107,7 +107,7 @@ (.PHD, .PSX)

OpenLara on github & facebook
-
last update: 11.09.2017
+
last update: 12.09.2017

diff --git a/src/sound.h b/src/sound.h index c05bf2c..5994d1f 100644 --- a/src/sound.h +++ b/src/sound.h @@ -28,11 +28,15 @@ namespace Sound { short L, R; }; - namespace Filter { - #define MAX_FDN 32 - #define MAX_DELAY 2048 + struct FrameHI { + int L, R; + }; - static const short FDN[MAX_FDN] = {281,331,373,419,461,503,547,593,641,683,727,769,811,853,907,953,997,1039,1087,1129,1171,1213,1259,1301,1361,1409,1451,1493,1543,1597,1657,1699}; + namespace Filter { + #define MAX_FDN 16 + #define MAX_DELAY 1024 + + static const short FDN[MAX_FDN] = {281,331,373,419,461,503,547,593,641,683,727,769,811,853,907,953}; struct Delay { int index; @@ -82,7 +86,7 @@ namespace Sound { void setRoomSize(const vec3 &size) { float S = (size.x * size.z + size.x * size.y + size.z * size.y) * 2; float V = size.x * size.y * size.z; - float f = 0.07f; // brick absorption + float f = 0.1f; // absorption factor float rt60 = 0.161f * (V / (S * f)); float k = -10.0f / (44100.0f * rt60); @@ -92,22 +96,23 @@ namespace Sound { } }; - void process(Frame *frames, int count) { + void process(FrameHI *frames, int count) { float buffer[MAX_FDN]; for (int i = 0; i < count; i++) { - Frame &frame = frames[i]; - float L = float(frame.L); - float R = float(frame.R); + FrameHI &frame = frames[i]; + float L = frame.L * (1.0f / 32768.0f); + float R = frame.R * (1.0f / 32768.0f); float in = (L + R) * 0.5f; float out = 0.0f; // apply delay & absorption filters for (int j = 0; j < MAX_FDN; j++) { - buffer[j] = in + output[j]; - buffer[j] = df[j].process(buffer[j], FDN[j]); - buffer[j] = af[j].process(buffer[j], absCoeff[j][0], absCoeff[j][1]); - out += buffer[j] * (2.0f / MAX_FDN); + float k = in + output[j]; + k = df[j].process(k, FDN[j]); + k = af[j].process(k, absCoeff[j][0], absCoeff[j][1]); + out += k * (2.0f / MAX_FDN); + buffer[j] = k; } // apply pan @@ -117,8 +122,8 @@ namespace Sound { R += buffer[j] * panCoeff[j][1]; } - frame.L = clamp(int(L), -32768, 32767); - frame.R = clamp(int(R), -32768, 32767); + frame.L = int(L * 32768.0f); + frame.R = int(R * 32768.0f); } } }; @@ -400,7 +405,6 @@ namespace Sound { struct Listener { mat4 matrix; - // vec3 velocity; } listener; enum Flags { @@ -410,12 +414,12 @@ namespace Sound { REPLAY = 8, SYNC = 16, STATIC = 32, + MUSIC = 64, }; struct Sample { Decoder *decoder; vec3 pos; - vec3 velocity; float volume; float volumeTarget; float volumeDelta; @@ -560,11 +564,15 @@ namespace Sound { typedef void (Callback)(Sample *channel); Callback *callback; + FrameHI *result; + Frame *buffer; Filter::Reverberation reverb; void init() { channelsCount = 0; callback = NULL; + buffer = NULL; + result = NULL; #ifdef DECODE_MP3 mp3_decode_init(); #endif @@ -576,27 +584,18 @@ namespace Sound { #ifdef DECODE_MP3 mp3_decode_free(); #endif + delete[] buffer; + delete[] result; } - void fill(Frame *frames, int count) { - if (!channelsCount) { - memset(frames, 0, sizeof(frames[0]) * count); - if (Core::settings.audio.reverb) - reverb.process(frames, count); - return; - } - - struct FrameHI { - int L, R; - }; - - FrameHI *result = new FrameHI[count]; - memset(result, 0, sizeof(FrameHI) * count); - + void renderChannels(FrameHI *result, int count, bool music) { int bufSize = count + count / 2; - Frame *buffer = new Frame[bufSize]; // + 50% for pitch + if (!buffer) buffer = new Frame[bufSize]; // + 50% for pitch for (int i = 0; i < channelsCount; i++) { + if (music != ((channels[i]->flags & MUSIC) != 0)) + continue; + if (channels[i]->flags & STATIC) { vec3 d = channels[i]->pos - listener.matrix.getPos(); if (fabsf(d.x) > SND_FADEOFF_DIST || fabsf(d.y) > SND_FADEOFF_DIST || fabsf(d.z) > SND_FADEOFF_DIST) @@ -625,18 +624,31 @@ namespace Sound { } } } + } + + void fill(Frame *frames, int count) { + if (!channelsCount) { + memset(frames, 0, sizeof(frames[0]) * count); + //if (Core::settings.audio.reverb) + // reverb.process(frames, count); + return; + } + + if (!result) result = new FrameHI[count]; + memset(result, 0, sizeof(FrameHI) * count); + + renderChannels(result, count, false); + + if (Core::settings.audio.reverb) + reverb.process(result, count); + + renderChannels(result, count, true); for (int i = 0; i < count; i++) { frames[i].L = clamp(result[i].L, -32768, 32767); frames[i].R = clamp(result[i].R, -32768, 32767); } - if (Core::settings.audio.reverb) - reverb.process(frames, count); - - delete[] buffer; - delete[] result; - for (int i = 0; i < channelsCount; i++) if (!channels[i]->isPlaying) { if (callback) callback(channels[i]); diff --git a/src/sprite.h b/src/sprite.h index 6b554c8..9b8b0fc 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -68,13 +68,6 @@ struct Sprite : Controller { virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) { Core::setBlending(bmAlpha); - - TR::Entity::Type eType = getEntity().type; - if (eType == TR::Entity::SMOKE || eType == TR::Entity::WATER_SPLASH) - Core::active.shader->setParam(uMaterial, vec4(0.5f, 1.0f, 0.0f, 0.75f)); - else - Core::active.shader->setParam(uMaterial, vec4(0.5f, 1.0f, 0.0f, 1.0f)); - Core::active.shader->setParam(uBasis, Basis(Core::mViewInv.getRot(), pos)); mesh->renderSprite(-(getEntity().modelIndex + 1), frame); Core::setBlending(bmNone);