Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : /*
19 : * System for representing tile-based information on top of the
20 : * terrain.
21 : */
22 :
23 : #ifndef INCLUDED_TERRAINOVERLAY
24 : #define INCLUDED_TERRAINOVERLAY
25 :
26 : #include "graphics/ShaderTechniquePtr.h"
27 : #include "renderer/backend/ITexture.h"
28 : #include "renderer/backend/IDeviceCommandContext.h"
29 : #include "renderer/backend/IShaderProgram.h"
30 : #include "renderer/backend/PipelineState.h"
31 :
32 : struct CColor;
33 : struct SColor4ub;
34 : class CTerrain;
35 : class CSimContext;
36 :
37 : /**
38 : * Common interface for terrain-tile-based and texture-based debug overlays.
39 : *
40 : * An overlay object will be rendered for as long as it is allocated
41 : * (it is automatically registered/deregistered by constructor/destructor).
42 : */
43 : class ITerrainOverlay
44 : {
45 : NONCOPYABLE(ITerrainOverlay);
46 :
47 : public:
48 : virtual ~ITerrainOverlay();
49 :
50 0 : virtual void RenderBeforeWater(Renderer::Backend::IDeviceCommandContext* UNUSED(deviceCommandContext)) { }
51 :
52 0 : virtual void RenderAfterWater(
53 0 : Renderer::Backend::IDeviceCommandContext* UNUSED(deviceCommandContext), int UNUSED(cullGroup)) { }
54 :
55 : /**
56 : * Draw all ITerrainOverlay objects that exist
57 : * and that should be drawn before water.
58 : */
59 : static void RenderOverlaysBeforeWater(
60 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
61 :
62 : /**
63 : * Draw all ITerrainOverlay objects that exist
64 : * and that should be drawn after water.
65 : */
66 : static void RenderOverlaysAfterWater(
67 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext, int cullGroup);
68 :
69 : protected:
70 : ITerrainOverlay(int priority);
71 : };
72 :
73 : /**
74 : * Base class for (relatively) simple drawing of
75 : * data onto terrain tiles, intended for debugging purposes and for the Atlas
76 : * editor (hence not trying to be very efficient).
77 : *
78 : * To start drawing a terrain overlay, first create a subclass of TerrainOverlay.
79 : * Override the method GetTileExtents if you want to change the range over which
80 : * it is drawn.
81 : * Override ProcessTile to do your processing for each tile, which should call
82 : * RenderTile and RenderTileOutline as appropriate.
83 : */
84 0 : class TerrainOverlay : public ITerrainOverlay
85 : {
86 : protected:
87 : /**
88 : * Construct the object and register it with the global
89 : * list of terrain overlays.
90 : * <p>
91 : * The priority parameter controls the order in which overlays are drawn,
92 : * if several exist - they are processed in order of increasing priority,
93 : * so later ones draw on top of earlier ones.
94 : * Most should use the default of 100. Numbers from 200 are used
95 : * by Atlas.
96 : *
97 : * @param priority controls the order of drawing
98 : */
99 : TerrainOverlay(const CSimContext& simContext, int priority = 100);
100 :
101 : /**
102 : * Override to perform processing at the start of the overlay rendering,
103 : * before the ProcessTile calls
104 : */
105 : virtual void StartRender();
106 :
107 : /**
108 : * Override to perform processing at the end of the overlay rendering,
109 : * after the ProcessTile calls
110 : */
111 : virtual void EndRender();
112 :
113 : /**
114 : * Override to limit the range over which ProcessTile will
115 : * be called. Defaults to the size of the map.
116 : *
117 : * @param min_i_inclusive [output] smallest <i>i</i> coordinate, in tile-space units
118 : * (1 unit per tile, <i>+i</i> is world-space <i>+x</i> and game-space East)
119 : * @param min_j_inclusive [output] smallest <i>j</i> coordinate
120 : * (<i>+j</i> is world-space <i>+z</i> and game-space North)
121 : * @param max_i_inclusive [output] largest <i>i</i> coordinate
122 : * @param max_j_inclusive [output] largest <i>j</i> coordinate
123 : */
124 : virtual void GetTileExtents(ssize_t& min_i_inclusive, ssize_t& min_j_inclusive,
125 : ssize_t& max_i_inclusive, ssize_t& max_j_inclusive);
126 :
127 : /**
128 : * Override to perform processing of each tile. Typically calls
129 : * RenderTile and/or RenderTileOutline.
130 : *
131 : * @param i <i>i</i> coordinate of tile being processed
132 : * @param j <i>j</i> coordinate of tile being processed
133 : */
134 : virtual void ProcessTile(
135 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
136 : ssize_t i, ssize_t j) = 0;
137 :
138 : /**
139 : * Draw a filled quad on top of the current tile.
140 : *
141 : * @param color color to draw. May be transparent (alpha < 1)
142 : * @param drawHidden true if hidden tiles (i.e. those behind other tiles)
143 : * should be drawn
144 : */
145 : void RenderTile(
146 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
147 : const CColor& color, bool drawHidden);
148 :
149 : /**
150 : * Draw a filled quad on top of the given tile.
151 : */
152 : void RenderTile(
153 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
154 : const CColor& color, bool drawHidden, ssize_t i, ssize_t j);
155 :
156 : /**
157 : * Draw an outlined quad on top of the current tile.
158 : *
159 : * @param color color to draw. May be transparent (alpha < 1)
160 : * @param lineWidth width of lines in pixels. 1 is a sensible value
161 : * @param drawHidden true if hidden tiles (i.e. those behind other tiles)
162 : * should be drawn
163 : */
164 : void RenderTileOutline(
165 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
166 : const CColor& color, bool drawHidden);
167 :
168 : /**
169 : * Draw an outlined quad on top of the given tile.
170 : */
171 : void RenderTileOutline(
172 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
173 : const CColor& color, bool drawHidden, ssize_t i, ssize_t j);
174 :
175 : private:
176 : // Process all tiles
177 : void RenderBeforeWater(
178 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext) override;
179 :
180 : // Temporary storage of tile coordinates, so ProcessTile doesn't need to
181 : // pass it to RenderTile/etc (and doesn't have a chance to get it wrong)
182 : ssize_t m_i, m_j;
183 :
184 : CTerrain* m_Terrain;
185 :
186 : CShaderTechniquePtr m_OverlayTechTile, m_OverlayTechTileHidden;
187 : CShaderTechniquePtr m_OverlayTechOutline, m_OverlayTechOutlineHidden;
188 :
189 : Renderer::Backend::IVertexInputLayout* m_VertexInputLayout = nullptr;
190 : };
191 :
192 : /**
193 : * Base class for texture-based terrain overlays, with an arbitrary number of
194 : * texels per terrain tile, intended for debugging purposes.
195 : * Subclasses must implement BuildTextureRGBA which will be called each frame.
196 : */
197 0 : class TerrainTextureOverlay : public ITerrainOverlay
198 : {
199 : public:
200 : TerrainTextureOverlay(float texelsPerTile, int priority = 100);
201 :
202 : ~TerrainTextureOverlay() override;
203 :
204 : protected:
205 : /**
206 : * Called each frame to generate the texture to render on the terrain.
207 : * @p data is w*h*4 bytes, where w and h are the terrain size multiplied
208 : * by texelsPerTile. @p data defaults to fully transparent, and should
209 : * be filled with data in RGBA order.
210 : */
211 : virtual void BuildTextureRGBA(u8* data, size_t w, size_t h) = 0;
212 :
213 : /**
214 : * Returns an arbitrary color, for subclasses that want to distinguish
215 : * different integers visually.
216 : */
217 : SColor4ub GetColor(size_t idx, u8 alpha) const;
218 :
219 : private:
220 : void RenderAfterWater(
221 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext, int cullGroup) override;
222 :
223 : float m_TexelsPerTile;
224 : std::unique_ptr<Renderer::Backend::ITexture> m_Texture;
225 : };
226 :
227 : #endif // INCLUDED_TERRAINOVERLAY
|