1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D.
*
* 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
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_MINIMAPTEXTURE
#define INCLUDED_MINIMAPTEXTURE
#include "graphics/Color.h"
#include "graphics/Texture.h"
#include "maths/Vector2D.h"
#include "renderer/backend/IDeviceCommandContext.h"
#include "renderer/backend/ITexture.h"
#include "renderer/VertexArray.h"
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
class CSimulation2;
class CTerrain;
class CMiniMapTexture
{
NONCOPYABLE(CMiniMapTexture);
public:
CMiniMapTexture(CSimulation2& simulation);
~CMiniMapTexture();
/**
* Marks the texture as dirty if it's old enough to redraw it on Render.
*/
void Update(const float deltaRealTime);
/**
* Redraws the texture if it's dirty.
*/
void Render(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
Renderer::Backend::ITexture* GetTexture() const { return m_FinalTexture.get(); }
/**
* @return The maximum height for unit passage in water.
*/
static float GetShallowPassageHeight();
struct Icon
{
CTexturePtr texture;
CColor color;
CVector2D worldPosition;
float halfSize;
};
// Returns icons for corresponding entities on the minimap texture.
const std::vector<Icon>& GetIcons() { return m_Icons; }
private:
void CreateTextures(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
const CTerrain* terrain);
void DestroyTextures();
void RebuildTerrainTexture(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
const CTerrain* terrain);
void RenderFinalTexture(
Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
CSimulation2& m_Simulation;
bool m_TerrainTextureDirty = true;
bool m_FinalTextureDirty = true;
double m_LastFinalTextureUpdate = 0.0;
// minimap texture handles
std::unique_ptr<Renderer::Backend::ITexture>
m_TerrainTexture, m_FinalTexture;
std::unique_ptr<Renderer::Backend::IFramebuffer>
m_FinalTextureFramebuffer;
// texture data
std::unique_ptr<u32[]> m_TerrainData;
// map size
ssize_t m_MapSize = 0;
// Maximal water height to allow the passage of a unit (for underwater shallows).
float m_ShallowPassageHeight = 0.0f;
float m_WaterHeight = 0.0f;
VertexIndexArray m_IndexArray;
VertexArray m_VertexArray;
VertexArray::Attribute m_AttributePos;
VertexArray::Attribute m_AttributeColor;
bool m_UseInstancing = false;
// Vertex data if instancing is supported.
VertexArray m_InstanceVertexArray;
VertexArray::Attribute m_InstanceAttributePosition;
size_t m_EntitiesDrawn = 0;
double m_PingDuration = 25.0;
double m_HalfBlinkDuration = 0.0;
double m_NextBlinkTime = 0.0;
bool m_BlinkState = false;
std::vector<Icon> m_Icons;
// We store the map as a member to avoid redundant reallocations on each
// update. We use a grid approach to combine icons by distance.
struct CellIconKey
{
std::string path;
u8 r, g, b;
};
struct CellIconKeyHash
{
size_t operator()(const CellIconKey& key) const;
};
struct CellIconKeyEqual
{
bool operator()(const CellIconKey& lhs, const CellIconKey& rhs) const;
};
struct CellIcon
{
// TODO: use CVector2DI.
u16 gridX, gridY;
float halfSize;
CVector2D worldPosition;
};
std::unordered_map<CellIconKey, std::vector<CellIcon>, CellIconKeyHash, CellIconKeyEqual> m_IconsCache;
};
#endif // INCLUDED_MINIMAPTEXTURE
|