diff --git a/Documentation/doc/1 modules/Effects.html b/Documentation/doc/1 modules/Effects.html index c7672b1db..d0e1a7f99 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -145,7 +145,7 @@ GetWind() - Get the current wind for the current frame. + Get the wind vector for the current game frame. @@ -508,8 +508,8 @@ GetWind()
- Get the current wind for the current frame. - This represents the 3D displacement applied by the engine on things like particles affected by wind. + Get the wind vector for the current game frame. + This represents the 3D displacement applied by the engine on things like particles affected by wind.() @@ -518,7 +518,7 @@
    Vec3 - The wind. + Wind vector.
diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 54b4f76af..823694a4e 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -383,6 +383,14 @@ pickups, and Lara herself (see also Disable the item, as if an antitrigger for it had been stepped on (i.e. + Moveable:GetCollidable() + Get the item's collision state. + + + Moveable:SetCollidable(collidable) + Set the item's collision. + + Moveable:MakeInvisible() Make the item invisible. @@ -1967,6 +1975,49 @@ sas:SetPosition(newPos, false) +
+
+ + Moveable:GetCollidable() +
+
+ Get the item's collision state. + + + + +

Returns:

+
    + + bool + item's collision state +
+ + + + +
+
+ + Moveable:SetCollidable(collidable) +
+
+ Set the item's collision. + + + +

Parameters:

+ + + + + +
diff --git a/TombEngine/Renderer/RenderView.cpp b/TombEngine/Renderer/RenderView.cpp index 1f02db401..10dd2c347 100644 --- a/TombEngine/Renderer/RenderView.cpp +++ b/TombEngine/Renderer/RenderView.cpp @@ -53,6 +53,7 @@ namespace TEN::Renderer FogBulbsToDraw.clear(); LensFlaresToDraw.clear(); TransparentObjectsToDraw.clear(); + Mirrors.clear(); } RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h) diff --git a/TombEngine/Renderer/RenderView.h b/TombEngine/Renderer/RenderView.h index b028b4788..740a9714c 100644 --- a/TombEngine/Renderer/RenderView.h +++ b/TombEngine/Renderer/RenderView.h @@ -15,6 +15,7 @@ #include "Renderer/Structures/RendererSortableObject.h" #include "Renderer/Structures/RendererSpriteToDraw.h" #include "Renderer/Structures/RendererLensFlare.h" +#include "Renderer/Structures/RendererMirror.h" namespace TEN::Renderer { @@ -54,6 +55,8 @@ namespace TEN::Renderer std::vector TransparentObjectsToDraw = {}; std::vector LensFlaresToDraw = {}; + std::vector Mirrors = {}; + RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h); RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov); diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index 2aac47518..c1d1de7ac 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -380,6 +380,7 @@ namespace TEN::Renderer ComPtr _psPostProcessExclusion; ComPtr _psPostProcessFinalPass; ComPtr _psPostProcessLensFlare; + ComPtr _psDownsampleDepthBuffer; bool _doingFullscreenPass = false; @@ -454,12 +455,12 @@ namespace TEN::Renderer void PrepareSingleLaserBeam(RenderView& view); void DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget); void DrawRooms(RenderView& view, RendererPass rendererPass); - void DrawItems(RenderView& view, RendererPass rendererPass); - void DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass); - void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass); - void DrawBaddyGunflashes(RenderView& view); - void DrawStatics(RenderView& view, RendererPass rendererPass); - void DrawLara(RenderView& view, RendererPass rendererPass); + void DrawItems(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawAnimatingItem(RendererItem* item, RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawWaterfalls(RendererItem* item, RendererMirror* mirror, RenderView& view, int fps, RendererPass rendererPass); + void DrawBaddyGunflashes(RendererMirror* mirror, RenderView& view); + void DrawStatics(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawLara(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); void PrepareFires(RenderView& view); void PrepareParticles(RenderView& view); void PrepareSmokes(RenderView& view); @@ -472,9 +473,9 @@ namespace TEN::Renderer void DrawEffects(RenderView& view, RendererPass rendererPass); void DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass); void PrepareSplashes(RenderView& view); - void DrawSprites(RenderView& view, RendererPass rendererPass); + void DrawSprites(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); void DrawDisplaySprites(RenderView& view); - void DrawSortedFaces(RenderView& view); + void DrawSortedFaces(RendererMirror* mirror, RenderView& view); void DrawSingleSprite(RendererSortableObject* object, RendererObjectType lastObjectType, RenderView& view); void DrawRoomSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view); void DrawItemSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view); @@ -487,13 +488,13 @@ namespace TEN::Renderer void DrawOverlays(RenderView& view); void PrepareRopes(RenderView& view); void DrawFishSwarm(RenderView& view, RendererPass rendererPass); - void DrawBats(RenderView& view, RendererPass rendererPass); - void DrawRats(RenderView& view, RendererPass rendererPass); - void DrawScarabs(RenderView& view, RendererPass rendererPass); + void DrawBats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawRats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawScarabs(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); void DrawSpiders(RenderView& view, RendererPass rendererPass); - bool DrawGunFlashes(RenderView& view); - void DrawGunShells(RenderView& view, RendererPass rendererPass); - void DrawLocusts(RenderView& view, RendererPass rendererPass); + bool DrawGunFlashes(RendererMirror* mirror, RenderView& view); + void DrawGunShells(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawLocusts(RendererMirror* mirror, RenderView& view, RendererPass rendererPass); void DrawStatistics(); void DrawExamines(); void DrawDiary(); @@ -508,9 +509,9 @@ namespace TEN::Renderer void PrepareSmokeParticles(RenderView& view); void PrepareSparkParticles(RenderView& view); void PrepareExplosionParticles(RenderView& view); - void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass); - void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass); - void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass); + void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass); + void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass); void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RenderView& view, RendererPass rendererPass); void PrepareSimpleParticles(RenderView& view); void PrepareStreamers(RenderView& view); @@ -561,7 +562,7 @@ namespace TEN::Renderer const Vector4& color0, const Vector4& color1, const Vector4& color2, const Vector4& color3, BlendMode blendMode, RenderView& view, SpriteRenderType renderType = SpriteRenderType::Default); - Matrix GetWorldMatrixForSprite(RendererSpriteToDraw* spr, RenderView& view); + Matrix GetWorldMatrixForSprite(RendererSpriteToDraw* spr, RendererMirror* mirror, RenderView& view); RendererObject& GetRendererObject(GAME_OBJECT_ID id); RendererMesh* GetMesh(int meshIndex); Texture2D CreateDefaultNormalTexture(); diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 0086e1fc2..3d04ed099 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -245,14 +245,14 @@ namespace TEN::Renderer { RendererRoom& room = _rooms[item->RoomNumber]; - DrawLaraHolsters(item, &room, renderView, RendererPass::ShadowMap); - DrawLaraJoints(item, &room, renderView, RendererPass::ShadowMap); - DrawLaraHair(item, &room, renderView, RendererPass::ShadowMap); + DrawLaraHolsters(item, &room, nullptr, renderView, RendererPass::ShadowMap); + DrawLaraJoints(item, &room, nullptr, renderView, RendererPass::ShadowMap); + DrawLaraHair(item, &room, nullptr, renderView, RendererPass::ShadowMap); } } } - void Renderer::DrawGunShells(RenderView& view, RendererPass rendererPass) + void Renderer::DrawGunShells(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { auto& room = _rooms[LaraItem->RoomNumber]; auto* item = &_items[LaraItem->Index]; @@ -282,6 +282,11 @@ namespace TEN::Renderer worldMatrix = Matrix::Lerp(prevWorldMatrix, worldMatrix, _interpolationFactor); + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } + _stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].World = worldMatrix; _stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Ambient = room.AmbientLight; _stInstancedStaticMeshBuffer.StaticMeshes[gunShellCount].Color = room.AmbientLight; @@ -476,7 +481,7 @@ namespace TEN::Renderer }*/ } - void Renderer::DrawRats(RenderView& view, RendererPass rendererPass) + void Renderer::DrawRats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (!Objects[ID_RATS_EMITTER].loaded) { @@ -567,7 +572,12 @@ namespace TEN::Renderer { RendererMesh* mesh = GetMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8)); - _stStatic.World = rat->Transform; + Matrix world = rat->Transform; + if (mirror != nullptr) + { + world = world * mirror->ReflectionMatrix; + } + _stStatic.World = world; _stStatic.Color = Vector4::One; _stStatic.AmbientLight = _rooms[rat->RoomNumber].AmbientLight; @@ -722,7 +732,7 @@ namespace TEN::Renderer } } - void Renderer::DrawBats(RenderView& view, RendererPass rendererPass) + void Renderer::DrawBats(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (!Objects[ID_BATS_EMITTER].loaded) return; @@ -775,7 +785,13 @@ namespace TEN::Renderer auto transformMatrix = Matrix::Lerp(bat.PrevTransform, bat.Transform, _interpolationFactor); - _stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = transformMatrix; + Matrix world = transformMatrix; + if (mirror != nullptr) + { + world = world * mirror->ReflectionMatrix; + } + + _stInstancedStaticMeshBuffer.StaticMeshes[batCount].World = world; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].Ambient = room.AmbientLight; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].Color = Vector4::One; _stInstancedStaticMeshBuffer.StaticMeshes[batCount].LightMode = (int)mesh.LightMode; @@ -834,7 +850,7 @@ namespace TEN::Renderer } } - void Renderer::DrawScarabs(RenderView& view, RendererPass rendererPass) + void Renderer::DrawScarabs(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (!Objects[ID_LITTLE_BEETLE].loaded) return; @@ -888,7 +904,13 @@ namespace TEN::Renderer auto transformMatrix = Matrix::Lerp(beetle.PrevTransform, beetle.Transform, _interpolationFactor); - _stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = transformMatrix; + Matrix world = transformMatrix; + if (mirror != nullptr) + { + world = world * mirror->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; @@ -953,7 +975,7 @@ namespace TEN::Renderer } } - void Renderer::DrawLocusts(RenderView& view, RendererPass rendererPass) + void Renderer::DrawLocusts(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (!Objects[ID_LOCUSTS].loaded) return; @@ -1039,7 +1061,12 @@ namespace TEN::Renderer auto& mesh = *GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust.counter & 3)); - _stStatic.World = Matrix::Lerp(locust.PrevTransform, locust.Transform, _interpolationFactor); + Matrix world = Matrix::Lerp(locust.PrevTransform, locust.Transform, _interpolationFactor); + if (mirror != nullptr) + { + world = world * mirror->ReflectionMatrix; + } + _stStatic.World = world; _stStatic.Color = Vector4::One; _stStatic.AmbientLight = _rooms[locust.roomNumber].AmbientLight; _cbStatic.UpdateData(_stStatic, _context.Get()); @@ -1724,7 +1751,7 @@ namespace TEN::Renderer cameraConstantBuffer.FogMinDistance = level.GetFogMinDistance(); cameraConstantBuffer.FogMaxDistance = level.GetFogMaxDistance(); } - else + else { cameraConstantBuffer.FogMaxDistance = 0; cameraConstantBuffer.FogColor = Vector4::Zero; @@ -1743,10 +1770,10 @@ namespace TEN::Renderer cameraConstantBuffer.FogBulbs[i].Color = view.FogBulbsToDraw[i].Color; cameraConstantBuffer.FogBulbs[i].SquaredCameraToFogBulbDistance = SQUARE(view.FogBulbsToDraw[i].Distance); cameraConstantBuffer.FogBulbs[i].FogBulbToCameraVector = view.FogBulbsToDraw[i].FogBulbToCameraVector; - } + } _cbCameraMatrices.UpdateData(cameraConstantBuffer, _context.Get()); - + ID3D11RenderTargetView* pRenderViewPtrs[2]; // Bind main render target. @@ -1754,7 +1781,7 @@ namespace TEN::Renderer // Draw horizon and sky. DrawHorizonAndSky(view, _renderTarget.DepthStencilView.Get()); - + // Build G-Buffer (normals + depth). _context->ClearRenderTargetView(_normalsRenderTarget.RenderTargetView.Get(), Colors::Black); _context->ClearRenderTargetView(_depthRenderTarget.RenderTargetView.Get(), Colors::White); @@ -1764,15 +1791,18 @@ namespace TEN::Renderer _context->OMSetRenderTargets(2, &pRenderViewPtrs[0], _renderTarget.DepthStencilView.Get()); DrawRooms(view, RendererPass::GBuffer); - DrawItems(view, RendererPass::GBuffer); - DrawStatics(view, RendererPass::GBuffer); + DrawItems(nullptr, view, RendererPass::GBuffer); + DrawStatics(nullptr, view, RendererPass::GBuffer); DrawSpiders(view, RendererPass::GBuffer); - DrawScarabs(view, RendererPass::GBuffer); - DrawGunShells(view, RendererPass::GBuffer); - DrawBats(view, RendererPass::GBuffer); + DrawScarabs(nullptr, view, RendererPass::GBuffer); + DrawGunShells(nullptr, view, RendererPass::GBuffer); + DrawBats(nullptr, view, RendererPass::GBuffer); DrawEffects(view, RendererPass::GBuffer); - DrawRats(view, RendererPass::GBuffer); - DrawLocusts(view, RendererPass::GBuffer); + DrawRats(nullptr, view, RendererPass::GBuffer); + DrawLocusts(nullptr, view, RendererPass::GBuffer); + + // Downsample G-Buffer for making faster soft particles and SSAO + DownsampleGBuffer(); // Calculate ambient occlusion. if (g_Configuration.EnableAmbientOcclusion) @@ -1785,62 +1815,128 @@ namespace TEN::Renderer _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); + _context->RSSetViewports(1, &view.Viewport); + ResetScissor(); + SetBlendMode(BlendMode::Opaque); SetCullMode(CullMode::CounterClockwise); SetDepthState(DepthState::Write); - _context->RSSetViewports(1, &view.Viewport); - ResetScissor(); - // 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()); - + // Draw opaque, alpha test, and fast alpha blend faces. DrawRooms(view, RendererPass::Opaque); - DrawItems(view, RendererPass::Opaque); - DrawStatics(view, RendererPass::Opaque); + DrawItems(nullptr, view, RendererPass::Opaque); + DrawStatics(nullptr, view, RendererPass::Opaque); DrawSpiders(view, RendererPass::Opaque); - DrawScarabs(view, RendererPass::Opaque); - DrawGunShells(view, RendererPass::Opaque); - DrawBats(view, RendererPass::Opaque); + DrawScarabs(nullptr, view, RendererPass::Opaque); + DrawGunShells(nullptr, view, RendererPass::Opaque); + DrawBats(nullptr, view, RendererPass::Opaque); DrawEffects(view, RendererPass::Opaque); - DrawRats(view, RendererPass::Opaque); - DrawLocusts(view, RendererPass::Opaque); + DrawRats(nullptr, view, RendererPass::Opaque); + DrawLocusts(nullptr, view, RendererPass::Opaque); DrawDebris(view, RendererPass::Opaque); - DrawSprites(view, RendererPass::Opaque); + DrawSprites(nullptr, view, RendererPass::Opaque); DrawFishSwarm(view, RendererPass::Opaque); + // Draw mirrored opaque geometry only if Lara is inside a mirror room + if (view.Mirrors.size() > 0) + { + SetCullMode(CullMode::Clockwise); + + for (auto& mirror : view.Mirrors) + { + DrawItems(&mirror, view, RendererPass::Opaque); + DrawStatics(&mirror, view, RendererPass::Opaque); + DrawScarabs(&mirror, view, RendererPass::Opaque); + DrawGunShells(&mirror, view, RendererPass::Opaque); + DrawBats(&mirror, view, RendererPass::Opaque); + DrawRats(&mirror, view, RendererPass::Opaque); + DrawLocusts(&mirror, view, RendererPass::Opaque); + DrawSprites(&mirror, view, RendererPass::Opaque); + } + + SetCullMode(CullMode::CounterClockwise); + } + // Draw additive faces. DrawRooms(view, RendererPass::Additive); - DrawItems(view, RendererPass::Additive); - DrawStatics(view, RendererPass::Additive); + DrawItems(nullptr, view, RendererPass::Additive); + DrawStatics(nullptr, view, RendererPass::Additive); DrawSpiders(view, RendererPass::Additive); - DrawScarabs(view, RendererPass::Additive); - DrawBats(view, RendererPass::Additive); + DrawScarabs(nullptr, view, RendererPass::Additive); + DrawBats(nullptr, view, RendererPass::Additive); DrawEffects(view, RendererPass::Additive); - DrawRats(view, RendererPass::Additive); - DrawLocusts(view, RendererPass::Additive); + DrawRats(nullptr, view, RendererPass::Additive); + DrawLocusts(nullptr, view, RendererPass::Additive); DrawDebris(view, RendererPass::Additive); - DrawSprites(view, RendererPass::Additive); + DrawSprites(nullptr, 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) + { + DrawItems(&mirror, view, RendererPass::Additive); + DrawStatics(&mirror, view, RendererPass::Additive); + DrawScarabs(&mirror, view, RendererPass::Additive); + DrawBats(&mirror, view, RendererPass::Additive); + DrawRats(&mirror, view, RendererPass::Additive); + DrawLocusts(&mirror, view, RendererPass::Additive); + DrawSprites(&mirror, view, RendererPass::Additive); + } + + 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); + DrawItems(nullptr, view, RendererPass::CollectTransparentFaces); + DrawStatics(nullptr, view, RendererPass::CollectTransparentFaces); + DrawBats(nullptr, view, RendererPass::CollectTransparentFaces); DrawEffects(view, RendererPass::CollectTransparentFaces); - DrawRats(view, RendererPass::CollectTransparentFaces); - DrawLocusts(view, RendererPass::CollectTransparentFaces); + DrawRats(nullptr, view, RendererPass::CollectTransparentFaces); + DrawLocusts(nullptr, view, RendererPass::CollectTransparentFaces); DrawFishSwarm(view, RendererPass::CollectTransparentFaces); // Draw sorted faces. - DrawSortedFaces(view); + DrawSortedFaces(nullptr, 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) + { + DrawSortedFaces(&mirror, view); + } + + SetCullMode(CullMode::CounterClockwise); + } // HACK: Gunflashes drawn after everything because they are very near the camera. - DrawGunFlashes(view); - DrawBaddyGunflashes(view); + DrawGunFlashes(nullptr, view); + DrawBaddyGunflashes(nullptr, 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) + { + DrawGunFlashes(&mirror, view); + DrawBaddyGunflashes(&mirror, view); + } + + SetCullMode(CullMode::CounterClockwise); + } // Draw 3D debug lines and triangles. DrawLines3D(view); @@ -2160,7 +2256,7 @@ namespace TEN::Renderer _graphicsSettingsChanged = false; } - void Renderer::DrawItems(RenderView& view, RendererPass rendererPass) + void Renderer::DrawItems(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { unsigned int stride = sizeof(Vertex); unsigned int offset = 0; @@ -2189,7 +2285,7 @@ namespace TEN::Renderer switch (itemToDraw->ObjectID) { case ID_LARA: - DrawLara(view, rendererPass); + DrawLara(mirror, view, rendererPass); break; case ID_WATERFALL1: @@ -2200,11 +2296,11 @@ namespace TEN::Renderer case ID_WATERFALL6: case ID_WATERFALLSS1: case ID_WATERFALLSS2: - DrawWaterfalls(itemToDraw, view, 10, rendererPass); + DrawWaterfalls(itemToDraw, mirror, view, 10, rendererPass); continue; default: - DrawAnimatingItem(itemToDraw, view, rendererPass); + DrawAnimatingItem(itemToDraw, mirror, view, rendererPass); break; } } @@ -2223,8 +2319,13 @@ namespace TEN::Renderer } } - void Renderer::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass) + void Renderer::DrawWaterfalls(RendererItem* item, RendererMirror* mirror, RenderView& view, int fps, RendererPass rendererPass) { + if (mirror != nullptr && item->RoomNumber != mirror->RoomNumber) + { + return; + } + // 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. @@ -2259,21 +2360,30 @@ namespace TEN::Renderer _cbAnimated.UpdateData(_stAnimated, _context.Get()); - DrawAnimatingItem(item, view, rendererPass); + DrawAnimatingItem(item, mirror, view, rendererPass); // Reset animated buffer after rendering just in case _stAnimated.Fps = _stAnimated.NumFrames = _stAnimated.Type = 0; _cbAnimated.UpdateData(_stAnimated, _context.Get()); } - void Renderer::DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass) + void Renderer::DrawAnimatingItem(RendererItem* item, RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { + if (mirror != nullptr && item->RoomNumber != mirror->RoomNumber) + { + return; + } + ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber]; RendererRoom* room = &_rooms[item->RoomNumber]; RendererObject& moveableObj = *_moveableObjects[item->ObjectID]; // Bind item main properties _stItem.World = item->InterpolatedWorld; + if (mirror != nullptr) + { + _stItem.World = _stItem.World * mirror->ReflectionMatrix; + } _stItem.Color = item->Color; _stItem.AmbientLight = item->AmbientLight; memcpy(_stItem.BonesMatrices, item->InterpolatedAnimTransforms, sizeof(Matrix) * MAX_BONES); @@ -2293,7 +2403,7 @@ namespace TEN::Renderer } } - void Renderer::DrawStatics(RenderView& view, RendererPass rendererPass) + void Renderer::DrawStatics(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (_staticTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0) { @@ -2427,6 +2537,11 @@ namespace TEN::Renderer RendererStatic* current = statics[s]; RendererRoom* room = &_rooms[current->RoomNumber]; + if (mirror != nullptr && current->RoomNumber != mirror->RoomNumber) + { + continue; + } + _stInstancedStaticMeshBuffer.StaticMeshes[k].World = current->World; _stInstancedStaticMeshBuffer.StaticMeshes[k].Color = current->Color; _stInstancedStaticMeshBuffer.StaticMeshes[k].Ambient = room->AmbientLight; @@ -2440,35 +2555,38 @@ namespace TEN::Renderer k++; } - _cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get()); - baseStaticIndex += bucketSize; - for (auto& bucket : refMesh->Buckets) + if (k > 0) { - if (bucket.NumVertices == 0) - { - continue; - } + _cbInstancedStaticMeshBuffer.UpdateData(_stInstancedStaticMeshBuffer, _context.Get()); - int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1; - - for (int p = 0; p < passes; p++) + for (auto& bucket : refMesh->Buckets) { - if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p)) + if (bucket.NumVertices == 0) { continue; } - BindTexture(TextureRegister::ColorMap, - &std::get<0>(_staticTextures[bucket.Texture]), - SamplerStateRegister::AnisotropicClamp); - BindTexture(TextureRegister::NormalMap, - &std::get<1>(_staticTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp); + int passes = rendererPass == RendererPass::Opaque && bucket.BlendMode == BlendMode::AlphaTest ? 2 : 1; - DrawIndexedInstancedTriangles(bucket.NumIndices, instanceCount, bucket.StartIndex, 0); + for (int p = 0; p < passes; p++) + { + if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p)) + { + continue; + } - _numInstancedStaticsDrawCalls++; + BindTexture(TextureRegister::ColorMap, + &std::get<0>(_staticTextures[bucket.Texture]), + SamplerStateRegister::AnisotropicClamp); + BindTexture(TextureRegister::NormalMap, + &std::get<1>(_staticTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp); + + DrawIndexedInstancedTriangles(bucket.NumIndices, instanceCount, bucket.StartIndex, 0); + + _numInstancedStaticsDrawCalls++; + } } } } @@ -2821,7 +2939,7 @@ namespace TEN::Renderer rDrawSprite.Width = STAR_SIZE * star.Scale; rDrawSprite.Height = STAR_SIZE * star.Scale; - _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, renderView); + _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, nullptr, renderView); _stInstancedSpriteBuffer.Sprites[i].Color = Vector4( star.Color.x, star.Color.y, @@ -2884,7 +3002,7 @@ namespace TEN::Renderer rDrawSprite.Height = 192; rDrawSprite.ConstrainAxis = meteor.Direction; - _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, renderView); + _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, nullptr, renderView); _stInstancedSpriteBuffer.Sprites[i].Color = Vector4( meteor.Color.x, meteor.Color.y, @@ -2989,7 +3107,7 @@ namespace TEN::Renderer rDrawSprite.Width = SUN_SIZE; rDrawSprite.Height = SUN_SIZE; - _stInstancedSpriteBuffer.Sprites[0].World = GetWorldMatrixForSprite(&rDrawSprite, renderView); + _stInstancedSpriteBuffer.Sprites[0].World = GetWorldMatrixForSprite(&rDrawSprite, nullptr, renderView); _stInstancedSpriteBuffer.Sprites[0].Color = Vector4::One; _stInstancedSpriteBuffer.Sprites[0].IsBillboard = 1; _stInstancedSpriteBuffer.Sprites[0].IsSoftParticle = 0; @@ -3177,7 +3295,7 @@ namespace TEN::Renderer return true; } - void Renderer::DrawSortedFaces(RenderView& view) + void Renderer::DrawSortedFaces(RendererMirror* mirror, RenderView& view) { std::sort( view.TransparentObjectsToDraw.begin(), @@ -3196,6 +3314,11 @@ namespace TEN::Renderer _sortedPolygonsVertices.clear(); _sortedPolygonsIndices.clear(); + if (mirror != nullptr && object->ObjectType != RendererObjectType::Sprite) + { + continue; + } + if (object->ObjectType == RendererObjectType::Room) { while (i < view.TransparentObjectsToDraw.size() && @@ -3346,23 +3469,25 @@ namespace TEN::Renderer uv2 = spr->Sprite->UV[2]; uv3 = spr->Sprite->UV[3]; + Matrix world = GetWorldMatrixForSprite(currentObject->Sprite, mirror, view); + Vertex v0; - v0.Position = Vector3::Transform(p0t, currentObject->World); + v0.Position = Vector3::Transform(p0t, world); v0.UV = uv0; v0.Color = spr->c1; Vertex v1; - v1.Position = Vector3::Transform(p1t, currentObject->World); + v1.Position = Vector3::Transform(p1t, world); v1.UV = uv1; v1.Color = spr->c2; Vertex v2; - v2.Position = Vector3::Transform(p2t, currentObject->World); + v2.Position = Vector3::Transform(p2t, world); v2.UV = uv2; v2.Color = spr->c3; Vertex v3; - v3.Position = Vector3::Transform(p3t, currentObject->World); + v3.Position = Vector3::Transform(p3t, world); v3.UV = uv3; v3.Color = spr->c4; @@ -3609,8 +3734,8 @@ namespace TEN::Renderer D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = _screenWidth; - viewport.Height = _screenHeight; + viewport.Width = _screenWidth/2; + viewport.Height = _screenHeight / 2; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; @@ -3685,4 +3810,58 @@ namespace TEN::Renderer _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane; _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane; } + + void Renderer::DownsampleGBuffer() + { + // Downsample depth + _doingFullscreenPass = true; + + SetBlendMode(BlendMode::Opaque); + SetCullMode(CullMode::CounterClockwise); + SetDepthState(DepthState::Write); + + // Common vertex shader to all full screen effects + _context->VSSetShader(_vsPostProcess.Get(), nullptr, 0); + + _context->PSSetShader(_psDownsampleDepthBuffer.Get(), nullptr, 0); + _context->ClearRenderTargetView(_downsampledDepthRenderTarget.RenderTargetView.Get(), Colors::White); + _context->OMSetRenderTargets(1, _downsampledDepthRenderTarget.RenderTargetView.GetAddressOf(), nullptr); + + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = _screenWidth / 2; + viewport.Height = _screenHeight / 2; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + _context->RSSetViewports(1, &viewport); + + D3D11_RECT rects[1]; + rects[0].left = 0; + rects[0].right = viewport.Width; + rects[0].top = 0; + rects[0].bottom = viewport.Height; + + _context->RSSetScissorRects(1, rects); + + _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + _context->IASetInputLayout(_fullscreenTriangleInputLayout.Get()); + + UINT stride = sizeof(PostProcessVertex); + UINT offset = 0; + + _context->IASetVertexBuffers(0, 1, _fullscreenTriangleVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); + + BindRenderTargetAsTexture(static_cast(0), &_depthRenderTarget, SamplerStateRegister::PointWrap); + + _stPostProcessBuffer.ViewportWidth = viewport.Width; + _stPostProcessBuffer.ViewportHeight = viewport.Height; + memcpy(_stPostProcessBuffer.SSAOKernel, _SSAOKernel.data(), 16 * _SSAOKernel.size()); + _cbPostProcessBuffer.UpdateData(_stPostProcessBuffer, _context.Get()); + + DrawTriangles(3, 0); + + _doingFullscreenPass = false; + } } diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index bd031cee0..d12697193 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -1009,7 +1009,7 @@ namespace TEN::Renderer } } - bool Renderer::DrawGunFlashes(RenderView& view) + bool Renderer::DrawGunFlashes(RendererMirror* mirror, RenderView& view) { _context->VSSetShader(_vsStatics.Get(), nullptr, 0); _context->PSSetShader(_psStatics.Get(), nullptr, 0); @@ -1106,6 +1106,11 @@ namespace TEN::Renderer worldMatrix = tMatrix * worldMatrix; worldMatrix = rotMatrix * worldMatrix; + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } + _stStatic.World = worldMatrix; _cbStatic.UpdateData(_stStatic, _context.Get()); @@ -1120,6 +1125,11 @@ namespace TEN::Renderer worldMatrix = tMatrix * worldMatrix; worldMatrix = rotMatrix * worldMatrix; + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } + _stStatic.World = worldMatrix; _cbStatic.UpdateData(_stStatic, _context.Get()); @@ -1134,7 +1144,7 @@ namespace TEN::Renderer return true; } - void Renderer::DrawBaddyGunflashes(RenderView& view) + void Renderer::DrawBaddyGunflashes(RendererMirror* mirror, RenderView& view) { _context->VSSetShader(_vsStatics.Get(), nullptr, 0); _context->PSSetShader(_psStatics.Get(), nullptr, 0); @@ -1151,6 +1161,11 @@ namespace TEN::Renderer { auto& nativeItem = g_Level.Items[rItemPtr->ItemNumber]; + if (mirror != nullptr && nativeItem.RoomNumber != mirror->RoomNumber) + { + continue; + } + if (!nativeItem.IsCreature()) continue; @@ -1196,6 +1211,11 @@ namespace TEN::Renderer if (creature.MuzzleFlash[0].ApplyZRotation) worldMatrix = rotMatrixZ * worldMatrix; + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } + _stStatic.World = worldMatrix; _cbStatic.UpdateData(_stStatic, _context.Get()); @@ -1236,6 +1256,11 @@ namespace TEN::Renderer if (creature.MuzzleFlash[1].ApplyZRotation) worldMatrix = rotMatrixZ * worldMatrix; + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } + _stStatic.World = worldMatrix; _cbStatic.UpdateData(_stStatic, _context.Get()); @@ -1267,17 +1292,23 @@ namespace TEN::Renderer } } - Matrix Renderer::GetWorldMatrixForSprite(RendererSpriteToDraw* sprite, RenderView& view) + Matrix Renderer::GetWorldMatrixForSprite(RendererSpriteToDraw* sprite, RendererMirror* mirror, RenderView& view) { auto spriteMatrix = Matrix::Identity; auto scaleMatrix = Matrix::CreateScale(sprite->Width * sprite->Scale, sprite->Height * sprite->Scale, sprite->Scale); + Vector3 spritePosition = sprite->pos; + if (mirror != nullptr) + { + spritePosition = Vector3::Transform(spritePosition, mirror->ReflectionMatrix); // Vector3::Reflect(spritePosition, mirror->Plane.Normal()); + } + switch (sprite->Type) { case SpriteType::Billboard: { auto cameraUp = Vector3(view.Camera.View._12, view.Camera.View._22, view.Camera.View._32); - spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(sprite->pos, Camera.pos.ToVector3(), cameraUp); + spriteMatrix = scaleMatrix * Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateBillboard(spritePosition, Camera.pos.ToVector3(), cameraUp); } break; @@ -1286,7 +1317,7 @@ namespace TEN::Renderer auto rotMatrix = Matrix::CreateRotationY(sprite->Rotation); auto quadForward = Vector3(0.0f, 0.0f, 1.0f); spriteMatrix = scaleMatrix * Matrix::CreateConstrainedBillboard( - sprite->pos, + spritePosition, Camera.pos.ToVector3(), sprite->ConstrainAxis, nullptr, @@ -1296,7 +1327,7 @@ namespace TEN::Renderer case SpriteType::LookAtBillboard: { - auto tMatrix = Matrix::CreateTranslation(sprite->pos); + auto tMatrix = Matrix::CreateTranslation(spritePosition); auto rotMatrix = Matrix::CreateRotationZ(sprite->Rotation) * Matrix::CreateLookAt(Vector3::Zero, sprite->LookAtAxis, Vector3::UnitZ); spriteMatrix = scaleMatrix * rotMatrix * tMatrix; } diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index c5244ef1e..b18435dd7 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -147,6 +147,19 @@ namespace TEN::Renderer for (int i = 0; i < std::min(MAX_LENS_FLARES_DRAW, (int)tempLensFlares.size()); i++) renderView.LensFlaresToDraw.push_back(tempLensFlares[i]); + + for (auto& mirror : g_Level.Mirrors) + { + if (mirror.RoomNumber == LaraItem->RoomNumber) + { + RendererMirror rendererMirror; + rendererMirror.RoomNumber = mirror.RoomNumber; + rendererMirror.MirroredRoomNumber = mirror.MirroredRoomNumber; + rendererMirror.Plane = mirror.MirrorPlane; + rendererMirror.ReflectionMatrix = Matrix::CreateReflection(rendererMirror.Plane); + renderView.Mirrors.push_back(rendererMirror); + } + } } bool Renderer::CheckPortal(short parentRoomNumber, RendererDoor* door, Vector4 viewPort, Vector4* clipPort, RenderView& renderView) diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index b1e29ebe5..fde9bcf84 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -278,8 +278,13 @@ void Renderer::UpdateLaraAnimations(bool force) rItem.DoneAnimations = true; } -void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPass) +void TEN::Renderer::Renderer::DrawLara(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { + if (mirror != nullptr && LaraItem->RoomNumber != mirror->RoomNumber) + { + return; + } + // Don't draw player if using optics. if (Lara.Control.Look.OpticRange != 0 || SpotcamDontDrawLara) return; @@ -305,7 +310,12 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa RendererRoom* room = &_rooms[LaraItem->RoomNumber]; - _stItem.World = item->InterpolatedWorld; // _laraWorldMatrix; + _stItem.World = item->InterpolatedWorld; + if (mirror != nullptr) + { + _stItem.World = _stItem.World * mirror->ReflectionMatrix; + } + _stItem.Color = item->Color; _stItem.AmbientLight = item->AmbientLight; memcpy(_stItem.BonesMatrices, item->InterpolatedAnimTransforms, laraObj.AnimationTransforms.size() * sizeof(Matrix)); @@ -324,12 +334,12 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, view, rendererPass); } - DrawLaraHolsters(item, room, view, rendererPass); - DrawLaraJoints(item, room, view, rendererPass); - DrawLaraHair(item, room, view, rendererPass); + DrawLaraHolsters(item, room, mirror, view, rendererPass); + DrawLaraJoints(item, room, mirror, view, rendererPass); + DrawLaraHair(item, room, mirror, view, rendererPass); } -void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) +void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { for (int i = 0; i < HairEffect.Units.size(); i++) { @@ -345,6 +355,10 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render _stItem.World = Matrix::Identity; _stItem.BonesMatrices[0] = itemToDraw->InterpolatedAnimTransforms[LM_HEAD] * itemToDraw->InterpolatedWorld; + if (mirror != nullptr) + { + _stItem.BonesMatrices[0] = _stItem.BonesMatrices[0] * mirror->ReflectionMatrix; + } for (int i = 0; i < unit.Segments.size(); i++) { @@ -354,6 +368,11 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render Quaternion::Lerp(segment.PrevOrientation, segment.Orientation, _interpolationFactor)) * Matrix::CreateTranslation( Vector3::Lerp(segment.PrevPosition, segment.Position, _interpolationFactor)); + + if (mirror != nullptr) + { + worldMatrix = worldMatrix * mirror->ReflectionMatrix; + } _stItem.BonesMatrices[i + 1] = worldMatrix; _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; @@ -369,7 +388,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render } } -void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) +void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (!_moveableObjects[ID_LARA_SKIN_JOINTS].has_value()) return; @@ -383,7 +402,7 @@ void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, Rend } } -void Renderer::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) +void Renderer::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { HolsterSlot leftHolsterID = Lara.Control.Weapon.HolsterInfo.LeftHolster; HolsterSlot rightHolsterID = Lara.Control.Weapon.HolsterInfo.RightHolster; diff --git a/TombEngine/Renderer/RendererSprites.cpp b/TombEngine/Renderer/RendererSprites.cpp index 417155097..457b3399f 100644 --- a/TombEngine/Renderer/RendererSprites.cpp +++ b/TombEngine/Renderer/RendererSprites.cpp @@ -243,7 +243,7 @@ namespace TEN::Renderer object.Centre = rDrawSprite.pos; object.Distance = distance; object.Sprite = &rDrawSprite; - object.World = GetWorldMatrixForSprite(&rDrawSprite, view); + //object.World = GetWorldMatrixForSprite(&rDrawSprite, view); view.TransparentObjectsToDraw.push_back(object); } @@ -256,7 +256,7 @@ namespace TEN::Renderer _spriteBuckets.push_back(currentSpriteBucket); } - void Renderer::DrawSprites(RenderView& view, RendererPass rendererPass) + void Renderer::DrawSprites(RendererMirror* mirror, RenderView& view, RendererPass rendererPass) { if (view.SpritesToDraw.empty()) return; @@ -296,7 +296,7 @@ namespace TEN::Renderer { auto& rDrawSprite = spriteBucket.SpritesToDraw[i]; - _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, view); + _stInstancedSpriteBuffer.Sprites[i].World = GetWorldMatrixForSprite(&rDrawSprite, mirror, view); _stInstancedSpriteBuffer.Sprites[i].Color = rDrawSprite.color; _stInstancedSpriteBuffer.Sprites[i].IsBillboard = 1; _stInstancedSpriteBuffer.Sprites[i].IsSoftParticle = rDrawSprite.SoftParticle ? 1 : 0; @@ -414,7 +414,7 @@ namespace TEN::Renderer UINT offset = 0; _context->IASetVertexBuffers(0, 1, _quadVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); - _stInstancedSpriteBuffer.Sprites[0].World = GetWorldMatrixForSprite(object->Sprite, view); + _stInstancedSpriteBuffer.Sprites[0].World = GetWorldMatrixForSprite(object->Sprite, nullptr, view); _stInstancedSpriteBuffer.Sprites[0].Color = object->Sprite->color; _stInstancedSpriteBuffer.Sprites[0].IsBillboard = 1; _stInstancedSpriteBuffer.Sprites[0].IsSoftParticle = object->Sprite->SoftParticle ? 1 : 0; diff --git a/TombEngine/Renderer/Structures/RendererMirror.h b/TombEngine/Renderer/Structures/RendererMirror.h new file mode 100644 index 000000000..42ed41064 --- /dev/null +++ b/TombEngine/Renderer/Structures/RendererMirror.h @@ -0,0 +1,16 @@ +#pragma once +#include + +namespace TEN::Renderer::Structures +{ + using namespace DirectX; + using namespace DirectX::SimpleMath; + + struct RendererMirror + { + short RoomNumber; + short MirroredRoomNumber; + Plane Plane; + Matrix ReflectionMatrix; + }; +} \ No newline at end of file diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx index 3d7b7b786..53893fb38 100644 --- a/TombEngine/Shaders/PostProcess.fx +++ b/TombEngine/Shaders/PostProcess.fx @@ -32,6 +32,20 @@ PixelShaderInput VS(VertexShaderInput input) return output; } +float4 PSDownsampleDepthBuffer(PixelShaderInput input) : SV_Target +{ + // Use 2x2 max technique + float d1 = ColorTexture.Sample(ColorSampler, input.UV, float2(0, 0)).r; + float d2 = ColorTexture.Sample(ColorSampler, input.UV, float2(0, 1)).r; + float d3 = ColorTexture.Sample(ColorSampler, input.UV, float2(1, 0)).r; + float d4 = ColorTexture.Sample(ColorSampler, input.UV, float2(1, 1)).r; + + return float4( + max(max(d1, d2), max(d3, d4)), + 0, 0, 1 + ); +} + float4 PSCopy(PixelShaderInput input) : SV_Target { return ColorTexture.Sample(ColorSampler, input.UV); diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index a88807274..484a57c02 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -1417,6 +1417,17 @@ bool LoadLevel(const std::string& path, bool partial) UpdateProgress(100, partial); + // MIRROR: remove after TE changes + g_Level.Mirrors.clear(); + + MirrorInfo mirror; + mirror.RoomNumber = 7; + mirror.MirrorPlane = Plane(Vector3(0, 0, 30000), Vector3(0, 0, -1)); + g_Level.Mirrors.push_back(mirror); + + mirror.MirrorPlane = Plane(Vector3(0, -2048, 0), Vector3(0,-1, 0)); + g_Level.Mirrors.push_back(mirror); + TENLog("Level loading complete.", LogLevel::Info); loadedSuccessfully = true; diff --git a/TombEngine/Specific/level.h b/TombEngine/Specific/level.h index 7942b68d3..d71c91fde 100644 --- a/TombEngine/Specific/level.h +++ b/TombEngine/Specific/level.h @@ -85,6 +85,13 @@ struct MESH std::vector buckets; }; +struct MirrorInfo +{ + short RoomNumber; + short MirroredRoomNumber; + Plane MirrorPlane; +}; + // LevelData struct LEVEL { @@ -123,6 +130,7 @@ struct LEVEL std::vector LoopedEventSetIndices = {}; std::vector AIObjects = {}; std::vector Sprites = {}; + std::vector Mirrors = {}; // Texture data TEXTURE SkyTexture = {}; diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index d96d876a9..463379d38 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -821,6 +821,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. +