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(&params);
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