1 /* Copyright (C) 2017 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 #include "precompiled.h"
19
20 #include <sstream>
21 #include <string>
22
23 #include "graphics/CinemaManager.h"
24
25 #include "graphics/Camera.h"
26 #include "graphics/GameView.h"
27 #include "gui/CGUI.h"
28 #include "gui/GUIutil.h"
29 #include "gui/GUIManager.h"
30 #include "gui/IGUIObject.h"
31 #include "lib/ogl.h"
32 #include "maths/MathUtil.h"
33 #include "maths/Quaternion.h"
34 #include "maths/Vector3D.h"
35 #include "maths/Vector4D.h"
36 #include "ps/CLogger.h"
37 #include "ps/ConfigDB.h"
38 #include "ps/CStr.h"
39 #include "ps/Game.h"
40 #include "ps/GameSetup/Config.h"
41 #include "ps/Hotkey.h"
42 #include "ps/World.h"
43 #include "simulation2/components/ICmpCinemaManager.h"
44 #include "simulation2/components/ICmpOverlayRenderer.h"
45 #include "simulation2/components/ICmpRangeManager.h"
46 #include "simulation2/components/ICmpSelectable.h"
47 #include "simulation2/components/ICmpTerritoryManager.h"
48 #include "simulation2/MessageTypes.h"
49 #include "simulation2/system/ComponentManager.h"
50 #include "simulation2/Simulation2.h"
51 #include "renderer/Renderer.h"
52
53
CCinemaManager()54 CCinemaManager::CCinemaManager()
55 : m_DrawPaths(false)
56 {
57 }
58
Update(const float deltaRealTime) const59 void CCinemaManager::Update(const float deltaRealTime) const
60 {
61 CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
62 if (!cmpCinemaManager)
63 return;
64
65 if (IsPlaying())
66 cmpCinemaManager->PlayQueue(deltaRealTime, g_Game->GetView()->GetCamera());
67 }
68
Render() const69 void CCinemaManager::Render() const
70 {
71 if (IsEnabled())
72 DrawBars();
73 else if (m_DrawPaths)
74 DrawPaths();
75 }
76
DrawPaths() const77 void CCinemaManager::DrawPaths() const
78 {
79 CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
80 if (!cmpCinemaManager)
81 return;
82
83 for (const std::pair<CStrW, CCinemaPath>& p : cmpCinemaManager->GetPaths())
84 {
85 DrawSpline(p.second, CColor(0.2f, 0.2f, 1.f, 0.9f), 128, true);
86 DrawNodes(p.second, CColor(0.1f, 1.f, 0.f, 1.f));
87
88 if (p.second.GetTargetSpline().GetAllNodes().empty())
89 continue;
90
91 DrawSpline(p.second.GetTargetSpline(), CColor(1.f, 0.3f, 0.4f, 0.9f), 128, true);
92 DrawNodes(p.second.GetTargetSpline(), CColor(1.f, 0.1f, 0.f, 1.f));
93 }
94 }
95
DrawSpline(const RNSpline & spline,const CColor & splineColor,int smoothness,bool lines) const96 void CCinemaManager::DrawSpline(const RNSpline& spline, const CColor& splineColor, int smoothness, bool lines) const
97 {
98 if (spline.GetAllNodes().size() < 2)
99 return;
100 if (spline.GetAllNodes().size() == 2 && lines)
101 smoothness = 2;
102
103 float start = spline.MaxDistance.ToFloat() / smoothness;
104 float time = 0;
105
106 #if CONFIG2_GLES
107 #warning TODO : implement CCinemaPath on GLES
108 #else
109
110 glDisable(GL_DEPTH_TEST);
111 glEnable(GL_BLEND);
112 glColor4f(splineColor.r, splineColor.g, splineColor.b, splineColor.a);
113 if (lines)
114 {
115 glLineWidth(1.8f);
116 glEnable(GL_LINE_SMOOTH);
117 glBegin(GL_LINE_STRIP);
118 for (int i = 0; i <= smoothness; ++i)
119 {
120 time = start * i / spline.MaxDistance.ToFloat();
121 CVector3D tmp = spline.GetPosition(time);
122 glVertex3f(tmp.X, tmp.Y, tmp.Z);
123 }
124 glEnd();
125
126 // Height indicator
127 if (g_Game && g_Game->GetWorld() && g_Game->GetWorld()->GetTerrain())
128 {
129 glLineWidth(1.1f);
130 glBegin(GL_LINES);
131 for (int i = 0; i <= smoothness; ++i)
132 {
133 time = start * i / spline.MaxDistance.ToFloat();
134 CVector3D tmp = spline.GetPosition(time);
135 float groundY = g_Game->GetWorld()->GetTerrain()->GetExactGroundLevel(tmp.X, tmp.Z);
136 glVertex3f(tmp.X, tmp.Y, tmp.Z);
137 glVertex3f(tmp.X, groundY, tmp.Z);
138 }
139 glEnd();
140 }
141
142 glDisable(GL_LINE_SMOOTH);
143 glLineWidth(1.0f);
144 }
145 else
146 {
147 smoothness /= 2;
148 start = spline.MaxDistance.ToFloat() / smoothness;
149 glEnable(GL_POINT_SMOOTH);
150 glPointSize(3.0f);
151 glBegin(GL_POINTS);
152 for (int i = 0; i <= smoothness; ++i)
153 {
154 time = start * i / spline.MaxDistance.ToFloat();
155 CVector3D tmp = spline.GetPosition(time);
156 glVertex3f(tmp.X, tmp.Y, tmp.Z);
157 }
158 glEnd();
159 glPointSize(1.0f);
160 glDisable(GL_POINT_SMOOTH);
161 }
162 glDisable(GL_BLEND);
163 glEnable(GL_DEPTH_TEST);
164
165 #endif
166 }
167
DrawNodes(const RNSpline & spline,const CColor & nodeColor) const168 void CCinemaManager::DrawNodes(const RNSpline& spline, const CColor& nodeColor) const
169 {
170 #if CONFIG2_GLES
171 #warning TODO : implement CCinemaPath on GLES
172 #else
173
174 glDisable(GL_DEPTH_TEST);
175 glEnable(GL_POINT_SMOOTH);
176 glPointSize(7.0f);
177 glColor4f(nodeColor.r, nodeColor.g, nodeColor.b, nodeColor.a);
178 glBegin(GL_POINTS);
179
180 for (const SplineData& node : spline.GetAllNodes())
181 glVertex3f(node.Position.X.ToFloat(), node.Position.Y.ToFloat(), node.Position.Z.ToFloat());
182
183 glEnd();
184 glPointSize(1.0f);
185 glDisable(GL_POINT_SMOOTH);
186 glEnable(GL_DEPTH_TEST);
187 #endif
188 }
189
DrawBars() const190 void CCinemaManager::DrawBars() const
191 {
192 int height = (float)g_xres / 2.39f;
193 int shift = (g_yres - height) / 2;
194 if (shift <= 0)
195 return;
196
197 #if CONFIG2_GLES
198 #warning TODO : implement bars for GLES
199 #else
200 // Set up transform for GL bars
201 glMatrixMode(GL_PROJECTION);
202 glPushMatrix();
203 glLoadIdentity();
204 glMatrixMode(GL_MODELVIEW);
205 glPushMatrix();
206 glLoadIdentity();
207 CMatrix3D transform;
208 transform.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f);
209 glLoadMatrixf(&transform._11);
210
211 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
212
213 glEnable(GL_BLEND);
214 glDisable(GL_DEPTH_TEST);
215
216 glBegin(GL_QUADS);
217 glVertex2i(0, 0);
218 glVertex2i(g_xres, 0);
219 glVertex2i(g_xres, shift);
220 glVertex2i(0, shift);
221 glEnd();
222
223 glBegin(GL_QUADS);
224 glVertex2i(0, g_yres - shift);
225 glVertex2i(g_xres, g_yres - shift);
226 glVertex2i(g_xres, g_yres);
227 glVertex2i(0, g_yres);
228 glEnd();
229
230 glDisable(GL_BLEND);
231 glEnable(GL_DEPTH_TEST);
232
233 // Restore transform
234 glMatrixMode(GL_PROJECTION);
235 glPopMatrix();
236 glMatrixMode(GL_MODELVIEW);
237 glPopMatrix();
238 #endif
239 }
240
IsEnabled() const241 bool CCinemaManager::IsEnabled() const
242 {
243 CmpPtr<ICmpCinemaManager> cmpCinemaManager(g_Game->GetSimulation2()->GetSimContext().GetSystemEntity());
244 return cmpCinemaManager && cmpCinemaManager->IsEnabled();
245 }
246
IsPlaying() const247 bool CCinemaManager::IsPlaying() const
248 {
249 return IsEnabled() && g_Game && !g_Game->m_Paused;
250 }
251
GetPathsDrawing() const252 bool CCinemaManager::GetPathsDrawing() const
253 {
254 return m_DrawPaths;
255 }
256
SetPathsDrawing(const bool drawPath)257 void CCinemaManager::SetPathsDrawing(const bool drawPath)
258 {
259 m_DrawPaths = drawPath;
260 }
261