1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #include "Rendering/GL/myGL.h"
4
5
6 #include "WorldDrawer.h"
7 #include "Rendering/Env/CubeMapHandler.h"
8 #include "Rendering/Env/GrassDrawer.h"
9 #include "Rendering/Env/IGroundDecalDrawer.h"
10 #include "Rendering/Env/ISky.h"
11 #include "Rendering/Env/ITreeDrawer.h"
12 #include "Rendering/Env/IWater.h"
13 #include "Rendering/DebugColVolDrawer.h"
14 #include "Rendering/FarTextureHandler.h"
15 #include "Rendering/LineDrawer.h"
16 #include "Rendering/FeatureDrawer.h"
17 #include "Rendering/ProjectileDrawer.h"
18 #include "Rendering/UnitDrawer.h"
19 #include "Rendering/IPathDrawer.h"
20 #include "Rendering/SmoothHeightMeshDrawer.h"
21 #include "Rendering/InMapDrawView.h"
22 #include "Rendering/ShadowHandler.h"
23 #include "Rendering/Models/ModelDrawer.h"
24 #include "Lua/LuaUnsyncedCtrl.h"
25 #include "Map/BaseGroundDrawer.h"
26 #include "Map/HeightMapTexture.h"
27 #include "Map/MapInfo.h"
28 #include "Map/ReadMap.h"
29 #include "Game/Camera.h"
30 #include "Game/SelectedUnitsHandler.h"
31 #include "Game/Game.h"
32 #include "Game/LoadScreen.h"
33 #include "Game/UI/UnitTracker.h"
34 #include "Game/UI/CommandColors.h"
35 #include "Game/UI/GuiHandler.h"
36 #include "System/EventHandler.h"
37 #include "System/TimeProfiler.h"
38 #include "System/Util.h"
39
40
CWorldDrawer()41 CWorldDrawer::CWorldDrawer()
42 {
43 // rendering components
44 loadscreen->SetLoadMessage("Creating ShadowHandler & DecalHandler");
45 cubeMapHandler = new CubeMapHandler();
46 shadowHandler = new CShadowHandler();
47
48 loadscreen->SetLoadMessage("Creating GroundDrawer");
49 readMap->NewGroundDrawer();
50
51 loadscreen->SetLoadMessage("Creating TreeDrawer");
52 treeDrawer = ITreeDrawer::GetTreeDrawer();
53 grassDrawer = new CGrassDrawer();
54
55 inMapDrawerView = new CInMapDrawView();
56 pathDrawer = IPathDrawer::GetInstance();
57
58 farTextureHandler = new CFarTextureHandler();
59 heightMapTexture = new HeightMapTexture();
60
61 loadscreen->SetLoadMessage("Creating ProjectileDrawer & UnitDrawer");
62 projectileDrawer = new CProjectileDrawer();
63 projectileDrawer->LoadWeaponTextures();
64 unitDrawer = new CUnitDrawer();
65 // FIXME: see CGame::LoadSimulation (we only delete it)
66 // featureDrawer = new CFeatureDrawer();
67 modelDrawer = IModelDrawer::GetInstance();
68
69 loadscreen->SetLoadMessage("Creating Water");
70 water = IWater::GetWater(NULL, -1);
71 }
72
73
~CWorldDrawer()74 CWorldDrawer::~CWorldDrawer()
75 {
76 SafeDelete(water);
77 SafeDelete(sky);
78 SafeDelete(treeDrawer);
79 SafeDelete(grassDrawer);
80 SafeDelete(pathDrawer);
81 SafeDelete(modelDrawer);
82 SafeDelete(shadowHandler);
83 SafeDelete(inMapDrawerView);
84
85 SafeDelete(featureDrawer);
86 SafeDelete(unitDrawer); // depends on unitHandler, cubeMapHandler
87 SafeDelete(projectileDrawer);
88
89 SafeDelete(farTextureHandler);
90 SafeDelete(heightMapTexture);
91
92 SafeDelete(cubeMapHandler);
93 IGroundDecalDrawer::FreeInstance();
94 }
95
96
Update()97 void CWorldDrawer::Update()
98 {
99 readMap->UpdateDraw();
100 if (globalRendering->drawGround) {
101 SCOPED_TIMER("GroundDrawer::Update");
102 CBaseGroundDrawer* gd = readMap->GetGroundDrawer();
103 gd->Update();
104 }
105 //XXX: do in CGame, cause it needs to get updated even when doDrawWorld==false, cause it updates unitdrawpos which is used for maximized minimap too
106 //unitDrawer->Update();
107 //lineDrawer.UpdateLineStipple();
108 treeDrawer->Update();
109 featureDrawer->Update();
110 IWater::ApplyPushedChanges(game);
111 }
112
113
Draw()114 void CWorldDrawer::Draw()
115 {
116 SCOPED_TIMER("WorldDrawer::Total");
117
118 CBaseGroundDrawer* gd = readMap->GetGroundDrawer();
119
120 if (globalRendering->drawSky) {
121 sky->Draw();
122 }
123
124 if (globalRendering->drawGround) {
125 {
126 SCOPED_TIMER("WorldDrawer::Terrain");
127 gd->Draw(DrawPass::Normal);
128 }
129 {
130 SCOPED_TIMER("WorldDrawer::GroundDecals");
131 groundDecals->Draw();
132 projectileDrawer->DrawGroundFlashes();
133 }
134 {
135 SCOPED_TIMER("WorldDrawer::Foliage");
136 grassDrawer->Draw();
137 gd->DrawTrees();
138 }
139 smoothHeightMeshDrawer->Draw(1.0f);
140 }
141
142 if (globalRendering->drawWater && !mapInfo->map.voidWater) {
143 SCOPED_TIMER("WorldDrawer::Water");
144
145 water->OcclusionQuery();
146 if (water->DrawSolid()) {
147 water->UpdateWater(game);
148 water->Draw();
149 }
150 }
151
152 selectedUnitsHandler.Draw();
153 eventHandler.DrawWorldPreUnit();
154
155 {
156 SCOPED_TIMER("WorldDrawer::Models");
157 unitDrawer->Draw(false);
158 modelDrawer->Draw();
159 featureDrawer->Draw();
160 DebugColVolDrawer::Draw();
161
162 pathDrawer->DrawAll();
163 }
164
165 //! transparent stuff
166 glEnable(GL_BLEND);
167 glDepthFunc(GL_LEQUAL);
168
169 static const double plane_below[4] = {0.0f, -1.0f, 0.0f, 0.0f};
170 static const double plane_above[4] = {0.0f, 1.0f, 0.0f, 0.0f};
171
172 {
173 glClipPlane(GL_CLIP_PLANE3, plane_below);
174 glEnable(GL_CLIP_PLANE3);
175
176 //! draw cloaked objects below water surface
177 unitDrawer->DrawCloakedUnits(shadowHandler->shadowsLoaded);
178 featureDrawer->DrawFadeFeatures(shadowHandler->shadowsLoaded);
179
180 glDisable(GL_CLIP_PLANE3);
181 }
182
183 //! draw water
184 if (globalRendering->drawWater && !mapInfo->map.voidWater) {
185 SCOPED_TIMER("WorldDrawer::Water");
186
187 if (!water->DrawSolid()) {
188 //! Water rendering will overwrite features, so save them
189 featureDrawer->SwapFeatures();
190 water->UpdateWater(game);
191 water->Draw();
192 featureDrawer->SwapFeatures();
193 }
194 }
195
196 {
197 glClipPlane(GL_CLIP_PLANE3, plane_above);
198 glEnable(GL_CLIP_PLANE3);
199
200 //! draw cloaked objects above water surface
201 unitDrawer->DrawCloakedUnits(shadowHandler->shadowsLoaded);
202 featureDrawer->DrawFadeFeatures(shadowHandler->shadowsLoaded);
203
204 glDisable(GL_CLIP_PLANE3);
205 }
206
207 {
208 SCOPED_TIMER("WorldDrawer::Projectiles");
209 projectileDrawer->Draw(false);
210 }
211
212 if (globalRendering->drawSky) {
213 sky->DrawSun();
214 }
215
216 eventHandler.DrawWorld();
217
218 LuaUnsyncedCtrl::DrawUnitCommandQueues();
219 if (cmdColors.AlwaysDrawQueue() || guihandler->GetQueueKeystate()) {
220 selectedUnitsHandler.DrawCommands();
221 }
222
223 lineDrawer.DrawAll();
224 cursorIcons.Draw();
225 cursorIcons.Clear();
226
227 mouse->DrawSelectionBox();
228
229 guihandler->DrawMapStuff(false);
230
231 if (globalRendering->drawMapMarks && !game->hideInterface) {
232 inMapDrawerView->Draw();
233 }
234
235
236 //! underwater overlay
237 if (camera->GetPos().y < 0.0f && globalRendering->drawWater && !mapInfo->map.voidWater) {
238 glEnableClientState(GL_VERTEX_ARRAY);
239 const float3& cpos = camera->GetPos();
240 const float vr = globalRendering->viewRange * 0.5f;
241 glDepthMask(GL_FALSE);
242 glDisable(GL_TEXTURE_2D);
243 glColor4f(0.0f, 0.5f, 0.3f, 0.50f);
244 {
245 float3 verts[] = {
246 float3(cpos.x - vr, 0.0f, cpos.z - vr),
247 float3(cpos.x - vr, 0.0f, cpos.z + vr),
248 float3(cpos.x + vr, 0.0f, cpos.z + vr),
249 float3(cpos.x + vr, 0.0f, cpos.z - vr)
250 };
251 glVertexPointer(3, GL_FLOAT, 0, verts);
252 glDrawArrays(GL_QUADS, 0, 4);
253 }
254
255 {
256 float3 verts[] = {
257 float3(cpos.x - vr, 0.0f, cpos.z - vr),
258 float3(cpos.x - vr, -vr, cpos.z - vr),
259 float3(cpos.x - vr, 0.0f, cpos.z + vr),
260 float3(cpos.x - vr, -vr, cpos.z + vr),
261 float3(cpos.x + vr, 0.0f, cpos.z + vr),
262 float3(cpos.x + vr, -vr, cpos.z + vr),
263 float3(cpos.x + vr, 0.0f, cpos.z - vr),
264 float3(cpos.x + vr, -vr, cpos.z - vr),
265 float3(cpos.x - vr, 0.0f, cpos.z - vr),
266 float3(cpos.x - vr, -vr, cpos.z - vr),
267 };
268 glVertexPointer(3, GL_FLOAT, 0, verts);
269 glDrawArrays(GL_QUAD_STRIP, 0, 10);
270 }
271
272 glDepthMask(GL_TRUE);
273 glDisableClientState(GL_VERTEX_ARRAY);
274 }
275
276 //reset fov
277 glMatrixMode(GL_PROJECTION);
278 glLoadIdentity();
279 gluOrtho2D(0,1,0,1);
280 glMatrixMode(GL_MODELVIEW);
281 glLoadIdentity();
282
283 glEnable(GL_BLEND);
284 glDisable(GL_DEPTH_TEST);
285 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
286
287 // underwater overlay, part 2
288 if (camera->GetPos().y < 0.0f && globalRendering->drawWater && !mapInfo->map.voidWater) {
289 glEnableClientState(GL_VERTEX_ARRAY);
290 glDisable(GL_TEXTURE_2D);
291 glColor4f(0.0f, 0.2f, 0.8f, 0.333f);
292 float3 verts[] = {
293 float3 (0.f, 0.f, -1.f),
294 float3 (1.f, 0.f, -1.f),
295 float3 (1.f, 1.f, -1.f),
296 float3 (0.f, 1.f, -1.f),
297 };
298 glVertexPointer(3, GL_FLOAT, 0, verts);
299 glDrawArrays(GL_QUADS, 0, 4);
300 glDisableClientState(GL_VERTEX_ARRAY);
301 }
302 }
303