mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
WIP TR4 style mirrors
This commit is contained in:
parent
116c3d71fc
commit
bb3d0b993b
15 changed files with 474 additions and 126 deletions
|
@ -145,7 +145,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="name" ><a href="#GetWind">GetWind()</a></td>
|
||||
<td class="summary">Get the current wind for the current frame.</td>
|
||||
<td class="summary">Get the wind vector for the current game frame.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -508,8 +508,8 @@
|
|||
<strong>GetWind()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
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 @@
|
|||
<ol>
|
||||
|
||||
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
|
||||
The wind.
|
||||
Wind vector.
|
||||
</ol>
|
||||
|
||||
|
||||
|
|
|
@ -383,6 +383,14 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
|
|||
<td class="summary">Disable the item, as if an antitrigger for it had been stepped on (i.e.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" ><a href="#Moveable:GetCollidable">Moveable:GetCollidable()</a></td>
|
||||
<td class="summary">Get the item's collision state.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" ><a href="#Moveable:SetCollidable">Moveable:SetCollidable(collidable)</a></td>
|
||||
<td class="summary">Set the item's collision.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" ><a href="#Moveable:MakeInvisible">Moveable:MakeInvisible()</a></td>
|
||||
<td class="summary">Make the item invisible.</td>
|
||||
</tr>
|
||||
|
@ -1967,6 +1975,49 @@ sas:SetPosition(newPos, <span class="keyword">false</span>)</pre>
|
|||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Moveable:GetCollidable"></a>
|
||||
<strong>Moveable:GetCollidable()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Get the item's collision state.
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">bool</span></span>
|
||||
item's collision state
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Moveable:SetCollidable"></a>
|
||||
<strong>Moveable:SetCollidable(collidable)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Set the item's collision.
|
||||
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">collidable</span>
|
||||
<span class="types"><span class="type">bool</span></span>
|
||||
true if the caller should be collidable, false if no collision should occur.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "Moveable:MakeInvisible"></a>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<RendererSortableObject> TransparentObjectsToDraw = {};
|
||||
std::vector<RendererLensFlare> LensFlaresToDraw = {};
|
||||
|
||||
std::vector<RendererMirror> 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);
|
||||
|
||||
|
|
|
@ -380,6 +380,7 @@ namespace TEN::Renderer
|
|||
ComPtr<ID3D11PixelShader> _psPostProcessExclusion;
|
||||
ComPtr<ID3D11PixelShader> _psPostProcessFinalPass;
|
||||
ComPtr<ID3D11PixelShader> _psPostProcessLensFlare;
|
||||
ComPtr<ID3D11PixelShader> _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();
|
||||
|
|
|
@ -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());
|
||||
|
@ -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<TextureRegister>(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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
@ -355,6 +369,11 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
16
TombEngine/Renderer/Structures/RendererMirror.h
Normal file
16
TombEngine/Renderer/Structures/RendererMirror.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include <SimpleMath.h>
|
||||
|
||||
namespace TEN::Renderer::Structures
|
||||
{
|
||||
using namespace DirectX;
|
||||
using namespace DirectX::SimpleMath;
|
||||
|
||||
struct RendererMirror
|
||||
{
|
||||
short RoomNumber;
|
||||
short MirroredRoomNumber;
|
||||
Plane Plane;
|
||||
Matrix ReflectionMatrix;
|
||||
};
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -85,6 +85,13 @@ struct MESH
|
|||
std::vector<BUCKET> buckets;
|
||||
};
|
||||
|
||||
struct MirrorInfo
|
||||
{
|
||||
short RoomNumber;
|
||||
short MirroredRoomNumber;
|
||||
Plane MirrorPlane;
|
||||
};
|
||||
|
||||
// LevelData
|
||||
struct LEVEL
|
||||
{
|
||||
|
@ -123,6 +130,7 @@ struct LEVEL
|
|||
std::vector<int> LoopedEventSetIndices = {};
|
||||
std::vector<AI_OBJECT> AIObjects = {};
|
||||
std::vector<SPRITE> Sprites = {};
|
||||
std::vector<MirrorInfo> Mirrors = {};
|
||||
|
||||
// Texture data
|
||||
TEXTURE SkyTexture = {};
|
||||
|
|
|
@ -821,6 +821,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
|
|||
<ClInclude Include="Renderer\Graphics\Vertices\Vertex.h" />
|
||||
<ClInclude Include="Renderer\Renderer.h" />
|
||||
<ClInclude Include="Renderer\RendererEnums.h" />
|
||||
<ClInclude Include="Renderer\Structures\RendererMirror.h" />
|
||||
<ClInclude Include="Renderer\RendererSprite2D.h" />
|
||||
<ClInclude Include="Renderer\RendererBucket.h" />
|
||||
<ClInclude Include="Renderer\RendererPolygon.h" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue