mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge branch 'develop' into develop_mirrors;
Removed RendererMirror references in methods calls;
This commit is contained in:
commit
4e08942d86
28 changed files with 462 additions and 382 deletions
|
@ -31,6 +31,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
|
||||||
* Fixed Lara's Home entry not working.
|
* Fixed Lara's Home entry not working.
|
||||||
* Fixed exploding TR3 bosses.
|
* Fixed exploding TR3 bosses.
|
||||||
* Fixed original issue with deactivation of Dart Emitter.
|
* Fixed original issue with deactivation of Dart Emitter.
|
||||||
|
* Fixed original issue with weapon hotkeys available in binoculars or lasersight mode.
|
||||||
* Fixed Lens Flare object not functioning properly.
|
* Fixed Lens Flare object not functioning properly.
|
||||||
* Fixed lens flares not being occluded by static meshes and moveables.
|
* Fixed lens flares not being occluded by static meshes and moveables.
|
||||||
* Fixed spotlight shadows.
|
* Fixed spotlight shadows.
|
||||||
|
@ -38,7 +39,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
* Added fast savegame reloading.
|
* Added fast savegame reloading.
|
||||||
|
* Added dynamic shadow casting on objects and static meshes.
|
||||||
* Added ricochet sounds and make the effect more prominent.
|
* Added ricochet sounds and make the effect more prominent.
|
||||||
|
* Allow camera shake during flybys.
|
||||||
* Allow to run the engine without title level.
|
* Allow to run the engine without title level.
|
||||||
* Allow more than 1024 objects in a level.
|
* Allow more than 1024 objects in a level.
|
||||||
* Allow more than 1000 static mesh slots in a level.
|
* Allow more than 1000 static mesh slots in a level.
|
||||||
|
@ -56,6 +59,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
|
||||||
* Use load camera instead of load screen by playing fixed camera from OnEnd() event and removing loadScreenFile field from level's gameflow entry.
|
* Use load camera instead of load screen by playing fixed camera from OnEnd() event and removing loadScreenFile field from level's gameflow entry.
|
||||||
* Fixed DisplayString class not supporting some Unicode characters and empty lines in multiline strings.
|
* Fixed DisplayString class not supporting some Unicode characters and empty lines in multiline strings.
|
||||||
* Fixed DisplayString not being deallocated after showing.
|
* Fixed DisplayString not being deallocated after showing.
|
||||||
|
* Fixed GameVars not transferring between levels in hub mode.
|
||||||
* Fixed incorrect behaviour of Moveable:GetJointRotation() function.
|
* Fixed incorrect behaviour of Moveable:GetJointRotation() function.
|
||||||
* Fixed incorrect behaviour of Logic.EnableEvent() and Logic.DisableEvent() functions.
|
* Fixed incorrect behaviour of Logic.EnableEvent() and Logic.DisableEvent() functions.
|
||||||
* Fixed Util.HasLineOfSight() not taking static meshes into consideration.
|
* Fixed Util.HasLineOfSight() not taking static meshes into consideration.
|
||||||
|
|
|
@ -342,6 +342,10 @@ void HandlePlayerQuickActions(ItemInfo& item)
|
||||||
g_Gui.UseItem(item, GAME_OBJECT_ID::ID_BIGMEDI_ITEM);
|
g_Gui.UseItem(item, GAME_OBJECT_ID::ID_BIGMEDI_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't process weapon hotkeys in optics mode.
|
||||||
|
if (player.Control.Look.IsUsingBinoculars)
|
||||||
|
return;
|
||||||
|
|
||||||
// Handle weapon scroll request.
|
// Handle weapon scroll request.
|
||||||
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
|
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
|
||||||
{
|
{
|
||||||
|
@ -888,7 +892,9 @@ void HandlePlayerFlyCheat(ItemInfo& item)
|
||||||
{
|
{
|
||||||
if (player.Context.Vehicle == NO_VALUE)
|
if (player.Context.Vehicle == NO_VALUE)
|
||||||
{
|
{
|
||||||
GivePlayerItemsCheat(item);
|
if (KeyMap[OIS::KeyCode::KC_LSHIFT] || KeyMap[OIS::KeyCode::KC_RSHIFT])
|
||||||
|
GivePlayerItemsCheat(item);
|
||||||
|
|
||||||
GivePlayerWeaponsCheat(item);
|
GivePlayerWeaponsCheat(item);
|
||||||
|
|
||||||
if (player.Control.WaterStatus != WaterStatus::FlyCheat)
|
if (player.Control.WaterStatus != WaterStatus::FlyCheat)
|
||||||
|
|
|
@ -215,6 +215,38 @@ inline void RumbleFromBounce()
|
||||||
Rumble(std::clamp((float)abs(Camera.bounce) / 70.0f, 0.0f, 0.8f), 0.2f);
|
Rumble(std::clamp((float)abs(Camera.bounce) / 70.0f, 0.0f, 0.8f), 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalculateBounce(bool binocularMode)
|
||||||
|
{
|
||||||
|
if (Camera.bounce == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Camera.bounce <= 0)
|
||||||
|
{
|
||||||
|
if (binocularMode)
|
||||||
|
{
|
||||||
|
Camera.target.x += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
||||||
|
Camera.target.y += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
||||||
|
Camera.target.z += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int bounce = -Camera.bounce;
|
||||||
|
int bounce2 = bounce / 2;
|
||||||
|
Camera.target.x += GetRandomControl() % bounce - bounce2;
|
||||||
|
Camera.target.y += GetRandomControl() % bounce - bounce2;
|
||||||
|
Camera.target.z += GetRandomControl() % bounce - bounce2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera.bounce += 5;
|
||||||
|
RumbleFromBounce();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Camera.pos.y += Camera.bounce;
|
||||||
|
Camera.target.y += Camera.bounce;
|
||||||
|
Camera.bounce = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeCamera()
|
void InitializeCamera()
|
||||||
{
|
{
|
||||||
|
@ -313,25 +345,7 @@ void MoveCamera(GameVector* ideal, int speed)
|
||||||
Camera.pos.z += (ideal->z - Camera.pos.z) / speed;
|
Camera.pos.z += (ideal->z - Camera.pos.z) / speed;
|
||||||
Camera.pos.RoomNumber = ideal->RoomNumber;
|
Camera.pos.RoomNumber = ideal->RoomNumber;
|
||||||
|
|
||||||
if (Camera.bounce)
|
CalculateBounce(false);
|
||||||
{
|
|
||||||
if (Camera.bounce <= 0)
|
|
||||||
{
|
|
||||||
int bounce = -Camera.bounce;
|
|
||||||
int bounce2 = bounce / 2;
|
|
||||||
Camera.target.x += GetRandomControl() % bounce - bounce2;
|
|
||||||
Camera.target.y += GetRandomControl() % bounce - bounce2;
|
|
||||||
Camera.target.z += GetRandomControl() % bounce - bounce2;
|
|
||||||
Camera.bounce += 5;
|
|
||||||
RumbleFromBounce();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Camera.pos.y += Camera.bounce;
|
|
||||||
Camera.target.y += Camera.bounce;
|
|
||||||
Camera.bounce = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int y = Camera.pos.y;
|
int y = Camera.pos.y;
|
||||||
if (TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber))
|
if (TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber))
|
||||||
|
@ -1000,23 +1014,8 @@ void BinocularCamera(ItemInfo* item)
|
||||||
Camera.target.RoomNumber = item->RoomNumber;
|
Camera.target.RoomNumber = item->RoomNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Camera.bounce &&
|
if (Camera.type == Camera.oldType)
|
||||||
Camera.type == Camera.oldType)
|
CalculateBounce(true);
|
||||||
{
|
|
||||||
if (Camera.bounce <= 0)
|
|
||||||
{
|
|
||||||
Camera.target.x += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
|
||||||
Camera.target.y += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
|
||||||
Camera.target.z += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce / 2));
|
|
||||||
Camera.bounce += 5;
|
|
||||||
RumbleFromBounce();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Camera.bounce = 0;
|
|
||||||
Camera.target.y += Camera.bounce;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera.target.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.target.RoomNumber).GetRoomNumber();
|
Camera.target.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.target.RoomNumber).GetRoomNumber();
|
||||||
LookAt(&Camera, 0);
|
LookAt(&Camera, 0);
|
||||||
|
|
|
@ -99,6 +99,7 @@ void BounceCamera(ItemInfo* item, short bounce, short maxDistance);
|
||||||
void BinocularCamera(ItemInfo* item);
|
void BinocularCamera(ItemInfo* item);
|
||||||
void ConfirmCameraTargetPos();
|
void ConfirmCameraTargetPos();
|
||||||
void CalculateCamera(const CollisionInfo& coll);
|
void CalculateCamera(const CollisionInfo& coll);
|
||||||
|
void CalculateBounce(bool binocularMode);
|
||||||
void RumbleScreen();
|
void RumbleScreen();
|
||||||
bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius);
|
bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius);
|
||||||
void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius);
|
void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius);
|
||||||
|
|
|
@ -376,7 +376,6 @@ unsigned CALLBACK GameMain(void *)
|
||||||
GameStatus DoLevel(int levelIndex, bool loadGame)
|
GameStatus DoLevel(int levelIndex, bool loadGame)
|
||||||
{
|
{
|
||||||
bool isTitle = !levelIndex;
|
bool isTitle = !levelIndex;
|
||||||
auto loadType = loadGame ? LevelLoadType::Load : (SaveGame::IsOnHub(levelIndex) ? LevelLoadType::Hub : LevelLoadType::New);
|
|
||||||
|
|
||||||
TENLog(isTitle ? "DoTitle" : "DoLevel", LogLevel::Info);
|
TENLog(isTitle ? "DoTitle" : "DoLevel", LogLevel::Info);
|
||||||
|
|
||||||
|
@ -392,7 +391,7 @@ GameStatus DoLevel(int levelIndex, bool loadGame)
|
||||||
InitializeItemBoxData();
|
InitializeItemBoxData();
|
||||||
|
|
||||||
// Initialize scripting.
|
// Initialize scripting.
|
||||||
InitializeScripting(levelIndex, loadType);
|
InitializeScripting(levelIndex, loadGame);
|
||||||
InitializeNodeScripts();
|
InitializeNodeScripts();
|
||||||
|
|
||||||
// Initialize menu and inventory state.
|
// Initialize menu and inventory state.
|
||||||
|
@ -540,12 +539,12 @@ void CleanUp()
|
||||||
ClearObjCamera();
|
ClearObjCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeScripting(int levelIndex, LevelLoadType type)
|
void InitializeScripting(int levelIndex, bool loadGame)
|
||||||
{
|
{
|
||||||
TENLog("Loading level script...", LogLevel::Info);
|
TENLog("Loading level script...", LogLevel::Info);
|
||||||
|
|
||||||
g_GameStringsHandler->ClearDisplayStrings();
|
g_GameStringsHandler->ClearDisplayStrings();
|
||||||
g_GameScript->ResetScripts(!levelIndex || type != LevelLoadType::New);
|
g_GameScript->ResetScripts(!levelIndex || loadGame);
|
||||||
|
|
||||||
const auto& level = *g_GameFlow->GetLevel(levelIndex);
|
const auto& level = *g_GameFlow->GetLevel(levelIndex);
|
||||||
|
|
||||||
|
@ -575,7 +574,7 @@ void InitializeScripting(int levelIndex, LevelLoadType type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play default background music.
|
// Play default background music.
|
||||||
if (type != LevelLoadType::Load)
|
if (!loadGame)
|
||||||
PlaySoundTrack(level.GetAmbientTrack(), SoundTrackType::BGM, 0, SOUND_XFADETIME_LEVELJUMP);
|
PlaySoundTrack(level.GetAmbientTrack(), SoundTrackType::BGM, 0, SOUND_XFADETIME_LEVELJUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,8 +593,14 @@ void InitializeOrLoadGame(bool loadGame)
|
||||||
g_Gui.SetEnterInventory(NO_VALUE);
|
g_Gui.SetEnterInventory(NO_VALUE);
|
||||||
|
|
||||||
// Restore game?
|
// Restore game?
|
||||||
if (loadGame && SaveGame::Load(g_GameFlow->SelectedSaveGame))
|
if (loadGame)
|
||||||
{
|
{
|
||||||
|
if (!SaveGame::Load(g_GameFlow->SelectedSaveGame))
|
||||||
|
{
|
||||||
|
NextLevel = g_GameFlow->GetNumLevels();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InitializeGame = false;
|
InitializeGame = false;
|
||||||
|
|
||||||
g_GameFlow->SelectedSaveGame = 0;
|
g_GameFlow->SelectedSaveGame = 0;
|
||||||
|
|
|
@ -34,13 +34,6 @@ enum class FreezeMode
|
||||||
Player
|
Player
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class LevelLoadType
|
|
||||||
{
|
|
||||||
New,
|
|
||||||
Hub,
|
|
||||||
Load
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CardinalDirection
|
enum CardinalDirection
|
||||||
{
|
{
|
||||||
NORTH,
|
NORTH,
|
||||||
|
@ -106,8 +99,8 @@ void UpdateShatters();
|
||||||
void CleanUp();
|
void CleanUp();
|
||||||
|
|
||||||
void InitializeOrLoadGame(bool loadGame);
|
void InitializeOrLoadGame(bool loadGame);
|
||||||
void InitializeScripting(int levelIndex, LevelLoadType type);
|
void InitializeScripting(int levelIndex, bool loadGame);
|
||||||
void DeInitializeScripting(int levelIndex);
|
void DeInitializeScripting(int levelIndex, GameStatus reason);
|
||||||
|
|
||||||
void SetupInterpolation();
|
void SetupInterpolation();
|
||||||
|
|
||||||
|
|
|
@ -206,6 +206,19 @@ bool SaveGame::DoesSaveGameExist(int slot, bool silent)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SaveGame::IsSaveGameValid(int slot)
|
||||||
|
{
|
||||||
|
SaveGameHeader header;
|
||||||
|
if (!LoadHeader(slot, &header))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Hash mismatch between savegame and level file means that level version has changed.
|
||||||
|
if (header.LevelHash != LastLevelHash)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SaveGame::IsLoadGamePossible()
|
bool SaveGame::IsLoadGamePossible()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SAVEGAME_MAX; i++)
|
for (int i = 0; i < SAVEGAME_MAX; i++)
|
||||||
|
@ -1614,15 +1627,9 @@ bool SaveGame::Save(int slot)
|
||||||
|
|
||||||
bool SaveGame::Load(int slot)
|
bool SaveGame::Load(int slot)
|
||||||
{
|
{
|
||||||
if (!IsSaveGameSlotValid(slot))
|
if (!IsSaveGameValid(slot))
|
||||||
{
|
{
|
||||||
TENLog("Savegame slot " + std::to_string(slot) + " is invalid, load is impossible.", LogLevel::Error);
|
TENLog("Loading from savegame in slot " + std::to_string(slot) + " is impossible, data is missing or level has changed.", LogLevel::Error);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DoesSaveGameExist(slot))
|
|
||||||
{
|
|
||||||
TENLog("Savegame in slot " + std::to_string(slot) + " does not exist.", LogLevel::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1704,7 +1711,7 @@ static void ParseStatistics(const Save::SaveGame* s, bool isHub)
|
||||||
SaveGame::Statistics.Game.Timer = s->game()->timer();
|
SaveGame::Statistics.Game.Timer = s->game()->timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ParseLua(const Save::SaveGame* s)
|
static void ParseLua(const Save::SaveGame* s, bool hubMode)
|
||||||
{
|
{
|
||||||
// Event sets
|
// Event sets
|
||||||
|
|
||||||
|
@ -1808,7 +1815,7 @@ static void ParseLua(const Save::SaveGame* s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_GameScript->SetVariables(loadedVars);
|
g_GameScript->SetVariables(loadedVars, hubMode);
|
||||||
|
|
||||||
auto populateCallbackVecs = [&s](auto callbackFunc)
|
auto populateCallbackVecs = [&s](auto callbackFunc)
|
||||||
{
|
{
|
||||||
|
@ -2672,7 +2679,7 @@ void SaveGame::Parse(const std::vector<byte>& buffer, bool hubMode)
|
||||||
const Save::SaveGame* s = Save::GetSaveGame(buffer.data());
|
const Save::SaveGame* s = Save::GetSaveGame(buffer.data());
|
||||||
|
|
||||||
ParseLevel(s, hubMode);
|
ParseLevel(s, hubMode);
|
||||||
ParseLua(s);
|
ParseLua(s, hubMode);
|
||||||
ParseStatistics(s, hubMode);
|
ParseStatistics(s, hubMode);
|
||||||
|
|
||||||
// Effects and player data is ignored when loading hub.
|
// Effects and player data is ignored when loading hub.
|
||||||
|
|
|
@ -66,6 +66,7 @@ public:
|
||||||
|
|
||||||
static bool DoesSaveGameExist(int slot, bool silent = false);
|
static bool DoesSaveGameExist(int slot, bool silent = false);
|
||||||
static bool IsLoadGamePossible();
|
static bool IsLoadGamePossible();
|
||||||
|
static bool IsSaveGameValid(int slot);
|
||||||
|
|
||||||
static void SaveHub(int index);
|
static void SaveHub(int index);
|
||||||
static void LoadHub(int index);
|
static void LoadHub(int index);
|
||||||
|
|
|
@ -494,6 +494,7 @@ void CalculateSpotCameras()
|
||||||
Camera.target.x = ctx;
|
Camera.target.x = ctx;
|
||||||
Camera.target.y = cty;
|
Camera.target.y = cty;
|
||||||
Camera.target.z = ctz;
|
Camera.target.z = ctz;
|
||||||
|
CalculateBounce(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int outsideRoom = IsRoomOutside(cpx, cpy, cpz);
|
int outsideRoom = IsRoomOutside(cpx, cpy, cpz);
|
||||||
|
|
|
@ -201,49 +201,68 @@ namespace TEN::Renderer
|
||||||
_context->PSSetSamplers((UINT)registerType, 1, &samplerState);
|
_context->PSSetSamplers((UINT)registerType, 1, &samplerState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindLight(RendererLight& light, ShaderLight* lights, int index, RendererMirror* mirror)
|
int Renderer::BindLight(RendererLight& light, ShaderLight* lights, int index)
|
||||||
{
|
{
|
||||||
memcpy(&lights[index], &light, sizeof(ShaderLight));
|
memcpy(&lights[index], &light, sizeof(ShaderLight));
|
||||||
|
|
||||||
|
// Precalculate ranges so that it's not recalculated in shader for every pixel.
|
||||||
|
if (light.Type == LightType::Spot)
|
||||||
|
{
|
||||||
|
lights[index].InRange = cos(light.InRange * (PI / 180.0f));
|
||||||
|
lights[index].OutRange = cos(light.OutRange * (PI / 180.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If light has hash, interpolate its position with previous position.
|
||||||
if (light.Hash != 0)
|
if (light.Hash != 0)
|
||||||
{
|
{
|
||||||
lights[index].Position = Vector3::Lerp(light.PrevPosition, light.Position, GetInterpolationFactor());
|
lights[index].Position = Vector3::Lerp(light.PrevPosition, light.Position, GetInterpolationFactor());
|
||||||
lights[index].Direction = Vector3::Lerp(light.PrevDirection, light.Direction, GetInterpolationFactor());
|
lights[index].Direction = Vector3::Lerp(light.PrevDirection, light.Direction, GetInterpolationFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
lights[index].Position = Vector3::Transform(lights[index].Position, mirror->ReflectionMatrix);
|
lights[index].Position = Vector3::Transform(lights[index].Position, _currentMirror->ReflectionMatrix);
|
||||||
lights[index].Direction = Vector3::Transform(lights[index].Direction, mirror->ReflectionMatrix);
|
lights[index].Direction = Vector3::Transform(lights[index].Direction, _currentMirror->ReflectionMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bitmask light type to filter it in the shader later.
|
||||||
|
return (1 << (31 - (int)light.Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindRoomLights(std::vector<RendererLight*>& lights, RendererMirror* mirror)
|
void Renderer::BindRoomLights(std::vector<RendererLight*>& lights)
|
||||||
{
|
{
|
||||||
|
int lightTypeMask = 0;
|
||||||
|
|
||||||
for (int i = 0; i < lights.size(); i++)
|
for (int i = 0; i < lights.size(); i++)
|
||||||
BindLight(*lights[i], _stRoom.RoomLights, i, mirror);
|
lightTypeMask = lightTypeMask | BindLight(*lights[i], _stRoom.RoomLights, i);
|
||||||
|
|
||||||
_stRoom.NumRoomLights = (int)lights.size();
|
_stRoom.NumRoomLights = (int)lights.size() | lightTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindStaticLights(std::vector<RendererLight*>& lights, RendererMirror* mirror)
|
void Renderer::BindStaticLights(std::vector<RendererLight*>& lights)
|
||||||
{
|
{
|
||||||
|
int lightTypeMask = 0;
|
||||||
|
|
||||||
for (int i = 0; i < lights.size(); i++)
|
for (int i = 0; i < lights.size(); i++)
|
||||||
BindLight(*lights[i], _stStatic.Lights, i, mirror);
|
lightTypeMask = lightTypeMask | BindLight(*lights[i], _stStatic.Lights, i);
|
||||||
|
|
||||||
_stStatic.NumLights = (int)lights.size();
|
_stStatic.NumLights = (int)lights.size() | lightTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindInstancedStaticLights(std::vector<RendererLight*>& lights, int instanceID, RendererMirror* mirror)
|
void Renderer::BindInstancedStaticLights(std::vector<RendererLight*>& lights, int instanceID)
|
||||||
{
|
{
|
||||||
|
int lightTypeMask = 0;
|
||||||
|
|
||||||
for (int i = 0; i < lights.size(); i++)
|
for (int i = 0; i < lights.size(); i++)
|
||||||
BindLight(*lights[i], _stInstancedStaticMeshBuffer.StaticMeshes[instanceID].Lights, i, mirror);
|
lightTypeMask = lightTypeMask | BindLight(*lights[i], _stInstancedStaticMeshBuffer.StaticMeshes[instanceID].Lights, i);
|
||||||
|
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[instanceID].NumLights = (int)lights.size();
|
_stInstancedStaticMeshBuffer.StaticMeshes[instanceID].NumLights = (int)lights.size() | lightTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindMoveableLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade, RendererMirror* mirror)
|
void Renderer::BindMoveableLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade)
|
||||||
{
|
{
|
||||||
|
int lightTypeMask = 0;
|
||||||
|
|
||||||
int numLights = 0;
|
int numLights = 0;
|
||||||
for (int i = 0; i < lights.size(); i++)
|
for (int i = 0; i < lights.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -263,12 +282,13 @@ namespace TEN::Renderer
|
||||||
if (fadedCoeff == 0.0f)
|
if (fadedCoeff == 0.0f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BindLight(*lights[i], _stItem.Lights, numLights, mirror);
|
lightTypeMask = lightTypeMask | BindLight(*lights[i], _stItem.Lights, numLights);
|
||||||
|
|
||||||
_stItem.Lights[numLights].Intensity *= fadedCoeff;
|
_stItem.Lights[numLights].Intensity *= fadedCoeff;
|
||||||
numLights++;
|
numLights++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stItem.NumLights = numLights;
|
_stItem.NumLights = numLights | lightTypeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::BindConstantBufferVS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer)
|
void Renderer::BindConstantBufferVS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer)
|
||||||
|
|
|
@ -400,6 +400,7 @@ namespace TEN::Renderer
|
||||||
// Special effects
|
// Special effects
|
||||||
|
|
||||||
std::vector<Texture2D> _causticTextures;
|
std::vector<Texture2D> _causticTextures;
|
||||||
|
RendererMirror* _currentMirror = nullptr;
|
||||||
|
|
||||||
// Transparency
|
// Transparency
|
||||||
|
|
||||||
|
@ -419,11 +420,11 @@ namespace TEN::Renderer
|
||||||
void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view);
|
void ApplySMAA(RenderTarget2D* renderTarget, RenderView& view);
|
||||||
void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view);
|
void ApplyFXAA(RenderTarget2D* renderTarget, RenderView& view);
|
||||||
void BindTexture(TextureRegister registerType, TextureBase* texture, SamplerStateRegister samplerType);
|
void BindTexture(TextureRegister registerType, TextureBase* texture, SamplerStateRegister samplerType);
|
||||||
void BindLight(RendererLight& light, ShaderLight* lights, int index, RendererMirror* mirror);
|
int BindLight(RendererLight& light, ShaderLight* lights, int index);
|
||||||
void BindRoomLights(std::vector<RendererLight*>& lights, RendererMirror* mirror);
|
void BindRoomLights(std::vector<RendererLight*>& lights);
|
||||||
void BindStaticLights(std::vector<RendererLight*>& lights, RendererMirror* mirror);
|
void BindStaticLights(std::vector<RendererLight*>& lights);
|
||||||
void BindInstancedStaticLights(std::vector<RendererLight*>& lights, int instanceID, RendererMirror* mirror);
|
void BindInstancedStaticLights(std::vector<RendererLight*>& lights, int instanceID);
|
||||||
void BindMoveableLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade, RendererMirror* mirror);
|
void BindMoveableLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade);
|
||||||
void BindRenderTargetAsTexture(TextureRegister registerType, RenderTarget2D* target, SamplerStateRegister samplerType);
|
void BindRenderTargetAsTexture(TextureRegister registerType, RenderTarget2D* target, SamplerStateRegister samplerType);
|
||||||
void BindConstantBufferVS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer);
|
void BindConstantBufferVS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer);
|
||||||
void BindConstantBufferPS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer);
|
void BindConstantBufferPS(ConstantBufferRegister constantBufferType, ID3D11Buffer** buffer);
|
||||||
|
@ -455,12 +456,12 @@ namespace TEN::Renderer
|
||||||
void PrepareSingleLaserBeam(RenderView& view);
|
void PrepareSingleLaserBeam(RenderView& view);
|
||||||
void DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget);
|
void DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget);
|
||||||
void DrawRooms(RenderView& view, RendererPass rendererPass);
|
void DrawRooms(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawItems(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawItems(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawAnimatingItem(RendererItem* item, RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass);
|
||||||
void DrawWaterfalls(RendererItem* item, RendererMirror* mirror, RenderView& view, int fps, RendererPass rendererPass);
|
void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass);
|
||||||
void DrawBaddyGunflashes(RendererMirror* mirror, RenderView& view);
|
void DrawBaddyGunflashes(RenderView& view);
|
||||||
void DrawStatics(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawStatics(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawLara(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawLara(RenderView& view, RendererPass rendererPass);
|
||||||
void PrepareFires(RenderView& view);
|
void PrepareFires(RenderView& view);
|
||||||
void PrepareParticles(RenderView& view);
|
void PrepareParticles(RenderView& view);
|
||||||
void PrepareSmokes(RenderView& view);
|
void PrepareSmokes(RenderView& view);
|
||||||
|
@ -470,12 +471,12 @@ namespace TEN::Renderer
|
||||||
void PrepareWeatherParticles(RenderView& view);
|
void PrepareWeatherParticles(RenderView& view);
|
||||||
void PrepareDrips(RenderView& view);
|
void PrepareDrips(RenderView& view);
|
||||||
void PrepareBubbles(RenderView& view);
|
void PrepareBubbles(RenderView& view);
|
||||||
void DrawEffects(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawEffects(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawEffect(RendererMirror* mirror, RenderView& view, RendererEffect* effect, RendererPass rendererPass);
|
void DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass);
|
||||||
void PrepareSplashes(RenderView& view);
|
void PrepareSplashes(RenderView& view);
|
||||||
void DrawSprites(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawSprites(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawDisplaySprites(RenderView& view);
|
void DrawDisplaySprites(RenderView& view);
|
||||||
void DrawSortedFaces(RendererMirror* mirror, RenderView& view);
|
void DrawSortedFaces(RenderView& view);
|
||||||
void DrawSingleSprite(RendererSortableObject* object, RendererObjectType lastObjectType, RenderView& view);
|
void DrawSingleSprite(RendererSortableObject* object, RendererObjectType lastObjectType, RenderView& view);
|
||||||
void DrawRoomSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view);
|
void DrawRoomSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view);
|
||||||
void DrawItemSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view);
|
void DrawItemSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view);
|
||||||
|
@ -488,17 +489,17 @@ namespace TEN::Renderer
|
||||||
void DrawOverlays(RenderView& view);
|
void DrawOverlays(RenderView& view);
|
||||||
void PrepareRopes(RenderView& view);
|
void PrepareRopes(RenderView& view);
|
||||||
void DrawFishSwarm(RenderView& view, RendererPass rendererPass);
|
void DrawFishSwarm(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawBats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawBats(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawRats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawRats(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawScarabs(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawScarabs(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawSpiders(RenderView& view, RendererPass rendererPass);
|
void DrawSpiders(RenderView& view, RendererPass rendererPass);
|
||||||
bool DrawGunFlashes(RendererMirror* mirror, RenderView& view);
|
bool DrawGunFlashes(RenderView& view);
|
||||||
void DrawGunShells(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawGunShells(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawLocusts(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawLocusts(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawStatistics();
|
void DrawStatistics();
|
||||||
void DrawExamines();
|
void DrawExamines();
|
||||||
void DrawDiary();
|
void DrawDiary();
|
||||||
void DrawDebris(RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawDebris(RenderView& view, RendererPass rendererPass);
|
||||||
void DrawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target,
|
void DrawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target,
|
||||||
ID3D11DepthStencilView* depthTarget);
|
ID3D11DepthStencilView* depthTarget);
|
||||||
void PrepareShockwaves(RenderView& view);
|
void PrepareShockwaves(RenderView& view);
|
||||||
|
@ -509,9 +510,9 @@ namespace TEN::Renderer
|
||||||
void PrepareSmokeParticles(RenderView& view);
|
void PrepareSmokeParticles(RenderView& view);
|
||||||
void PrepareSparkParticles(RenderView& view);
|
void PrepareSparkParticles(RenderView& view);
|
||||||
void PrepareExplosionParticles(RenderView& view);
|
void PrepareExplosionParticles(RenderView& view);
|
||||||
void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass);
|
||||||
void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass);
|
||||||
void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass);
|
void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass);
|
||||||
void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RenderView& view, RendererPass rendererPass);
|
void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RenderView& view, RendererPass rendererPass);
|
||||||
void PrepareSimpleParticles(RenderView& view);
|
void PrepareSimpleParticles(RenderView& view);
|
||||||
void PrepareStreamers(RenderView& view);
|
void PrepareStreamers(RenderView& view);
|
||||||
|
|
|
@ -231,14 +231,14 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
RendererRoom& room = _rooms[item->RoomNumber];
|
RendererRoom& room = _rooms[item->RoomNumber];
|
||||||
|
|
||||||
DrawLaraHolsters(item, &room, nullptr, renderView, RendererPass::ShadowMap);
|
DrawLaraHolsters(item, &room, renderView, RendererPass::ShadowMap);
|
||||||
DrawLaraJoints(item, &room, nullptr, renderView, RendererPass::ShadowMap);
|
DrawLaraJoints(item, &room, renderView, RendererPass::ShadowMap);
|
||||||
DrawLaraHair(item, &room, nullptr, renderView, RendererPass::ShadowMap);
|
DrawLaraHair(item, &room, renderView, RendererPass::ShadowMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawGunShells(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawGunShells(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
auto& room = _rooms[LaraItem->RoomNumber];
|
auto& room = _rooms[LaraItem->RoomNumber];
|
||||||
auto* item = &_items[LaraItem->Index];
|
auto* item = &_items[LaraItem->Index];
|
||||||
|
@ -253,6 +253,11 @@ namespace TEN::Renderer
|
||||||
if (gunshell->counter <= 0)
|
if (gunshell->counter <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (_currentMirror != nullptr && gunshell->roomNumber != _currentMirror->RealRoom)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
objectID = gunshell->objectNumber;
|
objectID = gunshell->objectNumber;
|
||||||
|
|
||||||
auto translation = Matrix::CreateTranslation(gunshell->pos.Position.ToVector3());
|
auto translation = Matrix::CreateTranslation(gunshell->pos.Position.ToVector3());
|
||||||
|
@ -268,16 +273,16 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
worldMatrix = Matrix::Lerp(prevWorldMatrix, worldMatrix, GetInterpolationFactor());
|
worldMatrix = Matrix::Lerp(prevWorldMatrix, worldMatrix, GetInterpolationFactor());
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].World = worldMatrix;
|
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].World = worldMatrix;
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Ambient = room.AmbientLight;
|
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Ambient = room.AmbientLight;
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Color = room.AmbientLight;
|
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Color = room.AmbientLight;
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].LightMode = (int)LightMode::Dynamic;
|
_stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].LightMode = (int)LightMode::Dynamic;
|
||||||
BindInstancedStaticLights(item->LightsToDraw, gunShellCount, mirror);
|
BindInstancedStaticLights(item->LightsToDraw, gunShellCount);
|
||||||
|
|
||||||
gunShellCount++;
|
gunShellCount++;
|
||||||
}
|
}
|
||||||
|
@ -467,7 +472,7 @@ namespace TEN::Renderer
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawRats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawRats(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!Objects[ID_RATS_EMITTER].loaded)
|
if (!Objects[ID_RATS_EMITTER].loaded)
|
||||||
{
|
{
|
||||||
|
@ -480,7 +485,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
auto* rat = &Rats[i];
|
auto* rat = &Rats[i];
|
||||||
|
|
||||||
if (mirror != nullptr && rat->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && rat->RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rat->On)
|
if (rat->On)
|
||||||
|
@ -523,7 +528,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
auto* rat = &Rats[i];
|
auto* rat = &Rats[i];
|
||||||
|
|
||||||
if (mirror != nullptr && rat->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && rat->RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rat->On)
|
if (rat->On)
|
||||||
|
@ -565,9 +570,9 @@ namespace TEN::Renderer
|
||||||
RendererMesh* mesh = GetMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8));
|
RendererMesh* mesh = GetMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8));
|
||||||
|
|
||||||
Matrix world = rat->Transform;
|
Matrix world = rat->Transform;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stStatic.World = world;
|
_stStatic.World = world;
|
||||||
_stStatic.Color = Vector4::One;
|
_stStatic.Color = Vector4::One;
|
||||||
|
@ -575,7 +580,7 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
if (rendererPass != RendererPass::GBuffer)
|
if (rendererPass != RendererPass::GBuffer)
|
||||||
{
|
{
|
||||||
BindStaticLights(_rooms[rat->RoomNumber].LightsToDraw, mirror);
|
BindStaticLights(_rooms[rat->RoomNumber].LightsToDraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cbStatic.UpdateData(_stStatic, _context.Get());
|
_cbStatic.UpdateData(_stStatic, _context.Get());
|
||||||
|
@ -696,7 +701,7 @@ namespace TEN::Renderer
|
||||||
_stStatic.AmbientLight = _rooms[fish.RoomNumber].AmbientLight;
|
_stStatic.AmbientLight = _rooms[fish.RoomNumber].AmbientLight;
|
||||||
|
|
||||||
if (rendererPass != RendererPass::GBuffer)
|
if (rendererPass != RendererPass::GBuffer)
|
||||||
BindStaticLights(_rooms[fish.RoomNumber].LightsToDraw, nullptr);
|
BindStaticLights(_rooms[fish.RoomNumber].LightsToDraw);
|
||||||
|
|
||||||
_cbStatic.UpdateData(_stStatic, _context.Get());
|
_cbStatic.UpdateData(_stStatic, _context.Get());
|
||||||
|
|
||||||
|
@ -724,7 +729,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawBats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawBats(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!Objects[ID_BATS_EMITTER].loaded)
|
if (!Objects[ID_BATS_EMITTER].loaded)
|
||||||
return;
|
return;
|
||||||
|
@ -738,7 +743,7 @@ namespace TEN::Renderer
|
||||||
if (!bat.On)
|
if (!bat.On)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mirror != nullptr && bat.RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && bat.RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto& bucket : mesh.Buckets)
|
for (auto& bucket : mesh.Buckets)
|
||||||
|
@ -774,7 +779,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
const auto& bat = Bats[i];
|
const auto& bat = Bats[i];
|
||||||
|
|
||||||
if (mirror != nullptr && bat.RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && bat.RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (bat.On)
|
if (bat.On)
|
||||||
|
@ -784,9 +789,9 @@ namespace TEN::Renderer
|
||||||
auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, GetInterpolationFactor());
|
auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, GetInterpolationFactor());
|
||||||
|
|
||||||
Matrix world = transformMatrix;
|
Matrix world = transformMatrix;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world;
|
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world;
|
||||||
|
@ -795,7 +800,7 @@ namespace TEN::Renderer
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].LightMode = (int)mesh.LightMode;
|
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].LightMode = (int)mesh.LightMode;
|
||||||
|
|
||||||
if (rendererPass != RendererPass::GBuffer)
|
if (rendererPass != RendererPass::GBuffer)
|
||||||
BindInstancedStaticLights(room.LightsToDraw, batCount, mirror);
|
BindInstancedStaticLights(room.LightsToDraw, batCount);
|
||||||
|
|
||||||
batCount++;
|
batCount++;
|
||||||
}
|
}
|
||||||
|
@ -848,7 +853,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawScarabs(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawScarabs(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!Objects[ID_LITTLE_BEETLE].loaded)
|
if (!Objects[ID_LITTLE_BEETLE].loaded)
|
||||||
return;
|
return;
|
||||||
|
@ -896,7 +901,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
|
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
|
||||||
|
|
||||||
if (mirror != nullptr && beetle.RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && beetle.RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (beetle.On)
|
if (beetle.On)
|
||||||
|
@ -906,9 +911,9 @@ namespace TEN::Renderer
|
||||||
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor());
|
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor());
|
||||||
|
|
||||||
Matrix world = transformMatrix;
|
Matrix world = transformMatrix;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world;
|
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world;
|
||||||
|
@ -922,7 +927,7 @@ namespace TEN::Renderer
|
||||||
for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
|
for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
|
||||||
lights.push_back(room.LightsToDraw[i]);
|
lights.push_back(room.LightsToDraw[i]);
|
||||||
|
|
||||||
BindInstancedStaticLights(lights, beetleCount, mirror);
|
BindInstancedStaticLights(lights, beetleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
beetleCount++;
|
beetleCount++;
|
||||||
|
@ -976,7 +981,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawLocusts(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawLocusts(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!Objects[ID_LOCUSTS].loaded)
|
if (!Objects[ID_LOCUSTS].loaded)
|
||||||
return;
|
return;
|
||||||
|
@ -991,7 +996,7 @@ namespace TEN::Renderer
|
||||||
if (!locust.on)
|
if (!locust.on)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mirror != nullptr && locust.roomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && locust.roomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
|
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
|
||||||
|
@ -1030,7 +1035,7 @@ namespace TEN::Renderer
|
||||||
if (!locust.on)
|
if (!locust.on)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mirror != nullptr && locust.roomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && locust.roomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
activeLocustsExist = true;
|
activeLocustsExist = true;
|
||||||
|
@ -1069,9 +1074,9 @@ namespace TEN::Renderer
|
||||||
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
|
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
|
||||||
|
|
||||||
Matrix world = Matrix::Lerp(locust.PrevTransform, locust.Transform, GetInterpolationFactor());
|
Matrix world = Matrix::Lerp(locust.PrevTransform, locust.Transform, GetInterpolationFactor());
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stStatic.World = world;
|
_stStatic.World = world;
|
||||||
|
|
||||||
|
@ -1885,15 +1890,15 @@ namespace TEN::Renderer
|
||||||
_context->OMSetRenderTargets(2, &pRenderViewPtrs[0], _renderTarget.DepthStencilView.Get());
|
_context->OMSetRenderTargets(2, &pRenderViewPtrs[0], _renderTarget.DepthStencilView.Get());
|
||||||
|
|
||||||
DrawRooms(view, RendererPass::GBuffer);
|
DrawRooms(view, RendererPass::GBuffer);
|
||||||
DrawItems(nullptr, view, RendererPass::GBuffer);
|
DrawItems(view, RendererPass::GBuffer);
|
||||||
DrawStatics(nullptr, view, RendererPass::GBuffer);
|
DrawStatics(view, RendererPass::GBuffer);
|
||||||
DrawSpiders(view, RendererPass::GBuffer);
|
DrawSpiders(view, RendererPass::GBuffer);
|
||||||
DrawScarabs(nullptr, view, RendererPass::GBuffer);
|
DrawScarabs(view, RendererPass::GBuffer);
|
||||||
DrawGunShells(nullptr, view, RendererPass::GBuffer);
|
DrawGunShells(view, RendererPass::GBuffer);
|
||||||
DrawBats(nullptr, view, RendererPass::GBuffer);
|
DrawBats(view, RendererPass::GBuffer);
|
||||||
DrawEffects(nullptr, view, RendererPass::GBuffer);
|
DrawEffects(view, RendererPass::GBuffer);
|
||||||
DrawRats(nullptr, view, RendererPass::GBuffer);
|
DrawRats(view, RendererPass::GBuffer);
|
||||||
DrawLocusts(nullptr, view, RendererPass::GBuffer);
|
DrawLocusts(view, RendererPass::GBuffer);
|
||||||
|
|
||||||
// Calculate ambient occlusion.
|
// Calculate ambient occlusion.
|
||||||
if (g_Configuration.EnableAmbientOcclusion)
|
if (g_Configuration.EnableAmbientOcclusion)
|
||||||
|
@ -1918,17 +1923,17 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
// Draw opaque, alpha test, and fast alpha blend faces.
|
// Draw opaque, alpha test, and fast alpha blend faces.
|
||||||
DrawRooms(view, RendererPass::Opaque);
|
DrawRooms(view, RendererPass::Opaque);
|
||||||
DrawItems(nullptr, view, RendererPass::Opaque);
|
DrawItems(view, RendererPass::Opaque);
|
||||||
DrawStatics(nullptr, view, RendererPass::Opaque);
|
DrawStatics(view, RendererPass::Opaque);
|
||||||
DrawSpiders(view, RendererPass::Opaque);
|
DrawSpiders(view, RendererPass::Opaque);
|
||||||
DrawScarabs(nullptr, view, RendererPass::Opaque);
|
DrawScarabs(view, RendererPass::Opaque);
|
||||||
DrawGunShells(nullptr, view, RendererPass::Opaque);
|
DrawGunShells(view, RendererPass::Opaque);
|
||||||
DrawBats(nullptr, view, RendererPass::Opaque);
|
DrawBats(view, RendererPass::Opaque);
|
||||||
DrawEffects(nullptr, view, RendererPass::Opaque);
|
DrawEffects(view, RendererPass::Opaque);
|
||||||
DrawRats(nullptr, view, RendererPass::Opaque);
|
DrawRats(view, RendererPass::Opaque);
|
||||||
DrawLocusts(nullptr, view, RendererPass::Opaque);
|
DrawLocusts(view, RendererPass::Opaque);
|
||||||
DrawDebris(nullptr, view, RendererPass::Opaque);
|
DrawDebris(view, RendererPass::Opaque);
|
||||||
DrawSprites(nullptr, view, RendererPass::Opaque);
|
DrawSprites(view, RendererPass::Opaque);
|
||||||
DrawFishSwarm(view, RendererPass::Opaque);
|
DrawFishSwarm(view, RendererPass::Opaque);
|
||||||
|
|
||||||
// Draw mirrored opaque geometry only if Lara is inside a mirror room
|
// Draw mirrored opaque geometry only if Lara is inside a mirror room
|
||||||
|
@ -1938,16 +1943,20 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
for (auto& mirror : view.Mirrors)
|
for (auto& mirror : view.Mirrors)
|
||||||
{
|
{
|
||||||
DrawItems(&mirror, view, RendererPass::Opaque);
|
_currentMirror = &mirror;
|
||||||
DrawStatics(&mirror, view, RendererPass::Opaque);
|
|
||||||
DrawScarabs(&mirror, view, RendererPass::Opaque);
|
DrawItems(view, RendererPass::Opaque);
|
||||||
DrawGunShells(&mirror, view, RendererPass::Opaque);
|
DrawStatics(view, RendererPass::Opaque);
|
||||||
DrawBats(&mirror, view, RendererPass::Opaque);
|
DrawScarabs(view, RendererPass::Opaque);
|
||||||
DrawEffects(&mirror, view, RendererPass::Opaque);
|
DrawGunShells(view, RendererPass::Opaque);
|
||||||
DrawRats(&mirror, view, RendererPass::Opaque);
|
DrawBats(view, RendererPass::Opaque);
|
||||||
DrawLocusts(&mirror, view, RendererPass::Opaque);
|
DrawEffects(view, RendererPass::Opaque);
|
||||||
DrawDebris(&mirror, view, RendererPass::Opaque);
|
DrawRats(view, RendererPass::Opaque);
|
||||||
DrawSprites(&mirror, view, RendererPass::Opaque);
|
DrawLocusts(view, RendererPass::Opaque);
|
||||||
|
DrawDebris(view, RendererPass::Opaque);
|
||||||
|
DrawSprites(view, RendererPass::Opaque);
|
||||||
|
|
||||||
|
_currentMirror = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCullMode(CullMode::CounterClockwise);
|
SetCullMode(CullMode::CounterClockwise);
|
||||||
|
@ -1955,16 +1964,16 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
// Draw additive faces.
|
// Draw additive faces.
|
||||||
DrawRooms(view, RendererPass::Additive);
|
DrawRooms(view, RendererPass::Additive);
|
||||||
DrawItems(nullptr, view, RendererPass::Additive);
|
DrawItems(view, RendererPass::Additive);
|
||||||
DrawStatics(nullptr, view, RendererPass::Additive);
|
DrawStatics(view, RendererPass::Additive);
|
||||||
DrawSpiders(view, RendererPass::Additive);
|
DrawSpiders(view, RendererPass::Additive);
|
||||||
DrawScarabs(nullptr, view, RendererPass::Additive);
|
DrawScarabs(view, RendererPass::Additive);
|
||||||
DrawBats(nullptr, view, RendererPass::Additive);
|
DrawBats(view, RendererPass::Additive);
|
||||||
DrawEffects(nullptr, view, RendererPass::Additive);
|
DrawEffects(view, RendererPass::Additive);
|
||||||
DrawRats(nullptr, view, RendererPass::Additive);
|
DrawRats(view, RendererPass::Additive);
|
||||||
DrawLocusts(nullptr, view, RendererPass::Additive);
|
DrawLocusts(view, RendererPass::Additive);
|
||||||
DrawDebris(nullptr, view, RendererPass::Additive);
|
DrawDebris(view, RendererPass::Additive);
|
||||||
DrawSprites(nullptr, view, RendererPass::Additive);
|
DrawSprites(view, RendererPass::Additive);
|
||||||
DrawFishSwarm(view, RendererPass::Additive);
|
DrawFishSwarm(view, RendererPass::Additive);
|
||||||
|
|
||||||
// Draw mirrored additive geometry only if Lara is inside a mirror room
|
// Draw mirrored additive geometry only if Lara is inside a mirror room
|
||||||
|
@ -1974,15 +1983,19 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
for (auto& mirror : view.Mirrors)
|
for (auto& mirror : view.Mirrors)
|
||||||
{
|
{
|
||||||
DrawItems(&mirror, view, RendererPass::Additive);
|
_currentMirror = &mirror;
|
||||||
DrawStatics(&mirror, view, RendererPass::Additive);
|
|
||||||
DrawScarabs(&mirror, view, RendererPass::Additive);
|
DrawItems(view, RendererPass::Additive);
|
||||||
DrawBats(&mirror, view, RendererPass::Additive);
|
DrawStatics(view, RendererPass::Additive);
|
||||||
DrawEffects(&mirror, view, RendererPass::Additive);
|
DrawScarabs(view, RendererPass::Additive);
|
||||||
DrawRats(&mirror, view, RendererPass::Additive);
|
DrawBats(view, RendererPass::Additive);
|
||||||
DrawLocusts(&mirror, view, RendererPass::Additive);
|
DrawEffects(view, RendererPass::Additive);
|
||||||
DrawDebris(&mirror, view, RendererPass::Additive);
|
DrawRats(view, RendererPass::Additive);
|
||||||
DrawSprites(&mirror, view, RendererPass::Additive);
|
DrawLocusts(view, RendererPass::Additive);
|
||||||
|
DrawDebris(view, RendererPass::Additive);
|
||||||
|
DrawSprites(view, RendererPass::Additive);
|
||||||
|
|
||||||
|
_currentMirror = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCullMode(CullMode::CounterClockwise);
|
SetCullMode(CullMode::CounterClockwise);
|
||||||
|
@ -1991,16 +2004,16 @@ namespace TEN::Renderer
|
||||||
// Collect all non-commutative transparent faces.
|
// Collect all non-commutative transparent faces.
|
||||||
// NOTE: Sorted sprites already collected at beginning of frame.
|
// NOTE: Sorted sprites already collected at beginning of frame.
|
||||||
DrawRooms(view, RendererPass::CollectTransparentFaces);
|
DrawRooms(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawItems(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawItems(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawStatics(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawStatics(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawBats(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawBats(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawEffects(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawEffects(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawRats(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawRats(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawLocusts(nullptr, view, RendererPass::CollectTransparentFaces);
|
DrawLocusts(view, RendererPass::CollectTransparentFaces);
|
||||||
DrawFishSwarm(view, RendererPass::CollectTransparentFaces);
|
DrawFishSwarm(view, RendererPass::CollectTransparentFaces);
|
||||||
|
|
||||||
// Draw sorted faces.
|
// Draw sorted faces.
|
||||||
DrawSortedFaces(nullptr, view);
|
DrawSortedFaces(view);
|
||||||
|
|
||||||
// Draw mirrored sorted faces only if Lara is inside a mirror room
|
// Draw mirrored sorted faces only if Lara is inside a mirror room
|
||||||
if (view.Mirrors.size() > 0)
|
if (view.Mirrors.size() > 0)
|
||||||
|
@ -2009,15 +2022,19 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
for (auto& mirror : view.Mirrors)
|
for (auto& mirror : view.Mirrors)
|
||||||
{
|
{
|
||||||
DrawSortedFaces(&mirror, view);
|
_currentMirror = &mirror;
|
||||||
|
|
||||||
|
DrawSortedFaces(view);
|
||||||
|
|
||||||
|
_currentMirror = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCullMode(CullMode::CounterClockwise);
|
SetCullMode(CullMode::CounterClockwise);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: Gunflashes drawn after everything because they are very near the camera.
|
// HACK: Gunflashes drawn after everything because they are very near the camera.
|
||||||
DrawGunFlashes(nullptr, view);
|
DrawGunFlashes(view);
|
||||||
DrawBaddyGunflashes(nullptr, view);
|
DrawBaddyGunflashes( view);
|
||||||
|
|
||||||
// Draw mirrored gunflashes only if Lara is inside a mirror room
|
// Draw mirrored gunflashes only if Lara is inside a mirror room
|
||||||
if (view.Mirrors.size() > 0)
|
if (view.Mirrors.size() > 0)
|
||||||
|
@ -2026,8 +2043,12 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
for (auto& mirror : view.Mirrors)
|
for (auto& mirror : view.Mirrors)
|
||||||
{
|
{
|
||||||
DrawGunFlashes(&mirror, view);
|
_currentMirror = &mirror;
|
||||||
DrawBaddyGunflashes(&mirror, view);
|
|
||||||
|
DrawGunFlashes(view);
|
||||||
|
DrawBaddyGunflashes(view);
|
||||||
|
|
||||||
|
_currentMirror = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCullMode(CullMode::CounterClockwise);
|
SetCullMode(CullMode::CounterClockwise);
|
||||||
|
@ -2355,7 +2376,7 @@ namespace TEN::Renderer
|
||||||
RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode);
|
RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawItems(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawItems(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
unsigned int stride = sizeof(Vertex);
|
unsigned int stride = sizeof(Vertex);
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
|
@ -2384,7 +2405,7 @@ namespace TEN::Renderer
|
||||||
switch (itemToDraw->ObjectID)
|
switch (itemToDraw->ObjectID)
|
||||||
{
|
{
|
||||||
case ID_LARA:
|
case ID_LARA:
|
||||||
DrawLara(mirror, view, rendererPass);
|
DrawLara(view, rendererPass);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_WATERFALL1:
|
case ID_WATERFALL1:
|
||||||
|
@ -2395,11 +2416,11 @@ namespace TEN::Renderer
|
||||||
case ID_WATERFALL6:
|
case ID_WATERFALL6:
|
||||||
case ID_WATERFALLSS1:
|
case ID_WATERFALLSS1:
|
||||||
case ID_WATERFALLSS2:
|
case ID_WATERFALLSS2:
|
||||||
DrawWaterfalls(itemToDraw, mirror, view, 10, rendererPass);
|
DrawWaterfalls(itemToDraw, view, 10, rendererPass);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DrawAnimatingItem(itemToDraw, mirror, view, rendererPass);
|
DrawAnimatingItem(itemToDraw, view, rendererPass);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2418,12 +2439,10 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawWaterfalls(RendererItem* item, RendererMirror* mirror, RenderView& view, int fps, RendererPass rendererPass)
|
void Renderer::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && item->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && item->RoomNumber != _currentMirror->RealRoom)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Extremely hacky function to get first rendered face of a waterfall object mesh, calculate
|
// Extremely hacky function to get first rendered face of a waterfall object mesh, calculate
|
||||||
// its texture height and scroll all the textures according to that height.
|
// its texture height and scroll all the textures according to that height.
|
||||||
|
@ -2459,16 +2478,16 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
_cbAnimated.UpdateData(_stAnimated, _context.Get());
|
_cbAnimated.UpdateData(_stAnimated, _context.Get());
|
||||||
|
|
||||||
DrawAnimatingItem(item, mirror, view, rendererPass);
|
DrawAnimatingItem(item, view, rendererPass);
|
||||||
|
|
||||||
// Reset animated buffer after rendering just in case
|
// Reset animated buffer after rendering just in case
|
||||||
_stAnimated.Fps = _stAnimated.NumFrames = _stAnimated.Type = 0;
|
_stAnimated.Fps = _stAnimated.NumFrames = _stAnimated.Type = 0;
|
||||||
_cbAnimated.UpdateData(_stAnimated, _context.Get());
|
_cbAnimated.UpdateData(_stAnimated, _context.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawAnimatingItem(RendererItem* item, RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && item->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && item->RoomNumber != _currentMirror->RealRoom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
|
||||||
|
@ -2477,9 +2496,9 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
// Bind item main properties
|
// Bind item main properties
|
||||||
_stItem.World = item->InterpolatedWorld;
|
_stItem.World = item->InterpolatedWorld;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
_stItem.World = _stItem.World * mirror->ReflectionMatrix;
|
_stItem.World = _stItem.World * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stItem.Color = item->Color;
|
_stItem.Color = item->Color;
|
||||||
_stItem.AmbientLight = item->AmbientLight;
|
_stItem.AmbientLight = item->AmbientLight;
|
||||||
|
@ -2488,7 +2507,7 @@ namespace TEN::Renderer
|
||||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||||
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
|
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
|
||||||
|
|
||||||
BindMoveableLights(item->LightsToDraw, item->RoomNumber, item->PrevRoomNumber, item->LightFade, mirror);
|
BindMoveableLights(item->LightsToDraw, item->RoomNumber, item->PrevRoomNumber, item->LightFade);
|
||||||
_cbItem.UpdateData(_stItem, _context.Get());
|
_cbItem.UpdateData(_stItem, _context.Get());
|
||||||
|
|
||||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||||
|
@ -2500,7 +2519,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawStatics(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawStatics(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (_staticTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0)
|
if (_staticTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -2634,15 +2653,15 @@ namespace TEN::Renderer
|
||||||
RendererStatic* current = statics[s];
|
RendererStatic* current = statics[s];
|
||||||
RendererRoom* room = &_rooms[current->RoomNumber];
|
RendererRoom* room = &_rooms[current->RoomNumber];
|
||||||
|
|
||||||
if (mirror != nullptr && current->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && current->RoomNumber != _currentMirror->RealRoom)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix world = current->World;
|
Matrix world = current->World;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stInstancedStaticMeshBuffer.StaticMeshes[k].World = world;
|
_stInstancedStaticMeshBuffer.StaticMeshes[k].World = world;
|
||||||
|
|
||||||
|
@ -2652,7 +2671,7 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
if (rendererPass != RendererPass::GBuffer)
|
if (rendererPass != RendererPass::GBuffer)
|
||||||
{
|
{
|
||||||
BindInstancedStaticLights(current->LightsToDraw, k, mirror);
|
BindInstancedStaticLights(current->LightsToDraw, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
k++;
|
k++;
|
||||||
|
@ -2698,9 +2717,6 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mirror != nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Collect sorted blend modes faces ordered by room, if transparent pass
|
// Collect sorted blend modes faces ordered by room, if transparent pass
|
||||||
|
|
||||||
for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++)
|
for (auto it = view.SortedStaticsToDraw.begin(); it != view.SortedStaticsToDraw.end(); it++)
|
||||||
|
@ -2716,11 +2732,6 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
for (int i = 0; i < statics.size(); i++)
|
for (int i = 0; i < statics.size(); i++)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && statics[i]->RoomNumber != mirror->RealRoom)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < refMesh->Buckets.size(); j++)
|
for (int j = 0; j < refMesh->Buckets.size(); j++)
|
||||||
{
|
{
|
||||||
auto& bucket = refMesh->Buckets[j];
|
auto& bucket = refMesh->Buckets[j];
|
||||||
|
@ -2829,7 +2840,7 @@ namespace TEN::Renderer
|
||||||
// Set shadow map data and bind shadow map texture.
|
// Set shadow map data and bind shadow map texture.
|
||||||
if (_shadowLight != nullptr)
|
if (_shadowLight != nullptr)
|
||||||
{
|
{
|
||||||
memcpy(&_stShadowMap.Light, _shadowLight, sizeof(ShaderLight));
|
BindLight(*_shadowLight, &_stShadowMap.Light, 0);
|
||||||
_stShadowMap.ShadowMapSize = g_Configuration.ShadowMapSize;
|
_stShadowMap.ShadowMapSize = g_Configuration.ShadowMapSize;
|
||||||
_stShadowMap.CastShadows = true;
|
_stShadowMap.CastShadows = true;
|
||||||
|
|
||||||
|
@ -2857,7 +2868,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
_stRoom.Caustics = int(g_Configuration.EnableCaustics && (nativeRoom.flags & ENV_FLAG_WATER));
|
_stRoom.Caustics = int(g_Configuration.EnableCaustics && (nativeRoom.flags & ENV_FLAG_WATER));
|
||||||
_stRoom.AmbientColor = room.AmbientLight;
|
_stRoom.AmbientColor = room.AmbientLight;
|
||||||
BindRoomLights(view.LightsToDraw, nullptr);
|
BindRoomLights(view.LightsToDraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
_stRoom.Water = (nativeRoom.flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
|
_stRoom.Water = (nativeRoom.flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
|
||||||
|
@ -3407,9 +3418,9 @@ namespace TEN::Renderer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawSortedFaces(RendererMirror* mirror, RenderView& view)
|
void Renderer::DrawSortedFaces(RenderView& view)
|
||||||
{
|
{
|
||||||
if (mirror == nullptr)
|
if (_currentMirror == nullptr)
|
||||||
{
|
{
|
||||||
std::sort(
|
std::sort(
|
||||||
view.TransparentObjectsToDraw.begin(),
|
view.TransparentObjectsToDraw.begin(),
|
||||||
|
@ -3429,7 +3440,7 @@ namespace TEN::Renderer
|
||||||
_sortedPolygonsVertices.clear();
|
_sortedPolygonsVertices.clear();
|
||||||
_sortedPolygonsIndices.clear();
|
_sortedPolygonsIndices.clear();
|
||||||
|
|
||||||
if (mirror != nullptr && object->ObjectType == RendererObjectType::Room)
|
if (_currentMirror != nullptr && object->ObjectType == RendererObjectType::Room)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3584,7 +3595,7 @@ namespace TEN::Renderer
|
||||||
uv2 = spr->Sprite->UV[2];
|
uv2 = spr->Sprite->UV[2];
|
||||||
uv3 = spr->Sprite->UV[3];
|
uv3 = spr->Sprite->UV[3];
|
||||||
|
|
||||||
Matrix world = GetWorldMatrixForSprite(currentObject->Sprite, mirror, view);
|
Matrix world = GetWorldMatrixForSprite(currentObject->Sprite, _currentMirror, view);
|
||||||
|
|
||||||
Vertex v0;
|
Vertex v0;
|
||||||
v0.Position = Vector3::Transform(p0t, world);
|
v0.Position = Vector3::Transform(p0t, world);
|
||||||
|
@ -3645,7 +3656,7 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
_stRoom.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
|
_stRoom.Caustics = (int)(g_Configuration.EnableCaustics && (nativeRoom->flags & ENV_FLAG_WATER));
|
||||||
_stRoom.AmbientColor = objectInfo->Room->AmbientLight;
|
_stRoom.AmbientColor = objectInfo->Room->AmbientLight;
|
||||||
BindRoomLights(view.LightsToDraw, nullptr);
|
BindRoomLights(view.LightsToDraw);
|
||||||
_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
|
_stRoom.Water = (nativeRoom->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
|
||||||
_cbRoom.UpdateData(_stRoom, _context.Get());
|
_cbRoom.UpdateData(_stRoom, _context.Get());
|
||||||
|
|
||||||
|
@ -3738,7 +3749,7 @@ namespace TEN::Renderer
|
||||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||||
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
|
_stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode;
|
||||||
|
|
||||||
BindMoveableLights(objectInfo->Item->LightsToDraw, objectInfo->Item->RoomNumber, objectInfo->Item->PrevRoomNumber, objectInfo->Item->LightFade, nullptr);
|
BindMoveableLights(objectInfo->Item->LightsToDraw, objectInfo->Item->RoomNumber, objectInfo->Item->PrevRoomNumber, objectInfo->Item->LightFade);
|
||||||
_cbItem.UpdateData(_stItem, _context.Get());
|
_cbItem.UpdateData(_stItem, _context.Get());
|
||||||
|
|
||||||
BindTexture(
|
BindTexture(
|
||||||
|
@ -3774,7 +3785,7 @@ namespace TEN::Renderer
|
||||||
_stStatic.Color = objectInfo->Static->Color;
|
_stStatic.Color = objectInfo->Static->Color;
|
||||||
_stStatic.AmbientLight = objectInfo->Room->AmbientLight;
|
_stStatic.AmbientLight = objectInfo->Room->AmbientLight;
|
||||||
_stStatic.LightMode = (int)GetStaticRendererObject(objectInfo->Static->ObjectNumber).ObjectMeshes[0]->LightMode;
|
_stStatic.LightMode = (int)GetStaticRendererObject(objectInfo->Static->ObjectNumber).ObjectMeshes[0]->LightMode;
|
||||||
BindStaticLights(objectInfo->Static->LightsToDraw, nullptr);
|
BindStaticLights(objectInfo->Static->LightsToDraw);
|
||||||
_cbStatic.UpdateData(_stStatic, _context.Get());
|
_cbStatic.UpdateData(_stStatic, _context.Get());
|
||||||
|
|
||||||
SetDepthState(DepthState::Read);
|
SetDepthState(DepthState::Read);
|
||||||
|
@ -3813,7 +3824,7 @@ namespace TEN::Renderer
|
||||||
_stStatic.Color = Vector4::One;
|
_stStatic.Color = Vector4::One;
|
||||||
_stStatic.AmbientLight = objectInfo->Room->AmbientLight;
|
_stStatic.AmbientLight = objectInfo->Room->AmbientLight;
|
||||||
_stStatic.LightMode = (int)objectInfo->Mesh->LightMode;
|
_stStatic.LightMode = (int)objectInfo->Mesh->LightMode;
|
||||||
BindStaticLights(objectInfo->Room->LightsToDraw, nullptr);
|
BindStaticLights(objectInfo->Room->LightsToDraw);
|
||||||
_cbStatic.UpdateData(_stStatic, _context.Get());
|
_cbStatic.UpdateData(_stStatic, _context.Get());
|
||||||
|
|
||||||
SetDepthState(DepthState::Read);
|
SetDepthState(DepthState::Read);
|
||||||
|
|
|
@ -1009,7 +1009,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::DrawGunFlashes(RendererMirror* mirror, RenderView& view)
|
bool Renderer::DrawGunFlashes(RenderView& view)
|
||||||
{
|
{
|
||||||
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
||||||
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
||||||
|
@ -1033,7 +1033,7 @@ namespace TEN::Renderer
|
||||||
_stStatic.Color = Vector4::One;
|
_stStatic.Color = Vector4::One;
|
||||||
_stStatic.AmbientLight = room.AmbientLight;
|
_stStatic.AmbientLight = room.AmbientLight;
|
||||||
_stStatic.LightMode = (int)LightMode::Static;
|
_stStatic.LightMode = (int)LightMode::Static;
|
||||||
BindStaticLights(itemPtr->LightsToDraw, mirror);
|
BindStaticLights(itemPtr->LightsToDraw);
|
||||||
|
|
||||||
short length = 0;
|
short length = 0;
|
||||||
short zOffset = 0;
|
short zOffset = 0;
|
||||||
|
@ -1106,9 +1106,9 @@ namespace TEN::Renderer
|
||||||
worldMatrix = tMatrix * worldMatrix;
|
worldMatrix = tMatrix * worldMatrix;
|
||||||
worldMatrix = rotMatrix * worldMatrix;
|
worldMatrix = rotMatrix * worldMatrix;
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stStatic.World = worldMatrix;
|
_stStatic.World = worldMatrix;
|
||||||
|
@ -1125,9 +1125,9 @@ namespace TEN::Renderer
|
||||||
worldMatrix = tMatrix * worldMatrix;
|
worldMatrix = tMatrix * worldMatrix;
|
||||||
worldMatrix = rotMatrix * worldMatrix;
|
worldMatrix = rotMatrix * worldMatrix;
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stStatic.World = worldMatrix;
|
_stStatic.World = worldMatrix;
|
||||||
|
@ -1144,7 +1144,7 @@ namespace TEN::Renderer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawBaddyGunflashes(RendererMirror* mirror, RenderView& view)
|
void Renderer::DrawBaddyGunflashes(RenderView& view)
|
||||||
{
|
{
|
||||||
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
||||||
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
||||||
|
@ -1161,7 +1161,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
auto& nativeItem = g_Level.Items[rItemPtr->ItemNumber];
|
auto& nativeItem = g_Level.Items[rItemPtr->ItemNumber];
|
||||||
|
|
||||||
if (mirror != nullptr && nativeItem.RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && nativeItem.RoomNumber != _currentMirror->RealRoom)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1176,7 @@ namespace TEN::Renderer
|
||||||
_stStatic.AmbientLight = rRoom.AmbientLight;
|
_stStatic.AmbientLight = rRoom.AmbientLight;
|
||||||
_stStatic.LightMode = (int)LightMode::Static;
|
_stStatic.LightMode = (int)LightMode::Static;
|
||||||
|
|
||||||
BindStaticLights(rItemPtr->LightsToDraw, mirror); // FIXME: Is it really needed for gunflashes? -- Lwmte, 15.07.22
|
BindStaticLights(rItemPtr->LightsToDraw); // FIXME: Is it really needed for gunflashes? -- Lwmte, 15.07.22
|
||||||
SetBlendMode(BlendMode::Additive);
|
SetBlendMode(BlendMode::Additive);
|
||||||
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
|
SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD);
|
||||||
|
|
||||||
|
@ -1211,9 +1211,9 @@ namespace TEN::Renderer
|
||||||
if (creature.MuzzleFlash[0].ApplyZRotation)
|
if (creature.MuzzleFlash[0].ApplyZRotation)
|
||||||
worldMatrix = rotMatrixZ * worldMatrix;
|
worldMatrix = rotMatrixZ * worldMatrix;
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stStatic.World = worldMatrix;
|
_stStatic.World = worldMatrix;
|
||||||
|
@ -1256,9 +1256,9 @@ namespace TEN::Renderer
|
||||||
if (creature.MuzzleFlash[1].ApplyZRotation)
|
if (creature.MuzzleFlash[1].ApplyZRotation)
|
||||||
worldMatrix = rotMatrixZ * worldMatrix;
|
worldMatrix = rotMatrixZ * worldMatrix;
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stStatic.World = worldMatrix;
|
_stStatic.World = worldMatrix;
|
||||||
|
@ -1341,21 +1341,21 @@ namespace TEN::Renderer
|
||||||
return spriteMatrix;
|
return spriteMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawEffect(RendererMirror* mirror, RenderView& view, RendererEffect* effect, RendererPass rendererPass)
|
void Renderer::DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
const auto& room = _rooms[effect->RoomNumber];
|
const auto& room = _rooms[effect->RoomNumber];
|
||||||
|
|
||||||
Matrix world = effect->InterpolatedWorld;
|
Matrix world = effect->InterpolatedWorld;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stStatic.World = world;
|
_stStatic.World = world;
|
||||||
|
|
||||||
_stStatic.Color = effect->Color;
|
_stStatic.Color = effect->Color;
|
||||||
_stStatic.AmbientLight = effect->AmbientLight;
|
_stStatic.AmbientLight = effect->AmbientLight;
|
||||||
_stStatic.LightMode = (int)LightMode::Dynamic;
|
_stStatic.LightMode = (int)LightMode::Dynamic;
|
||||||
BindStaticLights(effect->LightsToDraw, mirror);
|
BindStaticLights(effect->LightsToDraw);
|
||||||
_cbStatic.UpdateData(_stStatic, _context.Get());
|
_cbStatic.UpdateData(_stStatic, _context.Get());
|
||||||
|
|
||||||
auto& mesh = *effect->Mesh;
|
auto& mesh = *effect->Mesh;
|
||||||
|
@ -1381,7 +1381,7 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawEffects(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawEffects(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
_context->VSSetShader(_vsStatics.Get(), nullptr, 0);
|
||||||
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
_context->PSSetShader(_psStatics.Get(), nullptr, 0);
|
||||||
|
@ -1396,26 +1396,26 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
for (auto* effectPtr : roomPtr->EffectsToDraw)
|
for (auto* effectPtr : roomPtr->EffectsToDraw)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && effectPtr->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && effectPtr->RoomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto& room = _rooms[effectPtr->RoomNumber];
|
const auto& room = _rooms[effectPtr->RoomNumber];
|
||||||
const auto& object = Objects[effectPtr->ObjectID];
|
const auto& object = Objects[effectPtr->ObjectID];
|
||||||
|
|
||||||
if (object.drawRoutine && object.loaded)
|
if (object.drawRoutine && object.loaded)
|
||||||
DrawEffect(mirror, view, effectPtr, rendererPass);
|
DrawEffect(view, effectPtr, rendererPass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawDebris(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawDebris(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
bool activeDebrisExist = false;
|
bool activeDebrisExist = false;
|
||||||
for (auto& deb : DebrisFragments)
|
for (auto& deb : DebrisFragments)
|
||||||
{
|
{
|
||||||
if (deb.active)
|
if (deb.active)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && deb.roomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && deb.roomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
activeDebrisExist = true;
|
activeDebrisExist = true;
|
||||||
|
@ -1434,7 +1434,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
if (deb.active)
|
if (deb.active)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && deb.roomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && deb.roomNumber != _currentMirror->RealRoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!SetupBlendModeAndAlphaTest(deb.mesh.blendMode, rendererPass, 0))
|
if (!SetupBlendModeAndAlphaTest(deb.mesh.blendMode, rendererPass, 0))
|
||||||
|
@ -1450,9 +1450,9 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix world = Matrix::Lerp(deb.PrevTransform, deb.Transform, GetInterpolationFactor());
|
Matrix world = Matrix::Lerp(deb.PrevTransform, deb.Transform, GetInterpolationFactor());
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
world = world * mirror->ReflectionMatrix;
|
world = world * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
_stStatic.World = world;
|
_stStatic.World = world;
|
||||||
|
|
||||||
|
@ -1495,7 +1495,7 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
SetBlendMode(BlendMode::Opaque, true);
|
SetBlendMode(BlendMode::Opaque, true);
|
||||||
SetDepthState(DepthState::Write, true);
|
SetDepthState(DepthState::Write, true);
|
||||||
SetCullMode(mirror != nullptr ? CullMode::Clockwise : CullMode::CounterClockwise, true);
|
SetCullMode(_currentMirror != nullptr ? CullMode::Clockwise : CullMode::CounterClockwise, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -692,7 +692,7 @@ namespace TEN::Renderer
|
||||||
std::vector<RendererLight*> lightsToDraw;
|
std::vector<RendererLight*> lightsToDraw;
|
||||||
CollectLights(Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z), CAMERA_LIGHT_COLLECTION_RADIUS, Camera.pos.RoomNumber, NO_VALUE, true, false, nullptr, &lightsToDraw);
|
CollectLights(Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z), CAMERA_LIGHT_COLLECTION_RADIUS, Camera.pos.RoomNumber, NO_VALUE, true, false, nullptr, &lightsToDraw);
|
||||||
|
|
||||||
if (!lightsToDraw.empty() && lightsToDraw.front()->CastShadows)
|
if (g_Configuration.ShadowType != ShadowMode::None && !lightsToDraw.empty() && lightsToDraw.front()->CastShadows)
|
||||||
{
|
{
|
||||||
_shadowLight = lightsToDraw.front();
|
_shadowLight = lightsToDraw.front();
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,9 +278,9 @@ void Renderer::UpdateLaraAnimations(bool force)
|
||||||
rItem.DoneAnimations = true;
|
rItem.DoneAnimations = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TEN::Renderer::Renderer::DrawLara(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (mirror != nullptr && LaraItem->RoomNumber != mirror->RealRoom)
|
if (_currentMirror != nullptr && LaraItem->RoomNumber != _currentMirror->RealRoom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't draw player if using optics.
|
// Don't draw player if using optics.
|
||||||
|
@ -309,9 +309,9 @@ void TEN::Renderer::Renderer::DrawLara(RendererMirror* mirror, RenderView& view,
|
||||||
RendererRoom* room = &_rooms[LaraItem->RoomNumber];
|
RendererRoom* room = &_rooms[LaraItem->RoomNumber];
|
||||||
|
|
||||||
_stItem.World = item->InterpolatedWorld;
|
_stItem.World = item->InterpolatedWorld;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
_stItem.World = _stItem.World * mirror->ReflectionMatrix;
|
_stItem.World = _stItem.World * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stItem.Color = item->Color;
|
_stItem.Color = item->Color;
|
||||||
|
@ -321,7 +321,7 @@ void TEN::Renderer::Renderer::DrawLara(RendererMirror* mirror, RenderView& view,
|
||||||
{
|
{
|
||||||
_stItem.BoneLightModes[k] = (int)GetMesh(nativeItem->Model.MeshIndex[k])->LightMode;
|
_stItem.BoneLightModes[k] = (int)GetMesh(nativeItem->Model.MeshIndex[k])->LightMode;
|
||||||
}
|
}
|
||||||
BindMoveableLights(item->LightsToDraw, item->RoomNumber, item->PrevRoomNumber, item->LightFade, mirror);
|
BindMoveableLights(item->LightsToDraw, item->RoomNumber, item->PrevRoomNumber, item->LightFade);
|
||||||
_cbItem.UpdateData(_stItem, _context.Get());
|
_cbItem.UpdateData(_stItem, _context.Get());
|
||||||
|
|
||||||
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
||||||
|
@ -332,12 +332,12 @@ void TEN::Renderer::Renderer::DrawLara(RendererMirror* mirror, RenderView& view,
|
||||||
DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, view, rendererPass);
|
DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, view, rendererPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawLaraHolsters(item, room, mirror, view, rendererPass);
|
DrawLaraHolsters(item, room, view, rendererPass);
|
||||||
DrawLaraJoints(item, room, mirror, view, rendererPass);
|
DrawLaraJoints(item, room, view, rendererPass);
|
||||||
DrawLaraHair(item, room, mirror, view, rendererPass);
|
DrawLaraHair(item, room, view, rendererPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
bool forceValue = g_GameFlow->CurrentFreezeMode == FreezeMode::Player;
|
bool forceValue = g_GameFlow->CurrentFreezeMode == FreezeMode::Player;
|
||||||
|
|
||||||
|
@ -355,9 +355,9 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
|
||||||
|
|
||||||
_stItem.World = Matrix::Identity;
|
_stItem.World = Matrix::Identity;
|
||||||
_stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimTransforms[LM_HEAD] * itemToDraw->InterpolatedWorld;
|
_stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimTransforms[LM_HEAD] * itemToDraw->InterpolatedWorld;
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
_stItem.BonesMatrices[0] = _stItem.BonesMatrices[0] * mirror->ReflectionMatrix;
|
_stItem.BonesMatrices[0] = _stItem.BonesMatrices[0] * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < unit.Segments.size(); i++)
|
for (int i = 0; i < unit.Segments.size(); i++)
|
||||||
|
@ -369,9 +369,9 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
|
||||||
Matrix::CreateTranslation(
|
Matrix::CreateTranslation(
|
||||||
Vector3::Lerp(segment.PrevPosition, segment.Position, GetInterpolationFactor(forceValue)));
|
Vector3::Lerp(segment.PrevPosition, segment.Position, GetInterpolationFactor(forceValue)));
|
||||||
|
|
||||||
if (mirror != nullptr)
|
if (_currentMirror != nullptr)
|
||||||
{
|
{
|
||||||
worldMatrix = worldMatrix * mirror->ReflectionMatrix;
|
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stItem.BonesMatrices[i + 1] = worldMatrix;
|
_stItem.BonesMatrices[i + 1] = worldMatrix;
|
||||||
|
@ -388,7 +388,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
|
if (!_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
|
||||||
return;
|
return;
|
||||||
|
@ -402,7 +402,7 @@ void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, Rend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
HolsterSlot leftHolsterID = Lara.Control.Weapon.HolsterInfo.LeftHolster;
|
HolsterSlot leftHolsterID = Lara.Control.Weapon.HolsterInfo.LeftHolster;
|
||||||
HolsterSlot rightHolsterID = Lara.Control.Weapon.HolsterInfo.RightHolster;
|
HolsterSlot rightHolsterID = Lara.Control.Weapon.HolsterInfo.RightHolster;
|
||||||
|
|
|
@ -256,7 +256,7 @@ namespace TEN::Renderer
|
||||||
_spriteBuckets.push_back(currentSpriteBucket);
|
_spriteBuckets.push_back(currentSpriteBucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawSprites(RendererMirror* mirror, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawSprites(RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (view.SpritesToDraw.empty())
|
if (view.SpritesToDraw.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -296,7 +296,7 @@ namespace TEN::Renderer
|
||||||
{
|
{
|
||||||
auto& rDrawSprite = spriteBucket.SpritesToDraw[i];
|
auto& rDrawSprite = spriteBucket.SpritesToDraw[i];
|
||||||
|
|
||||||
_stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, mirror, view);
|
_stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, _currentMirror, view);
|
||||||
_stInstancedSpriteBuffer.Sprites[i].Color = rDrawSprite.color;
|
_stInstancedSpriteBuffer.Sprites[i].Color = rDrawSprite.color;
|
||||||
_stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1;
|
_stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1;
|
||||||
_stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = rDrawSprite.SoftParticle ? 1 : 0;
|
_stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = rDrawSprite.SoftParticle ? 1 : 0;
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
virtual void ExecuteFunction(const std::string& luaFuncName, short idOne, short idTwo = 0) = 0;
|
virtual void ExecuteFunction(const std::string& luaFuncName, short idOne, short idTwo = 0) = 0;
|
||||||
|
|
||||||
virtual void GetVariables(std::vector<SavedVar>& vars) = 0;
|
virtual void GetVariables(std::vector<SavedVar>& vars) = 0;
|
||||||
virtual void SetVariables(const std::vector<SavedVar>& vars) = 0;
|
virtual void SetVariables(const std::vector<SavedVar>& vars, bool onlyLevelVars) = 0;
|
||||||
|
|
||||||
virtual void GetCallbackStrings(
|
virtual void GetCallbackStrings(
|
||||||
std::vector<std::string>& preStart,
|
std::vector<std::string>& preStart,
|
||||||
|
|
|
@ -485,9 +485,11 @@ void LogicHandler::FreeLevelScripts()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when loading.
|
// Used when loading.
|
||||||
void LogicHandler::SetVariables(const std::vector<SavedVar>& vars)
|
void LogicHandler::SetVariables(const std::vector<SavedVar>& vars, bool onlyLevelVars)
|
||||||
{
|
{
|
||||||
ResetGameTables();
|
if (!onlyLevelVars)
|
||||||
|
ResetGameTables();
|
||||||
|
|
||||||
ResetLevelTables();
|
ResetLevelTables();
|
||||||
|
|
||||||
std::unordered_map<unsigned int, sol::table> solTables;
|
std::unordered_map<unsigned int, sol::table> solTables;
|
||||||
|
@ -565,6 +567,9 @@ void LogicHandler::SetVariables(const std::vector<SavedVar>& vars)
|
||||||
for (auto& [first, second] : levelVars)
|
for (auto& [first, second] : levelVars)
|
||||||
(*m_handler.GetState())[ScriptReserved_LevelVars][first] = second;
|
(*m_handler.GetState())[ScriptReserved_LevelVars][first] = second;
|
||||||
|
|
||||||
|
if (onlyLevelVars)
|
||||||
|
return;
|
||||||
|
|
||||||
sol::table gameVars = rootTable[ScriptReserved_GameVars];
|
sol::table gameVars = rootTable[ScriptReserved_GameVars];
|
||||||
for (auto& [first, second] : gameVars)
|
for (auto& [first, second] : gameVars)
|
||||||
(*m_handler.GetState())[ScriptReserved_GameVars][first] = second;
|
(*m_handler.GetState())[ScriptReserved_GameVars][first] = second;
|
||||||
|
|
|
@ -145,7 +145,7 @@ public:
|
||||||
void ExecuteFunction(const std::string& name, short idOne, short idTwo) override;
|
void ExecuteFunction(const std::string& name, short idOne, short idTwo) override;
|
||||||
|
|
||||||
void GetVariables(std::vector<SavedVar>& vars) override;
|
void GetVariables(std::vector<SavedVar>& vars) override;
|
||||||
void SetVariables(const std::vector<SavedVar>& vars) override;
|
void SetVariables(const std::vector<SavedVar>& vars, bool onlyLevelVars) override;
|
||||||
void ResetVariables();
|
void ResetVariables();
|
||||||
|
|
||||||
void SetCallbackStrings(const std::vector<std::string>& preStart,
|
void SetCallbackStrings(const std::vector<std::string>& preStart,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define ALPHATEST_GREATER_THAN 1
|
#define ALPHATEST_GREATER_THAN 1
|
||||||
#define ALPHATEST_LESS_THAN 2
|
#define ALPHATEST_LESS_THAN 2
|
||||||
|
|
||||||
#define BLENDMODE_OPAQUE 0,
|
#define BLENDMODE_OPAQUE 0
|
||||||
#define BLENDMODE_ALPHATEST 1
|
#define BLENDMODE_ALPHATEST 1
|
||||||
#define BLENDMODE_ADDITIVE 2
|
#define BLENDMODE_ADDITIVE 2
|
||||||
#define BLENDMODE_NOZTEST 4
|
#define BLENDMODE_NOZTEST 4
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "./VertexEffects.hlsli"
|
#include "./VertexEffects.hlsli"
|
||||||
#include "./VertexInput.hlsli"
|
#include "./VertexInput.hlsli"
|
||||||
#include "./Blending.hlsli"
|
#include "./Blending.hlsli"
|
||||||
|
#include "./Shadows.hlsli"
|
||||||
|
|
||||||
#define INSTANCED_STATIC_MESH_BUCKET_SIZE 100
|
#define INSTANCED_STATIC_MESH_BUCKET_SIZE 100
|
||||||
|
|
||||||
|
@ -124,6 +125,8 @@ PixelShaderOutput PS(PixelShaderInput input)
|
||||||
input.FogBulbs.w) :
|
input.FogBulbs.w) :
|
||||||
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
||||||
|
|
||||||
|
color = DoShadow(input.WorldPosition, normal, color, -0.5f);
|
||||||
|
|
||||||
output.Color = float4(color * occlusion, tex.w);
|
output.Color = float4(color * occlusion, tex.w);
|
||||||
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
||||||
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "./VertexInput.hlsli"
|
#include "./VertexInput.hlsli"
|
||||||
#include "./Blending.hlsli"
|
#include "./Blending.hlsli"
|
||||||
#include "./AnimatedTextures.hlsli"
|
#include "./AnimatedTextures.hlsli"
|
||||||
//#include "./Shadows.hlsli"
|
#include "./Shadows.hlsli"
|
||||||
|
|
||||||
#define MAX_BONES 32
|
#define MAX_BONES 32
|
||||||
|
|
||||||
|
@ -155,6 +155,8 @@ PixelShaderOutput PS(PixelShaderInput input)
|
||||||
input.FogBulbs.w) :
|
input.FogBulbs.w) :
|
||||||
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
||||||
|
|
||||||
|
color = DoShadow(input.WorldPosition, normal, color, -0.5f);
|
||||||
|
|
||||||
output.Color = saturate(float4(color * occlusion, tex.w));
|
output.Color = saturate(float4(color * occlusion, tex.w));
|
||||||
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
||||||
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
||||||
|
|
|
@ -3,12 +3,19 @@
|
||||||
|
|
||||||
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923
|
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923
|
||||||
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
|
#define PI2 6.2831853071795864769252867665590057683943387987502116419498891846
|
||||||
|
#define EPSILON 1e-38
|
||||||
#define OCTAVES 6
|
#define OCTAVES 6
|
||||||
|
|
||||||
#define LT_SUN 0
|
#define LT_SUN 0
|
||||||
#define LT_POINT 1
|
#define LT_POINT 1
|
||||||
#define LT_SPOT 2
|
#define LT_SPOT 2
|
||||||
#define LT_SHADOW 3
|
#define LT_SHADOW 3
|
||||||
|
|
||||||
|
#define LT_MASK 0xFFFF
|
||||||
|
#define LT_MASK_SUN (1 << (31 - LT_SUN))
|
||||||
|
#define LT_MASK_POINT (1 << (31 - LT_POINT))
|
||||||
|
#define LT_MASK_SPOT (1 << (31 - LT_SPOT))
|
||||||
|
#define LT_MASK_SHADOW (1 << (31 - LT_SHADOW))
|
||||||
|
|
||||||
#define MAX_LIGHTS_PER_ROOM 48
|
#define MAX_LIGHTS_PER_ROOM 48
|
||||||
#define MAX_LIGHTS_PER_ITEM 8
|
#define MAX_LIGHTS_PER_ITEM 8
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "./Shadows.hlsli"
|
#include "./Shadows.hlsli"
|
||||||
#include "./ShaderLight.hlsli"
|
#include "./ShaderLight.hlsli"
|
||||||
|
|
||||||
|
#define ROOM_LIGHT_COEFF 0.7f
|
||||||
|
|
||||||
cbuffer RoomBuffer : register(b5)
|
cbuffer RoomBuffer : register(b5)
|
||||||
{
|
{
|
||||||
int Water;
|
int Water;
|
||||||
|
@ -141,28 +143,31 @@ PixelShaderOutput PS(PixelShaderInput input)
|
||||||
occlusion = pow(SSAOTexture.Sample(SSAOSampler, samplePosition).x, AmbientOcclusionExponent);
|
occlusion = pow(SSAOTexture.Sample(SSAOSampler, samplePosition).x, AmbientOcclusionExponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CastShadows)
|
lighting = DoShadow(input.WorldPosition, normal, lighting, -2.5f);
|
||||||
|
lighting = DoBlobShadows(input.WorldPosition, lighting);
|
||||||
|
|
||||||
|
bool onlyPointLights = (NumRoomLights & ~LT_MASK) == LT_MASK_POINT;
|
||||||
|
int numLights = NumRoomLights & LT_MASK;
|
||||||
|
|
||||||
|
for (int i = 0; i < numLights; i++)
|
||||||
{
|
{
|
||||||
float isPointLight = step(0.5f, Light.Type == LT_POINT); // 1.0 if LT_POINT, 0.0 otherwise
|
if (onlyPointLights)
|
||||||
float isSpotLight = step(0.5f, Light.Type == LT_SPOT); // 1.0 if LT_SPOT, 0.0 otherwise
|
{
|
||||||
float isOtherLight = 1.0 - (isPointLight + isSpotLight); // 1.0 if neither LT_POINT nor LT_SPOT
|
lighting += DoPointLight(input.WorldPosition, normal, RoomLights[i]) * ROOM_LIGHT_COEFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Room dynamic lights can only be spot or point, so we use simplified function for that.
|
||||||
|
|
||||||
float3 pointLightShadow = DoPointLightShadow(input.WorldPosition, lighting);
|
float isPoint = step(0.5f, RoomLights[i].Type == LT_POINT);
|
||||||
float3 spotLightShadow = DoSpotLightShadow(input.WorldPosition, normal, lighting);
|
float isSpot = step(0.5f, RoomLights[i].Type == LT_SPOT);
|
||||||
|
|
||||||
// Blend the shadows based on the light type
|
float3 pointLight = float3(0.0f, 0.0f, 0.0f);
|
||||||
lighting = pointLightShadow * isPointLight + spotLightShadow * isSpotLight + lighting * isOtherLight;
|
float3 spotLight = float3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
DoPointAndSpotLight(input.WorldPosition, normal, RoomLights[i], pointLight, spotLight);
|
||||||
|
|
||||||
lighting = DoBlobShadows(input.WorldPosition, lighting);
|
lighting += pointLight * isPoint * ROOM_LIGHT_COEFF + spotLight * isSpot * ROOM_LIGHT_COEFF;
|
||||||
|
}
|
||||||
for (int i = 0; i < NumRoomLights; i++)
|
|
||||||
{
|
|
||||||
float isPointLightRoom = step(0.5f, RoomLights[i].Type == LT_POINT);
|
|
||||||
float isSpotLightRoom = step(0.5f, RoomLights[i].Type == LT_SPOT);
|
|
||||||
|
|
||||||
lighting += DoPointLight(input.WorldPosition, normal, RoomLights[i]) * isPointLightRoom;
|
|
||||||
lighting += DoSpotLight(input.WorldPosition, normal, RoomLights[i]) * isSpotLightRoom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Caustics)
|
if (Caustics)
|
||||||
|
|
|
@ -129,21 +129,30 @@ float3 DoSpotLight(float3 pos, float3 normal, ShaderLight light)
|
||||||
float3 lightVec = pos - light.Position.xyz;
|
float3 lightVec = pos - light.Position.xyz;
|
||||||
float distance = length(lightVec);
|
float distance = length(lightVec);
|
||||||
float3 lightDir = normalize(lightVec);
|
float3 lightDir = normalize(lightVec);
|
||||||
float cosine = dot(lightDir, light.Direction.xyz);
|
|
||||||
|
|
||||||
// Angle attenuation
|
float cosine = dot(lightDir, light.Direction.xyz);
|
||||||
float coneInCos = cos(light.InRange * (PI / 180.0f));
|
float angleAttenuation = saturate((cosine - light.OutRange) / (light.InRange - light.OutRange));
|
||||||
float coneOutCos = cos(light.OutRange * (PI / 180.0f));
|
|
||||||
float angleAttenuation = saturate((cosine - coneOutCos) / (coneInCos - coneOutCos));
|
|
||||||
|
|
||||||
// Distance attenuation
|
|
||||||
float distanceAttenuation = saturate((light.Out - distance) / (light.Out - light.In));
|
float distanceAttenuation = saturate((light.Out - distance) / (light.Out - light.In));
|
||||||
|
|
||||||
// Surface lighting
|
|
||||||
float d = saturate(dot(normal, -lightDir));
|
float d = saturate(dot(normal, -lightDir));
|
||||||
return saturate(light.Color.xyz * light.Intensity * angleAttenuation * distanceAttenuation * d);
|
return saturate(light.Color.xyz * light.Intensity * angleAttenuation * distanceAttenuation * d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoPointAndSpotLight(float3 pos, float3 normal, ShaderLight light, out float3 pointOutput, out float3 spotOutput)
|
||||||
|
{
|
||||||
|
float3 lightVec = light.Position.xyz - pos;
|
||||||
|
float distance = length(lightVec);
|
||||||
|
float3 lightDir = normalize(lightVec);
|
||||||
|
|
||||||
|
float cosine = dot(-lightDir, light.Direction.xyz);
|
||||||
|
float distanceAttenuation = saturate((light.Out - distance) / (light.Out - light.In));
|
||||||
|
float angleAttenuation = saturate((cosine - light.OutRange) / (light.InRange - light.OutRange));
|
||||||
|
|
||||||
|
float d = saturate(dot(normal, lightDir));
|
||||||
|
pointOutput = saturate(light.Color.xyz * light.Intensity * distanceAttenuation * d);
|
||||||
|
spotOutput = saturate(light.Color.xyz * light.Intensity * angleAttenuation * distanceAttenuation * d);
|
||||||
|
}
|
||||||
|
|
||||||
float3 DoDirectionalLight(float3 pos, float3 normal, ShaderLight light)
|
float3 DoDirectionalLight(float3 pos, float3 normal, ShaderLight light)
|
||||||
{
|
{
|
||||||
float d = saturate(dot(-light.Direction.xyz, normal));
|
float d = saturate(dot(-light.Direction.xyz, normal));
|
||||||
|
@ -364,23 +373,37 @@ float3 CombineLights(float3 ambient, float3 vertex, float3 tex, float3 pos, floa
|
||||||
float3 shadow = 0;
|
float3 shadow = 0;
|
||||||
float3 spec = 0;
|
float3 spec = 0;
|
||||||
|
|
||||||
|
int lightTypeMask = (numLights & ~LT_MASK);
|
||||||
|
numLights = numLights & LT_MASK;
|
||||||
|
|
||||||
for (int i = 0; i < numLights; i++)
|
for (int i = 0; i < numLights; i++)
|
||||||
{
|
{
|
||||||
float isPoint = step(0.5f, float(lights[i].Type == LT_POINT));
|
if (lightTypeMask & LT_MASK_SUN)
|
||||||
float isSpot = step(0.5f, float(lights[i].Type == LT_SPOT));
|
{
|
||||||
float isSun = step(0.5f, float(lights[i].Type == LT_SUN));
|
float isSun = step(0.5f, float(lights[i].Type == LT_SUN));
|
||||||
float isShadow = step(0.5f, float(lights[i].Type == LT_SHADOW));
|
diffuse += isSun * DoDirectionalLight(pos, normal, lights[i]);
|
||||||
|
spec += isSun * DoSpecularSun(normal, lights[i], sheen);
|
||||||
|
}
|
||||||
|
|
||||||
diffuse += isPoint * DoPointLight(pos, normal, lights[i]);
|
if (lightTypeMask & LT_MASK_POINT)
|
||||||
spec += isPoint * DoSpecularPoint(pos, normal, lights[i], sheen);
|
{
|
||||||
|
float isPoint = step(0.5f, float(lights[i].Type == LT_POINT));
|
||||||
|
diffuse += isPoint * DoPointLight(pos, normal, lights[i]);
|
||||||
|
spec += isPoint * DoSpecularPoint(pos, normal, lights[i], sheen);
|
||||||
|
}
|
||||||
|
|
||||||
diffuse += isSpot * DoSpotLight(pos, normal, lights[i]);
|
if (lightTypeMask & LT_MASK_SPOT)
|
||||||
spec += isSpot * DoSpecularSpot(pos, normal, lights[i], sheen);
|
{
|
||||||
|
float isSpot = step(0.5f, float(lights[i].Type == LT_SPOT));
|
||||||
|
diffuse += isSpot * DoSpotLight(pos, normal, lights[i]);
|
||||||
|
spec += isSpot * DoSpecularSpot(pos, normal, lights[i], sheen);
|
||||||
|
}
|
||||||
|
|
||||||
diffuse += isSun * DoDirectionalLight(pos, normal, lights[i]);
|
if (lightTypeMask & LT_MASK_SHADOW)
|
||||||
spec += isSun * DoSpecularSun(normal, lights[i], sheen);
|
{
|
||||||
|
float isShadow = step(0.5f, float(lights[i].Type == LT_SHADOW));
|
||||||
shadow += isShadow * DoShadowLight(pos, normal, lights[i]);
|
shadow += isShadow * DoShadowLight(pos, normal, lights[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow = saturate(shadow);
|
shadow = saturate(shadow);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "./Blending.hlsli"
|
||||||
|
#include "./Math.hlsli"
|
||||||
#include "./ShaderLight.hlsli"
|
#include "./ShaderLight.hlsli"
|
||||||
|
|
||||||
#define SHADOW_INTENSITY (0.55f)
|
#define SHADOW_INTENSITY (0.55f)
|
||||||
|
@ -86,20 +88,32 @@ float3 DoBlobShadows(float3 worldPos, float3 lighting)
|
||||||
return lighting * saturate(shadowFactor + SHADOW_INTENSITY);
|
return lighting * saturate(shadowFactor + SHADOW_INTENSITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 DoPointLightShadow(float3 worldPos, float3 lighting)
|
float3 DoShadow(float3 worldPos, float3 normal, float3 lighting, float bias)
|
||||||
{
|
{
|
||||||
|
if (!CastShadows)
|
||||||
|
return lighting;
|
||||||
|
|
||||||
|
if (BlendMode != BLENDMODE_OPAQUE && BlendMode != BLENDMODE_ALPHATEST && BlendMode != BLENDMODE_ALPHABLEND)
|
||||||
|
return lighting;
|
||||||
|
|
||||||
float shadowFactor = 1.0f;
|
float shadowFactor = 1.0f;
|
||||||
|
|
||||||
|
float3 dir = normalize(Light.Position - worldPos);
|
||||||
|
float ndot = dot(normal, dir);
|
||||||
|
float facingFactor = saturate((ndot - bias) / (1.0f - bias + EPSILON));
|
||||||
|
|
||||||
[unroll]
|
[unroll]
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
float3 dir = normalize(worldPos - Light.Position);
|
|
||||||
float4 lightClipSpace = mul(float4(worldPos, 1.0f), LightViewProjections[i]);
|
float4 lightClipSpace = mul(float4(worldPos, 1.0f), LightViewProjections[i]);
|
||||||
lightClipSpace.xyz /= lightClipSpace.w;
|
lightClipSpace.xyz /= lightClipSpace.w;
|
||||||
|
|
||||||
if (lightClipSpace.x >= -1.0f && lightClipSpace.x <= 1.0f &&
|
float insideLightBounds =
|
||||||
lightClipSpace.y >= -1.0f && lightClipSpace.y <= 1.0f &&
|
step(-1.0f, lightClipSpace.x) * step(lightClipSpace.x, 1.0f) *
|
||||||
lightClipSpace.z >= 0.0f && lightClipSpace.z <= 1.0f)
|
step(-1.0f, lightClipSpace.y) * step(lightClipSpace.y, 1.0f) *
|
||||||
|
step( 0.0f, lightClipSpace.z) * step(lightClipSpace.z, 1.0f);
|
||||||
|
|
||||||
|
if (insideLightBounds > 0.0f)
|
||||||
{
|
{
|
||||||
lightClipSpace.x = lightClipSpace.x / 2 + 0.5;
|
lightClipSpace.x = lightClipSpace.x / 2 + 0.5;
|
||||||
lightClipSpace.y = lightClipSpace.y / -2 + 0.5;
|
lightClipSpace.y = lightClipSpace.y / -2 + 0.5;
|
||||||
|
@ -108,63 +122,29 @@ float3 DoPointLightShadow(float3 worldPos, float3 lighting)
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
// Perform PCF filtering on a 4 x 4 texel neighborhood.
|
// Perform PCF filtering on a 4 x 4 texel neighborhood.
|
||||||
[unroll]
|
[unroll]
|
||||||
for (y = -1.5; y <= 1.5; y += 1.0)
|
for (y = -1.5; y <= 1.5; y += 1.0)
|
||||||
{
|
{
|
||||||
[unroll]
|
[unroll]
|
||||||
for (x = -1.5; x <= 1.5; x += 1.0)
|
for (x = -1.5; x <= 1.5; x += 1.0)
|
||||||
{
|
{
|
||||||
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + TexOffset(x, y), i), lightClipSpace.z);
|
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + TexOffset(x, y), i), lightClipSpace.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowFactor = sum / 16.0;
|
shadowFactor = lerp(shadowFactor, sum / 16.0, facingFactor * insideLightBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute attenuation and combine lighting contribution with shadow factor
|
float isPoint = step(0.5f, Light.Type == LT_POINT); // 1.0 if LT_POINT, 0.0 otherwise
|
||||||
float distanceFactor = saturate(((distance(worldPos, Light.Position)) / (Light.Out)));
|
float isSpot = step(0.5f, Light.Type == LT_SPOT); // 1.0 if LT_SPOT, 0.0 otherwise
|
||||||
return lighting * saturate((shadowFactor + SHADOW_INTENSITY) + (pow(distanceFactor, 4) * INV_SHADOW_INTENSITY));
|
float isOther = 1.0 - (isPoint + isSpot); // 1.0 if neither LT_POINT nor LT_SPOT
|
||||||
}
|
|
||||||
|
float pointFactor = 1.0f - Luma(DoPointLight(worldPos, normal, Light));
|
||||||
float3 DoSpotLightShadow(float3 worldPos, float3 normal, float3 lighting)
|
float spotFactor = 1.0f - Luma(DoSpotLight(worldPos, normal, Light));
|
||||||
{
|
|
||||||
float influence = 1.0f - Luma(DoSpotLight(worldPos, normal, Light));
|
float3 pointShadow = lighting * saturate((shadowFactor + SHADOW_INTENSITY) + (pow(pointFactor, 4) * INV_SHADOW_INTENSITY));
|
||||||
|
float3 spotShadow = lighting * saturate((shadowFactor + SHADOW_INTENSITY) + (pow(spotFactor, 4) * INV_SHADOW_INTENSITY));
|
||||||
float shadowFactor = 1.0f;
|
|
||||||
|
return pointShadow * isPoint + spotShadow * isSpot + lighting * isOther;
|
||||||
[unroll]
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
float3 dir = normalize(worldPos - Light.Position);
|
|
||||||
float4 lightClipSpace = mul(float4(worldPos, 1.0f), LightViewProjections[i]);
|
|
||||||
lightClipSpace.xyz /= lightClipSpace.w;
|
|
||||||
|
|
||||||
if (lightClipSpace.x >= -1.0f && lightClipSpace.x <= 1.0f &&
|
|
||||||
lightClipSpace.y >= -1.0f && lightClipSpace.y <= 1.0f &&
|
|
||||||
lightClipSpace.z >= 0.0f && lightClipSpace.z <= 1.0f)
|
|
||||||
{
|
|
||||||
lightClipSpace.x = lightClipSpace.x / 2 + 0.5;
|
|
||||||
lightClipSpace.y = lightClipSpace.y / -2 + 0.5;
|
|
||||||
|
|
||||||
float sum = 0;
|
|
||||||
float x, y;
|
|
||||||
|
|
||||||
// Perform PCF filtering on a 4 x 4 texel neighborhood.
|
|
||||||
[unroll]
|
|
||||||
for (y = -1.5; y <= 1.5; y += 1.0)
|
|
||||||
{
|
|
||||||
[unroll]
|
|
||||||
for (x = -1.5; x <= 1.5; x += 1.0)
|
|
||||||
{
|
|
||||||
sum += ShadowMap.SampleCmpLevelZero(ShadowMapSampler, float3(lightClipSpace.xy + TexOffset(x, y), i), lightClipSpace.z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowFactor = sum / 16.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute attenuation and combine lighting contribution with shadow factor
|
|
||||||
return lighting * saturate((shadowFactor + SHADOW_INTENSITY) + (pow(influence, 4) * INV_SHADOW_INTENSITY));
|
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "./VertexInput.hlsli"
|
#include "./VertexInput.hlsli"
|
||||||
#include "./Blending.hlsli"
|
#include "./Blending.hlsli"
|
||||||
#include "./CBStatic.hlsli"
|
#include "./CBStatic.hlsli"
|
||||||
|
#include "./Shadows.hlsli"
|
||||||
|
|
||||||
struct PixelShaderInput
|
struct PixelShaderInput
|
||||||
{
|
{
|
||||||
|
@ -92,6 +93,8 @@ PixelShaderOutput PS(PixelShaderInput input)
|
||||||
input.FogBulbs.w) :
|
input.FogBulbs.w) :
|
||||||
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
StaticLight(input.Color.xyz, tex.xyz, input.FogBulbs.w);
|
||||||
|
|
||||||
|
color = DoShadow(input.WorldPosition, normal, color, -0.5f);
|
||||||
|
|
||||||
output.Color = float4(color, tex.w);
|
output.Color = float4(color, tex.w);
|
||||||
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
output.Color = DoFogBulbsForPixel(output.Color, float4(input.FogBulbs.xyz, 1.0f));
|
||||||
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
output.Color = DoDistanceFogForPixel(output.Color, FogColor, input.DistanceFog);
|
||||||
|
|
|
@ -1380,7 +1380,10 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
|
||||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</DeploymentContent>
|
||||||
<FileType>Text</FileType>
|
<FileType>Text</FileType>
|
||||||
</None>
|
</None>
|
||||||
<None Include="Shaders\Blending.hlsli" />
|
<None Include="Shaders\Blending.hlsli">
|
||||||
|
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DeploymentContent>
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
</None>
|
||||||
<None Include="Shaders\CBPostProcess.hlsli">
|
<None Include="Shaders\CBPostProcess.hlsli">
|
||||||
<DeploymentContent>true</DeploymentContent>
|
<DeploymentContent>true</DeploymentContent>
|
||||||
</None>
|
</None>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue