Changeset View
Standalone View
source/gui/ObjectTypes/CMiniMap.cpp
Show All 28 Lines | |||||
#include "graphics/TerritoryTexture.h" | #include "graphics/TerritoryTexture.h" | ||||
#include "gui/CGUI.h" | #include "gui/CGUI.h" | ||||
#include "gui/GUIManager.h" | #include "gui/GUIManager.h" | ||||
#include "gui/GUIMatrix.h" | #include "gui/GUIMatrix.h" | ||||
#include "lib/bits.h" | #include "lib/bits.h" | ||||
#include "lib/external_libraries/libsdl.h" | #include "lib/external_libraries/libsdl.h" | ||||
#include "lib/ogl.h" | #include "lib/ogl.h" | ||||
#include "lib/timer.h" | #include "lib/timer.h" | ||||
#include "ps/CLogger.h" | |||||
#include "ps/ConfigDB.h" | #include "ps/ConfigDB.h" | ||||
#include "ps/CStrInternStatic.h" | #include "ps/CStrInternStatic.h" | ||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||
#include "ps/Game.h" | #include "ps/Game.h" | ||||
#include "ps/GameSetup/Config.h" | #include "ps/GameSetup/Config.h" | ||||
#include "ps/Profile.h" | #include "ps/Profile.h" | ||||
#include "ps/World.h" | #include "ps/World.h" | ||||
#include "ps/XML/Xeromyces.h" | #include "ps/XML/Xeromyces.h" | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
} // anonymous namespace | } // anonymous namespace | ||||
const CStr CMiniMap::EventNameWorldClick = "WorldClick"; | const CStr CMiniMap::EventNameWorldClick = "WorldClick"; | ||||
CMiniMap::CMiniMap(CGUI& pGUI) : | CMiniMap::CMiniMap(CGUI& pGUI) : | ||||
IGUIObject(pGUI), | IGUIObject(pGUI), | ||||
m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f), | 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_Mask(this, "mask", false), | m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(this, "mask", false), | ||||
m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0) | m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0), | ||||
m_FlareTextureCount(this, "flare_texture_count", 0), m_FlareRenderSize(this, "flare_render_size", 0), | |||||
m_FlareAnimationSpeed(this, "flare_animation_speed", 0), m_FlareInterleave(this, "flare_interleave", false), | |||||
m_FlareLifetimeSeconds(this, "flare_lifetime_seconds", 0) | |||||
{ | { | ||||
m_Clicking = false; | m_Clicking = false; | ||||
m_MouseHovering = false; | m_MouseHovering = false; | ||||
// Register Relax NG validator | // Register Relax NG validator | ||||
CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng"); | CXeromyces::AddValidator(g_VFS, "pathfinder", "simulation/data/pathfinder.rng"); | ||||
m_ShallowPassageHeight = GetShallowPassageHeight(); | m_ShallowPassageHeight = GetShallowPassageHeight(); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | CMiniMap::CMiniMap(CGUI& pGUI) : | ||||
{ | { | ||||
CFG_GET_VAL("gui.session.minimap.pingduration", m_PingDuration); | CFG_GET_VAL("gui.session.minimap.pingduration", m_PingDuration); | ||||
CFG_GET_VAL("gui.session.minimap.blinkduration", blinkDuration); | CFG_GET_VAL("gui.session.minimap.blinkduration", blinkDuration); | ||||
} | } | ||||
m_HalfBlinkDuration = blinkDuration/2; | m_HalfBlinkDuration = blinkDuration/2; | ||||
} | } | ||||
CMiniMap::~CMiniMap() | CMiniMap::~CMiniMap() | ||||
{ | { | ||||
vladislavbelov: So, you're not going to use DDS? | |||||
Done Inline ActionsHmm, good point. Other parts of our code used png, so I didn't thought about that. Imarok: Hmm, good point. Other parts of our code used png, so I didn't thought about that.
Isn't the… | |||||
Done Inline ActionsIf you use .png directly, then there shouldn't be any automatic DDS usage AFAIK. Also CStr should be CStrW I suppose. Since you always use L and CStr might be CStrW for Unicode. vladislavbelov: If you use `.png` directly, then there shouldn't be any automatic DDS usage AFAIK.
Also `CStr`… | |||||
Done Inline ActionsWhat else should I use?
That's what FromUTF8() does. Imarok: What else should I use?
If I use `.dds` it errors out.
> Also `CStr` should be `CStrW` I… | |||||
Done Inline ActionsYou can just use CStrW().FromInt wraitii: You can just use CStrW().FromInt | |||||
Done Inline ActionsI don't think so as I need the 0 at the front. Imarok: I don't think so as I need the 0 at the front. | |||||
Destroy(); | Destroy(); | ||||
} | } | ||||
void CMiniMap::HandleMessage(SGUIMessage& Message) | void CMiniMap::HandleMessage(SGUIMessage& Message) | ||||
{ | { | ||||
IGUIObject::HandleMessage(Message); | IGUIObject::HandleMessage(Message); | ||||
switch (Message.type) | switch (Message.type) | ||||
{ | { | ||||
case GUIM_LOAD: | |||||
RecreateFlareTextures(); | |||||
break; | |||||
case GUIM_SETTINGS_UPDATED: | |||||
if (Message.value == "flare_texture_count") | |||||
RecreateFlareTextures(); | |||||
break; | |||||
case GUIM_MOUSE_PRESS_LEFT: | case GUIM_MOUSE_PRESS_LEFT: | ||||
if (m_MouseHovering) | if (m_MouseHovering) | ||||
{ | { | ||||
if (!CMiniMap::FireWorldClickEvent(SDL_BUTTON_LEFT, 1)) | if (!CMiniMap::FireWorldClickEvent(SDL_BUTTON_LEFT, 1)) | ||||
{ | { | ||||
SetCameraPos(); | SetCameraPos(); | ||||
m_Clicking = true; | m_Clicking = true; | ||||
} | } | ||||
Show All 31 Lines | case GUIM_MOUSE_WHEEL_UP: | ||||
Message.Skip(); | Message.Skip(); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
void CMiniMap::RecreateFlareTextures() | |||||
{ | |||||
const CStr numberingFormat = "%02u"; | |||||
Done Inline Actionsdebug? wraitii: debug? | |||||
Done Inline ActionsAh, yeah. Imarok: Ah, yeah.
I uploaded in a hurry >< | |||||
m_FlareTextures.clear(); | |||||
Not Done Inline ActionsCould do m_FlareTextures.reserve(m_FlareTextureCount);. vladislavbelov: Could do `m_FlareTextures.reserve(m_FlareTextureCount);`. | |||||
Done Inline ActionsTrue. I thought about that but was too lazy ;) Imarok: True. I thought about that but was too lazy ;) | |||||
for (u32 i = 0; i < m_FlareTextureCount; ++i) | |||||
{ | |||||
Done Inline ActionsWrong format type. Also it's hardcoded for 2 digits. At least it should be a named format constant. vladislavbelov: Wrong format type. Also it's hardcoded for 2 digits. At least it should be a named format… | |||||
CTextureProperties textureProps(L"art/textures/animated/minimap-flare/frame" + CStr(fmt::sprintf(numberingFormat, i)).FromUTF8() + L".png"); | |||||
m_FlareTextures.push_back(g_Renderer.GetTextureManager().CreateTexture(textureProps)); | |||||
vladislavbelovUnsubmitted Done Inline Actionsemplace_back. vladislavbelov: `emplace_back`. | |||||
} | |||||
} | |||||
bool CMiniMap::IsMouseOver() const | bool CMiniMap::IsMouseOver() const | ||||
{ | { | ||||
// Get the mouse position. | // Get the mouse position. | ||||
const CVector2D& mousePos = m_pGUI.GetMousePos(); | const CVector2D& mousePos = m_pGUI.GetMousePos(); | ||||
// Get the position of the center of the minimap. | // Get the position of the center of the minimap. | ||||
CVector2D minimapCenter = CVector2D(m_CachedActualSize.left + m_CachedActualSize.GetWidth() / 2.0, m_CachedActualSize.bottom - m_CachedActualSize.GetHeight() / 2.0); | CVector2D minimapCenter = CVector2D(m_CachedActualSize.left + m_CachedActualSize.GetWidth() / 2.0, m_CachedActualSize.bottom - m_CachedActualSize.GetHeight() / 2.0); | ||||
// Take the magnitude of the difference of the mouse position and minimap center. | // Take the magnitude of the difference of the mouse position and minimap center. | ||||
double distFromCenter = sqrt(pow((mousePos.X - minimapCenter.X), 2) + pow((mousePos.Y - minimapCenter.Y), 2)); | double distFromCenter = sqrt(pow((mousePos.X - minimapCenter.X), 2) + pow((mousePos.Y - minimapCenter.Y), 2)); | ||||
Show All 15 Lines | void CMiniMap::GetMouseWorldCoordinates(float& x, float& z) const | ||||
float angle = GetAngle(); | float angle = GetAngle(); | ||||
// Scale world coordinates for shrunken square map | // Scale world coordinates for shrunken square map | ||||
x = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(px-0.5) - sin(angle)*(py-0.5)) + 0.5); | x = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(px-0.5) - sin(angle)*(py-0.5)) + 0.5); | ||||
z = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(py-0.5) + sin(angle)*(px-0.5)) + 0.5); | z = TERRAIN_TILE_SIZE * m_MapSize * (m_MapScale * (cos(angle)*(py-0.5) + sin(angle)*(px-0.5)) + 0.5); | ||||
} | } | ||||
CVector2D CMiniMap::GetMapCoordinates(float x, float z) const | |||||
{ | |||||
const float width = m_CachedActualSize.GetWidth(); | |||||
const float height = m_CachedActualSize.GetHeight(); | |||||
const float invTileMapSize = 1.0f / (TERRAIN_TILE_SIZE * m_MapSize); | |||||
return CVector2D(width * x * invTileMapSize, height * z * invTileMapSize); | |||||
} | |||||
void CMiniMap::SetCameraPos() | void CMiniMap::SetCameraPos() | ||||
{ | { | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | ||||
CVector3D target; | CVector3D target; | ||||
GetMouseWorldCoordinates(target.X, target.Z); | GetMouseWorldCoordinates(target.X, target.Z); | ||||
target.Y = terrain->GetExactGroundLevel(target.X, target.Z); | target.Y = terrain->GetExactGroundLevel(target.X, target.Z); | ||||
g_Game->GetView()->MoveCameraTarget(target); | g_Game->GetView()->MoveCameraTarget(target); | ||||
Show All 29 Lines | |||||
// which represents the view of the camera in the world. | // which represents the view of the camera in the world. | ||||
void CMiniMap::DrawViewRect(const CMatrix3D& transform) const | void CMiniMap::DrawViewRect(const CMatrix3D& transform) const | ||||
{ | { | ||||
// Compute the camera frustum intersected with a fixed-height plane. | // Compute the camera frustum intersected with a fixed-height plane. | ||||
// Use the water height as a fixed base height, which should be the lowest we can go | // Use the water height as a fixed base height, which should be the lowest we can go | ||||
float h = g_Renderer.GetWaterManager()->m_WaterHeight; | float h = g_Renderer.GetWaterManager()->m_WaterHeight; | ||||
const float width = m_CachedActualSize.GetWidth(); | const float width = m_CachedActualSize.GetWidth(); | ||||
const float height = m_CachedActualSize.GetHeight(); | const float height = m_CachedActualSize.GetHeight(); | ||||
const float invTileMapSize = 1.0f / float(TERRAIN_TILE_SIZE * m_MapSize); | |||||
const std::array<CVector3D, 4> hitPoints = { | const std::array<CVector3D, 4> hitPoints = { | ||||
m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h), | m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h), | ||||
m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h), | m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h), | ||||
m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h), | m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h), | ||||
m_Camera->GetWorldCoordinates(0, 0, h) | m_Camera->GetWorldCoordinates(0, 0, h) | ||||
}; | }; | ||||
std::vector<CVector3D> lines; | std::vector<CVector3D> lines; | ||||
// We need to prevent drawing view bounds out of the map. | // We need to prevent drawing view bounds out of the map. | ||||
const float halfMapSize = static_cast<float>((m_MapSize - 1) * TERRAIN_TILE_SIZE) * 0.5f; | const float halfMapSize = static_cast<float>((m_MapSize - 1) * TERRAIN_TILE_SIZE) * 0.5f; | ||||
CropPointsByCircle(hitPoints, CVector3D(halfMapSize, 0.0f, halfMapSize), halfMapSize * m_MapScale, &lines); | CropPointsByCircle(hitPoints, CVector3D(halfMapSize, 0.0f, halfMapSize), halfMapSize * m_MapScale, &lines); | ||||
if (lines.empty()) | if (lines.empty()) | ||||
return; | return; | ||||
std::vector<float> vertices; | std::vector<float> vertices; | ||||
vertices.reserve(lines.size() * 2); | vertices.reserve(lines.size() * 2); | ||||
for (const CVector3D& point : lines) | for (const CVector3D& point : lines) | ||||
{ | { | ||||
// Convert to minimap space. | // Convert to minimap space. | ||||
vertices.emplace_back(width * point.X * invTileMapSize); | const CVector2D posInMiniMap = GetMapCoordinates(point.X, point.Z); | ||||
vertices.emplace_back(-(height * point.Z * invTileMapSize)); | vertices.emplace_back(posInMiniMap.X); | ||||
vertices.emplace_back(-posInMiniMap.Y); | |||||
} | } | ||||
// Enable Scissoring to restrict the rectangle to only the minimap. | // Enable Scissoring to restrict the rectangle to only the minimap. | ||||
glScissor( | glScissor( | ||||
m_CachedActualSize.left * g_GuiScale, | m_CachedActualSize.left * g_GuiScale, | ||||
g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | ||||
width * g_GuiScale, | width * g_GuiScale, | ||||
height * g_GuiScale); | height * g_GuiScale); | ||||
Show All 15 Lines | if (!g_Renderer.DoSkipSubmit()) | ||||
glDrawArrays(GL_LINES, 0, vertices.size() / 2); | glDrawArrays(GL_LINES, 0, vertices.size() / 2); | ||||
tech->EndPass(); | tech->EndPass(); | ||||
glLineWidth(1.0f); | glLineWidth(1.0f); | ||||
glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
} | } | ||||
void CMiniMap::DrawFlare(CShaderProgramPtr shader, const MapFlare& flare, double cur_time) const | |||||
vladislavbelovUnsubmitted Done Inline ActionscurrentTime. vladislavbelov: `currentTime`. | |||||
{ | |||||
if (!m_FlareTextures.size()) | |||||
Done Inline Actions. vladislavbelov: . | |||||
Done Inline ActionsStill some commented code. vladislavbelov: Still some commented code. | |||||
return; | |||||
float x = flare.pos.X + m_FlareRenderSize; | |||||
float y = -flare.pos.Y - m_FlareRenderSize; | |||||
Done Inline Actionsstatic_cast. vladislavbelov: `static_cast`. | |||||
float x2 = flare.pos.X - m_FlareRenderSize; | |||||
float y2 = -flare.pos.Y + m_FlareRenderSize; | |||||
float z = 0; | |||||
float quadTex[] = { | |||||
0, 1, | |||||
1, 1, | |||||
1, 0, | |||||
1, 0, | |||||
0, 0, | |||||
0, 1 | |||||
}; | |||||
float quadVerts[] = { | |||||
x, y, z, | |||||
x2, y, z, | |||||
x2, y2, z, | |||||
x2, y2, z, | |||||
x, y2, z, | |||||
x, y, z | |||||
}; | |||||
u32 flooredStep = floor((cur_time - flare.time) * m_FlareAnimationSpeed); | |||||
vladislavbelovUnsubmitted Done Inline Actionsconst. vladislavbelov: `const`. | |||||
shader->Uniform(str_color, flare.color); | |||||
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex); | |||||
shader->VertexPointer(3, GL_FLOAT, 0, quadVerts); | |||||
shader->AssertPointersBound(); | |||||
if (g_Renderer.DoSkipSubmit()) | |||||
vladislavbelovUnsubmitted Done Inline ActionsFor the skip we need to skip the only glDraw* calls but leave all bindings. vladislavbelov: For the skip we need to skip the only `glDraw*` calls but leave all bindings. | |||||
return; | |||||
shader->BindTexture(str_baseTex, m_FlareTextures.at(flooredStep % m_FlareTextures.size())); | |||||
glDrawArrays(GL_TRIANGLES, 0, 6); | |||||
Done Inline ActionsThis actually seems like it should use a magic number & could use a comment wraitii: This actually seems like it should use a magic number & could use a comment | |||||
// Draw a second circle if the first has reached half of the animation | |||||
if (m_FlareInterleave && flooredStep >= m_FlareTextures.size() / 2) | |||||
{ | |||||
Done Inline ActionsMissed constants for 8 and 16. vladislavbelov: Missed constants for 8 and 16. | |||||
shader->BindTexture(str_baseTex, m_FlareTextures.at((flooredStep - m_FlareTextures.size() / 2) % m_FlareTextures.size())); | |||||
glDrawArrays(GL_TRIANGLES, 0, 6); | |||||
} | |||||
} | |||||
struct MinimapUnitVertex | struct MinimapUnitVertex | ||||
{ | { | ||||
// This struct is copyable for convenience and because to move is to copy for primitives. | // This struct is copyable for convenience and because to move is to copy for primitives. | ||||
u8 r, g, b, a; | u8 r, g, b, a; | ||||
float x, y; | float x, y; | ||||
}; | }; | ||||
// Adds a vertex to the passed VertexArray | // Adds a vertex to the passed VertexArray | ||||
static void inline addVertex(const MinimapUnitVertex& v, | static void inline addVertex(const MinimapUnitVertex& v, | ||||
VertexArrayIterator<u8[4]>& attrColor, | VertexArrayIterator<u8[4]>& attrColor, | ||||
VertexArrayIterator<float[2]>& attrPos) | VertexArrayIterator<float[2]>& attrPos) | ||||
{ | { | ||||
(*attrColor)[0] = v.r; | (*attrColor)[0] = v.r; | ||||
(*attrColor)[1] = v.g; | (*attrColor)[1] = v.g; | ||||
(*attrColor)[2] = v.b; | (*attrColor)[2] = v.b; | ||||
(*attrColor)[3] = v.a; | (*attrColor)[3] = v.a; | ||||
++attrColor; | ++attrColor; | ||||
(*attrPos)[0] = v.x; | (*attrPos)[0] = v.x; | ||||
(*attrPos)[1] = v.y; | (*attrPos)[1] = v.y; | ||||
++attrPos; | ++attrPos; | ||||
} | } | ||||
void CMiniMap::DrawTexture(CShaderProgramPtr shader, float coordMax, float angle, float x, float y, float x2, float y2) const | void CMiniMap::DrawTexture(CShaderProgramPtr shader, float coordMax, float angle, float x, float y, float x2, float y2) const | ||||
{ | { | ||||
// Rotate the texture coordinates (0,0)-(coordMax,coordMax) around their center point (m,m) | // Rotate the texture coordinates (0,0)-(coordMax,coordMax) around their center point (m,m) | ||||
// Scale square maps to fit in circular minimap area | // Scale square maps to fit in circular minimap area | ||||
const float s = sin(angle) * m_MapScale; | const float s = sin(angle) * m_MapScale; | ||||
const float c = cos(angle) * m_MapScale; | const float c = cos(angle) * m_MapScale; | ||||
const float m = coordMax / 2.f; | const float m = coordMax / 2.f; | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | void CMiniMap::Draw() | ||||
CShaderDefines baseDefines; | CShaderDefines baseDefines; | ||||
baseDefines.Add(str_MINIMAP_BASE, str_1); | baseDefines.Add(str_MINIMAP_BASE, str_1); | ||||
if (m_Mask) | if (m_Mask) | ||||
baseDefines.Add(str_MINIMAP_MASK, str_1); | baseDefines.Add(str_MINIMAP_MASK, str_1); | ||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), baseDefines); | tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), baseDefines); | ||||
tech->BeginPass(); | tech->BeginPass(); | ||||
shader = tech->GetShader(); | shader = tech->GetShader(); | ||||
Done Inline ActionsThis loads up the minimap shader with MINIMAP_BASE define. wraitii: This loads up the minimap shader with `MINIMAP_BASE` define. | |||||
// Draw the main textured quad | // Draw the main textured quad | ||||
shader->BindTexture(str_baseTex, m_TerrainTexture); | shader->BindTexture(str_baseTex, m_TerrainTexture); | ||||
if (m_Mask) | if (m_Mask) | ||||
{ | { | ||||
shader->BindTexture(str_maskTex, losTexture.GetTexture()); | shader->BindTexture(str_maskTex, losTexture.GetTexture()); | ||||
CMatrix3D maskTextureTransform = *losTexture.GetMinimapTextureMatrix(); | CMatrix3D maskTextureTransform = *losTexture.GetMinimapTextureMatrix(); | ||||
// We need to have texture coordinates in the same coordinate space. | // We need to have texture coordinates in the same coordinate space. | ||||
const float scale = 1.0f / texCoordMax; | const float scale = 1.0f / texCoordMax; | ||||
maskTextureTransform.Scale(scale, scale, 1.0f); | maskTextureTransform.Scale(scale, scale, 1.0f); | ||||
shader->Uniform(str_maskTextureTransform, maskTextureTransform); | shader->Uniform(str_maskTextureTransform, maskTextureTransform); | ||||
} | } | ||||
const CMatrix3D baseTransform = GetDefaultGuiMatrix(); | const CMatrix3D baseTransform = GetDefaultGuiMatrix(); | ||||
CMatrix3D baseTextureTransform; | CMatrix3D baseTextureTransform; | ||||
baseTextureTransform.SetIdentity(); | baseTextureTransform.SetIdentity(); | ||||
shader->Uniform(str_transform, baseTransform); | shader->Uniform(str_transform, baseTransform); | ||||
shader->Uniform(str_textureTransform, baseTextureTransform); | shader->Uniform(str_textureTransform, baseTextureTransform); | ||||
if (m_Mask) | if (m_Mask) | ||||
{ | { | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
} | } | ||||
Done Inline ActionsHere it binds the transform and the texture, and then uses the helper DrawTexture to render two triangles at the appropriate coordinates. You should be able to do exactly the same thing, but call DrawTexture with different x,y,x2,y2 and your Flare texture. wraitii: Here it binds the transform and the texture, and then uses the helper DrawTexture to render two… | |||||
DrawTexture(shader, texCoordMax, angle, x, y, x2, y2); | DrawTexture(shader, texCoordMax, angle, x, y, x2, y2); | ||||
if (!m_Mask) | if (!m_Mask) | ||||
{ | { | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
} | } | ||||
// Draw territory boundaries | // Draw territory boundaries | ||||
CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture(); | CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture(); | ||||
shader->BindTexture(str_baseTex, territoryTexture.GetTexture()); | shader->BindTexture(str_baseTex, territoryTexture.GetTexture()); | ||||
if (m_Mask) | if (m_Mask) | ||||
{ | { | ||||
shader->BindTexture(str_maskTex, losTexture.GetTexture()); | shader->BindTexture(str_maskTex, losTexture.GetTexture()); | ||||
shader->Uniform(str_maskTextureTransform, *losTexture.GetMinimapTextureMatrix()); | shader->Uniform(str_maskTextureTransform, *losTexture.GetMinimapTextureMatrix()); | ||||
} | } | ||||
const CMatrix3D* territoryTransform = territoryTexture.GetMinimapTextureMatrix(); | const CMatrix3D* territoryTransform = territoryTexture.GetMinimapTextureMatrix(); | ||||
shader->Uniform(str_transform, baseTransform); | shader->Uniform(str_transform, baseTransform); | ||||
shader->Uniform(str_textureTransform, *territoryTransform); | shader->Uniform(str_textureTransform, *territoryTransform); | ||||
DrawTexture(shader, 1.0f, angle, x, y, x2, y2); | DrawTexture(shader, 1.0f, angle, x, y, x2, y2); | ||||
tech->EndPass(); | tech->EndPass(); | ||||
Done Inline ActionsSee here it's doing the same for territory -> you can pretty much reuse this wraitii: See here it's doing the same for territory -> you can pretty much reuse this | |||||
// Draw the LOS quad in black, using alpha values from the LOS texture | // Draw the LOS quad in black, using alpha values from the LOS texture | ||||
if (!m_Mask) | if (!m_Mask) | ||||
{ | { | ||||
CShaderDefines losDefines; | CShaderDefines losDefines; | ||||
losDefines.Add(str_MINIMAP_LOS, str_1); | losDefines.Add(str_MINIMAP_LOS, str_1); | ||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), losDefines); | tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), losDefines); | ||||
tech->BeginPass(); | tech->BeginPass(); | ||||
shader = tech->GetShader(); | shader = tech->GetShader(); | ||||
shader->BindTexture(str_baseTex, losTexture.GetTexture()); | shader->BindTexture(str_baseTex, losTexture.GetTexture()); | ||||
const CMatrix3D* losTransform = losTexture.GetMinimapTextureMatrix(); | const CMatrix3D* losTransform = losTexture.GetMinimapTextureMatrix(); | ||||
shader->Uniform(str_transform, baseTransform); | shader->Uniform(str_transform, baseTransform); | ||||
shader->Uniform(str_textureTransform, *losTransform); | shader->Uniform(str_textureTransform, *losTransform); | ||||
DrawTexture(shader, 1.0f, angle, x, y, x2, y2); | DrawTexture(shader, 1.0f, angle, x, y, x2, y2); | ||||
tech->EndPass(); | tech->EndPass(); | ||||
} | } | ||||
glDisable(GL_BLEND); | glDisable(GL_BLEND); | ||||
PROFILE_START("minimap units"); | PROFILE_START("minimap units and flares"); | ||||
CShaderDefines pointDefines; | CShaderDefines pointDefines; | ||||
pointDefines.Add(str_MINIMAP_POINT, str_1); | pointDefines.Add(str_MINIMAP_POINT, str_1); | ||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), pointDefines); | tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), pointDefines); | ||||
Done Inline ActionsHere it reloads the shader with MINIMAP_POINT but I think you can just keep MINIMAP_BASE wraitii: Here it reloads the shader with MINIMAP_POINT but I think you can just keep MINIMAP_BASE | |||||
tech->BeginPass(); | tech->BeginPass(); | ||||
shader = tech->GetShader(); | shader = tech->GetShader(); | ||||
shader->Uniform(str_transform, baseTransform); | shader->Uniform(str_transform, baseTransform); | ||||
shader->Uniform(str_pointSize, 3.f); | shader->Uniform(str_pointSize, 3.f); | ||||
CMatrix3D unitMatrix; | CMatrix3D unitMatrix; | ||||
unitMatrix.SetIdentity(); | unitMatrix.SetIdentity(); | ||||
// Center the minimap on the origin of the axis of rotation. | // Center the minimap on the origin of the axis of rotation. | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | #if !CONFIG2_GLES | ||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | ||||
#endif | #endif | ||||
} | } | ||||
tech->EndPass(); | tech->EndPass(); | ||||
DrawViewRect(unitMatrix); | DrawViewRect(unitMatrix); | ||||
PROFILE_END("minimap units"); | while (!m_MapFlares.empty() && m_FlareLifetimeSeconds + m_MapFlares.front().time < cur_time) | ||||
m_MapFlares.pop_front(); | |||||
glEnable(GL_BLEND); | |||||
const float width = m_CachedActualSize.GetWidth(); | |||||
const float height = m_CachedActualSize.GetHeight(); | |||||
glScissor( | |||||
m_CachedActualSize.left * g_GuiScale, | |||||
g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | |||||
width * g_GuiScale, | |||||
height * g_GuiScale); | |||||
Done Inline ActionsI needto enable scissoring here to get it. ^^ Imarok: I needto enable scissoring here to get it. ^^
| |||||
Done Inline ActionsWhy do you need that? vladislavbelov: Why do you need that? | |||||
Done Inline ActionsElse parts of the circles may be drawn outside the minimap. Imarok: Else parts of the circles may be drawn outside the minimap. | |||||
Done Inline ActionsIs that bad? You will have circles over/under interface anyway. But anyway you have a mask that you might use to hide the circular area. vladislavbelov: Is that bad? You will have circles over/under interface anyway. But anyway you have a mask that… | |||||
glEnable(GL_SCISSOR_TEST); | |||||
CShaderDefines flareDefines; | |||||
flareDefines.Add(str_MINIMAP_FLARE, str_1); | |||||
tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), flareDefines); | |||||
tech->BeginPass(); | |||||
shader = tech->GetShader(); | |||||
shader->Uniform(str_transform, unitMatrix); | |||||
shader->Uniform(str_textureTransform, baseTextureTransform); | |||||
for (const MapFlare& flare : m_MapFlares) | |||||
DrawFlare(shader, flare, cur_time); | |||||
tech->EndPass(); | |||||
glDisable(GL_SCISSOR_TEST); | |||||
glDisable(GL_BLEND); | |||||
PROFILE_END("minimap units and flares"); | |||||
} | } | ||||
Not Done Inline ActionsIt's not good to modify a state during drawing. vladislavbelov: It's not good to modify a state during drawing. | |||||
Done Inline ActionsDon't see a good alternative. Do you have one? Imarok: Don't see a good alternative. Do you have one?
| |||||
Not Done Inline ActionsYou might check void Tick(). vladislavbelov: You might check `void Tick()`. | |||||
Done Inline Actionswhere? Imarok: where?
| |||||
void CMiniMap::CreateTextures() | void CMiniMap::CreateTextures() | ||||
{ | { | ||||
Destroy(); | Destroy(); | ||||
// Create terrain texture | // Create terrain texture | ||||
glGenTextures(1, &m_TerrainTexture); | glGenTextures(1, &m_TerrainTexture); | ||||
g_Renderer.BindTexture(0, m_TerrainTexture); | g_Renderer.BindTexture(0, m_TerrainTexture); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | for (u32 j = 0; j < h; ++j) | ||||
} | } | ||||
} | } | ||||
// Upload the texture | // Upload the texture | ||||
g_Renderer.BindTexture(0, m_TerrainTexture); | g_Renderer.BindTexture(0, m_TerrainTexture); | ||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize - 1, m_MapSize - 1, GL_RGBA, GL_UNSIGNED_BYTE, m_TerrainData); | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize - 1, m_MapSize - 1, GL_RGBA, GL_UNSIGNED_BYTE, m_TerrainData); | ||||
} | } | ||||
bool CMiniMap::Flare(const CVector2D& pos, const CStr& colorStr) | |||||
{ | |||||
CColor color; | |||||
Done Inline Actions. vladislavbelov: . | |||||
Done Inline ActionsWhat do you mean? Imarok: What do you mean? | |||||
Done Inline Actionsemplace_back. vladislavbelov: `emplace_back`. | |||||
if (!color.ParseString(colorStr)) | |||||
Done Inline ActionsMight use emplace. vladislavbelov: Might use `emplace`. | |||||
Done Inline ActionsDoesn't work. Maybe because color is a const ref and the rest not. Imarok: Doesn't work. Maybe because `color` is a const ref and the rest not. | |||||
{ | |||||
LOGERROR("CMiniMap::Flare: Couldn't parse color string"); | |||||
return false; | |||||
} | |||||
m_MapFlares.push_back({ GetMapCoordinates(pos.X, pos.Y), color, timer_Time() }); | |||||
Done Inline Actionsspaces after { and before } wraitii: spaces after { and before } | |||||
return true; | |||||
} | |||||
void CMiniMap::Destroy() | void CMiniMap::Destroy() | ||||
{ | { | ||||
if (m_TerrainTexture) | if (m_TerrainTexture) | ||||
{ | { | ||||
glDeleteTextures(1, &m_TerrainTexture); | glDeleteTextures(1, &m_TerrainTexture); | ||||
m_TerrainTexture = 0; | m_TerrainTexture = 0; | ||||
} | } | ||||
SAFE_ARRAY_DELETE(m_TerrainData); | SAFE_ARRAY_DELETE(m_TerrainData); | ||||
Done Inline Actionsdelete wraitii: delete | |||||
Done Inline Actionsnot the scope of the diff I'd say. Imarok: not the scope of the diff I'd say. | |||||
} | } | ||||
// static | // static | ||||
float CMiniMap::GetShallowPassageHeight() | float CMiniMap::GetShallowPassageHeight() | ||||
{ | { | ||||
float shallowPassageHeight = 0.0f; | float shallowPassageHeight = 0.0f; | ||||
CParamNode externalParamNode; | CParamNode externalParamNode; | ||||
CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml", "pathfinder"); | CParamNode::LoadXML(externalParamNode, L"simulation/data/pathfinder.xml", "pathfinder"); | ||||
const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses"); | const CParamNode pathingSettings = externalParamNode.GetChild("Pathfinder").GetChild("PassabilityClasses"); | ||||
if (pathingSettings.GetChild("default").IsOk() && pathingSettings.GetChild("default").GetChild("MaxWaterDepth").IsOk()) | if (pathingSettings.GetChild("default").IsOk() && pathingSettings.GetChild("default").GetChild("MaxWaterDepth").IsOk()) | ||||
shallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat(); | shallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat(); | ||||
return shallowPassageHeight; | return shallowPassageHeight; | ||||
} | } |
So, you're not going to use DDS?