1
0
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:
vladislavbelov
2019-12-10 23:13:37 +00:00
parent 6110d108c1
commit df329d1b81
9 changed files with 69 additions and 20 deletions
+11 -1
View File
@@ -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);
}
+3
View File
@@ -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;
};
/**
+11 -1
View File
@@ -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);
}
+7 -1
View File
@@ -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]);