Properly enforce the MAX_QUAD_OVERLAYS constraint
Some cleanup of graphics/Overlay.h This was SVN commit r11629.
This commit is contained in:
parent
62ec2bac69
commit
3cbfd9260e
@ -23,9 +23,9 @@
|
|||||||
#include "maths/Vector2D.h"
|
#include "maths/Vector2D.h"
|
||||||
#include "maths/Vector3D.h"
|
#include "maths/Vector3D.h"
|
||||||
#include "ps/Overlay.h" // CColor (TODO: that file has nothing to do with overlays, it should be renamed)
|
#include "ps/Overlay.h" // CColor (TODO: that file has nothing to do with overlays, it should be renamed)
|
||||||
#include "simulation2/components/ICmpFootprint.h"
|
|
||||||
|
|
||||||
class CTerrain;
|
class CTerrain;
|
||||||
|
class CSimContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line-based overlay, with world-space coordinates, rendered in the world
|
* Line-based overlay, with world-space coordinates, rendered in the world
|
||||||
@ -39,8 +39,13 @@ struct SOverlayLine
|
|||||||
std::vector<float> m_Coords; // (x, y, z) vertex coordinate triples; shape is not automatically closed
|
std::vector<float> m_Coords; // (x, y, z) vertex coordinate triples; shape is not automatically closed
|
||||||
u8 m_Thickness; // in pixels
|
u8 m_Thickness; // in pixels
|
||||||
|
|
||||||
void PushCoords(const float x, const float y, const float z) { m_Coords.push_back(x); m_Coords.push_back(y); m_Coords.push_back(z); }
|
|
||||||
void PushCoords(const CVector3D& v) { PushCoords(v.X, v.Y, v.Z); }
|
void PushCoords(const CVector3D& v) { PushCoords(v.X, v.Y, v.Z); }
|
||||||
|
void PushCoords(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
m_Coords.push_back(x);
|
||||||
|
m_Coords.push_back(y);
|
||||||
|
m_Coords.push_back(z);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,9 +59,10 @@ struct SOverlayTexturedLine
|
|||||||
LINECAP_FLAT, ///< no line ending; abrupt stop of the line (aka. butt ending)
|
LINECAP_FLAT, ///< no line ending; abrupt stop of the line (aka. butt ending)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Semi-circular line ending. The texture is mapped by curving the left vertical edge around the semi-circle's rim. That is,
|
* Semi-circular line ending. The texture is mapped by curving the left vertical edge
|
||||||
* the center point has UV coordinates (0.5;0.5), and the rim vertices all have U coordinate 0 and a V coordinate that ranges
|
* around the semi-circle's rim. That is, the center point has UV coordinates (0.5;0.5),
|
||||||
* from 0 to 1 as the rim is traversed.
|
* and the rim vertices all have U coordinate 0 and a V coordinate that ranges from 0 to
|
||||||
|
* 1 as the rim is traversed.
|
||||||
*/
|
*/
|
||||||
LINECAP_ROUND,
|
LINECAP_ROUND,
|
||||||
LINECAP_SHARP, ///< sharp point ending
|
LINECAP_SHARP, ///< sharp point ending
|
||||||
@ -70,21 +76,31 @@ struct SOverlayTexturedLine
|
|||||||
|
|
||||||
CTexturePtr m_TextureBase;
|
CTexturePtr m_TextureBase;
|
||||||
CTexturePtr m_TextureMask;
|
CTexturePtr m_TextureMask;
|
||||||
CColor m_Color; ///< Color to apply to the line texture
|
|
||||||
std::vector<float> m_Coords; ///< (x, z) vertex coordinate pairs; y is computed automatically
|
|
||||||
float m_Thickness; ///< Half-width of the line, in world-space units
|
|
||||||
|
|
||||||
bool m_Closed; ///< Should this line be treated as a closed loop? (if set, the end cap settings are ignored)
|
/// Color to apply to the line texture, where indicated by the mask.
|
||||||
bool m_AlwaysVisible; ///< Should this line be rendered even under the SoD?
|
CColor m_Color;
|
||||||
LineCapType m_StartCapType; ///< LineCapType to be used at the start of the line
|
/// (x, z) vertex coordinate pairs; y is computed automatically.
|
||||||
LineCapType m_EndCapType; ///< LineCapType to be used at the end of the line
|
std::vector<float> m_Coords;
|
||||||
|
/// Half-width of the line, in world-space units.
|
||||||
|
float m_Thickness;
|
||||||
|
/// Should this line be treated as a closed loop? If set, any end cap settings are ignored.
|
||||||
|
bool m_Closed;
|
||||||
|
/// Should this line be rendered fully visible at all times, even under the SoD?
|
||||||
|
bool m_AlwaysVisible;
|
||||||
|
|
||||||
const CSimContext* m_SimContext; /// Simulation context applicable for this overlay line; used to obtain terrain information
|
LineCapType m_StartCapType;
|
||||||
shared_ptr<CRenderData> m_RenderData; ///< Cached renderer data (shared_ptr so that copies/deletes are automatic)
|
LineCapType m_EndCapType;
|
||||||
|
|
||||||
|
/// Simulation context applicable for this overlay line; used to obtain terrain information
|
||||||
|
/// during automatic computation of Y coordinates.
|
||||||
|
const CSimContext* m_SimContext;
|
||||||
|
/// Cached renderer data (shared_ptr so that copies/deletes are automatic).
|
||||||
|
shared_ptr<CRenderData> m_RenderData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a string line cap type into its corresponding LineCap enum value, and returns the resulting value.
|
* Converts a string line cap type into its corresponding LineCap enum value, and returns
|
||||||
* If the input string is unrecognized, a warning is issued and a default value is returned.
|
* the resulting value. If the input string is unrecognized, a warning is issued and a
|
||||||
|
* default value is returned.
|
||||||
*/
|
*/
|
||||||
static LineCapType StrToLineCapType(const std::wstring& str);
|
static LineCapType StrToLineCapType(const std::wstring& str);
|
||||||
|
|
||||||
@ -109,9 +125,9 @@ struct SOverlaySprite
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rectangular single-quad terrain overlay, with world space coordinates. The vertices of the quad
|
* Rectangular single-quad terrain overlay, in world space coordinates. The vertices of the quad
|
||||||
* are not required to be coplanar; the quad is arbitrarily triangulated with no effort being made to
|
* are not required to be coplanar; the quad is arbitrarily triangulated with no effort being made
|
||||||
* find a best fit to the underlying terrain.
|
* to find a best fit to the underlying terrain.
|
||||||
*/
|
*/
|
||||||
struct SOverlayQuad
|
struct SOverlayQuad
|
||||||
{
|
{
|
||||||
|
@ -68,13 +68,18 @@ struct QuadBatchKey
|
|||||||
class QuadBatchData : public CRenderData
|
class QuadBatchData : public CRenderData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QuadBatchData() : m_IndicesBase(0) { }
|
QuadBatchData() : m_IndicesBase(0), m_NumRenderQuads(0) { }
|
||||||
|
|
||||||
/// Holds the quad overlay structures to be rendered during this batch.
|
/// Holds the quad overlay structures requested to be rendered in this batch. Must be cleared
|
||||||
/// Must be cleared after each frame.
|
/// after each frame.
|
||||||
std::vector<SOverlayQuad*> m_Quads;
|
std::vector<SOverlayQuad*> m_Quads;
|
||||||
|
|
||||||
/// Start index of this batch into the dedicated quad indices VertexArray (see OverlayInternals).
|
/// Start index of this batch into the dedicated quad indices VertexArray (see OverlayInternals).
|
||||||
size_t m_IndicesBase;
|
size_t m_IndicesBase;
|
||||||
|
/// Amount of quads to actually render in this batch. Potentially (although unlikely to be)
|
||||||
|
/// different from m_Quads.size() due to restrictions on the total amount of quads that can be
|
||||||
|
/// rendered. Must be reset after each frame.
|
||||||
|
size_t m_NumRenderQuads;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OverlayRendererInternals
|
struct OverlayRendererInternals
|
||||||
@ -271,7 +276,10 @@ void OverlayRenderer::EndFrame()
|
|||||||
// Empty the batch rendering data structures, but keep their key mappings around for the next frames
|
// Empty the batch rendering data structures, but keep their key mappings around for the next frames
|
||||||
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); it++)
|
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); it++)
|
||||||
{
|
{
|
||||||
it->second.m_Quads.clear();
|
QuadBatchData& quadBatchData = (it->second);
|
||||||
|
quadBatchData.m_Quads.clear();
|
||||||
|
quadBatchData.m_NumRenderQuads = 0;
|
||||||
|
quadBatchData.m_IndicesBase = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +305,7 @@ void OverlayRenderer::PrepareForRendering()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Group quad overlays by their texture/mask combination for efficient rendering
|
// Group quad overlays by their texture/mask combination for efficient rendering
|
||||||
|
// TODO: consider doing this directly in Submit()
|
||||||
for (size_t i = 0; i < m->quads.size(); ++i)
|
for (size_t i = 0; i < m->quads.size(); ++i)
|
||||||
{
|
{
|
||||||
SOverlayQuad* const quad = m->quads[i];
|
SOverlayQuad* const quad = m->quads[i];
|
||||||
@ -316,18 +325,21 @@ void OverlayRenderer::PrepareForRendering()
|
|||||||
VertexArrayIterator<short[2]> vertexUV = m->quadAttributeUV.GetIterator<short[2]>();
|
VertexArrayIterator<short[2]> vertexUV = m->quadAttributeUV.GetIterator<short[2]>();
|
||||||
|
|
||||||
size_t indicesIdx = 0;
|
size_t indicesIdx = 0;
|
||||||
|
size_t totalNumQuads = 0;
|
||||||
|
|
||||||
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
|
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
|
||||||
{
|
{
|
||||||
QuadBatchData& batchRenderData = (it->second);
|
QuadBatchData& batchRenderData = (it->second);
|
||||||
|
batchRenderData.m_NumRenderQuads = 0;
|
||||||
|
|
||||||
if (batchRenderData.m_Quads.empty())
|
if (batchRenderData.m_Quads.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remember our current index into the (entire) indices array as our base offset for this batch
|
// Remember the current index into the (entire) indices array as our base offset for this batch
|
||||||
batchRenderData.m_IndicesBase = indicesIdx;
|
batchRenderData.m_IndicesBase = indicesIdx;
|
||||||
|
|
||||||
// points to the index where each iteration's vertices will be appended
|
// points to the index where each iteration's vertices will be appended
|
||||||
for (size_t i = 0; i < batchRenderData.m_Quads.size(); i++)
|
for (size_t i = 0; i < batchRenderData.m_Quads.size() && totalNumQuads < OverlayRendererInternals::MAX_QUAD_OVERLAYS; i++)
|
||||||
{
|
{
|
||||||
const SOverlayQuad* quad = batchRenderData.m_Quads[i];
|
const SOverlayQuad* quad = batchRenderData.m_Quads[i];
|
||||||
|
|
||||||
@ -359,6 +371,9 @@ void OverlayRenderer::PrepareForRendering()
|
|||||||
*vertexColor++ = quadColor;
|
*vertexColor++ = quadColor;
|
||||||
|
|
||||||
indicesIdx += 6;
|
indicesIdx += 6;
|
||||||
|
|
||||||
|
totalNumQuads++;
|
||||||
|
batchRenderData.m_NumRenderQuads++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,10 +573,9 @@ void OverlayRenderer::RenderQuadOverlays()
|
|||||||
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); it++)
|
for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); it++)
|
||||||
{
|
{
|
||||||
QuadBatchData& batchRenderData = it->second;
|
QuadBatchData& batchRenderData = it->second;
|
||||||
const size_t batchNumQuads = batchRenderData.m_Quads.size();
|
const size_t batchNumQuads = batchRenderData.m_NumRenderQuads;
|
||||||
|
|
||||||
// Careful; some drivers don't like drawing calls with 0 stuff to draw.
|
// Careful; some drivers don't like drawing calls with 0 stuff to draw.
|
||||||
// Also needed to ensure that batchRenderData.m_IndicesBase is valid (see PrepareForRendering).
|
|
||||||
if (batchNumQuads == 0)
|
if (batchNumQuads == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user