1
0
forked from mirrors/0ad

Draws entities on minimap via triangles instead of points.

Tested By: Stan
Differential Revision: https://code.wildfiregames.com/D4509
This was SVN commit r26493.
This commit is contained in:
vladislavbelov
2022-02-26 20:30:09 +00:00
parent 67cafcd599
commit 6bc2f7a783
5 changed files with 59 additions and 41 deletions
@@ -33,7 +33,6 @@ DP4 result.position.w, transform[3], position;
#if MINIMAP_POINT
MOV result.color, vertex.color;
MOV result.pointsize, program.local[8];
#endif
#if MINIMAP_MASK
@@ -7,8 +7,7 @@
<stream name="color" if="MINIMAP_POINT"/>
<uniform name="transform" loc="0" type="mat4"/>
<uniform name="textureTransform" loc="4" type="mat4"/>
<uniform name="pointSize" loc="8" type="float"/>
<uniform name="maskTextureTransform" loc="12" type="mat4" if="MINIMAP_MASK"/>
<uniform name="maskTextureTransform" loc="8" type="mat4" if="MINIMAP_MASK"/>
</vertex>
<fragment file="arb/minimap.fp">
@@ -2,7 +2,6 @@
uniform mat4 transform;
uniform mat4 textureTransform;
uniform float pointSize;
#if MINIMAP_MASK
uniform mat4 maskTextureTransform;
@@ -40,7 +39,6 @@ void main()
#endif
#if MINIMAP_POINT
gl_PointSize = pointSize;
gl_Position = transform * vec4(a_vertex, 0.0, 1.0);
color = a_color;
#endif
+58 -35
View File
@@ -31,6 +31,7 @@
#include "graphics/TextureManager.h"
#include "lib/bits.h"
#include "lib/timer.h"
#include "maths/Vector2D.h"
#include "ps/ConfigDB.h"
#include "ps/CStrInternStatic.h"
#include "ps/Filesystem.h"
@@ -51,9 +52,11 @@
namespace
{
// Set max drawn entities to UINT16_MAX for now, which is more than enough
// TODO: we should be cleverer about drawing them to reduce clutter
const u16 MAX_ENTITIES_DRAWN = 65535;
// Set max drawn entities to 64K / 4 for now, which is more than enough.
// 4 is the number of vertices per entity.
// TODO: we should be cleverer about drawing them to reduce clutter,
// f.e. use instancing.
const size_t MAX_ENTITIES_DRAWN = 65536 / 4;
const size_t FINAL_TEXTURE_SIZE = 512;
@@ -65,7 +68,7 @@ unsigned int ScaleColor(unsigned int color, float x)
return (0xff000000 | b | g << 8 | r << 16);
}
void DrawTexture(CShaderProgramPtr shader)
void DrawTexture(const CShaderProgramPtr& shader)
{
const float quadUVs[] =
{
@@ -99,24 +102,35 @@ struct MinimapUnitVertex
{
// This struct is copyable for convenience and because to move is to copy for primitives.
u8 r, g, b, a;
float x, y;
CVector2D position;
};
// Adds a vertex to the passed VertexArray
static void inline addVertex(const MinimapUnitVertex& v,
inline void AddEntity(const MinimapUnitVertex& v,
VertexArrayIterator<u8[4]>& attrColor,
VertexArrayIterator<float[2]>& attrPos)
VertexArrayIterator<float[2]>& attrPos,
const float entityRadius)
{
(*attrColor)[0] = v.r;
(*attrColor)[1] = v.g;
(*attrColor)[2] = v.b;
(*attrColor)[3] = v.a;
++attrColor;
const CVector2D offsets[4] =
{
{-entityRadius, 0.0f},
{0.0f, -entityRadius},
{entityRadius, 0.0f},
{0.0f, entityRadius}
};
(*attrPos)[0] = v.x;
(*attrPos)[1] = v.y;
for (const CVector2D& offset : offsets)
{
(*attrColor)[0] = v.r;
(*attrColor)[1] = v.g;
(*attrColor)[2] = v.b;
(*attrColor)[3] = v.a;
++attrColor;
++attrPos;
(*attrPos)[0] = v.position.X + offset.X;
(*attrPos)[1] = v.position.Y + offset.Y;
++attrPos;
}
}
} // anonymous namespace
@@ -147,20 +161,19 @@ CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
m_AttributeColor.elems = 4;
m_VertexArray.AddAttribute(&m_AttributeColor);
m_VertexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN);
m_VertexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN * 4);
m_VertexArray.Layout();
m_IndexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN);
m_IndexArray.SetNumberOfVertices(MAX_ENTITIES_DRAWN * 6);
m_IndexArray.Layout();
VertexArrayIterator<u16> index = m_IndexArray.GetIterator();
for (u16 i = 0; i < MAX_ENTITIES_DRAWN; ++i)
*index++ = i;
for (size_t i = 0; i < m_IndexArray.GetNumberOfVertices(); ++i)
*index++ = 0;
m_IndexArray.Upload();
m_IndexArray.FreeBackingStore();
VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>();
VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>();
for (u16 i = 0; i < MAX_ENTITIES_DRAWN; ++i)
for (size_t i = 0; i < m_VertexArray.GetNumberOfVertices(); ++i)
{
(*attrColor)[0] = 0;
(*attrColor)[1] = 0;
@@ -172,7 +185,6 @@ CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
(*attrPos)[1] = -10000.0f;
++attrPos;
}
m_VertexArray.Upload();
}
@@ -300,7 +312,7 @@ void CMiniMapTexture::RebuildTerrainTexture(
{
// If the texture can't be loaded yet, set the dirty flags
// so we'll try regenerating the terrain texture again soon
if(!tex->GetTexture()->TryLoad())
if (!tex->GetTexture()->TryLoad())
m_TerrainTextureDirty = true;
color = tex->GetBaseColor();
@@ -420,7 +432,6 @@ void CMiniMapTexture::RenderFinalTexture(
tech->GetGraphicsPipelineStateDesc());
shader = tech->GetShader();
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_pointSize, 9.0f);
CMatrix3D unitMatrix;
unitMatrix.SetIdentity();
@@ -443,6 +454,11 @@ void CMiniMapTexture::RenderFinalTexture(
std::vector<MinimapUnitVertex> pingingVertices;
pingingVertices.reserve(MAX_ENTITIES_DRAWN / 2);
// We might scale entities properly in the vertex shader but it requires
// additional space in the vertex buffer. So we assume that we don't need
// to change an entity size so often.
const float entityRadius = static_cast<float>(m_MapSize) / 128.0f * 6.0f;
if (currentTime > m_NextBlinkTime)
{
m_BlinkState = !m_BlinkState;
@@ -459,8 +475,8 @@ void CMiniMapTexture::RenderFinalTexture(
if (vis != LosVisibility::HIDDEN)
{
v.a = 255;
v.x = posX.ToFloat();
v.y = posZ.ToFloat();
v.position.X = posX.ToFloat();
v.position.Y = posZ.ToFloat();
// Check minimap pinging to indicate something
if (m_BlinkState && cmpMinimap->CheckPing(currentTime, m_PingDuration))
@@ -472,7 +488,7 @@ void CMiniMapTexture::RenderFinalTexture(
}
else
{
addVertex(v, attrColor, attrPos);
AddEntity(v, attrColor, attrPos, entityRadius);
++m_EntitiesDrawn;
}
}
@@ -482,12 +498,25 @@ void CMiniMapTexture::RenderFinalTexture(
// Add the pinged vertices at the end, so they are drawn on top
for (const MinimapUnitVertex& vertex : pingingVertices)
{
addVertex(vertex, attrColor, attrPos);
AddEntity(vertex, attrColor, attrPos, entityRadius);
++m_EntitiesDrawn;
}
ENSURE(m_EntitiesDrawn < MAX_ENTITIES_DRAWN);
VertexArrayIterator<u16> index = m_IndexArray.GetIterator();
for (size_t entityIndex = 0; entityIndex < m_EntitiesDrawn; ++entityIndex)
{
index[entityIndex * 6 + 0] = static_cast<u16>(entityIndex * 4 + 0);
index[entityIndex * 6 + 1] = static_cast<u16>(entityIndex * 4 + 1);
index[entityIndex * 6 + 2] = static_cast<u16>(entityIndex * 4 + 2);
index[entityIndex * 6 + 3] = static_cast<u16>(entityIndex * 4 + 0);
index[entityIndex * 6 + 4] = static_cast<u16>(entityIndex * 4 + 2);
index[entityIndex * 6 + 5] = static_cast<u16>(entityIndex * 4 + 3);
}
m_VertexArray.Upload();
m_IndexArray.Upload();
}
m_VertexArray.PrepareForRendering();
@@ -498,9 +527,6 @@ void CMiniMapTexture::RenderFinalTexture(
scissorRect.x = scissorRect.y = 1;
scissorRect.width = scissorRect.height = FINAL_TEXTURE_SIZE - 2;
deviceCommandContext->SetScissors(1, &scissorRect);
#if !CONFIG2_GLES
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
u8* indexBase = m_IndexArray.Bind(deviceCommandContext);
u8* base = m_VertexArray.Bind(deviceCommandContext);
@@ -510,14 +536,11 @@ void CMiniMapTexture::RenderFinalTexture(
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset);
shader->AssertPointersBound();
glDrawElements(GL_POINTS, (GLsizei)(m_EntitiesDrawn), GL_UNSIGNED_SHORT, indexBase);
glDrawElements(GL_TRIANGLES, m_EntitiesDrawn * 6, GL_UNSIGNED_SHORT, indexBase);
g_Renderer.GetStats().m_DrawCalls++;
CVertexBuffer::Unbind(deviceCommandContext);
#if !CONFIG2_GLES
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
deviceCommandContext->SetScissors(0, nullptr);
}
-1
View File
@@ -139,7 +139,6 @@ X(particle_overlay)
X(particle_solid)
X(particle_subtract)
X(playerColor)
X(pointSize)
X(projInvTransform)
X(qualityLevel)
X(reflectionMap)