Line data Source code
1 : /* Copyright (C) 2021 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 : #ifndef INCLUDED_GRAPHICS_OVERLAY
19 : #define INCLUDED_GRAPHICS_OVERLAY
20 :
21 : #include "graphics/Color.h"
22 : #include "graphics/Texture.h"
23 : #include "maths/Vector2D.h"
24 : #include "maths/Vector3D.h"
25 : #include "ps/CStrIntern.h"
26 :
27 : #include <vector>
28 :
29 : class CFrustum;
30 : class CSimContext;
31 : class CTexturedLineRData;
32 : struct SOverlayDescriptor;
33 :
34 : /**
35 : * Line-based overlay, with world-space coordinates, rendered in the world
36 : * potentially behind other objects. Designed for debug info.
37 : */
38 0 : struct SOverlayLine
39 : {
40 0 : SOverlayLine() : m_Thickness(0.1f) { }
41 :
42 : CColor m_Color;
43 : // Shape is not automatically closed.
44 : std::vector<CVector3D> m_Coords;
45 : // Half-width of the line, in world-space units.
46 : float m_Thickness;
47 :
48 0 : void PushCoords(const CVector3D& v) { m_Coords.emplace_back(v); }
49 :
50 0 : void PushCoords(const float x, const float y, const float z)
51 : {
52 0 : m_Coords.emplace_back(x, y, z);
53 0 : }
54 : };
55 :
56 : /**
57 : * Textured line overlay, with world-space coordinates, rendered in the world onto the terrain.
58 : * Designed for relatively static textured lines, i.e. territory borders, originally.
59 : *
60 : * Once submitted for rendering, instances must not be copied afterwards. The reason is that they
61 : * are assigned rendering data that is unique to the submitted instance, and non-transferable to
62 : * any copies that would otherwise be made. Amongst others, this restraint includes that they must
63 : * not be submitted by their address inside a std::vector storing them by value.
64 : */
65 0 : struct SOverlayTexturedLine
66 : {
67 : enum LineCapType
68 : {
69 : LINECAP_FLAT, ///< no line ending; abrupt stop of the line (aka. butt ending)
70 :
71 : /**
72 : * Semi-circular line ending. The texture is mapped by curving the left vertical edge
73 : * around the semi-circle's rim. That is, the center point has UV coordinates (0.5;0.5),
74 : * and the rim vertices all have U coordinate 0 and a V coordinate that ranges from 0 to
75 : * 1 as the rim is traversed.
76 : */
77 : LINECAP_ROUND,
78 : LINECAP_SHARP, ///< sharp point ending
79 : LINECAP_SQUARE, ///< square end that extends half the line width beyond the line end
80 : };
81 :
82 0 : SOverlayTexturedLine()
83 0 : : m_Thickness(1.0f), m_Closed(false), m_AlwaysVisible(false),
84 0 : m_StartCapType(LINECAP_FLAT), m_EndCapType(LINECAP_FLAT), m_SimContext(NULL)
85 0 : { }
86 :
87 : CTexturePtr m_TextureBase;
88 : CTexturePtr m_TextureMask;
89 :
90 : /// Color to apply to the line texture, where indicated by the mask.
91 : CColor m_Color;
92 : /// (x, z) vertex coordinate pairs; y is computed automatically.
93 : std::vector<CVector2D> m_Coords;
94 : /// Half-width of the line, in world-space units.
95 : float m_Thickness;
96 : /// Should this line be treated as a closed loop? If set, any end cap settings are ignored.
97 : bool m_Closed;
98 : /// Should this line be rendered fully visible at all times, even under the SoD?
99 : bool m_AlwaysVisible;
100 :
101 : LineCapType m_StartCapType;
102 : LineCapType m_EndCapType;
103 :
104 : /**
105 : * Simulation context applicable for this overlay line; used to obtain terrain information
106 : * during automatic computation of Y coordinates.
107 : */
108 : const CSimContext* m_SimContext;
109 :
110 : /**
111 : * Cached renderer data, because expensive to compute. Allocated by the renderer when necessary
112 : * for rendering purposes.
113 : *
114 : * Note: the rendering data may be shared between copies of this object to prevent having to
115 : * recompute it, while at the same time maintaining copyability of this object (see also docs on
116 : * CTexturedLineRData).
117 : */
118 : std::shared_ptr<CTexturedLineRData> m_RenderData;
119 :
120 : /**
121 : * Converts a string line cap type into its corresponding LineCap enum value, and returns
122 : * the resulting value. If the input string is unrecognized, a warning is issued and a
123 : * default value is returned.
124 : */
125 : static LineCapType StrToLineCapType(const std::wstring& str);
126 :
127 : /**
128 : * Creates the texture specified by the given overlay descriptor and assigns it to this overlay.
129 : */
130 : void CreateOverlayTexture(const SOverlayDescriptor* overlayDescriptor);
131 :
132 0 : void PushCoords(const float x, const float z) { m_Coords.emplace_back(x, z); }
133 0 : void PushCoords(const CVector2D& v) { m_Coords.push_back(v); }
134 0 : void PushCoords(const std::vector<CVector2D>& points)
135 : {
136 0 : for (const CVector2D& point : points)
137 0 : PushCoords(point);
138 0 : }
139 :
140 : bool IsVisibleInFrustum(const CFrustum& frustum) const;
141 : };
142 :
143 : /**
144 : * Billboard sprite overlay, with world-space coordinates, rendered on top
145 : * of all other objects. Designed for health bars and rank icons.
146 : */
147 0 : struct SOverlaySprite
148 : {
149 : CTexturePtr m_Texture;
150 : CColor m_Color;
151 : CVector3D m_Position; // base position
152 : float m_X0, m_Y0, m_X1, m_Y1; // billboard corner coordinates, relative to base position
153 : };
154 :
155 : /**
156 : * Rectangular single-quad terrain overlay, in world space coordinates. The vertices of the quad
157 : * are not required to be coplanar; the quad is arbitrarily triangulated with no effort being made
158 : * to find a best fit to the underlying terrain.
159 : */
160 0 : struct SOverlayQuad
161 : {
162 : CTexturePtr m_Texture;
163 : CTexturePtr m_TextureMask;
164 : CVector3D m_Corners[4];
165 : CColor m_Color;
166 : };
167 :
168 : struct SOverlaySphere
169 : {
170 0 : SOverlaySphere() : m_Radius(0) { }
171 :
172 : CVector3D m_Center;
173 : float m_Radius;
174 : CColor m_Color;
175 : };
176 :
177 : enum EOverlayType
178 : {
179 : /// A single textured quad overlay, intended for entities that move around much, like units (e.g. foot soldiers, etc).
180 : DYNAMIC_QUAD,
181 : /// A more complex textured line overlay, composed of several textured line segments.
182 : STATIC_OUTLINE,
183 : };
184 :
185 : struct SOverlayDescriptor
186 : {
187 : EOverlayType m_Type;
188 : CStrIntern m_QuadTexture;
189 : CStrIntern m_QuadTextureMask;
190 : CStrIntern m_LineTexture;
191 : CStrIntern m_LineTextureMask;
192 : float m_LineThickness;
193 : int m_Radius;
194 :
195 0 : SOverlayDescriptor() : m_LineThickness(0) { }
196 : };
197 :
198 : // TODO: OverlayText
199 :
200 : #endif // INCLUDED_GRAPHICS_OVERLAY
|