1
0
forked from 0ad/0ad

Adds a LOS mask to Minimap.

Commented By: elexis, Stan
Differential Revision: https://code.wildfiregames.com/D2216
This was SVN commit r24141.
This commit is contained in:
Vladislav Belov 2020-11-08 08:51:54 +00:00
parent 212f1bdec4
commit 9d53bed0bd
10 changed files with 128 additions and 33 deletions

View File

@ -5,7 +5,7 @@
type="image"
>
<!-- MiniMap -->
<object name="minimap" size="8 8 100%-8 100%-8" type="minimap" z="20"/>
<object name="minimap" size="8 8 100%-8 100%-8" type="minimap" z="20" mask="true"/>
<!-- Background image -->
<object

View File

@ -1,8 +1,21 @@
!!ARBfp1.0
#if MINIMAP_MASK
ATTRIB v_maskUV = fragment.texcoord[1];
TEMP mask;
TEX mask, v_maskUV, texture[2], 2D;
#endif
#if MINIMAP_BASE
#if MINIMAP_MASK
TEMP color;
TEX color, fragment.texcoord[0], texture[0], 2D;
MUL color.a, color.a, mask.a;
MOV result.color, color;
#else
TEX result.color, fragment.texcoord[0], texture[0], 2D;
#endif
#endif
#if MINIMAP_LOS
TEMP tex;

View File

@ -1,5 +1,12 @@
!!ARBvp1.0
PARAM transform[4] = { program.local[0..3] };
PARAM textureTransform[4] = { program.local[4..7] };
#if MINIMAP_MASK
PARAM maskTextureTransform[4] = { program.local[12..15] };
#endif
OUTPUT v_tex = result.texcoord[0];
TEMP position;
MOV position, vertex.position;
#if MINIMAP_POINT || MINIMAP_LINE
@ -7,19 +14,21 @@ MOV position, vertex.position;
#endif
MOV position.w, 1.0;
DP4 result.position.x, program.local[0], position;
DP4 result.position.y, program.local[1], position;
DP4 result.position.z, program.local[2], position;
DP4 result.position.w, program.local[3], position;
DP4 result.position.x, transform[0], position;
DP4 result.position.y, transform[1], position;
DP4 result.position.z, transform[2], position;
DP4 result.position.w, transform[3], position;
#if MINIMAP_BASE || MINIMAP_LOS
#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK
TEMP tex;
MOV tex, vertex.texcoord;
#endif
DP4 result.texcoord.x, program.local[4], tex;
DP4 result.texcoord.y, program.local[5], tex;
DP4 result.texcoord.z, program.local[6], tex;
DP4 result.texcoord.w, program.local[7], tex;
#if MINIMAP_BASE || MINIMAP_LOS
DP4 v_tex.x, textureTransform[0], tex;
DP4 v_tex.y, textureTransform[1], tex;
DP4 v_tex.z, textureTransform[2], tex;
DP4 v_tex.w, textureTransform[3], tex;
#endif
#if MINIMAP_POINT
@ -27,4 +36,14 @@ DP4 result.position.w, program.local[3], position;
MOV result.pointsize, program.local[8];
#endif
#if MINIMAP_MASK
OUTPUT v_maskUV = result.texcoord[1];
MOV v_maskUV.x, tex.x;
MOV v_maskUV.y, tex.y;
DP4 v_maskUV.x, maskTextureTransform[0], tex;
DP4 v_maskUV.y, maskTextureTransform[1], tex;
DP4 v_maskUV.z, maskTextureTransform[2], tex;
DP4 v_maskUV.w, maskTextureTransform[3], tex;
#endif
END

View File

@ -3,16 +3,18 @@
<vertex file="arb/minimap.vp">
<stream name="pos"/>
<stream name="uv0" if="MINIMAP_BASE || MINIMAP_LOS"/>
<stream name="uv0" if="MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK"/>
<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"/>
</vertex>
<fragment file="arb/minimap.fp">
<uniform name="baseTex" loc="0" type="sampler2D" if="MINIMAP_BASE || MINIMAP_LOS"/>
<uniform name="color" loc="1" type="vec4" if="MINIMAP_LINE"/>
<uniform name="maskTex" loc="2" type="sampler2D" if="MINIMAP_MASK"/>
</fragment>
</program>

View File

@ -5,6 +5,11 @@
varying vec2 v_tex;
#endif
#if MINIMAP_MASK
uniform sampler2D maskTex;
varying vec2 v_maskUV;
#endif
#if MINIMAP_POINT
varying vec3 color;
#endif
@ -15,9 +20,19 @@
void main()
{
#if MINIMAP_MASK
float mask = texture2D(maskTex, v_maskUV).a;
#endif
#if MINIMAP_BASE
#if MINIMAP_MASK
vec4 color = texture2D(baseTex, v_tex);
gl_FragColor.rgb = color.rgb;
gl_FragColor.a = color.a * mask;
#else
gl_FragColor = texture2D(baseTex, v_tex);
#endif
#endif
#if MINIMAP_LOS
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0 - texture2D(baseTex, v_tex).a);

View File

@ -4,9 +4,17 @@ uniform mat4 transform;
uniform mat4 textureTransform;
uniform float pointSize;
#if MINIMAP_BASE || MINIMAP_LOS
#if MINIMAP_MASK
uniform mat4 maskTextureTransform;
varying vec2 v_maskUV;
#endif
#if MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK
attribute vec3 a_vertex;
attribute vec2 a_uv0;
#endif
#if MINIMAP_BASE || MINIMAP_LOS
varying vec2 v_tex;
#endif
@ -27,6 +35,10 @@ void main()
v_tex = (textureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
#endif
#if MINIMAP_MASK
v_maskUV = (maskTextureTransform * vec4(a_uv0, 0.0, 1.0)).xy;
#endif
#if MINIMAP_POINT
gl_PointSize = pointSize;
gl_Position = transform * vec4(a_vertex, 0.0, 1.0);

View File

@ -3,10 +3,10 @@
<vertex file="glsl/minimap.vs">
<stream name="pos"/>
<stream name="uv0" if="MINIMAP_BASE || MINIMAP_LOS"/>
<stream name="uv0" if="MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK"/>
<stream name="color" if="MINIMAP_POINT"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0" if="MINIMAP_BASE || MINIMAP_LOS"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0" if="MINIMAP_BASE || MINIMAP_LOS || MINIMAP_MASK"/>
<attrib name="a_color" semantics="gl_Color" if="MINIMAP_POINT"/>
</vertex>

View File

@ -70,9 +70,11 @@ const CStr CMiniMap::EventNameWorldClick = "WorldClick";
CMiniMap::CMiniMap(CGUI& pGUI) :
IGUIObject(pGUI),
m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f),
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW),
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(false),
m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0)
{
RegisterSetting("mask", m_Mask);
m_Clicking = false;
m_MouseHovering = false;
@ -427,6 +429,7 @@ void CMiniMap::Draw()
const float angle = GetAngle();
const float unitScale = (cmpRangeManager->GetLosCircular() ? 1.f : m_MapScale/2.f);
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
// Disable depth updates to prevent apparent z-fighting-related issues
// with some drivers causing units to get drawn behind the texture.
glDepthMask(0);
@ -436,26 +439,53 @@ void CMiniMap::Draw()
CShaderDefines baseDefines;
baseDefines.Add(str_MINIMAP_BASE, str_1);
if (m_Mask)
baseDefines.Add(str_MINIMAP_MASK, str_1);
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), baseDefines);
tech->BeginPass();
shader = tech->GetShader();
// Draw the main textured quad
shader->BindTexture(str_baseTex, m_TerrainTexture);
if (m_Mask)
{
shader->BindTexture(str_maskTex, losTexture.GetTexture());
CMatrix3D maskTextureTransform = *losTexture.GetMinimapTextureMatrix();
// We need to have texture coordinates in the same coordinate space.
const float scale = 1.0f / texCoordMax;
maskTextureTransform.Scale(scale, scale, 1.0f);
shader->Uniform(str_maskTextureTransform, maskTextureTransform);
}
const CMatrix3D baseTransform = GetDefaultGuiMatrix();
CMatrix3D baseTextureTransform;
baseTextureTransform.SetIdentity();
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, baseTextureTransform);
if (m_Mask)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
DrawTexture(shader, texCoordMax, angle, x, y, x2, y2, z);
// Draw territory boundaries
glEnable(GL_BLEND);
if (!m_Mask)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
// Draw territory boundaries
CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture();
shader->BindTexture(str_baseTex, territoryTexture.GetTexture());
if (m_Mask)
{
shader->BindTexture(str_maskTex, losTexture.GetTexture());
shader->Uniform(str_maskTextureTransform, *losTexture.GetMinimapTextureMatrix());
}
const CMatrix3D* territoryTransform = territoryTexture.GetMinimapTextureMatrix();
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, *territoryTransform);
@ -464,23 +494,22 @@ void CMiniMap::Draw()
tech->EndPass();
// Draw the LOS quad in black, using alpha values from the LOS texture
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
if (!m_Mask)
{
CShaderDefines losDefines;
losDefines.Add(str_MINIMAP_LOS, str_1);
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), losDefines);
tech->BeginPass();
shader = tech->GetShader();
shader->BindTexture(str_baseTex, losTexture.GetTexture());
CShaderDefines losDefines;
losDefines.Add(str_MINIMAP_LOS, str_1);
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), losDefines);
tech->BeginPass();
shader = tech->GetShader();
shader->BindTexture(str_baseTex, losTexture.GetTexture());
const CMatrix3D* losTransform = losTexture.GetMinimapTextureMatrix();
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, *losTransform);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
const CMatrix3D* losTransform = losTexture.GetMinimapTextureMatrix();
shader->Uniform(str_transform, baseTransform);
shader->Uniform(str_textureTransform, *losTransform);
DrawTexture(shader, 1.0f, angle, x, y, x2, y2, z);
tech->EndPass();
DrawTexture(shader, 1.0f, angle, x, y, x2, y2, z);
tech->EndPass();
}
glDisable(GL_BLEND);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -83,6 +83,9 @@ protected:
// whether we need to regenerate the terrain texture
bool m_TerrainDirty;
// Whether to draw a black square around and under the minimap.
bool m_Mask;
ssize_t m_Width, m_Height;
// map size

View File

@ -41,6 +41,7 @@ X(IGNORE_LOS)
X(MINIMAP_BASE)
X(MINIMAP_LINE)
X(MINIMAP_LOS)
X(MINIMAP_MASK)
X(MINIMAP_POINT)
X(MODE_SHADOWCAST)
X(MODE_SILHOUETTEDISPLAY)
@ -109,6 +110,7 @@ X(losTransform)
X(los_interp)
X(mapSize)
X(maskTex)
X(maskTextureTransform)
X(minimap)
X(modelViewMatrix)
X(murkiness)