From 078a2ab07b2217299b3bd5fb420cd2c0bde70e80 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 19 Dec 2024 00:58:48 +0100 Subject: [PATCH 01/26] Remove unsafe reference usage --- TombEngine/Game/Lara/lara_fire.cpp | 8 ++++---- TombEngine/Game/Lara/lara_fire.h | 2 +- TombEngine/Game/Lara/lara_one_gun.cpp | 4 ++-- TombEngine/Game/Lara/lara_two_guns.cpp | 2 +- TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp index f1f7d6efc..bbaeb03ff 100644 --- a/TombEngine/Game/Lara/lara_fire.cpp +++ b/TombEngine/Game/Lara/lara_fire.cpp @@ -837,7 +837,7 @@ void AimWeapon(ItemInfo& laraItem, ArmInfo& arm, const WeaponInfo& weaponInfo) } // TODO: Include snowmobile gun in GetAmmo(), otherwise the player won't be able to shoot while controlling it. -- TokyoSU 2023.04.21 -FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, ItemInfo& laraItem, const EulerAngles& armOrient) +FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo* targetEntity, ItemInfo& laraItem, const EulerAngles& armOrient) { auto& player = *GetLaraInfo(&laraItem); auto& ammo = GetAmmo(player, weaponType); @@ -872,14 +872,14 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite GetFloor(pos.x, pos.y, pos.z, &roomNumber); vOrigin.RoomNumber = roomNumber; - if (&targetEntity == nullptr) + if (targetEntity == nullptr) { auto vTarget = GameVector(target); GetTargetOnLOS(&vOrigin, &vTarget, false, true); return FireWeaponType::Miss; } - auto spheres = targetEntity.GetSpheres(); + auto spheres = targetEntity->GetSpheres(); int closestJointIndex = NO_VALUE; float closestDist = INFINITY; for (int i = 0; i < spheres.size(); i++) @@ -909,7 +909,7 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite // NOTE: It seems that entities hit by the player in the normal way must have GetTargetOnLOS return false. // It's strange, but this replicates original behaviour until we fully understand what is happening. if (!GetTargetOnLOS(&vOrigin, &vTarget, false, true)) - HitTarget(&laraItem, &targetEntity, &vTarget, weapon.Damage, false, closestJointIndex); + HitTarget(&laraItem, targetEntity, &vTarget, weapon.Damage, false, closestJointIndex); return FireWeaponType::PossibleHit; } diff --git a/TombEngine/Game/Lara/lara_fire.h b/TombEngine/Game/Lara/lara_fire.h index 51a6a1934..61822d8a5 100644 --- a/TombEngine/Game/Lara/lara_fire.h +++ b/TombEngine/Game/Lara/lara_fire.h @@ -61,7 +61,7 @@ GAME_OBJECT_ID GetWeaponObjectMeshID(ItemInfo& laraItem, LaraWeaponType weapon void HandleWeapon(ItemInfo& laraItem); void AimWeapon(ItemInfo& laraItem, ArmInfo& arm, const WeaponInfo& weaponInfo); -FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, ItemInfo& laraItem, const EulerAngles& armOrient); +FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo* targetEntity, ItemInfo& laraItem, const EulerAngles& armOrient); void FindNewTarget(ItemInfo& laraItem, const WeaponInfo& weaponInfo); void LaraTargetInfo(ItemInfo& laraItem, const WeaponInfo& weaponInfo); diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index b4a494ec3..9fb37faa9 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -395,7 +395,7 @@ void FireShotgun(ItemInfo& laraItem) armOrient.y + scatter * (GetRandomControl() - ANGLE(90.0f)) / 65536, 0); - if (FireWeapon(LaraWeaponType::Shotgun, *player.TargetEntity, laraItem, wobbledArmOrient) != FireWeaponType::NoAmmo) + if (FireWeapon(LaraWeaponType::Shotgun, player.TargetEntity, laraItem, wobbledArmOrient) != FireWeaponType::NoAmmo) hasFired = true; // HACK: Compensate for spending 6 units of shotgun ammo. -- Lwmte, 18.11.22 @@ -1152,7 +1152,7 @@ void FireHK(ItemInfo& laraItem, bool inaccurateMode) Weapons[(int)LaraWeaponType::HK].Damage = damage / 3; } - if (FireWeapon(LaraWeaponType::HK, *player.TargetEntity, laraItem, angles) != FireWeaponType::NoAmmo) + if (FireWeapon(LaraWeaponType::HK, player.TargetEntity, laraItem, angles) != FireWeaponType::NoAmmo) { player.LeftArm.GunSmoke = 12; diff --git a/TombEngine/Game/Lara/lara_two_guns.cpp b/TombEngine/Game/Lara/lara_two_guns.cpp index 303a6ba57..fbd854a3f 100644 --- a/TombEngine/Game/Lara/lara_two_guns.cpp +++ b/TombEngine/Game/Lara/lara_two_guns.cpp @@ -154,7 +154,7 @@ static void AnimateWeapon(ItemInfo& laraItem, LaraWeaponType weaponType, bool& h arm.Orientation.y + laraItem.Pose.Orientation.y, 0); - if (FireWeapon(weaponType, *player.TargetEntity, laraItem, armOrient) != FireWeaponType::NoAmmo) + if (FireWeapon(weaponType, player.TargetEntity, laraItem, armOrient) != FireWeaponType::NoAmmo) { arm.GunSmoke = 28; TriggerGunShell(isRightWeapon ? true : false, ID_GUNSHELL, weaponType); diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp index 71cbd746b..8f620b4f9 100644 --- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp +++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp @@ -680,8 +680,8 @@ namespace TEN::Entities::Vehicles lara->RightArm.Orientation.y + laraItem->Pose.Orientation.y, 0); - FireWeapon(LaraWeaponType::Snowmobile, *lara->TargetEntity, *laraItem, angles); - FireWeapon(LaraWeaponType::Snowmobile, *lara->TargetEntity, *laraItem, angles); + FireWeapon(LaraWeaponType::Snowmobile, lara->TargetEntity, *laraItem, angles); + FireWeapon(LaraWeaponType::Snowmobile, lara->TargetEntity, *laraItem, angles); SoundEffect(weapon.SampleNum, &laraItem->Pose); skidooItem->ItemFlags[0] = 4; } From 625131fbb71aa271b02c687dcba37f05c0659493 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 19 Dec 2024 01:26:39 +0100 Subject: [PATCH 02/26] Use O1 optimizations --- TombEngine/TombEngine.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 867133d68..49587e421 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -297,7 +297,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. stdcpp17 framework.h ProgramDatabase - Disabled + MinSpace Default AnySuitable true @@ -377,7 +377,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. stdcpp17 framework.h ProgramDatabase - Disabled + MinSpace Default AnySuitable true From 64c1777023a657134f1b9e0aa22de0c3c9d8a904 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:34:02 +0100 Subject: [PATCH 03/26] Use level time for volume timestamps, as using GlobalCounter may be inconsistent --- TombEngine/Game/control/volume.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp index 64f55db11..b46e3dbbb 100644 --- a/TombEngine/Game/control/volume.cpp +++ b/TombEngine/Game/control/volume.cpp @@ -168,7 +168,7 @@ namespace TEN::Control::Volumes if (candidate.Status == VolumeStateStatus::Leaving) { - if ((GlobalCounter - candidate.Timestamp) > VOLUME_BUSY_TIMEOUT) + if ((SaveGame::Statistics.Level.TimeTaken - candidate.Timestamp) > VOLUME_BUSY_TIMEOUT) candidate.Status = VolumeStateStatus::Outside; } else if (candidate.Status != VolumeStateStatus::Outside) @@ -191,7 +191,7 @@ namespace TEN::Control::Volumes { VolumeStateStatus::Entering, activator, - GlobalCounter + SaveGame::Statistics.Level.TimeTaken }); HandleEvent(set.Events[(int)EventType::Enter], activator); @@ -199,7 +199,7 @@ namespace TEN::Control::Volumes else { entryPtr->Status = VolumeStateStatus::Inside; - entryPtr->Timestamp = GlobalCounter; + entryPtr->Timestamp = SaveGame::Statistics.Level.TimeTaken; HandleEvent(set.Events[(int)EventType::Inside], activator); } @@ -209,10 +209,10 @@ namespace TEN::Control::Volumes // Only fire leave event when a certain timeout has passed. // This helps to filter out borderline cases when moving around volumes. - if ((GlobalCounter - entryPtr->Timestamp) > VOLUME_LEAVE_TIMEOUT) + if ((SaveGame::Statistics.Level.TimeTaken - entryPtr->Timestamp) > VOLUME_LEAVE_TIMEOUT) { entryPtr->Status = VolumeStateStatus::Leaving; - entryPtr->Timestamp = GlobalCounter; + entryPtr->Timestamp = SaveGame::Statistics.Level.TimeTaken; HandleEvent(set.Events[(int)EventType::Leave], activator); } From 13bad20803c84f52b251f616c1d480c0877a7e1c Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:31:10 +0100 Subject: [PATCH 04/26] Fixed #1514, #1515, #1516 --- TombEngine/Objects/Utils/object_helper.cpp | 2 -- .../Scripting/Internal/TEN/Types/Time/Time.cpp | 18 +++++++++--------- .../Scripting/Internal/TEN/Types/Time/Time.h | 6 +++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/TombEngine/Objects/Utils/object_helper.cpp b/TombEngine/Objects/Utils/object_helper.cpp index dcf6ba717..936bac4cb 100644 --- a/TombEngine/Objects/Utils/object_helper.cpp +++ b/TombEngine/Objects/Utils/object_helper.cpp @@ -140,7 +140,6 @@ void InitPickup(ObjectInfo* object, int objectNumber, std::functionloaded) { object->Initialize = InitializePickup; - object->collision = PickupCollision; object->control = (func != nullptr) ? func : PickupControl; object->isPickup = true; @@ -156,7 +155,6 @@ void InitFlare(ObjectInfo* object, int objectNumber) object->collision = PickupCollision; object->control = FlareControl; object->pivotLength = 256; - object->HitPoints = 256; // Time. object->usingDrawAnimatingItem = false; object->isPickup = true; } diff --git a/TombEngine/Scripting/Internal/TEN/Types/Time/Time.cpp b/TombEngine/Scripting/Internal/TEN/Types/Time/Time.cpp index 6b5f8c722..eedc024c9 100644 --- a/TombEngine/Scripting/Internal/TEN/Types/Time/Time.cpp +++ b/TombEngine/Scripting/Internal/TEN/Types/Time/Time.cpp @@ -58,7 +58,7 @@ namespace TEN::Scripting // @treturn Time A new Time object initialized with the given frame count. Time::Time(int gameFrames) { - _frameCount = gameFrames; + _frameCount = std::clamp(gameFrames, 0, INT_MAX); } /// Create a Time object from a formatted string. @@ -194,18 +194,18 @@ namespace TEN::Scripting Time& Time::operator -=(const Time& time) { - _frameCount -= time._frameCount; + _frameCount = std::clamp(_frameCount - time._frameCount, 0, INT_MAX); return *this; } Time Time::operator +(int frameCount) const { - return Time(frameCount + _frameCount); + return Time(_frameCount + frameCount); } Time Time::operator -(int frameCount) const { - return Time(frameCount - _frameCount); + return Time(std::clamp(_frameCount - frameCount, 0, INT_MAX)); } Time Time::operator +(const Time& time) const @@ -215,17 +215,17 @@ namespace TEN::Scripting Time Time::operator -(const Time& time) const { - return Time(_frameCount - time._frameCount); + return Time(std::clamp(_frameCount - time._frameCount, 0, INT_MAX)); } - Time Time::operator <(const Time& time) const + bool Time::operator <(const Time& time) const { - return Time(_frameCount < time._frameCount); + return _frameCount < time._frameCount; } - Time Time::operator <=(const Time& time) const + bool Time::operator <=(const Time& time) const { - return Time(_frameCount <= time._frameCount); + return _frameCount <= time._frameCount; } bool Time::operator ==(const Time& time) const diff --git a/TombEngine/Scripting/Internal/TEN/Types/Time/Time.h b/TombEngine/Scripting/Internal/TEN/Types/Time/Time.h index 171b18d58..be652bcba 100644 --- a/TombEngine/Scripting/Internal/TEN/Types/Time/Time.h +++ b/TombEngine/Scripting/Internal/TEN/Types/Time/Time.h @@ -42,13 +42,13 @@ namespace TEN::Scripting // Operators + bool operator <(const Time& time) const; + bool operator <=(const Time& time) const; + bool operator ==(const Time& time) const; Time operator +(int frameCount) const; Time operator -(int frameCount) const; Time operator +(const Time& time) const; Time operator -(const Time& time) const; - Time operator <(const Time& time) const; - Time operator <=(const Time& time) const; - bool operator ==(const Time& time) const; Time& operator +=(const Time& time); Time& operator -=(const Time& time); Time& Time::operator ++(); From d75bba698f850501ef463363324eebb072abf985 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 01:02:50 +0100 Subject: [PATCH 05/26] Fixed Electricity Wires object not doing instant kill when Lara is in close proximity --- CHANGELOG.md | 1 + TombEngine/Objects/Effects/tr5_electricity.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d9103ce8..9d26d1156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed exploding TR3 bosses. * Fixed original issue with deactivation of Dart Emitter. * Fixed original issue with weapon hotkeys available in binoculars or lasersight mode. +* Fixed Electricity Wires object not doing instant kill when Lara is in close proximity. * Fixed Lens Flare object not functioning properly. * Fixed lens flares not being occluded by static meshes and moveables. * Fixed spotlight shadows. diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp index 81e6db94a..d28616621 100644 --- a/TombEngine/Objects/Effects/tr5_electricity.cpp +++ b/TombEngine/Objects/Effects/tr5_electricity.cpp @@ -222,7 +222,7 @@ void ElectricityWiresControl(short itemNumber) isWaterNearby = true; } - bool instantKill = BoundingSphere(Vector3(pos.x, pos.y, pos.z), CLICK(0.25f)).Intersects(npcBox); + bool instantKill = BoundingSphere(Vector3(pos.x, pos.y, pos.z), BLOCK(0.25f)).Intersects(npcBox); if (isWaterNearby || instantKill) { From 0ae388845612a5bd08c7b5f822a6304180a8b8db Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 10:09:00 +0100 Subject: [PATCH 06/26] Expose different animation slots to scripting API --- CHANGELOG.md | 2 ++ .../doc/2 classes/Objects.Moveable.html | 36 +++++++++++++++++-- .../Scripting/Internal/ReservedScriptNames.h | 1 + .../TEN/Objects/Moveable/MoveableObject.cpp | 23 +++++++++--- .../TEN/Objects/Moveable/MoveableObject.h | 3 +- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d26d1156..fb93aac62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Added optional cast shadow and name parameters for Effects.EmitLight() function. * Added Effects.GetWind() function to get current wind speed vector. * Added Moveable:GetCollidable() and Moveable:SetCollidable() functions. +* Added Moveable:GetAnimSlot() and optional second argument for Moveable:SetAnim() to access different animation slots. * Added Rotation:Direction() method to get directional vector. * Added support for transparency value in Strings.DisplayString class. * Added extra argument for Sound.SetAmbientTrack() function to specify if new ambient track should play from the beginning. @@ -69,6 +70,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed Strings.DisplayString class not supporting some Unicode characters and empty lines in multiline strings. * Fixed Strings.DisplayString not being deallocated after showing. * Fixed GameVars not transferring between levels in hub mode. +* Fixed incorrect return value of Moveable:GetAnim() function, if animation from another slot is currently playing. * Fixed incorrect behaviour of Moveable:GetJointRotation() function. * Fixed incorrect behaviour of Logic.EnableEvent() and Logic.DisableEvent() functions. * Fixed Util.HasLineOfSight() not taking static meshes into consideration. diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 9ba2acd1e..11998a0d1 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -171,7 +171,11 @@ pickups, and Lara herself (see also Retrieve the index of the current animation. - Moveable:SetAnim(index) + Moveable:GetAnimSlot() + Retrieve the slot ID of the animation. + + + Moveable:SetAnim(index[, slot]) Set the object's animation to the one specified by the given index. @@ -774,10 +778,33 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) + +
+ + Moveable:GetAnimSlot() +
+
+ Retrieve the slot ID of the animation. + In certain cases, moveable may play animations from another object slot. Use this + function when you need to identify such cases. + + + + +

Returns:

+
    + + int + animation slot ID +
+ + + +
- Moveable:SetAnim(index) + Moveable:SetAnim(index[, slot])
Set the object's animation to the one specified by the given index. @@ -792,6 +819,11 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) int the index of the desired anim +
  • slot + int + slot ID of the desired anim (if omitted, moveable's own slot ID is used) + (optional) +
  • diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index 25c798287..e2cafe4b4 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -166,6 +166,7 @@ static constexpr char ScriptReserved_SetVelocity[] = "SetVelocity"; static constexpr char ScriptReserved_GetFrameNumber[] = "GetFrame"; static constexpr char ScriptReserved_GetEndFrame[] = "GetEndFrame"; static constexpr char ScriptReserved_SetFrameNumber[] = "SetFrame"; +static constexpr char ScriptReserved_GetAnimSlot[] = "GetAnimSlot"; static constexpr char ScriptReserved_GetAnimNumber[] = "GetAnim"; static constexpr char ScriptReserved_SetAnimNumber[] = "SetAnim"; static constexpr char ScriptReserved_GetStateNumber[] = "GetState"; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 37c7057a0..c681ea956 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -130,7 +130,7 @@ static std::unique_ptr Create( if (std::holds_alternative(animNumber)) { - ptr->SetAnimNumber(std::get(animNumber)); + ptr->SetAnimNumber(std::get(animNumber), objID); ptr->SetFrameNumber(USE_IF_HAVE(int, frameNumber, 0)); } @@ -245,11 +245,19 @@ void Moveable::Register(sol::state& state, sol::table& parent) // @treturn int the index of the active animation ScriptReserved_GetAnimNumber, &Moveable::GetAnimNumber, +/// Retrieve the slot ID of the animation. +// In certain cases, moveable may play animations from another object slot. Use this +// function when you need to identify such cases. +// @function Moveable:GetAnimSlot +// @treturn int animation slot ID + ScriptReserved_GetAnimSlot, &Moveable::GetAnimSlot, + /// Set the object's animation to the one specified by the given index. // Performs no bounds checking. *Ensure the number given is correct, else // object may end up in corrupted animation state.* // @function Moveable:SetAnim // @tparam int index the index of the desired anim +// @tparam[opt] int slot slot ID of the desired anim (if omitted, moveable's own slot ID is used) ScriptReserved_SetAnimNumber, &Moveable::SetAnimNumber, /// Retrieve frame number. @@ -878,14 +886,19 @@ void Moveable::SetStateNumber(int stateNumber) m_item->Animation.TargetState = stateNumber; } -int Moveable::GetAnimNumber() const +int Moveable::GetAnimSlot() const { - return m_item->Animation.AnimNumber - Objects[m_item->ObjectNumber].animIndex; + return m_item->Animation.AnimObjectID; } -void Moveable::SetAnimNumber(int animNumber) +int Moveable::GetAnimNumber() const { - SetAnimation(m_item, animNumber); + return m_item->Animation.AnimNumber - Objects[m_item->Animation.AnimObjectID].animIndex; +} + +void Moveable::SetAnimNumber(int animNumber, sol::optional slotIndex) +{ + SetAnimation(*m_item, (GAME_OBJECT_ID)slotIndex.value_or(m_item->ObjectNumber), animNumber); } int Moveable::GetFrameNumber() const diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h index 3abf62860..746c66a6a 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h @@ -62,7 +62,8 @@ public: void SetStateNumber(int stateNumber); [[nodiscard]] int GetAnimNumber() const; - void SetAnimNumber(int animNumber); + [[nodiscard]] int GetAnimSlot() const; + void SetAnimNumber(int animNumber, sol::optional slotIndex); [[nodiscard]] int GetFrameNumber() const; [[nodiscard]] int GetEndFrame() const; From 0620e83125703d2728e7bdebfe997d431eb90280 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 12:40:24 +0100 Subject: [PATCH 07/26] Don't give LDoc warning on compile --- Scripts/Engine/Util.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/Scripts/Engine/Util.lua b/Scripts/Engine/Util.lua index ad6c0a9d9..0f4c711b2 100644 --- a/Scripts/Engine/Util.lua +++ b/Scripts/Engine/Util.lua @@ -1,3 +1,4 @@ +-- ldignore local Util = {} Util.ShortenTENCalls = function() From 04b659b4101e62cf09fdfbff20c4be9d504fa51f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:31:24 +0100 Subject: [PATCH 08/26] Revert joint connection code, fix compass needle --- TombEngine/Game/gui.cpp | 3 +- TombEngine/Renderer/RendererCompatibility.cpp | 47 ++++++++++++------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index ec338990f..26b9ad59c 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -3303,6 +3303,7 @@ namespace TEN::Gui while (g_Synchronizer.Synced()) { TimeInMenu++; + GlobalCounter++; SaveGame::Statistics.Game.TimeTaken++; SaveGame::Statistics.Level.TimeTaken++; @@ -3451,7 +3452,7 @@ namespace TEN::Gui needleOrient.Lerp(EulerAngles(0, item->Pose.Orientation.y, 0), LERP_ALPHA); float wibble = std::sin((float(GlobalCounter & 0x3F) / (float)0x3F) * PI_MUL_2); - CompassNeedleAngle = needleOrient.y + ANGLE(wibble / 2); + CompassNeedleAngle = needleOrient.y + ANGLE(wibble); // HACK: Needle is rotated in the draw function. const auto& invObject = InventoryObjectTable[INV_OBJECT_COMPASS]; diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index 77d2970d3..e8cc46136 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -671,18 +671,25 @@ namespace TEN::Renderer { auto* skinVertex = &_moveablesVertices[skinBucket->StartVertex + v2]; - auto vertex0 = _moveablesVertices[jointBucket->StartVertex + v1].Position + jointBone->GlobalTranslation; - auto vertex1 = _moveablesVertices[skinBucket->StartVertex + v2].Position + skinBone->GlobalTranslation; + // NOTE: Don't vectorize these coordinates, it breaks the connection in some cases. -- Lwmte, 21.12.24 - if (Vector3::Distance(vertex0, vertex1) > 2) - continue; + int x1 = _moveablesVertices[jointBucket->StartVertex + v1].Position.x + jointBone->GlobalTranslation.x; + int y1 = _moveablesVertices[jointBucket->StartVertex + v1].Position.y + jointBone->GlobalTranslation.y; + int z1 = _moveablesVertices[jointBucket->StartVertex + v1].Position.z + jointBone->GlobalTranslation.z; - jointVertex->Bone = bonesToCheck[k]; - jointVertex->Position = skinVertex->Position; - jointVertex->Normal = skinVertex->Normal; + int x2 = _moveablesVertices[skinBucket->StartVertex + v2].Position.x + skinBone->GlobalTranslation.x; + int y2 = _moveablesVertices[skinBucket->StartVertex + v2].Position.y + skinBone->GlobalTranslation.y; + int z2 = _moveablesVertices[skinBucket->StartVertex + v2].Position.z + skinBone->GlobalTranslation.z; - isDone = true; - break; + if (abs(x1 - x2) < 2 && abs(y1 - y2) < 2 && abs(z1 - z2) < 2) + { + jointVertex->Bone = bonesToCheck[k]; + jointVertex->Position = skinVertex->Position; + jointVertex->Normal = skinVertex->Normal; + + isDone = true; + break; + } } if (isDone) @@ -765,17 +772,23 @@ namespace TEN::Renderer { auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; - auto vertex1 = _moveablesVertices[currentBucket.StartVertex + v1].Position + currentBone->GlobalTranslation; - auto vertex2 = _moveablesVertices[parentBucket->StartVertex + v2].Position + parentBone->GlobalTranslation; + int x1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.x + currentBone->GlobalTranslation.x; + int y1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.y + currentBone->GlobalTranslation.y; + int z1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.z + currentBone->GlobalTranslation.z; + + int x2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.x + parentBone->GlobalTranslation.x; + int y2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.y + parentBone->GlobalTranslation.y; + int z2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.z + parentBone->GlobalTranslation.z; // FIXME: If a tolerance is used, a strange bug occurs where certain vertices don't connect. -- Lwmte, 14.12.2024 - if (vertex1 != vertex2) - continue; - currentVertex->Bone = j; - currentVertex->Position = parentVertex->Position; - currentVertex->Normal = parentVertex->Normal; - break; + if (abs(x1 - x2) == 0 && abs(y1 - y2) == 0 && abs(z1 - z2) == 0) + { + currentVertex->Bone = j; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; + break; + } } } } From b62c8d7c409882711977157395f5a06c38d545ba Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 21 Dec 2024 20:01:55 +0100 Subject: [PATCH 09/26] Minor changes --- .../doc/2 classes/Objects.Moveable.html | 166 +++++++++--------- Scripts/Settings.lua | 26 +-- TombEngine/Scripting/Internal/ScriptUtil.h | 4 +- .../TEN/Objects/Moveable/MoveableObject.cpp | 41 ++--- TombEngine/Specific/winmain.cpp | 4 +- TombEngine/version.h | 2 +- 6 files changed, 122 insertions(+), 121 deletions(-) diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 11998a0d1..b7dc02275 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -171,18 +171,26 @@ pickups, and Lara herself (see also Retrieve the index of the current animation. - Moveable:GetAnimSlot() - Retrieve the slot ID of the animation. - - Moveable:SetAnim(index[, slot]) Set the object's animation to the one specified by the given index. + Moveable:GetAnimSlot() + Retrieve the slot ID of the animation. + + Moveable:GetFrame() Retrieve frame number. + Moveable:SetFrame(frame) + Set frame number. + + + Moveable:GetEndFrame() + Get the end frame number of the moveable's active animation. + + Moveable:SetVelocity(velocity) Set the object's velocity to specified value. @@ -191,10 +199,6 @@ pickups, and Lara herself (see also Get the object's velocity. - Moveable:SetFrame(frame) - Set frame number. - - Moveable:GetHP() Get current HP (hit points/health points) @@ -328,10 +332,6 @@ pickups, and Lara herself (see also Set AIBits of object Use this to force a moveable into a certain AI mode or modes, as if a certain nullmesh (or more than one) had suddenly spawned beneath their feet. - - - Moveable:GetEndFrame() - Get the end frame number of the moveable's active animation. Moveable:GetRoom() @@ -778,29 +778,6 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) -
    -
    - - Moveable:GetAnimSlot() -
    -
    - Retrieve the slot ID of the animation. - In certain cases, moveable may play animations from another object slot. Use this - function when you need to identify such cases. - - - - -

    Returns:

    -
      - - int - animation slot ID -
    - - - -
    @@ -830,6 +807,29 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) + +
    + + Moveable:GetAnimSlot() +
    +
    + Retrieve the slot ID of the animation. + In certain cases, moveable may play animations from another object slot. Use this + function when you need to identify such cases. + + + + +

    Returns:

    +
      + + int + animation slot ID +
    + + + +
    @@ -852,6 +852,54 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) + +
    + + Moveable:SetFrame(frame) +
    +
    + Set frame number. + This will move the animation to the given frame. + The number of frames in an animation can be seen under the heading "End frame" in + the WadTool animation editor. If the animation has no frames, the only valid argument + is -1. + + + +

    Parameters:

    + + + + + + +
    +
    + + Moveable:GetEndFrame() +
    +
    + Get the end frame number of the moveable's active animation. + This is the "End Frame" set in WADTool for the animation.() + + + + +

    Returns:

    +
      + + int + End frame number of the active animation. +
    + + + +
    @@ -899,32 +947,6 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) - -
    - - Moveable:SetFrame(frame) -
    -
    - Set frame number. - This will move the animation to the given frame. - The number of frames in an animation can be seen under the heading "End frame" in - the WadTool animation editor. If the animation has no frames, the only valid argument - is -1. - - - -

    Parameters:

    - - - - - -
    @@ -1693,28 +1715,6 @@ baddy:SetOnKilled(LevelFuncs.baddyKilled) sas:SetAIBits({1, 0, 0, 0, 0, 0}) - -
    - - Moveable:GetEndFrame() -
    -
    - Get the end frame number of the moveable's active animation. - This is the "End Frame" set in WADTool for the animation.() - - - - -

    Returns:

    -
      - - int - End frame number of the active animation. -
    - - - -
    diff --git a/Scripts/Settings.lua b/Scripts/Settings.lua index 081e268e8..75981eaf7 100644 --- a/Scripts/Settings.lua +++ b/Scripts/Settings.lua @@ -82,19 +82,19 @@ local settings = Flow.Settings.new() settings.Weapons[WeaponType.REVOLVER].colorizeMuzzleFlash = false settings.Weapons[WeaponType.REVOLVER].pickupCount = 6 - settings.Weapons[WeaponType.UZI].accuracy = 8 - settings.Weapons[WeaponType.UZI].targetingDistance = 8192 - settings.Weapons[WeaponType.UZI].interval = 3 - settings.Weapons[WeaponType.UZI].waterLevel = 650 - settings.Weapons[WeaponType.UZI].flashDuration = 2 - settings.Weapons[WeaponType.UZI].flashRange = 9 - settings.Weapons[WeaponType.UZI].flashColor = Color(192, 128, 0) - settings.Weapons[WeaponType.UZI].damage = 1 - settings.Weapons[WeaponType.UZI].smoke = true - settings.Weapons[WeaponType.UZI].shell = true - settings.Weapons[WeaponType.UZI].muzzleFlash = true - settings.Weapons[WeaponType.UZI].colorizeMuzzleFlash = false - settings.Weapons[WeaponType.UZI].pickupCount = 30 + settings.Weapons[WeaponType.UZIS].accuracy = 8 + settings.Weapons[WeaponType.UZIS].targetingDistance = 8192 + settings.Weapons[WeaponType.UZIS].interval = 3 + settings.Weapons[WeaponType.UZIS].waterLevel = 650 + settings.Weapons[WeaponType.UZIS].flashDuration = 2 + settings.Weapons[WeaponType.UZIS].flashRange = 9 + settings.Weapons[WeaponType.UZIS].flashColor = Color(192, 128, 0) + settings.Weapons[WeaponType.UZIS].damage = 1 + settings.Weapons[WeaponType.UZIS].smoke = true + settings.Weapons[WeaponType.UZIS].shell = true + settings.Weapons[WeaponType.UZIS].muzzleFlash = true + settings.Weapons[WeaponType.UZIS].colorizeMuzzleFlash = false + settings.Weapons[WeaponType.UZIS].pickupCount = 30 settings.Weapons[WeaponType.SHOTGUN].accuracy = 10 settings.Weapons[WeaponType.SHOTGUN].targetingDistance = 8192 diff --git a/TombEngine/Scripting/Internal/ScriptUtil.h b/TombEngine/Scripting/Internal/ScriptUtil.h index 700aab232..add1584de 100644 --- a/TombEngine/Scripting/Internal/ScriptUtil.h +++ b/TombEngine/Scripting/Internal/ScriptUtil.h @@ -4,13 +4,13 @@ #define index_error_maker(CPP_TYPE, LUA_CLASS_NAME) [](CPP_TYPE& item, sol::object key) \ { \ - std::string err = "Attempted to read missing var \"" + key.as() + "\" from " + LUA_CLASS_NAME; \ + std::string err = "Attempted to read missing variable \"" + key.as() + "\" from " + LUA_CLASS_NAME; \ ScriptAssert(false, err);\ } #define newindex_error_maker(CPP_TYPE, LUA_CLASS_NAME) [](CPP_TYPE& item, sol::object key) \ { \ - std::string err = "Attempted to set missing var \"" + key.as() + "\" of " + LUA_CLASS_NAME; \ + std::string err = "Attempted to set missing variable \"" + key.as() + "\" of " + LUA_CLASS_NAME; \ ScriptAssert(false, err);\ } diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index c681ea956..264265fec 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -245,13 +245,6 @@ void Moveable::Register(sol::state& state, sol::table& parent) // @treturn int the index of the active animation ScriptReserved_GetAnimNumber, &Moveable::GetAnimNumber, -/// Retrieve the slot ID of the animation. -// In certain cases, moveable may play animations from another object slot. Use this -// function when you need to identify such cases. -// @function Moveable:GetAnimSlot -// @treturn int animation slot ID - ScriptReserved_GetAnimSlot, &Moveable::GetAnimSlot, - /// Set the object's animation to the one specified by the given index. // Performs no bounds checking. *Ensure the number given is correct, else // object may end up in corrupted animation state.* @@ -260,12 +253,33 @@ void Moveable::Register(sol::state& state, sol::table& parent) // @tparam[opt] int slot slot ID of the desired anim (if omitted, moveable's own slot ID is used) ScriptReserved_SetAnimNumber, &Moveable::SetAnimNumber, +/// Retrieve the slot ID of the animation. +// In certain cases, moveable may play animations from another object slot. Use this +// function when you need to identify such cases. +// @function Moveable:GetAnimSlot +// @treturn int animation slot ID + ScriptReserved_GetAnimSlot, &Moveable::GetAnimSlot, + /// Retrieve frame number. // This is the current frame of the object's active animation. // @function Moveable:GetFrame // @treturn int the current frame of the active animation ScriptReserved_GetFrameNumber, &Moveable::GetFrameNumber, +/// Set frame number. +// This will move the animation to the given frame. +// The number of frames in an animation can be seen under the heading "End frame" in +// the WadTool animation editor. If the animation has no frames, the only valid argument +// is -1. +// @function Moveable:SetFrame +// @tparam int frame the new frame number + ScriptReserved_SetFrameNumber, &Moveable::SetFrameNumber, + + +/// Get the end frame number of the moveable's active animation. +// This is the "End Frame" set in WADTool for the animation. +// @function Moveable:GetEndFrame() +// @treturn int End frame number of the active animation. ScriptReserved_GetEndFrame, &Moveable::GetEndFrame, /// Set the object's velocity to specified value. @@ -282,15 +296,6 @@ void Moveable::Register(sol::state& state, sol::table& parent) // @treturn Vec3 current object velocity ScriptReserved_GetVelocity, &Moveable::GetVelocity, -/// Set frame number. -// This will move the animation to the given frame. -// The number of frames in an animation can be seen under the heading "End frame" in -// the WadTool animation editor. If the animation has no frames, the only valid argument -// is -1. -// @function Moveable:SetFrame -// @tparam int frame the new frame number - ScriptReserved_SetFrameNumber, &Moveable::SetFrameNumber, - /// Get current HP (hit points/health points) // @function Moveable:GetHP // @treturn int the amount of HP the moveable currently has @@ -940,10 +945,6 @@ void Moveable::SetFrameNumber(int frameNumber) } } -/// Get the end frame number of the moveable's active animation. -// This is the "End Frame" set in WADTool for the animation. -// @function Moveable:GetEndFrame() -// @treturn int End frame number of the active animation. int Moveable::GetEndFrame() const { const auto& anim = GetAnimData(*m_item); diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 7ed2fc1f9..27ec3f127 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -538,14 +538,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine void WinClose() { + TENLog("Cleaning up and exiting...", LogLevel::Info); + WaitForSingleObject((HANDLE)ThreadHandle, 5000); DestroyAcceleratorTable(hAccTable); Sound_DeInit(); DeinitializeInput(); - - TENLog("Cleaning up and exiting...", LogLevel::Info); delete g_GameScript; g_GameScript = nullptr; diff --git a/TombEngine/version.h b/TombEngine/version.h index ad5d353fc..1f244287b 100644 --- a/TombEngine/version.h +++ b/TombEngine/version.h @@ -8,7 +8,7 @@ #define TEN_MAJOR_VERSION 1 #define TEN_MINOR_VERSION 6 #define TEN_BUILD_NUMBER 0 -#define TEN_REVISION_NUMBER 1 +#define TEN_REVISION_NUMBER 6 #define TEST_BUILD 1 From 6d38bb36174a1f4d55d9c2580168ba61fdff2a31 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:42:42 +0100 Subject: [PATCH 10/26] Prevent log spam with fish swarm --- TombEngine/Objects/TR3/Entity/FishSwarm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp index 7adb8940a..d55f5e549 100644 --- a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp +++ b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp @@ -147,7 +147,7 @@ namespace TEN::Entities::Creatures::TR3 float closestDist = INFINITY; for (auto& targetItem : g_Level.Items) { - if (!Objects.CheckID(targetItem.ObjectNumber) || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_VALUE) + if (!Objects.CheckID(targetItem.ObjectNumber, true) || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_VALUE) continue; if (SameZone(&creature, &targetItem) && item.TriggerFlags < 0) From c757422f2d3bc4dd46249f020cf85ef83be62cc7 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue, 24 Dec 2024 01:34:36 +0100 Subject: [PATCH 11/26] Fixed #1526 --- TombEngine/Game/collision/floordata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp index b1ffdac52..99e0200cf 100644 --- a/TombEngine/Game/collision/floordata.cpp +++ b/TombEngine/Game/collision/floordata.cpp @@ -546,7 +546,7 @@ namespace TEN::Collision::Floordata // For bridges with zero thickness (which is incorrect setup, but still possible), break out of // infinite loop caused by infinite traversal over the same height value. int nextPos = sector->GetBridgeSurfaceHeight(pos, !isBottom); - if (nextPos = pos.y) + if (nextPos == pos.y) nextPos += (isBottom ? 1 : -1); // Set vertical position to lowest bridge ceiling height or highest bridge floor height. From 96f41ef9e89dedf6ac167b5628e4d12805a032ed Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 24 Dec 2024 13:13:45 +1100 Subject: [PATCH 12/26] Draw interaction box in collision stats debug page --- TombEngine/Game/collision/collide_item.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index e9d74b743..1d6348ce8 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -330,6 +330,8 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) bool TestLaraPosition(const ObjectCollisionBounds& bounds, ItemInfo* item, ItemInfo* laraItem) { + DrawDebugBox(bounds.BoundingBox.ToBoundingOrientedBox(item->Pose), Color(1.0f, 0.0f, 0.0f), RendererDebugPage::CollisionStats); + auto deltaOrient = laraItem->Pose.Orientation - item->Pose.Orientation; if (deltaOrient.x < bounds.OrientConstraint.first.x || deltaOrient.x > bounds.OrientConstraint.second.x || deltaOrient.y < bounds.OrientConstraint.first.y || deltaOrient.y > bounds.OrientConstraint.second.y || @@ -341,11 +343,7 @@ bool TestLaraPosition(const ObjectCollisionBounds& bounds, ItemInfo* item, ItemI auto pos = (laraItem->Pose.Position - item->Pose.Position).ToVector3(); auto rotMatrix = item->Pose.Orientation.ToRotationMatrix(); - // This solves once for all the minus sign hack of CreateFromYawPitchRoll. - // In reality it should be the inverse, but the inverse of a rotation matrix is equal to the transpose - // and transposing a matrix is faster. - // It's the only piece of code that does it, because we want Lara's location relative to the identity frame - // of the object we are test against. + // NOTE: Transpose = faster inverse. rotMatrix = rotMatrix.Transpose(); pos = Vector3::Transform(pos, rotMatrix); From 3ea8978c679dae4dcc6db96e1d654816312e515c Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue, 24 Dec 2024 20:04:13 +0100 Subject: [PATCH 13/26] Rename traveledDistance to distanceTraveled --- Documentation/doc/2 classes/Flow.Statistics.html | 8 ++++---- .../Scripting/Internal/TEN/Flow/Statistics/Statistics.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/doc/2 classes/Flow.Statistics.html b/Documentation/doc/2 classes/Flow.Statistics.html index d4c982804..584c50e51 100644 --- a/Documentation/doc/2 classes/Flow.Statistics.html +++ b/Documentation/doc/2 classes/Flow.Statistics.html @@ -122,7 +122,7 @@ Ammo used. - traveledDistance + distanceTraveled Distance traveled. @@ -197,8 +197,8 @@
    - - traveledDistance + + distanceTraveled
    Distance traveled. @@ -206,7 +206,7 @@
    -
    - - GetNextLevel() -
    -
    - Returns the level that is about to load. If no new level is about to load, returns current level. - - - - -

    Returns:

    -
      - - Level - incoming new level or current level, if no new level is loading -
    - - - -
    diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index e2cafe4b4..dfe075dbe 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -224,7 +224,6 @@ static constexpr char ScriptReserved_IsTagPresent[] = "IsTagPresent"; static constexpr char ScriptReserved_AddLevel[] = "AddLevel"; static constexpr char ScriptReserved_GetLevel[] = "GetLevel"; static constexpr char ScriptReserved_GetCurrentLevel[] = "GetCurrentLevel"; -static constexpr char ScriptReserved_GetNextLevel[] = "GetNextLevel"; static constexpr char ScriptReserved_SetIntroImagePath[] = "SetIntroImagePath"; static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreenImagePath"; static constexpr char ScriptReserved_SetFarView[] = "SetFarView"; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index 3bdcf305c..9fa965abd 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -137,12 +137,6 @@ have an ID of 0, the second an ID of 1, and so on. */ tableFlow.set_function(ScriptReserved_GetCurrentLevel, &FlowHandler::GetCurrentLevel, this); -/*** Returns the level that is about to load. If no new level is about to load, returns current level. -@function GetNextLevel -@treturn Flow.Level incoming new level or current level, if no new level is loading -*/ - tableFlow.set_function(ScriptReserved_GetNextLevel, &FlowHandler::GetNextLevel, this); - /*** Finishes the current level, with optional level index and start position index provided. If level index is not provided or is zero, jumps to next level. If level index is more than level count, jumps to title. If LARA\_START\_POS objects are present in level, player will be @@ -467,15 +461,6 @@ Level* FlowHandler::GetCurrentLevel() return Levels[CurrentLevel]; } -Level* FlowHandler::GetNextLevel() -{ - if (NextLevel == CurrentLevel) - return Levels[CurrentLevel]; - - // NOTE: Negative value indicates incoming savegame. - return Levels[abs(NextLevel)]; -} - int FlowHandler::GetNumLevels() const { return (int)Levels.size(); diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h index e5641eaef..17b496bfe 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h @@ -54,7 +54,6 @@ public: void SetLanguageNames(sol::as_table_t>&& src); Level* GetLevel(int id); Level* GetCurrentLevel(); - Level* GetNextLevel(); int GetLevelNumber(const std::string& flieName); int GetNumLevels() const; void EndLevel(std::optional nextLevel, std::optional startPosIndex); From 74499ccef20fdeb91842516b6765228022328da8 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 25 Dec 2024 11:27:58 +0100 Subject: [PATCH 19/26] Revert variable shadow softness for performance reasons --- TombEngine/Shaders/Shadows.hlsli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TombEngine/Shaders/Shadows.hlsli b/TombEngine/Shaders/Shadows.hlsli index 6af7a9283..ed75e2175 100644 --- a/TombEngine/Shaders/Shadows.hlsli +++ b/TombEngine/Shaders/Shadows.hlsli @@ -128,9 +128,9 @@ float3 DoShadow(float3 worldPos, float3 normal, float3 lighting, float bias) float samples = 0; // Perform basic PCF filtering with distance-based kernel size - for (float y = -kernelSize; y <= kernelSize; y += 1.0) + for (float y = -SHADOW_BLUR_MIN; y <= SHADOW_BLUR_MIN; y += 1.0) { - for (float x = -kernelSize; x <= kernelSize; x += 1.0) + for (float x = -SHADOW_BLUR_MIN; x <= SHADOW_BLUR_MIN; x += 1.0) { sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + TexOffset(x, y), i), lightClipSpace.z); samples += 1.0; From a1c76af54644dfbbd90dc70a9886bab3438a0d95 Mon Sep 17 00:00:00 2001 From: Jakub <80340234+Jakub768@users.noreply.github.com> Date: Wed, 25 Dec 2024 11:13:17 +0000 Subject: [PATCH 20/26] Update CHANGELOG.md --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 920ea0773..fe8bacc7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,15 @@ The dates are in European standard format where date is presented as **YYYY-MM-DD**. TombEngine releases are located in this repository (alongside with Tomb Editor): https://github.com/TombEngine/TombEditorReleases -## Version 1.7 - 2024-12-25 +## Version 1.8 - xxxx-xx-xx + +### Bug fixes + +### New Features + +### Lua API changes + +## [Version 1.7](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.3) - 2024-12-25 ### Bug fixes * Significantly improved renderer performance. From 749d6626f9ef72c81d4782bd3fd44a2ced669859 Mon Sep 17 00:00:00 2001 From: Jakub <80340234+Jakub768@users.noreply.github.com> Date: Thu, 26 Dec 2024 00:05:24 +0000 Subject: [PATCH 21/26] include description of OnUseItem and OnFreeze --- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 9bc36f302..77572e22c 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -1193,6 +1193,8 @@ For example: print("death") end end +@tfield function OnUseItem Will be called when using an item from inventory. +@tfield function OnFreeze Will be called when any of the Freeze modes are activated. @table LevelFuncs */ From e888b9d7e1e71235095e01ad6f05dd1d47634275 Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 26 Dec 2024 15:31:43 +1100 Subject: [PATCH 22/26] Move light effect functions to new file; lara_optics.cpp/h -> Optics.cpp/h; Trigger -> Spawn prefix for light effect functions --- .../Game/Lara/{lara_optics.cpp => Optics.cpp} | 6 ++--- .../Game/Lara/{lara_optics.h => Optics.h} | 0 TombEngine/Game/Lara/lara_cheat.cpp | 2 +- TombEngine/Game/Lara/lara_flare.cpp | 2 +- TombEngine/Game/Lara/lara_one_gun.cpp | 6 ++--- TombEngine/Game/Lara/lara_two_guns.cpp | 2 +- TombEngine/Game/camera.cpp | 2 +- TombEngine/Game/control/box.cpp | 2 +- TombEngine/Game/effects/Light.cpp | 24 +++++++++++++++++ TombEngine/Game/effects/Light.h | 10 +++++++ TombEngine/Game/effects/effects.cpp | 26 +++++-------------- TombEngine/Game/effects/effects.h | 12 ++++----- TombEngine/Game/effects/tomb4fx.cpp | 2 +- TombEngine/Game/gui.cpp | 2 +- TombEngine/Game/missile.cpp | 6 +++-- TombEngine/Objects/Effects/Boss.cpp | 2 +- TombEngine/Objects/Effects/enemy_missile.cpp | 2 +- TombEngine/Objects/Effects/flame_emitters.cpp | 14 +++++----- .../Objects/Effects/tr5_electricity.cpp | 4 +-- .../Objects/Generic/Object/burning_torch.cpp | 4 +-- TombEngine/Objects/TR2/Entity/Bartoli.cpp | 8 +++--- TombEngine/Objects/TR2/Entity/Dragon.cpp | 4 +-- .../TR2/Entity/tr2_worker_flamethrower.cpp | 4 +-- TombEngine/Objects/TR3/Entity/PunaBoss.cpp | 4 +-- TombEngine/Objects/TR3/Entity/SealMutant.cpp | 2 +- TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp | 4 +-- TombEngine/Objects/TR3/Entity/TwinAutoGun.cpp | 4 +-- TombEngine/Objects/TR3/Entity/WaspMutant.cpp | 2 +- .../Objects/TR3/Entity/tr3_claw_mutant.cpp | 2 +- .../Objects/TR3/Entity/tr3_flamethrower.cpp | 4 +-- TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 6 ++--- .../Objects/TR3/Trap/ElectricCleaner.cpp | 2 +- TombEngine/Objects/TR3/Trap/train.cpp | 2 +- TombEngine/Objects/TR3/Vehicles/minecart.cpp | 2 +- TombEngine/Objects/TR3/Vehicles/upv.cpp | 2 +- TombEngine/Objects/TR4/Entity/Wraith.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_demigod.cpp | 2 +- .../Objects/TR4/Entity/tr4_enemy_jeep.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_guide.cpp | 10 +++---- .../Objects/TR4/Entity/tr4_sentry_gun.cpp | 2 +- .../Objects/TR4/Object/tr4_element_puzzle.cpp | 2 +- TombEngine/Objects/TR4/Object/tr4_mapper.cpp | 2 +- TombEngine/Objects/TR4/Vehicles/jeep.cpp | 2 +- TombEngine/Objects/TR4/Vehicles/motorbike.cpp | 4 +-- TombEngine/Objects/TR5/Entity/AutoGun.cpp | 2 +- TombEngine/Objects/TR5/Entity/HeavyGuard.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_gunship.cpp | 4 +-- .../Objects/TR5/Entity/tr5_laser_head.cpp | 6 ++--- .../Objects/TR5/Entity/tr5_roman_statue.cpp | 16 ++++++------ .../Objects/TR5/Entity/tr5_submarine.cpp | 2 +- TombEngine/Objects/TR5/Light/tr5_light.cpp | 12 ++++----- TombEngine/Objects/TR5/Trap/LaserBarrier.cpp | 2 +- TombEngine/Objects/TR5/Trap/LaserBeam.cpp | 2 +- .../Internal/TEN/Effects/EffectsFunctions.cpp | 4 +-- TombEngine/TombEngine.vcxproj | 6 +++-- 57 files changed, 147 insertions(+), 125 deletions(-) rename TombEngine/Game/Lara/{lara_optics.cpp => Optics.cpp} (97%) rename TombEngine/Game/Lara/{lara_optics.h => Optics.h} (100%) create mode 100644 TombEngine/Game/effects/Light.cpp create mode 100644 TombEngine/Game/effects/Light.h diff --git a/TombEngine/Game/Lara/lara_optics.cpp b/TombEngine/Game/Lara/Optics.cpp similarity index 97% rename from TombEngine/Game/Lara/lara_optics.cpp rename to TombEngine/Game/Lara/Optics.cpp index dc3600c5f..d09e9ebcb 100644 --- a/TombEngine/Game/Lara/lara_optics.cpp +++ b/TombEngine/Game/Lara/Optics.cpp @@ -1,5 +1,5 @@ #include "framework.h" -#include "Game/Lara/lara_optics.h" +#include "Game/Lara/Optics.h" #include "Game/camera.h" #include "Game/control/los.h" @@ -178,7 +178,7 @@ static void DoOpticsHighlight(const ItemInfo& item, const Vector3i& origin, cons const auto& lasersightColor = g_GameFlow->GetSettings()->Camera.LasersightLightColor; const auto& color = GetLaraInfo(item).Control.Look.IsUsingLasersight ? lasersightColor : binocularsColor; - TriggerDynamicLight(origin2.x, origin2.y, origin2.z, 12, color.GetR(), color.GetG(), color.GetB()); + SpawnDynamicLight(origin2.x, origin2.y, origin2.z, 12, color.GetR(), color.GetG(), color.GetB()); if (!LOS(&origin2, &target2)) { @@ -193,7 +193,7 @@ static void DoOpticsHighlight(const ItemInfo& item, const Vector3i& origin, cons byte r = std::max(0, color.GetR() - luma); byte g = std::max(0, color.GetG() - luma); byte b = std::max(0, color.GetB() - luma); - TriggerDynamicLight(target2.x + dir.x, target2.y + dir.y, target2.z + dir.z, luma + 12, r, g, b); + SpawnDynamicLight(target2.x + dir.x, target2.y + dir.y, target2.z + dir.z, luma + 12, r, g, b); } } diff --git a/TombEngine/Game/Lara/lara_optics.h b/TombEngine/Game/Lara/Optics.h similarity index 100% rename from TombEngine/Game/Lara/lara_optics.h rename to TombEngine/Game/Lara/Optics.h diff --git a/TombEngine/Game/Lara/lara_cheat.cpp b/TombEngine/Game/Lara/lara_cheat.cpp index 3e87b6583..71b9659b0 100644 --- a/TombEngine/Game/Lara/lara_cheat.cpp +++ b/TombEngine/Game/Lara/lara_cheat.cpp @@ -38,7 +38,7 @@ namespace TEN::Entities::Player } if (IsHeld(In::Action)) - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150); + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150); if (IsHeld(In::Jump)) { diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp index 219952047..884e3df59 100644 --- a/TombEngine/Game/Lara/lara_flare.cpp +++ b/TombEngine/Game/Lara/lara_flare.cpp @@ -497,7 +497,7 @@ bool DoFlareLight(ItemInfo& item, const Vector3i& pos, int flareLife) auto color = (flareColor * intensity * std::clamp(mult, 0.0f, 1.0f)); // Spawn dynamic light. - TriggerDynamicPointLight(lightPos, Color(color), falloff, false, GetHash(item.Name)); + SpawnDynamicPointLight(lightPos, Color(color), falloff, false, GetHash(item.Name)); // Spawn lensflare if brightness is not 0. if (settings.LensflareBrightness > EPSILON) diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index 9fb37faa9..38fb2f43e 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -972,7 +972,7 @@ void RocketControl(short itemNumber) // Trigger fire, smoke, and light. TriggerRocketSmoke(wx + rocketItem.Pose.Position.x, wy + rocketItem.Pose.Position.y, wz + rocketItem.Pose.Position.z); TriggerRocketFire(wx + rocketItem.Pose.Position.x, wy + rocketItem.Pose.Position.y, wz + rocketItem.Pose.Position.z); - TriggerDynamicLight( + SpawnDynamicLight( wx + rocketItem.Pose.Position.x + (GetRandomControl() & 15) - 8, wy + rocketItem.Pose.Position.y + (GetRandomControl() & 15) - 8, wz + rocketItem.Pose.Position.z + (GetRandomControl() & 15) - 8, @@ -1305,12 +1305,12 @@ void RifleHandler(ItemInfo& laraItem, LaraWeaponType weaponType) if (weaponType == LaraWeaponType::Shotgun || weaponType == LaraWeaponType::HK) { auto pos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(0, -64, 0)); - TriggerDynamicPointLight(pos.ToVector3(), color, CLICK(settings.FlashRange)); + SpawnDynamicPointLight(pos.ToVector3(), color, CLICK(settings.FlashRange)); } else if (weaponType == LaraWeaponType::Revolver) { auto pos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(0, -32, 0)); - TriggerDynamicPointLight(pos.ToVector3(), color, CLICK(settings.FlashRange)); + SpawnDynamicPointLight(pos.ToVector3(), color, CLICK(settings.FlashRange)); } } } diff --git a/TombEngine/Game/Lara/lara_two_guns.cpp b/TombEngine/Game/Lara/lara_two_guns.cpp index fbd854a3f..a044c4282 100644 --- a/TombEngine/Game/Lara/lara_two_guns.cpp +++ b/TombEngine/Game/Lara/lara_two_guns.cpp @@ -321,7 +321,7 @@ void HandlePistols(ItemInfo& laraItem, LaraWeaponType weaponType) auto lightPos = Random::GeneratePointInSphere(sphere); int range = abs(Random::GenerateInt(settings.FlashRange - 2, settings.FlashRange + 2)); - TriggerDynamicPointLight(lightPos, color, CLICK(range)); + SpawnDynamicPointLight(lightPos, color, CLICK(range)); } } diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp index 2ff2778d9..761074070 100644 --- a/TombEngine/Game/camera.cpp +++ b/TombEngine/Game/camera.cpp @@ -12,7 +12,7 @@ #include "Game/Lara/lara.h" #include "Game/Lara/lara_fire.h" #include "Game/Lara/lara_helpers.h" -#include "Game/Lara/lara_optics.h" +#include "Game/Lara/Optics.h" #include "Game/room.h" #include "Game/savegame.h" #include "Game/Setup.h" diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 91ecaf960..8b1688320 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -744,7 +744,7 @@ static void SpawnCreatureGunEffect(const ItemInfo& item, const CreatureMuzzleFla auto muzzlePos = muzzleFlash.Bite; auto pos = GetJointPosition(item, muzzlePos); - TriggerDynamicLight(pos.x, pos.y, pos.z, 15, 128, 64, 16); + SpawnDynamicLight(pos.x, pos.y, pos.z, 15, 128, 64, 16); if (muzzleFlash.UseSmoke) { diff --git a/TombEngine/Game/effects/Light.cpp b/TombEngine/Game/effects/Light.cpp new file mode 100644 index 000000000..50ac09efd --- /dev/null +++ b/TombEngine/Game/effects/Light.cpp @@ -0,0 +1,24 @@ +#include "framework.h" +#include "Game/effects/Light.h" + +#include "Renderer/Renderer.h" + +using TEN::Renderer::g_Renderer; + +namespace TEN::Effects::Light +{ + void SpawnDynamicPointLight(const Vector3& pos, const Color& color, float falloff, bool castShadows, int hash) + { + g_Renderer.AddDynamicPointLight(pos, falloff, color, castShadows, hash); + } + + void SpawnDynamicSpotLight(const Vector3& pos, const Vector3& dir, const Color& color, float radius, float falloff, float dist, bool castShadows, int hash) + { + g_Renderer.AddDynamicSpotLight(pos, dir, radius, falloff, dist, color, castShadows, hash); + } + + void SpawnDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b) + { + g_Renderer.AddDynamicPointLight(Vector3(x, y, z), float(falloff * UCHAR_MAX), Color(r / (float)CHAR_MAX, g / (float)CHAR_MAX, b / (float)CHAR_MAX), false); + } +} diff --git a/TombEngine/Game/effects/Light.h b/TombEngine/Game/effects/Light.h new file mode 100644 index 000000000..52a0c5497 --- /dev/null +++ b/TombEngine/Game/effects/Light.h @@ -0,0 +1,10 @@ +#pragma once + +namespace TEN::Effects::Light +{ + void SpawnDynamicPointLight(const Vector3& pos, const Color& color, float falloff, bool castShadows = false, int hash = 0); + void SpawnDynamicSpotLight(const Vector3& pos, const Vector3& dir, const Color& color, float radius, float falloff, float dist, bool castShadows = false, int hash = 0); + + // DEPRECATED!!! Use SpawnDynamicPointLight() instead and phase out this legacy function. + void SpawnDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b); +} diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp index 196a5da53..a934f224d 100644 --- a/TombEngine/Game/effects/effects.cpp +++ b/TombEngine/Game/effects/effects.cpp @@ -10,6 +10,7 @@ #include "Game/effects/Drip.h" #include "Game/effects/explosion.h" #include "Game/effects/item_fx.h" +#include "Game/effects/Light.h" #include "Game/effects/Ripple.h" #include "Game/effects/smoke.h" #include "Game/effects/spark.h" @@ -33,6 +34,7 @@ using namespace TEN::Effects::Drip; using namespace TEN::Effects::Environment; using namespace TEN::Effects::Explosion; using namespace TEN::Effects::Items; +using namespace TEN::Effects::Light; using namespace TEN::Effects::Ripple; using namespace TEN::Effects::Spark; using namespace TEN::Math; @@ -430,7 +432,7 @@ void UpdateSparks() else falloff = 31; - TriggerDynamicLight(x, y, z, falloff, r, g, b); + SpawnDynamicLight(x, y, z, falloff, r, g, b); } else { @@ -438,11 +440,11 @@ void UpdateSparks() if (spark->flags & SP_COLOR) { - TriggerDynamicLight(x, y, z, falloff, spark->dR, spark->dG, spark->dB); + SpawnDynamicLight(x, y, z, falloff, spark->dR, spark->dG, spark->dB); } else { - TriggerDynamicLight(x, y, z, falloff, g, b, r); + SpawnDynamicLight(x, y, z, falloff, g, b, r); } } } @@ -1247,22 +1249,6 @@ void KillAllCurrentItems(short itemNumber) // TODO: Reimplement this functionality. } -void TriggerDynamicPointLight(const Vector3& pos, const Color& color, float falloff, bool castShadows, int hash) -{ - g_Renderer.AddDynamicPointLight(pos, falloff , color, castShadows, hash); -} - -void TriggerDynamicSpotLight(const Vector3& pos, const Vector3& dir, const Color& color, float radius, float falloff, float distance, bool castShadows, int hash) -{ - g_Renderer.AddDynamicSpotLight(pos, dir, radius, falloff, distance, color, castShadows, hash); -} - -// Deprecated. Use above version instead. -void TriggerDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b) -{ - g_Renderer.AddDynamicPointLight(Vector3(x, y, z), (float)(falloff * UCHAR_MAX), Color(r / (float)CHAR_MAX, g / (float)CHAR_MAX, b / (float)CHAR_MAX), false); -} - void SpawnPlayerWaterSurfaceEffects(const ItemInfo& item, int waterHeight, int waterDepth) { const auto& player = GetLaraInfo(item); @@ -1919,7 +1905,7 @@ void ProcessEffects(ItemInfo* item) MAX_LIGHT_FALLOFF - std::clamp(MAX_LIGHT_FALLOFF - item->Effect.Count, 0, MAX_LIGHT_FALLOFF); auto pos = GetJointPosition(item, 0); - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, falloff, std::clamp(Random::GenerateInt(-32, 32) + int(item->Effect.LightColor.x * UCHAR_MAX), 0, UCHAR_MAX), std::clamp(Random::GenerateInt(-32, 32) + int(item->Effect.LightColor.y * UCHAR_MAX), 0, UCHAR_MAX), diff --git a/TombEngine/Game/effects/effects.h b/TombEngine/Game/effects/effects.h index bfb9c5b4f..aae51d439 100644 --- a/TombEngine/Game/effects/effects.h +++ b/TombEngine/Game/effects/effects.h @@ -1,8 +1,12 @@ #pragma once -#include "Math/Math.h" + #include "Game/Items.h" +#include "Game/effects/Light.h" +#include "Math/Math.h" #include "Renderer/RendererEnums.h" +using namespace TEN::Effects::Light; + enum class LaraWeaponType; enum GAME_OBJECT_ID : short; struct CollisionInfo; @@ -299,12 +303,6 @@ void DoLotsOfBlood(int x, int y, int z, int speed, short direction, short roomNu void ControlWaterfallMist(short itemNumber); void TriggerWaterfallMist(const ItemInfo& item); void KillAllCurrentItems(short itemNumber); -void TriggerDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b); - -// TODO: use Spawn prefix instead. -void TriggerDynamicPointLight(const Vector3& pos, const Color& color, float falloff, bool castShadows = false, int hash = 0); -void TriggerDynamicSpotLight(const Vector3& pos, const Vector3& dir, const Color& color, float radius, float falloff, float distance, bool castShadows = false, int hash = 0); - void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNumber); void TriggerRocketSmoke(int x, int y, int z); void TriggerFlashSmoke(int x, int y, int z, short roomNumber); diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp index 8bad734c1..5cce1354a 100644 --- a/TombEngine/Game/effects/tomb4fx.cpp +++ b/TombEngine/Game/effects/tomb4fx.cpp @@ -1380,7 +1380,7 @@ void UpdateShockwaves() { auto lightColor = Color(shockwave.r / (float)UCHAR_MAX, shockwave.g / (float)UCHAR_MAX, shockwave.b / (float)UCHAR_MAX); auto pos = Vector3(shockwave.x, shockwave.y, shockwave.z); - TriggerDynamicPointLight(pos, lightColor, shockwave.life / 4.0f); + SpawnDynamicPointLight(pos, lightColor, shockwave.life / 4.0f); } if (shockwave.style != (int)ShockwaveStyle::Knockback) diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index d5b38f83a..162a2e0b8 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -12,7 +12,7 @@ #include "Game/Lara/lara.h" #include "Game/Lara/lara_fire.h" #include "Game/Lara/lara_helpers.h" -#include "Game/Lara/lara_optics.h" +#include "Game/Lara/Optics.h" #include "Game/Lara/lara_one_gun.h" #include "Game/Lara/lara_two_guns.h" #include "Game/pickup/pickup.h" diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp index 991ac5adb..c520056b6 100644 --- a/TombEngine/Game/missile.cpp +++ b/TombEngine/Game/missile.cpp @@ -8,6 +8,7 @@ #include "Game/effects/tomb4fx.h" #include "Game/effects/effects.h" #include "Game/effects/explosion.h" +#include "Game/effects/Light.h" #include "Game/effects/Bubble.h" #include "Game/Lara/lara.h" #include "Game/items.h" @@ -16,9 +17,10 @@ #include "Sound/sound.h" #include "Specific/level.h" -using namespace TEN::Collision::Point;; +using namespace TEN::Collision::Point; using namespace TEN::Effects::Bubble; using namespace TEN::Effects::Explosion; +using namespace TEN::Effects::Light; using namespace TEN::Math; constexpr auto MUTANT_SHARD_DAMAGE = 30; @@ -130,7 +132,7 @@ void ControlMissile(short fxNumber) break; case ID_PROJ_BOMB: - TriggerDynamicLight(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 14, 180, 100, 0); + SpawnDynamicLight(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 14, 180, 100, 0); break; } } diff --git a/TombEngine/Objects/Effects/Boss.cpp b/TombEngine/Objects/Effects/Boss.cpp index ed7cf2af4..e24cf6259 100644 --- a/TombEngine/Objects/Effects/Boss.cpp +++ b/TombEngine/Objects/Effects/Boss.cpp @@ -259,7 +259,7 @@ namespace TEN::Effects::Boss SoundEffect(SFX_TR3_BLAST_CIRCLE, &shockwavePos); } - TriggerDynamicLight( + SpawnDynamicLight( item.Pose.Position.x, item.Pose.Position.y - CLICK(2), item.Pose.Position.z, diff --git a/TombEngine/Objects/Effects/enemy_missile.cpp b/TombEngine/Objects/Effects/enemy_missile.cpp index 2ab48ec11..315ae8d13 100644 --- a/TombEngine/Objects/Effects/enemy_missile.cpp +++ b/TombEngine/Objects/Effects/enemy_missile.cpp @@ -399,6 +399,6 @@ namespace TEN::Entities::Effects } if (fx.flag1 == (int)MissileType::ClawMutantPlasma) - TriggerDynamicLight(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 8, 0, 64, 128); + SpawnDynamicLight(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 8, 0, 64, 128); } } diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp index 12319e2d1..c8404814f 100644 --- a/TombEngine/Objects/Effects/flame_emitters.cpp +++ b/TombEngine/Objects/Effects/flame_emitters.cpp @@ -94,7 +94,7 @@ namespace TEN::Entities::Effects // Constant flames. SoundEffect(SFX_TR4_FLAME_EMITTER, &item->Pose); TriggerSuperJetFlame(item, -256 - (3072 * GlobalCounter & 0x1C00), GlobalCounter & 1); - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, (GetRandomControl() & 3) + 20, (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0); @@ -163,14 +163,14 @@ namespace TEN::Entities::Effects TriggerSuperJetFlame(item, jetFlameVel, GlobalCounter & 1); } - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, (-jetFlameVel >> 10) - (GetRandomControl() & 1) + 16, (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0); } else { - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 10 - (GetRandomControl() & 1), (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0); @@ -184,7 +184,7 @@ namespace TEN::Entities::Effects // Normal flames. AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber, 2.0f); - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 16 - (GetRandomControl() & 1), (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0); @@ -241,7 +241,7 @@ namespace TEN::Entities::Effects { if (item->ItemFlags[3]) { - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 10, (((GetRandomControl() & 0x3F) + 192) * item->ItemFlags[3]) >> 8, ((GetRandomControl() & 0x1F) + 96 * item->ItemFlags[3]) >> 8, @@ -249,7 +249,7 @@ namespace TEN::Entities::Effects } else { - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 10, (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, @@ -488,7 +488,7 @@ namespace TEN::Entities::Effects } SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose); - TriggerDynamicLight(x, item->Pose.Position.y, z, 12, (GetRandomControl() & 0x3F) + 192, ((GetRandomControl() >> 4) & 0x1F) + 96, 0); + SpawnDynamicLight(x, item->Pose.Position.y, z, 12, (GetRandomControl() & 0x3F) + 192, ((GetRandomControl() >> 4) & 0x1F) + 96, 0); auto pos = item->Pose.Position; if (ItemNearLara(pos, FLAME_BIG_RADIUS)) diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp index d28616621..d575258aa 100644 --- a/TombEngine/Objects/Effects/tr5_electricity.cpp +++ b/TombEngine/Objects/Effects/tr5_electricity.cpp @@ -159,7 +159,7 @@ void ElectricityWiresControl(short itemNumber) continue; if (((GetRandomControl() & 0x0F) < 8) && flashingNode == currentEndNode) - TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 0, ((GetRandomControl() & 0x3F) + 96) / 2, (GetRandomControl() & 0x3F) + 128); + SpawnDynamicLight(pos.x, pos.y, pos.z, 10, 0, ((GetRandomControl() & 0x3F) + 96) / 2, (GetRandomControl() & 0x3F) + 128); for (int s = 0; s < 3; s++) { @@ -253,7 +253,7 @@ void ElectricityWiresControl(short itemNumber) TriggerElectricitySparks(itemPtr, j, false); } - TriggerDynamicLight( + SpawnDynamicLight( itemPtr->Pose.Position.x, itemPtr->Pose.Position.y, itemPtr->Pose.Position.z, diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp index 075bd3122..db5519fa9 100644 --- a/TombEngine/Objects/Generic/Object/burning_torch.cpp +++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp @@ -188,7 +188,7 @@ namespace TEN::Entities::Generic Random::GenerateFloat(0.4f, 0.5f), 0.0f); float lightFalloff = Random::GenerateFloat(0.04f, 0.045f); - TriggerDynamicLight(pos.x, pos.y, pos.z, lightFalloff * UCHAR_MAX, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); + SpawnDynamicLight(pos.x, pos.y, pos.z, lightFalloff * UCHAR_MAX, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); if (!(Wibble & 3)) TriggerTorchFlame(laraItem->Index, 0); @@ -287,7 +287,7 @@ namespace TEN::Entities::Generic Random::GenerateFloat(0.4f, 0.5f), 0.0f); float lightFalloff = Random::GenerateFloat(0.04f, 0.045f); - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, lightFalloff * UCHAR_MAX, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, lightFalloff * UCHAR_MAX, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); if (!(Wibble & 7)) TriggerTorchFlame(itemNumber, 1); diff --git a/TombEngine/Objects/TR2/Entity/Bartoli.cpp b/TombEngine/Objects/TR2/Entity/Bartoli.cpp index 3eedc9838..be31d6b96 100644 --- a/TombEngine/Objects/TR2/Entity/Bartoli.cpp +++ b/TombEngine/Objects/TR2/Entity/Bartoli.cpp @@ -74,26 +74,26 @@ namespace TEN::Entities::Creatures::TR2 // Spawn light. auto lightPos = item.Pose.Position.ToVector3() + Vector3(0.0f, -CLICK(1), 0.0f); auto lightColor = Color(0.0f,Random::GenerateFloat(0.7f, 1.0f), Random::GenerateFloat(0.2f, 0.3f)); - TriggerDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(6), BLOCK(12))); + SpawnDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(6), BLOCK(12))); // Handle transformation. if (effectTimer == timeExplosion1) { - TriggerDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); + SpawnDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); SpawnBartoliTransformEffect(item, ID_SPHERE_OF_DOOM); SoundEffect(SFX_TR2_MARCO_BARTOLLI_TRANSFORM, &item.Pose); } if (effectTimer == timeExplosion2) { - TriggerDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); + SpawnDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); SpawnBartoliTransformEffect(item, ID_SPHERE_OF_DOOM2); SoundEffect(SFX_TR2_MARCO_BARTOLLI_TRANSFORM, &item.Pose); } if (effectTimer == timeExplosion3) { - TriggerDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); + SpawnDynamicPointLight(lightPos, lightColor, Random::GenerateFloat(BLOCK(12), BLOCK(24))); SpawnBartoliTransformEffect(item, ID_SPHERE_OF_DOOM3); SoundEffect(SFX_TR2_MARCO_BARTOLLI_TRANSFORM, &item.Pose); item.Animation.FrameNumber = animationFrameEnd; diff --git a/TombEngine/Objects/TR2/Entity/Dragon.cpp b/TombEngine/Objects/TR2/Entity/Dragon.cpp index 893b5ff2b..7d64749ff 100644 --- a/TombEngine/Objects/TR2/Entity/Dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/Dragon.cpp @@ -195,7 +195,7 @@ namespace TEN::Entities::Creatures::TR2 Random::GenerateFloat(0.2f, 0.3f)); float falloff = Random::GenerateFloat(BLOCK(6), BLOCK(20)); - TriggerDynamicPointLight(pos, color, falloff); + SpawnDynamicPointLight(pos, color, falloff); } break; @@ -207,7 +207,7 @@ namespace TEN::Entities::Creatures::TR2 Random::GenerateFloat(0.0f, 0.1f)); float falloff = Random::GenerateFloat(BLOCK(6), BLOCK(12)); - TriggerDynamicPointLight(pos, color, falloff); + SpawnDynamicPointLight(pos, color, falloff); } break; } diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp index 01c55541f..8b549b730 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp @@ -81,12 +81,12 @@ namespace TEN::Entities::Creatures::TR2 { if (item->Animation.ActiveState != WORKER_FLAME_STATE_ATTACK && item->Animation.ActiveState != WORKER_FLAME_STATE_WALK_FORWARD_ATTACK) { - TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 10, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7); + SpawnDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 10, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7); TriggerPilotFlame(itemNumber, WorkerFlamethrowerBite.BoneID); } else { - TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 14, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7); + SpawnDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 14, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7); ThrowFire(itemNumber, WorkerFlamethrowerBite.BoneID, WorkerFlamethrowerOffset, WorkerFlamethrowerOffset); } diff --git a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp index 0597ede22..8ab98777b 100644 --- a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp +++ b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp @@ -228,7 +228,7 @@ namespace TEN::Entities::Creatures::TR3 SpawnElectricity(origin.ToVector3(), target.ToVector3(), Random::GenerateInt(25, 50), 100, 200, 200, 30, (int)(int)(int)ElectricityFlags::ThinIn | (int)(int)ElectricityFlags::ThinOut, 4, 12); SpawnElectricity(origin.ToVector3(), target.ToVector3(), Random::GenerateInt(25, 50), 100, 250, 255, 30, (int)(int)(int)ElectricityFlags::ThinIn | (int)(int)ElectricityFlags::ThinOut, 2, 12); - TriggerDynamicLight(origin.x, origin.y, origin.z, 20, 0, 255, 0); + SpawnDynamicLight(origin.x, origin.y, origin.z, 20, 0, 255, 0); SpawnLizard(item); } else @@ -256,7 +256,7 @@ namespace TEN::Entities::Creatures::TR3 SpawnElectricity(origin.ToVector3(), target.ToVector3(), 1, 20, 160, 160, 30, (int)(int)(int)ElectricityFlags::ThinIn | (int)ElectricityFlags::Spline | (int)ElectricityFlags::MoveEnd, 12, 12); SpawnElectricity(origin.ToVector3(), target.ToVector3(), 1, 80, 160, 160, 30, (int)(int)(int)ElectricityFlags::ThinIn | (int)ElectricityFlags::Spline | (int)ElectricityFlags::MoveEnd, 5, 12); - TriggerDynamicLight(origin.x, origin.y, origin.z, 20, 0, 255, 255); + SpawnDynamicLight(origin.x, origin.y, origin.z, 20, 0, 255, 255); auto hitPos = Vector3i::Zero; if (ObjectOnLOS2(&origin, &target, &hitPos, nullptr, ID_LARA) == creature.Enemy->Index) diff --git a/TombEngine/Objects/TR3/Entity/SealMutant.cpp b/TombEngine/Objects/TR3/Entity/SealMutant.cpp index aa297dbe2..a937346fa 100644 --- a/TombEngine/Objects/TR3/Entity/SealMutant.cpp +++ b/TombEngine/Objects/TR3/Entity/SealMutant.cpp @@ -179,7 +179,7 @@ namespace TEN::Entities::Creatures::TR3 auto pos = GetJointPosition(item, SealMutantGasBite.BoneID, Vector3(0.0f, -SEAL_MUTANT_FLAME_LIGHT_Y_OFFSET, 0.0f)); auto color = Color(Random::GenerateFloat(0.75f, 1.0f), Random::GenerateFloat(0.4f, 0.5f), Random::GenerateFloat(0.0f, 0.25f)); float falloff = Random::GenerateFloat(BLOCK(1.5f), BLOCK(2.5f)); - TriggerDynamicPointLight(pos.ToVector3(), color, falloff); + SpawnDynamicPointLight(pos.ToVector3(), color, falloff); } } else if (TestAnimFrameRange(item, 1, 124)) diff --git a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp index 4b5336059..72a66d895 100644 --- a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp +++ b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp @@ -224,7 +224,7 @@ namespace TEN::Entities::Creatures::TR3 (item.Animation.AnimNumber == GetAnimIndex(item, SOPHIALEIGH_ANIM_SCEPTER_SHOOT) && item.Animation.FrameNumber > GetFrameIndex(&item, 39) && item.Animation.FrameNumber < GetFrameIndex(&item, 47)) || (item.Animation.AnimNumber == GetAnimIndex(item, SOPHIALEIGH_ANIM_SCEPTER_SMALL_SHOOT) && item.Animation.FrameNumber > GetFrameIndex(&item, 14) && item.Animation.FrameNumber < GetFrameIndex(&item, 18))) { - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, item.ItemFlags[1] + SOPHIALEIGH_LIGHTNING_GLOW_SIZE, SOPHIALEIGH_EFFECT_COLOR.x * UCHAR_MAX, SOPHIALEIGH_EFFECT_COLOR.y * UCHAR_MAX, SOPHIALEIGH_EFFECT_COLOR.z * UCHAR_MAX); @@ -234,7 +234,7 @@ namespace TEN::Entities::Creatures::TR3 } else if (item.Animation.AnimNumber == GetAnimIndex(item, SOPHIALEIGH_ANIM_SUMMON_END) && item.Animation.FrameNumber >= GetFrameIndex(&item, 3) && item.ItemFlags[1] > 0) { - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, item.ItemFlags[1] + SOPHIALEIGH_LIGHTNING_GLOW_SIZE, SOPHIALEIGH_EFFECT_COLOR.x * UCHAR_MAX, SOPHIALEIGH_EFFECT_COLOR.y * UCHAR_MAX, SOPHIALEIGH_EFFECT_COLOR.z * UCHAR_MAX); diff --git a/TombEngine/Objects/TR3/Entity/TwinAutoGun.cpp b/TombEngine/Objects/TR3/Entity/TwinAutoGun.cpp index e944f5062..782c342b9 100644 --- a/TombEngine/Objects/TR3/Entity/TwinAutoGun.cpp +++ b/TombEngine/Objects/TR3/Entity/TwinAutoGun.cpp @@ -116,7 +116,7 @@ namespace TEN::Entities::Creatures::TR3 Random::GenerateFloat(0.75f, 1.0f), Random::GenerateFloat(0.5f, 0.6f), Random::GenerateFloat(0.0f, 0.25f)); - TriggerDynamicLight(lightPos.x, lightPos.y, lightPos.z, 2 * item.ItemFlags[0] + 8, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); + SpawnDynamicLight(lightPos.x, lightPos.y, lightPos.z, 2 * item.ItemFlags[0] + 8, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); autoGun.MuzzleFlash[0].Bite = TwinAutoGunLeftBite; autoGun.MuzzleFlash[0].SwitchToMuzzle2 = true; @@ -139,7 +139,7 @@ namespace TEN::Entities::Creatures::TR3 Random::GenerateFloat(0.75f, 1.0f), Random::GenerateFloat(0.5f, 0.6f), Random::GenerateFloat(0.0f, 0.25f)); - TriggerDynamicLight(lightPos.x, lightPos.y, lightPos.z, 2 * item.ItemFlags[0] + 8, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); + SpawnDynamicLight(lightPos.x, lightPos.y, lightPos.z, 2 * item.ItemFlags[0] + 8, lightColor.R() * UCHAR_MAX, lightColor.G() * UCHAR_MAX, lightColor.B() * UCHAR_MAX); autoGun.MuzzleFlash[1].Bite = TwinAutoGunRightBite; autoGun.MuzzleFlash[1].SwitchToMuzzle2 = true; diff --git a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp index 1e858ae6f..a86fd07c6 100644 --- a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp +++ b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp @@ -113,7 +113,7 @@ namespace TEN::Entities::Creatures::TR3 // Spawn light. auto pos = GetJointPosition(&item, WaspVenomSackBite); - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, item.ItemFlags[0], WaspVenomSackLightColor.x * UCHAR_MAX, diff --git a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp index a92765cf8..df6fd0592 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp @@ -201,7 +201,7 @@ namespace TEN::Entities::Creatures::TR3 r = (r * bright) / 16; g = (g * bright) / 16; b = (b * bright) / 16; - TriggerDynamicLight(pos.x, pos.y, pos.z, bright, r, g, b); + SpawnDynamicLight(pos.x, pos.y, pos.z, bright, r, g, b); } } diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 4c1c60021..11e65a7b0 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -70,12 +70,12 @@ namespace TEN::Entities::Creatures::TR3 if (item->Animation.ActiveState != 6 && item->Animation.ActiveState != 11) { - TriggerDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 6, 24 - ((randomInt / 16) & 3), 16 - ((randomInt / 64) & 3), randomInt & 3); + SpawnDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 6, 24 - ((randomInt / 16) & 3), 16 - ((randomInt / 64) & 3), randomInt & 3); TriggerPilotFlame(itemNumber, 9); } else { - TriggerDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 10, 31 - ((randomInt / 16) & 3), 24 - ((randomInt / 64) & 3), randomInt & 7); + SpawnDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 10, 31 - ((randomInt / 16) & 3), 24 - ((randomInt / 64) & 3), randomInt & 7); } if (item->HitPoints <= 0) diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp index 9a4ed5ac5..c5789243c 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp @@ -475,7 +475,7 @@ namespace TEN::Entities::Creatures::TR3 if (LightIntensityTable[fx.flag1]) { - TriggerDynamicLight( + SpawnDynamicLight( fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, LightIntensityTable[fx.flag1], 31 - ((GetRandomControl() / 16) & 3), @@ -657,14 +657,14 @@ namespace TEN::Entities::Creatures::TR3 auto handPos = GetJointPosition(item, TonyLeftHandBite); TriggerTonyFlame(itemNumber, 13); - TriggerDynamicLight(handPos.x, handPos.y, handPos.z, 12, r, g, b); + SpawnDynamicLight(handPos.x, handPos.y, handPos.z, 12, r, g, b); if (item->Animation.ActiveState == TONY_STATE_SHOOT_CEILING || item->Animation.ActiveState == TONY_STATE_FLIPMAP) { handPos = GetJointPosition(item, TonyRightHandBite); TriggerTonyFlame(itemNumber, 14); - TriggerDynamicLight(handPos.x, handPos.y, handPos.z, 12, r, g, b); + SpawnDynamicLight(handPos.x, handPos.y, handPos.z, 12, r, g, b); } } diff --git a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp index 436ade346..27ae0d230 100644 --- a/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp +++ b/TombEngine/Objects/TR3/Trap/ElectricCleaner.cpp @@ -151,7 +151,7 @@ namespace TEN::Entities::Traps auto pos = GetJointPosition(&item, joint, Vector3i(-160, -8, 16)); byte c = Random::GenerateInt(0, 64) + 128; - TriggerDynamicLight(pos.x, pos.y, pos.z, 10, c >> 2, c >> 1, c); + SpawnDynamicLight(pos.x, pos.y, pos.z, 10, c >> 2, c >> 1, c); auto& spark = GetFreeSparkParticle(); diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp index 94d29c5ce..dc9f992bb 100644 --- a/TombEngine/Objects/TR3/Trap/train.cpp +++ b/TombEngine/Objects/TR3/Trap/train.cpp @@ -76,7 +76,7 @@ namespace TEN::Entities::Traps item.Pose.Orientation.x = -(rh - floorHeight) * 2; - TriggerDynamicLight(item.Pose.Position.x + BLOCK(3) * sinY, item.Pose.Position.y, item.Pose.Position.z + BLOCK(3) * cosY, 16, 31, 31, 31); + SpawnDynamicLight(item.Pose.Position.x + BLOCK(3) * sinY, item.Pose.Position.y, item.Pose.Position.z + BLOCK(3) * cosY, 16, 31, 31, 31); if (item.ItemFlags[1] != TRAIN_VEL) { diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp index 5fc83591b..2ae111057 100644 --- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp +++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp @@ -236,7 +236,7 @@ namespace TEN::Entities::Vehicles float mult = Random::GenerateFloat(0.7f, 1.0f); byte r = (byte)(mult * 190.0f); byte g = (byte)(mult * 100.0f); - TriggerDynamicLight(pos.x, pos.y, pos.z, 2, r, g, 0); + SpawnDynamicLight(pos.x, pos.y, pos.z, 2, r, g, 0); } } } diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp index 60ea75f8a..90046ddb5 100644 --- a/TombEngine/Objects/TR3/Vehicles/upv.cpp +++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp @@ -333,7 +333,7 @@ namespace TEN::Entities::Vehicles else origin = GameVector(pos, UPVItem->RoomNumber); - TriggerDynamicLight(pos.x, pos.y, pos.z, 16 + (lp << 3), random, random, random); + SpawnDynamicLight(pos.x, pos.y, pos.z, 16 + (lp << 3), random, random, random); } if (UPV->HarpoonTimer) diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp index 9eccd1b87..b843f6751 100644 --- a/TombEngine/Objects/TR4/Entity/Wraith.cpp +++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp @@ -630,7 +630,7 @@ namespace TEN::Entities::TR4 b = wraithPtr[1].b; } - TriggerDynamicLight( + SpawnDynamicLight( wraithPtr[0].Position.x, wraithPtr[0].Position.y, wraithPtr[0].Position.z, diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index 71284ef93..2ddbbd642 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -91,7 +91,7 @@ namespace TEN::Entities::TR4 TriggerFireFlame(spherePtr->Center.x, spherePtr->Center.y, spherePtr->Center.z, FlameType::Medium); } - TriggerDynamicLight( + SpawnDynamicLight( item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, diff --git a/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp b/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp index c7dbbca90..46d6fe6c2 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_demigod.cpp @@ -713,7 +713,7 @@ namespace TEN::Entities::TR4 TriggerShockwave((Pose*)&pos, 24, 88, 200, 128, 128, 128, 32, EulerAngles::Identity, 8, true, false, true, (int)ShockwaveStyle::Normal); auto lightColor = Color(1.0f, 0.4f, 0.2f); - TriggerDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(6)); + SpawnDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(6)); Camera.bounce = -128; diff --git a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp index 98791d0f5..1a183f0cf 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp @@ -159,7 +159,7 @@ namespace TEN::Entities::TR4 item->MeshBits = -98305; pos = GetJointPosition(item, 11, Vector3i(0, -144, -1024)); - TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); + SpawnDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); if (item->ItemFlags[0] < 0) item->ItemFlags[0] = 0; diff --git a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp index cd657f137..62f57a457 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp @@ -124,7 +124,7 @@ namespace TEN::Entities::TR4 SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose); short random = GetRandomControl(); - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, 15, 255 - ((random >> 4) & 0x1F), @@ -501,7 +501,7 @@ namespace TEN::Entities::TR4 ((random >> 10) & 0x3F) + pos1.z - 64, FlameType::Trail); - TriggerDynamicLight( + SpawnDynamicLight( pos1.x - 32, pos1.y - 64, pos1.z - 32, @@ -516,7 +516,7 @@ namespace TEN::Entities::TR4 else { TriggerMetalSparks(pos1.x, pos1.y, pos1.z, -1, -1, 0, Vector3(1.0f, 1.0f, 0.3f), 1); - TriggerDynamicLight( + SpawnDynamicLight( pos1.x, pos1.y, pos1.z, 10, random & 0x1F, @@ -526,7 +526,7 @@ namespace TEN::Entities::TR4 } else { - TriggerDynamicLight( + SpawnDynamicLight( pos1.x - 32, pos1.y - 64, pos1.z - 32, @@ -544,7 +544,7 @@ namespace TEN::Entities::TR4 } else { - TriggerDynamicLight( + SpawnDynamicLight( pos1.x, pos1.y, pos1.z, 10, random & 0x1F, diff --git a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp index 6a54d69eb..fb228cf8b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp @@ -81,7 +81,7 @@ namespace TEN::Entities::TR4 if (flashDuration) { auto pos = GetJointPosition(item, SentryGunBite); - TriggerDynamicLight(pos.x, pos.y, pos.z, 4 * flashDuration + 12, 24, 16, 4); + SpawnDynamicLight(pos.x, pos.y, pos.z, 4 * flashDuration + 12, 24, 16, 4); flashDuration--; } diff --git a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp index 4ef807d66..f7132f71d 100644 --- a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp @@ -71,7 +71,7 @@ namespace TEN::Entities::TR4 fade = 0; AddFire(item->Pose.Position.x, item->Pose.Position.y - 620, item->Pose.Position.z, item->RoomNumber, 0.5f, fade); - TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y - 768, item->Pose.Position.z, 12, r, g, b); + SpawnDynamicLight(item->Pose.Position.x, item->Pose.Position.y - 768, item->Pose.Position.z, 12, r, g, b); return; } diff --git a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp index 27d8f26fa..93e418d7b 100644 --- a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp @@ -35,7 +35,7 @@ namespace TEN::Entities::TR4 auto pos = GetJointPosition(item, 0); byte color = (GetRandomControl() & 0x1F) + 192; - TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0); + SpawnDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0); int height = GetPointCollision(*item).GetFloorHeight(); diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp index 159674bc9..579185851 100644 --- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp +++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp @@ -852,7 +852,7 @@ namespace TEN::Entities::Vehicles if (IsHeld(In::Brake)) { auto pos = GetJointPosition(jeepItem, 11, Vector3i(0, -144, -1024)); - TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); + SpawnDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); jeepItem->MeshBits.Set(17); jeepItem->MeshBits.Clear(JeepBrakeLightJoints); diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp index 8a5774676..7940510b4 100644 --- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp +++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp @@ -324,7 +324,7 @@ namespace TEN::Entities::Vehicles int random = (motorbike->LightPower * 2) - (GetRandomControl() & 0xF); // TODO: Use target as direction vector for spotlight. - TriggerDynamicLight(origin.x, origin.y, origin.z, 8, random, random / 2, 0); + SpawnDynamicLight(origin.x, origin.y, origin.z, 8, random, random / 2, 0); } static void TriggerMotorbikeExhaustSmoke(int x, int y, int z, short angle, short speed, bool moving) @@ -1040,7 +1040,7 @@ namespace TEN::Entities::Vehicles if (IsHeld(In::Brake)) { auto pos = GetJointPosition(motorbikeItem, 0, Vector3i(0, -144, -1024)); - TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); + SpawnDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); motorbikeItem->MeshBits.Set(MotorbikeBrakeLightJoints); } diff --git a/TombEngine/Objects/TR5/Entity/AutoGun.cpp b/TombEngine/Objects/TR5/Entity/AutoGun.cpp index 4cf4f89d8..aa4de1569 100644 --- a/TombEngine/Objects/TR5/Entity/AutoGun.cpp +++ b/TombEngine/Objects/TR5/Entity/AutoGun.cpp @@ -126,7 +126,7 @@ namespace TEN::Entities::Creatures::TR5 item.MeshBits.Set(AutoGunFlashJoints); auto lightColor = Vector3(Random::GenerateFloat(0.75f, 0.85f), Random::GenerateFloat(0.5f, 0.6f), 0.0f) * 255; - TriggerDynamicLight(origin.x, origin.y, origin.z, 10, lightColor.x, lightColor.y, lightColor.z); + SpawnDynamicLight(origin.x, origin.y, origin.z, 10, lightColor.x, lightColor.y, lightColor.z); // Spawn blood. if (Random::TestProbability(AUTO_GUN_BLOOD_EFFECT_CHANCE)) diff --git a/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp b/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp index 3c35dc53a..651554277 100644 --- a/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp +++ b/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp @@ -221,7 +221,7 @@ namespace TEN::Entities::Creatures::TR5 short green = blue >> 2; short red = 0; - TriggerDynamicLight(pos1.x, pos1.y, pos1.z, item.ItemFlags[i] + 8, red, green, blue); + SpawnDynamicLight(pos1.x, pos1.y, pos1.z, item.ItemFlags[i] + 8, red, green, blue); item.ItemFlags[i]--; } else diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp index 65d0fdd13..bbd2ae4fd 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp @@ -215,7 +215,7 @@ namespace TEN::Entities::Creatures::TR5 SpawnElectricityGlow(pos, 48, 32, 32, 64); SpawnCyborgSpark(pos); - TriggerDynamicLight(pos.x, pos.y, pos.z, Random::GenerateInt(4, 20), 31, 63, 127); + SpawnDynamicLight(pos.x, pos.y, pos.z, Random::GenerateInt(4, 20), 31, 63, 127); SoundEffect(SFX_TR5_HITMAN_SPARKS_SHORT, &item.Pose); diff --git a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp index 193d21cde..b4c990701 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp @@ -96,7 +96,7 @@ namespace TEN::Entities::Creatures::TR5 if (GunShipCounter >= 15) return AnimateItem(item); - TriggerDynamicLight( + SpawnDynamicLight( origin.x, origin.y, origin.z, 16, (GetRandomControl() & 0x3F) + 96, (GetRandomControl() & 0x1F) + 64, @@ -135,7 +135,7 @@ namespace TEN::Entities::Creatures::TR5 } else { - TriggerDynamicLight( + SpawnDynamicLight( origin.x, origin.y, origin.z, 16, (GetRandomControl() & 0x3F) + 96, diff --git a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp index 0be4cdc39..256436d61 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp @@ -369,12 +369,12 @@ namespace TEN::Entities::Creatures::TR5 { SpawnGuardianSparks(origin1.ToVector3(), colorSparks, 3); SpawnElectricityGlow(origin1.ToVector3(), (GetRandomControl() & 3) + 32, color.x, color.y, color.z); - TriggerDynamicLight(origin1.x, origin1.y, origin1.z, (GetRandomControl() & 3) + 16, color.x, color.y, color.z); + SpawnDynamicLight(origin1.x, origin1.y, origin1.z, (GetRandomControl() & 3) + 16, color.x, color.y, color.z); if (!guardian->LOS[i] && guardian->fireArcs[i] != nullptr) { SpawnElectricityGlow(guardian->fireArcs[i]->pos4, (GetRandomControl() & 3) + 16, color.x, color.y, color.z); - TriggerDynamicLight(guardian->fireArcs[i]->pos4.x, guardian->fireArcs[i]->pos4.y, guardian->fireArcs[i]->pos4.z, (GetRandomControl() & 3) + 6, color.x, color.y, color.z); + SpawnDynamicLight(guardian->fireArcs[i]->pos4.x, guardian->fireArcs[i]->pos4.y, guardian->fireArcs[i]->pos4.z, (GetRandomControl() & 3) + 6, color.x, color.y, color.z); SpawnGuardianSparks(guardian->fireArcs[i]->pos4, colorSparks, 3); } } @@ -579,7 +579,7 @@ namespace TEN::Entities::Creatures::TR5 } SpawnElectricityGlow(target, (GetRandomControl() & 3) + size + 8, color.x, color.y, color.z); - TriggerDynamicLight(target.x, target.y, target.z, (GetRandomControl() & 3) + 16, color.x, color.y, color.z); + SpawnDynamicLight(target.x, target.y, target.z, (GetRandomControl() & 3) + 16, color.x, color.y, color.z); } if (!(GlobalCounter & 3)) diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp index 997be4ad3..b787dfa92 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp @@ -439,9 +439,9 @@ namespace TEN::Entities::Creatures::TR5 color = (deltaFrame2 * ((GetRandomControl() & 0x3F) + 128)) / 16; if (item->TriggerFlags) - TriggerDynamicLight(pos2.x, pos2.y, pos2.z, 16, 0, color, color / 2); + SpawnDynamicLight(pos2.x, pos2.y, pos2.z, 16, 0, color, color / 2); else - TriggerDynamicLight(pos2.x, pos2.y, pos2.z, 16, 0, color / 2, color); + SpawnDynamicLight(pos2.x, pos2.y, pos2.z, 16, 0, color / 2, color); for (int i = 0; i < 2; i++) { @@ -599,7 +599,7 @@ namespace TEN::Entities::Creatures::TR5 TriggerShockwave(&Pose(pos1), 16, 160, 64, 0, color / 2, color, 48, EulerAngles::Identity, 1, true, false, true, (int)ShockwaveStyle::Normal); auto lightColor = Color(0.4f, 0.3f, 0.0f); - TriggerDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(2.5f)); + SpawnDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(2.5f)); } deltaFrame = item->Animation.FrameNumber - GetAnimData(item).frameBase; @@ -614,11 +614,11 @@ namespace TEN::Entities::Creatures::TR5 if (item->ItemFlags[3]) { - TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 8, 0, color / 4, color / 2); + SpawnDynamicLight(pos1.x, pos1.y, pos1.z, 8, 0, color / 4, color / 2); } else { - TriggerDynamicLight(pos1.x, pos1.y - 64, pos1.z, 18, 0, color / 4, color / 2); + SpawnDynamicLight(pos1.x, pos1.y - 64, pos1.z, 18, 0, color / 4, color / 2); } } else @@ -628,7 +628,7 @@ namespace TEN::Entities::Creatures::TR5 if (item->ItemFlags[3]) { auto lightColor = Color(0.0f, 0.4f, 1.0f); - TriggerDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(4)); + SpawnDynamicPointLight(pos.ToVector3(), lightColor, BLOCK(4)); } } } @@ -710,7 +710,7 @@ namespace TEN::Entities::Creatures::TR5 { RomanStatueData.Count--; color = (RomanStatueData.Count * ((GetRandomControl() & 0x3F) + 128)) / 16; - TriggerDynamicLight(RomanStatueData.Position.x, RomanStatueData.Position.y, RomanStatueData.Position.z, 16, 0, color, color / 2); + SpawnDynamicLight(RomanStatueData.Position.x, RomanStatueData.Position.y, RomanStatueData.Position.z, 16, 0, color, color / 2); } deltaFrame = item->Animation.FrameNumber - GetAnimData(item).frameBase; @@ -762,7 +762,7 @@ namespace TEN::Entities::Creatures::TR5 if (i == 0) { - TriggerDynamicLight( + SpawnDynamicLight( pos2.x, pos2.y, pos2.z, 8, 0, diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp index cd102bd45..f3f8fb60e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp @@ -324,7 +324,7 @@ namespace TEN::Entities::Creatures::TR5 { distance = BLOCK(16) - distance; byte color = (GetRandomControl() & 0xF) + (distance / 128) + 64; - TriggerDynamicLight(target.x, target.y, target.z, (GetRandomControl() & 1) + (distance / 2048) + 12, color / 2, color, color / 2); + SpawnDynamicLight(target.x, target.y, target.z, (GetRandomControl() & 1) + (distance / 2048) + 12, color / 2, color, color / 2); } } diff --git a/TombEngine/Objects/TR5/Light/tr5_light.cpp b/TombEngine/Objects/TR5/Light/tr5_light.cpp index a032a5c82..e28d76e14 100644 --- a/TombEngine/Objects/TR5/Light/tr5_light.cpp +++ b/TombEngine/Objects/TR5/Light/tr5_light.cpp @@ -31,7 +31,7 @@ void PulseLightControl(short itemNumber) if (pulse > 255) pulse = 255; - TriggerDynamicLight( + SpawnDynamicLight( item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, @@ -50,7 +50,7 @@ void TriggerAlertLight(int x, int y, int z, int r, int g, int b, short angle, sh auto target = GameVector(Geometry::TranslatePoint(origin.ToVector3(), angle * 16, BLOCK(16))); if (!LOS(&origin, &target)) - TriggerDynamicLight(target.x, target.y, target.z, falloff, r, g, b); + SpawnDynamicLight(target.x, target.y, target.z, falloff, r, g, b); } void StrobeLightControl(short itemNumber) @@ -74,7 +74,7 @@ void StrobeLightControl(short itemNumber) item->RoomNumber, 12); - TriggerDynamicLight( + SpawnDynamicLight( item->Pose.Position.x + 256 * phd_sin(item->Pose.Orientation.y + 22528), item->Pose.Position.y - 768, item->Pose.Position.z + 256 * phd_cos(item->Pose.Orientation.y + 22528), @@ -89,7 +89,7 @@ void ColorLightControl(short itemNumber) if (TriggerActive(item)) { - TriggerDynamicLight( + SpawnDynamicLight( item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, @@ -192,7 +192,7 @@ void ElectricalLightControl(short itemNumber) } } - TriggerDynamicLight( + SpawnDynamicLight( item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, @@ -225,7 +225,7 @@ void BlinkingLightControl(short itemNumber) { auto pos = GetJointPosition(item, 0); - TriggerDynamicLight( + SpawnDynamicLight( pos.x, pos.y, pos.z, 16, item->Model.Color.x * SCHAR_MAX, diff --git a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp index 45db36846..3dc5637e1 100644 --- a/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp +++ b/TombEngine/Objects/TR5/Trap/LaserBarrier.cpp @@ -100,7 +100,7 @@ namespace TEN::Entities::Traps static void SpawnLaserBarrierLight(const ItemInfo& item, float intensity, float amplitude) { float intensityNorm = intensity - Random::GenerateFloat(0.0f, amplitude); - TriggerDynamicLight( + SpawnDynamicLight( item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, 8, intensityNorm * (item.Model.Color.x / 2), diff --git a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp index 2154be045..27ca31e30 100644 --- a/TombEngine/Objects/TR5/Trap/LaserBeam.cpp +++ b/TombEngine/Objects/TR5/Trap/LaserBeam.cpp @@ -75,7 +75,7 @@ namespace TEN::Entities::Traps constexpr auto LASER_BEAM_FALLOFF = BLOCK(1.5f); float intensityNorm = intensity - Random::GenerateFloat(0.0f, amplitudeMax); - TriggerDynamicPointLight(pos, color * intensityNorm, LASER_BEAM_FALLOFF); + SpawnDynamicPointLight(pos, color * intensityNorm, LASER_BEAM_FALLOFF); } void LaserBeamEffect::StoreInterpolationData() diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp index bf946e959..d0fcd96fe 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp +++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp @@ -269,7 +269,7 @@ namespace TEN::Scripting::Effects { auto color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); int rad = (float)(USE_IF_HAVE(int, radius, 20) * BLOCK(0.25f)); - TriggerDynamicPointLight(pos.ToVector3(), color, rad, USE_IF_HAVE(bool, castShadows, false), GetHash(USE_IF_HAVE(std::string, name, std::string()))); + SpawnDynamicPointLight(pos.ToVector3(), color, rad, USE_IF_HAVE(bool, castShadows, false), GetHash(USE_IF_HAVE(std::string, name, std::string()))); } /***Emit dynamic directional spotlight that lasts for a single frame. @@ -290,7 +290,7 @@ namespace TEN::Scripting::Effects int rad = (float)(USE_IF_HAVE(int, radius, 10) * BLOCK(0.25f)); int fallOff = (float)(USE_IF_HAVE(int, falloff, 5) * BLOCK(0.25f)); int dist = (float)(USE_IF_HAVE(int, distance, 20) * BLOCK(0.25f)); - TriggerDynamicSpotLight(pos.ToVector3(), dir.ToVector3(), color, rad, fallOff, dist, USE_IF_HAVE(bool, castShadows, false), GetHash(USE_IF_HAVE(std::string, name, std::string()))); + SpawnDynamicSpotLight(pos.ToVector3(), dir.ToVector3(), color, rad, fallOff, dist, USE_IF_HAVE(bool, castShadows, false), GetHash(USE_IF_HAVE(std::string, name, std::string()))); } /***Emit blood. diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 26cebdd14..c32f575be 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -448,6 +448,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -469,7 +470,6 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. - @@ -513,6 +513,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -999,6 +1000,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -1031,13 +1033,13 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. - + From a9af06e2fa82dce56320a11473f240a5d668f4b0 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:52:13 +0100 Subject: [PATCH 23/26] Revert light collector changes which caused static mesh lights to break --- TombEngine/Renderer/RendererFrame.cpp | 142 +++++++++++++++++--------- 1 file changed, 91 insertions(+), 51 deletions(-) diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index c47b5f33d..181993140 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -382,7 +382,7 @@ namespace TEN::Renderer void Renderer::CollectItems(short roomNumber, RenderView& renderView) { - if (_rooms.size() < roomNumber) + if (_rooms.size() <= roomNumber) return; auto& rendererRoom = _rooms[roomNumber]; @@ -484,7 +484,7 @@ namespace TEN::Renderer void Renderer::CollectStatics(short roomNumber, RenderView& renderView) { - if (_rooms.size() < roomNumber) + if (_rooms.size() <= roomNumber) return; auto& room = _rooms[roomNumber]; @@ -540,7 +540,7 @@ namespace TEN::Renderer } else { - // Collecy only dynamic lights and use cached lights from rooms + // Collect only dynamic lights and use cached lights from rooms CollectLights(mesh->Pose.Position.ToVector3(), 1024, room.RoomNumber, NO_VALUE, false, true, &mesh->CachedRoomLights, &lights); } } @@ -558,7 +558,7 @@ namespace TEN::Renderer } } - void Renderer::CollectLights(const Vector3& pos, float radius, int roomNumber, int prevRoomNumber, bool prioritizeShadowLight, bool useCachedRoomLights, std::vector* roomsLights, std::vector* outputLights) + void Renderer::CollectLights(const Vector3& position, float radius, int roomNumber, int prevRoomNumber, bool prioritizeShadowLight, bool useCachedRoomLights, std::vector* roomsLights, std::vector* outputLights) { if (_rooms.size() <= roomNumber) return; @@ -566,45 +566,31 @@ namespace TEN::Renderer // Now collect lights from dynamic list and from rooms std::vector tempLights; tempLights.reserve(MAX_LIGHTS_DRAW); - + auto& room = _rooms[roomNumber]; RendererLight* brightestLight = nullptr; - float highestIntensity = 0.0f; - - auto calculateIntensity = [](float distSqr, const RendererLight& light, float radius) -> std::optional - { - if (distSqr >= SQUARE(BLOCK(20)) || distSqr > SQUARE(light.Out + radius)) - return std::nullopt; // Light is too far. - - float distance = sqrt(distSqr); - float attenuation = 1.0f - distance / light.Out; - return attenuation * light.Intensity * light.Luma; - }; - - auto processLight = [&](RendererLight& light, float distSqr, int dynamicFlag) - { - float distance = sqrt(distSqr); - float intensity = calculateIntensity(distSqr, light, radius).value_or(0.0f); - - if (intensity <= EPSILON) - return; - - if ((light.Type == LightType::Point || light.Type == LightType::Spot) && - light.CastShadows && prioritizeShadowLight && intensity >= highestIntensity) - { - highestIntensity = intensity; - brightestLight = &light; - } - - tempLights.push_back({ &light, intensity, distance, dynamicFlag }); - }; + float brightest = 0.0f; // Dynamic lights have the priority for (auto& light : _dynamicLights[_dynamicLightList]) { - float distSqr = Vector3::DistanceSquared(pos, light.Position); - processLight(light, distSqr, 1); + float distSqr = Vector3::DistanceSquared(position, light.Position); + + // Collect only lights nearer than 20 sectors + if (distSqr >= SQUARE(BLOCK(20))) + continue; + + // Check the out radius + if (distSqr > SQUARE(light.Out + radius)) + continue; + + float distance = sqrt(distSqr); + float attenuation = 1.0f - distance / light.Out; + float intensity = attenuation * light.Intensity * light.Luma; + + RendererLightNode node = { &light, intensity, distance, 1 }; + tempLights.push_back(node); } if (!useCachedRoomLights) @@ -613,8 +599,15 @@ namespace TEN::Renderer for (int roomToCheck : room.Neighbors) { auto& currentRoom = _rooms[roomToCheck]; - for (auto& light : currentRoom.Lights) + int lightCount = (int)currentRoom.Lights.size(); + + for (int j = 0; j < lightCount; j++) { + auto& light = currentRoom.Lights[j]; + + float intensity = 0; + float dist = 0; + // Check only lights different from sun. if (light.Type == LightType::Sun) { @@ -623,25 +616,72 @@ namespace TEN::Renderer continue; // Sun is added without distance checks. - float intensity = light.Intensity * Luma(light.Color); - RendererLightNode node = { &light, intensity, 0.0f, 0 }; - tempLights.push_back(node); - - if (roomsLights != nullptr) - roomsLights->push_back(node); + intensity = light.Intensity * Luma(light.Color); } - else if (light.Type == LightType::Point || - light.Type == LightType::Shadow || - light.Type == LightType::Spot) + else if (light.Type == LightType::Point || light.Type == LightType::Shadow) { - float distSqr = Vector3::DistanceSquared(pos, light.Position); - processLight(light, distSqr, 0); + float distSqr = Vector3::DistanceSquared(position, light.Position); + + // Collect only lights nearer than 20 blocks. + if (distSqr >= SQUARE(BLOCK(20))) + continue; + + // Check out radius. + if (distSqr > SQUARE(light.Out + radius)) + continue; + + dist = sqrt(distSqr); + float attenuation = 1.0f - dist / light.Out; + intensity = attenuation * light.Intensity * Luma(light.Color); + + // If collecting shadows, try collecting shadow-casting light. + if (light.CastShadows && prioritizeShadowLight && light.Type == LightType::Point) + { + if (intensity >= brightest) + { + brightest = intensity; + brightestLight = &light; + } + } + } + else if (light.Type == LightType::Spot) + { + float distSqr = Vector3::DistanceSquared(position, light.Position); + + // Collect only lights nearer than 20 blocks. + if (distSqr >= SQUARE(BLOCK(20))) + continue; + + // Check range. + if (distSqr > SQUARE(light.Out + radius)) + continue; + + dist = sqrt(distSqr); + float attenuation = 1.0f - dist / light.Out; + intensity = attenuation * light.Intensity * light.Luma; + + // If shadow pointer provided, try collecting shadow-casting light. + if (light.CastShadows && prioritizeShadowLight) + { + if (intensity >= brightest) + { + brightest = intensity; + brightestLight = &light; + } + } } else { // Invalid light type. continue; } + + RendererLightNode node = { &light, intensity, dist, 0 }; + + if (roomsLights != nullptr) + roomsLights->push_back(node); + + tempLights.push_back(node); } } } @@ -663,7 +703,7 @@ namespace TEN::Renderer // Put actual lights in provided vector. outputLights->clear(); - // Add brightest light, if collecting shadow light is specified, even if it's far in range. + // Add brightest ligh, if collecting shadow light is specified, even if it's far in range. if (prioritizeShadowLight && brightestLight) outputLights->push_back(brightestLight); @@ -746,7 +786,7 @@ namespace TEN::Renderer void Renderer::CollectLightsForRoom(short roomNumber, RenderView &renderView) { - if (_rooms.size() < roomNumber) + if (_rooms.size() <= roomNumber) return; RendererRoom& room = _rooms[roomNumber]; @@ -788,7 +828,7 @@ namespace TEN::Renderer void Renderer::CollectEffects(short roomNumber) { - if (_rooms.size() < roomNumber) + if (_rooms.size() <= roomNumber) return; RendererRoom& room = _rooms[roomNumber]; From 6105f707dba058de4ffa1249a6dc37efcf88c8bd Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:52:57 +0100 Subject: [PATCH 24/26] Update RendererFrame.cpp --- TombEngine/Renderer/RendererFrame.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index 181993140..53861d99a 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -558,7 +558,7 @@ namespace TEN::Renderer } } - void Renderer::CollectLights(const Vector3& position, float radius, int roomNumber, int prevRoomNumber, bool prioritizeShadowLight, bool useCachedRoomLights, std::vector* roomsLights, std::vector* outputLights) + void Renderer::CollectLights(const Vector3& pos, float radius, int roomNumber, int prevRoomNumber, bool prioritizeShadowLight, bool useCachedRoomLights, std::vector* roomsLights, std::vector* outputLights) { if (_rooms.size() <= roomNumber) return; @@ -575,7 +575,7 @@ namespace TEN::Renderer // Dynamic lights have the priority for (auto& light : _dynamicLights[_dynamicLightList]) { - float distSqr = Vector3::DistanceSquared(position, light.Position); + float distSqr = Vector3::DistanceSquared(pos, light.Position); // Collect only lights nearer than 20 sectors if (distSqr >= SQUARE(BLOCK(20))) @@ -620,7 +620,7 @@ namespace TEN::Renderer } else if (light.Type == LightType::Point || light.Type == LightType::Shadow) { - float distSqr = Vector3::DistanceSquared(position, light.Position); + float distSqr = Vector3::DistanceSquared(pos, light.Position); // Collect only lights nearer than 20 blocks. if (distSqr >= SQUARE(BLOCK(20))) @@ -646,7 +646,7 @@ namespace TEN::Renderer } else if (light.Type == LightType::Spot) { - float distSqr = Vector3::DistanceSquared(position, light.Position); + float distSqr = Vector3::DistanceSquared(pos, light.Position); // Collect only lights nearer than 20 blocks. if (distSqr >= SQUARE(BLOCK(20))) From 575bf6cfb101f85e772bb3a3bcf0b18490e26c0f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:48:14 +0300 Subject: [PATCH 25/26] Shader manager (#1534) * Squashed commit of the following: commit 0543f9146aa233d05b09a86d72ccba9f890477a3 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 25 13:49:12 2024 +0100 Fix bad merge commit 529ffb50dd8439672bae970dcdbff3e1d5ed2188 Merge: 329bb52ec a1c76af54 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 25 13:47:26 2024 +0100 Merge branch 'develop' into realtime_shader_reloading commit 329bb52ec71fc2673928e27dcc1d33cb19ee9847 Merge: 3f749b485 ac800ff1e Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 25 13:40:38 2024 +0100 Merge branch 'develop_mirrors' into realtime_shader_reloading commit ac800ff1e10bd9d7ea1fc1548fb0605ca9d07312 Author: Sezz Date: Wed Dec 25 18:23:26 2024 +1100 Final formatting pass commit c2b275672547671242191c030f629499d1f561f3 Author: Sezz Date: Wed Dec 25 18:22:59 2024 +1100 Update RendererFrame.cpp commit d32eeac7abd6d10f4ce2757afe8e9e29040f788b Author: Sezz Date: Wed Dec 25 18:15:45 2024 +1100 Reapply "Formatting pass" This reverts commit becd24da93a2eb33bf78b9be97f6dc6b25d6e744. commit becd24da93a2eb33bf78b9be97f6dc6b25d6e744 Author: Sezz Date: Wed Dec 25 18:12:43 2024 +1100 Revert "Formatting pass" This reverts commit 88a8ba24dea9cf7006920c8d7a52b6d047f6d749. commit 88a8ba24dea9cf7006920c8d7a52b6d047f6d749 Author: Sezz Date: Wed Dec 25 17:35:39 2024 +1100 Formatting pass commit a56d487e30326a3181651cbad6f0522a7c1f1eac Author: Jakub <80340234+Jakub768@users.noreply.github.com> Date: Wed Dec 25 00:31:11 2024 +0000 Update CHANGELOG.md commit 86aad7c7b1f523702fb0f832c8b1ff3c65ee2d01 Merge: daa65d4e3 e3ecc3acd Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 23:22:50 2024 +0100 Merge branch 'develop' into develop_mirrors commit daa65d4e3c59364cca6aebae19a0c82b40ad2824 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 20:46:01 2024 +0100 Update CHANGELOG.md commit 58fc1a8ea0ceb40f9db3217462a430429c39f690 Merge: 63ffb77bd ee867fb9d Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 20:15:28 2024 +0100 Merge branch 'develop' into develop_mirrors commit 63ffb77bd683948698f1eda7d0f688307e757063 Merge: b3195ae83 3ea8978c6 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 20:07:53 2024 +0100 Merge branch 'develop' into develop_mirrors commit b3195ae83f3e32c3de1da717f68aa40b5f72dd0c Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 20:01:11 2024 +0100 Update RendererInit.cpp commit 3f749b485608c02028b696fdc1819c2a22a4cee4 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 09:10:07 2024 +0100 Reload shaders on graphic settings change commit f04dcd42cc9affdc6c3d6d017ca435f414d492b0 Merge: 63539e4f9 1118b2fb2 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 08:57:13 2024 +0100 Merge branch 'develop_mirrors' into realtime_shader_reloading commit 1118b2fb221669a504215e7d8366ec6139f6a47d Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 08:47:33 2024 +0100 Disable self-shadowing for now, as it's causing visual glitches commit 63539e4f98f2e807ce91374d7633301a426fbb62 Merge: ca25f8773 32f94c2f2 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 01:49:18 2024 +0100 Merge branch 'develop_mirrors' into realtime_shader_reloading commit 32f94c2f2aea7a9feca2ec5d27ce9d146df20524 Merge: e6f4e9e24 c757422f2 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 01:35:17 2024 +0100 Merge branch 'develop' into develop_mirrors commit e6f4e9e24b1cc09d1129fb7764d0ad586edd43bb Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 01:07:20 2024 +0100 Implement proper soft shadows commit 9fbcc7b8cfa0dc56695f755265c9134df3e190b3 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 00:52:32 2024 +0100 Fixed silent crash if several Lara objects are present in level near dynamic light with shadow commit ca25f87738b09f74ad3d4f6598ab692f63d34b6b Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 24 00:51:11 2024 +0100 Work commit 12dae8df9924dc7f21d240e3fe05aa718c548c34 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 22:55:50 2024 +0100 Fixed #1524 commit 9df39696a289a2dbe16347af4a8175e409eae6eb Merge: 724953329 6d38bb361 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 20:45:10 2024 +0100 Merge branch 'develop' into develop_mirrors commit 724953329025349b4c1fc9e99f59e59a08f5d3ee Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 20:42:06 2024 +0100 Fixed postprocessing order and precompile shaders to speed-up loading commit b75d14184f25b0709eb08690bc833e91d513a0f0 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 19:57:12 2024 +0100 Fix #1525 commit bcf4dc5497f5a9152a907004bd405a22c641a31b Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 16:11:53 2024 +0100 Interpolate Lara flare light, hide target highlighters in binos commit 9e923a36bb19b6d2e17eeddcd4b78db8e52f0955 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 22 15:06:27 2024 +0100 Fixed #1522 commit 1de0d48d5874f01f3629aac0b73eca19932c655e Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 22:07:46 2024 +0100 Fixed #1521 commit 7076014c9bac586ca9d68c27d094a52024cb590e Merge: af097017f b62c8d7c4 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 20:03:47 2024 +0100 Merge branch 'develop' into develop_mirrors commit af097017f580075bb95283f3d6c96e31f38f07f5 Merge: 4ed353000 04b659b41 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 19:32:07 2024 +0100 Merge branch 'develop' into develop_mirrors commit 4ed353000d0f6b485ed50ef10b00a29b53c2ccdf Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 12:20:05 2024 +0100 Update title.bin commit 7a3aea07faf383fb85715cae795329e5b5dfe4b5 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 11:26:49 2024 +0100 Rename CamOldPos and use more consistent type for it commit 1748eef34a0e0ce4c67099ddfdc74f60101a46c2 Merge: 839f05b3d 0ae388845 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 10:25:23 2024 +0100 Merge branch 'develop' into develop_mirrors commit 839f05b3d1a50a4bbd33c4a525942a2c1660a0cb Merge: e4fe73ffd d75bba698 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 01:05:36 2024 +0100 Merge branch 'develop' into develop_mirrors commit e4fe73ffd533cdb521c9024b06db57bc2d180151 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat Dec 21 00:02:53 2024 +0100 Don't perform binocular animations if binocular meshswap is not present commit 3f7942eb763e3e3bf0a3153a32259bf826f50766 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri Dec 20 23:55:15 2024 +0100 Fix meshswap, if object is not present commit 40cfaaeb0de7a2b648e38e5e16c8ac3152ba0002 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri Dec 20 23:43:27 2024 +0100 Fixed various binocular / lasersight issues commit 1ef9a0e7e60dfc105584702da02fa78ca5032138 Merge: ca578885a 64c177702 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu Dec 19 22:36:14 2024 +0100 Merge branch 'develop' into develop_mirrors commit ca578885a228646496a46784e6b2c51da184c623 Author: MontyTRC89 Date: Thu Dec 19 12:19:07 2024 +0100 Fixed 3D non-sorted sprites mirroring commit 288a413400b987e021aee20823c2ab620a9b7cb8 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu Dec 19 08:59:37 2024 +0100 Continuation of previous fix commit 60cfe1e2f43327284b32286221a8fdc9e9902c09 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu Dec 19 08:47:24 2024 +0100 Fix Lara not mirroring when using binoculars commit 2e17f7f8d9f32f9349c29c3c7a2b5c64632d33a0 Merge: a6687654b 625131fbb Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu Dec 19 01:40:19 2024 +0100 Merge branch 'develop' into develop_mirrors commit a6687654b00a32f7236c4cb5ccdf2ae4778bb6fa Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 22:44:00 2024 +0100 Fixed mirrors on savegame reloading commit 22460e0edfa9a38442689a8b2b7d310d189cef46 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 17:01:19 2024 +0100 Update CHANGELOG.md commit 842d6345fec7a4514a6ff62bd683b14a847d5e70 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 16:40:25 2024 +0100 Add option to reflect sprites commit ab79156bfe8b5c3b8293a61fd3f01f52e7f121be Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 15:37:25 2024 +0100 Update RendererDraw.cpp commit 8ba6a2c286a94ae520e7733555ca7d09cdbaac1e Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 14:56:24 2024 +0100 Spawn mirrored dynamic lights in Lara rooms too commit 1afa98169face34dd9dca9bbf30ddadfb86c9b76 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 14:17:59 2024 +0100 Rename commit 6d195dbb63ebd5155a620cc86549b7ed6a935f52 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 13:35:47 2024 +0100 Reorganize renderer code a little commit 1f002745f35b549f92674ee2146607e5e84ef6d1 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 13:14:08 2024 +0100 Rename fields for consistency commit 79a8db0655928d93bb48d046f54839afe4f92841 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 12:51:17 2024 +0100 Remove lambdas commit b586dce76e8a237eb14ed51f46b77d16385f204c Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 12:36:58 2024 +0100 Remove unrelated changes commit 8cebdae0ef59cfdd0c1e7e88129225030aff524e Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 12:23:23 2024 +0100 Draw reflections also when Lara is in any of mirrored rooms, not only camera commit 38b210013fb1de5b4571ebb10214bf7a3283e46b Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 11:55:00 2024 +0100 Fixed 3D sprites mirroring commit 2705a5ae7b2e88e67c8f730240c3db4a31f9fa36 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 11:09:56 2024 +0100 Update RendererDraw.cpp commit 14f6ab36d069935fa648b0367be9ba500b64f89a Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 10:57:59 2024 +0100 Fixed dynamic lights commit 85469cb4d4aee5cd6a7895f758cc026711afc411 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 10:18:04 2024 +0100 Fixed billboards, reintroduce ReflectVectorOptionally commit 3535eddf5db20a40af7d67fc9d075222e9e89548 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 03:12:13 2024 +0100 Remove unnecessary inline, dont reflect room lights commit bf6ef08c576dce5cfe31d477c713c4543e26cde0 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 02:44:49 2024 +0100 More decopypasting, rename inline function, remove unneeded arg commit 569644f1d4b41b7a5b616f1fd4576de28e6747b6 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 02:28:31 2024 +0100 Decopypaste more mirror-related code commit 60a59caa53ea11d85fe3c9fb435edf6874ea20cc Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 01:09:47 2024 +0100 Update level.cpp commit 5dd8db198cb8f2089ceb0a7fe540fa987598246b Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed Dec 18 01:07:10 2024 +0100 Simplify renderer code, remove excessive if statements commit 31d278a780519c9b44f4cfc8e7435f24e76dffe2 Merge: f09b81fc8 88bbe4862 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue Dec 17 19:48:18 2024 +0100 Merge branch 'develop' into develop_mirrors commit f09b81fc87b34877d58301d930a4d5aa1bf67c4c Merge: 3e6e9cb61 ab7e25aa7 Author: MontyTRC89 Date: Sun Dec 15 06:56:26 2024 +0100 Merge branch 'develop' into develop_mirrors commit 3e6e9cb61eeaccdaaa6b7c98f0b8c82ea5004d11 Author: MontyTRC89 Date: Sun Dec 15 06:56:05 2024 +0100 Added logic for hiding selectively reflecting moveables and statics; Added enabled flag for disabling mirrros in the future with LUA; commit c5f10777e7441048155395532ff777629258ce44 Author: MontyTRC89 Date: Fri Dec 13 05:20:23 2024 +0100 Fixed random statics positions while shooting commit 8978a51bfee9eb762b72eefb91bebbbd534a88da Author: MontyTRC89 Date: Fri Dec 13 04:51:07 2024 +0100 Fixed ambient occlusion in mirrored rooms commit f3afaf47cfce5a5d0e6719ef41e6d73c085c571f Merge: 4e08942d8 6198975be Author: MontyTRC89 Date: Thu Dec 12 06:10:39 2024 +0100 Merge branch 'develop' into develop_mirrors commit 4e08942d86f2601fd5a82964fd9975e5f8f9d631 Merge: 265283aac e674b8526 Author: MontyTRC89 Date: Wed Dec 11 13:43:19 2024 +0100 Merge branch 'develop' into develop_mirrors; Removed RendererMirror references in methods calls; commit 265283aacfee0412df6386d9b6c5e2fec315ee54 Author: MontyTRC89 Date: Wed Dec 11 04:35:20 2024 +0100 Cached reflection matrix of mirrors at load time; Fixed lighting in mirrored items; Added bad cull mode after mirrore debrises drawing; Added mirroring of dynamic lights; commit f44a04d05738539be97075d9dccf47c7856466d9 Author: MontyTRC89 Date: Tue Dec 10 14:57:00 2024 +0100 Fixed items culling in mirror rooms; Changed file format for having also virtual room; commit 74c74042d52084e859a59e60db6e629fccd5b962 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 8 21:41:51 2024 +0100 Use emplace_back and camera room number commit 41b16e5696c0d6947fc5a6818d5b071747b285d4 Merge: 39f0c131c 9a241dbc8 Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 8 21:07:44 2024 +0100 Merge branch 'develop' into develop_mirrors commit 39f0c131c39e727a9451b3fec089b0d0205eab0c Author: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun Dec 8 21:02:00 2024 +0100 Use default argument value for ReadCount commit c4330a777cda0de4e842b204735a07f7003df4e2 Merge: 374abb27d d96bf4ba8 Author: MontyTRC89 Date: Sat Dec 7 05:03:24 2024 +0100 Merge branch 'develop' into develop_mirrors commit 374abb27d3adfa50c48711e5576b285336c2c2e8 Author: MontyTRC89 Date: Sat Dec 7 05:02:09 2024 +0100 Implemented mirrors in file format commit 3e89391776d688dc1f3865c1ba3cd44c605a3224 Merge: ec6ab6413 f9f1f59eb Author: MontyTRC89 Date: Fri Dec 6 15:10:05 2024 +0100 Merge branch 'develop' into develop_mirrors commit ec6ab641311551b25cf5b60798194413d7f72dbd Author: MontyTRC89 Date: Fri Dec 6 15:08:54 2024 +0100 Added debris and effects drawing in mirrored rooms; Some optimizations for early skip non mirrored items; commit 2218dd3179efd53a13bbd151f6e88ba07b79b3a4 Merge: 92eb4af79 2ee37ea7d Author: MontyTRC89 Date: Thu Dec 5 11:54:59 2024 +0100 Merge branch 'develop' into develop_mirrors; Added correct lights to reflected items; commit 92eb4af796a34ebc4add869c80581ebd5bd51320 Author: MontyTRC89 Date: Thu Dec 5 11:19:11 2024 +0100 Fixed broken previous commit commit bb3d0b993bb2ef66e351ae295c2cf78b36e6ed2a Author: MontyTRC89 Date: Thu Dec 5 10:20:32 2024 +0100 WIP TR4 style mirrors * Code etiquette * Recompile AA shaders on graphics settings change * Fixed code under ifdef --------- Co-authored-by: Sezz --- Documentation/doc/1 modules/Logic.html | 8 + TombEngine/Game/gui.cpp | 5 + TombEngine/Renderer/Renderer.cpp | 12 + TombEngine/Renderer/Renderer.h | 59 +--- TombEngine/Renderer/RendererAntialiasing.cpp | 14 +- TombEngine/Renderer/RendererDraw.cpp | 126 +++---- TombEngine/Renderer/RendererDraw2D.cpp | 24 +- TombEngine/Renderer/RendererDrawEffect.cpp | 8 +- TombEngine/Renderer/RendererDrawMenu.cpp | 14 +- TombEngine/Renderer/RendererInit.cpp | 269 ++------------- TombEngine/Renderer/RendererPostProcess.cpp | 14 +- TombEngine/Renderer/RendererSprites.cpp | 15 +- TombEngine/Renderer/RendererUtils.cpp | 8 +- TombEngine/Renderer/RendererUtils.h | 2 + .../Renderer/ShaderManager/ShaderManager.cpp | 317 ++++++++++++++++++ .../Renderer/ShaderManager/ShaderManager.h | 101 ++++++ TombEngine/Specific/IO/Streams.h | 1 - TombEngine/Specific/Input/Input.cpp | 6 + TombEngine/TombEngine.vcxproj | 2 + TombEngine/framework.h | 2 + 20 files changed, 599 insertions(+), 408 deletions(-) create mode 100644 TombEngine/Renderer/ShaderManager/ShaderManager.cpp create mode 100644 TombEngine/Renderer/ShaderManager/ShaderManager.h diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index 822541db9..0f60fea35 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -524,6 +524,14 @@ end +
  • OnUseItem + function + Will be called when using an item from inventory. +
  • +
  • OnFreeze + function + Will be called when any of the Freeze modes are activated. +
  • diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index 162a2e0b8..d5a432cd9 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -621,6 +621,10 @@ namespace TEN::Gui CurrentSettings.Configuration.ScreenWidth = screenResolution.x; CurrentSettings.Configuration.ScreenHeight = screenResolution.y; + // Determine whether we should update AA shaders. + bool shouldRecompileAAShaders = g_Configuration.AntialiasingMode != CurrentSettings.Configuration.AntialiasingMode && + CurrentSettings.Configuration.AntialiasingMode != AntialiasingMode::Low; + g_Configuration = CurrentSettings.Configuration; SaveConfiguration(); @@ -628,6 +632,7 @@ namespace TEN::Gui g_Renderer.ChangeScreenResolution(CurrentSettings.Configuration.ScreenWidth, CurrentSettings.Configuration.ScreenHeight, CurrentSettings.Configuration.EnableWindowedMode); + g_Renderer.ReloadShaders(shouldRecompileAAShaders); g_Renderer.SetGraphicsSettingsChanged(); MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; diff --git a/TombEngine/Renderer/Renderer.cpp b/TombEngine/Renderer/Renderer.cpp index 4fb6b4322..39d3e5e76 100644 --- a/TombEngine/Renderer/Renderer.cpp +++ b/TombEngine/Renderer/Renderer.cpp @@ -61,6 +61,18 @@ namespace TEN::Renderer _isLocked = true; } + void Renderer::ReloadShaders(bool recompileAAShaders) + { + try + { + _shaders.LoadShaders(_screenWidth, _screenHeight, recompileAAShaders); + } + catch (const std::exception& e) + { + TENLog("An exception occured during shader reload: " + std::string(e.what()), LogLevel::Error); + } + } + int Renderer::Synchronize() { // Sync the renderer diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index 365fbcb83..6f3e5abfd 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -53,6 +53,7 @@ #include "Renderer/Graphics/Texture2DArray.h" #include "Renderer/Graphics/VertexBuffer.h" #include "Renderer/Graphics/Vertices/PostProcessVertex.h" +#include "Renderer/ShaderManager/ShaderManager.h" #include "Renderer/Structures/RendererItem.h" #include "Renderer/Structures/RendererEffect.h" #include "Renderer/Structures/RendererLine3D.h" @@ -81,6 +82,7 @@ namespace TEN::Renderer using namespace TEN::Renderer::ConstantBuffers; using namespace TEN::Renderer::Graphics; using namespace TEN::Renderer::Structures; + using namespace TEN::Renderer::Utils; using namespace DirectX::SimpleMath; using TexturePair = std::tuple; @@ -123,34 +125,6 @@ namespace TEN::Renderer RenderTarget2D _tempRoomAmbientRenderTarget4; Texture2DArray _shadowMap; - // Shaders - - RendererShader _sRooms; - RendererShader _sRoomsAnimated; - RendererShader _sRoomsTransparent; - RendererShader _sRoomAmbient; - RendererShader _sRoomAmbientSky; - RendererShader _sItems; - RendererShader _sStatics; - RendererShader _sInstancedStatics; - RendererShader _sSprites; - RendererShader _sInstancedSprites; - RendererShader _sSky; - RendererShader _sSolid; - RendererShader _sInventory; - RendererShader _sFullScreenQuad; - RendererShader _sShadowMap; - RendererShader _sHUD; - RendererShader _sHUDColor; - RendererShader _sHUDTexture; - RendererShader _sHUDBarColor; - RendererShader _sGBuffer; - RendererShader _sGBufferRooms; - RendererShader _sGBufferRoomsAnimated; - RendererShader _sGBufferItems; - RendererShader _sGBufferStatics; - RendererShader _sGBufferInstancedStatics; - // Constant buffers RenderView _gameCamera; @@ -341,14 +315,6 @@ namespace TEN::Renderer RenderTarget2D _SMAAEdgesRenderTarget; RenderTarget2D _SMAABlendRenderTarget; - RendererShader _sSMAAEdgeDetection; - RendererShader _sSMAALumaEdgeDetection; - RendererShader _sSMAAColorEdgeDetection; - RendererShader _sSMAADepthEdgeDetection; - RendererShader _sSMAABlendingWeightCalculation; - RendererShader _sSMAANeighborhoodBlending; - RendererShader _sFXAA; - // Post-process PostProcessMode _postProcessMode = PostProcessMode::None; @@ -357,12 +323,6 @@ namespace TEN::Renderer VertexBuffer _fullscreenTriangleVertexBuffer; ComPtr _fullscreenTriangleInputLayout = nullptr; - RendererShader _sPostProcess; - RendererShader _sPostProcessMonochrome; - RendererShader _sPostProcessNegative; - RendererShader _sPostProcessExclusion; - RendererShader _sPostProcessFinalPass; - RendererShader _sPostProcessLensFlare; bool _doingFullscreenPass = false; @@ -373,9 +333,6 @@ namespace TEN::Renderer RenderTarget2D _SSAOBlurredRenderTarget; std::vector _SSAOKernel; - RendererShader _sSSAO; - RendererShader _sSSAOBlur; - // New ambient light techinque RenderTarget2D _roomAmbientMapFront; @@ -393,15 +350,14 @@ namespace TEN::Renderer VertexBuffer _sortedPolygonsVertexBuffer; IndexBuffer _sortedPolygonsIndexBuffer; - // High framerate. + // High framerate - float _interpolationFactor = 0.0f; - bool _graphicsSettingsChanged = false; + float _interpolationFactor = 0.0f; + bool _graphicsSettingsChanged = false; - // Private functions + // Shader manager - RendererShader CompileOrLoadShader(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines = nullptr); - void BindShader(const RendererShader& shader); + ShaderManager _shaders; void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view); void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view); @@ -643,6 +599,7 @@ namespace TEN::Renderer void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison); void Create(); void Initialize(int w, int h, bool windowed, HWND handle); + void ReloadShaders(bool recompileAAShaders = false); void Render(float interpFactor); void RenderTitle(float interpFactor); void Lock(); diff --git a/TombEngine/Renderer/RendererAntialiasing.cpp b/TombEngine/Renderer/RendererAntialiasing.cpp index b78fd9b1b..2c0f0b9c0 100644 --- a/TombEngine/Renderer/RendererAntialiasing.cpp +++ b/TombEngine/Renderer/RendererAntialiasing.cpp @@ -14,7 +14,7 @@ namespace TEN::Renderer ResetScissor(); // Common vertex shader to all fullscreen effects - BindShader(_sPostProcess); + _shaders.Bind(Shader::PostProcess); // We draw a fullscreen triangle _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -40,8 +40,8 @@ namespace TEN::Renderer SetCullMode(CullMode::CounterClockwise); _context->OMSetRenderTargets(1, _SMAAEdgesRenderTarget.RenderTargetView.GetAddressOf(), nullptr); - BindShader(_sSMAAEdgeDetection); - BindShader(_sSMAAColorEdgeDetection); + _shaders.Bind(Shader::SmaaEdgeDetection); + _shaders.Bind(Shader::SmaaColorEdgeDetection); _stSMAABuffer.BlendFactor = 1.0f; _cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get()); @@ -59,7 +59,7 @@ namespace TEN::Renderer // 2) Blend weights calculation. _context->OMSetRenderTargets(1, _SMAABlendRenderTarget.RenderTargetView.GetAddressOf(), nullptr); - BindShader(_sSMAABlendingWeightCalculation); + _shaders.Bind(Shader::SmaaBlendingWeightCalculation); _stSMAABuffer.SubsampleIndices = Vector4::Zero; _cbSMAABuffer.UpdateData(_stSMAABuffer, _context.Get()); @@ -76,7 +76,7 @@ namespace TEN::Renderer // 3) Neighborhood blending. _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); - BindShader(_sSMAANeighborhoodBlending); + _shaders.Bind(Shader::SmaaNeighborhoodBlending); BindRenderTargetAsTexture(static_cast(0), &_SMAASceneRenderTarget, SamplerStateRegister::LinearClamp); BindRenderTargetAsTexture(static_cast(1), &_SMAASceneSRGBRenderTarget, SamplerStateRegister::LinearClamp); @@ -100,7 +100,7 @@ namespace TEN::Renderer ResetScissor(); // Common vertex shader to all fullscreen effects - BindShader(_sPostProcess); + _shaders.Bind(Shader::PostProcess); // We draw a fullscreen triangle _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -123,7 +123,7 @@ namespace TEN::Renderer _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); - BindShader(_sFXAA); + _shaders.Bind(Shader::Fxaa); _stPostProcessBuffer.ViewportWidth = _screenWidth; _stPostProcessBuffer.ViewportHeight = _screenHeight; diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index fc18ca9e5..662ad0b7e 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -153,7 +153,7 @@ namespace TEN::Renderer for (int step = 0; step < 6; step++) { - // Bind render target + // Bind render target. _context->OMSetRenderTargets(1, _shadowMap.RenderTargetView[step].GetAddressOf(), _shadowMap.DepthStencilView[step].Get()); @@ -163,27 +163,27 @@ namespace TEN::Renderer if (shadowLightPos == item->Position) return; - UINT stride = sizeof(Vertex); - UINT offset = 0; + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; - // Set shaders - BindShader(_sShadowMap); + // Set shaders. + _shaders.Bind(Shader::ShadowMap); _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - // Set texture + // Set texture. BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[0]), SamplerStateRegister::AnisotropicClamp); BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[0]), SamplerStateRegister::AnisotropicClamp); - // Set camera matrices - Matrix view = Matrix::CreateLookAt(shadowLightPos, shadowLightPos + + // Set camera matrices. + auto view = Matrix::CreateLookAt(shadowLightPos, shadowLightPos + RenderTargetCube::forwardVectors[step] * BLOCK(10), RenderTargetCube::upVectors[step]); - Matrix projection = Matrix::CreatePerspectiveFieldOfView(90.0f * PI / 180.0f, 1.0f, 16.0f, _shadowLight->Out); + auto projection = Matrix::CreatePerspectiveFieldOfView(90.0f * PI / 180.0f, 1.0f, 16.0f, _shadowLight->Out); CCameraMatrixBuffer shadowProjection; shadowProjection.ViewProjection = view * projection; @@ -290,7 +290,7 @@ namespace TEN::Renderer { auto& moveableObject = *_moveableObjects[objectID]; - BindShader(_sInstancedStatics); + _shaders.Bind(Shader::InstancedStatics); unsigned int stride = sizeof(Vertex); unsigned int offset = 0; @@ -367,7 +367,7 @@ namespace TEN::Renderer SetDepthState(DepthState::Read); SetCullMode(CullMode::None); - BindShader(_sSolid); + _shaders.Bind(Shader::Solid); auto worldMatrix = Matrix::CreateOrthographicOffCenter(0, _screenWidth, _screenHeight, 0, _viewport.MinDepth, _viewport.MaxDepth); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); @@ -537,12 +537,12 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferStatics); } else { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); } UINT stride = sizeof(Vertex); @@ -656,12 +656,12 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferStatics); } else { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); } unsigned int stride = sizeof(Vertex); @@ -792,12 +792,12 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferInstancedStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferInstancedStatics); } else { - BindShader(_sInstancedStatics); + _shaders.Bind(Shader::InstancedStatics); } unsigned int stride = sizeof(Vertex); @@ -919,12 +919,12 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferInstancedStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferInstancedStatics); } else { - BindShader(_sInstancedStatics); + _shaders.Bind(Shader::InstancedStatics); } unsigned int stride = sizeof(Vertex); @@ -1026,12 +1026,12 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferStatics); } else { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); } unsigned int stride = sizeof(Vertex); @@ -1089,7 +1089,7 @@ namespace TEN::Renderer SetBlendMode(BlendMode::Additive); SetCullMode(CullMode::None); - BindShader(_sSolid); + _shaders.Bind(Shader::Solid); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); @@ -1122,7 +1122,7 @@ namespace TEN::Renderer SetBlendMode(BlendMode::Additive); SetCullMode(CullMode::None); - BindShader(_sSolid); + _shaders.Bind(Shader::Solid); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); @@ -1928,7 +1928,7 @@ namespace TEN::Renderer SetBlendMode(BlendMode::Opaque); SetCullMode(CullMode::CounterClockwise); - BindShader(_sRoomAmbient); + _shaders.Bind(Shader::RoomAmbient); // Bind and clear render target _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); @@ -1978,7 +1978,7 @@ namespace TEN::Renderer if (levelPtr->Horizon) { - BindShader(_sRoomAmbientSky); + _shaders.Bind(Shader::RoomAmbientSky); if (Lara.Control.Look.OpticRange != 0) AlterFOV(ANGLE(DEFAULT_FOV) - Lara.Control.Look.OpticRange, false); @@ -2060,7 +2060,7 @@ namespace TEN::Renderer _context->ClearDepthStencilView(renderTarget->DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); } - BindShader(_sRoomAmbient); + _shaders.Bind(Shader::RoomAmbient); // Draw rooms UINT stride = sizeof(Vertex); @@ -2267,12 +2267,12 @@ namespace TEN::Renderer // Set shaders. if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferItems); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferItems); } else { - BindShader(_sItems); + _shaders.Bind(Shader::Items); } BindRenderTargetAsTexture(TextureRegister::SSAO, &_SSAOBlurredRenderTarget, SamplerStateRegister::PointWrap); @@ -2410,12 +2410,12 @@ namespace TEN::Renderer #ifdef DISABLE_INSTANCING if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferStatics); } else { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); } // Bind vertex and index buffer @@ -2431,7 +2431,7 @@ namespace TEN::Renderer std::vector statics = it->second; RendererStatic* refStatic = statics[0]; - RendererObject& refStaticObj = *_staticObjects[refStatic->ObjectNumber]; + RendererObject& refStaticObj = GetStaticRendererObject(refStatic->ObjectNumber); if (refStaticObj.ObjectMeshes.size() == 0) continue; @@ -2491,12 +2491,12 @@ namespace TEN::Renderer #else if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); - BindShader(_sGBufferInstancedStatics); + _shaders.Bind(Shader::GBuffer); + _shaders.Bind(Shader::GBufferInstancedStatics); } else { - BindShader(_sInstancedStatics); + _shaders.Bind(Shader::InstancedStatics); } // Bind vertex and index buffer @@ -2676,11 +2676,11 @@ namespace TEN::Renderer { if (rendererPass == RendererPass::GBuffer) { - BindShader(_sGBuffer); + _shaders.Bind(Shader::GBuffer); } else { - BindShader(_sRooms); + _shaders.Bind(Shader::Rooms); } UINT stride = sizeof(Vertex); @@ -2744,11 +2744,11 @@ namespace TEN::Renderer { if (rendererPass != RendererPass::GBuffer) { - if (animated == 0) BindShader(_sRooms); else BindShader(_sRoomsAnimated); + if (animated == 0) _shaders.Bind(Shader::Rooms); else _shaders.Bind(Shader::RoomsAnimated); } else { - if (animated == 0) BindShader(_sGBufferRooms); else BindShader(_sGBufferRoomsAnimated); + if (animated == 0) _shaders.Bind(Shader::GBufferRooms); else _shaders.Bind(Shader::GBufferRoomsAnimated); } for (const auto& bucket : room.Buckets) @@ -2847,7 +2847,7 @@ namespace TEN::Renderer // Draw sky. auto rotation = Matrix::CreateRotationX(PI); - BindShader(_sSky); + _shaders.Bind(Shader::Sky); BindTexture(TextureRegister::ColorMap, &_skyTexture, SamplerStateRegister::AnisotropicClamp); _context->IASetVertexBuffers(0, 1, _skyVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); @@ -2888,7 +2888,7 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - BindShader(_sInstancedSprites); + _shaders.Bind(Shader::InstancedSprites); // Set up vertex buffer and parameters. UINT stride = sizeof(Vertex); @@ -3027,7 +3027,7 @@ namespace TEN::Renderer _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - BindShader(_sSky); + _shaders.Bind(Shader::Sky); auto& moveableObj = *_moveableObjects[ID_HORIZON]; @@ -3071,7 +3071,7 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - BindShader(_sInstancedSprites); + _shaders.Bind(Shader::InstancedSprites); // Set up vertex buffer and parameters. unsigned int stride = sizeof(Vertex); @@ -3490,7 +3490,7 @@ namespace TEN::Renderer ROOM_INFO* nativeRoom = &g_Level.Rooms[objectInfo->Room->RoomNumber]; - BindShader(_sRooms); + _shaders.Bind(Shader::Rooms); UINT stride = sizeof(Vertex); UINT offset = 0; @@ -3507,7 +3507,7 @@ namespace TEN::Renderer SetScissor(objectInfo->Room->ClipBounds); if (objectInfo->Bucket->Animated != 0) - BindShader(_sRoomsAnimated); + _shaders.Bind(Shader::RoomsAnimated); SetBlendMode(objectInfo->Bucket->BlendMode); SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD); @@ -3573,7 +3573,7 @@ namespace TEN::Renderer SetBlendMode(objectInfo->Bucket->BlendMode); SetAlphaTest(AlphaTestMode::None, ALPHA_TEST_THRESHOLD); - BindShader(_sItems); + _shaders.Bind(Shader::Items); // Bind main item properties. Matrix world = objectInfo->Item->InterpolatedWorld; @@ -3614,7 +3614,7 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); auto world = objectInfo->Static->World; _stStatic.World = world; @@ -3652,7 +3652,7 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); auto world = objectInfo->World; _stStatic.World = world; @@ -3690,16 +3690,16 @@ namespace TEN::Renderer SetCullMode(CullMode::CounterClockwise); SetDepthState(DepthState::Write); - // Common vertex shader to all full screen effects - BindShader(_sPostProcess); + // Common vertex shader to all full screen effects. + _shaders.Bind(Shader::PostProcess); - // SSAO pixel shader - BindShader(_sSSAO); + // SSAO pixel shader. + _shaders.Bind(Shader::Ssao); _context->ClearRenderTargetView(_SSAORenderTarget.RenderTargetView.Get(), Colors::White); _context->OMSetRenderTargets(1, _SSAORenderTarget.RenderTargetView.GetAddressOf(), nullptr); - // Need to set correctly the viewport because SSAO is done at 1/4 screen resolution + // Must set correctly viewport because SSAO is done at 1/4 screen resolution. D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; @@ -3721,8 +3721,8 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_fullscreenTriangleInputLayout.Get()); - UINT stride = sizeof(PostProcessVertex); - UINT offset = 0; + unsigned int stride = sizeof(PostProcessVertex); + unsigned int offset = 0; _context->IASetVertexBuffers(0, 1, _fullscreenTriangleVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); @@ -3737,8 +3737,8 @@ namespace TEN::Renderer DrawTriangles(3, 0); - // Blur step - BindShader(_sSSAOBlur); + // Blur step. + _shaders.Bind(Shader::SsaoBlur); _context->ClearRenderTargetView(_SSAOBlurredRenderTarget.RenderTargetView.Get(), Colors::Black); _context->OMSetRenderTargets(1, _SSAOBlurredRenderTarget.RenderTargetView.GetAddressOf(), nullptr); diff --git a/TombEngine/Renderer/RendererDraw2D.cpp b/TombEngine/Renderer/RendererDraw2D.cpp index 698b9dea9..8dd4434a8 100644 --- a/TombEngine/Renderer/RendererDraw2D.cpp +++ b/TombEngine/Renderer/RendererDraw2D.cpp @@ -132,8 +132,8 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetIndexBuffer(bar.IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - BindShader(_sHUD); - BindShader(_sHUDTexture); + _shaders.Bind(Shader::Hud); + _shaders.Bind(Shader::HudDTexture); SetBlendMode(BlendMode::Opaque); SetDepthState(DepthState::None); @@ -161,8 +161,8 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetIndexBuffer(bar.InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - BindShader(_sHUD); - BindShader(_sHUDBarColor); + _shaders.Bind(Shader::Hud); + _shaders.Bind(Shader::HudBarColor); _stHUDBar.Percent = percent; _stHUDBar.Poisoned = isPoisoned; @@ -195,8 +195,8 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetIndexBuffer(g_LoadingBar->IndexBufferBorder.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - BindShader(_sHUD); - BindShader(_sHUDTexture); + _shaders.Bind(Shader::Hud); + _shaders.Bind(Shader::HudDTexture); SetBlendMode(BlendMode::Opaque); SetDepthState(DepthState::None); @@ -220,8 +220,8 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetIndexBuffer(g_LoadingBar->InnerIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - BindShader(_sHUD); - BindShader(_sHUDBarColor); + _shaders.Bind(Shader::Hud); + _shaders.Bind(Shader::HudBarColor); _stHUDBar.Percent = percentage / 100.0f; _stHUDBar.Poisoned = false; @@ -305,7 +305,7 @@ namespace TEN::Renderer vertices[3].UV.y = 1.0f; vertices[3].Color = Vector4(1.0f, 0.0f, 0.0f, 1.0f); - BindShader(_sFullScreenQuad); + _shaders.Bind(Shader::FullScreenQuad); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); @@ -341,7 +341,7 @@ namespace TEN::Renderer if (renderView.DisplaySpritesToDraw.empty()) return; - BindShader(_sFullScreenQuad); + _shaders.Bind(Shader::FullScreenQuad); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); @@ -463,7 +463,7 @@ namespace TEN::Renderer vertices[3].UV.y = uvEnd.y; vertices[3].Color = colorVec4; - BindShader(_sFullScreenQuad); + _shaders.Bind(Shader::FullScreenQuad); _context->PSSetShaderResources(0, 1, &texture); @@ -540,7 +540,7 @@ namespace TEN::Renderer vertices[3].UV.y = uvEnd.y; vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f); - BindShader(_sFullScreenQuad); + _shaders.Bind(Shader::FullScreenQuad); _context->PSSetShaderResources(0, 1, &texture); auto* sampler = _renderStates->AnisotropicClamp(); diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index 24c605741..7e9fea36e 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -1022,7 +1022,7 @@ namespace TEN::Renderer if (!settings.MuzzleFlash) return false; - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); unsigned int stride = sizeof(Vertex); unsigned int offset = 0; @@ -1143,7 +1143,7 @@ namespace TEN::Renderer void Renderer::DrawBaddyGunflashes(RenderView& view) { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); unsigned int stride = sizeof(Vertex); unsigned int offset = 0; @@ -1373,7 +1373,7 @@ namespace TEN::Renderer void Renderer::DrawEffects(RenderView& view, RendererPass rendererPass) { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); unsigned int stride = sizeof(Vertex); unsigned int offset = 0; @@ -1414,7 +1414,7 @@ namespace TEN::Renderer if (activeDebrisExist) { - BindShader(_sStatics); + _shaders.Bind(Shader::Statics); SetCullMode(CullMode::None); diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp index 1da3c1df4..a3871b8e3 100644 --- a/TombEngine/Renderer/RendererDrawMenu.cpp +++ b/TombEngine/Renderer/RendererDrawMenu.cpp @@ -817,7 +817,7 @@ namespace TEN::Renderer _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); // Set shaders. - BindShader(_sInventory); + _shaders.Bind(Shader::Inventory); // Set matrices. CCameraMatrixBuffer hudCamera; @@ -994,23 +994,21 @@ namespace TEN::Renderer _context->ClearRenderTargetView(_renderTarget.RenderTargetView.Get(), Colors::Black); if (background != nullptr) - { DrawFullScreenImage(background->ShaderResourceView.Get(), backgroundFade, _renderTarget.RenderTargetView.Get(), _renderTarget.DepthStencilView.Get()); - } _context->ClearDepthStencilView(_renderTarget.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); - UINT stride = sizeof(Vertex); - UINT offset = 0; + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; - // Set vertex buffer + // Set vertex buffer. _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - // Set shaders - BindShader(_sInventory); + // Set shaders. + _shaders.Bind(Shader::Inventory); if (CurrentLevel == 0) { diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp index d0c0f6655..19c3f572f 100644 --- a/TombEngine/Renderer/RendererInit.cpp +++ b/TombEngine/Renderer/RendererInit.cpp @@ -18,11 +18,6 @@ extern GameConfiguration g_Configuration; using namespace TEN::Renderer::Utils; -static std::wstring GetAssetPath(const wchar_t* fileName) -{ - return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName; -} - namespace TEN::Renderer { void Renderer::Initialize(int w, int h, bool windowed, HWND handle) @@ -35,12 +30,11 @@ namespace TEN::Renderer InitializeScreen(w, h, handle, false); InitializeCommonTextures(); - // Initialize render states - _renderStates = std::make_unique(_device.Get()); + // Load shaders. + _shaders.LoadShaders(w, h); - // Load shaders - const D3D_SHADER_MACRO roomDefinesAnimated[] = { "ANIMATED", "", nullptr, nullptr }; - const D3D_SHADER_MACRO roomDefinesShadowMap[] = { "SHADOW_MAP", "", nullptr, nullptr }; + // Initialize render states. + _renderStates = std::make_unique(_device.Get()); // Initialize input layout using first vertex shader. D3D11_INPUT_ELEMENT_DESC inputLayoutItems[] = @@ -59,42 +53,10 @@ namespace TEN::Renderer { "HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; - _sRooms = CompileOrLoadShader("Rooms", "", ShaderType::PixelAndVertex); - Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, _sRooms.Vertex.Blob->GetBufferPointer(), _sRooms.Vertex.Blob->GetBufferSize(), &_inputLayout)); + const auto& roomShader = _shaders.Get(Shader::Rooms); + Utils::throwIfFailed(_device->CreateInputLayout(inputLayoutItems, 12, roomShader.Vertex.Blob->GetBufferPointer(), roomShader.Vertex.Blob->GetBufferSize(), &_inputLayout)); - _sRoomsAnimated = CompileOrLoadShader("Rooms", "", ShaderType::Vertex, &roomDefinesAnimated[0]); - _sItems = CompileOrLoadShader("Items", "", ShaderType::PixelAndVertex); - _sStatics = CompileOrLoadShader("Statics", "", ShaderType::PixelAndVertex); - _sSky = CompileOrLoadShader("Sky", "", ShaderType::PixelAndVertex); - _sSprites = CompileOrLoadShader("Sprites", "", ShaderType::PixelAndVertex); - _sSolid = CompileOrLoadShader("Solid", "", ShaderType::PixelAndVertex); - _sInventory = CompileOrLoadShader("Inventory", "", ShaderType::PixelAndVertex); - _sFullScreenQuad = CompileOrLoadShader("FullScreenQuad", "", ShaderType::PixelAndVertex); - _sShadowMap = CompileOrLoadShader("ShadowMap", "", ShaderType::PixelAndVertex, &roomDefinesShadowMap[0]); - _sHUD = CompileOrLoadShader("HUD", "", ShaderType::Vertex); - _sHUDColor = CompileOrLoadShader("HUD", "ColoredHUD", ShaderType::Pixel); - _sHUDTexture = CompileOrLoadShader("HUD", "TexturedHUD", ShaderType::Pixel); - _sHUDBarColor = CompileOrLoadShader("HUD", "TexturedHUDBar", ShaderType::Pixel); - _sInstancedStatics = CompileOrLoadShader("InstancedStatics", "", ShaderType::PixelAndVertex); - _sInstancedSprites = CompileOrLoadShader("InstancedSprites", "", ShaderType::PixelAndVertex); - - _sGBuffer = CompileOrLoadShader("GBuffer", "", ShaderType::Pixel); - _sGBufferRooms = CompileOrLoadShader("GBuffer", "Rooms", ShaderType::Vertex); - _sGBufferRoomsAnimated = CompileOrLoadShader("GBuffer", "Rooms", ShaderType::Vertex, &roomDefinesAnimated[0]); - _sGBufferItems = CompileOrLoadShader("GBuffer", "Items", ShaderType::Vertex); - _sGBufferStatics = CompileOrLoadShader("GBuffer", "Statics", ShaderType::Vertex); - _sGBufferInstancedStatics = CompileOrLoadShader("GBuffer", "InstancedStatics", ShaderType::Vertex); - - _sRoomAmbient = CompileOrLoadShader("RoomAmbient", "", ShaderType::PixelAndVertex); - _sRoomAmbientSky = CompileOrLoadShader("RoomAmbient", "Sky", ShaderType::Vertex); - _sFXAA = CompileOrLoadShader("FXAA", "", ShaderType::Pixel); - _sSSAO = CompileOrLoadShader("SSAO", "", ShaderType::Pixel); - _sSSAOBlur = CompileOrLoadShader("SSAO", "Blur", ShaderType::Pixel); - - const D3D_SHADER_MACRO transparentDefines[] = { "TRANSPARENT", "", nullptr, nullptr }; - _sRoomsTransparent = CompileOrLoadShader("Rooms", "", ShaderType::Pixel, &transparentDefines[0]); - - // Initialize constant buffers + // Initialize constant buffers. _cbCameraMatrices = CreateConstantBuffer(); _cbItem = CreateConstantBuffer(); _cbStatic = CreateConstantBuffer(); @@ -108,7 +70,7 @@ namespace TEN::Renderer _cbInstancedStaticMeshBuffer = CreateConstantBuffer(); _cbSMAABuffer = CreateConstantBuffer(); - // Prepare HUD Constant buffer + // Prepare HUD Constant buffer. _cbHUDBar = CreateConstantBuffer(); _cbHUD = CreateConstantBuffer(); _cbSprite = CreateConstantBuffer(); @@ -117,7 +79,7 @@ namespace TEN::Renderer _cbHUD.UpdateData(_stHUD, _context.Get()); _currentCausticsFrame = 0; - // Preallocate lists + // Preallocate lists. _lines2DToDraw = createVector(MAX_LINES_2D); _lines3DToDraw = createVector(MAX_LINES_3D); _triangles3DToDraw = createVector(MAX_TRIANGLES_3D); @@ -219,7 +181,7 @@ namespace TEN::Renderer shadowSamplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; shadowSamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; Utils::throwIfFailed(_device->CreateSamplerState(&shadowSamplerDesc, _shadowSampler.GetAddressOf())); - _shadowSampler->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("ShadowSampler") + 1, "ShadowSampler"); + _shadowSampler->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("ShadowSampler") - 1, "ShadowSampler"); D3D11_RASTERIZER_DESC rasterizerStateDesc = {}; @@ -284,8 +246,6 @@ namespace TEN::Renderer _fullscreenTriangleVertexBuffer = VertexBuffer(_device.Get(), 3, &vertices[0]); - _sPostProcess = CompileOrLoadShader("PostProcess", "", ShaderType::PixelAndVertex); - D3D11_INPUT_ELEMENT_DESC postProcessInputLayoutItems[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, @@ -293,14 +253,9 @@ namespace TEN::Renderer { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; + const auto& ppShader = _shaders.Get(Shader::PostProcess); Utils::throwIfFailed(_device->CreateInputLayout(postProcessInputLayoutItems, 3, - _sPostProcess.Vertex.Blob->GetBufferPointer(), _sPostProcess.Vertex.Blob->GetBufferSize(), &_fullscreenTriangleInputLayout)); - - _sPostProcessMonochrome = CompileOrLoadShader("PostProcess", "Monochrome", ShaderType::Pixel); - _sPostProcessNegative = CompileOrLoadShader("PostProcess", "Negative", ShaderType::Pixel); - _sPostProcessExclusion = CompileOrLoadShader("PostProcess", "Exclusion", ShaderType::Pixel); - _sPostProcessFinalPass = CompileOrLoadShader("PostProcess", "FinalPass", ShaderType::Pixel); - _sPostProcessLensFlare = CompileOrLoadShader("PostProcess", "LensFlare", ShaderType::Pixel); + ppShader.Vertex.Blob->GetBufferPointer(), ppShader.Vertex.Blob->GetBufferSize(), &_fullscreenTriangleInputLayout)); } void Renderer::CreateSSAONoiseTexture() @@ -381,8 +336,9 @@ namespace TEN::Renderer void Renderer::InitializeSky() { - Vertex vertices[SKY_VERTICES_COUNT]; - int indices[SKY_INDICES_COUNT]; + auto vertices = std::vector(SKY_VERTICES_COUNT); + auto indices = std::vector(SKY_INDICES_COUNT); + int size = SKY_SIZE; int lastVertex = 0; @@ -451,8 +407,8 @@ namespace TEN::Renderer } } - _skyVertexBuffer = VertexBuffer(_device.Get(), SKY_VERTICES_COUNT, vertices); - _skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices); + _skyVertexBuffer = VertexBuffer(_device.Get(), SKY_VERTICES_COUNT, vertices.data()); + _skyIndexBuffer = IndexBuffer(_device.Get(), SKY_INDICES_COUNT, indices.data()); } void Renderer::InitializeScreen(int w, int h, HWND handle, bool reset) @@ -560,40 +516,6 @@ namespace TEN::Renderer _SMAASceneSRGBRenderTarget = RenderTarget2D(_device.Get(), &_SMAASceneRenderTarget, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); _SMAAEdgesRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8_UNORM, false, DXGI_FORMAT_UNKNOWN); _SMAABlendRenderTarget = RenderTarget2D(_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM, false, DXGI_FORMAT_UNKNOWN); - - auto string = std::stringstream{}; - auto defines = std::vector{}; - - // Set up pixel size macro. - string << "float4(1.0 / " << w << ", 1.0 / " << h << ", " << w << ", " << h << ")"; - auto pixelSizeText = string.str(); - auto renderTargetMetricsMacro = D3D10_SHADER_MACRO{ "SMAA_RT_METRICS", pixelSizeText.c_str() }; - defines.push_back(renderTargetMetricsMacro); - - if (g_Configuration.AntialiasingMode == AntialiasingMode::Medium) - { - defines.push_back({ "SMAA_PRESET_HIGH", nullptr }); - } - else - { - defines.push_back({ "SMAA_PRESET_ULTRA", nullptr }); - } - - // defines.push_back({ "SMAA_PREDICATION", "1" }); - - // Set up target macro. - auto dx101Macro = D3D10_SHADER_MACRO{ "SMAA_HLSL_4_1", "1" }; - defines.push_back(dx101Macro); - - auto null = D3D10_SHADER_MACRO{ nullptr, nullptr }; - defines.push_back(null); - - _sSMAALumaEdgeDetection = CompileOrLoadShader("SMAA", "LumaEdgeDetection", ShaderType::Pixel, defines.data()); - _sSMAAColorEdgeDetection = CompileOrLoadShader("SMAA", "ColorEdgeDetection", ShaderType::Pixel, defines.data()); - _sSMAADepthEdgeDetection = CompileOrLoadShader("SMAA", "DepthEdgeDetection", ShaderType::Pixel, defines.data()); - _sSMAABlendingWeightCalculation = CompileOrLoadShader("SMAA", "BlendingWeightCalculation", ShaderType::PixelAndVertex, defines.data()); - _sSMAANeighborhoodBlending = CompileOrLoadShader("SMAA", "NeighborhoodBlending", ShaderType::PixelAndVertex, defines.data()); - _sSMAAEdgeDetection = CompileOrLoadShader("SMAA", "EdgeDetection", ShaderType::Vertex, defines.data()); } void Renderer::InitializeCommonTextures() @@ -631,15 +553,18 @@ namespace TEN::Renderer if constexpr (DebugBuild) { res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, - levels, 1, D3D11_SDK_VERSION, &_device, &featureLevel, &_context); + levels, 1, D3D11_SDK_VERSION, &_device, &featureLevel, &_context); } else { res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, - levels, 1, D3D11_SDK_VERSION, &_device, &featureLevel, &_context); + levels, 1, D3D11_SDK_VERSION, &_device, &featureLevel, &_context); } Utils::throwIfFailed(res); + + // Initialize shader manager. + _shaders.Initialize(_device, _context); } void Renderer::ToggleFullScreen(bool force) @@ -675,152 +600,4 @@ namespace TEN::Renderer UpdateWindow(WindowsHandle); } - - void Renderer::BindShader(const RendererShader& shader) - { - if (shader.Vertex.Shader != nullptr) _context->VSSetShader(shader.Vertex.Shader.Get(), nullptr, 0); - if (shader.Pixel.Shader != nullptr) _context->PSSetShader(shader.Pixel.Shader.Get(), nullptr, 0); - if (shader.Compute.Shader != nullptr) _context->CSSetShader(shader.Compute.Shader.Get(), nullptr, 0); - } - - RendererShader Renderer::CompileOrLoadShader(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines) - { - RendererShader result = {}; - - // We need to increment the counter to avoid overwriting compiled shaders with the same source file name. - static int compileCounter = 0; - - // Define paths for native (uncompiled) shaders and compiled shaders. - std::wstring shaderPath = GetAssetPath(L"Shaders\\"); - std::wstring compiledShaderPath = shaderPath + L"Bin\\"; - std::wstring wideFileName = TEN::Utils::ToWString(fileName); - - // Ensure the /Bin subdirectory exists. - std::filesystem::create_directories(compiledShaderPath); - - // Helper function to load or compile a shader. - auto loadOrCompileShader = [this, type, defines, shaderPath, compiledShaderPath] - (const std::wstring& baseFileName, const std::string& shaderType, const std::string& functionName, const char* model, ComPtr& bytecode) - { - // Construct the full paths using GetAssetPath. - auto prefix = ((compileCounter < 10) ? L"0" : L"") + std::to_wstring(compileCounter) + L"_"; - auto csoFileName = compiledShaderPath + prefix + baseFileName + L"." + std::wstring(shaderType.begin(), shaderType.end()) + L".cso"; - auto srcFileName = shaderPath + baseFileName; - - // Try both .hlsl and .fx extensions for the source shader. - auto srcFileNameWithExtension = srcFileName + L".hlsl"; - if (!std::filesystem::exists(srcFileNameWithExtension)) - { - srcFileNameWithExtension = srcFileName + L".fx"; - if (!std::filesystem::exists(srcFileNameWithExtension)) - { - TENLog("Shader source file not found: " + TEN::Utils::ToString(srcFileNameWithExtension), LogLevel::Error); - throw std::runtime_error("Shader source file not found"); - } - } - - // Check modification dates of the source and compiled files. - bool shouldRecompile = false; - if (std::filesystem::exists(csoFileName)) - { - auto csoTime = std::filesystem::last_write_time(csoFileName); - auto srcTime = std::filesystem::last_write_time(srcFileNameWithExtension); - shouldRecompile = srcTime > csoTime; // Recompile if the source is newer. - } - - // Load compiled shader if it exists and is up to date. - if (!shouldRecompile) - { - std::ifstream csoFile(csoFileName, std::ios::binary); - - if (csoFile.is_open()) - { - // Load compiled shader. - csoFile.seekg(0, std::ios::end); - size_t fileSize = csoFile.tellg(); - csoFile.seekg(0, std::ios::beg); - - std::vector buffer(fileSize); - csoFile.read(buffer.data(), fileSize); - csoFile.close(); - - D3DCreateBlob(fileSize, &bytecode); - memcpy(bytecode->GetBufferPointer(), buffer.data(), fileSize); - - return; - } - } - - // Set up compilation flags according to the build configuration. - unsigned int flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - - if constexpr (DebugBuild) - flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; - else - flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS; - - auto trimmedFileName = std::filesystem::path(srcFileNameWithExtension).filename().string(); - TENLog("Compiling shader: " + trimmedFileName, LogLevel::Info); - - // Compile shader. - ComPtr errors; - HRESULT res = D3DCompileFromFile(srcFileNameWithExtension.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, - (shaderType + functionName).c_str(), model, flags, 0, bytecode.GetAddressOf(), errors.GetAddressOf()); - - if (FAILED(res)) - { - if (errors) - { - auto error = std::string(static_cast(errors->GetBufferPointer())); - TENLog(error, LogLevel::Error); - throw std::runtime_error(error); - } - else - { - TENLog("Error while compiling shader: " + trimmedFileName, LogLevel::Error); - throwIfFailed(res); - } - } - - // Save compiled shader to .cso file. - std::ofstream outCsoFile(csoFileName, std::ios::binary); - if (outCsoFile.is_open()) - { - outCsoFile.write(reinterpret_cast(bytecode->GetBufferPointer()), bytecode->GetBufferSize()); - outCsoFile.close(); - } - }; - - // Load or compile and create pixel shader. - if (type == ShaderType::Pixel || type == ShaderType::PixelAndVertex) - { - loadOrCompileShader(wideFileName, "PS", funcName, "ps_5_0", result.Pixel.Blob); - throwIfFailed(_device->CreatePixelShader(result.Pixel.Blob->GetBufferPointer(), result.Pixel.Blob->GetBufferSize(), - nullptr, result.Pixel.Shader.GetAddressOf() - )); - } - - // Load or compile and create vertex shader. - if (type == ShaderType::Vertex || type == ShaderType::PixelAndVertex) - { - loadOrCompileShader(wideFileName, "VS", funcName, "vs_5_0", result.Vertex.Blob); - throwIfFailed(_device->CreateVertexShader(result.Vertex.Blob->GetBufferPointer(), result.Vertex.Blob->GetBufferSize(), - nullptr, result.Vertex.Shader.GetAddressOf() - )); - } - - // Load or compile and create compute shader. - if (type == ShaderType::Compute) - { - loadOrCompileShader(wideFileName, "CS", funcName, "cs_5_0", result.Compute.Blob); - throwIfFailed(_device->CreateComputeShader(result.Compute.Blob->GetBufferPointer(), result.Compute.Blob->GetBufferSize(), - nullptr, result.Compute.Shader.GetAddressOf() - )); - } - - // Increment the compile counter. - compileCounter++; - - return result; - } -} \ No newline at end of file +} diff --git a/TombEngine/Renderer/RendererPostProcess.cpp b/TombEngine/Renderer/RendererPostProcess.cpp index 91370ef08..ccd87f8b9 100644 --- a/TombEngine/Renderer/RendererPostProcess.cpp +++ b/TombEngine/Renderer/RendererPostProcess.cpp @@ -42,7 +42,7 @@ namespace TEN::Renderer _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get()); // Common vertex shader to all fullscreen effects. - BindShader(_sPostProcess); + _shaders.Bind(Shader::PostProcess); // Draw fullscreen triangle. _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -71,7 +71,7 @@ namespace TEN::Renderer _context->ClearRenderTargetView(_postProcessRenderTarget[destRenderTarget].RenderTargetView.Get(), clearColor); _context->OMSetRenderTargets(1, _postProcessRenderTarget[destRenderTarget].RenderTargetView.GetAddressOf(), nullptr); - BindShader(_sPostProcessLensFlare); + _shaders.Bind(Shader::PostProcessLensFlare); for (int i = 0; i < view.LensFlaresToDraw.size(); i++) { @@ -97,15 +97,15 @@ namespace TEN::Renderer switch (_postProcessMode) { case PostProcessMode::Monochrome: - BindShader(_sPostProcessMonochrome); + _shaders.Bind(Shader::PostProcessMonochrome); break; case PostProcessMode::Negative: - BindShader(_sPostProcessNegative); + _shaders.Bind(Shader::PostProcessNegative); break; case PostProcessMode::Exclusion: - BindShader(_sPostProcessExclusion); + _shaders.Bind(Shader::PostProcessExclusion); break; default: @@ -120,7 +120,7 @@ namespace TEN::Renderer } // Do final pass. - BindShader(_sPostProcessFinalPass); + _shaders.Bind(Shader::PostProcessFinalPass); _context->ClearRenderTargetView(renderTarget->RenderTargetView.Get(), Colors::Black); _context->OMSetRenderTargets(1, renderTarget->RenderTargetView.GetAddressOf(), nullptr); @@ -171,7 +171,7 @@ namespace TEN::Renderer ResetScissor(); // Common vertex shader to all fullscreen effects - BindShader(_sPostProcess); + _shaders.Bind(Shader::PostProcess); // We draw a fullscreen triangle _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp index a4cc72c7c..22e841990 100644 --- a/TombEngine/Renderer/RendererSprites.cpp +++ b/TombEngine/Renderer/RendererSprites.cpp @@ -279,7 +279,7 @@ namespace TEN::Renderer SetDepthState(DepthState::Read); SetCullMode(CullMode::None); - BindShader(_sInstancedSprites); + _shaders.Bind(Shader::InstancedSprites); // Set up vertex buffer and parameters. unsigned int stride = sizeof(Vertex); @@ -340,7 +340,7 @@ namespace TEN::Renderer SetDepthState(DepthState::Read); SetCullMode(CullMode::None); - BindShader(_sSprites); + _shaders.Bind(Shader::Sprites); wasGPUSet = true; } @@ -411,7 +411,7 @@ namespace TEN::Renderer SetBlendMode(object->Sprite->BlendMode); SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); - BindShader(_sInstancedSprites); + _shaders.Bind(Shader::InstancedSprites); // Set up vertex buffer and parameters. UINT stride = sizeof(Vertex); @@ -456,7 +456,7 @@ namespace TEN::Renderer SetBlendMode(object->Sprite->BlendMode); SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); - BindShader(_sSprites); + _shaders.Bind(Shader::Sprites); _stSprite.IsSoftParticle = object->Sprite->SoftParticle ? 1 : 0; _stSprite.RenderType = (int)object->Sprite->renderType; @@ -498,10 +498,10 @@ namespace TEN::Renderer void Renderer::DrawSpriteSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view) { - UINT stride = sizeof(Vertex); - UINT offset = 0; + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; - BindShader(_sSprites); + _shaders.Bind(Shader::Sprites); _sortedPolygonsVertexBuffer.Update(_context.Get(), _sortedPolygonsVertices.data(), 0, (int)_sortedPolygonsVertices.size()); @@ -527,4 +527,3 @@ namespace TEN::Renderer _numSortedTriangles += (int)_sortedPolygonsVertices.size() / 3; } } - diff --git a/TombEngine/Renderer/RendererUtils.cpp b/TombEngine/Renderer/RendererUtils.cpp index ae6b6a030..dc5efe4b1 100644 --- a/TombEngine/Renderer/RendererUtils.cpp +++ b/TombEngine/Renderer/RendererUtils.cpp @@ -8,8 +8,9 @@ #include #include "Renderer/Renderer.h" +#include "Renderer/Structures/RendererShader.h" +#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Specific/trutils.h" -#include "Structures/RendererShader.h" namespace TEN::Renderer::Utils { @@ -42,4 +43,9 @@ namespace TEN::Renderer::Utils throw std::runtime_error("An error occured!"); } } + + std::wstring GetAssetPath(const wchar_t* fileName) + { + return TEN::Utils::ToWString(g_GameFlow->GetGameDir()) + fileName; + } } diff --git a/TombEngine/Renderer/RendererUtils.h b/TombEngine/Renderer/RendererUtils.h index 8fc12b203..d9336688c 100644 --- a/TombEngine/Renderer/RendererUtils.h +++ b/TombEngine/Renderer/RendererUtils.h @@ -9,4 +9,6 @@ namespace TEN::Renderer::Utils void throwIfFailed(const HRESULT& res); void throwIfFailed(const HRESULT& res, const std::string& info); void throwIfFailed(const HRESULT& res, const std::wstring& info); + + std::wstring GetAssetPath(const wchar_t* fileName); } diff --git a/TombEngine/Renderer/ShaderManager/ShaderManager.cpp b/TombEngine/Renderer/ShaderManager/ShaderManager.cpp new file mode 100644 index 000000000..bf489e1b7 --- /dev/null +++ b/TombEngine/Renderer/ShaderManager/ShaderManager.cpp @@ -0,0 +1,317 @@ +#include "framework.h" +#include "Renderer/ShaderManager/ShaderManager.h" + +#include "Renderer/RendererUtils.h" +#include "Renderer/Structures/RendererShader.h" +#include "Specific/configuration.h" +#include "Specific/trutils.h" + +using namespace TEN::Renderer::Structures; + +namespace TEN::Renderer::Utils +{ + ShaderManager::~ShaderManager() + { + _device = nullptr; + _context = nullptr; + + for (int i = 0; i < (int)Shader::Count; i++) + Destroy((Shader)i); + } + + const RendererShader& ShaderManager::Get(Shader shader) + { + return _shaders[(int)shader]; + } + + void ShaderManager::Initialize(ComPtr& device, ComPtr& context) + { + _device = device; + _context = context; + } + + void ShaderManager::LoadPostprocessShaders() + { + Load(Shader::PostProcess, "PostProcess", "", ShaderType::PixelAndVertex); + + Load(Shader::PostProcessMonochrome, "PostProcess", "Monochrome", ShaderType::Pixel); + Load(Shader::PostProcessNegative, "PostProcess", "Negative", ShaderType::Pixel); + Load(Shader::PostProcessExclusion, "PostProcess", "Exclusion", ShaderType::Pixel); + Load(Shader::PostProcessFinalPass, "PostProcess", "FinalPass", ShaderType::Pixel); + Load(Shader::PostProcessLensFlare, "PostProcess", "LensFlare", ShaderType::Pixel); + + Load(Shader::Ssao, "SSAO", "", ShaderType::Pixel); + Load(Shader::SsaoBlur, "SSAO", "Blur", ShaderType::Pixel); + } + + void ShaderManager::LoadAAShaders(int width, int height, bool recompile) + { + auto string = std::stringstream{}; + auto defines = std::vector{}; + + // Set up pixel size macro. + string << "float4(1.0 / " << width << ", 1.0 / " << height << ", " << width << ", " << height << ")"; + auto pixelSizeText = string.str(); + auto renderTargetMetricsMacro = D3D10_SHADER_MACRO{ "SMAA_RT_METRICS", pixelSizeText.c_str() }; + defines.push_back(renderTargetMetricsMacro); + + if (g_Configuration.AntialiasingMode == AntialiasingMode::Medium) + { + defines.push_back({ "SMAA_PRESET_MEDIUM", nullptr }); + } + else + { + defines.push_back({ "SMAA_PRESET_ULTRA", nullptr }); + } + + // defines.push_back({ "SMAA_PREDICATION", "1" }); + + // Set up target macro. + auto dx101Macro = D3D10_SHADER_MACRO{ "SMAA_HLSL_4_1", "1" }; + defines.push_back(dx101Macro); + + auto null = D3D10_SHADER_MACRO{ nullptr, nullptr }; + defines.push_back(null); + + Load(Shader::SmaaEdgeDetection, "SMAA", "EdgeDetection", ShaderType::Vertex, defines.data(), recompile); + Load(Shader::SmaaLumaEdgeDetection, "SMAA", "LumaEdgeDetection", ShaderType::Pixel, defines.data(), recompile); + Load(Shader::SmaaColorEdgeDetection, "SMAA", "ColorEdgeDetection", ShaderType::Pixel, defines.data(), recompile); + Load(Shader::SmaaDepthEdgeDetection, "SMAA", "DepthEdgeDetection", ShaderType::Pixel, defines.data(), recompile); + Load(Shader::SmaaBlendingWeightCalculation, "SMAA", "BlendingWeightCalculation", ShaderType::PixelAndVertex, defines.data(), recompile); + Load(Shader::SmaaNeighborhoodBlending, "SMAA", "NeighborhoodBlending", ShaderType::PixelAndVertex, defines.data(), recompile); + + Load(Shader::Fxaa, "FXAA", "", ShaderType::Pixel); + } + + void ShaderManager::LoadCommonShaders() + { + D3D_SHADER_MACRO roomAnimated[] = { "ANIMATED", "", nullptr, nullptr }; + D3D_SHADER_MACRO roomTransparent[] = { "TRANSPARENT", "", nullptr, nullptr }; + D3D_SHADER_MACRO shadowMap[] = { "SHADOW_MAP", "", nullptr, nullptr }; + + Load(Shader::Rooms, "Rooms", "", ShaderType::PixelAndVertex); + Load(Shader::RoomsAnimated, "Rooms", "", ShaderType::Vertex, roomAnimated); + Load(Shader::RoomsTransparent, "Rooms", "", ShaderType::Pixel, roomTransparent); + + Load(Shader::RoomAmbient, "RoomAmbient", "", ShaderType::PixelAndVertex); + Load(Shader::RoomAmbientSky, "RoomAmbient", "Sky", ShaderType::Vertex); + + Load(Shader::Items, "Items", "", ShaderType::PixelAndVertex); + Load(Shader::Statics, "Statics", "", ShaderType::PixelAndVertex); + Load(Shader::Sky, "Sky", "", ShaderType::PixelAndVertex); + Load(Shader::Sprites, "Sprites", "", ShaderType::PixelAndVertex); + Load(Shader::Solid, "Solid", "", ShaderType::PixelAndVertex); + Load(Shader::Inventory, "Inventory", "", ShaderType::PixelAndVertex); + Load(Shader::FullScreenQuad, "FullScreenQuad", "", ShaderType::PixelAndVertex); + Load(Shader::ShadowMap, "ShadowMap", "", ShaderType::PixelAndVertex, shadowMap); + + Load(Shader::Hud, "HUD", "", ShaderType::Vertex); + Load(Shader::HudColor, "HUD", "ColoredHUD", ShaderType::Pixel); + Load(Shader::HudDTexture, "HUD", "TexturedHUD", ShaderType::Pixel); + Load(Shader::HudBarColor, "HUD", "TexturedHUDBar", ShaderType::Pixel); + + Load(Shader::InstancedStatics, "InstancedStatics", "", ShaderType::PixelAndVertex); + Load(Shader::InstancedSprites, "InstancedSprites", "", ShaderType::PixelAndVertex); + + Load(Shader::GBuffer, "GBuffer", "", ShaderType::Pixel); + Load(Shader::GBufferRooms, "GBuffer", "Rooms", ShaderType::Vertex); + Load(Shader::GBufferRoomsAnimated, "GBuffer", "Rooms", ShaderType::Vertex, roomAnimated); + Load(Shader::GBufferItems, "GBuffer", "Items", ShaderType::Vertex); + Load(Shader::GBufferStatics, "GBuffer", "Statics", ShaderType::Vertex); + Load(Shader::GBufferInstancedStatics, "GBuffer", "InstancedStatics", ShaderType::Vertex); + } + + void ShaderManager::LoadShaders(int width, int height, bool recompileAAShaders) + { + TENLog("Loading shaders...", LogLevel::Info); + + // Unbind any currently bound shader. + Bind(Shader::None, true); + + // Reset compile counter. + _compileCounter = 0; + + LoadCommonShaders(); + LoadPostprocessShaders(); + LoadAAShaders(width, height, recompileAAShaders); + } + + void ShaderManager::Bind(Shader shader, bool forceNull) + { + const auto& shaderObj = _shaders[(int)shader]; + + if (shaderObj.Vertex.Shader != nullptr || forceNull) + _context->VSSetShader(shaderObj.Vertex.Shader.Get(), nullptr, 0); + + if (shaderObj.Pixel.Shader != nullptr || forceNull) + _context->PSSetShader(shaderObj.Pixel.Shader.Get(), nullptr, 0); + + if (shaderObj.Compute.Shader != nullptr || forceNull) + _context->CSSetShader(shaderObj.Compute.Shader.Get(), nullptr, 0); + } + + RendererShader ShaderManager::LoadOrCompile(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines, bool forceRecompile) + { + auto rendererShader = RendererShader{}; + + // Define paths for native (uncompiled) shaders and compiled shaders. + auto shaderPath = GetAssetPath(L"Shaders\\"); + auto compiledShaderPath = shaderPath + L"Bin\\"; + auto wideFileName = TEN::Utils::ToWString(fileName); + + // Ensure the /Bin subdirectory exists. + std::filesystem::create_directories(compiledShaderPath); + + // Helper function to load or compile a shader. + auto loadOrCompileShader = [this, type, defines, forceRecompile, shaderPath, compiledShaderPath] + (const std::wstring& baseFileName, const std::string& shaderType, const std::string& functionName, const char* model, ComPtr& bytecode) + { + // Construct full paths using GetAssetPath. + auto prefix = ((_compileCounter < 10) ? L"0" : L"") + std::to_wstring(_compileCounter) + L"_"; + auto csoFileName = compiledShaderPath + prefix + baseFileName + L"." + std::wstring(shaderType.begin(), shaderType.end()) + L".cso"; + auto srcFileName = shaderPath + baseFileName; + + // Try both .hlsl and .fx extensions for source shader. + auto srcFileNameWithExtension = srcFileName + L".hlsl"; + if (!std::filesystem::exists(srcFileNameWithExtension)) + { + srcFileNameWithExtension = srcFileName + L".fx"; + if (!std::filesystem::exists(srcFileNameWithExtension)) + { + TENLog("Shader source file not found: " + TEN::Utils::ToString(srcFileNameWithExtension), LogLevel::Error); + throw std::runtime_error("Shader source file not found."); + } + } + + // Check modification dates of source and compiled files. + if (!forceRecompile && std::filesystem::exists(csoFileName)) + { + auto csoTime = std::filesystem::last_write_time(csoFileName); + auto srcTime = std::filesystem::last_write_time(srcFileNameWithExtension); + + // Load compiled shader if it exists and is up-to-date. + if (srcTime < csoTime) + { + auto csoFile = std::ifstream(csoFileName, std::ios::binary); + + if (csoFile.is_open()) + { + // Load compiled shader. + csoFile.seekg(0, std::ios::end); + auto fileSize = csoFile.tellg(); + csoFile.seekg(0, std::ios::beg); + + auto buffer = std::vector(fileSize); + csoFile.read(buffer.data(), fileSize); + csoFile.close(); + + D3DCreateBlob(fileSize, &bytecode); + memcpy(bytecode->GetBufferPointer(), buffer.data(), fileSize); + + return; + } + } + } + + // Set up compilation flags according to build configuration. + unsigned int flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; + if constexpr (DebugBuild) + { + flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; + } + else + { + flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS; + } + + auto trimmedFileName = std::filesystem::path(srcFileNameWithExtension).filename().string(); + TENLog("Compiling shader: " + trimmedFileName, LogLevel::Info); + + // Compile shader. + auto errors = ComPtr{}; + HRESULT res = D3DCompileFromFile(srcFileNameWithExtension.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, + (shaderType + functionName).c_str(), model, flags, 0, bytecode.GetAddressOf(), errors.GetAddressOf()); + + if (FAILED(res)) + { + if (errors) + { + auto error = std::string((const char*)(errors->GetBufferPointer())); + TENLog(error, LogLevel::Error); + throw std::runtime_error(error); + } + else + { + TENLog("Error while compiling shader: " + trimmedFileName, LogLevel::Error); + throwIfFailed(res); + } + } + + // Save compiled shader to .cso file. + auto outCsoFile = std::ofstream(csoFileName, std::ios::binary); + if (outCsoFile.is_open()) + { + outCsoFile.write((const char*)(bytecode->GetBufferPointer()), bytecode->GetBufferSize()); + outCsoFile.close(); + } + }; + + // Load or compile and create pixel shader. + if (type == ShaderType::Pixel || type == ShaderType::PixelAndVertex) + { + loadOrCompileShader(wideFileName, "PS", funcName, "ps_5_0", rendererShader.Pixel.Blob); + throwIfFailed(_device->CreatePixelShader(rendererShader.Pixel.Blob->GetBufferPointer(), rendererShader.Pixel.Blob->GetBufferSize(), + nullptr, rendererShader.Pixel.Shader.GetAddressOf())); + } + + // Load or compile and create vertex shader. + if (type == ShaderType::Vertex || type == ShaderType::PixelAndVertex) + { + loadOrCompileShader(wideFileName, "VS", funcName, "vs_5_0", rendererShader.Vertex.Blob); + throwIfFailed(_device->CreateVertexShader(rendererShader.Vertex.Blob->GetBufferPointer(), rendererShader.Vertex.Blob->GetBufferSize(), + nullptr, rendererShader.Vertex.Shader.GetAddressOf())); + } + + // Load or compile and create compute shader. + if (type == ShaderType::Compute) + { + loadOrCompileShader(wideFileName, "CS", funcName, "cs_5_0", rendererShader.Compute.Blob); + throwIfFailed(_device->CreateComputeShader(rendererShader.Compute.Blob->GetBufferPointer(), rendererShader.Compute.Blob->GetBufferSize(), + nullptr, rendererShader.Compute.Shader.GetAddressOf())); + } + + // Increment compile counter. + _compileCounter++; + + return rendererShader; + } + + void ShaderManager::Load(Shader shader, const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines, bool forceRecompile) + { + Destroy(shader); + _shaders[(int)shader] = LoadOrCompile(fileName, funcName, type, defines, forceRecompile); + } + + void ShaderManager::Destroy(Shader shader) + { + auto& shaderData = _shaders[(int)shader]; + + if (shaderData.Vertex.Shader != nullptr) + { + shaderData.Vertex.Shader.Reset(); + shaderData.Vertex.Blob.Reset(); + } + + if (shaderData.Pixel.Shader != nullptr) + { + shaderData.Pixel.Shader.Reset(); + shaderData.Pixel.Blob.Reset(); + } + + if (shaderData.Compute.Shader != nullptr) + { + shaderData.Compute.Shader.Reset(); + shaderData.Compute.Blob.Reset(); + } + } +} diff --git a/TombEngine/Renderer/ShaderManager/ShaderManager.h b/TombEngine/Renderer/ShaderManager/ShaderManager.h new file mode 100644 index 000000000..d28d5d300 --- /dev/null +++ b/TombEngine/Renderer/ShaderManager/ShaderManager.h @@ -0,0 +1,101 @@ +#pragma once + +#include "Renderer/Structures/RendererShader.h" + +using namespace TEN::Renderer::Structures; + +namespace TEN::Renderer::Utils +{ + enum class Shader + { + // General + + None, + Rooms, + RoomsAnimated, + RoomsTransparent, + RoomAmbient, + RoomAmbientSky, + Items, + Statics, + InstancedStatics, + Sprites, + InstancedSprites, + Sky, + Solid, + Inventory, + FullScreenQuad, + ShadowMap, + + // HUD + + Hud, + HudColor, + HudDTexture, + HudBarColor, + + // GBuffer + + GBuffer, + GBufferRooms, + GBufferRoomsAnimated, + GBufferItems, + GBufferStatics, + GBufferInstancedStatics, + + // SMAA + + SmaaEdgeDetection, + SmaaLumaEdgeDetection, + SmaaColorEdgeDetection, + SmaaDepthEdgeDetection, + SmaaBlendingWeightCalculation, + SmaaNeighborhoodBlending, + Fxaa, + + // Post-process + + PostProcess, + PostProcessMonochrome, + PostProcessNegative, + PostProcessExclusion, + PostProcessFinalPass, + PostProcessLensFlare, + + // SSAO + + Ssao, + SsaoBlur, + + Count + }; + + class ShaderManager + { + private: + ComPtr _device = nullptr; + ComPtr _context = nullptr; + + int _compileCounter = 0; + std::array _shaders = {}; + + public: + ShaderManager() = default; + ~ShaderManager(); + + const RendererShader& Get(Shader shader); + + void Initialize(ComPtr& device, ComPtr& context); + void LoadShaders(int width, int height, bool recompileAAShaders = false); + void Bind(Shader shader, bool forceNull = false); + + private: + void LoadCommonShaders(); + void LoadPostprocessShaders(); + void LoadAAShaders(int width, int height, bool recompile); + + RendererShader LoadOrCompile(const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines, bool forceRecompile); + void Load(Shader shader, const std::string& fileName, const std::string& funcName, ShaderType type, const D3D_SHADER_MACRO* defines = nullptr, bool forceRecompile = false); + void Destroy(Shader shader); + }; +} diff --git a/TombEngine/Specific/IO/Streams.h b/TombEngine/Specific/IO/Streams.h index 04c206dc6..93cce4c3b 100644 --- a/TombEngine/Specific/IO/Streams.h +++ b/TombEngine/Specific/IO/Streams.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/TombEngine/Specific/Input/Input.cpp b/TombEngine/Specific/Input/Input.cpp index 6a1779225..3dbab76cd 100644 --- a/TombEngine/Specific/Input/Input.cpp +++ b/TombEngine/Specific/Input/Input.cpp @@ -651,6 +651,12 @@ namespace TEN::Input if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage) g_Renderer.SwitchDebugPage(KeyMap[KC_F10]); dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]); + + // Reload shaders. + static bool dbReloadShaders = true; + if (KeyMap[KC_F9] && dbReloadShaders) + g_Renderer.ReloadShaders(); + dbReloadShaders = !KeyMap[KC_F9]; } static void UpdateRumble() diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index c32f575be..97a2d7462 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -823,6 +823,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -1318,6 +1319,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + diff --git a/TombEngine/framework.h b/TombEngine/framework.h index 7d9cd9fac..8b57fc862 100644 --- a/TombEngine/framework.h +++ b/TombEngine/framework.h @@ -3,8 +3,10 @@ #include #include #include +#include #include #include +#include #include #include #include From 8fb4668dfc621bb3ea2f595e3a73ee12c5f961a6 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 26 Dec 2024 11:19:19 +0100 Subject: [PATCH 26/26] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe8bacc7f..c064432ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,12 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## Version 1.8 - xxxx-xx-xx ### Bug fixes +* Fixed static meshes with dynamic light mode not accepting room lights. +* Fixed antialiasing quality not changing after changing it in display settings. + ### New Features +* Added realtime shader reloading in debug mode by pressing F9 key. ### Lua API changes