Implemented frustum culling

This commit is contained in:
parax0 2015-09-27 16:02:53 -06:00
parent a284cebe64
commit d8ac185656
25 changed files with 229 additions and 50 deletions

View File

@ -18,6 +18,7 @@ CCamera::CCamera()
mLookSpeed = 1.f; // Old: 0.003f mLookSpeed = 1.f; // Old: 0.003f
mViewOutdated = true; mViewOutdated = true;
mProjectionOutdated = true; mProjectionOutdated = true;
mFrustumPlanesOutdated = true;
} }
CCamera::CCamera(CVector3f Position, CVector3f) CCamera::CCamera(CVector3f Position, CVector3f)
@ -50,6 +51,7 @@ void CCamera::Pan(float XAmount, float YAmount)
mPosition += Right * (XAmount * mMoveSpeed); mPosition += Right * (XAmount * mMoveSpeed);
mPosition += Up * (YAmount * mMoveSpeed); mPosition += Up * (YAmount * mMoveSpeed);
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
break; break;
} }
@ -77,6 +79,7 @@ void CCamera::Rotate(float XAmount, float YAmount)
mYaw -= (XAmount * mLookSpeed * 0.3f); mYaw -= (XAmount * mLookSpeed * 0.3f);
mPitch -= (YAmount * mLookSpeed * 0.3f); mPitch -= (YAmount * mLookSpeed * 0.3f);
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
break; break;
} }
} }
@ -85,6 +88,7 @@ void CCamera::Zoom(float Amount)
{ {
mPosition += (mDirection * Amount) * (mMoveSpeed * 25.f); mPosition += (mDirection * Amount) * (mMoveSpeed * 25.f);
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
} }
void CCamera::Snap(CVector3f Position) void CCamera::Snap(CVector3f Position)
@ -93,6 +97,8 @@ void CCamera::Snap(CVector3f Position)
mYaw = -Math::skHalfPi; mYaw = -Math::skHalfPi;
mPitch = 0.0f; mPitch = 0.0f;
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
CalculateDirection();
} }
void CCamera::ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime) void CCamera::ProcessKeyInput(EKeyInputs KeyFlags, double DeltaTime)
@ -132,6 +138,8 @@ void CCamera::ProcessMouseInput(EKeyInputs KeyFlags, EMouseInputs MouseFlags, fl
else if ((MouseFlags & eMiddleButton) || (MouseFlags & eRightButton)) else if ((MouseFlags & eMiddleButton) || (MouseFlags & eRightButton))
Pan(XMovement, YMovement); Pan(XMovement, YMovement);
} }
CalculateDirection();
} }
CRay CCamera::CastRay(CVector2f DeviceCoords) CRay CCamera::CastRay(CVector2f DeviceCoords)
@ -215,17 +223,27 @@ const CMatrix4f& CCamera::ProjectionMatrix()
return mCachedProjectionMatrix; return mCachedProjectionMatrix;
} }
const CFrustumPlanes& CCamera::FrustumPlanes()
{
if (mFrustumPlanesOutdated)
CalculateFrustumPlanes();
return mCachedFrustumPlanes;
}
// ************ SETTERS ************ // ************ SETTERS ************
void CCamera::SetPosition(CVector3f Position) void CCamera::SetPosition(CVector3f Position)
{ {
mPosition = Position; mPosition = Position;
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
} }
void CCamera::SetDirection(CVector3f Direction) void CCamera::SetDirection(CVector3f Direction)
{ {
mDirection = Direction; mDirection = Direction;
mViewOutdated = true; mViewOutdated = true;
mFrustumPlanesOutdated = true;
} }
void CCamera::SetYaw(float Yaw) void CCamera::SetYaw(float Yaw)
@ -263,6 +281,7 @@ void CCamera::SetAspectRatio(float AspectRatio)
{ {
mAspectRatio = AspectRatio; mAspectRatio = AspectRatio;
mProjectionOutdated = true; mProjectionOutdated = true;
mFrustumPlanesOutdated = true;
} }
// ************ PRIVATE ************ // ************ PRIVATE ************
@ -303,3 +322,9 @@ void CCamera::CalculateProjection()
mCachedProjectionMatrix = Math::PerspectiveMatrix(55.f, mAspectRatio, 0.1f, 4096.f); mCachedProjectionMatrix = Math::PerspectiveMatrix(55.f, mAspectRatio, 0.1f, 4096.f);
mProjectionOutdated = false; mProjectionOutdated = false;
} }
void CCamera::CalculateFrustumPlanes()
{
mCachedFrustumPlanes.SetPlanes(mPosition, mDirection, 55.f, mAspectRatio, 0.1f, 4096.f);
mFrustumPlanesOutdated = false;
}

View File

@ -1,6 +1,7 @@
#ifndef CCAMERA_H #ifndef CCAMERA_H
#define CCAMERA_H #define CCAMERA_H
#include "CFrustumPlanes.h"
#include <Common/CAABox.h> #include <Common/CAABox.h>
#include <Common/CMatrix4f.h> #include <Common/CMatrix4f.h>
#include <Common/CRay.h> #include <Common/CRay.h>
@ -30,8 +31,10 @@ class CCamera
CMatrix4f mCachedViewMatrix; CMatrix4f mCachedViewMatrix;
CMatrix4f mCachedProjectionMatrix; CMatrix4f mCachedProjectionMatrix;
CFrustumPlanes mCachedFrustumPlanes;
bool mViewOutdated; bool mViewOutdated;
bool mProjectionOutdated; bool mProjectionOutdated;
bool mFrustumPlanesOutdated;
public: public:
CCamera(); CCamera();
@ -56,6 +59,7 @@ public:
const CMatrix4f& ViewMatrix(); const CMatrix4f& ViewMatrix();
CMatrix4f RotationOnlyViewMatrix(); CMatrix4f RotationOnlyViewMatrix();
const CMatrix4f& ProjectionMatrix(); const CMatrix4f& ProjectionMatrix();
const CFrustumPlanes& FrustumPlanes();
// Setters // Setters
void SetPosition(CVector3f Position); void SetPosition(CVector3f Position);
@ -74,6 +78,7 @@ private:
void CalculateDirection(); void CalculateDirection();
void CalculateView(); void CalculateView();
void CalculateProjection(); void CalculateProjection();
void CalculateFrustumPlanes();
}; };
#endif // CCAMERA_H #endif // CCAMERA_H

98
Core/CFrustumPlanes.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "CFrustumPlanes.h"
#include <Common/Math.h>
#include <Common/types.h>
CFrustumPlanes::CFrustumPlanes()
{
}
CFrustumPlanes::~CFrustumPlanes()
{
}
const CPlane& CFrustumPlanes::GetPlane(EFrustumSide side) const
{
return mPlanes[side];
}
void CFrustumPlanes::SetPlanes(const CVector3f& position, const CVector3f& direction, float fieldOfView, float aspectRatio, float near, float far)
{
// Calculate up/right vectors
CVector3f right = direction.Cross(CVector3f::skUp).Normalized();
CVector3f up = right.Cross(direction).Normalized();
// Calculate dimensions of near plane
float nearHeight = 2 * tanf(Math::DegreesToRadians(fieldOfView) / 2.f) * near;
float nearWidth = nearHeight * aspectRatio;
// Define the planes
CVector3f nearCenter = position + (direction * near);
mPlanes[eNearPlane].Redefine(direction, nearCenter);
CVector3f farCenter = position + (direction * far);
mPlanes[eFarPlane].Redefine(-direction, farCenter);
CVector3f midRight = nearCenter + (right * (nearWidth / 2.f));
CVector3f rightNormal = up.Cross((midRight - position).Normalized());
mPlanes[eRightPlane].Redefine(rightNormal, position);
CVector3f midLeft = nearCenter - (right * (nearWidth / 2.f));
CVector3f leftNormal = (midLeft - position).Normalized().Cross(up);
mPlanes[eLeftPlane].Redefine(leftNormal, position);
CVector3f midTop = nearCenter + (up * (nearHeight / 2.f));
CVector3f topNormal = (midTop - position).Normalized().Cross(right);
mPlanes[eTopPlane].Redefine(topNormal, position);
CVector3f midBottom = nearCenter - (up * (nearHeight / 2.f));
CVector3f bottomNormal = right.Cross((midBottom - position).Normalized());
mPlanes[eBottomPlane].Redefine(bottomNormal, position);
}
bool CFrustumPlanes::PointInFrustum(const CVector3f& point) const
{
for (u32 iPlane = 0; iPlane < 6; iPlane++)
{
const CPlane& plane = mPlanes[iPlane];
if (plane.Normal().Dot(point) + plane.Dist() < 0.f)
return false;
}
return true;
}
bool CFrustumPlanes::BoxInFrustum(const CAABox& box) const
{
CVector3f min = box.Min();
CVector3f max = box.Max();
CVector3f points[8];
points[0] = min;
points[1] = max;
points[2] = CVector3f(min.x, min.y, max.z);
points[3] = CVector3f(min.x, max.y, min.z);
points[4] = CVector3f(min.x, max.y, max.z);
points[5] = CVector3f(max.x, min.y, max.z);
points[6] = CVector3f(max.x, max.y, min.z);
points[7] = CVector3f(max.x, min.y, min.z);
for (u32 iPlane = 0; iPlane < 6; iPlane++)
{
const CPlane& plane = mPlanes[iPlane];
int numPoints = 0;
for (u32 iPoint = 0; iPoint < 8; iPoint++)
{
if (plane.Normal().Dot(points[iPoint]) + plane.Dist() < 0.f)
numPoints++;
else
break;
}
if (numPoints == 8) return false;
}
return true;
}

30
Core/CFrustumPlanes.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef CFRUSTUMPLANES_H
#define CFRUSTUMPLANES_H
#include <Common/CAABox.h>
#include <Common/CPlane.h>
#include <Common/CVector3f.h>
class CFrustumPlanes
{
public:
enum EFrustumSide
{
eNearPlane = 0, eFarPlane = 1,
eTopPlane = 2, eBottomPlane = 3,
eLeftPlane = 4, eRightPlane = 5
};
private:
CPlane mPlanes[6];
public:
CFrustumPlanes();
~CFrustumPlanes();
const CPlane& GetPlane(EFrustumSide side) const;
void SetPlanes(const CVector3f& position, const CVector3f& direction, float fieldOfView, float aspectRatio, float near, float far);
bool PointInFrustum(const CVector3f& point) const;
bool BoxInFrustum(const CAABox& box) const;
};
#endif // CFRUSTUMPLANES_H

View File

@ -215,7 +215,7 @@ void CSceneManager::ClearScene()
mNodeCount = 0; mNodeCount = 0;
} }
void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer) void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer, CCamera& camera)
{ {
ERenderOptions options = pRenderer->RenderOptions(); ERenderOptions options = pRenderer->RenderOptions();
@ -223,32 +223,32 @@ void CSceneManager::AddSceneToRenderer(CRenderer *pRenderer)
{ {
for (u32 n = 0; n < mModelNodes.size(); n++) for (u32 n = 0; n < mModelNodes.size(); n++)
if (mModelNodes[n]->IsVisible()) if (mModelNodes[n]->IsVisible())
mModelNodes[n]->AddToRenderer(pRenderer); mModelNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
for (u32 n = 0; n < mStaticNodes.size(); n++) for (u32 n = 0; n < mStaticNodes.size(); n++)
if (mStaticNodes[n]->IsVisible()) if (mStaticNodes[n]->IsVisible())
mStaticNodes[n]->AddToRenderer(pRenderer); mStaticNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
} }
if (options & eDrawWorldCollision) if (options & eDrawWorldCollision)
{ {
for (u32 n = 0; n < mCollisionNodes.size(); n++) for (u32 n = 0; n < mCollisionNodes.size(); n++)
if (mCollisionNodes[n]->IsVisible()) if (mCollisionNodes[n]->IsVisible())
mCollisionNodes[n]->AddToRenderer(pRenderer); mCollisionNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
} }
if (options & eDrawLights) if (options & eDrawLights)
{ {
for (u32 n = 0; n < mLightNodes.size(); n++) for (u32 n = 0; n < mLightNodes.size(); n++)
if (mLightNodes[n]->IsVisible()) if (mLightNodes[n]->IsVisible())
mLightNodes[n]->AddToRenderer(pRenderer); mLightNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
} }
if ((options & eDrawObjects) || (options & eDrawObjectCollision)) if ((options & eDrawObjects) || (options & eDrawObjectCollision))
{ {
for (u32 n = 0; n < mScriptNodes.size(); n++) for (u32 n = 0; n < mScriptNodes.size(); n++)
if (mScriptNodes[n]->IsVisible()) if (mScriptNodes[n]->IsVisible())
mScriptNodes[n]->AddToRenderer(pRenderer); mScriptNodes[n]->AddToRenderer(pRenderer, camera.FrustumPlanes());
} }
} }

View File

@ -57,7 +57,7 @@ public:
void SetActiveArea(CGameArea *_area); void SetActiveArea(CGameArea *_area);
void SetActiveWorld(CWorld *_world); void SetActiveWorld(CWorld *_world);
void ClearScene(); void ClearScene();
void AddSceneToRenderer(CRenderer *pRenderer); void AddSceneToRenderer(CRenderer *pRenderer, CCamera& camera);
SRayIntersection SceneRayCast(const CRay& Ray, ERenderOptions renderOptions); SRayIntersection SceneRayCast(const CRay& Ray, ERenderOptions renderOptions);
void PickEnvironmentObjects(); void PickEnvironmentObjects();
CScriptNode* ScriptNodeByID(u32 InstanceID); CScriptNode* ScriptNodeByID(u32 InstanceID);

View File

@ -4,6 +4,7 @@
#include "ERenderOptions.h" #include "ERenderOptions.h"
#include <Common/CAABox.h> #include <Common/CAABox.h>
#include <Common/types.h> #include <Common/types.h>
#include <Core/CFrustumPlanes.h>
class CRenderer; class CRenderer;
@ -12,7 +13,7 @@ class IRenderable
public: public:
IRenderable() {} IRenderable() {}
virtual ~IRenderable() {} virtual ~IRenderable() {}
virtual void AddToRenderer(CRenderer *pRenderer) = 0; virtual void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum) = 0;
virtual void Draw(ERenderOptions options) {} virtual void Draw(ERenderOptions options) {}
virtual void DrawAsset(ERenderOptions options, u32 asset) {} virtual void DrawAsset(ERenderOptions options, u32 asset) {}
virtual void DrawSelection() {} virtual void DrawSelection() {}

View File

@ -151,7 +151,8 @@ SOURCES += \
Resource/script/CProperty.cpp \ Resource/script/CProperty.cpp \
Resource/CAnimationParameters.cpp \ Resource/CAnimationParameters.cpp \
UI/WAnimParamsEditor.cpp \ UI/WAnimParamsEditor.cpp \
Resource/CCollisionMeshGroup.cpp Resource/CCollisionMeshGroup.cpp \
Core/CFrustumPlanes.cpp
HEADERS += \ HEADERS += \
Common/AnimUtil.h \ Common/AnimUtil.h \
@ -318,7 +319,8 @@ HEADERS += \
Resource/script/EVolumeShape.h \ Resource/script/EVolumeShape.h \
Resource/CAnimationParameters.h \ Resource/CAnimationParameters.h \
UI/WAnimParamsEditor.h \ UI/WAnimParamsEditor.h \
Resource/CCollisionMeshGroup.h Resource/CCollisionMeshGroup.h \
Core/CFrustumPlanes.h
FORMS += \ FORMS += \
UI/CWorldEditorWindow.ui \ UI/CWorldEditorWindow.ui \

View File

@ -328,5 +328,4 @@ void CMaterial::SetLightingEnabled(bool Enabled)
void CMaterial::KillCachedMaterial() void CMaterial::KillCachedMaterial()
{ {
sCurrentMaterial = 0; sCurrentMaterial = 0;
CShader::KillCachedShader();
} }

View File

@ -15,9 +15,10 @@ ENodeType CCollisionNode::NodeType()
return eCollisionNode; return eCollisionNode;
} }
void CCollisionNode::AddToRenderer(CRenderer *pRenderer) void CCollisionNode::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum)
{ {
if (!mpCollision) return; if (!mpCollision) return;
if (!frustum.BoxInFrustum(AABox())) return;
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh); pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);

View File

@ -12,7 +12,7 @@ class CCollisionNode : public CSceneNode
public: public:
CCollisionNode(CSceneManager *pScene, CSceneNode *pParent = 0, CCollisionMeshGroup *pCollision = 0); CCollisionNode(CSceneManager *pScene, CSceneNode *pParent = 0, CCollisionMeshGroup *pCollision = 0);
ENodeType NodeType(); ENodeType NodeType();
void AddToRenderer(CRenderer *pRenderer); void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustumPlanes);
void Draw(ERenderOptions Options); void Draw(ERenderOptions Options);
void DrawAsset(ERenderOptions Options, u32 asset); void DrawAsset(ERenderOptions Options, u32 asset);
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, ERenderOptions options); SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, ERenderOptions options);

View File

@ -24,8 +24,10 @@ ENodeType CLightNode::NodeType()
return eLightNode; return eLightNode;
} }
void CLightNode::AddToRenderer(CRenderer *pRenderer) void CLightNode::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum)
{ {
if (!frustum.BoxInFrustum(AABox())) return;
pRenderer->AddOpaqueMesh(this, 0, CAABox(mPosition + 0.5f, mPosition - 0.5f), eDrawMesh); pRenderer->AddOpaqueMesh(this, 0, CAABox(mPosition + 0.5f, mPosition - 0.5f), eDrawMesh);
if (IsSelected()) if (IsSelected())

View File

@ -10,7 +10,7 @@ class CLightNode : public CSceneNode
public: public:
CLightNode(CSceneManager *pScene, CSceneNode *pParent = 0, CLight *Light = 0); CLightNode(CSceneManager *pScene, CSceneNode *pParent = 0, CLight *Light = 0);
ENodeType NodeType(); ENodeType NodeType();
void AddToRenderer(CRenderer *pRenderer); void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum);
void Draw(ERenderOptions Options); void Draw(ERenderOptions Options);
void DrawAsset(ERenderOptions Options, u32 asset); void DrawAsset(ERenderOptions Options, u32 asset);
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, ERenderOptions options); SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, ERenderOptions options);

View File

@ -16,9 +16,10 @@ ENodeType CModelNode::NodeType()
return eModelNode; return eModelNode;
} }
void CModelNode::AddToRenderer(CRenderer *pRenderer) void CModelNode::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum)
{ {
if (!mpModel) return; if (!mpModel) return;
if (!frustum.BoxInFrustum(AABox())) return;
if (!mpModel->HasTransparency(mActiveMatSet)) if (!mpModel->HasTransparency(mActiveMatSet))
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh); pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);
@ -29,10 +30,13 @@ void CModelNode::AddToRenderer(CRenderer *pRenderer)
for (u32 iSurf = 0; iSurf < SurfaceCount; iSurf++) for (u32 iSurf = 0; iSurf < SurfaceCount; iSurf++)
{ {
if (!mpModel->IsSurfaceTransparent(iSurf, mActiveMatSet)) if (frustum.BoxInFrustum(mpModel->GetSurfaceAABox(iSurf).Transformed(Transform())))
pRenderer->AddOpaqueMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset); {
else if (!mpModel->IsSurfaceTransparent(iSurf, mActiveMatSet))
pRenderer->AddTransparentMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset); pRenderer->AddOpaqueMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset);
else
pRenderer->AddTransparentMesh(this, iSurf, mpModel->GetSurfaceAABox(iSurf).Transformed(Transform()), eDrawAsset);
}
} }
} }

View File

@ -16,7 +16,7 @@ public:
explicit CModelNode(CSceneManager *pScene, CSceneNode *pParent = 0, CModel *pModel = 0); explicit CModelNode(CSceneManager *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
virtual ENodeType NodeType(); virtual ENodeType NodeType();
virtual void AddToRenderer(CRenderer *pRenderer); virtual void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum);
virtual void Draw(ERenderOptions Options); virtual void Draw(ERenderOptions Options);
virtual void DrawAsset(ERenderOptions Options, u32 asset); virtual void DrawAsset(ERenderOptions Options, u32 asset);
virtual void RayAABoxIntersectTest(CRayCollisionTester &Tester); virtual void RayAABoxIntersectTest(CRayCollisionTester &Tester);

View File

@ -15,7 +15,7 @@ public:
return eRootNode; return eRootNode;
} }
inline void AddToRenderer(CRenderer *) {} inline void AddToRenderer(CRenderer *, const CFrustumPlanes&) {}
inline void Draw(ERenderOptions) {} inline void Draw(ERenderOptions) {}
inline void DrawAsset(ERenderOptions, u32) {} inline void DrawAsset(ERenderOptions, u32) {}
inline void RayAABoxIntersectTest(CRayCollisionTester &) {} inline void RayAABoxIntersectTest(CRayCollisionTester &) {}

View File

@ -92,48 +92,58 @@ std::string CScriptNode::PrefixedName() const
return "[" + mpInstance->Template()->TemplateName() + "] " + mpInstance->InstanceName(); return "[" + mpInstance->Template()->TemplateName() + "] " + mpInstance->InstanceName();
} }
void CScriptNode::AddToRenderer(CRenderer *pRenderer) void CScriptNode::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum)
{ {
if (!mpInstance) return; if (!mpInstance) return;
ERenderOptions options = pRenderer->RenderOptions(); ERenderOptions options = pRenderer->RenderOptions();
if (options & eDrawObjectCollision) if (options & eDrawObjectCollision)
mpCollisionNode->AddToRenderer(pRenderer); mpCollisionNode->AddToRenderer(pRenderer, frustum);
if (options & eDrawObjects) if (options & eDrawObjects)
{ {
if (!mpActiveModel) if (frustum.BoxInFrustum(AABox()))
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);
else
{ {
if (!mpActiveModel->IsBuffered()) if (!mpActiveModel)
mpActiveModel->BufferGL();
if (!mpActiveModel->HasTransparency(0))
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh); pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);
else else
{ {
u32 SubmeshCount = mpActiveModel->GetSurfaceCount(); if (!mpActiveModel->IsBuffered())
mpActiveModel->BufferGL();
for (u32 s = 0; s < SubmeshCount; s++) if (!mpActiveModel->HasTransparency(0))
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);
else
{ {
if (!mpActiveModel->IsSurfaceTransparent(s, 0)) u32 SubmeshCount = mpActiveModel->GetSurfaceCount();
pRenderer->AddOpaqueMesh(this, s, mpActiveModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset);
else for (u32 s = 0; s < SubmeshCount; s++)
pRenderer->AddTransparentMesh(this, s, mpActiveModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset); {
if (frustum.BoxInFrustum(mpActiveModel->GetSurfaceAABox(s).Transformed(Transform())))
{
if (!mpActiveModel->IsSurfaceTransparent(s, 0))
pRenderer->AddOpaqueMesh(this, s, mpActiveModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset);
else
pRenderer->AddTransparentMesh(this, s, mpActiveModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset);
}
}
} }
} }
} }
} }
if (IsSelected() && (options & ((ERenderOptions) (eDrawObjects | eDrawObjectCollision))) != 0) if (IsSelected())
{ {
// Script nodes always draw their selections regardless of frustum planes
// in order to ensure that script connection lines don't get improperly culled.
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawSelection); pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawSelection);
if (mHasVolumePreview) if (mHasVolumePreview)
mpVolumePreviewNode->AddToRenderer(pRenderer); mpVolumePreviewNode->AddToRenderer(pRenderer, frustum);
} }
} }

View File

@ -21,7 +21,7 @@ public:
CScriptNode(CSceneManager *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0); CScriptNode(CSceneManager *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
ENodeType NodeType(); ENodeType NodeType();
std::string PrefixedName() const; std::string PrefixedName() const;
void AddToRenderer(CRenderer *pRenderer); void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum);
void Draw(ERenderOptions Options); void Draw(ERenderOptions Options);
void DrawAsset(ERenderOptions Options, u32 Asset); void DrawAsset(ERenderOptions Options, u32 Asset);
void DrawSelection(); void DrawSelection();

View File

@ -19,10 +19,11 @@ ENodeType CStaticNode::NodeType()
return eStaticNode; return eStaticNode;
} }
void CStaticNode::AddToRenderer(CRenderer *pRenderer) void CStaticNode::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum)
{ {
if (!mpModel) return; if (!mpModel) return;
if (mpModel->IsOccluder()) return; if (mpModel->IsOccluder()) return;
if (!frustum.BoxInFrustum(AABox())) return;
if (!mpModel->IsTransparent()) if (!mpModel->IsTransparent())
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh); pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawMesh);
@ -32,7 +33,8 @@ void CStaticNode::AddToRenderer(CRenderer *pRenderer)
u32 sm_count = mpModel->GetSurfaceCount(); u32 sm_count = mpModel->GetSurfaceCount();
for (u32 s = 0; s < sm_count; s++) for (u32 s = 0; s < sm_count; s++)
{ {
pRenderer->AddTransparentMesh(this, s, mpModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset); if (frustum.BoxInFrustum(mpModel->GetSurfaceAABox(s).Transformed(Transform())))
pRenderer->AddTransparentMesh(this, s, mpModel->GetSurfaceAABox(s).Transformed(Transform()), eDrawAsset);
} }
} }

View File

@ -11,7 +11,7 @@ class CStaticNode : public CSceneNode
public: public:
CStaticNode(CSceneManager *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0); CStaticNode(CSceneManager *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
ENodeType NodeType(); ENodeType NodeType();
void AddToRenderer(CRenderer *pRenderer); void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum);
void Draw(ERenderOptions Options); void Draw(ERenderOptions Options);
void DrawAsset(ERenderOptions Options, u32 asset); void DrawAsset(ERenderOptions Options, u32 asset);
void RayAABoxIntersectTest(CRayCollisionTester &Tester); void RayAABoxIntersectTest(CRayCollisionTester &Tester);

View File

@ -42,7 +42,7 @@ CGizmo::~CGizmo()
{ {
} }
void CGizmo::AddToRenderer(CRenderer *pRenderer) void CGizmo::AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes&)
{ {
// Transform is updated every frame even if the user doesn't modify the gizmo // Transform is updated every frame even if the user doesn't modify the gizmo
// in order to account for scale changes based on camera distance // in order to account for scale changes based on camera distance

View File

@ -124,7 +124,7 @@ public:
CGizmo(); CGizmo();
~CGizmo(); ~CGizmo();
void AddToRenderer(CRenderer *pRenderer); void AddToRenderer(CRenderer *pRenderer, const CFrustumPlanes& frustum);
void DrawAsset(ERenderOptions options, u32 asset); void DrawAsset(ERenderOptions options, u32 asset);
void IncrementSize(); void IncrementSize();

View File

@ -49,7 +49,7 @@ void CModelEditorViewport::Paint()
else if (mMode == eDrawMesh) else if (mMode == eDrawMesh)
{ {
CDrawUtil::DrawGrid(); CDrawUtil::DrawGrid();
mpModelNode->AddToRenderer(mpRenderer); mpModelNode->AddToRenderer(mpRenderer, mCamera.FrustumPlanes());
mpRenderer->RenderBuckets(mCamera); mpRenderer->RenderBuckets(mCamera);
} }

View File

@ -135,7 +135,7 @@ void CSceneViewport::Paint()
} }
mCamera.LoadMatrices(); mCamera.LoadMatrices();
mpScene->AddSceneToRenderer(mpRenderer); mpScene->AddSceneToRenderer(mpRenderer, mCamera);
mpRenderer->RenderBuckets(mCamera); mpRenderer->RenderBuckets(mCamera);
mpRenderer->RenderBloom(); mpRenderer->RenderBloom();
@ -146,7 +146,7 @@ void CSceneViewport::Paint()
mpRenderer->ClearDepthBuffer(); mpRenderer->ClearDepthBuffer();
pGizmo->UpdateForCamera(mCamera); pGizmo->UpdateForCamera(mCamera);
pGizmo->AddToRenderer(mpRenderer); pGizmo->AddToRenderer(mpRenderer, mCamera.FrustumPlanes());
mpRenderer->RenderBuckets(mCamera); mpRenderer->RenderBuckets(mCamera);
} }

View File

@ -89,7 +89,7 @@ void CWorldEditorWindow::PaintViewport(double DeltaTime)
mCamera.ProcessKeyInput((EKeyInputs) mViewportKeysPressed, DeltaTime); mCamera.ProcessKeyInput((EKeyInputs) mViewportKeysPressed, DeltaTime);
mCamera.LoadMatrices(); mCamera.LoadMatrices();
mpRenderer->BeginFrame(); mpRenderer->BeginFrame();
mpSceneManager->AddSceneToRenderer(mpRenderer); mpSceneManager->AddSceneToRenderer(mpRenderer, mCamera);
if (mShouldDrawSky) if (mShouldDrawSky)