Index: ps/trunk/source/graphics/Overlay.h =================================================================== --- ps/trunk/source/graphics/Overlay.h +++ ps/trunk/source/graphics/Overlay.h @@ -25,6 +25,7 @@ #include "maths/FixedVector3D.h" #include "ps/CStrIntern.h" +class CFrustum; class CTerrain; class CSimContext; class CTexturedLineRData; @@ -134,6 +135,8 @@ for (size_t i = 0; i < points.size(); ++i) PushCoords(points[i]); } + + bool IsVisibleInFrustum(const CFrustum& frustum) const; }; /** Index: ps/trunk/source/graphics/Overlay.cpp =================================================================== --- ps/trunk/source/graphics/Overlay.cpp +++ ps/trunk/source/graphics/Overlay.cpp @@ -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 @@ 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); +} Index: ps/trunk/source/renderer/TexturedLineRData.h =================================================================== --- ps/trunk/source/renderer/TexturedLineRData.h +++ ps/trunk/source/renderer/TexturedLineRData.h @@ -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 @@ 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 @@ CVertexBuffer::VBChunk* m_VB; CVertexBuffer::VBChunk* m_VBIndices; + CBoundingBoxAligned m_BoundingBox; }; #endif // INCLUDED_TEXTUREDLINERDATA Index: ps/trunk/source/renderer/TexturedLineRData.cpp =================================================================== --- ps/trunk/source/renderer/TexturedLineRData.cpp +++ ps/trunk/source/renderer/TexturedLineRData.cpp @@ -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 @@ 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 @@ } } + +bool CTexturedLineRData::IsVisibleInFrustum(const CFrustum& frustum) const +{ + return frustum.IsBoxVisible(m_BoundingBox); +} Index: ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.h =================================================================== --- ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.h +++ ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.h @@ -268,7 +268,7 @@ */ static void MergeVisibilitySegments(std::vector& segments); - void RenderSubmit(SceneCollector& collector); + void RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling); }; REGISTER_COMPONENT_TYPE(RallyPointRenderer) Index: ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.cpp +++ ps/trunk/source/simulation2/components/CCmpRallyPointRenderer.cpp @@ -165,7 +165,7 @@ if (m_Displayed && IsSet()) { const CMessageRenderSubmit& msgData = static_cast (msg); - RenderSubmit(msgData.collector); + RenderSubmit(msgData.collector, msgData.frustum, msgData.culling); } } break; @@ -920,13 +920,17 @@ } } -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& 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()) { Index: ps/trunk/source/simulation2/components/CCmpRangeOverlayRenderer.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpRangeOverlayRenderer.cpp +++ ps/trunk/source/simulation2/components/CCmpRangeOverlayRenderer.cpp @@ -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 @@ case MT_RenderSubmit: { const CMessageRenderSubmit& msgData = static_cast (msg); - RenderSubmit(msgData.collector); + RenderSubmit(msgData.collector, msgData.frustum, msgData.culling); break; } } @@ -186,14 +186,18 @@ } } - 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: Index: ps/trunk/source/simulation2/components/CCmpSelectable.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpSelectable.cpp +++ ps/trunk/source/simulation2/components/CCmpSelectable.cpp @@ -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 @@ 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 @@ SOverlayTexturedLine* m_BuildingOverlay; SOverlayQuad* m_UnitOverlay; + CBoundingBoxAligned m_UnitOverlayBoundingBox; + SOverlayLine* m_DebugBoundingBoxOverlay; SOverlayLine* m_DebugSelectionBoxOverlay; @@ -358,7 +360,7 @@ PROFILE("Selectable::RenderSubmit"); const CMessageRenderSubmit& msgData = static_cast (msg); - RenderSubmit(msgData.collector); + RenderSubmit(msgData.collector, msgData.frustum, msgData.culling); break; } @@ -522,7 +524,8 @@ 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 @@ ); 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 @@ 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); } Index: ps/trunk/source/simulation2/components/CCmpTerritoryManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpTerritoryManager.cpp +++ ps/trunk/source/simulation2/components/CCmpTerritoryManager.cpp @@ -223,7 +223,7 @@ case MT_RenderSubmit: { const CMessageRenderSubmit& msgData = static_cast (msg); - RenderSubmit(msgData.collector); + RenderSubmit(msgData.collector, msgData.frustum, msgData.culling); break; } } @@ -302,7 +302,7 @@ 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::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]);