1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3
4 #include "SM3GroundDrawer.h"
5 #include "SM3Map.h"
6 #include "terrain/TerrainNode.h"
7
8 #include "Game/Camera.h"
9 #include "Map/MapInfo.h"
10 #include "Rendering/GlobalRendering.h"
11 #include "Rendering/ShadowHandler.h"
12 #include "Rendering/Env/IGroundDecalDrawer.h"
13 #include "Rendering/ProjectileDrawer.h"
14 #include "Rendering/Env/ISky.h"
15 #include "Rendering/Shaders/Shader.h"
16 #include "Rendering/GL/myGL.h"
17 #include "System/Config/ConfigHandler.h"
18 #include "System/Log/ILog.h"
19
20 #include <SDL_keysym.h>
21
22 CONFIG(int, SM3TerrainDetail).defaultValue(200);
23
CSM3GroundDrawer(CSM3ReadMap * m)24 CSM3GroundDrawer::CSM3GroundDrawer(CSM3ReadMap* m)
25 {
26 map = m;
27 tr = map->renderer;
28 rc = tr->AddRenderContext(&cam, true);
29
30 tr->config.detailMod = configHandler->GetInt("SM3TerrainDetail") / 100.0f;
31
32 if (shadowHandler->shadowsSupported) {
33 shadowrc = tr->AddRenderContext(&shadowCam, false);
34 } else {
35 shadowrc = 0;
36 }
37 reflectrc = 0;
38 }
39
~CSM3GroundDrawer()40 CSM3GroundDrawer::~CSM3GroundDrawer()
41 {
42 configHandler->Set("SM3TerrainDetail", int(tr->config.detailMod * 100));
43 }
44
SpringCamToTerrainCam(CCamera & sc,terrain::Camera & tc)45 static void SpringCamToTerrainCam(CCamera &sc, terrain::Camera& tc)
46 {
47 // Copy camera settings
48 tc.fov = sc.GetFov();
49 tc.front = sc.forward;
50 tc.right = sc.right;
51 tc.up = sc.up;
52 tc.pos = sc.GetPos();
53 tc.aspect = globalRendering->aspectRatio;
54
55 tc.right = tc.front.cross(tc.up);
56 tc.right.ANormalize();
57
58 tc.up=tc.right.cross(tc.front);
59 tc.up.ANormalize();
60 }
61
Update()62 void CSM3GroundDrawer::Update()
63 {
64 SpringCamToTerrainCam(*camera, cam);
65
66 tr->Update();
67 tr->CacheTextures();
68 }
69
Draw(const DrawPass::e & drawPass)70 void CSM3GroundDrawer::Draw(const DrawPass::e& drawPass)
71 {
72 if (wireframe) {
73 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
74 }
75
76 terrain::RenderContext* currc = rc;
77
78 tr->SetShaderParams(sky->GetLight()->GetLightDir(), currc->cam->pos);
79
80 if (shadowHandler->shadowsLoaded) {
81 terrain::ShadowMapParams params;
82
83 params.mid[0] = shadowHandler->GetShadowParams().x;
84 params.mid[1] = shadowHandler->GetShadowParams().y;
85 params.f_a = shadowHandler->GetShadowParams().z;
86 params.f_b = shadowHandler->GetShadowParams().w;
87 params.shadowMap = shadowHandler->shadowTexture;
88
89 for (int a = 0; a < 16; a++)
90 params.shadowMatrix[a] = shadowHandler->shadowMatrix[a];
91
92 tr->SetShadowParams(¶ms);
93 }
94
95 tr->SetActiveContext(currc);
96
97 glEnable(GL_CULL_FACE);
98 glFrontFace(GL_CW);
99
100 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
101 glEnable(GL_LIGHTING);
102 glLightfv(GL_LIGHT0, GL_POSITION, sky->GetLight()->GetLightDir());
103
104 float d[4] = {0.0f, 0.0f, 0.0f, 1.0f};
105 const float z[] = {0.0f, 0.0f, 0.0f, 1.0f};
106
107 for (int a = 0; a < 3; a++)
108 d[a] = mapInfo->light.groundSunColor[a];
109 glLightfv(GL_LIGHT0, GL_DIFFUSE, d);
110
111 for (int a = 0; a < 3; a++)
112 d[a] = mapInfo->light.groundAmbientColor[a];
113 glLightfv(GL_LIGHT0, GL_AMBIENT, d);
114
115 for (int a = 0; a < 3; a++)
116 d[a] = mapInfo->light.groundSpecularColor[a];
117 glLightfv(GL_LIGHT0, GL_SPECULAR, d);
118
119 for (int a = 0; a < 4; a++)
120 d[a] = 0.0f;
121 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, d);
122
123 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, z);
124 glDisable(GL_LIGHT1);
125 glEnable(GL_LIGHT0);
126 glEnable(GL_RESCALE_NORMAL);
127
128 // glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION,dir.getf());
129 // glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90.0f);
130 /* const float ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
131 const float diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
132 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
133 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
134
135 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
136
137 const float md[] = { 1.0f, 1.0f, 1.0f, 1.0f };
138 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, md);
139 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, md);
140 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 10.0f);*/
141 /////////////////////
142
143 tr->Draw();
144 glDisable(GL_LIGHT0);
145 glDisable(GL_LIGHTING);
146
147 if (wireframe) {
148 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
149 }
150
151 if (drawMode != drawNormal) {
152 glEnable(GL_BLEND);
153 glDepthMask(GL_FALSE);
154
155 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
156 glEnable(GL_POLYGON_OFFSET_FILL);
157 glPolygonOffset(0.0f, -10.0f);
158 glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
159 tr->DrawOverlayTexture(infoTex);
160 glDisable(GL_POLYGON_OFFSET_FILL);
161
162 glDepthMask(GL_TRUE);
163 glDisable(GL_BLEND);
164 }
165
166 glFrontFace(GL_CCW);
167 glDisable(GL_CULL_FACE);
168
169 glColor3ub(255, 255, 255);
170
171 DrawObjects(drawPass);
172
173 glActiveTextureARB(GL_TEXTURE0_ARB);
174 glDisable(GL_TEXTURE_2D);
175 }
176
177
DrawShadowPass()178 void CSM3GroundDrawer::DrawShadowPass()
179 {
180 if (!shadowrc)
181 return;
182
183 shadowCam.fov = camera->GetHalfFov()*2.0f; // Why *2?
184 shadowCam.front = camera->forward;
185 shadowCam.right = camera->right;
186 shadowCam.up = camera->up;
187 shadowCam.pos = camera->GetPos();
188 shadowCam.aspect = 1.0f;
189
190 Shader::IProgramObject* po =
191 shadowHandler->GetShadowGenProg(CShadowHandler::SHADOWGEN_PROGRAM_MAP);
192
193 glPolygonOffset(1, 1);
194 glEnable(GL_POLYGON_OFFSET_FILL);
195
196 glEnable(GL_CULL_FACE);
197 glCullFace(GL_FRONT);
198
199 po->Enable();
200 tr->SetActiveContext(shadowrc);
201 tr->DrawSimple();
202 tr->SetActiveContext(rc);
203 po->Disable();
204
205 glCullFace(GL_BACK);
206 glDisable(GL_CULL_FACE);
207
208 glDisable(GL_POLYGON_OFFSET_FILL);
209 }
210
DrawObjects(const DrawPass::e & drawPass)211 void CSM3GroundDrawer::DrawObjects(const DrawPass::e& drawPass)
212 {
213 /* glEnable(GL_ALPHA_TEST);
214 glEnable(GL_TEXTURE_2D);
215 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
216 glEnable(GL_BLEND);
217 */
218 // sky->SetCloudShadow(1);
219 // if(drawWaterReflection)
220 // treeDistance*=0.5f;
221
222 if (drawPass == DrawPass::Normal) {
223 groundDecals->Draw();
224 projectileDrawer->DrawGroundFlashes();
225 }
226 }
227
228 const int maxQuadDepth = 4;
229
IncreaseDetail()230 void CSM3GroundDrawer::IncreaseDetail()
231 {
232 tr->config.detailMod *= 1.1f;
233 if (tr->config.detailMod > 12.0f)
234 tr->config.detailMod = 12.0f;
235 LOG("Terrain detail changed to: %2.2f", tr->config.detailMod);
236 }
237
DecreaseDetail()238 void CSM3GroundDrawer::DecreaseDetail()
239 {
240 tr->config.detailMod /= 1.1f;
241 if (tr->config.detailMod < 0.25f)
242 tr->config.detailMod = 0.25f;
243
244 LOG("Terrain detail changed to: %2.2f", tr->config.detailMod);
245 }
246
GetGroundDetail(const DrawPass::e & drawPass) const247 int CSM3GroundDrawer::GetGroundDetail(const DrawPass::e& drawPass) const
248 {
249 return 100 * tr->config.detailMod;
250 }
251