forked from mirrors/0ad
Optimise out of frustum rendering of texture overlays.
Reviewed By: wraitii Commented By: Stan Differential Revision: https://code.wildfiregames.com/D1847 This was SVN commit r23229.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/TexturedLineRData.h"
|
||||
|
||||
SOverlayTexturedLine::LineCapType SOverlayTexturedLine::StrToLineCapType(const std::wstring& str)
|
||||
{
|
||||
@@ -57,3 +58,12 @@ void SOverlayTexturedLine::CreateOverlayTexture(const SOverlayDescriptor* overla
|
||||
|
||||
ENSURE(m_TextureBase);
|
||||
}
|
||||
|
||||
bool SOverlayTexturedLine::IsVisibleInFrustum(const CFrustum& frustum) const
|
||||
{
|
||||
// If we don't have render data, we don't have actual bounds and we need
|
||||
// to calculate them on a prerendering stage.
|
||||
if (!m_RenderData)
|
||||
return true;
|
||||
return m_RenderData->IsVisibleInFrustum(frustum);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "maths/FixedVector3D.h"
|
||||
#include "ps/CStrIntern.h"
|
||||
|
||||
class CFrustum;
|
||||
class CTerrain;
|
||||
class CSimContext;
|
||||
class CTexturedLineRData;
|
||||
@@ -134,6 +135,8 @@ struct SOverlayTexturedLine
|
||||
for (size_t i = 0; i < points.size(); ++i)
|
||||
PushCoords(points[i]);
|
||||
}
|
||||
|
||||
bool IsVisibleInFrustum(const CFrustum& frustum) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "TexturedLineRData.h"
|
||||
|
||||
#include "graphics/Frustum.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "maths/Quaternion.h"
|
||||
@@ -303,6 +304,10 @@ void CTexturedLineRData::Update(const SOverlayTexturedLine& line)
|
||||
|
||||
ENSURE(indices.size() % 3 == 0); // GL_TRIANGLES indices, so must be multiple of 3
|
||||
|
||||
m_BoundingBox = CBoundingBoxAligned();
|
||||
for (const SVertex& vertex : vertices)
|
||||
m_BoundingBox += vertex.m_Position;
|
||||
|
||||
m_VB = g_VBMan.Allocate(sizeof(SVertex), vertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER);
|
||||
if (m_VB) // allocation might fail (e.g. due to too many vertices)
|
||||
{
|
||||
@@ -436,3 +441,8 @@ void CTexturedLineRData::CreateLineCap(const SOverlayTexturedLine& line, const C
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CTexturedLineRData::IsVisibleInFrustum(const CFrustum& frustum) const
|
||||
{
|
||||
return frustum.IsBoxVisible(m_BoundingBox);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2012 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -22,8 +22,11 @@
|
||||
#include "graphics/RenderableObject.h"
|
||||
#include "graphics/ShaderProgramPtr.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "maths/BoundingBoxAligned.h"
|
||||
#include "renderer/VertexBufferManager.h"
|
||||
|
||||
class CFrustum;
|
||||
|
||||
/**
|
||||
* Rendering data for an STexturedOverlayLine.
|
||||
*
|
||||
@@ -57,6 +60,8 @@ public:
|
||||
void Update(const SOverlayTexturedLine& line);
|
||||
void Render(const SOverlayTexturedLine& line, const CShaderProgramPtr& shader);
|
||||
|
||||
bool IsVisibleInFrustum(const CFrustum& frustum) const;
|
||||
|
||||
protected:
|
||||
|
||||
struct SVertex
|
||||
@@ -90,6 +95,7 @@ protected:
|
||||
|
||||
CVertexBuffer::VBChunk* m_VB;
|
||||
CVertexBuffer::VBChunk* m_VBIndices;
|
||||
CBoundingBoxAligned m_BoundingBox;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_TEXTUREDLINERDATA
|
||||
|
||||
@@ -165,7 +165,7 @@ void CCmpRallyPointRenderer::HandleMessage(const CMessage& msg, bool UNUSED(glob
|
||||
if (m_Displayed && IsSet())
|
||||
{
|
||||
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
|
||||
RenderSubmit(msgData.collector);
|
||||
RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -920,13 +920,17 @@ void CCmpRallyPointRenderer::MergeVisibilitySegments(std::vector<SVisibilitySegm
|
||||
}
|
||||
}
|
||||
|
||||
void CCmpRallyPointRenderer::RenderSubmit(SceneCollector& collector)
|
||||
void CCmpRallyPointRenderer::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling)
|
||||
{
|
||||
// We only get here if the rally point is set and should be displayed
|
||||
for(std::vector<SOverlayTexturedLine>& row : m_TexturedOverlayLines)
|
||||
for (SOverlayTexturedLine& col : row)
|
||||
if (!col.m_Coords.empty())
|
||||
collector.Submit(&col);
|
||||
for (SOverlayTexturedLine& col : row) {
|
||||
if (col.m_Coords.empty())
|
||||
continue;
|
||||
if (culling && !col.IsVisibleInFrustum(frustum))
|
||||
continue;
|
||||
collector.Submit(&col);
|
||||
}
|
||||
|
||||
if (m_EnableDebugNodeOverlay && !m_DebugNodeOverlays.empty())
|
||||
{
|
||||
|
||||
@@ -268,7 +268,7 @@ private:
|
||||
*/
|
||||
static void MergeVisibilitySegments(std::vector<SVisibilitySegment>& segments);
|
||||
|
||||
void RenderSubmit(SceneCollector& collector);
|
||||
void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_TYPE(RallyPointRenderer)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
case MT_RenderSubmit:
|
||||
{
|
||||
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
|
||||
RenderSubmit(msgData.collector);
|
||||
RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -186,14 +186,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSubmit(SceneCollector& collector)
|
||||
void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling)
|
||||
{
|
||||
if (!m_RangeOverlayData.size())
|
||||
return;
|
||||
|
||||
for (const RangeOverlayData& rangeOverlay : m_RangeOverlayData)
|
||||
if (rangeOverlay.second)
|
||||
{
|
||||
if (culling && !rangeOverlay.second->IsVisibleInFrustum(frustum))
|
||||
continue;
|
||||
collector.Submit(rangeOverlay.second);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2018 Wildfire Games.
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
return m_EditorOnly;
|
||||
}
|
||||
|
||||
void RenderSubmit(SceneCollector& collector);
|
||||
void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
|
||||
|
||||
/**
|
||||
* Draw a textured line overlay. The selection overlays for structures are based solely on footprint shape.
|
||||
@@ -251,6 +251,8 @@ private:
|
||||
SOverlayTexturedLine* m_BuildingOverlay;
|
||||
SOverlayQuad* m_UnitOverlay;
|
||||
|
||||
CBoundingBoxAligned m_UnitOverlayBoundingBox;
|
||||
|
||||
SOverlayLine* m_DebugBoundingBoxOverlay;
|
||||
SOverlayLine* m_DebugSelectionBoxOverlay;
|
||||
|
||||
@@ -358,7 +360,7 @@ void CCmpSelectable::HandleMessage(const CMessage& msg, bool UNUSED(global))
|
||||
PROFILE("Selectable::RenderSubmit");
|
||||
|
||||
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
|
||||
RenderSubmit(msgData.collector);
|
||||
RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -522,7 +524,8 @@ void CCmpSelectable::UpdateDynamicOverlay(float frameOffset)
|
||||
points.push_back(CVector2D(position + unitX * halfSizeX + unitZ *(-halfSizeZ))); // bottom right
|
||||
points.push_back(CVector2D(position + unitX * halfSizeX + unitZ * halfSizeZ)); // top right
|
||||
|
||||
for (int i=0; i < 4; i++)
|
||||
m_UnitOverlayBoundingBox = CBoundingBoxAligned();
|
||||
for (size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
float quadY = std::max(
|
||||
terrain->GetExactGroundLevel(points[i].X, points[i].Y),
|
||||
@@ -530,10 +533,11 @@ void CCmpSelectable::UpdateDynamicOverlay(float frameOffset)
|
||||
);
|
||||
|
||||
m_UnitOverlay->m_Corners[i] = CVector3D(points[i].X, quadY, points[i].Y);
|
||||
m_UnitOverlayBoundingBox += m_UnitOverlay->m_Corners[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CCmpSelectable::RenderSubmit(SceneCollector& collector)
|
||||
void CCmpSelectable::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling)
|
||||
{
|
||||
// don't render selection overlay if it's not gonna be visible
|
||||
if (!ICmpSelectable::m_OverrideVisible)
|
||||
@@ -560,11 +564,15 @@ void CCmpSelectable::RenderSubmit(SceneCollector& collector)
|
||||
UpdateTexturedLineOverlay(&m_OverlayDescriptor, *m_BuildingOverlay, 0);
|
||||
}
|
||||
m_BuildingOverlay->m_Color = m_Color; // done separately so alpha changes don't require a full update call
|
||||
if (culling && !m_BuildingOverlay->IsVisibleInFrustum(frustum))
|
||||
break;
|
||||
collector.Submit(m_BuildingOverlay);
|
||||
}
|
||||
break;
|
||||
case DYNAMIC_QUAD:
|
||||
{
|
||||
if (culling && !frustum.IsBoxVisible(m_UnitOverlayBoundingBox))
|
||||
break;
|
||||
if (m_UnitOverlay)
|
||||
collector.Submit(m_UnitOverlay);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
case MT_RenderSubmit:
|
||||
{
|
||||
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
|
||||
RenderSubmit(msgData.collector);
|
||||
RenderSubmit(msgData.collector, msgData.frustum, msgData.culling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ public:
|
||||
|
||||
void Interpolate(float frameTime, float frameOffset);
|
||||
|
||||
void RenderSubmit(SceneCollector& collector);
|
||||
void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling);
|
||||
|
||||
void SetVisibility(bool visible)
|
||||
{
|
||||
@@ -691,13 +691,17 @@ void CCmpTerritoryManager::Interpolate(float frameTime, float UNUSED(frameOffset
|
||||
}
|
||||
}
|
||||
|
||||
void CCmpTerritoryManager::RenderSubmit(SceneCollector& collector)
|
||||
void CCmpTerritoryManager::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling)
|
||||
{
|
||||
if (!m_Visible)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < m_BoundaryLines.size(); ++i)
|
||||
{
|
||||
if (culling && !m_BoundaryLines[i].overlay.IsVisibleInFrustum(frustum))
|
||||
continue;
|
||||
collector.Submit(&m_BoundaryLines[i].overlay);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_DebugBoundaryLineNodes.size(); ++i)
|
||||
collector.Submit(&m_DebugBoundaryLineNodes[i]);
|
||||
|
||||
Reference in New Issue
Block a user