Simplify renderer code, remove excessive if statements

This commit is contained in:
Lwmte 2024-12-18 01:07:10 +01:00
parent 31d278a780
commit 5dd8db198c
10 changed files with 171 additions and 322 deletions

View file

@ -219,6 +219,7 @@ namespace TEN::Renderer
lights[index].Direction = Vector3::Lerp(light.PrevDirection, light.Direction, GetInterpolationFactor()); lights[index].Direction = Vector3::Lerp(light.PrevDirection, light.Direction, GetInterpolationFactor());
} }
// If we are in mirror renderer pass, reflect light.
if (_currentMirror != nullptr) if (_currentMirror != nullptr)
{ {
lights[index].Position = Vector3::Transform(lights[index].Position, _currentMirror->ReflectionMatrix); lights[index].Position = Vector3::Transform(lights[index].Position, _currentMirror->ReflectionMatrix);

View file

@ -456,7 +456,7 @@ 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(RenderView& view, RendererPass rendererPass); void DrawItems(RenderView& view, RendererPass rendererPass, bool onlyPlayer = false);
void DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass); void DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass);
void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass); void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass);
void DrawBaddyGunflashes(RenderView& view); void DrawBaddyGunflashes(RenderView& view);
@ -536,6 +536,7 @@ namespace TEN::Renderer
void SetScissor(RendererRectangle rectangle); void SetScissor(RendererRectangle rectangle);
bool SetupBlendModeAndAlphaTest(BlendMode blendMode, RendererPass rendererPass, int drawPass); bool SetupBlendModeAndAlphaTest(BlendMode blendMode, RendererPass rendererPass, int drawPass);
void SortAndPrepareSprites(RenderView& view); void SortAndPrepareSprites(RenderView& view);
void SortTransparentFaces(RenderView& view);
void ResetItems(); void ResetItems();
void ResetScissor(); void ResetScissor();
void ResetDebugVariables(); void ResetDebugVariables();
@ -574,6 +575,19 @@ namespace TEN::Renderer
void CreateSSAONoiseTexture(); void CreateSSAONoiseTexture();
void InitializeSMAA(); void InitializeSMAA();
inline bool IgnoreMirrorPassForRoom(int room)
{
return (_currentMirror != nullptr && room != _currentMirror->RealRoom);
}
inline void ReflectMatrixOptionally(Matrix& matrix)
{
if (_currentMirror == nullptr)
return;
matrix = matrix * _currentMirror->ReflectionMatrix;
}
inline void DrawIndexedTriangles(int count, int baseIndex, int baseVertex) inline void DrawIndexedTriangles(int count, int baseIndex, int baseVertex)
{ {
_context->DrawIndexed(count, baseIndex, baseVertex); _context->DrawIndexed(count, baseIndex, baseVertex);

View file

@ -253,10 +253,8 @@ namespace TEN::Renderer
if (gunshell->counter <= 0) if (gunshell->counter <= 0)
continue; continue;
if (_currentMirror != nullptr && gunshell->roomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(gunshell->roomNumber))
{
continue; continue;
}
objectID = gunshell->objectNumber; objectID = gunshell->objectNumber;
@ -272,11 +270,7 @@ namespace TEN::Renderer
auto prevWorldMatrix = prevRotMatrix * prevTranslation; auto prevWorldMatrix = prevRotMatrix * prevTranslation;
worldMatrix = Matrix::Lerp(prevWorldMatrix, worldMatrix, GetInterpolationFactor()); worldMatrix = Matrix::Lerp(prevWorldMatrix, worldMatrix, GetInterpolationFactor());
ReflectMatrixOptionally(worldMatrix);
if (_currentMirror != nullptr)
{
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;
@ -477,16 +471,13 @@ namespace TEN::Renderer
if (!Objects[ID_RATS_EMITTER].loaded) if (!Objects[ID_RATS_EMITTER].loaded)
return; return;
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
return;
if (rendererPass == RendererPass::CollectTransparentFaces) if (rendererPass == RendererPass::CollectTransparentFaces)
{ {
for (int i = 0; i < NUM_RATS; i++) for (int i = 0; i < NUM_RATS; i++)
{ {
auto* rat = &Rats[i]; auto* rat = &Rats[i];
if (_currentMirror != nullptr && rat->RoomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(rat->RoomNumber))
continue; continue;
if (rat->On) if (rat->On)
@ -529,7 +520,7 @@ namespace TEN::Renderer
{ {
auto* rat = &Rats[i]; auto* rat = &Rats[i];
if (_currentMirror != nullptr && rat->RoomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(rat->RoomNumber))
continue; continue;
if (rat->On) if (rat->On)
@ -571,10 +562,8 @@ 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 (_currentMirror != nullptr) ReflectMatrixOptionally(world);
{
world = world * _currentMirror->ReflectionMatrix;
}
_stStatic.World = world; _stStatic.World = world;
_stStatic.Color = Vector4::One; _stStatic.Color = Vector4::One;
_stStatic.AmbientLight = _rooms[rat->RoomNumber].AmbientLight; _stStatic.AmbientLight = _rooms[rat->RoomNumber].AmbientLight;
@ -735,9 +724,6 @@ namespace TEN::Renderer
if (!Objects[ID_BATS_EMITTER].loaded) if (!Objects[ID_BATS_EMITTER].loaded)
return; return;
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
return;
auto& mesh = *GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3)); auto& mesh = *GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (GlobalCounter & 3));
if (rendererPass == RendererPass::CollectTransparentFaces) if (rendererPass == RendererPass::CollectTransparentFaces)
@ -747,7 +733,7 @@ namespace TEN::Renderer
if (!bat.On) if (!bat.On)
continue; continue;
if (_currentMirror != nullptr && bat.RoomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(bat.RoomNumber))
continue; continue;
for (auto& bucket : mesh.Buckets) for (auto& bucket : mesh.Buckets)
@ -783,7 +769,7 @@ namespace TEN::Renderer
{ {
const auto& bat = Bats[i]; const auto& bat = Bats[i];
if (_currentMirror != nullptr && bat.RoomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(bat.RoomNumber))
continue; continue;
if (bat.On) if (bat.On)
@ -793,10 +779,7 @@ 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 (_currentMirror != nullptr) ReflectMatrixOptionally(world);
{
world = world * _currentMirror->ReflectionMatrix;
}
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[batCount].Ambient = room.AmbientLight; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].Ambient = room.AmbientLight;
@ -862,9 +845,6 @@ namespace TEN::Renderer
if (!Objects[ID_LITTLE_BEETLE].loaded) if (!Objects[ID_LITTLE_BEETLE].loaded)
return; return;
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
return;
auto& mesh = *GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2)); auto& mesh = *GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
if (rendererPass == RendererPass::CollectTransparentFaces) if (rendererPass == RendererPass::CollectTransparentFaces)
@ -874,6 +854,9 @@ namespace TEN::Renderer
if (!beetle.On) if (!beetle.On)
continue; continue;
if (IgnoreMirrorPassForRoom(beetle.RoomNumber))
continue;
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor()); auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor());
for (auto& bucket : mesh.Buckets) for (auto& bucket : mesh.Buckets)
@ -908,38 +891,35 @@ namespace TEN::Renderer
{ {
const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i]; const auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
if (_currentMirror != nullptr && beetle.RoomNumber != _currentMirror->RealRoom) if (!beetle.On)
continue; continue;
if (beetle.On) if (IgnoreMirrorPassForRoom(beetle.RoomNumber))
continue;
auto& room = _rooms[beetle.RoomNumber];
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor());
Matrix world = transformMatrix;
ReflectMatrixOptionally(world);
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = (int)mesh.LightMode;
if (rendererPass != RendererPass::GBuffer)
{ {
auto& room = _rooms[beetle.RoomNumber]; auto lights = std::vector<RendererLight*>{};
for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, GetInterpolationFactor()); lights.push_back(room.LightsToDraw[i]);
Matrix world = transformMatrix;
if (_currentMirror != nullptr)
{
world = world * _currentMirror->ReflectionMatrix;
}
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = (int)mesh.LightMode;
if (rendererPass != RendererPass::GBuffer)
{
auto lights = std::vector<RendererLight*>{};
for (int i = 0; i < std::min((int)room.LightsToDraw.size(), MAX_LIGHTS_PER_ITEM); i++)
lights.push_back(room.LightsToDraw[i]);
BindInstancedStaticLights(lights, beetleCount); BindInstancedStaticLights(lights, beetleCount);
}
beetleCount++;
} }
beetleCount++;
if (beetleCount == INSTANCED_STATIC_MESH_BUCKET_SIZE || if (beetleCount == INSTANCED_STATIC_MESH_BUCKET_SIZE ||
(i == TEN::Entities::TR4::NUM_BEETLES - 1 && beetleCount > 0)) (i == TEN::Entities::TR4::NUM_BEETLES - 1 && beetleCount > 0))
{ {
@ -993,9 +973,6 @@ namespace TEN::Renderer
if (!Objects[ID_LOCUSTS].loaded) if (!Objects[ID_LOCUSTS].loaded)
return; return;
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
return;
if (rendererPass == RendererPass::CollectTransparentFaces) if (rendererPass == RendererPass::CollectTransparentFaces)
{ {
auto* obj = &Objects[ID_LOCUSTS]; auto* obj = &Objects[ID_LOCUSTS];
@ -1006,7 +983,7 @@ namespace TEN::Renderer
if (!locust.on) if (!locust.on)
continue; continue;
if (_currentMirror != nullptr && locust.roomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(locust.roomNumber))
continue; continue;
auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3)); auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3));
@ -1045,7 +1022,7 @@ namespace TEN::Renderer
if (!locust.on) if (!locust.on)
continue; continue;
if (_currentMirror != nullptr && locust.roomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(locust.roomNumber))
continue; continue;
activeLocustsExist = true; activeLocustsExist = true;
@ -1084,12 +1061,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 (_currentMirror != nullptr) ReflectMatrixOptionally(world);
{
world = world * _currentMirror->ReflectionMatrix;
}
_stStatic.World = world;
_stStatic.World = world;
_stStatic.Color = Vector4::One; _stStatic.Color = Vector4::One;
_stStatic.AmbientLight = _rooms[locust.roomNumber].AmbientLight; _stStatic.AmbientLight = _rooms[locust.roomNumber].AmbientLight;
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -1899,39 +1873,79 @@ namespace TEN::Renderer
pRenderViewPtrs[1] = _depthRenderTarget.RenderTargetView.Get(); pRenderViewPtrs[1] = _depthRenderTarget.RenderTargetView.Get();
_context->OMSetRenderTargets(2, &pRenderViewPtrs[0], _renderTarget.DepthStencilView.Get()); _context->OMSetRenderTargets(2, &pRenderViewPtrs[0], _renderTarget.DepthStencilView.Get());
DrawRooms(view, RendererPass::GBuffer); // Lambda function to perform normal render pass and mirror passes, if needed.
DrawItems(view, RendererPass::GBuffer); auto doRenderPass = [&](RendererPass pass, bool drawMirrors)
DrawStatics(view, RendererPass::GBuffer);
DrawSpiders(view, RendererPass::GBuffer);
DrawScarabs(view, RendererPass::GBuffer);
DrawGunShells(view, RendererPass::GBuffer);
DrawBats(view, RendererPass::GBuffer);
DrawEffects(view, RendererPass::GBuffer);
DrawRats(view, RendererPass::GBuffer);
DrawLocusts(view, RendererPass::GBuffer);
if (view.Mirrors.size() > 0)
{ {
SetCullMode(CullMode::Clockwise); // Draw room geometry first, if applicable for a given pass.
if (pass != RendererPass::Transparent && pass != RendererPass::GunFlashes)
DrawRooms(view, pass);
for (auto& mirror : view.Mirrors) // Draw all objects, and additionally draw all reflections for them.
auto renderObjects = [&](bool player, bool moveables, bool statics)
{ {
_currentMirror = &mirror; switch (pass)
{
case RendererPass::Transparent:
DrawSortedFaces(view);
break;
DrawItems(view, RendererPass::GBuffer); case RendererPass::GunFlashes:
DrawStatics(view, RendererPass::GBuffer); DrawGunFlashes(view);
DrawScarabs(view, RendererPass::GBuffer); DrawBaddyGunflashes(view);
DrawGunShells(view, RendererPass::GBuffer); break;
DrawBats(view, RendererPass::GBuffer);
DrawEffects(view, RendererPass::GBuffer);
DrawRats(view, RendererPass::GBuffer);
DrawLocusts(view, RendererPass::GBuffer);
_currentMirror = nullptr; default:
if (statics)
{
DrawStatics(view, pass);
DrawDebris(view, pass); // Debris mostly originate from shatter statics.
}
if (moveables)
{
DrawItems(view, pass);
DrawEffects(view, pass);
DrawGunShells(view, pass);
DrawSpiders(view, pass);
DrawScarabs(view, pass);
DrawBats(view, pass);
DrawRats(view, pass);
DrawLocusts(view, pass);
DrawFishSwarm(view, pass);
}
else if (player)
{
DrawItems(view, pass, true);
DrawGunShells(view, pass);
}
// Sorted sprites already collected at beginning of frame.
if (pass != RendererPass::CollectTransparentFaces)
DrawSprites(view, pass);
break;
}
};
// Draw original objects.
renderObjects(true, true, true);
// Draw mirrored objects for all visible mirrors.
if (drawMirrors && !view.Mirrors.empty())
{
SetCullMode(CullMode::Clockwise);
for (auto& mirror : view.Mirrors)
{
_currentMirror = &mirror;
renderObjects(mirror.ReflectLara, mirror.ReflectMoveables, mirror.ReflectStatics);
_currentMirror = nullptr;
}
SetCullMode(CullMode::CounterClockwise);
} }
};
SetCullMode(CullMode::CounterClockwise); // Render G-Buffer pass.
} doRenderPass(RendererPass::GBuffer, true);
// Calculate ambient occlusion. // Calculate ambient occlusion.
if (g_Configuration.EnableAmbientOcclusion) if (g_Configuration.EnableAmbientOcclusion)
@ -1954,139 +1968,14 @@ namespace TEN::Renderer
// Bind main render target again. Main depth buffer is already filled and avoids overdraw in following steps. // Bind main render target again. Main depth buffer is already filled and avoids overdraw in following steps.
_context->OMSetRenderTargets(1, _renderTarget.RenderTargetView.GetAddressOf(), _renderTarget.DepthStencilView.Get()); _context->OMSetRenderTargets(1, _renderTarget.RenderTargetView.GetAddressOf(), _renderTarget.DepthStencilView.Get());
// Draw opaque, alpha test, and fast alpha blend faces. doRenderPass(RendererPass::Opaque, true);
DrawRooms(view, RendererPass::Opaque); doRenderPass(RendererPass::Additive, true);
DrawItems(view, RendererPass::Opaque); doRenderPass(RendererPass::CollectTransparentFaces, false);
DrawStatics(view, RendererPass::Opaque); SortTransparentFaces(view);
DrawSpiders(view, RendererPass::Opaque);
DrawScarabs(view, RendererPass::Opaque);
DrawGunShells(view, RendererPass::Opaque);
DrawBats(view, RendererPass::Opaque);
DrawEffects(view, RendererPass::Opaque);
DrawRats(view, RendererPass::Opaque);
DrawLocusts(view, RendererPass::Opaque);
DrawDebris(view, RendererPass::Opaque);
DrawSprites(view, RendererPass::Opaque);
DrawFishSwarm(view, RendererPass::Opaque);
// Draw mirrored opaque geometry only if Lara is inside a mirror room doRenderPass(RendererPass::Transparent, true);
if (view.Mirrors.size() > 0) doRenderPass(RendererPass::GunFlashes, true); // HACK: Gunflashes are drawn after everything because they are near the camera.
{
SetCullMode(CullMode::Clockwise);
for (auto& mirror : view.Mirrors)
{
_currentMirror = &mirror;
DrawItems(view, RendererPass::Opaque);
DrawStatics(view, RendererPass::Opaque);
DrawScarabs(view, RendererPass::Opaque);
DrawGunShells(view, RendererPass::Opaque);
DrawBats(view, RendererPass::Opaque);
DrawEffects(view, RendererPass::Opaque);
DrawRats(view, RendererPass::Opaque);
DrawLocusts(view, RendererPass::Opaque);
DrawDebris(view, RendererPass::Opaque);
DrawSprites(view, RendererPass::Opaque);
_currentMirror = nullptr;
}
SetCullMode(CullMode::CounterClockwise);
}
// Draw additive faces.
DrawRooms(view, RendererPass::Additive);
DrawItems(view, RendererPass::Additive);
DrawStatics(view, RendererPass::Additive);
DrawSpiders(view, RendererPass::Additive);
DrawScarabs(view, RendererPass::Additive);
DrawBats(view, RendererPass::Additive);
DrawEffects(view, RendererPass::Additive);
DrawRats(view, RendererPass::Additive);
DrawLocusts(view, RendererPass::Additive);
DrawDebris(view, RendererPass::Additive);
DrawSprites(view, RendererPass::Additive);
DrawFishSwarm(view, RendererPass::Additive);
// Draw mirrored additive geometry only if Lara is inside a mirror room
if (view.Mirrors.size() > 0)
{
SetCullMode(CullMode::Clockwise);
for (auto& mirror : view.Mirrors)
{
_currentMirror = &mirror;
DrawItems(view, RendererPass::Additive);
DrawStatics(view, RendererPass::Additive);
DrawScarabs(view, RendererPass::Additive);
DrawBats(view, RendererPass::Additive);
DrawEffects(view, RendererPass::Additive);
DrawRats(view, RendererPass::Additive);
DrawLocusts(view, RendererPass::Additive);
DrawDebris(view, RendererPass::Additive);
DrawSprites(view, RendererPass::Additive);
_currentMirror = nullptr;
}
SetCullMode(CullMode::CounterClockwise);
}
// Collect all non-commutative transparent faces.
// NOTE: Sorted sprites already collected at beginning of frame.
DrawRooms(view, RendererPass::CollectTransparentFaces);
DrawItems(view, RendererPass::CollectTransparentFaces);
DrawStatics(view, RendererPass::CollectTransparentFaces);
DrawBats(view, RendererPass::CollectTransparentFaces);
DrawEffects(view, RendererPass::CollectTransparentFaces);
DrawRats(view, RendererPass::CollectTransparentFaces);
DrawLocusts(view, RendererPass::CollectTransparentFaces);
DrawFishSwarm(view, RendererPass::CollectTransparentFaces);
// Draw sorted faces.
DrawSortedFaces(view);
// Draw mirrored sorted faces only if Lara is inside a mirror room
if (view.Mirrors.size() > 0)
{
SetCullMode(CullMode::None);
for (auto& mirror : view.Mirrors)
{
_currentMirror = &mirror;
DrawSortedFaces(view);
_currentMirror = nullptr;
}
SetCullMode(CullMode::CounterClockwise);
}
// HACK: Gunflashes drawn after everything because they are very near the camera.
DrawGunFlashes(view);
DrawBaddyGunflashes( view);
// Draw mirrored gunflashes only if Lara is inside a mirror room
if (view.Mirrors.size() > 0)
{
SetCullMode(CullMode::Clockwise);
for (auto& mirror : view.Mirrors)
{
_currentMirror = &mirror;
DrawGunFlashes(view);
DrawBaddyGunflashes(view);
_currentMirror = nullptr;
}
SetCullMode(CullMode::CounterClockwise);
}
// Draw 3D debug lines and triangles. // Draw 3D debug lines and triangles.
DrawLines3D(view); DrawLines3D(view);
DrawTriangles3D(view); DrawTriangles3D(view);
@ -2409,7 +2298,7 @@ namespace TEN::Renderer
RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode); RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode);
} }
void Renderer::DrawItems(RenderView& view, RendererPass rendererPass) void Renderer::DrawItems(RenderView& view, RendererPass rendererPass, bool onlyPlayer)
{ {
unsigned int stride = sizeof(Vertex); unsigned int stride = sizeof(Vertex);
unsigned int offset = 0; unsigned int offset = 0;
@ -2433,20 +2322,22 @@ namespace TEN::Renderer
for (auto room : view.RoomsToDraw) for (auto room : view.RoomsToDraw)
{ {
if (_currentMirror != nullptr && _currentMirror->RealRoom != room->RoomNumber) if (IgnoreMirrorPassForRoom(room->RoomNumber))
continue; continue;
for (auto itemToDraw : room->ItemsToDraw) for (auto itemToDraw : room->ItemsToDraw)
{ {
if (_currentMirror != nullptr && if (_currentMirror != nullptr && (g_Level.Items[itemToDraw->ItemNumber].Flags & IFLAG_CLEAR_BODY))
(g_Level.Items[itemToDraw->ItemNumber].Flags & IFLAG_CLEAR_BODY)) continue;
if (onlyPlayer && itemToDraw->ObjectID != ID_LARA)
continue; continue;
switch (itemToDraw->ObjectID) switch (itemToDraw->ObjectID)
{ {
case ID_LARA: case ID_LARA:
DrawLara(view, rendererPass); DrawLara(view, rendererPass);
break; continue;
case ID_WATERFALL1: case ID_WATERFALL1:
case ID_WATERFALL2: case ID_WATERFALL2:
@ -2456,16 +2347,12 @@ namespace TEN::Renderer
case ID_WATERFALL6: case ID_WATERFALL6:
case ID_WATERFALLSS1: case ID_WATERFALLSS1:
case ID_WATERFALLSS2: case ID_WATERFALLSS2:
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
continue;
DrawWaterfalls(itemToDraw, view, 10, rendererPass); DrawWaterfalls(itemToDraw, view, 10, rendererPass);
continue; continue;
default: default:
if (_currentMirror != nullptr && !_currentMirror->ReflectMoveables)
continue;
DrawAnimatingItem(itemToDraw, view, rendererPass); DrawAnimatingItem(itemToDraw, view, rendererPass);
break; continue;
} }
} }
} }
@ -2485,9 +2372,6 @@ namespace TEN::Renderer
void Renderer::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass) void Renderer::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass)
{ {
if (_currentMirror != nullptr && item->RoomNumber != _currentMirror->RealRoom)
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.
@ -2531,19 +2415,14 @@ namespace TEN::Renderer
void Renderer::DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass) void Renderer::DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass)
{ {
if (_currentMirror != nullptr && item->RoomNumber != _currentMirror->RealRoom)
return;
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber]; ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
RendererRoom* room = &_rooms[item->RoomNumber]; RendererRoom* room = &_rooms[item->RoomNumber];
RendererObject& moveableObj = *_moveableObjects[item->ObjectID]; RendererObject& moveableObj = *_moveableObjects[item->ObjectID];
// Bind item main properties // Bind item main properties
_stItem.World = item->InterpolatedWorld; _stItem.World = item->InterpolatedWorld;
if (_currentMirror != nullptr) ReflectMatrixOptionally(_stItem.World);
{
_stItem.World = _stItem.World * _currentMirror->ReflectionMatrix;
}
_stItem.Color = item->Color; _stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight; _stItem.AmbientLight = item->AmbientLight;
memcpy(_stItem.BonesMatrices, item->InterpolatedAnimTransforms, sizeof(Matrix) * MAX_BONES); memcpy(_stItem.BonesMatrices, item->InterpolatedAnimTransforms, sizeof(Matrix) * MAX_BONES);
@ -2567,9 +2446,6 @@ namespace TEN::Renderer
{ {
if (_staticTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0) if (_staticTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0)
return; return;
if (_currentMirror != nullptr && !_currentMirror->ReflectStatics)
return;
if (rendererPass != RendererPass::CollectTransparentFaces) if (rendererPass != RendererPass::CollectTransparentFaces)
{ {
@ -2697,16 +2573,13 @@ namespace TEN::Renderer
RendererStatic* current = statics[s]; RendererStatic* current = statics[s];
RendererRoom* room = &_rooms[current->RoomNumber]; RendererRoom* room = &_rooms[current->RoomNumber];
if (_currentMirror != nullptr && current->RoomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(current->RoomNumber))
continue; continue;
Matrix world = current->World; Matrix world = current->World;
if (_currentMirror != nullptr) ReflectMatrixOptionally(world);
{
world = world * _currentMirror->ReflectionMatrix;
}
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].World = world;
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].Color = current->Color; _stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].Color = current->Color;
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].Ambient = room->AmbientLight; _stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].Ambient = room->AmbientLight;
_stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].LightMode = (int)refMesh->LightMode; _stInstancedStaticMeshBuffer.StaticMeshes[instancesCount].LightMode = (int)refMesh->LightMode;
@ -3460,20 +3333,20 @@ namespace TEN::Renderer
return true; return true;
} }
void Renderer::SortTransparentFaces(RenderView& view)
{
std::sort(
view.TransparentObjectsToDraw.begin(),
view.TransparentObjectsToDraw.end(),
[](RendererSortableObject& a, RendererSortableObject& b)
{
return (a.Distance > b.Distance);
}
);
}
void Renderer::DrawSortedFaces(RenderView& view) void Renderer::DrawSortedFaces(RenderView& view)
{ {
if (_currentMirror == nullptr)
{
std::sort(
view.TransparentObjectsToDraw.begin(),
view.TransparentObjectsToDraw.end(),
[](RendererSortableObject& a, RendererSortableObject& b)
{
return (a.Distance > b.Distance);
}
);
}
for (int i = 0; i < view.TransparentObjectsToDraw.size(); i++) for (int i = 0; i < view.TransparentObjectsToDraw.size(); i++)
{ {
RendererSortableObject* object = &view.TransparentObjectsToDraw[i]; RendererSortableObject* object = &view.TransparentObjectsToDraw[i];

View file

@ -1111,11 +1111,7 @@ namespace TEN::Renderer
worldMatrix = itemPtr->AnimTransforms[LM_LHAND] * itemPtr->World; worldMatrix = itemPtr->AnimTransforms[LM_LHAND] * itemPtr->World;
worldMatrix = tMatrix * worldMatrix; worldMatrix = tMatrix * worldMatrix;
worldMatrix = rotMatrix * worldMatrix; worldMatrix = rotMatrix * worldMatrix;
ReflectMatrixOptionally(worldMatrix);
if (_currentMirror != nullptr)
{
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
}
_stStatic.World = worldMatrix; _stStatic.World = worldMatrix;
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -1130,11 +1126,7 @@ namespace TEN::Renderer
worldMatrix = itemPtr->AnimTransforms[LM_RHAND] * itemPtr->World; worldMatrix = itemPtr->AnimTransforms[LM_RHAND] * itemPtr->World;
worldMatrix = tMatrix * worldMatrix; worldMatrix = tMatrix * worldMatrix;
worldMatrix = rotMatrix * worldMatrix; worldMatrix = rotMatrix * worldMatrix;
ReflectMatrixOptionally(worldMatrix);
if (_currentMirror != nullptr)
{
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
}
_stStatic.World = worldMatrix; _stStatic.World = worldMatrix;
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -1163,15 +1155,13 @@ namespace TEN::Renderer
for (auto* rRoomPtr : view.RoomsToDraw) for (auto* rRoomPtr : view.RoomsToDraw)
{ {
if (IgnoreMirrorPassForRoom(rRoomPtr->RoomNumber))
continue;
for (auto* rItemPtr : rRoomPtr->ItemsToDraw) for (auto* rItemPtr : rRoomPtr->ItemsToDraw)
{ {
auto& nativeItem = g_Level.Items[rItemPtr->ItemNumber]; auto& nativeItem = g_Level.Items[rItemPtr->ItemNumber];
if (_currentMirror != nullptr && nativeItem.RoomNumber != _currentMirror->RealRoom)
{
continue;
}
if (!nativeItem.IsCreature()) if (!nativeItem.IsCreature())
continue; continue;
@ -1217,10 +1207,7 @@ namespace TEN::Renderer
if (creature.MuzzleFlash[0].ApplyZRotation) if (creature.MuzzleFlash[0].ApplyZRotation)
worldMatrix = rotMatrixZ * worldMatrix; worldMatrix = rotMatrixZ * worldMatrix;
if (_currentMirror != nullptr) ReflectMatrixOptionally(worldMatrix);
{
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
}
_stStatic.World = worldMatrix; _stStatic.World = worldMatrix;
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -1262,10 +1249,7 @@ namespace TEN::Renderer
if (creature.MuzzleFlash[1].ApplyZRotation) if (creature.MuzzleFlash[1].ApplyZRotation)
worldMatrix = rotMatrixZ * worldMatrix; worldMatrix = rotMatrixZ * worldMatrix;
if (_currentMirror != nullptr) ReflectMatrixOptionally(worldMatrix);
{
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
}
_stStatic.World = worldMatrix; _stStatic.World = worldMatrix;
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
@ -1352,12 +1336,9 @@ namespace TEN::Renderer
const auto& room = _rooms[effect->RoomNumber]; const auto& room = _rooms[effect->RoomNumber];
Matrix world = effect->InterpolatedWorld; Matrix world = effect->InterpolatedWorld;
if (_currentMirror != nullptr) ReflectMatrixOptionally(world);
{
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;
@ -1400,11 +1381,11 @@ namespace TEN::Renderer
for (auto* roomPtr : view.RoomsToDraw) for (auto* roomPtr : view.RoomsToDraw)
{ {
if (IgnoreMirrorPassForRoom(roomPtr->RoomNumber))
continue;
for (auto* effectPtr : roomPtr->EffectsToDraw) for (auto* effectPtr : roomPtr->EffectsToDraw)
{ {
if (_currentMirror != nullptr && effectPtr->RoomNumber != _currentMirror->RealRoom)
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];
@ -1421,7 +1402,7 @@ namespace TEN::Renderer
{ {
if (deb.active) if (deb.active)
{ {
if (_currentMirror != nullptr && deb.roomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(deb.roomNumber))
continue; continue;
activeDebrisExist = true; activeDebrisExist = true;
@ -1442,7 +1423,7 @@ namespace TEN::Renderer
{ {
if (deb.active) if (deb.active)
{ {
if (_currentMirror != nullptr && deb.roomNumber != _currentMirror->RealRoom) if (IgnoreMirrorPassForRoom(deb.roomNumber))
continue; continue;
if (!SetupBlendModeAndAlphaTest(deb.mesh.blendMode, rendererPass, 0)) if (!SetupBlendModeAndAlphaTest(deb.mesh.blendMode, rendererPass, 0))
@ -1465,10 +1446,7 @@ namespace TEN::Renderer
_cbStatic.UpdateData(_stStatic, _context.Get()); _cbStatic.UpdateData(_stStatic, _context.Get());
auto matrix = Matrix::Lerp(deb.PrevTransform, deb.Transform, GetInterpolationFactor()); auto matrix = Matrix::Lerp(deb.PrevTransform, deb.Transform, GetInterpolationFactor());
if (_currentMirror != nullptr) ReflectMatrixOptionally(matrix);
{
matrix = matrix * _currentMirror->ReflectionMatrix;
}
Vertex vtx0; Vertex vtx0;
vtx0.Position = Vector3::Transform(deb.mesh.Positions[0], matrix); vtx0.Position = Vector3::Transform(deb.mesh.Positions[0], matrix);
@ -1503,7 +1481,6 @@ namespace TEN::Renderer
SetBlendMode(BlendMode::Opaque, true); SetBlendMode(BlendMode::Opaque, true);
SetDepthState(DepthState::Write, true); SetDepthState(DepthState::Write, true);
SetCullMode(_currentMirror != nullptr ? CullMode::Clockwise : CullMode::CounterClockwise, true);
} }
} }

View file

@ -226,6 +226,7 @@ enum class RendererPass
CollectTransparentFaces, CollectTransparentFaces,
Additive, Additive,
GBuffer, GBuffer,
GunFlashes,
RoomAmbient RoomAmbient
}; };

View file

@ -39,7 +39,6 @@ namespace TEN::Renderer
auto& rendererMirror = renderView.Mirrors.emplace_back(); auto& rendererMirror = renderView.Mirrors.emplace_back();
rendererMirror.RealRoom = mirror.RealRoom; rendererMirror.RealRoom = mirror.RealRoom;
rendererMirror.VirtualRoom = mirror.VirtualRoom;
rendererMirror.ReflectionMatrix = mirror.ReflectionMatrix; rendererMirror.ReflectionMatrix = mirror.ReflectionMatrix;
rendererMirror.ReflectLara = mirror.ReflectLara; rendererMirror.ReflectLara = mirror.ReflectLara;
rendererMirror.ReflectMoveables = mirror.ReflectMoveables; rendererMirror.ReflectMoveables = mirror.ReflectMoveables;

View file

@ -280,9 +280,6 @@ void Renderer::UpdateLaraAnimations(bool force)
void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass) void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass)
{ {
if (_currentMirror != nullptr && LaraItem->RoomNumber != _currentMirror->RealRoom)
return;
// Don't draw player if using optics. // Don't draw player if using optics.
if (Lara.Control.Look.OpticRange != 0 || SpotcamDontDrawLara) if (Lara.Control.Look.OpticRange != 0 || SpotcamDontDrawLara)
return; return;
@ -309,10 +306,7 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa
RendererRoom* room = &_rooms[LaraItem->RoomNumber]; RendererRoom* room = &_rooms[LaraItem->RoomNumber];
_stItem.World = item->InterpolatedWorld; _stItem.World = item->InterpolatedWorld;
if (_currentMirror != nullptr) ReflectMatrixOptionally(_stItem.World);
{
_stItem.World = _stItem.World * _currentMirror->ReflectionMatrix;
}
_stItem.Color = item->Color; _stItem.Color = item->Color;
_stItem.AmbientLight = item->AmbientLight; _stItem.AmbientLight = item->AmbientLight;
@ -355,11 +349,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
_stItem.World = Matrix::Identity; _stItem.World = Matrix::Identity;
_stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimTransforms[HairUnit::GetRootMeshID(i)] * itemToDraw->InterpolatedWorld; _stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimTransforms[HairUnit::GetRootMeshID(i)] * itemToDraw->InterpolatedWorld;
ReflectMatrixOptionally(_stItem.BonesMatrices[0]);
if (_currentMirror != nullptr)
{
_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++)
{ {
@ -370,10 +360,7 @@ 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 (_currentMirror != nullptr) ReflectMatrixOptionally(worldMatrix);
{
worldMatrix = worldMatrix * _currentMirror->ReflectionMatrix;
}
_stItem.BonesMatrices[i + 1] = worldMatrix; _stItem.BonesMatrices[i + 1] = worldMatrix;
_stItem.BoneLightModes[i] = (int)LightMode::Dynamic; _stItem.BoneLightModes[i] = (int)LightMode::Dynamic;

View file

@ -9,7 +9,6 @@ namespace TEN::Renderer::Structures
struct RendererMirror struct RendererMirror
{ {
short RealRoom; short RealRoom;
short VirtualRoom;
Plane Plane; Plane Plane;
Matrix ReflectionMatrix; Matrix ReflectionMatrix;
bool ReflectLara; bool ReflectLara;

View file

@ -1530,7 +1530,6 @@ void LoadMirrors()
auto& mirror = g_Level.Mirrors.emplace_back(); auto& mirror = g_Level.Mirrors.emplace_back();
mirror.RealRoom = ReadInt16(); mirror.RealRoom = ReadInt16();
mirror.VirtualRoom = ReadInt16();
mirror.MirrorPlane.x = ReadFloat(); mirror.MirrorPlane.x = ReadFloat();
mirror.MirrorPlane.y = ReadFloat(); mirror.MirrorPlane.y = ReadFloat();
mirror.MirrorPlane.z = ReadFloat(); mirror.MirrorPlane.z = ReadFloat();

View file

@ -88,7 +88,6 @@ struct MESH
struct MirrorInfo struct MirrorInfo
{ {
short RealRoom; short RealRoom;
short VirtualRoom;
Vector4 MirrorPlane; Vector4 MirrorPlane;
Matrix ReflectionMatrix; Matrix ReflectionMatrix;
bool ReflectLara; bool ReflectLara;