diff --git a/binaries/data/mods/public/shaders/arb/minimap.vp b/binaries/data/mods/public/shaders/arb/minimap.vp index d2e576a94c..a11e8e1b46 100644 --- a/binaries/data/mods/public/shaders/arb/minimap.vp +++ b/binaries/data/mods/public/shaders/arb/minimap.vp @@ -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 diff --git a/binaries/data/mods/public/shaders/arb/minimap.xml b/binaries/data/mods/public/shaders/arb/minimap.xml index 980519b18f..146f69cd21 100644 --- a/binaries/data/mods/public/shaders/arb/minimap.xml +++ b/binaries/data/mods/public/shaders/arb/minimap.xml @@ -7,8 +7,7 @@ - - + diff --git a/binaries/data/mods/public/shaders/glsl/minimap.vs b/binaries/data/mods/public/shaders/glsl/minimap.vs index 7169f8e52c..1afff86e98 100644 --- a/binaries/data/mods/public/shaders/glsl/minimap.vs +++ b/binaries/data/mods/public/shaders/glsl/minimap.vs @@ -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 diff --git a/source/graphics/MiniMapTexture.cpp b/source/graphics/MiniMapTexture.cpp index 113fb4124a..9c3ee6d70d 100644 --- a/source/graphics/MiniMapTexture.cpp +++ b/source/graphics/MiniMapTexture.cpp @@ -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& attrColor, - VertexArrayIterator& attrPos) + VertexArrayIterator& 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 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 attrPos = m_AttributePos.GetIterator(); VertexArrayIterator attrColor = m_AttributeColor.GetIterator(); - 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 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(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 index = m_IndexArray.GetIterator(); + for (size_t entityIndex = 0; entityIndex < m_EntitiesDrawn; ++entityIndex) + { + index[entityIndex * 6 + 0] = static_cast(entityIndex * 4 + 0); + index[entityIndex * 6 + 1] = static_cast(entityIndex * 4 + 1); + index[entityIndex * 6 + 2] = static_cast(entityIndex * 4 + 2); + index[entityIndex * 6 + 3] = static_cast(entityIndex * 4 + 0); + index[entityIndex * 6 + 4] = static_cast(entityIndex * 4 + 2); + index[entityIndex * 6 + 5] = static_cast(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); } diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h index aef4ba4404..16fd2d9e4a 100644 --- a/source/ps/CStrInternStatic.h +++ b/source/ps/CStrInternStatic.h @@ -139,7 +139,6 @@ X(particle_overlay) X(particle_solid) X(particle_subtract) X(playerColor) -X(pointSize) X(projInvTransform) X(qualityLevel) X(reflectionMap)