Added support for depth groups on the renderer

This commit is contained in:
parax0 2016-04-27 23:32:02 -06:00
parent 5b63556527
commit 59d8de0f31
21 changed files with 182 additions and 123 deletions

View File

@ -193,7 +193,8 @@ HEADERS += \
Resource/Factory/CAnimationLoader.h \
Render/CBoneTransformData.h \
Resource/CSkin.h \
Resource/Factory/CSkinLoader.h
Resource/Factory/CSkinLoader.h \
Render/EDepthGroup.h
# Source Files
SOURCES += \

View File

@ -4,7 +4,8 @@
#include "CRenderer.h"
#include <algorithm>
void CRenderBucket::Add(const SRenderablePtr& rkPtr)
// ************ CSubBucket ************
void CRenderBucket::CSubBucket::Add(const SRenderablePtr& rkPtr)
{
if (mSize >= mEstSize)
mRenderables.push_back(rkPtr);
@ -14,15 +15,13 @@ void CRenderBucket::Add(const SRenderablePtr& rkPtr)
mSize++;
}
void CRenderBucket::Sort(CCamera* pCamera)
{
if (mEnableDepthSort)
void CRenderBucket::CSubBucket::Sort(const CCamera* pkCamera, bool DebugVisualization)
{
std::stable_sort(mRenderables.begin(), mRenderables.begin() + mSize,
[&, pCamera](const SRenderablePtr& rkLeft, const SRenderablePtr& rkRight) -> bool
[&, pkCamera](const SRenderablePtr& rkLeft, const SRenderablePtr& rkRight) -> bool
{
CVector3f CamPos = pCamera->Position();
CVector3f CamDir = pCamera->Direction();
CVector3f CamPos = pkCamera->Position();
CVector3f CamDir = pkCamera->Direction();
CVector3f DistL = rkLeft.AABox.ClosestPointAlongVector(CamDir) - CamPos;
CVector3f DistR = rkRight.AABox.ClosestPointAlongVector(CamDir) - CamPos;
@ -31,16 +30,16 @@ void CRenderBucket::Sort(CCamera* pCamera)
return (DotL > DotR);
});
if (mEnableDepthSortDebugVisualization)
if (DebugVisualization)
{
for (u32 iPtr = 0; iPtr < mSize; iPtr++)
{
SRenderablePtr *pPtr = &mRenderables[iPtr];
CVector3f Point = pPtr->AABox.ClosestPointAlongVector(pCamera->Direction());
CVector3f Point = pPtr->AABox.ClosestPointAlongVector(pkCamera->Direction());
CDrawUtil::DrawWireCube(pPtr->AABox, CColor::skWhite);
CVector3f Dist = Point - pCamera->Position();
float Dot = Dist.Dot(pCamera->Direction());
CVector3f Dist = Point - pkCamera->Position();
float Dot = Dist.Dot(pkCamera->Direction());
if (Dot < 0.f) Dot = -Dot;
if (Dot > 50.f) Dot = 50.f;
float Intensity = 1.f - (Dot / 50.f);
@ -52,25 +51,48 @@ void CRenderBucket::Sort(CCamera* pCamera)
}
}
}
}
void CRenderBucket::Clear()
void CRenderBucket::CSubBucket::Clear()
{
mEstSize = mSize;
if (mRenderables.size() > mSize) mRenderables.resize(mSize);
mSize = 0;
}
void CRenderBucket::Draw(const SViewInfo& rkViewInfo)
void CRenderBucket::CSubBucket::Draw(const SViewInfo& rkViewInfo)
{
FRenderOptions Options = rkViewInfo.pRenderer->RenderOptions();
for (u32 iPtr = 0; iPtr < mSize; iPtr++)
{
if (mRenderables[iPtr].Command == eDrawMesh)
mRenderables[iPtr].pRenderable->Draw(Options, mRenderables[iPtr].ComponentIndex, rkViewInfo);
const SRenderablePtr& rkPtr = mRenderables[iPtr];
else if (mRenderables[iPtr].Command == eDrawSelection)
mRenderables[iPtr].pRenderable->DrawSelection();
if (rkPtr.Command == eDrawMesh)
rkPtr.pRenderable->Draw(Options, rkPtr.ComponentIndex, rkViewInfo);
else if (rkPtr.Command == eDrawSelection)
rkPtr.pRenderable->DrawSelection();
}
}
// ************ CRenderBucket ************
void CRenderBucket::Add(const SRenderablePtr& rkPtr, bool Transparent)
{
if (Transparent)
mTransparentSubBucket.Add(rkPtr);
else
mOpaqueSubBucket.Add(rkPtr);
}
void CRenderBucket::Clear()
{
mOpaqueSubBucket.Clear();
mTransparentSubBucket.Clear();
}
void CRenderBucket::Draw(const SViewInfo& rkViewInfo)
{
mOpaqueSubBucket.Draw(rkViewInfo);
mTransparentSubBucket.Sort(rkViewInfo.pCamera, mEnableDepthSortDebugVisualization);
mTransparentSubBucket.Draw(rkViewInfo);
}

View File

@ -12,27 +12,35 @@
class CRenderBucket
{
bool mEnableDepthSort;
bool mEnableDepthSortDebugVisualization;
class CSubBucket
{
std::vector<SRenderablePtr> mRenderables;
u32 mEstSize;
u32 mSize;
public:
CRenderBucket()
: mEnableDepthSort(false)
, mEnableDepthSortDebugVisualization(false)
, mEstSize(0)
CSubBucket()
: mEstSize(0)
, mSize(0)
{}
inline void SetDepthSortingEnabled(bool Enabled)
{
mEnableDepthSort = Enabled;
}
void Add(const SRenderablePtr &rkPtr);
void Sort(CCamera* pCamera);
void Sort(const CCamera *pkCamera, bool DebugVisualization);
void Clear();
void Draw(const SViewInfo& rkViewInfo);
};
CSubBucket mOpaqueSubBucket;
CSubBucket mTransparentSubBucket;
public:
CRenderBucket()
: mEnableDepthSortDebugVisualization(false)
{}
void Add(const SRenderablePtr& rkPtr, bool Transparent);
void Clear();
void Draw(const SViewInfo& rkViewInfo);
};

View File

@ -24,7 +24,6 @@ CRenderer::CRenderer()
, mInitialized(false)
, mContextIndex(-1)
{
mTransparentBucket.SetDepthSortingEnabled(true);
sNumRenderers++;
}
@ -127,11 +126,21 @@ void CRenderer::RenderBuckets(const SViewInfo& rkViewInfo)
glDepthRange(0.f, 1.f);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
mOpaqueBucket.Draw(rkViewInfo);
mOpaqueBucket.Clear();
mTransparentBucket.Sort(rkViewInfo.pCamera);
mTransparentBucket.Draw(rkViewInfo);
mTransparentBucket.Clear();
mBackgroundBucket.Draw(rkViewInfo);
mBackgroundBucket.Clear();
ClearDepthBuffer();
mMidgroundBucket.Draw(rkViewInfo);
mMidgroundBucket.Clear();
ClearDepthBuffer();
RenderBloom();
ClearDepthBuffer();
rkViewInfo.pCamera->LoadMatrices();
mForegroundBucket.Draw(rkViewInfo);
mForegroundBucket.Clear();
ClearDepthBuffer();
mUIBucket.Draw(rkViewInfo);
mUIBucket.Clear();
ClearDepthBuffer();
}
void CRenderer::RenderBloom()
@ -266,24 +275,32 @@ void CRenderer::RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo)
pSkyboxModel->Draw(mOptions, 0);
}
void CRenderer::AddOpaqueMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command)
void CRenderer::AddMesh(IRenderable *pRenderable, int ComponentIndex, const CAABox& rkAABox, bool Transparent, ERenderCommand Command, EDepthGroup DepthGroup /*= eMidground*/)
{
SRenderablePtr Ptr;
Ptr.pRenderable = pRenderable;
Ptr.ComponentIndex = AssetID;
Ptr.ComponentIndex = ComponentIndex;
Ptr.AABox = rkAABox;
Ptr.Command = Command;
mOpaqueBucket.Add(Ptr);
}
void CRenderer::AddTransparentMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command)
switch (DepthGroup)
{
SRenderablePtr Ptr;
Ptr.pRenderable = pRenderable;
Ptr.ComponentIndex = AssetID;
Ptr.AABox = rkAABox;
Ptr.Command = Command;
mTransparentBucket.Add(Ptr);
case eBackground:
mBackgroundBucket.Add(Ptr, Transparent);
break;
case eMidground:
mMidgroundBucket.Add(Ptr, Transparent);
break;
case eForeground:
mForegroundBucket.Add(Ptr, Transparent);
break;
case eUI:
mUIBucket.Add(Ptr, Transparent);
break;
}
}
void CRenderer::BeginFrame()

View File

@ -4,8 +4,9 @@
#include "CCamera.h"
#include "CGraphics.h"
#include "CRenderBucket.h"
#include "FRenderOptions.h"
#include "EDepthGroup.h"
#include "ERenderCommand.h"
#include "FRenderOptions.h"
#include "SRenderablePtr.h"
#include "SViewInfo.h"
#include "Core/OpenGL/CFramebuffer.h"
@ -33,8 +34,6 @@ private:
bool mDrawGrid;
CColor mClearColor;
u32 mContextIndex;
CRenderBucket mOpaqueBucket;
CRenderBucket mTransparentBucket;
bool mInitialized;
u32 mViewportWidth, mViewportHeight;
u32 mBloomWidth, mBloomHeight;
@ -44,6 +43,11 @@ private:
CFramebuffer mBloomFramebuffers[3];
GLint mDefaultFramebuffer;
CRenderBucket mBackgroundBucket;
CRenderBucket mMidgroundBucket;
CRenderBucket mForegroundBucket;
CRenderBucket mUIBucket;
// Static Members
static u32 sNumRenderers;
@ -68,8 +72,7 @@ public:
void RenderBuckets(const SViewInfo& rkViewInfo);
void RenderBloom();
void RenderSky(CModel *pSkyboxModel, const SViewInfo& rkViewInfo);
void AddOpaqueMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command);
void AddTransparentMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, ERenderCommand Command);
void AddMesh(IRenderable *pRenderable, int AssetID, const CAABox& rkAABox, bool Transparent, ERenderCommand Command, EDepthGroup DepthGroup = eMidground);
void BeginFrame();
void EndFrame();
void ClearDepthBuffer();

View File

@ -0,0 +1,13 @@
#ifndef EDEPTHGROUP
#define EDEPTHGROUP
enum EDepthGroup
{
eBackground,
eMidground,
eForeground,
eUI
};
#endif // EDEPTHGROUP

View File

@ -40,7 +40,10 @@ CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
bool CBone::IsRoot() const
{
return (mpParent == nullptr);
// In Retro's engine most skeletons have another bone named Skeleton_Root parented directly under the
// actual root bone... that bone sometimes acts as the actual root (transforming the entire skeleton),
// so we need to account for both
return (mpParent == nullptr || mpParent->Parent() == nullptr);
}
// ************ CSkeleton ************

View File

@ -35,9 +35,9 @@ void CCharacterNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkView
if (pModel)
{
if (!pModel->HasTransparency(0))
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
else
AddSurfacesToRenderer(pRenderer, pModel, 0, rkViewInfo, false);
AddSurfacesToRenderer(pRenderer, pModel, 0, rkViewInfo, eMidground, false);
}
if (pSkel)
@ -46,7 +46,7 @@ void CCharacterNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkView
pSkel->UpdateTransform(mTransformData, pAnim, mAnimTime, false);
if (rkViewInfo.ShowFlags.HasFlag(eShowSkeletons))
pRenderer->AddOpaqueMesh(this, -2, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -2, AABox(), false, eDrawMesh, eForeground);
}
}

View File

@ -21,10 +21,10 @@ void CCollisionNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkView
if (!rkViewInfo.ViewFrustum.BoxInFrustum(AABox())) return;
if (rkViewInfo.GameMode) return;
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
if (mSelected)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, const SViewInfo& rkViewInfo)

View File

@ -30,14 +30,14 @@ void CLightNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo
if (rkViewInfo.GameMode) return;
if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox()))
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
if (IsSelected() && mpLight->Type() == eCustom)
{
CAABox RadiusBox = (CAABox::skOne * 2.f * mpLight->GetRadius()) + mPosition;
if (rkViewInfo.ViewFrustum.BoxInFrustum(RadiusBox))
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
}

View File

@ -36,12 +36,12 @@ void CModelNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo
if (rkViewInfo.GameMode) return;
if (!mpModel->HasTransparency(mActiveMatSet))
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
else
AddSurfacesToRenderer(pRenderer, mpModel, mActiveMatSet, rkViewInfo);
if (mSelected)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
void CModelNode::Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& rkViewInfo)

View File

@ -224,7 +224,7 @@ void CSceneNode::DrawRotationArrow() const
spArrowModel->Draw(eNoRenderOptions, 0);
}
void CSceneNode::AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& rkViewInfo, bool DoFrustumTest /*= true*/)
void CSceneNode::AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& rkViewInfo, EDepthGroup DepthGroup /*= eMidground*/, bool DoFrustumTest /*= true*/)
{
u32 SurfaceCount = pModel->GetSurfaceCount();
@ -234,10 +234,7 @@ void CSceneNode::AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32
if (!DoFrustumTest || rkViewInfo.ViewFrustum.BoxInFrustum(TransformedBox))
{
if (!pModel->IsSurfaceTransparent(iSurf, MatSet))
pRenderer->AddOpaqueMesh(this, (int) iSurf, TransformedBox, eDrawMesh);
else
pRenderer->AddTransparentMesh(this, (int) iSurf, TransformedBox, eDrawMesh);
pRenderer->AddMesh(this, (int) iSurf, TransformedBox, pModel->IsSurfaceTransparent(iSurf, MatSet), eDrawMesh, DepthGroup);
}
}
}

View File

@ -2,6 +2,7 @@
#define CSCENENODE_H
#include "ENodeType.h"
#include "Core/Render/EDepthGroup.h"
#include "Core/Render/FRenderOptions.h"
#include "Core/Render/IRenderable.h"
#include "Core/Resource/CLight.h"
@ -79,7 +80,7 @@ public:
void LoadLights(const SViewInfo& rkViewInfo);
void DrawBoundingBox() const;
void DrawRotationArrow() const;
void AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& rkViewInfo, bool DoFrustumTest = true);
void AddSurfacesToRenderer(CRenderer *pRenderer, CModel *pModel, u32 MatSet, const SViewInfo& rkViewInfo, EDepthGroup DepthGroup = eMidground, bool DoFrustumTest = true);
// Transform
void Translate(const CVector3f& rkTranslation, ETransformSpace TransformSpace);

View File

@ -133,12 +133,12 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox()))
{
if (!mpActiveModel)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
else
{
if (!mpActiveModel->HasTransparency(0))
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
else
AddSurfacesToRenderer(pRenderer, mpActiveModel, 0, rkViewInfo);
}
@ -151,7 +151,7 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
// Script nodes always draw their selections regardless of frustum planes
// in order to ensure that script connection lines don't get improperly culled.
if (ShouldDraw)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
if (mHasVolumePreview && (!mpExtra || mpExtra->ShouldDrawVolume()))
mpVolumePreviewNode->AddToRenderer(pRenderer, rkViewInfo);
@ -193,6 +193,8 @@ void CScriptNode::Draw(FRenderOptions Options, int ComponentIndex, const SViewIn
// Draw model if possible!
if (mpActiveModel)
{
if (mpActiveModel->IsSkinned()) CGraphics::LoadIdentityBoneTransforms();
if (mpExtra) CGraphics::sPixelBlock.TevColor = mpExtra->TevColor();
else CGraphics::sPixelBlock.TevColor = CColor::skWhite;

View File

@ -34,7 +34,7 @@ void CStaticNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
if (!rkViewInfo.ViewFrustum.BoxInFrustum(AABox())) return;
if (!mpModel->IsTransparent())
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
else
{
@ -44,12 +44,12 @@ void CStaticNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
CAABox TransformedBox = mpModel->GetSurfaceAABox(iSurf).Transformed(Transform());
if (rkViewInfo.ViewFrustum.BoxInFrustum(TransformedBox))
pRenderer->AddTransparentMesh(this, iSurf, TransformedBox, eDrawMesh);
pRenderer->AddMesh(this, iSurf, TransformedBox, true, eDrawMesh);
}
}
if (mSelected && !rkViewInfo.GameMode)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
void CStaticNode::Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& rkViewInfo)

View File

@ -183,9 +183,9 @@ void CDamageableTriggerExtra::AddToRenderer(CRenderer *pRenderer, const SViewInf
if (mRenderSide != eNoRender)
{
if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox()))
pRenderer->AddTransparentMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), true, eDrawMesh);
if (mpParent->IsSelected() && !rkViewInfo.GameMode)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
}

View File

@ -67,10 +67,10 @@ void CDoorExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo
if (mpShieldModel->HasTransparency(0))
AddSurfacesToRenderer(pRenderer, mpShieldModel, 0, rkViewInfo);
else
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawMesh);
if (mpParent->IsSelected() && !rkViewInfo.GameMode)
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
pRenderer->AddMesh(this, -1, AABox(), false, eDrawSelection);
}
}

View File

@ -32,7 +32,7 @@ void CRadiusSphereExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rk
CAABox BoundingBox = Bounds();
if (rkViewInfo.ViewFrustum.BoxInFrustum(BoundingBox))
pRenderer->AddOpaqueMesh(this, -1, BoundingBox, eDrawMesh);
pRenderer->AddMesh(this, -1, BoundingBox, false, eDrawMesh);
}
}

View File

@ -167,7 +167,7 @@ void CWaypointExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkView
CScriptNode *pNode = mLinks[iLink].pWaypoint;
if (pNode->IsVisible() && !pNode->IsSelected() && rkViewInfo.ViewFrustum.BoxInFrustum(mLinks[iLink].LineAABB))
pRenderer->AddOpaqueMesh(this, iLink, mLinks[iLink].LineAABB, eDrawMesh);
pRenderer->AddMesh(this, iLink, mLinks[iLink].LineAABB, false, eDrawMesh);
}
}
}

View File

@ -57,11 +57,7 @@ void CGizmo::AddToRenderer(CRenderer *pRenderer, const SViewInfo&)
u32 SetID = (IsHighlighted ? 1 : 0);
// Add to renderer...
if (pModel->HasTransparency(SetID))
pRenderer->AddTransparentMesh(this, iPart, pModel->AABox().Transformed(mTransform), eDrawMesh);
else
pRenderer->AddOpaqueMesh(this, iPart, pModel->AABox().Transformed(mTransform), eDrawMesh);
pRenderer->AddMesh(this, iPart, pModel->AABox().Transformed(mTransform), pModel->HasTransparency(SetID), eDrawMesh, eForeground);
pPart++;
}
}

View File

@ -299,6 +299,7 @@ void CSceneViewport::Paint()
mpRenderer->BeginFrame();
// todo: The sky should really just be a regular node in the background depth group instead of having special rendering code here
if ((mViewInfo.ShowFlags & eShowSky) || mViewInfo.GameMode)
{
CModel *pSky = mpScene->ActiveSkybox();
@ -308,6 +309,14 @@ void CSceneViewport::Paint()
mCamera.LoadMatrices();
mpScene->AddSceneToRenderer(mpRenderer, mViewInfo);
// Add gizmo to renderer
if (mpEditor->IsGizmoVisible() && !mViewInfo.GameMode)
{
CGizmo *pGizmo = mpEditor->Gizmo();
pGizmo->UpdateForCamera(mCamera);
pGizmo->AddToRenderer(mpRenderer, mViewInfo);
}
// Draw the line for the link the user is editing. This is a little hacky but I don't really have a better way to do this atm.
if (mLinkLineEnabled)
{
@ -318,19 +327,6 @@ void CSceneViewport::Paint()
}
mpRenderer->RenderBuckets(mViewInfo);
mpRenderer->RenderBloom();
if (mpEditor->IsGizmoVisible() && !mViewInfo.GameMode)
{
CGizmo *pGizmo = mpEditor->Gizmo();
mCamera.LoadMatrices();
mpRenderer->ClearDepthBuffer();
pGizmo->UpdateForCamera(mCamera);
pGizmo->AddToRenderer(mpRenderer, mViewInfo);
mpRenderer->RenderBuckets(mViewInfo);
}
mpRenderer->EndFrame();
}