Changeset View
Standalone View
source/gui/ObjectTypes/CMiniMap.cpp
/* Copyright (C) 2019 Wildfire Games. | /* Copyright (C) 2020 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
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_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), | ||||
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) | ||||
{ | { | ||||
AddSetting<float>("ping_x"); | |||||
AddSetting<float>("ping_z"); | |||||
AddSetting<CColor>("ping_color"); | |||||
AddSetting<bool>("ping"); | |||||
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"); | ||||
// Get the maximum height for unit passage in water. | // Get the maximum height for unit passage in water. | ||||
CParamNode externalParamNode; | CParamNode externalParamNode; | ||||
▲ Show 20 Lines • Show All 49 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) | ||||
{ | { | ||||
Show All 17 Lines | void CMiniMap::HandleMessage(SGUIMessage& Message) | ||||
case GUIM_MOUSE_ENTER: | case GUIM_MOUSE_ENTER: | ||||
m_MouseHovering = true; | m_MouseHovering = true; | ||||
break; | break; | ||||
case GUIM_MOUSE_LEAVE: | case GUIM_MOUSE_LEAVE: | ||||
m_Clicking = false; | m_Clicking = false; | ||||
m_MouseHovering = false; | m_MouseHovering = false; | ||||
break; | break; | ||||
case GUIM_MOUSE_RELEASE_RIGHT: | case GUIM_MOUSE_RELEASE_RIGHT: | ||||
CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 1); | FireWorldClickEvent("mouserightrelease"); | ||||
break; | break; | ||||
case GUIM_MOUSE_DBLCLICK_RIGHT: | case GUIM_MOUSE_DBLCLICK_RIGHT: | ||||
CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 2); | FireWorldClickEvent("mouserightdoubleclick"); | ||||
break; | |||||
case GUIM_MOUSE_RELEASE_MIDDLE: | |||||
FireWorldClickEvent("mousemiddlerelease"); | |||||
break; | |||||
case GUIM_MOUSE_DBLCLICK_MIDDLE: | |||||
FireWorldClickEvent("mousemiddledoubleclick"); | |||||
break; | break; | ||||
case GUIM_MOUSE_MOTION: | case GUIM_MOUSE_MOTION: | ||||
if (m_MouseHovering && m_Clicking) | if (m_MouseHovering && m_Clicking) | ||||
SetCameraPos(); | SetCameraPos(); | ||||
break; | break; | ||||
case GUIM_MOUSE_WHEEL_DOWN: | case GUIM_MOUSE_WHEEL_DOWN: | ||||
case GUIM_MOUSE_WHEEL_UP: | case GUIM_MOUSE_WHEEL_UP: | ||||
Message.Skip(); | Message.Skip(); | ||||
break; | break; | ||||
case GUIM_SETTINGS_UPDATED: | |||||
if (Message.value == "ping") | |||||
{ | |||||
bool doPing = false; | |||||
GUI<bool>::GetSetting(this, "ping", doPing); | |||||
if (doPing) | |||||
{ | |||||
GUI<bool>::SetSetting(this, "ping", false); | |||||
float pingX; | |||||
GUI<float>::GetSetting(this, "ping_x", pingX); | |||||
float pingZ; | |||||
GUI<float>::GetSetting(this, "ping_z", pingZ); | |||||
CColor pingColor; | |||||
GUI<CColor>::GetSetting(this, "ping_color", pingColor); | |||||
m_MapPings.push_back({GetMapCoordinates(pingX, pingZ), pingColor, timer_Time()}); | |||||
} | |||||
} | |||||
break; | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
bool CMiniMap::IsMouseOver() const | bool CMiniMap::IsMouseOver() const | ||||
{ | { | ||||
// Get the mouse position. | // Get the mouse position. | ||||
Done Inline Actionsdebug? wraitii: debug? | |||||
Done Inline ActionsAh, yeah. Imarok: Ah, yeah.
I uploaded in a hurry >< | |||||
const CPos& mousePos = m_pGUI.GetMousePos(); | const CPos& mousePos = m_pGUI.GetMousePos(); | ||||
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 ;) | |||||
// Get the position of the center of the minimap. | // Get the position of the center of the minimap. | ||||
CPos minimapCenter = CPos(m_CachedActualSize.left + m_CachedActualSize.GetWidth() / 2.0, m_CachedActualSize.bottom - m_CachedActualSize.GetHeight() / 2.0); | CPos minimapCenter = CPos(m_CachedActualSize.left + m_CachedActualSize.GetWidth() / 2.0, m_CachedActualSize.bottom - m_CachedActualSize.GetHeight() / 2.0); | ||||
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… | |||||
// 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)); | ||||
Done Inline Actionsemplace_back. vladislavbelov: `emplace_back`. | |||||
// If the distance is less then the radius of the minimap (half the width) the mouse is over the minimap. | // If the distance is less then the radius of the minimap (half the width) the mouse is over the minimap. | ||||
if (distFromCenter < m_CachedActualSize.GetWidth() / 2.0) | if (distFromCenter < m_CachedActualSize.GetWidth() / 2.0) | ||||
return true; | return true; | ||||
else | else | ||||
return false; | return false; | ||||
} | } | ||||
void CMiniMap::GetMouseWorldCoordinates(float& x, float& z) const | void CMiniMap::GetMouseWorldCoordinates(float& x, float& z) const | ||||
{ | { | ||||
// Determine X and Z according to proportion of mouse position and minimap | // Determine X and Z according to proportion of mouse position and minimap | ||||
const CPos& mousePos = m_pGUI.GetMousePos(); | const CPos& mousePos = m_pGUI.GetMousePos(); | ||||
float px = (mousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth(); | float px = (mousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth(); | ||||
float py = (m_CachedActualSize.bottom - mousePos.y) / m_CachedActualSize.GetHeight(); | float py = (m_CachedActualSize.bottom - mousePos.y) / m_CachedActualSize.GetHeight(); | ||||
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); | ||||
} | } | ||||
CPos 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 CPos(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); | ||||
} | } | ||||
float CMiniMap::GetAngle() const | float CMiniMap::GetAngle() const | ||||
{ | { | ||||
CVector3D cameraIn = m_Camera->GetOrientation().GetIn(); | CVector3D cameraIn = m_Camera->GetOrientation().GetIn(); | ||||
return -atan2(cameraIn.X, cameraIn.Z); | return -atan2(cameraIn.X, cameraIn.Z); | ||||
} | } | ||||
void CMiniMap::FireWorldClickEvent(int UNUSED(button), int UNUSED(clicks)) | void CMiniMap::FireWorldClickEvent(const CStr& eventType) | ||||
{ | { | ||||
JSContext* cx = g_GUI->GetActiveGUI()->GetScriptInterface()->GetContext(); | JSContext* cx = g_GUI->GetActiveGUI()->GetScriptInterface()->GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
float x, z; | float x, z; | ||||
GetMouseWorldCoordinates(x, z); | GetMouseWorldCoordinates(x, z); | ||||
JS::RootedValue coords(cx); | JS::RootedValue target(cx); | ||||
ScriptInterface::CreateObject(cx, &coords, "x", x, "z", z); | g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &target); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(target, "x", x, false); | |||||
JS::AutoValueVector paramData(cx); | g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(target, "z", z, false); | ||||
paramData.append(coords); | JS::RootedValue data(cx); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", &data); | |||||
ScriptEvent(EventNameWorldClick, paramData); | g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(data, "target", target, false); | ||||
g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(data, "type", eventType, false); | |||||
ScriptEvent("worldclick", data); | |||||
} | } | ||||
// This sets up and draws the rectangle on the minimap | // This sets up and draws the rectangle on the minimap | ||||
// which represents the view of the camera in the world. | // which represents the view of the camera in the world. | ||||
void CMiniMap::DrawViewRect(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 float invTileMapSize = 1.0f / float(TERRAIN_TILE_SIZE * m_MapSize); | ||||
CVector3D hitPt[4]; | CVector3D hitPt[4]; | ||||
hitPt[0] = m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h); | hitPt[0] = m_Camera->GetWorldCoordinates(0, g_Renderer.GetHeight(), h); | ||||
hitPt[1] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h); | hitPt[1] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), g_Renderer.GetHeight(), h); | ||||
hitPt[2] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h); | hitPt[2] = m_Camera->GetWorldCoordinates(g_Renderer.GetWidth(), 0, h); | ||||
hitPt[3] = m_Camera->GetWorldCoordinates(0, 0, h); | hitPt[3] = m_Camera->GetWorldCoordinates(0, 0, h); | ||||
float ViewRect[4][2]; | CPos ViewRect[4]; | ||||
for (int i = 0; i < 4; ++i) | for (int i = 0; i < 4; ++i) | ||||
{ | |||||
// convert to minimap space | // convert to minimap space | ||||
ViewRect[i][0] = (width * hitPt[i].X * invTileMapSize); | ViewRect[i] = GetMapCoordinates(hitPt[i].X, hitPt[i].Z); | ||||
ViewRect[i][1] = (height * hitPt[i].Z * invTileMapSize); | |||||
} | |||||
float viewVerts[] = { | float viewVerts[] = { | ||||
ViewRect[0][0], -ViewRect[0][1], | ViewRect[0].x, -ViewRect[0].y, | ||||
ViewRect[1][0], -ViewRect[1][1], | ViewRect[1].x, -ViewRect[1].y, | ||||
ViewRect[2][0], -ViewRect[2][1], | ViewRect[2].x, -ViewRect[2].y, | ||||
ViewRect[3][0], -ViewRect[3][1] | ViewRect[3].x, -ViewRect[3].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.m_SkipSubmit) | ||||
glDrawArrays(GL_LINE_LOOP, 0, 4); | glDrawArrays(GL_LINE_LOOP, 0, 4); | ||||
tech->EndPass(); | tech->EndPass(); | ||||
glLineWidth(1.0f); | glLineWidth(1.0f); | ||||
glDisable(GL_SCISSOR_TEST); | glDisable(GL_SCISSOR_TEST); | ||||
} | } | ||||
// TODO: Hacky and ugly copypasta | |||||
Done Inline ActionscurrentTime. vladislavbelov: `currentTime`. | |||||
void CMiniMap::DrawPing(const CMatrix3D& transform, const MapPingObj& ping, double cur_time) | |||||
{ | |||||
Done Inline Actions. vladislavbelov: . | |||||
Done Inline ActionsStill some commented code. vladislavbelov: Still some commented code. | |||||
float step = std::fmod((cur_time - ping.time) * 10, 10); | |||||
float viewVerts[] = { | |||||
ping.pos.x + step, -ping.pos.y-step, | |||||
ping.pos.x - step, -ping.pos.y-step, | |||||
Done Inline Actionsstatic_cast. vladislavbelov: `static_cast`. | |||||
ping.pos.x - step, -ping.pos.y+step, | |||||
ping.pos.x + step, -ping.pos.y+step | |||||
}; | |||||
const float width = m_CachedActualSize.GetWidth(); | |||||
const float height = m_CachedActualSize.GetHeight(); | |||||
// Enable Scissoring to restrict the rectangle to only the minimap. | |||||
glScissor( | |||||
m_CachedActualSize.left * g_GuiScale, | |||||
g_Renderer.GetHeight() - m_CachedActualSize.bottom * g_GuiScale, | |||||
width * g_GuiScale, | |||||
height * g_GuiScale); | |||||
glEnable(GL_SCISSOR_TEST); | |||||
glLineWidth(2.0f); | |||||
CShaderDefines lineDefines; | |||||
lineDefines.Add(str_MINIMAP_LINE, str_1); | |||||
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), lineDefines); | |||||
tech->BeginPass(); | |||||
CShaderProgramPtr shader = tech->GetShader(); | |||||
shader->Uniform(str_transform, transform); | |||||
shader->Uniform(str_color, ping.color.r, ping.color.g, ping.color.b, ping.color.a); | |||||
shader->VertexPointer(2, GL_FLOAT, 0, viewVerts); | |||||
shader->AssertPointersBound(); | |||||
Done Inline Actionsconst. vladislavbelov: `const`. | |||||
if (!g_Renderer.m_SkipSubmit) | |||||
glDrawArrays(GL_LINE_LOOP, 0, 4); | |||||
tech->EndPass(); | |||||
glLineWidth(1.0f); | |||||
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. | |||||
glDisable(GL_SCISSOR_TEST); | |||||
} | |||||
struct MinimapUnitVertex | struct MinimapUnitVertex | ||||
{ | { | ||||
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 | |||||
// 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; | ||||
Done Inline ActionsMissed constants for 8 and 16. vladislavbelov: Missed constants for 8 and 16. | |||||
}; | }; | ||||
// 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; | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | void CMiniMap::Draw() | ||||
CShaderProgramPtr shader; | CShaderProgramPtr shader; | ||||
CShaderTechniquePtr tech; | CShaderTechniquePtr tech; | ||||
CShaderDefines baseDefines; | CShaderDefines baseDefines; | ||||
baseDefines.Add(str_MINIMAP_BASE, str_1); | baseDefines.Add(str_MINIMAP_BASE, 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); | ||||
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); | ||||
DrawTexture(shader, texCoordMax, angle, x, y, x2, y2, z); | DrawTexture(shader, texCoordMax, angle, x, y, x2, y2, z); | ||||
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… | |||||
// Draw territory boundaries | // Draw territory boundaries | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture(); | CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture(); | ||||
shader->BindTexture(str_baseTex, territoryTexture.GetTexture()); | shader->BindTexture(str_baseTex, territoryTexture.GetTexture()); | ||||
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, z); | DrawTexture(shader, 1.0f, angle, x, y, x2, y2, z); | ||||
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 | ||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); | CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); | ||||
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(); | ||||
Show All 10 Lines | void CMiniMap::Draw() | ||||
tech->EndPass(); | tech->EndPass(); | ||||
glDisable(GL_BLEND); | glDisable(GL_BLEND); | ||||
PROFILE_START("minimap units"); | PROFILE_START("minimap units"); | ||||
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 101 Lines • ▼ Show 20 Lines | if (g_RenderingOptions.GetRenderPath() == RenderPath::SHADER) | ||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | ||||
#endif | #endif | ||||
} | } | ||||
tech->EndPass(); | tech->EndPass(); | ||||
DrawViewRect(unitMatrix); | DrawViewRect(unitMatrix); | ||||
while (!m_MapPings.empty() && 3 + m_MapPings.front().time < cur_time) | |||||
m_MapPings.pop_front(); | |||||
for (const MapPingObj& ping : m_MapPings) | |||||
DrawPing(unitMatrix, ping, cur_time); | |||||
PROFILE_END("minimap units"); | PROFILE_END("minimap units"); | ||||
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?
| |||||
// Reset depth mask | // Reset depth mask | ||||
glDepthMask(1); | glDepthMask(1); | ||||
} | } | ||||
void CMiniMap::CreateTextures() | void CMiniMap::CreateTextures() | ||||
{ | { | ||||
Destroy(); | Destroy(); | ||||
// Create terrain texture | // Create terrain texture | ||||
glGenTextures(1, &m_TerrainTexture); | glGenTextures(1, &m_TerrainTexture); | ||||
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… | |||||
g_Renderer.BindTexture(0, m_TerrainTexture); | g_Renderer.BindTexture(0, m_TerrainTexture); | ||||
// Initialise texture with solid black, for the areas we don't | // Initialise texture with solid black, for the areas we don't | ||||
// overwrite with glTexSubImage2D later | // overwrite with glTexSubImage2D later | ||||
u32* texData = new u32[m_TextureSize * m_TextureSize]; | u32* texData = new u32[m_TextureSize * m_TextureSize]; | ||||
for (ssize_t i = 0; i < m_TextureSize * m_TextureSize; ++i) | for (ssize_t i = 0; i < m_TextureSize * m_TextureSize; ++i) | ||||
texData[i] = 0xFF000000; | texData[i] = 0xFF000000; | ||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | void CMiniMap::RebuildTerrainTexture() | ||||
// 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); | ||||
} | } | ||||
void CMiniMap::Destroy() | void CMiniMap::Destroy() | ||||
{ | { | ||||
if (m_TerrainTexture) | if (m_TerrainTexture) | ||||
Done Inline Actions. vladislavbelov: . | |||||
Done Inline ActionsWhat do you mean? Imarok: What do you mean? | |||||
Done Inline Actionsemplace_back. vladislavbelov: `emplace_back`. | |||||
{ | { | ||||
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. | |||||
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 Actionsspaces after { and before } wraitii: spaces after { and before } | |||||
} | } | ||||
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. |
So, you're not going to use DDS?