Index: ps/trunk/source/graphics/Camera.cpp
===================================================================
--- ps/trunk/source/graphics/Camera.cpp (revision 25354)
+++ ps/trunk/source/graphics/Camera.cpp (revision 25355)
@@ -1,394 +1,433 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* CCamera holds a view and a projection matrix. It also has a frustum
* which can be used to cull objects for rendering.
*/
#include "precompiled.h"
#include "Camera.h"
#include "graphics/HFTracer.h"
#include "graphics/Terrain.h"
#include "lib/ogl.h"
#include "maths/MathUtil.h"
#include "maths/Vector4D.h"
#include "ps/Game.h"
#include "ps/World.h"
#include "renderer/Renderer.h"
#include "renderer/WaterManager.h"
CCamera::CCamera()
{
// Set viewport to something anything should handle, but should be initialised
// to window size before use.
m_ViewPort.m_X = 0;
m_ViewPort.m_Y = 0;
m_ViewPort.m_Width = 800;
m_ViewPort.m_Height = 600;
}
CCamera::~CCamera() = default;
void CCamera::SetProjection(const CMatrix3D& matrix)
{
m_ProjType = ProjectionType::CUSTOM;
m_ProjMat = matrix;
}
void CCamera::SetProjectionFromCamera(const CCamera& camera)
{
m_ProjType = camera.m_ProjType;
m_NearPlane = camera.m_NearPlane;
m_FarPlane = camera.m_FarPlane;
if (m_ProjType == ProjectionType::PERSPECTIVE)
{
m_FOV = camera.m_FOV;
}
else if (m_ProjType == ProjectionType::ORTHO)
{
m_OrthoScale = camera.m_OrthoScale;
}
m_ProjMat = camera.m_ProjMat;
}
void CCamera::SetOrthoProjection(float nearp, float farp, float scale)
{
m_ProjType = ProjectionType::ORTHO;
m_NearPlane = nearp;
m_FarPlane = farp;
m_OrthoScale = scale;
const float halfHeight = 0.5f * m_OrthoScale;
const float halfWidth = halfHeight * GetAspectRatio();
m_ProjMat.SetOrtho(-halfWidth, halfWidth, -halfHeight, halfHeight, m_NearPlane, m_FarPlane);
}
void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov)
{
m_ProjType = ProjectionType::PERSPECTIVE;
m_NearPlane = nearp;
m_FarPlane = farp;
m_FOV = fov;
m_ProjMat.SetPerspective(m_FOV, GetAspectRatio(), m_NearPlane, m_FarPlane);
}
// Updates the frustum planes. Should be called
// everytime the view or projection matrices are
// altered.
void CCamera::UpdateFrustum(const CBoundingBoxAligned& scissor)
{
CMatrix3D MatFinal;
CMatrix3D MatView;
m_Orientation.GetInverse(MatView);
MatFinal = m_ProjMat * MatView;
m_ViewFrustum.SetNumPlanes(6);
// get the RIGHT plane
m_ViewFrustum[0].m_Norm.X = scissor[1].X*MatFinal._41 - MatFinal._11;
m_ViewFrustum[0].m_Norm.Y = scissor[1].X*MatFinal._42 - MatFinal._12;
m_ViewFrustum[0].m_Norm.Z = scissor[1].X*MatFinal._43 - MatFinal._13;
m_ViewFrustum[0].m_Dist = scissor[1].X*MatFinal._44 - MatFinal._14;
// get the LEFT plane
m_ViewFrustum[1].m_Norm.X = -scissor[0].X*MatFinal._41 + MatFinal._11;
m_ViewFrustum[1].m_Norm.Y = -scissor[0].X*MatFinal._42 + MatFinal._12;
m_ViewFrustum[1].m_Norm.Z = -scissor[0].X*MatFinal._43 + MatFinal._13;
m_ViewFrustum[1].m_Dist = -scissor[0].X*MatFinal._44 + MatFinal._14;
// get the BOTTOM plane
m_ViewFrustum[2].m_Norm.X = -scissor[0].Y*MatFinal._41 + MatFinal._21;
m_ViewFrustum[2].m_Norm.Y = -scissor[0].Y*MatFinal._42 + MatFinal._22;
m_ViewFrustum[2].m_Norm.Z = -scissor[0].Y*MatFinal._43 + MatFinal._23;
m_ViewFrustum[2].m_Dist = -scissor[0].Y*MatFinal._44 + MatFinal._24;
// get the TOP plane
m_ViewFrustum[3].m_Norm.X = scissor[1].Y*MatFinal._41 - MatFinal._21;
m_ViewFrustum[3].m_Norm.Y = scissor[1].Y*MatFinal._42 - MatFinal._22;
m_ViewFrustum[3].m_Norm.Z = scissor[1].Y*MatFinal._43 - MatFinal._23;
m_ViewFrustum[3].m_Dist = scissor[1].Y*MatFinal._44 - MatFinal._24;
// get the FAR plane
m_ViewFrustum[4].m_Norm.X = scissor[1].Z*MatFinal._41 - MatFinal._31;
m_ViewFrustum[4].m_Norm.Y = scissor[1].Z*MatFinal._42 - MatFinal._32;
m_ViewFrustum[4].m_Norm.Z = scissor[1].Z*MatFinal._43 - MatFinal._33;
m_ViewFrustum[4].m_Dist = scissor[1].Z*MatFinal._44 - MatFinal._34;
// get the NEAR plane
m_ViewFrustum[5].m_Norm.X = -scissor[0].Z*MatFinal._41 + MatFinal._31;
m_ViewFrustum[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32;
m_ViewFrustum[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33;
m_ViewFrustum[5].m_Dist = -scissor[0].Z*MatFinal._44 + MatFinal._34;
for (size_t i = 0; i < 6; ++i)
m_ViewFrustum[i].Normalize();
}
void CCamera::ClipFrustum(const CPlane& clipPlane)
{
CPlane normClipPlane = clipPlane;
normClipPlane.Normalize();
m_ViewFrustum.AddPlane(normClipPlane);
}
void CCamera::SetViewPort(const SViewPort& viewport)
{
m_ViewPort.m_X = viewport.m_X;
m_ViewPort.m_Y = viewport.m_Y;
m_ViewPort.m_Width = viewport.m_Width;
m_ViewPort.m_Height = viewport.m_Height;
}
float CCamera::GetAspectRatio() const
{
return static_cast(m_ViewPort.m_Width) / static_cast(m_ViewPort.m_Height);
}
void CCamera::GetViewQuad(float dist, Quad& quad) const
{
ENSURE(m_ProjType == ProjectionType::PERSPECTIVE || m_ProjType == ProjectionType::ORTHO);
const float y = m_ProjType == ProjectionType::PERSPECTIVE ? dist * tanf(m_FOV * 0.5f) : m_OrthoScale * 0.5f;
const float x = y * GetAspectRatio();
quad[0].X = -x;
quad[0].Y = -y;
quad[0].Z = dist;
quad[1].X = x;
quad[1].Y = -y;
quad[1].Z = dist;
quad[2].X = x;
quad[2].Y = y;
quad[2].Z = dist;
quad[3].X = -x;
quad[3].Y = y;
quad[3].Z = dist;
}
void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const
{
ENSURE(m_ProjType == ProjectionType::PERSPECTIVE || m_ProjType == ProjectionType::ORTHO);
// Coordinates relative to the camera plane.
const float dx = static_cast(px) / m_ViewPort.m_Width;
const float dy = 1.0f - static_cast(py) / m_ViewPort.m_Height;
Quad points;
GetViewQuad(m_FarPlane, points);
// Transform from camera space to world space.
for (CVector3D& point : points)
point = m_Orientation.Transform(point);
// Get world space position of mouse point at the far clipping plane.
const CVector3D basisX = points[1] - points[0];
const CVector3D basisY = points[3] - points[0];
if (m_ProjType == ProjectionType::PERSPECTIVE)
{
// Build direction for the camera origin to the target point.
origin = m_Orientation.GetTranslation();
CVector3D targetPoint = points[0] + (basisX * dx) + (basisY * dy);
dir = targetPoint - origin;
}
else if (m_ProjType == ProjectionType::ORTHO)
{
origin = m_Orientation.GetTranslation() + (basisX * (dx - 0.5f)) + (basisY * (dy - 0.5f));
dir = m_Orientation.GetIn();
}
dir.Normalize();
}
void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) const
{
CMatrix3D transform = m_ProjMat * m_Orientation.GetInverse();
CVector4D screenspace = transform.Transform(CVector4D(world.X, world.Y, world.Z, 1.0f));
x = screenspace.X / screenspace.W;
y = screenspace.Y / screenspace.W;
x = (x + 1) * 0.5f * m_ViewPort.m_Width;
y = (1 - y) * 0.5f * m_ViewPort.m_Height;
}
CVector3D CCamera::GetWorldCoordinates(int px, int py, bool aboveWater) const
{
CHFTracer tracer(g_Game->GetWorld()->GetTerrain());
int x, z;
CVector3D origin, dir, delta, terrainPoint, waterPoint;
BuildCameraRay(px, py, origin, dir);
bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint);
if (!aboveWater)
{
if (gotTerrain)
return terrainPoint;
// Off the edge of the world?
// Work out where it /would/ hit, if the map were extended out to infinity with average height.
return GetWorldCoordinates(px, py, 50.0f);
}
CPlane plane;
plane.Set(CVector3D(0.f, 1.f, 0.f), // upwards normal
CVector3D(0.f, g_Renderer.GetWaterManager()->m_WaterHeight, 0.f)); // passes through water plane
bool gotWater = plane.FindRayIntersection( origin, dir, &waterPoint );
// Clamp the water intersection to within the map's bounds, so that
// we'll always return a valid position on the map
ssize_t mapSize = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide();
if (gotWater)
{
waterPoint.X = Clamp(waterPoint.X, 0.f, (mapSize - 1) * TERRAIN_TILE_SIZE);
waterPoint.Z = Clamp(waterPoint.Z, 0.f, (mapSize - 1) * TERRAIN_TILE_SIZE);
}
if (gotTerrain)
{
if (gotWater)
{
// Intersecting both heightmap and water plane; choose the closest of those
if ((origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared())
return terrainPoint;
else
return waterPoint;
}
else
{
// Intersecting heightmap but parallel to water plane
return terrainPoint;
}
}
else
{
if (gotWater)
{
// Only intersecting water plane
return waterPoint;
}
else
{
// Not intersecting terrain or water; just return 0,0,0.
return CVector3D(0.f, 0.f, 0.f);
}
}
}
CVector3D CCamera::GetWorldCoordinates(int px, int py, float h) const
{
CPlane plane;
plane.Set(CVector3D(0.f, 1.f, 0.f), CVector3D(0.f, h, 0.f)); // upwards normal, passes through h
CVector3D origin, dir, delta, currentTarget;
BuildCameraRay(px, py, origin, dir);
if (plane.FindRayIntersection(origin, dir, ¤tTarget))
return currentTarget;
// No intersection with the infinite plane - nothing sensible can be returned,
// so just choose an arbitrary point on the plane
return CVector3D(0.f, h, 0.f);
}
CVector3D CCamera::GetFocus() const
{
// Basically the same as GetWorldCoordinates
CHFTracer tracer(g_Game->GetWorld()->GetTerrain());
int x, z;
CVector3D origin, dir, delta, terrainPoint, waterPoint;
origin = m_Orientation.GetTranslation();
dir = m_Orientation.GetIn();
bool gotTerrain = tracer.RayIntersect(origin, dir, x, z, terrainPoint);
CPlane plane;
plane.Set(CVector3D(0.f, 1.f, 0.f), // upwards normal
CVector3D(0.f, g_Renderer.GetWaterManager()->m_WaterHeight, 0.f)); // passes through water plane
bool gotWater = plane.FindRayIntersection( origin, dir, &waterPoint );
// Clamp the water intersection to within the map's bounds, so that
// we'll always return a valid position on the map
ssize_t mapSize = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide();
if (gotWater)
{
waterPoint.X = Clamp(waterPoint.X, 0.f, (mapSize - 1) * TERRAIN_TILE_SIZE);
waterPoint.Z = Clamp(waterPoint.Z, 0.f, (mapSize - 1) * TERRAIN_TILE_SIZE);
}
if (gotTerrain)
{
if (gotWater)
{
// Intersecting both heightmap and water plane; choose the closest of those
if ((origin - terrainPoint).LengthSquared() < (origin - waterPoint).LengthSquared())
return terrainPoint;
else
return waterPoint;
}
else
{
// Intersecting heightmap but parallel to water plane
return terrainPoint;
}
}
else
{
if (gotWater)
{
// Only intersecting water plane
return waterPoint;
}
else
{
// Not intersecting terrain or water; just return 0,0,0.
return CVector3D(0.f, 0.f, 0.f);
}
}
}
+CBoundingBoxAligned CCamera::GetBoundsInViewPort(const CBoundingBoxAligned& boundigBox) const
+{
+ CVector4D v1 = GetViewProjection().Transform(CVector4D(boundigBox[0].X, boundigBox[1].Y, boundigBox[0].Z, 1.0f));
+ CVector4D v2 = GetViewProjection().Transform(CVector4D(boundigBox[1].X, boundigBox[1].Y, boundigBox[0].Z, 1.0f));
+ CVector4D v3 = GetViewProjection().Transform(CVector4D(boundigBox[0].X, boundigBox[1].Y, boundigBox[1].Z, 1.0f));
+ CVector4D v4 = GetViewProjection().Transform(CVector4D(boundigBox[1].X, boundigBox[1].Y, boundigBox[1].Z, 1.0f));
+ CBoundingBoxAligned viewPortBounds;
+ #define ADDBOUND(v1, v2, v3, v4) \
+ if (v1.Z >= -v1.W) \
+ viewPortBounds += CVector3D(v1.X, v1.Y, v1.Z) * (1.0f / v1.W); \
+ else \
+ { \
+ float t = v1.Z + v1.W; \
+ if (v2.Z > -v2.W) \
+ { \
+ CVector4D c2 = v1 + (v2 - v1) * (t / (t - (v2.Z + v2.W))); \
+ viewPortBounds += CVector3D(c2.X, c2.Y, c2.Z) * (1.0f / c2.W); \
+ } \
+ if (v3.Z > -v3.W) \
+ { \
+ CVector4D c3 = v1 + (v3 - v1) * (t / (t - (v3.Z + v3.W))); \
+ viewPortBounds += CVector3D(c3.X, c3.Y, c3.Z) * (1.0f / c3.W); \
+ } \
+ if (v4.Z > -v4.W) \
+ { \
+ CVector4D c4 = v1 + (v4 - v1) * (t / (t - (v4.Z + v4.W))); \
+ viewPortBounds += CVector3D(c4.X, c4.Y, c4.Z) * (1.0f / c4.W); \
+ } \
+ }
+ ADDBOUND(v1, v2, v3, v4);
+ ADDBOUND(v2, v1, v3, v4);
+ ADDBOUND(v3, v1, v2, v4);
+ ADDBOUND(v4, v1, v2, v3);
+ #undef ADDBOUND
+ if (viewPortBounds[0].X >= 1.0f || viewPortBounds[1].X <= -1.0f || viewPortBounds[0].Y >= 1.0f || viewPortBounds[1].Y <= -1.0f)
+ return CBoundingBoxAligned{};
+ return viewPortBounds;
+}
+
void CCamera::LookAt(const CVector3D& camera, const CVector3D& focus, const CVector3D& up)
{
CVector3D delta = focus - camera;
LookAlong(camera, delta, up);
}
void CCamera::LookAlong(const CVector3D& camera, CVector3D orientation, CVector3D up)
{
orientation.Normalize();
up.Normalize();
CVector3D s = orientation.Cross(up);
m_Orientation._11 = -s.X; m_Orientation._12 = up.X; m_Orientation._13 = orientation.X; m_Orientation._14 = camera.X;
m_Orientation._21 = -s.Y; m_Orientation._22 = up.Y; m_Orientation._23 = orientation.Y; m_Orientation._24 = camera.Y;
m_Orientation._31 = -s.Z; m_Orientation._32 = up.Z; m_Orientation._33 = orientation.Z; m_Orientation._34 = camera.Z;
m_Orientation._41 = 0.0f; m_Orientation._42 = 0.0f; m_Orientation._43 = 0.0f; m_Orientation._44 = 1.0f;
}
Index: ps/trunk/source/graphics/Camera.h
===================================================================
--- ps/trunk/source/graphics/Camera.h (revision 25354)
+++ ps/trunk/source/graphics/Camera.h (revision 25355)
@@ -1,132 +1,134 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* CCamera holds a view and a projection matrix. It also has a frustum
* which can be used to cull objects for rendering.
*/
#ifndef INCLUDED_CAMERA
#define INCLUDED_CAMERA
#include "maths/BoundingBoxAligned.h"
#include "maths/Frustum.h"
#include "maths/Matrix3D.h"
#include
// view port
struct SViewPort
{
int m_X;
int m_Y;
int m_Width;
int m_Height;
};
class CCamera
{
public:
// Represents camera viewport or frustum side in 3D space.
using Quad = std::array;
enum class ProjectionType
{
CUSTOM,
ORTHO,
PERSPECTIVE,
};
CCamera();
~CCamera();
CMatrix3D& GetProjection() { return m_ProjMat; }
const CMatrix3D& GetProjection() const { return m_ProjMat; }
CMatrix3D GetViewProjection() const { return m_ProjMat * m_Orientation.GetInverse(); }
void SetProjection(const CMatrix3D& matrix);
void SetProjectionFromCamera(const CCamera& camera);
void SetOrthoProjection(float nearp, float farp, float scale);
void SetPerspectiveProjection(float nearp, float farp, float fov);
ProjectionType GetProjectionType() const { return m_ProjType; }
CMatrix3D& GetOrientation() { return m_Orientation; }
const CMatrix3D& GetOrientation() const { return m_Orientation; }
// Updates the frustum planes. Should be called
// everytime the view or projection matrices are
// altered.
void UpdateFrustum(const CBoundingBoxAligned& scissor = CBoundingBoxAligned(CVector3D(-1.0f, -1.0f, -1.0f), CVector3D(1.0f, 1.0f, 1.0f)));
void ClipFrustum(const CPlane& clipPlane);
const CFrustum& GetFrustum() const { return m_ViewFrustum; }
void SetViewPort(const SViewPort& viewport);
const SViewPort& GetViewPort() const { return m_ViewPort; }
float GetAspectRatio() const;
float GetNearPlane() const { return m_NearPlane; }
float GetFarPlane() const { return m_FarPlane; }
float GetFOV() const { return m_FOV; }
float GetOrthoScale() const { return m_OrthoScale; }
// Returns a quad of view in camera space at given distance from camera.
void GetViewQuad(float dist, Quad& quad) const;
// Builds a ray passing through the screen coordinate (px, py), calculates
// origin and direction of the ray.
void BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const;
// General helpers that seem to fit here
// Get the screen-space coordinates corresponding to a given world-space position
void GetScreenCoordinates(const CVector3D& world, float& x, float& y) const;
// Get the point on the terrain corresponding to pixel (px,py) (or the mouse coordinates)
// The aboveWater parameter determines whether we want to stop at the water plane or also get underwater points
CVector3D GetWorldCoordinates(int px, int py, bool aboveWater=false) const;
// Get the point on the plane at height h corresponding to pixel (px,py)
CVector3D GetWorldCoordinates(int px, int py, float h) const;
// Get the point on the terrain (or water plane) the camera is pointing towards
CVector3D GetFocus() const;
+ CBoundingBoxAligned GetBoundsInViewPort(const CBoundingBoxAligned& boundigBox) const;
+
// Build an orientation matrix from camera position, camera focus point, and up-vector
void LookAt(const CVector3D& camera, const CVector3D& focus, const CVector3D& up);
// Build an orientation matrix from camera position, camera orientation, and up-vector
void LookAlong(const CVector3D& camera, CVector3D orientation, CVector3D up);
public:
// This is the orientation matrix. The inverse of this
// is the view matrix
CMatrix3D m_Orientation;
private:
CMatrix3D m_ProjMat;
ProjectionType m_ProjType = ProjectionType::CUSTOM;
float m_NearPlane = 0.0f;
float m_FarPlane = 0.0f;
union
{
float m_FOV;
float m_OrthoScale;
};
SViewPort m_ViewPort;
CFrustum m_ViewFrustum;
};
#endif // INCLUDED_CAMERA
Index: ps/trunk/source/renderer/Renderer.cpp
===================================================================
--- ps/trunk/source/renderer/Renderer.cpp (revision 25354)
+++ ps/trunk/source/renderer/Renderer.cpp (revision 25355)
@@ -1,1937 +1,1937 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
/*
* higher level interface on top of OpenGL to render basic objects:
* terrain, models, sprites, particles etc.
*/
#include "precompiled.h"
#include "Renderer.h"
#include "lib/bits.h" // is_pow2
#include "lib/res/graphics/ogl_tex.h"
#include "lib/allocators/shared_ptr.h"
#include "maths/Matrix3D.h"
#include "maths/MathUtil.h"
#include "ps/CLogger.h"
#include "ps/ConfigDB.h"
#include "ps/Game.h"
#include "ps/Profile.h"
#include "ps/Filesystem.h"
#include "ps/World.h"
#include "ps/Loader.h"
#include "ps/ProfileViewer.h"
#include "graphics/Camera.h"
#include "graphics/Decal.h"
#include "graphics/FontManager.h"
#include "graphics/GameView.h"
#include "graphics/LightEnv.h"
#include "graphics/LOSTexture.h"
#include "graphics/MaterialManager.h"
#include "graphics/Model.h"
#include "graphics/ModelDef.h"
#include "graphics/ParticleManager.h"
#include "graphics/Patch.h"
#include "graphics/ShaderManager.h"
#include "graphics/Terrain.h"
#include "graphics/Texture.h"
#include "graphics/TextureManager.h"
#include "renderer/DebugRenderer.h"
#include "renderer/HWLightingModelRenderer.h"
#include "renderer/InstancingModelRenderer.h"
#include "renderer/ModelRenderer.h"
#include "renderer/OverlayRenderer.h"
#include "renderer/ParticleRenderer.h"
#include "renderer/PostprocManager.h"
#include "renderer/RenderingOptions.h"
#include "renderer/RenderModifiers.h"
#include "renderer/ShadowMap.h"
#include "renderer/SilhouetteRenderer.h"
#include "renderer/SkyManager.h"
#include "renderer/TerrainOverlay.h"
#include "renderer/TerrainRenderer.h"
#include "renderer/TimeManager.h"
#include "renderer/VertexBufferManager.h"
#include "renderer/WaterManager.h"
#include "scriptinterface/ScriptInterface.h"
#include
#include
#include