1 //	This file is part of Glest (www.glest.org)
2 //
3 //	Copyright (C) 2001-2008 Martiño Figueroa
4 //
5 //	You can redistribute this code and/or modify it under
6 //	the terms of the GNU General Public License as published
7 //	by the Free Software Foundation; either version 2 of the
8 //	License, or (at your option) any later version
9 // ==============================================================
10 
11 #define NOMINMAX
12 #include "renderer.h"
13 
14 #include "texture_gl.h"
15 #include "main_menu.h"
16 #include "config.h"
17 #include "components.h"
18 #include "time_flow.h"
19 #include "graphics_interface.h"
20 #include "object.h"
21 #include "core_data.h"
22 #include "game.h"
23 #include "metrics.h"
24 #include "opengl.h"
25 #include "faction.h"
26 #include "factory_repository.h"
27 #include <cstdlib>
28 #include "cache_manager.h"
29 #include "network_manager.h"
30 #include <algorithm>
31 #include <iterator>
32 #include "leak_dumper.h"
33 
34 using namespace Shared::Graphics;
35 using namespace Shared::Graphics::Gl;
36 using namespace Shared::Util;
37 using namespace Shared::Graphics;
38 
39 namespace Glest { namespace Game{
40 
41 uint32 Renderer::SurfaceData::nextUniqueId = 1;
42 bool Renderer::renderText3DEnabled = true;
43 
44 //const float SKIP_INTERPOLATION_DISTANCE = 20.0f;
45 const string DEFAULT_CHAR_FOR_WIDTH_CALC = "V";
46 
47 enum PROJECTION_TO_INFINITY {
48 	pti_D_IS_ZERO,
49 	pti_N_OVER_D_IS_OUTSIDE
50 };
51 
52 // =====================================================
53 // 	class MeshCallbackTeamColor
54 // =====================================================
55 
56 bool MeshCallbackTeamColor::noTeamColors = false;
57 
execute(const Mesh * mesh)58 void MeshCallbackTeamColor::execute(const Mesh *mesh) {
59 	//team color
60 	if( mesh->getCustomTexture() && teamTexture != NULL &&
61 		MeshCallbackTeamColor::noTeamColors == false) {
62 		//texture 0
63 		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
64 
65 		//set color to interpolation
66 		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
67 
68 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
69 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
70 
71 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1);
72 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
73 
74 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
75 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
76 
77 		//set alpha to 1
78 		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
79 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
80 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
81 
82 		//texture 1
83 		glActiveTexture(GL_TEXTURE1);
84 		glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f);
85 		glEnable(GL_TEXTURE_2D);
86 
87 		glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(teamTexture)->getHandle());
88 		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
89 
90 		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
91 
92 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
93 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
94 
95 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
96 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
97 
98 		//set alpha to 1
99 		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
100 		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
101 		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
102 
103 		glActiveTexture(GL_TEXTURE0);
104 	}
105 	else {
106 		glActiveTexture(GL_TEXTURE1);
107 		glDisable(GL_TEXTURE_2D);
108 		glActiveTexture(GL_TEXTURE0);
109 		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
110 	}
111 }
112 
113 // ===========================================================
114 //	class Renderer
115 // ===========================================================
116 
117 // ===================== PUBLIC ========================
118 
119 const int Renderer::maxProgressBar= 100;
120 const Vec4f Renderer::progressBarBack1= Vec4f(0.7f, 0.7f, 0.7f, 0.7f);
121 const Vec4f Renderer::progressBarBack2= Vec4f(0.7f, 0.7f, 0.7f, 1.f);
122 const Vec4f Renderer::progressBarFront1= Vec4f(0.f, 0.5f, 0.f, 1.f);
123 const Vec4f Renderer::progressBarFront2= Vec4f(0.f, 0.1f, 0.f, 1.f);
124 
125 const float Renderer::sunDist= 10e6;
126 const float Renderer::moonDist= 10e6;
127 const float Renderer::lightAmbFactor= 0.4f;
128 
129 const int Renderer::maxMouse2dAnim= 100;
130 
131 const GLenum Renderer::baseTexUnit= GL_TEXTURE0;
132 const GLenum Renderer::fowTexUnit= GL_TEXTURE1;
133 const GLenum Renderer::shadowTexUnit= GL_TEXTURE2;
134 
135 const float Renderer::selectionCircleRadius= 0.7f;
136 const float Renderer::magicCircleRadius= 1.f;
137 
138 //perspective values
139 const float Renderer::perspFov= 60.f;
140 const float Renderer::perspNearPlane= 1.f;
141 //const float Renderer::perspFarPlane= 50.f;
142 float Renderer::perspFarPlane= 1000000.f;
143 
144 const float Renderer::ambFactor= 0.7f;
145 const Vec4f Renderer::fowColor= Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
146 const Vec4f Renderer::defSpecularColor= Vec4f(0.8f, 0.8f, 0.8f, 1.f);
147 const Vec4f Renderer::defDiffuseColor= Vec4f(1.f, 1.f, 1.f, 1.f);
148 const Vec4f Renderer::defAmbientColor= Vec4f(1.f * ambFactor, 1.f * ambFactor, 1.f * ambFactor, 1.f);
149 const Vec4f Renderer::defColor= Vec4f(1.f, 1.f, 1.f, 1.f);
150 
151 //const float Renderer::maxLightDist= 100.f;
152 const float Renderer::maxLightDist= 100.f;
153 
154 bool Renderer::rendererEnded = true;
155 
156 const int MIN_FPS_NORMAL_RENDERING = 15;
157 const int MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD = 25;
158 
159 const int OBJECT_SELECT_OFFSET=100000000;
160 
161 bool VisibleQuadContainerCache::enableFrustumCalcs = true;
162 
163 // ==================== constructor and destructor ====================
164 
Renderer()165 Renderer::Renderer() : BaseRenderer(), saveScreenShotThreadAccessor(new Mutex(CODE_AT_LINE)) {
166 	//this->masterserverMode = masterserverMode;
167 	//printf("this->masterserverMode = %d\n",this->masterserverMode);
168 	//assert(0==1);
169 
170 	Renderer::rendererEnded = false;
171 	shadowIntensity = 0;
172 	shadowFrameSkip = 0;
173 	triangleCount = 0;
174 	smoothedRenderFps = 0;
175 	shadowTextureSize = 0;
176 	shadows = sDisabled;
177 	shadowMapFrame = 0;
178 	textures3D = false;
179 	photoMode = false;
180 	focusArrows = false;
181 	pointCount = 0;
182 	maxLights = 0;
183 	waterAnim = 0;
184 
185 	this->allowRenderUnitTitles = false;
186 	this->menu = NULL;
187 	this->game = NULL;
188 	this->gameCamera = NULL;
189 	showDebugUI = false;
190 	showDebugUILevel = debugui_fps;
191 	modelRenderer = NULL;
192 	textRenderer = NULL;
193 	textRenderer3D = NULL;
194 	particleRenderer = NULL;
195 	saveScreenShotThread = NULL;
196 	mapSurfaceData.clear();
197 	visibleFrameUnitList.clear();
198 	visibleFrameUnitListCameraKey = "";
199 
200 	quadCache = VisibleQuadContainerCache();
201 	quadCache.clearFrustumData();
202 
203 	lastRenderFps=MIN_FPS_NORMAL_RENDERING;
204 	shadowsOffDueToMinRender=false;
205 	shadowMapHandle=0;
206 	shadowMapHandleValid=false;
207 
208 	//list3d=0;
209 	//list3dValid=false;
210 	//list2d=0;
211 	//list2dValid=false;
212 	//list3dMenu=0;
213 	//list3dMenuValid=false;
214 	//customlist3dMenu=NULL;
215 	//this->mm3d = NULL;
216 	this->custom_mm3d = NULL;
217 
218 	this->program = NULL;
219 
220 	//resources
221 	for(int i=0; i < rsCount; ++i) {
222 		modelManager[i] = NULL;
223 		textureManager[i] = NULL;
224 		particleManager[i] = NULL;
225 		fontManager[i] = NULL;
226 	}
227 
228 	Config &config= Config::getInstance();
229 
230 	Renderer::perspFarPlane = config.getFloat("PerspectiveFarPlane",floatToStr(Renderer::perspFarPlane).c_str());
231 	this->no2DMouseRendering = config.getBool("No2DMouseRendering","false");
232 	this->maxConsoleLines= config.getInt("ConsoleMaxLines");
233 
234 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Renderer::perspFarPlane [%f] this->no2DMouseRendering [%d] this->maxConsoleLines [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Renderer::perspFarPlane,this->no2DMouseRendering,this->maxConsoleLines);
235 
236 	GraphicsInterface &gi= GraphicsInterface::getInstance();
237 	FactoryRepository &fr= FactoryRepository::getInstance();
238 	gi.setFactory(fr.getGraphicsFactory(config.getString("FactoryGraphics")));
239 	GraphicsFactory *graphicsFactory= GraphicsInterface::getInstance().getFactory();
240 
241 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
242 		modelRenderer= graphicsFactory->newModelRenderer();
243 		textRenderer= graphicsFactory->newTextRenderer2D();
244 		textRenderer3D = graphicsFactory->newTextRenderer3D();
245 		particleRenderer= graphicsFactory->newParticleRenderer();
246 	}
247 
248 	//resources
249 	for(int i=0; i< rsCount; ++i) {
250 		if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
251 			modelManager[i]= graphicsFactory->newModelManager();
252 			textureManager[i]= graphicsFactory->newTextureManager();
253 			modelManager[i]->setTextureManager(textureManager[i]);
254 			fontManager[i]= graphicsFactory->newFontManager();
255 		}
256 		particleManager[i]= graphicsFactory->newParticleManager();
257 	}
258 
259 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
260 		static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
261 		saveScreenShotThread = new SimpleTaskThread(this,0,25);
262 		saveScreenShotThread->setUniqueID(mutexOwnerId);
263 		saveScreenShotThread->start();
264 	}
265 }
266 
cleanupScreenshotThread()267 void Renderer::cleanupScreenshotThread() {
268     if(saveScreenShotThread) {
269 		saveScreenShotThread->signalQuit();
270 //		for(time_t elapsed = time(NULL);
271 //			getSaveScreenQueueSize() > 0 && difftime((long int)time(NULL),elapsed) <= 7;) {
272 //			sleep(0);
273 //		}
274 //		if(saveScreenShotThread->canShutdown(true) == true &&
275 //				saveScreenShotThread->shutdownAndWait() == true) {
276 //			//printf("IN MenuStateCustomGame cleanup - C\n");
277 //			delete saveScreenShotThread;
278 //		}
279 //		saveScreenShotThread = NULL;
280 		if(saveScreenShotThread->shutdownAndWait() == true) {
281 			delete saveScreenShotThread;
282 		}
283 		saveScreenShotThread = NULL;
284 
285 
286 		if(getSaveScreenQueueSize() > 0) {
287 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] FORCING MEMORY CLEANUP and NOT SAVING screenshots, saveScreenQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,saveScreenQueue.size());
288 
289 			static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
290 			MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,mutexOwnerId);
291 			for(std::list<std::pair<string,Pixmap2D *> >::iterator iter = saveScreenQueue.begin();
292 				iter != saveScreenQueue.end(); ++iter) {
293 				delete iter->second;
294 			}
295 			saveScreenQueue.clear();
296 		}
297 	}
298 }
299 
~Renderer()300 Renderer::~Renderer() {
301 	try{
302 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
303 
304 		delete modelRenderer;
305 		modelRenderer = NULL;
306 		delete textRenderer;
307 		textRenderer = NULL;
308 		delete textRenderer3D;
309 		textRenderer3D = NULL;
310 		delete particleRenderer;
311 		particleRenderer = NULL;
312 
313 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
314 
315 		//resources
316 		for(int i=0; i<rsCount; ++i){
317 			delete modelManager[i];
318 			modelManager[i] = NULL;
319 			delete textureManager[i];
320 			textureManager[i] = NULL;
321 			delete particleManager[i];
322 			particleManager[i] = NULL;
323 			delete fontManager[i];
324 			fontManager[i] = NULL;
325 		}
326 
327 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
328 
329 		// Wait for the queue to become empty or timeout the thread at 7 seconds
330 		cleanupScreenshotThread();
331 
332 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
333 
334 		mapSurfaceData.clear();
335 		quadCache = VisibleQuadContainerCache();
336 		quadCache.clearFrustumData();
337 
338 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
339 
340 		this->menu = NULL;
341 		this->game = NULL;
342 		this->gameCamera = NULL;
343 
344 		delete saveScreenShotThreadAccessor;
345 		saveScreenShotThreadAccessor = NULL;
346 	}
347 	catch(const exception &e) {
348 		char szBuf[8096]="";
349 		snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
350 		SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
351 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
352 
353 		throw megaglest_runtime_error(szBuf);
354 	}
355 }
356 
simpleTask(BaseThread * callingThread,void * userdata)357 void Renderer::simpleTask(BaseThread *callingThread,void *userdata) {
358 	// This code reads pixmaps from a queue and saves them to disk
359 	Pixmap2D *savePixMapBuffer=NULL;
360 	string path="";
361 	static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
362 	MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,mutexOwnerId);
363 	if(saveScreenQueue.empty() == false) {
364 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] saveScreenQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,saveScreenQueue.size());
365 
366 		savePixMapBuffer = saveScreenQueue.front().second;
367 		path = saveScreenQueue.front().first;
368 
369 		saveScreenQueue.pop_front();
370 	}
371 	safeMutex.ReleaseLock();
372 
373 	if(savePixMapBuffer != NULL) {
374 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] about to save [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
375 
376 		savePixMapBuffer->save(path);
377 		delete savePixMapBuffer;
378 	}
379 }
380 
isEnded()381 bool Renderer::isEnded() {
382 	return Renderer::rendererEnded;
383 }
384 
getInstance()385 Renderer &Renderer::getInstance() {
386 	static Renderer renderer;
387 	return renderer;
388 }
389 
reinitAll()390 void Renderer::reinitAll() {
391 	//resources
392 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
393 		return;
394 	}
395 	for(int i=0; i<rsCount; ++i){
396 		//modelManager[i]->init();
397 		textureManager[i]->init(true);
398 		//particleManager[i]->init();
399 		//fontManager[i]->init();
400 	}
401 }
402 // ==================== init ====================
403 
init()404 void Renderer::init() {
405 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
406 
407 	Config &config= Config::getInstance();
408 
409 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
410 
411 	loadConfig();
412 
413 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
414 
415 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
416 		return;
417 	}
418 
419 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
420 
421 	if(config.getBool("CheckGlCaps")){
422 
423 		if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
424 
425 		checkGlCaps();
426 	}
427 
428 	if(glActiveTexture == NULL) {
429 		char szBuf[8096]="";
430 		snprintf(szBuf,8096,"Error: glActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!");
431 		throw megaglest_runtime_error(szBuf);
432 	}
433 
434 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
435 
436 	if(config.getBool("FirstTime")){
437 		if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
438 
439 		config.setBool("FirstTime", false);
440 		autoConfig();
441 
442 		if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
443 
444 		config.save();
445 	}
446 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
447 
448 	modelManager[rsGlobal]->init();
449 
450 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
451 
452 	textureManager[rsGlobal]->init();
453 
454 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
455 
456 	fontManager[rsGlobal]->init();
457 
458 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
459 
460 	init2dList();
461 
462 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
463 
464 	glHint(GL_FOG_HINT, GL_FASTEST);
465 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
466 	//glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
467 	glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
468 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
469 	//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
470 	//glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
471 
472 	//glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
473 	glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
474 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
475 
476 }
477 
initGame(const Game * game,GameCamera * gameCamera)478 void Renderer::initGame(const Game *game, GameCamera *gameCamera) {
479 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
480 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
481 
482 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
483 	this->gameCamera = gameCamera;
484 	VisibleQuadContainerCache::enableFrustumCalcs = Config::getInstance().getBool("EnableFrustrumCalcs","true");
485 	quadCache = VisibleQuadContainerCache();
486 	quadCache.clearFrustumData();
487 
488 	SurfaceData::nextUniqueId = 1;
489 	mapSurfaceData.clear();
490 	this->game= game;
491 	worldToScreenPosCache.clear();
492 
493 	//vars
494 	shadowMapFrame= 0;
495 	waterAnim= 0;
496 
497 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
498 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
499 
500 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
501 		return;
502 	}
503 
504 	//check gl caps
505 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
506 	checkGlOptionalCaps();
507 
508 	//shadows
509 	if(shadows == sProjected || shadows == sShadowMapping) {
510 		static_cast<ModelRendererGl*>(modelRenderer)->setSecondaryTexCoordUnit(2);
511 		Config &config= Config::getInstance();
512 
513 		glGenTextures(1, &shadowMapHandle);
514 		shadowMapHandleValid=true;
515 
516 		shadowIntensity= config.getFloat("ShadowIntensity","1.0");
517 		if(game!=NULL){
518 			shadowIntensity=shadowIntensity*game->getWorld()->getTileset()->getShadowIntense();
519 			if(shadowIntensity > 1.0f){
520 				shadowIntensity=1.0f;
521 			}
522 		}
523 
524 		glBindTexture(GL_TEXTURE_2D, shadowMapHandle);
525 
526 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
527 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
528 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
529 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
530 
531 		if(shadows == sShadowMapping) {
532 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
533 
534 			//shadow mapping
535 			glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
536 			//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
537 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
538 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
539 			//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1.0f-shadowAlpha);
540 
541 			glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
542 				shadowTextureSize, shadowTextureSize,
543 				0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
544 		}
545 		else {
546 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
547 
548 			//projected
549 			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
550 				shadowTextureSize, shadowTextureSize,
551 				0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
552 		}
553 
554 		shadowMapFrame= -1;
555 	}
556 
557 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
558 
559 	IF_DEBUG_EDITION( getDebugRenderer().init(); )
560 
561 	//texture init
562 	modelManager[rsGame]->init();
563 	textureManager[rsGame]->init();
564 	fontManager[rsGame]->init();
565 
566 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
567 
568 	init3dList();
569 }
570 
manageDeferredParticleSystems()571 void Renderer::manageDeferredParticleSystems() {
572 
573 //	if(deferredParticleSystems.empty() == false) {
574 //		printf("deferredParticleSystems.size() = %d\n",(int)deferredParticleSystems.size());
575 //	}
576 
577 	for(unsigned int i = 0; i < deferredParticleSystems.size(); ++i) {
578 		std::pair<ParticleSystem *, ResourceScope> &deferredParticleSystem = deferredParticleSystems[i];
579 		ParticleSystem *ps = deferredParticleSystem.first;
580 		ResourceScope rs = deferredParticleSystem.second;
581 		if(ps->getTextureFileLoadDeferred() != "" && ps->getTexture() == NULL) {
582 			CoreData::TextureSystemType textureSystemId =
583 					static_cast<CoreData::TextureSystemType>(
584 							ps->getTextureFileLoadDeferredSystemId());
585 
586 			//printf("Load DEFERRED particle i = %d textureSystemId = %d\n",i,textureSystemId);
587 
588 			if(textureSystemId != CoreData::tsyst_NONE) {
589 				Texture2D *texture= CoreData::getInstance().getTextureBySystemId(textureSystemId);
590 				//printf("Loading texture from system [%d] [%p]\n",textureSystemId,texture);
591 				ps->setTexture(texture);
592 
593 				//printf("#2 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture);
594 			}
595 			else {
596 				Texture2D *texture= newTexture2D(rs);
597 				if(texture) {
598 					texture->setFormat(ps->getTextureFileLoadDeferredFormat());
599 					texture->getPixmap()->init(ps->getTextureFileLoadDeferredComponents());
600 				}
601 				if(texture) {
602 					string textureFile = ps->getTextureFileLoadDeferred();
603 					if(fileExists(textureFile) == false) {
604 						textureFile = Config::findValidLocalFileFromPath(textureFile);
605 					}
606 					texture->load(textureFile);
607 					ps->setTexture(texture);
608 				}
609 				//printf("#3 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture);
610 			}
611 		}
612 		if(dynamic_cast<GameParticleSystem *>(ps) != NULL) {
613 			GameParticleSystem *gps = dynamic_cast<GameParticleSystem *>(ps);
614 			if(gps != NULL && gps->getModelFileLoadDeferred() != "" && gps->getModel() == NULL) {
615                 std::map<string,vector<pair<string, string> > > loadedFileList;
616                 Model *model= newModel(rsGame, gps->getModelFileLoadDeferred(), false, &loadedFileList, NULL);
617                 if(model)
618                     gps->setModel(model);
619 			}
620 		}
621 		manageParticleSystem(ps, rs);
622 		//printf("Managing ps [%p]\n",ps);
623 	}
624 	deferredParticleSystems.clear();
625 	//printf("After deferredParticleSystems.size() = %d\n",deferredParticleSystems.size());
626 }
627 
initMenu(const MainMenu * mm)628 void Renderer::initMenu(const MainMenu *mm) {
629 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
630 
631 	this->menu = mm;
632 
633 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
634 
635 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
636 		return;
637 	}
638 
639 	modelManager[rsMenu]->init();
640 	textureManager[rsMenu]->init();
641 	fontManager[rsMenu]->init();
642 	//modelRenderer->setCustomTexture(CoreData::getInstance().getCustomTexture());
643 
644 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
645 
646 	//init3dListMenu(mm);
647 
648 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
649 }
650 
reset3d()651 void Renderer::reset3d() {
652 	assertGl();
653 	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
654 	//glCallList(list3d);
655 	render3dSetup();
656 
657 	pointCount= 0;
658 	triangleCount= 0;
659 	assertGl();
660 }
661 
reset2d()662 void Renderer::reset2d() {
663 	assertGl();
664 	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
665 	//glCallList(list2d);
666 	render2dMenuSetup();
667 	assertGl();
668 }
669 
reset3dMenu()670 void Renderer::reset3dMenu() {
671 	assertGl();
672 	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
673 
674 	//printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d);
675 
676 	if(this->custom_mm3d != NULL) {
677 		render3dMenuSetup(this->custom_mm3d);
678 		//glCallList(*this->customlist3dMenu);
679 	}
680 	else {
681 		render3dMenuSetup(this->menu);
682 		//render3dMenuSetup(this->mm3d);
683 		//glCallList(list3dMenu);
684 	}
685 
686 	assertGl();
687 }
688 
689 // ==================== end ====================
690 
end()691 void Renderer::end() {
692 	quadCache = VisibleQuadContainerCache();
693 	quadCache.clearFrustumData();
694 
695 	if(Renderer::rendererEnded == true) {
696 		return;
697 	}
698 	std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
699 	crcFactionPreviewTextureCache.clear();
700 
701 	// Wait for the queue to become empty or timeout the thread at 7 seconds
702 	cleanupScreenshotThread();
703 
704 	mapSurfaceData.clear();
705 
706 	//delete resources
707 	if(modelManager[rsGlobal]) {
708 		modelManager[rsGlobal]->end();
709 	}
710 	if(textureManager[rsGlobal]) {
711 		textureManager[rsGlobal]->end();
712 	}
713 	if(fontManager[rsGlobal]) {
714 		fontManager[rsGlobal]->end();
715 	}
716 	if(particleManager[rsGlobal]) {
717 		particleManager[rsGlobal]->end();
718 	}
719 
720 	//delete 2d list
721 	//if(list2dValid == true) {
722 	//	glDeleteLists(list2d, 1);
723 	//	list2dValid=false;
724 	//}
725 
726 	Renderer::rendererEnded = true;
727 }
728 
endScenario()729 void Renderer::endScenario() {
730 	this->game= NULL;
731 	this->gameCamera = NULL;
732 	quadCache = VisibleQuadContainerCache();
733 	quadCache.clearFrustumData();
734 
735 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
736 		return;
737 	}
738 
739 	//delete resources
740 	//modelManager[rsGame]->end();
741 	//textureManager[rsGame]->end();
742 	//fontManager[rsGame]->end();
743 	//particleManager[rsGame]->end();
744 
745 	if(shadowMapHandleValid == true &&
746 		(shadows == sProjected || shadows == sShadowMapping)) {
747 		glDeleteTextures(1, &shadowMapHandle);
748 		shadowMapHandleValid=false;
749 	}
750 
751 	//if(list3dValid == true) {
752 	//	glDeleteLists(list3d, 1);
753 	//	list3dValid=false;
754 	//}
755 
756 	worldToScreenPosCache.clear();
757 	ReleaseSurfaceVBOs();
758 	mapSurfaceData.clear();
759 }
760 
endGame(bool isFinalEnd)761 void Renderer::endGame(bool isFinalEnd) {
762 	this->game= NULL;
763 	this->gameCamera = NULL;
764 	Config &config= Config::getInstance();
765 
766 	try {
767 		quadCache = VisibleQuadContainerCache();
768 		quadCache.clearFrustumData();
769 	}
770 	catch(const exception &e) {
771 		char szBuf[8096]="";
772 		snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
773 		SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
774 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
775 
776 		abort();
777 	}
778 
779 	if(isFinalEnd) {
780 		//delete resources
781 		if(modelManager[rsGame] != NULL) {
782 			modelManager[rsGame]->end();
783 		}
784 		if(textureManager[rsGame] != NULL) {
785 			textureManager[rsGame]->end();
786 		}
787 		if(fontManager[rsGame] != NULL) {
788 			fontManager[rsGame]->end();
789 		}
790 		if(particleManager[rsGame] != NULL) {
791 			particleManager[rsGame]->end();
792 		}
793 	}
794 
795 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
796 		return;
797 	}
798 
799 	if(shadowMapHandleValid == true &&
800 		(shadows == sProjected || shadows == sShadowMapping)) {
801 		glDeleteTextures(1, &shadowMapHandle);
802 		shadowMapHandleValid=false;
803 	}
804 	shadowIntensity= config.getFloat("ShadowIntensity","1.0");
805 
806 	//if(list3dValid == true) {
807 	//	glDeleteLists(list3d, 1);
808 	//	list3dValid=false;
809 	//}
810 
811 	worldToScreenPosCache.clear();
812 	ReleaseSurfaceVBOs();
813 	mapSurfaceData.clear();
814 }
815 
endMenu()816 void Renderer::endMenu() {
817 	this->menu = NULL;
818 
819 	//delete resources
820 	if(modelManager[rsMenu]) {
821 		modelManager[rsMenu]->end();
822 	}
823 	if(textureManager[rsMenu]) {
824 		textureManager[rsMenu]->end();
825 	}
826 	if(fontManager[rsMenu]) {
827 		fontManager[rsMenu]->end();
828 	}
829 	if(particleManager[rsMenu]) {
830 		particleManager[rsMenu]->end();
831 	}
832 
833 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
834 		return;
835 	}
836 
837 	//if(this->customlist3dMenu != NULL) {
838 	//	glDeleteLists(*this->customlist3dMenu,1);
839 	//}
840 	//else {
841 	//	glDeleteLists(list3dMenu, 1);
842 	//}
843 }
844 
reloadResources()845 void Renderer::reloadResources() {
846 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
847 		return;
848 	}
849 
850 	for(int i=0; i<rsCount; ++i) {
851 		modelManager[i]->end();
852 		textureManager[i]->end();
853 		fontManager[i]->end();
854 	}
855 
856 	for(int i=0; i<rsCount; ++i) {
857 		modelManager[i]->init();
858 		textureManager[i]->init();
859 		fontManager[i]->init();
860 	}
861 }
862 
863 // ==================== engine interface ====================
864 
initTexture(ResourceScope rs,Texture * texture)865 void Renderer::initTexture(ResourceScope rs, Texture *texture) {
866 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
867 		return;
868 	}
869 
870 	textureManager[rs]->initTexture(texture);
871 }
872 
endTexture(ResourceScope rs,Texture * texture,bool mustExistInList)873 void Renderer::endTexture(ResourceScope rs, Texture *texture, bool mustExistInList) {
874 	string textureFilename = texture->getPath();
875 
876 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from manager [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str());
877 
878 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
879 		return;
880 	}
881 
882 	textureManager[rs]->endTexture(texture,mustExistInList);
883 
884 	if(rs == rsGlobal) {
885 		std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
886 		if(crcFactionPreviewTextureCache.find(textureFilename) != crcFactionPreviewTextureCache.end()) {
887 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] textureFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str());
888 			if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str());
889 
890 			crcFactionPreviewTextureCache.erase(textureFilename);
891 		}
892 	}
893 }
endLastTexture(ResourceScope rs,bool mustExistInList)894 void Renderer::endLastTexture(ResourceScope rs, bool mustExistInList) {
895 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
896 		return;
897 	}
898 
899 	textureManager[rs]->endLastTexture(mustExistInList);
900 }
901 
newModel(ResourceScope rs,const string & path,bool deletePixMapAfterLoad,std::map<string,vector<pair<string,string>>> * loadedFileList,string * sourceLoader)902 Model *Renderer::newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad,std::map<string,vector<pair<string, string> > > *loadedFileList, string *sourceLoader){
903 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
904 		return NULL;
905 	}
906 
907 	return modelManager[rs]->newModel(path,deletePixMapAfterLoad,loadedFileList,sourceLoader);
908 }
909 
endModel(ResourceScope rs,Model * model,bool mustExistInList)910 void Renderer::endModel(ResourceScope rs, Model *model,bool mustExistInList) {
911 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
912 		return;
913 	}
914 
915 	modelManager[rs]->endModel(model,mustExistInList);
916 }
endLastModel(ResourceScope rs,bool mustExistInList)917 void Renderer::endLastModel(ResourceScope rs, bool mustExistInList) {
918 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
919 		return;
920 	}
921 
922 	modelManager[rs]->endLastModel(mustExistInList);
923 }
924 
newTexture2D(ResourceScope rs)925 Texture2D *Renderer::newTexture2D(ResourceScope rs){
926 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
927 		return NULL;
928 	}
929 
930 	return textureManager[rs]->newTexture2D();
931 }
932 
newTexture3D(ResourceScope rs)933 Texture3D *Renderer::newTexture3D(ResourceScope rs){
934 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
935 		return NULL;
936 	}
937 
938 	return textureManager[rs]->newTexture3D();
939 }
940 
newFont(ResourceScope rs)941 Font2D *Renderer::newFont(ResourceScope rs){
942 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
943 		return NULL;
944 	}
945 
946 	return fontManager[rs]->newFont2D();
947 }
948 
newFont3D(ResourceScope rs)949 Font3D *Renderer::newFont3D(ResourceScope rs){
950 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
951 		return NULL;
952 	}
953 
954 	return fontManager[rs]->newFont3D();
955 }
956 
endFont(::Shared::Graphics::Font * font,ResourceScope rs,bool mustExistInList)957 void Renderer::endFont(::Shared::Graphics::Font *font, ResourceScope rs, bool mustExistInList) {
958 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
959 		return;
960 	}
961 
962 	fontManager[rs]->endFont(font,mustExistInList);
963 }
964 
resetFontManager(ResourceScope rs)965 void Renderer::resetFontManager(ResourceScope rs) {
966 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
967 		return;
968 	}
969 	fontManager[rs]->end();
970 	fontManager[rsGlobal]->init();
971 }
972 
addToDeferredParticleSystemList(std::pair<ParticleSystem *,ResourceScope> deferredParticleSystem)973 void Renderer::addToDeferredParticleSystemList(std::pair<ParticleSystem *, ResourceScope> deferredParticleSystem) {
974 	deferredParticleSystems.push_back(deferredParticleSystem);
975 }
976 
manageParticleSystem(ParticleSystem * particleSystem,ResourceScope rs)977 void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs){
978 	particleManager[rs]->manage(particleSystem);
979 }
980 
validateParticleSystemStillExists(ParticleSystem * particleSystem,ResourceScope rs) const981 bool Renderer::validateParticleSystemStillExists(ParticleSystem * particleSystem,ResourceScope rs) const {
982 	return particleManager[rs]->validateParticleSystemStillExists(particleSystem);
983 }
984 
removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner,ResourceScope rs)985 void Renderer::removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner,ResourceScope rs) {
986 	particleManager[rs]->removeParticleSystemsForParticleOwner(particleOwner);
987 }
988 
cleanupParticleSystems(vector<ParticleSystem * > & particleSystems,ResourceScope rs)989 void Renderer::cleanupParticleSystems(vector<ParticleSystem *> &particleSystems, ResourceScope rs) {
990 	particleManager[rs]->cleanupParticleSystems(particleSystems);
991 }
992 
cleanupUnitParticleSystems(vector<UnitParticleSystem * > & particleSystems,ResourceScope rs)993 void Renderer::cleanupUnitParticleSystems(vector<UnitParticleSystem *> &particleSystems, ResourceScope rs) {
994 	particleManager[rs]->cleanupUnitParticleSystems(particleSystems);
995 }
996 
updateParticleManager(ResourceScope rs,int renderFps)997 void Renderer::updateParticleManager(ResourceScope rs, int renderFps) {
998 	particleManager[rs]->update(renderFps);
999 }
1000 
renderParticleManager(ResourceScope rs)1001 void Renderer::renderParticleManager(ResourceScope rs){
1002 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1003 		return;
1004 	}
1005 
1006 	glPushAttrib(GL_DEPTH_BUFFER_BIT  | GL_STENCIL_BUFFER_BIT);
1007 	glDepthFunc(GL_LESS);
1008 	particleRenderer->renderManager(particleManager[rs], modelRenderer);
1009 	glPopAttrib();
1010 }
1011 
swapBuffers()1012 void Renderer::swapBuffers() {
1013 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1014 		return;
1015 	}
1016 	//glFlush(); // should not be required - http://www.opengl.org/wiki/Common_Mistakes
1017 	//glFlush();
1018 
1019 	GraphicsInterface::getInstance().getCurrentContext()->swapBuffers();
1020 }
1021 
1022 // ==================== lighting ====================
1023 
1024 //places all the opengl lights
setupLighting()1025 void Renderer::setupLighting() {
1026 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1027 		return;
1028 	}
1029 
1030     int lightCount= 0;
1031 	const World *world= game->getWorld();
1032 	const GameCamera *gameCamera= game->getGameCamera();
1033 	const TimeFlow *timeFlow= world->getTimeFlow();
1034 	float time= timeFlow->getTime();
1035 
1036 	assertGl();
1037 
1038     //sun/moon light
1039 	Vec3f lightColor= timeFlow->computeLightColor();
1040 	Vec3f fogColor= world->getTileset()->getFogColor();
1041 	Vec4f lightPos= timeFlow->isDay()? computeSunPos(time): computeMoonPos(time);
1042 	nearestLightPos= lightPos;
1043 
1044 	glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr());
1045 	glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr());
1046 	glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr());
1047 	glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr());
1048 
1049 	glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr());
1050 
1051     lightCount++;
1052 
1053 	//disable all secondary lights
1054 	for(int i= 1; i < maxLights; ++i) {
1055 		glDisable(GL_LIGHT0 + i);
1056 	}
1057 
1058     //unit lights (not projectiles)
1059 
1060 	if(timeFlow->isTotalNight()) {
1061 		VisibleQuadContainerCache &qCache = getQuadCache();
1062 		if(qCache.visibleQuadUnitList.empty() == false) {
1063 			//bool modelRenderStarted = false;
1064 			for(int visibleUnitIndex = 0;
1065 					visibleUnitIndex < (int)qCache.visibleQuadUnitList.size() && lightCount < maxLights;
1066 					++visibleUnitIndex) {
1067 				Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
1068 
1069 				if(world->toRenderUnit(unit) &&
1070 					unit->getCurrMidHeightVector().dist(gameCamera->getPos()) < maxLightDist &&
1071 					unit->getType()->getLight() && unit->isOperative()) {
1072 					//printf("$$$ Show light for faction: %s # %d / %d for Unit [%d - %s]\n",world->getFaction(i)->getType()->getName().c_str(),lightCount,maxLights,unit->getId(),unit->getFullName().c_str());
1073 
1074 					Vec4f pos= Vec4f(unit->getCurrMidHeightVector());
1075 					pos.y+=4.f;
1076 
1077 					GLenum lightEnum= GL_LIGHT0 + lightCount;
1078 
1079 					glEnable(lightEnum);
1080 					glLightfv(lightEnum, GL_POSITION, pos.ptr());
1081 					glLightfv(lightEnum, GL_AMBIENT, Vec4f(unit->getType()->getLightColor()).ptr());
1082 					glLightfv(lightEnum, GL_DIFFUSE, Vec4f(unit->getType()->getLightColor()).ptr());
1083 					glLightfv(lightEnum, GL_SPECULAR, Vec4f(unit->getType()->getLightColor()*0.3f).ptr());
1084 					glLightf(lightEnum, GL_QUADRATIC_ATTENUATION, 0.05f);
1085 
1086 					++lightCount;
1087 
1088 					const GameCamera *gameCamera= game->getGameCamera();
1089 
1090 					if(Vec3f(pos).dist(gameCamera->getPos())<Vec3f(nearestLightPos).dist(gameCamera->getPos())){
1091 						nearestLightPos= pos;
1092 					}
1093 				}
1094 			}
1095 		}
1096 	}
1097 
1098 	assertGl();
1099 }
1100 
setupLightingForRotatedModel()1101 void Renderer::setupLightingForRotatedModel() {
1102 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1103 		return;
1104 	}
1105 
1106 	const World *world= game->getWorld();
1107 	//const GameCamera *gameCamera= game->getGameCamera();
1108 	const TimeFlow *timeFlow= world->getTimeFlow();
1109 	float time= timeFlow->getTime();
1110 
1111 	assertGl();
1112 
1113     //sun/moon light
1114 	Vec3f lightColor= timeFlow->computeLightColor();
1115 	Vec3f fogColor= world->getTileset()->getFogColor();
1116 	Vec4f lightPos= timeFlow->isDay()? computeSunPos(time): computeMoonPos(time);
1117 	//nearestLightPos= lightPos;
1118 
1119 	glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr());
1120 	glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr());
1121 	glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr());
1122 	glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr());
1123 
1124 	glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr());
1125 
1126 	assertGl();
1127 }
1128 
loadGameCameraMatrix()1129 void Renderer::loadGameCameraMatrix() {
1130 	const GameCamera *gameCamera= game->getGameCamera();
1131 
1132 	glMatrixMode(GL_MODELVIEW);
1133 	glLoadIdentity();
1134 	if(gameCamera != NULL) {
1135 		glRotatef(gameCamera->getVAng(), -1, 0, 0);
1136 		glRotatef(gameCamera->getHAng(), 0, 1, 0);
1137 		glTranslatef(-(gameCamera->getPos().x + gameCamera->getShakeOffset().x),
1138 				-gameCamera->getPos().y,
1139 				-(gameCamera->getPos().z + gameCamera->getShakeOffset().y));
1140 	}
1141 }
1142 
loadCameraMatrix(const Camera * camera)1143 void Renderer::loadCameraMatrix(const Camera *camera) {
1144 	const Vec3f &position= camera->getConstPosition();
1145 	Quaternion orientation= camera->getOrientation().conjugate();
1146 
1147 	glMatrixMode(GL_MODELVIEW);
1148 	glLoadIdentity();
1149 	glMultMatrixf(orientation.toMatrix4().ptr());
1150 	glTranslatef(-position.x, -position.y, -position.z);
1151 }
1152 
_unprojectMap(const Vec2i & pt,const GLdouble * model,const GLdouble * projection,const GLint * viewport,const char * label=NULL)1153 static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* projection,const GLint* viewport,const char* label=NULL) {
1154 	Vec3d a,b;
1155 	/*  note viewport[3] is height of window in pixels  */
1156 	GLint realy = viewport[3] - (GLint) pt.y;
1157 	gluUnProject(pt.x,realy,0,model,projection,viewport,&a.x,&a.y,&a.z);
1158 	gluUnProject(pt.x,realy,1,model,projection,viewport,&b.x,&b.y,&b.z);
1159 
1160 	// junk values if you were looking parallel to the XZ plane; this shouldn't happen as the camera can't do this?
1161 	const Vec3f
1162 		start(a.x,a.y,a.z),
1163 		stop(b.x,b.y,b.z),
1164 		plane(0,0,0),
1165 		norm(0,1,0),
1166 		u = stop-start,
1167 		w = start-plane;
1168 	const float d = norm.x*u.x + norm.y*u.y + norm.z*u.z;
1169 	if(std::fabs(d) < 0.00001)
1170 		throw pti_D_IS_ZERO;
1171 
1172 	const float nd = -(norm.x*w.x + norm.y*w.y + norm.z*w.z) / d;
1173 	if(nd < 0.0 || nd >= 1.0)
1174 		throw pti_N_OVER_D_IS_OUTSIDE;
1175 
1176 	const Vec3f i = start + u*nd;
1177 	//const Vec2i pos(i.x,i.z);
1178 
1179 	Vec2i pos;
1180 	if(strcmp(label,"tl") == 0) {
1181 		pos = Vec2i(std::floor(i.x),std::floor(i.z));
1182 	}
1183 	else if(strcmp(label,"tr") == 0) {
1184 		pos = Vec2i(std::ceil(i.x),std::floor(i.z));
1185 	}
1186 	else if(strcmp(label,"bl") == 0) {
1187 		pos = Vec2i(std::floor(i.x),std::ceil(i.z));
1188 	}
1189 	else if(strcmp(label,"br") == 0) {
1190 		pos = Vec2i(std::ceil(i.x),std::ceil(i.z));
1191 	}
1192 
1193 	if(false) { // print debug info
1194 		if(label) printf("%s ",label);
1195 		printf("%d,%d -> %f,%f,%f -> %f,%f,%f -> %f,%f,%f -> %d,%d\n",
1196 			pt.x,pt.y,
1197 			start.x,start.y,start.z,
1198 			stop.x,stop.y,stop.z,
1199 			i.x,i.y,i.z,
1200 			pos.x,pos.y);
1201 	}
1202 	return pos;
1203 
1204 }
1205 
ExtractFrustum(VisibleQuadContainerCache & quadCacheItem)1206 bool Renderer::ExtractFrustum(VisibleQuadContainerCache &quadCacheItem) {
1207    bool frustumChanged = false;
1208    vector<float> proj(16,0);
1209    vector<float> modl(16,0);
1210 
1211    /* Get the current PROJECTION matrix from OpenGL */
1212    glGetFloatv( GL_PROJECTION_MATRIX, &proj[0] );
1213 
1214    /* Get the current MODELVIEW matrix from OpenGL */
1215    glGetFloatv( GL_MODELVIEW_MATRIX, &modl[0] );
1216 
1217 //   for(unsigned int i = 0; i < proj.size(); ++i) {
1218 //	   //printf("\ni = %d proj [%f][%f] modl [%f][%f]\n",i,proj[i],quadCacheItem.proj[i],modl[i],quadCacheItem.modl[i]);
1219 //	   if(proj[i] != quadCacheItem.proj[i]) {
1220 //		   frustumChanged = true;
1221 //		   break;
1222 //	   }
1223 //	   if(modl[i] != quadCacheItem.modl[i]) {
1224 //		   frustumChanged = true;
1225 //		   break;
1226 //	   }
1227 //   }
1228 
1229    // Check the frustum cache
1230    const bool useFrustumCache = Config::getInstance().getBool("EnableFrustrumCache","false");
1231    pair<vector<float>,vector<float> > lookupKey;
1232    if(useFrustumCache == true) {
1233 	   lookupKey = make_pair(proj,modl);
1234 	   map<pair<vector<float>,vector<float> >, vector<vector<float> > >::iterator iterFind = quadCacheItem.frustumDataCache.find(lookupKey);
1235 	   if(iterFind != quadCacheItem.frustumDataCache.end()) {
1236 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum found in cache\n");
1237 
1238 		   quadCacheItem.frustumData = iterFind->second;
1239 		   frustumChanged = (quadCacheItem.proj != proj || quadCacheItem.modl != modl);
1240 		   if(frustumChanged == true) {
1241 			   quadCacheItem.proj = proj;
1242 			   quadCacheItem.modl = modl;
1243 		   }
1244 
1245 		   return frustumChanged;
1246 	   }
1247    }
1248 
1249    if(quadCacheItem.proj != proj || quadCacheItem.modl != modl) {
1250    //if(frustumChanged == true) {
1251 	   frustumChanged = true;
1252 	   vector<vector<float> > &frustum = quadCacheItem.frustumData;
1253 	   //assert(frustum.size() == 6);
1254 	   //assert(frustum[0].size() == 4);
1255 
1256 	   quadCacheItem.proj = proj;
1257 	   quadCacheItem.modl = modl;
1258 
1259 	   float   clip[16];
1260 	   float   t=0;
1261 
1262 	   /* Combine the two matrices (multiply projection by modelview) */
1263 	   clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
1264 	   clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
1265 	   clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
1266 	   clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];
1267 
1268 	   clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
1269 	   clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
1270 	   clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
1271 	   clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];
1272 
1273 	   clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
1274 	   clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
1275 	   clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
1276 	   clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];
1277 
1278 	   clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
1279 	   clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
1280 	   clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
1281 	   clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];
1282 
1283 	   /* Extract the numbers for the RIGHT plane */
1284 	   frustum[0][0] = clip[ 3] - clip[ 0];
1285 	   frustum[0][1] = clip[ 7] - clip[ 4];
1286 	   frustum[0][2] = clip[11] - clip[ 8];
1287 	   frustum[0][3] = clip[15] - clip[12];
1288 
1289 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",0,frustum[0][0],frustum[0][1],frustum[0][2],frustum[0][3]);
1290 
1291 	   /* Normalize the result */
1292 	   t = std::sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] );
1293 	   if(t != 0.0) {
1294 		   frustum[0][0] /= t;
1295 		   frustum[0][1] /= t;
1296 		   frustum[0][2] /= t;
1297 		   frustum[0][3] /= t;
1298 
1299 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",0,frustum[0][0],frustum[0][1],frustum[0][2],frustum[0][3],t);
1300 	   }
1301 
1302 	   /* Extract the numbers for the LEFT plane */
1303 	   frustum[1][0] = clip[ 3] + clip[ 0];
1304 	   frustum[1][1] = clip[ 7] + clip[ 4];
1305 	   frustum[1][2] = clip[11] + clip[ 8];
1306 	   frustum[1][3] = clip[15] + clip[12];
1307 
1308 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",1,frustum[1][0],frustum[1][1],frustum[1][2],frustum[1][3]);
1309 
1310 	   /* Normalize the result */
1311 	   t = std::sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] );
1312 	   if(t != 0.0) {
1313 		   frustum[1][0] /= t;
1314 		   frustum[1][1] /= t;
1315 		   frustum[1][2] /= t;
1316 		   frustum[1][3] /= t;
1317 
1318 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",1,frustum[1][0],frustum[1][1],frustum[1][2],frustum[1][3],t);
1319 	   }
1320 
1321 	   /* Extract the BOTTOM plane */
1322 	   frustum[2][0] = clip[ 3] + clip[ 1];
1323 	   frustum[2][1] = clip[ 7] + clip[ 5];
1324 	   frustum[2][2] = clip[11] + clip[ 9];
1325 	   frustum[2][3] = clip[15] + clip[13];
1326 
1327 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",2,frustum[2][0],frustum[2][1],frustum[2][2],frustum[2][3]);
1328 
1329 	   /* Normalize the result */
1330 
1331 	   t = std::sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] );
1332 	   if(t != 0.0) {
1333 		   frustum[2][0] /= t;
1334 		   frustum[2][1] /= t;
1335 		   frustum[2][2] /= t;
1336 		   frustum[2][3] /= t;
1337 
1338 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",2,frustum[2][0],frustum[2][1],frustum[2][2],frustum[2][3],t);
1339 	   }
1340 
1341 	   /* Extract the TOP plane */
1342 	   frustum[3][0] = clip[ 3] - clip[ 1];
1343 	   frustum[3][1] = clip[ 7] - clip[ 5];
1344 	   frustum[3][2] = clip[11] - clip[ 9];
1345 	   frustum[3][3] = clip[15] - clip[13];
1346 
1347 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",3,frustum[3][0],frustum[3][1],frustum[3][2],frustum[3][3]);
1348 
1349 	   /* Normalize the result */
1350 
1351 	   t = std::sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] );
1352 	   if(t != 0.0) {
1353 		   frustum[3][0] /= t;
1354 		   frustum[3][1] /= t;
1355 		   frustum[3][2] /= t;
1356 		   frustum[3][3] /= t;
1357 
1358 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",3,frustum[3][0],frustum[3][1],frustum[3][2],frustum[3][3],t);
1359 	   }
1360 
1361 	   /* Extract the FAR plane */
1362 	   frustum[4][0] = clip[ 3] - clip[ 2];
1363 	   frustum[4][1] = clip[ 7] - clip[ 6];
1364 	   frustum[4][2] = clip[11] - clip[10];
1365 	   frustum[4][3] = clip[15] - clip[14];
1366 
1367 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",4,frustum[4][0],frustum[4][1],frustum[4][2],frustum[4][3]);
1368 
1369 	   /* Normalize the result */
1370 
1371 	   t = std::sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] );
1372 
1373 	   if(t != 0.0) {
1374 		   frustum[4][0] /= t;
1375 		   frustum[4][1] /= t;
1376 		   frustum[4][2] /= t;
1377 		   frustum[4][3] /= t;
1378 
1379 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",4,frustum[4][0],frustum[4][1],frustum[4][2],frustum[4][3],t);
1380 	   }
1381 
1382 	   /* Extract the NEAR plane */
1383 	   frustum[5][0] = clip[ 3] + clip[ 2];
1384 	   frustum[5][1] = clip[ 7] + clip[ 6];
1385 	   frustum[5][2] = clip[11] + clip[10];
1386 	   frustum[5][3] = clip[15] + clip[14];
1387 
1388 	   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",5,frustum[5][0],frustum[5][1],frustum[5][2],frustum[5][3]);
1389 
1390 	   /* Normalize the result */
1391 
1392 	   t = std::sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] );
1393 
1394 	   if(t != 0.0) {
1395 		   frustum[5][0] /= t;
1396 		   frustum[5][1] /= t;
1397 		   frustum[5][2] /= t;
1398 		   frustum[5][3] /= t;
1399 
1400 		   if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",5,frustum[5][0],frustum[5][1],frustum[5][2],frustum[5][3],t);
1401 	   }
1402 
1403 	   if(useFrustumCache == true) {
1404 		   quadCacheItem.frustumDataCache[lookupKey] = frustum;
1405 	   }
1406    }
1407    return frustumChanged;
1408 }
1409 
PointInFrustum(vector<vector<float>> & frustum,float x,float y,float z)1410 bool Renderer::PointInFrustum(vector<vector<float> > &frustum, float x, float y, float z ) {
1411    unsigned int p=0;
1412 
1413    for( p = 0; p < frustum.size(); p++ ) {
1414       if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 ) {
1415          return false;
1416       }
1417    }
1418    return true;
1419 }
1420 
SphereInFrustum(vector<vector<float>> & frustum,float x,float y,float z,float radius)1421 bool Renderer::SphereInFrustum(vector<vector<float> > &frustum,  float x, float y, float z, float radius) {
1422 	// Go through all the sides of the frustum
1423 	for(int i = 0; i < (int)frustum.size(); i++ ) {
1424 		// If the center of the sphere is farther away from the plane than the radius
1425 		if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] <= -radius ) {
1426 			// The distance was greater than the radius so the sphere is outside of the frustum
1427 			return false;
1428 		}
1429 	}
1430 
1431 	// The sphere was inside of the frustum!
1432 	return true;
1433 }
1434 
CubeInFrustum(vector<vector<float>> & frustum,float x,float y,float z,float size)1435 bool Renderer::CubeInFrustum(vector<vector<float> > &frustum, float x, float y, float z, float size ) {
1436    unsigned int p=0;
1437 
1438    for( p = 0; p < frustum.size(); p++ ) {
1439       if( frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 )
1440          continue;
1441       if( frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 )
1442          continue;
1443       if( frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 )
1444          continue;
1445       if( frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 )
1446          continue;
1447       if( frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 )
1448          continue;
1449       if( frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 )
1450          continue;
1451       if( frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 )
1452          continue;
1453       if( frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 )
1454          continue;
1455       return false;
1456    }
1457    return true;
1458 }
1459 
computeVisibleQuad()1460 void Renderer::computeVisibleQuad() {
1461 	visibleQuad = this->gameCamera->computeVisibleQuad();
1462 
1463 	bool frustumChanged = false;
1464 	if(VisibleQuadContainerCache::enableFrustumCalcs == true) {
1465 		frustumChanged = ExtractFrustum(quadCache);
1466 	}
1467 
1468 	if(frustumChanged && SystemFlags::VERBOSE_MODE_ENABLED) {
1469 		printf("\nCamera: %d,%d %d,%d %d,%d %d,%d\n",
1470 			visibleQuad.p[0].x,visibleQuad.p[0].y,
1471 			visibleQuad.p[1].x,visibleQuad.p[1].y,
1472 			visibleQuad.p[2].x,visibleQuad.p[2].y,
1473 			visibleQuad.p[3].x,visibleQuad.p[3].y);
1474 
1475 		for(unsigned int i = 0; i < quadCache.frustumData.size(); ++i) {
1476 			printf("\nFrustum #%u [" MG_SIZE_T_SPECIFIER "]: ",i,quadCache.frustumData.size());
1477 			vector<float> &frustumDataInner = quadCache.frustumData[i];
1478 			for(unsigned int j = 0; j < frustumDataInner.size(); ++j) {
1479 				printf("[%f]",quadCache.frustumData[i][j]);
1480 			}
1481 		}
1482 
1483 		printf("\nEND\n");
1484 	}
1485 
1486 	const bool newVisibleQuadCalc = false;
1487 	if(newVisibleQuadCalc) {
1488 		const bool debug = false;
1489 		try {
1490 			if(debug) {
1491 				visibleQuad = gameCamera->computeVisibleQuad();
1492 				printf("Camera: %d,%d %d,%d %d,%d %d,%d\n",
1493 					visibleQuad.p[0].x,visibleQuad.p[0].y,
1494 					visibleQuad.p[1].x,visibleQuad.p[1].y,
1495 					visibleQuad.p[2].x,visibleQuad.p[2].y,
1496 					visibleQuad.p[3].x,visibleQuad.p[3].y);
1497 			}
1498 
1499 
1500 			// compute the four corners using OpenGL
1501 			GLdouble model[16], projection[16];
1502 			GLint viewport[4];
1503 			glGetDoublev(GL_MODELVIEW_MATRIX,model);
1504 			glGetDoublev(GL_PROJECTION_MATRIX,projection);
1505 			glGetIntegerv(GL_VIEWPORT,viewport);
1506 			Vec2i
1507 				tl = _unprojectMap(Vec2i(0,0),model,projection,viewport,"tl"),
1508 				tr = _unprojectMap(Vec2i(viewport[2],0),model,projection,viewport,"tr"),
1509 				br = _unprojectMap(Vec2i(viewport[2],viewport[3]),model,projection,viewport,"br"),
1510 				bl = _unprojectMap(Vec2i(0,viewport[3]),model,projection,viewport,"bl");
1511 
1512 
1513 			// orientate it for map iterator
1514 			//bool swapRequiredX = false;
1515 			bool swapRequiredY = false;
1516 			int const cellBuffer = 4;
1517 			if((tl.x > tr.x) || (bl.x > br.x)) {
1518 				if(debug) printf("Swap X???\n");
1519 
1520 				//std::swap(tl,bl);
1521 				//std::swap(tr,br);
1522 				if(tl.x > tr.x) {
1523 					if(debug) printf("Swap X1???\n");
1524 
1525 					tr.x += cellBuffer;
1526 					tl.x -= cellBuffer;
1527 
1528 					std::swap(tl.x,tr.x);
1529 					//swapRequiredX = true;
1530 				}
1531 				else {
1532 					tl.x += cellBuffer;
1533 					tr.x -= cellBuffer;
1534 				}
1535 				if(bl.x > br.x) {
1536 					if(debug) printf("Swap X2???\n");
1537 
1538 					bl.x += cellBuffer;
1539 					br.x -= cellBuffer;
1540 
1541 					std::swap(bl.x,br.x);
1542 					//swapRequiredX = true;
1543 				}
1544 				else {
1545 					br.x += cellBuffer;
1546 					bl.x -= cellBuffer;
1547 				}
1548 			}
1549 
1550 			if((tl.y > bl.y) || (tr.y > br.y)) {
1551 				visibleQuad = this->gameCamera->computeVisibleQuad();
1552 
1553 				if(debug) printf("Swap Y???\n");
1554 
1555 				if(tl.y > bl.y) {
1556 					if(debug) printf("Swap Y1???\n");
1557 
1558 					tl.y += cellBuffer;
1559 					bl.y -= cellBuffer;
1560 
1561 					std::swap(tl.y,bl.y);
1562 					swapRequiredY = true;
1563 				}
1564 				else {
1565 					bl.y += cellBuffer;
1566 					tl.y -= cellBuffer;
1567 				}
1568 				if(tr.y > br.y) {
1569 					if(debug) printf("Swap Y2???\n");
1570 
1571 					tr.y += cellBuffer;
1572 					br.y -= cellBuffer;
1573 
1574 					std::swap(tr.y,br.y);
1575 					swapRequiredY = true;
1576 				}
1577 				else {
1578 					br.y += cellBuffer;
1579 					tr.y -= cellBuffer;
1580 				}
1581 
1582 
1583 				//std::swap(tl,tr);
1584 				//std::swap(bl,br);
1585 			}
1586 			if(swapRequiredY == false) {
1587 				tl.y -= cellBuffer;
1588 				tr.y -= cellBuffer;
1589 				bl.y += cellBuffer;
1590 				br.y += cellBuffer;
1591 			}
1592 
1593 			// set it as the frustum
1594 			visibleQuad = Quad2i(tl,bl,tr,br); // strange order
1595 			if(debug) {
1596 				printf("Will:   %d,%d %d,%d %d,%d %d,%d\n",
1597 					visibleQuad.p[0].x,visibleQuad.p[0].y,
1598 					visibleQuad.p[1].x,visibleQuad.p[1].y,
1599 					visibleQuad.p[2].x,visibleQuad.p[2].y,
1600 					visibleQuad.p[3].x,visibleQuad.p[3].y);
1601 			}
1602 		}
1603 		catch(PROJECTION_TO_INFINITY &e) {
1604 			if(debug) printf("hmm staring at the horizon %d\n",(int)e);
1605 			// use historic code solution
1606 			visibleQuad = this->gameCamera->computeVisibleQuad();
1607 		}
1608 	}
1609 }
1610 
1611 // =======================================
1612 // basic rendering
1613 // =======================================
1614 
renderMouse2d(int x,int y,int anim,float fade)1615 void Renderer::renderMouse2d(int x, int y, int anim, float fade) {
1616 	if(no2DMouseRendering == true) {
1617 			return;
1618 	}
1619 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1620 		return;
1621 	}
1622 //	float blue=0.0f;
1623 //	float green=0.4f;
1624 	if(game != NULL && game->getGui() != NULL) {
1625 		const Gui *gui=game->getGui();
1626 		const Display *display=gui->getDisplay();
1627 		int downPos= display->getDownSelectedPos();
1628 		if(downPos != Display::invalidPos){
1629 			// in state of doing something
1630 			const Texture2D *texture= display->getDownImage(downPos);
1631 			renderTextureQuad(x+18,y-50,32,32,texture,0.8f);
1632 		}
1633 //		else {
1634 //			// Display current commandtype
1635 //			const Unit *unit=NULL;
1636 //			if(gui->getSelection()->isEmpty()){
1637 //				blue=0.0f;
1638 //				green=0.1f;
1639 //			}
1640 //			else{
1641 //				unit=gui->getSelection()->getFrontUnit();
1642 //				if(unit->getCurrCommand()!=NULL && unit->getCurrCommand()->getCommandType()->getImage()!=NULL){
1643 //					const Texture2D *texture = unit->getCurrCommand()->getCommandType()->getImage();
1644 //					renderTextureQuad(x+18,y-50,32,32,texture,0.2f);
1645 //				}
1646 //			}
1647 //		}
1648 
1649 		if(game->isMarkCellMode() == true) {
1650 			const Texture2D *texture= game->getMarkCellTexture();
1651 			renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f);
1652 		}
1653 		if(game->isUnMarkCellMode() == true) {
1654 			const Texture2D *texture= game->getUnMarkCellTexture();
1655 			renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f);
1656 		}
1657 	}
1658 
1659 	float fadeFactor = fade + 1.f;
1660 
1661 	anim= anim * 2 - maxMouse2dAnim;
1662 
1663 	float color2= (abs(anim*(int)fadeFactor)/static_cast<float>(maxMouse2dAnim))/2.f+0.4f;
1664 	float color1= (abs(anim*(int)fadeFactor)/static_cast<float>(maxMouse2dAnim))/2.f+0.8f;
1665 
1666 	glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT);
1667 		glEnable(GL_BLEND);
1668 
1669 		//inside
1670 		glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor);
1671 		glBegin(GL_TRIANGLES);
1672 			glVertex2i(x, y);
1673 			glVertex2i(x+20, y-10);
1674 			glVertex2i(x+10, y-20);
1675 		glEnd();
1676 
1677 		//border
1678 		glLineWidth(2);
1679 		glBegin(GL_LINE_LOOP);
1680 			glColor4f(1.f, 0.2f, 0, color1);
1681 			glVertex2i(x, y);
1682 			glColor4f(1.f, 0.4f, 0, color2);
1683 			glVertex2i(x+20, y-10);
1684 			glColor4f(1.f, 0.4f, 0, color2);
1685 			glVertex2i(x+10, y-20);
1686 		glEnd();
1687 	glPopAttrib();
1688 
1689 
1690 /*
1691 	if(no2DMouseRendering == true) {
1692 		return;
1693 	}
1694     float color1 = 0.0, color2 = 0.0;
1695 
1696 	float fadeFactor = fade + 1.f;
1697 
1698 	anim= anim * 2 - maxMouse2dAnim;
1699 
1700     color2= (abs(anim*(int)fadeFactor)/static_cast<float>(maxMouse2dAnim))/2.f+0.4f;
1701     color1= (abs(anim*(int)fadeFactor)/static_cast<float>(maxMouse2dAnim))/2.f+0.8f;
1702 
1703     glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT);
1704     glEnable(GL_BLEND);
1705 
1706 	//inside
1707 	Vec2i vertices[3];
1708 	vertices[0] = Vec2i(x, y);
1709 	vertices[1] = Vec2i(x+20, y-10);
1710 	vertices[2] = Vec2i(x+10, y-20);
1711 
1712 	glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor);
1713 	glEnableClientState(GL_VERTEX_ARRAY);
1714 	glVertexPointer(2, GL_INT, 0, &vertices[0]);
1715 	glDrawArrays(GL_TRIANGLES, 0, 3);
1716     glDisableClientState(GL_VERTEX_ARRAY);
1717 
1718 	//border
1719 	vertices[0] = Vec2i(x, y);
1720 	vertices[1] = Vec2i(x+20, y-10);
1721 	vertices[2] = Vec2i(x+10, y-20);
1722 
1723 	Vec4f colors[4];
1724 	colors[0] = Vec4f(1.f, 0.2f, 0, color1);
1725 	colors[1] = Vec4f(1.f, 0.4f, 0, color2);
1726 	colors[2] = Vec4f(1.f, 0.4f, 0, color2);
1727 
1728 	glLineWidth(2);
1729 	glEnableClientState(GL_VERTEX_ARRAY);
1730 	glVertexPointer(2, GL_INT, 0, &vertices[0]);
1731 	glEnableClientState(GL_COLOR_ARRAY);
1732 	glColorPointer(4, GL_FLOAT, 0, &colors[0]);
1733     glDrawArrays(GL_LINE_LOOP, 0, 3);
1734     glDisableClientState(GL_COLOR_ARRAY);
1735     glDisableClientState(GL_VERTEX_ARRAY);
1736 
1737     glPopAttrib();
1738 */
1739 }
1740 
renderMouse3d()1741 void Renderer::renderMouse3d() {
1742 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1743 		return;
1744 	}
1745 
1746 	Config &config= Config::getInstance();
1747 	if(config.getBool("RecordMode","false") == true) {
1748 		return;
1749 	}
1750 
1751 	if(game == NULL) {
1752 		char szBuf[8096]="";
1753 		snprintf(szBuf,8096,"In [%s::%s] Line: %d game == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1754 		throw megaglest_runtime_error(szBuf);
1755 	}
1756 	else if(game->getGui() == NULL) {
1757 		char szBuf[8096]="";
1758 		snprintf(szBuf,8096,"In [%s::%s] Line: %d game->getGui() == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1759 		throw megaglest_runtime_error(szBuf);
1760 	}
1761 	else if(game->getGui()->getMouse3d() == NULL) {
1762 		char szBuf[8096]="";
1763 		snprintf(szBuf,8096,"In [%s::%s] Line: %d game->getGui()->getMouse3d() == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1764 		throw megaglest_runtime_error(szBuf);
1765 	}
1766 
1767 	const Gui *gui= game->getGui();
1768 	const Mouse3d *mouse3d= gui->getMouse3d();
1769 	const Map *map= game->getWorld()->getMap();
1770 	if(map == NULL) {
1771 		char szBuf[8096]="";
1772 		snprintf(szBuf,8096,"In [%s::%s] Line: %d map == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
1773 		throw megaglest_runtime_error(szBuf);
1774 	}
1775 
1776 	assertGl();
1777 
1778 	if((mouse3d->isEnabled() || gui->isPlacingBuilding()) && gui->isValidPosObjWorld()) {
1779 		const Vec2i &pos= gui->getPosObjWorld();
1780 
1781 		glMatrixMode(GL_MODELVIEW);
1782 
1783 		glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
1784 		glEnable(GL_BLEND);
1785 		glDisable(GL_STENCIL_TEST);
1786 		glDepthFunc(GL_LESS);
1787 		glEnable(GL_COLOR_MATERIAL);
1788 		glDepthMask(GL_FALSE);
1789 
1790 		if(gui->isPlacingBuilding()) {
1791 
1792 			modelRenderer->begin(true, true, false, false);
1793 
1794 			const UnitType *building= gui->getBuilding();
1795 			const Gui *gui= game->getGui();
1796 			renderGhostModel(building, pos, gui->getSelectedFacing());
1797 
1798 			modelRenderer->end();
1799 
1800 			glDisable(GL_COLOR_MATERIAL);
1801 			glPopAttrib();
1802 		}
1803 		else {
1804 			glPushMatrix();
1805 			Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y);
1806 			Vec4f color;
1807 			GLUquadricObj *cilQuadric;
1808 			//standard mouse
1809 			glDisable(GL_TEXTURE_2D);
1810 			glDisable(GL_CULL_FACE);
1811 			color= Vec4f(1.f, 0.f, 0.f, 1.f-mouse3d->getFade());
1812 			glColor4fv(color.ptr());
1813 			glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr());
1814 
1815 			glTranslatef(pos3f.x, pos3f.y+2.f, pos3f.z);
1816 			glRotatef(90.f, 1.f, 0.f, 0.f);
1817 			glRotatef(static_cast<float>(mouse3d->getRot()), 0.f, 0.f, 1.f);
1818 
1819 			cilQuadric= gluNewQuadric();
1820 			gluQuadricDrawStyle(cilQuadric, GLU_FILL);
1821 			gluCylinder(cilQuadric, 0.5f, 0.f, 2.f, 4, 1);
1822 			gluCylinder(cilQuadric, 0.5f, 0.f, 0.f, 4, 1);
1823 			glTranslatef(0.f, 0.f, 1.f);
1824 			gluCylinder(cilQuadric, 0.7f, 0.f, 1.f, 4, 1);
1825 			gluCylinder(cilQuadric, 0.7f, 0.f, 0.f, 4, 1);
1826 			gluDeleteQuadric(cilQuadric);
1827 
1828 			glPopAttrib();
1829 			glPopMatrix();
1830 		}
1831 	}
1832 
1833 }
1834 
renderBackground(const Texture2D * texture)1835 void Renderer::renderBackground(const Texture2D *texture) {
1836 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1837 		return;
1838 	}
1839 
1840 	const Metrics &metrics= Metrics::getInstance();
1841 
1842 	assertGl();
1843 
1844     glPushAttrib(GL_ENABLE_BIT);
1845 
1846 	glDisable(GL_LIGHTING);
1847 	glEnable(GL_TEXTURE_2D);
1848 
1849 	renderQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(), texture);
1850 
1851 	glPopAttrib();
1852 
1853 	assertGl();
1854 }
1855 
renderTextureQuad(int x,int y,int w,int h,const Texture2D * texture,float alpha,const Vec3f * color)1856 void Renderer::renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha,const Vec3f *color) {
1857 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1858 		return;
1859 	}
1860 
1861     assertGl();
1862 
1863 	glPushAttrib(GL_ENABLE_BIT);
1864 
1865 	glDisable(GL_LIGHTING);
1866 	glEnable(GL_TEXTURE_2D);
1867 	glEnable(GL_BLEND);
1868 
1869 	if(color != NULL) {
1870 		Vec4f newColor(*color);
1871 		newColor.w = alpha;
1872 		glColor4fv(newColor.ptr());
1873 	}
1874 	else {
1875 		glColor4f(1.f, 1.f, 1.f, alpha);
1876 	}
1877 	renderQuad(x, y, w, h, texture);
1878 
1879 	glPopAttrib();
1880 
1881 	assertGl();
1882 }
1883 
renderConsoleLine3D(int lineIndex,int xPosition,int yPosition,int lineHeight,Font3D * font,string stringToHightlight,const ConsoleLineInfo * lineInfo)1884 void Renderer::renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight,
1885 								Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) {
1886 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1887 		return;
1888 	}
1889 
1890 	Vec4f fontColor;
1891 	Lang &lang= Lang::getInstance();
1892 	//const Metrics &metrics= Metrics::getInstance();
1893 	FontMetrics *fontMetrics= font->getMetrics();
1894 
1895 	if(game != NULL) {
1896 		fontColor = game->getGui()->getDisplay()->getColor();
1897 	}
1898 	else {
1899 		// white shadowed is default ( in the menu for example )
1900 		//fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f);
1901 		fontColor=Vec4f(lineInfo->color.x,lineInfo->color.y,lineInfo->color.z, 0.0f);
1902 	}
1903 
1904 	Vec4f defaultFontColor = fontColor;
1905 
1906 	if(lineInfo->PlayerIndex >= 0) {
1907 		std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
1908 		Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0);
1909 		fontColor.x = playerColor.x;
1910 		fontColor.y = playerColor.y;
1911 		fontColor.z = playerColor.z;
1912 
1913 		GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface();
1914 		if(gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) {
1915 			const GameSettings *gameSettings = gameNetInterface->getGameSettings();
1916 			string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex);
1917 			if(playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") {
1918 				playerName = lineInfo->originalPlayerName;
1919 			}
1920 			if(playerName == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) {
1921 				playerName = lang.getString("SystemUser");
1922 			}
1923 			//printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str());
1924 
1925 			//string headerLine = "*" + playerName + ":";
1926 			//string headerLine = playerName + ": ";
1927 			string headerLine = playerName;
1928 			if(lineInfo->teamMode == true) {
1929 				headerLine += " (" + lang.getString("Team") + ")";
1930 			}
1931 			headerLine += ": ";
1932 
1933 			if(fontMetrics == NULL) {
1934 				throw megaglest_runtime_error("fontMetrics == NULL");
1935 			}
1936 
1937 			renderTextShadow3D(
1938 					headerLine,
1939 					font,
1940 					fontColor,
1941                 	xPosition, lineIndex * lineHeight + yPosition);
1942 
1943 			fontColor = defaultFontColor;
1944 			//xPosition += (8 * (playerName.length() + 2));
1945 			// Proper font spacing after username portion of chat text rendering
1946 
1947 			//xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine)));
1948 			xPosition += fontMetrics->getTextWidth(headerLine);
1949 		}
1950 	}
1951 	else if(lineInfo->originalPlayerName != "") {
1952         string playerName = lineInfo->originalPlayerName;
1953         //string headerLine = playerName + ": ";
1954 		string headerLine = playerName;
1955 		if(lineInfo->teamMode == true) {
1956 			headerLine += " (" + lang.getString("Team") + ")";
1957 		}
1958 		headerLine += ": ";
1959 
1960         if(fontMetrics == NULL) {
1961             throw megaglest_runtime_error("fontMetrics == NULL");
1962         }
1963 
1964         renderTextShadow3D(
1965                 headerLine,
1966                 font,
1967                 fontColor,
1968                 xPosition, lineIndex * lineHeight + yPosition);
1969 
1970         fontColor = defaultFontColor;
1971         //xPosition += (8 * (playerName.length() + 2));
1972         // Proper font spacing after username portion of chat text rendering
1973         //xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine)));
1974         xPosition += fontMetrics->getTextWidth(headerLine);
1975 	}
1976 	else {
1977 		fontColor = defaultFontColor;
1978 	}
1979 
1980 	if(stringToHightlight!="" && lineInfo->text.find(stringToHightlight)!=string::npos){
1981 		fontColor=Vec4f(1.f, 0.5f, 0.5f, 0.0f);
1982 	}
1983 	renderTextShadow3D(
1984 			lineInfo->text,
1985 		font,
1986 		fontColor,
1987         xPosition, (lineIndex * lineHeight) + yPosition);
1988 }
1989 
renderConsoleLine(int lineIndex,int xPosition,int yPosition,int lineHeight,Font2D * font,string stringToHightlight,const ConsoleLineInfo * lineInfo)1990 void Renderer::renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight,
1991 								Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) {
1992 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
1993 		return;
1994 	}
1995 
1996 	Vec4f fontColor;
1997 	Lang &lang= Lang::getInstance();
1998 
1999 	const Metrics &metrics= Metrics::getInstance();
2000 	FontMetrics *fontMetrics= font->getMetrics();
2001 
2002 	if(game != NULL) {
2003 		fontColor = game->getGui()->getDisplay()->getColor();
2004 	}
2005 	else {
2006 		// white shadowed is default ( in the menu for example )
2007 		//fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f);
2008 		fontColor=Vec4f(lineInfo->color.x,lineInfo->color.y,lineInfo->color.z, 0.0f);
2009 	}
2010 
2011 	Vec4f defaultFontColor = fontColor;
2012 
2013 	if(lineInfo->PlayerIndex >= 0) {
2014 		std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
2015 		Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0);
2016 		fontColor.x = playerColor.x;
2017 		fontColor.y = playerColor.y;
2018 		fontColor.z = playerColor.z;
2019 
2020 		GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface();
2021 		if(gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) {
2022 			const GameSettings *gameSettings = gameNetInterface->getGameSettings();
2023 			string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex);
2024 			if(playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") {
2025 				playerName = lineInfo->originalPlayerName;
2026 			}
2027 			//printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str());
2028 
2029 			//string headerLine = "*" + playerName + ":";
2030 			//string headerLine = playerName + ": ";
2031 			string headerLine = playerName;
2032 			if(lineInfo->teamMode == true) {
2033 				headerLine += " (" + lang.getString("Team") + ")";
2034 			}
2035 			headerLine += ": ";
2036 
2037 			if(fontMetrics == NULL) {
2038 				throw megaglest_runtime_error("fontMetrics == NULL");
2039 			}
2040 
2041 			renderTextShadow(
2042 					headerLine,
2043 					font,
2044 					fontColor,
2045                 	xPosition, lineIndex * lineHeight + yPosition);
2046 
2047 			fontColor = defaultFontColor;
2048 			//xPosition += (8 * (playerName.length() + 2));
2049 			// Proper font spacing after username portion of chat text rendering
2050 			xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine)));
2051 		}
2052 	}
2053 	else if(lineInfo->originalPlayerName != "") {
2054         string playerName = lineInfo->originalPlayerName;
2055         //string headerLine = playerName + ": ";
2056         string headerLine = playerName;
2057 		if(lineInfo->teamMode == true) {
2058 			headerLine += " (" + lang.getString("Team") + ")";
2059 		}
2060 		headerLine += ": ";
2061 
2062         if(fontMetrics == NULL) {
2063             throw megaglest_runtime_error("fontMetrics == NULL");
2064         }
2065 
2066         renderTextShadow(
2067                 headerLine,
2068                 font,
2069                 fontColor,
2070                 xPosition, lineIndex * lineHeight + yPosition);
2071 
2072         fontColor = defaultFontColor;
2073         //xPosition += (8 * (playerName.length() + 2));
2074         // Proper font spacing after username portion of chat text rendering
2075         xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine)));
2076 	}
2077 	else {
2078 		fontColor = defaultFontColor;
2079 	}
2080 
2081 	if(stringToHightlight!="" && lineInfo->text.find(stringToHightlight)!=string::npos){
2082 		fontColor=Vec4f(1.f, 0.5f, 0.5f, 0.0f);
2083 	}
2084 	renderTextShadow(
2085 			lineInfo->text,
2086 		font,
2087 		fontColor,
2088         xPosition, (lineIndex * lineHeight) + yPosition);
2089 }
2090 
renderConsole(const Console * console,ConsoleMode mode,int overrideMaxConsoleLines)2091 void Renderer::renderConsole(const Console *console, ConsoleMode mode , int overrideMaxConsoleLines){
2092 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2093 		return;
2094 	}
2095 
2096 	if(console == NULL) {
2097 		throw megaglest_runtime_error("console == NULL");
2098 	}
2099 
2100 	glPushAttrib(GL_ENABLE_BIT);
2101 	glEnable(GL_BLEND);
2102 
2103 	if(mode==consoleFull) {
2104 	    int x= console->getXPos()-5;
2105 	    int y= console->getYPos()-5;
2106 	    int h= console->getLineHeight()*console->getStoredLineCount();
2107 
2108 	    if(h > 0) {
2109 	    	int w= 1000;
2110 	    	//background
2111 	    	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
2112 	    	glEnable(GL_BLEND);
2113 
2114 	    	glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
2115 
2116 	    	glBegin(GL_TRIANGLE_STRIP);
2117 	    		glVertex2i(x, y);
2118 	    		glVertex2i(x, y+h);
2119 	    		glVertex2i(x+w, y);
2120 	    		glVertex2i(x+w, y+h);
2121 	    	glEnd();
2122 	    	glPopAttrib();
2123 	    }
2124 		for(int i = 0; i < console->getStoredLineCount(); ++i) {
2125 			const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i);
2126 			if(renderText3DEnabled == true) {
2127 				renderConsoleLine3D(i, console->getXPos(), console->getYPos(),
2128 						console->getLineHeight(), console->getFont3D(),
2129 						console->getStringToHighlight(), &lineInfo);
2130 			}
2131 			else {
2132 				renderConsoleLine(i, console->getXPos(), console->getYPos(),
2133 						console->getLineHeight(), console->getFont(),
2134 						console->getStringToHighlight(), &lineInfo);
2135 			}
2136 		}
2137 	}
2138 	else if(mode==consoleStoredOnly) {
2139 		int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines);
2140 		for(int i = 0; i < console->getStoredLineCount() && i < allowedMaxLines; ++i) {
2141 			const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i);
2142 			if(renderText3DEnabled == true) {
2143 				renderConsoleLine3D(i, console->getXPos(), console->getYPos(),
2144 						console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo);
2145 			}
2146 			else {
2147 				renderConsoleLine(i, console->getXPos(), console->getYPos(),
2148 						console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo);
2149 			}
2150 		}
2151 	}
2152 	else if(mode==consoleStoredAndNormal) {
2153 		int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines);
2154 		float starttimestamp=-1;
2155 		int consoleIndex=0;
2156 		for(int i = 0; i < console->getLineCount() && i < allowedMaxLines; ++i) {
2157 			const ConsoleLineInfo &lineInfo = console->getLineItem(i);
2158 			if(starttimestamp>lineInfo.timeStamp || starttimestamp==-1) starttimestamp=lineInfo.timeStamp;
2159 			if(renderText3DEnabled == true) {
2160 				renderConsoleLine3D(i, console->getXPos(), console->getYPos(),
2161 						console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo);
2162 			}
2163 			else {
2164 				renderConsoleLine(i, console->getXPos(), console->getYPos(),
2165 						console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo);
2166 			}
2167 			consoleIndex++;
2168 		}
2169 		for(int i = 0; i < console->getStoredLineCount() && consoleIndex < allowedMaxLines; ++i) {
2170 			const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i);
2171 			if( lineInfo.timeStamp<starttimestamp || starttimestamp==-1){
2172 				if(renderText3DEnabled == true) {
2173 					renderConsoleLine3D(consoleIndex, console->getXPos(), console->getYPos(),
2174 							console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo);
2175 				}
2176 				else {
2177 					renderConsoleLine(consoleIndex, console->getXPos(), console->getYPos(),
2178 							console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo);
2179 				}
2180 				consoleIndex++;
2181 			}
2182 		}
2183 	}
2184 	else if(mode==consoleNormal) {
2185 		for(int i = 0; i < console->getLineCount(); ++i) {
2186 			const ConsoleLineInfo &lineInfo = console->getLineItem(i);
2187 			if(renderText3DEnabled == true) {
2188 				renderConsoleLine3D(i, console->getXPos(), console->getYPos(),
2189 						console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo);
2190 			}
2191 			else {
2192 				renderConsoleLine(i, console->getXPos(), console->getYPos(),
2193 						console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo);
2194 			}
2195 		}
2196 	}
2197 	glPopAttrib();
2198 }
2199 
renderChatManager(const ChatManager * chatManager)2200 void Renderer::renderChatManager(const ChatManager *chatManager) {
2201 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2202 		return;
2203 	}
2204 
2205 	Vec4f fontColor;
2206 	Lang &lang= Lang::getInstance();
2207 
2208 	if(chatManager->getEditEnabled()) {
2209 		Vec4f color=Vec4f(0.0f,0.0f,0.0f,0.6f);
2210 		string text="";
2211 
2212 		if(chatManager->isInCustomInputMode() == true) {
2213 			text += lang.getString("CellHint");
2214 		}
2215 		else if(chatManager->getInMenu()) {
2216 			text += lang.getString("Chat");
2217 		}
2218 		else if(chatManager->getTeamMode()) {
2219 			text += lang.getString("Team");
2220 		}
2221 		else {
2222 			text += lang.getString("All");
2223 		}
2224 		text += ": " + chatManager->getText() + "_";
2225 
2226 		if(game != NULL) {
2227 			fontColor = game->getGui()->getDisplay()->getColor();
2228 		}
2229 		else {
2230 			// white shadowed is default ( in the menu for example )
2231 			fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f);
2232 		}
2233 
2234 		// render Background
2235 		int x=chatManager->getXPos();
2236 		int y=chatManager->getYPos()-6;
2237 		int h=22;
2238 		int w=830;
2239 
2240     	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
2241     	glEnable(GL_BLEND);
2242 
2243     	glColor4f(color.x, color.y, color.z, color.w) ;
2244 
2245     	glBegin(GL_TRIANGLE_STRIP);
2246     		glVertex2i(x, y);
2247     		glVertex2i(x, y+h);
2248     		glVertex2i(x+w, y);
2249     		glVertex2i(x+w, y+h);
2250     	glEnd();
2251     	glPopAttrib();
2252 
2253 		if(renderText3DEnabled == true) {
2254 			renderTextShadow3D(
2255 					text,
2256 					chatManager->getFont3D(),
2257 					fontColor,
2258 					chatManager->getXPos(), chatManager->getYPos());
2259 		}
2260 		else {
2261 			renderTextShadow(
2262 					text,
2263 					chatManager->getFont(),
2264 					fontColor,
2265 					chatManager->getXPos(), chatManager->getYPos());
2266 		}
2267 	}
2268 	else
2269 	{
2270 		if (chatManager->getInMenu()) {
2271 			string text = "\t\t\t\t\t>> "+lang.getString("PressEnterToChat")+" <<";
2272 			fontColor = Vec4f(0.5f, 0.5f, 0.5f, 0.5f);
2273 
2274 			if(renderText3DEnabled == true) {
2275 				renderTextShadow3D(text, chatManager->getFont3D(), fontColor,
2276 						chatManager->getXPos(), chatManager->getYPos());
2277 			}
2278 			else {
2279 				renderTextShadow(text, chatManager->getFont(), fontColor,
2280 						chatManager->getXPos(), chatManager->getYPos());
2281 			}
2282 		}
2283 	}
2284 }
2285 
2286 
renderPerformanceStats()2287 void Renderer::renderPerformanceStats() {
2288 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2289 		return;
2290 	}
2291 
2292 	const Metrics &metrics = Metrics::getInstance();
2293 	const Vec4f fontColor = game->getGui()->getDisplay()->getColor();
2294 
2295 	char szBuf[200]="";
2296 	snprintf(szBuf,200,"Frame: %d",game->getWorld()->getFrameCount() / 20);
2297 	string str = string(szBuf) + string("\n");
2298 
2299 	static time_t lastGamePerfCheck = time(NULL);
2300 	static string gamePerfStats = "";
2301 	if(difftime((long int)time(NULL),lastGamePerfCheck) > 3) {
2302 		lastGamePerfCheck = time(NULL);
2303 		gamePerfStats = game->getGamePerformanceCounts(true);
2304 	}
2305 
2306 	if(gamePerfStats != "") {
2307 		str += gamePerfStats + "\n";
2308 	}
2309 
2310 	if(renderText3DEnabled == true) {
2311 		renderTextShadow3D(
2312 			str, CoreData::getInstance().getDisplayFontSmall3D(),
2313 			fontColor,
2314 			10, metrics.getVirtualH()-180, false);
2315 	}
2316 	else {
2317 		renderTextShadow(
2318 			str, CoreData::getInstance().getDisplayFontSmall(),
2319 			fontColor,
2320 			10, metrics.getVirtualH()-180, false);
2321 	}
2322 }
2323 
renderClock()2324 void Renderer::renderClock() {
2325 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2326 		return;
2327 	}
2328 
2329 	Config &config= Config::getInstance();
2330 	if(config.getBool("InGameClock","true") == false &&
2331 		config.getBool("InGameLocalClock","true") == false &&
2332 		config.getBool("InGameFrameCounter","false") == false) {
2333 		return;
2334 	}
2335 
2336 	string str = "";
2337 	const Metrics &metrics = Metrics::getInstance();
2338 	const World *world = game->getWorld();
2339 	const Vec4f fontColor = game->getGui()->getDisplay()->getColor();
2340 
2341 	if(config.getBool("InGameClock","true") == true) {
2342 		Lang &lang= Lang::getInstance();
2343 		char szBuf[501]="";
2344 
2345 		//int hours = world->getTimeFlow()->getTime();
2346 		//int minutes = (world->getTimeFlow()->getTime() - hours) * 100 * 0.6; // scale 100 to 60
2347 		//snprintf(szBuf,200,"%s %.2d:%.2d",lang.getString("GameTime","",true).c_str(),hours,minutes);
2348 		// string header2 = lang.getString("GameDurationTime","",true) + ": " + getTimeString(stats.getFramesToCalculatePlaytime());
2349 		snprintf(szBuf,500,"%s %s",lang.getString("GameDurationTime","",true).c_str(),getTimeDuationString(world->getFrameCount(),GameConstants::updateFps).c_str());
2350 		if(str != "") {
2351 			str += " ";
2352 		}
2353 		str += szBuf;
2354 	}
2355 
2356 	if(config.getBool("InGameLocalClock","true") == true) {
2357 		//time_t nowTime = time(NULL);
2358 		//struct tm *loctime = localtime(&nowTime);
2359 		struct tm loctime = threadsafe_localtime(systemtime_now());
2360 		char szBuf2[100]="";
2361 		strftime(szBuf2,100,"%H:%M",&loctime);
2362 
2363 		Lang &lang= Lang::getInstance();
2364 		char szBuf[200]="";
2365 		snprintf(szBuf,200,"%s %s",lang.getString("LocalTime","",true).c_str(),szBuf2);
2366 		if(str != "") {
2367 			str += " ";
2368 		}
2369 		str += szBuf;
2370 	}
2371 
2372 	if(config.getBool("InGameFrameCounter","false") == true) {
2373 		char szBuf[200]="";
2374 		snprintf(szBuf,200,"Frame: %d",game->getWorld()->getFrameCount() / 20);
2375 		if(str != "") {
2376 			str += " ";
2377 		}
2378 		str += szBuf;
2379 	}
2380 
2381 	//string str = szBuf;
2382 
2383 	if(renderText3DEnabled == true) {
2384 		renderTextShadow3D(
2385 			str, CoreData::getInstance().getDisplayFontSmall3D(),
2386 			fontColor,
2387 			10, metrics.getVirtualH()-160, false);
2388 	}
2389 	else {
2390 		renderTextShadow(
2391 			str, CoreData::getInstance().getDisplayFontSmall(),
2392 			fontColor,
2393 			10, metrics.getVirtualH()-160, false);
2394 	}
2395 }
2396 
renderResourceStatus()2397 void Renderer::renderResourceStatus() {
2398 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2399 		return;
2400 	}
2401 
2402 	const World *world		= game->getWorld();
2403 	Config &config= Config::getInstance();
2404 
2405 	if(world->getThisFactionIndex() < 0 ||
2406 		world->getThisFactionIndex() >= world->getFactionCount()) {
2407 		return;
2408 	}
2409 
2410 	const Faction *thisFaction = world->getFaction(world->getThisFactionIndex());
2411 
2412 	assertGl();
2413 	glPushAttrib(GL_ENABLE_BIT);
2414 
2415 	int rowsRendered = 0;
2416 	int resourceCountRendered = 0;
2417 	bool twoRessourceLines=false;
2418 
2419 	bool sharedTeamUnits = game != NULL && game->getGui() != NULL
2420 			&& game->isFlagType1BitEnabled(ft1_allow_shared_team_units)
2421 					== true;
2422 	bool sharedTeamResources = game != NULL && game->getGui() != NULL
2423 			&& game->isFlagType1BitEnabled(
2424 					ft1_allow_shared_team_resources) == true;
2425 
2426 	bool renderSharedTeamResources=false;
2427 	bool renderSharedTeamUnits=false;
2428 	bool renderLocalFactionResources=false;
2429 
2430 	if(config.getBool("TwoLineTeamResourceRendering","false") == true) {
2431 		if( sharedTeamResources == true || sharedTeamUnits == true){
2432 			twoRessourceLines=true;
2433 		}
2434 		if(sharedTeamResources == true){
2435 			renderSharedTeamResources=true;
2436 			renderSharedTeamUnits=true;
2437 		}
2438 		else if(sharedTeamUnits == true){
2439 			renderSharedTeamUnits=true;
2440 			renderLocalFactionResources=true;
2441 		}
2442 		else{
2443 			renderLocalFactionResources=true;
2444 		}
2445 	}
2446 	else {
2447 		if(sharedTeamResources == true)
2448 			renderSharedTeamResources=true;
2449 		else if(sharedTeamUnits == true)
2450 			renderSharedTeamUnits=true;
2451 		else
2452 			renderLocalFactionResources=true;
2453 	}
2454 
2455 	if(renderSharedTeamResources == true) {
2456 		resourceCountRendered = 0;
2457 		for(int techTreeResourceTypeIndex = 0;
2458 				techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount();
2459 					++techTreeResourceTypeIndex) {
2460 
2461 			const ResourceType *rt 	= world->getTechTree()->getResourceType(techTreeResourceTypeIndex);
2462 
2463 			if ( rt->getDisplayInHud() == false ) {
2464 				continue;
2465 			}
2466 
2467 			bool showResource = world->showResourceTypeForTeam(rt, thisFaction->getTeam());
2468 			if(showResource == true) {
2469 				rowsRendered = renderResource(thisFaction,
2470 						false, twoRessourceLines, rt, 0,
2471 						resourceCountRendered);
2472 			}
2473 		}
2474 		if(resourceCountRendered > 0) {
2475 			rowsRendered++;
2476 		}
2477 	}
2478 
2479 	if(renderLocalFactionResources == true){
2480 		resourceCountRendered = 0;
2481 
2482 		const Faction *factionForResourceView 	= thisFaction;
2483 		bool localFactionResourcesOnly 			= true;
2484 
2485 		for(int techTreeResourceTypeIndex = 0;
2486 				techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount();
2487 					++techTreeResourceTypeIndex) {
2488 			const ResourceType *rt 	= world->getTechTree()->getResourceType(techTreeResourceTypeIndex);
2489 			if ( rt->getDisplayInHud() == false ) {
2490 				continue;
2491 			}
2492 
2493 			//if any unit produces the resource
2494 			bool showResource;
2495 			if (twoRessourceLines)
2496 				showResource = world->showResourceTypeForTeam(rt,
2497 						factionForResourceView->getTeam());
2498 			else
2499 				showResource = world->showResourceTypeForFaction(rt,
2500 						factionForResourceView);
2501 			if(showResource == true) {
2502 				renderResource(factionForResourceView, localFactionResourcesOnly,
2503 						twoRessourceLines, rt, rowsRendered, resourceCountRendered);
2504 			}
2505 		}
2506 		if(resourceCountRendered > 0) {
2507 			rowsRendered++;
2508 		}
2509 	}
2510 
2511 	if(renderSharedTeamUnits == true){
2512 		resourceCountRendered = 0;
2513 
2514 		const Faction *factionForResourceView 	= thisFaction;
2515 		bool localFactionResourcesOnly 			= true;
2516 
2517 		const Gui *gui = game->getGui();
2518 		if(gui != NULL) {
2519 			const Selection *selection = gui->getSelection();
2520 			if(selection != NULL && selection->getCount() > 0 && selection->getFrontUnit() != NULL) {
2521 				const Unit *selectedUnit = selection->getFrontUnit();
2522 				if(selectedUnit != NULL && selectedUnit->getFaction()->isAlly(thisFaction) == true) {
2523 					factionForResourceView	  = selectedUnit->getFaction();
2524 				}
2525 			}
2526 		}
2527 
2528 		for(int techTreeResourceTypeIndex = 0;
2529 				techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount();
2530 					++techTreeResourceTypeIndex) {
2531 			const ResourceType *rt 	= world->getTechTree()->getResourceType(techTreeResourceTypeIndex);
2532 			if ( rt->getDisplayInHud() == false ) {
2533 				continue;
2534 			}
2535 
2536 			//if any unit produces the resource
2537 			bool showResource;
2538 			if (twoRessourceLines)
2539 				showResource = world->showResourceTypeForTeam(rt,
2540 						factionForResourceView->getTeam());
2541 			else
2542 				showResource = world->showResourceTypeForFaction(rt,
2543 						factionForResourceView);
2544 
2545 			if(showResource == true) {
2546 				renderResource(factionForResourceView, localFactionResourcesOnly,
2547 						twoRessourceLines, rt, rowsRendered, resourceCountRendered);
2548 			}
2549 		}
2550 		if(resourceCountRendered > 0) {
2551 			rowsRendered++;
2552 		}
2553 	}
2554 
2555 	glPopAttrib();
2556 
2557 	assertGl();
2558 }
2559 
renderResource(const Faction * factionForResourceView,bool localFactionResourcesOnly,bool twoResourceLines,const ResourceType * rt,int startRow,int & resourceCountRendered)2560 int Renderer::renderResource(const Faction *factionForResourceView,bool localFactionResourcesOnly,
2561 		bool twoResourceLines, const ResourceType *rt, int startRow, int &resourceCountRendered) {
2562 
2563 	const Metrics &metrics	= Metrics::getInstance();
2564 	const int MAX_RESOURCES_PER_ROW = 6;
2565 
2566 	int resourceRowHeigth=30;
2567 	int resourceYStart=metrics.getVirtualH()-30;
2568 	if(twoResourceLines){
2569 		// we need to save some space
2570 		resourceYStart=metrics.getVirtualH()-22;
2571 		resourceRowHeigth=16;
2572 	}
2573 
2574 	//draw resource status
2575 	if(localFactionResourcesOnly == true) {
2576 		Vec4f resourceFontColor = Vec4f(factionForResourceView->getTexture()->getPixmapConst()->getPixel3f(0,0));
2577 		int resourceCol = 0;
2578 		int resourceRow = startRow;
2579 
2580 		int x=resourceCol * 100 + 190;
2581 		int y=resourceYStart - (resourceRowHeigth * resourceRow);
2582 		int h=16;
2583 		int w=8;
2584 		glColor3f(resourceFontColor.x,resourceFontColor.y,resourceFontColor.z);
2585 		glBegin(GL_TRIANGLE_STRIP);
2586 			glVertex2i(x, y+h);
2587 			glVertex2i(x, y);
2588 			glVertex2i(x+w, y+h/2);
2589 		glEnd();
2590 	}
2591 
2592 	const Resource *r = factionForResourceView->getResource(rt,localFactionResourcesOnly);
2593 	string str = intToStr(r->getAmount());
2594 
2595 	glEnable(GL_TEXTURE_2D);
2596 
2597 	const Vec4f fontColor 	= game->getGui()->getDisplay()->getColor();
2598 	Vec4f resourceFontColor = fontColor;
2599 
2600 	bool isNegativeConsumableDisplayCycle = false;
2601 	if(rt->getClass() == rcConsumable) {
2602 		// Show in yellow/orange/red font if negative
2603 		if(r->getBalance() * 5 + r->getAmount() < 0) {
2604 			if(time(NULL) % 2 == 0) {
2605 
2606 				isNegativeConsumableDisplayCycle = true;
2607 				if(r->getBalance() * 1 + r->getAmount() < 0) {
2608 					glColor3f(RED.x,RED.y,RED.z);
2609 					resourceFontColor = RED;
2610 				}
2611 				else if(r->getBalance() * 3 + r->getAmount() < 0) {
2612 					glColor3f(ORANGE.x,ORANGE.y,ORANGE.z);
2613 					resourceFontColor = ORANGE;
2614 				}
2615 				else if(r->getBalance() * 5 + r->getAmount() < 0) {
2616 					glColor3f(YELLOW.x,YELLOW.y,YELLOW.z);
2617 					resourceFontColor = YELLOW;
2618 				}
2619 			}
2620 		}
2621 	}
2622 
2623 	if(isNegativeConsumableDisplayCycle == false) {
2624 		glColor3f(1.f, 1.f, 1.f);
2625 	}
2626 
2627 	int resourceRow = startRow + (resourceCountRendered > 0 ? resourceCountRendered / MAX_RESOURCES_PER_ROW : 0);
2628 	int resourceCol = resourceCountRendered % MAX_RESOURCES_PER_ROW;
2629 
2630 	renderQuad(resourceCol * 100 + 200, resourceYStart - (resourceRowHeigth * resourceRow), 16, 16, rt->getImage());
2631 
2632 	if(rt->getClass() != rcStatic) {
2633 		str+= "/" + intToStr(factionForResourceView->getStoreAmount(rt,localFactionResourcesOnly));
2634 	}
2635 	if(rt->getClass() == rcConsumable) {
2636 		str+= "(";
2637 		if(r->getBalance() > 0) {
2638 			str+= "+";
2639 		}
2640 		str+= intToStr(r->getBalance()) + ")";
2641 	}
2642 
2643 	glDisable(GL_TEXTURE_2D);
2644 
2645 	if(renderText3DEnabled == true) {
2646 		renderTextShadow3D(
2647 			str, CoreData::getInstance().getDisplayFontSmall3D(),
2648 			resourceFontColor,
2649 			resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false);
2650 	}
2651 	else {
2652 		renderTextShadow(
2653 			str, CoreData::getInstance().getDisplayFontSmall(),
2654 			resourceFontColor,
2655 			resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false);
2656 	}
2657 	++resourceCountRendered;
2658 
2659 	return resourceRow;
2660 }
2661 
renderSelectionQuad()2662 void Renderer::renderSelectionQuad() {
2663 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2664 		return;
2665 	}
2666 
2667 	Config &config= Config::getInstance();
2668 	if(config.getBool("RecordMode","false") == true) {
2669 		return;
2670 	}
2671 
2672 	const Gui *gui= game->getGui();
2673 	const SelectionQuad *sq= gui->getSelectionQuad();
2674 
2675     Vec2i down= sq->getPosDown();
2676     Vec2i up= sq->getPosUp();
2677 
2678     if(gui->isSelecting()) {
2679         glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT);
2680 
2681     	Vec2i vertices[4];
2682     	vertices[0] = Vec2i(down.x, down.y);
2683     	vertices[1] = Vec2i(up.x, down.y);
2684     	vertices[2] = Vec2i(up.x, up.y);
2685     	vertices[3] = Vec2i(down.x, up.y);
2686 
2687     	glColor3f(0,1,0);
2688     	glEnableClientState(GL_VERTEX_ARRAY);
2689     	glVertexPointer(2, GL_INT, 0, &vertices[0]);
2690         glDrawArrays(GL_LINE_LOOP, 0, 4);
2691         glDisableClientState(GL_VERTEX_ARRAY);
2692 
2693 /*
2694             glColor3f(0,1,0);
2695             glBegin(GL_LINE_LOOP);
2696                 glVertex2i(down.x, down.y);
2697                 glVertex2i(up.x, down.y);
2698                 glVertex2i(up.x, up.y);
2699                 glVertex2i(down.x, up.y);
2700             glEnd();
2701 */
2702         glPopAttrib();
2703     }
2704 }
2705 
computeCenteredPos(const string & text,Font2D * font,int x,int y)2706 Vec2i computeCenteredPos(const string &text, Font2D *font, int x, int y) {
2707 	if(font == NULL) {
2708 		//abort();
2709 		throw megaglest_runtime_error("font == NULL (1) text = " + text);
2710 	}
2711 	const Metrics &metrics= Metrics::getInstance();
2712 	FontMetrics *fontMetrics= font->getMetrics();
2713 
2714 	if(fontMetrics == NULL) {
2715 		throw megaglest_runtime_error("fontMetrics == NULL (1) text = " + text);
2716 	}
2717 
2718 	int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast<int>(fontMetrics->getTextWidth(text)/2.f) : 5);
2719 	int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast<int>(fontMetrics->getHeight(text)/2.f) : 5);
2720 
2721 	Vec2i textPos(
2722 		x-metrics.toVirtualX(virtualX),
2723 		y-metrics.toVirtualY(virtualY));
2724 
2725 	//printf("text [%s] x = %d y = %d virtualX = %d virtualY = %d fontMetrics->getHeight() = %f\n",text.c_str(),x,y,virtualX,virtualY,fontMetrics->getHeight());
2726 
2727 	return textPos;
2728 }
2729 
computeCenteredPos(const string & text,Font3D * font,int x,int y)2730 Vec2i computeCenteredPos(const string &text, Font3D *font, int x, int y) {
2731 	if(font == NULL) {
2732 		throw megaglest_runtime_error("font == NULL (2) text = " + text);
2733 	}
2734 	const Metrics &metrics= Metrics::getInstance();
2735 	FontMetrics *fontMetrics= font->getMetrics();
2736 
2737 	if(fontMetrics == NULL) {
2738 		throw megaglest_runtime_error("fontMetrics == NULL (2) text = " + text);
2739 	}
2740 
2741 	int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast<int>(fontMetrics->getTextWidth(text) / 2.f) : 5);
2742 	int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast<int>(fontMetrics->getHeight(text) / 2.f) : 5);
2743 
2744 	Vec2i textPos(
2745 		x-metrics.toVirtualX(virtualX),
2746 		y-metrics.toVirtualY(virtualY));
2747 
2748 	return textPos;
2749 }
2750 
renderTextSurroundingBox(int x,int y,int w,int h,int maxEditWidth,int maxEditRenderWidth)2751 void Renderer::renderTextSurroundingBox(int x, int y, int w, int h,
2752 		int maxEditWidth, int maxEditRenderWidth) {
2753 	//glColor4fv(color.ptr());
2754 	//glBegin(GL_QUADS); // Start drawing a quad primitive
2755 
2756 	//printf("A w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth);
2757 	if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) {
2758 		//printf("B w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth);
2759 		if(maxEditRenderWidth >= 0) {
2760 			w = maxEditRenderWidth;
2761 		}
2762 		else {
2763 			w = maxEditWidth;
2764 		}
2765 	}
2766 	//printf("HI!!!\n");
2767 	glPointSize(20.0f);
2768 
2769 	int margin = 4;
2770 	//glBegin(GL_POINTS); // Start drawing a point primitive
2771 	glBegin(GL_LINE_LOOP); // Start drawing a line primitive
2772 
2773 	glVertex3f(x, y+h, 0.0f); // The bottom left corner
2774 	glVertex3f(x, y-margin, 0.0f); // The top left corner
2775 	glVertex3f(x+w, y-margin, 0.0f); // The top right corner
2776 	glVertex3f(x+w, y+h, 0.0f); // The bottom right corner
2777 	glEnd();
2778 }
2779 
renderTextBoundingBox3D(const string & text,Font3D * font,float alpha,int x,int y,int w,int h,bool centeredW,bool centeredH,bool editModeEnabled,int maxEditWidth,int maxEditRenderWidth)2780 void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font,
2781 		float alpha, int x, int y, int w, int h, bool centeredW, bool centeredH,
2782 		bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) {
2783 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2784 		return;
2785 	}
2786 
2787 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
2788 	glEnable(GL_BLEND);
2789 	glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr());
2790 
2791 	Vec2f pos= Vec2f(x, y);
2792 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2793 	if(centeredW == true || centeredH == true) {
2794 		getCentered3DPos(text, font, pos, w, h, centeredW, centeredH);
2795 	}
2796 
2797 	if(editModeEnabled) {
2798 		if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) {
2799 			int useWidth = maxEditWidth;
2800 			string temp = "";
2801 			for(int i = 0; i < useWidth; ++i) {
2802 				temp += DEFAULT_CHAR_FOR_WIDTH_CALC;
2803 			}
2804 			float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue);
2805 			useWidth = (int)lineWidth;
2806 
2807 			maxEditWidth = useWidth;
2808 		}
2809 
2810 		renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth);
2811 	}
2812 	glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr());
2813 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
2814 	textRenderer3D->render(text, pos.x, pos.y);
2815 	safeTextRender.end();
2816 
2817 	glDisable(GL_BLEND);
2818 	glPopAttrib();
2819 }
2820 
renderText3D(const string & text,Font3D * font,float alpha,int x,int y,bool centered)2821 void Renderer::renderText3D(const string &text, Font3D *font, float alpha, int x, int y, bool centered) {
2822 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2823 		return;
2824 	}
2825 
2826 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
2827 	glEnable(GL_BLEND);
2828 	glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr());
2829 
2830 	Vec2i pos= Vec2i(x, y);
2831 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2832 
2833 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
2834 	textRenderer3D->render(text, pos.x, pos.y, centered);
2835 	//textRenderer3D->end();
2836 	safeTextRender.end();
2837 
2838 	glDisable(GL_BLEND);
2839 	glPopAttrib();
2840 }
2841 
renderText(const string & text,Font2D * font,float alpha,int x,int y,bool centered)2842 void Renderer::renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered) {
2843 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2844 		return;
2845 	}
2846 
2847 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
2848 	glEnable(GL_BLEND);
2849 	glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr());
2850 
2851 	Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2852 
2853 	TextRendererSafeWrapper safeTextRender(textRenderer,font);
2854 	textRenderer->render(text, pos.x, pos.y);
2855 	safeTextRender.end();
2856 
2857 	glPopAttrib();
2858 }
2859 
getCentered3DPos(const string & text,Font3D * font,Vec2f & pos,int w,int h,bool centeredW,bool centeredH)2860 Vec2f Renderer::getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h,bool centeredW, bool centeredH) {
2861 	if(centeredW == true) {
2862 		if(font == NULL) {
2863 			//abort();
2864 			throw megaglest_runtime_error("font == NULL (5) text = " + text);
2865 		}
2866 		else if(font->getTextHandler() == NULL) {
2867 			char szBuf[8096] = "";
2868 			snprintf(szBuf, 8096, "font->getTextHandler() == NULL(5) text = [%s] FontPtr = [%p]\n", text.c_str(),font);
2869 			throw megaglest_runtime_error(szBuf);
2870 		}
2871 
2872 		float lineWidth = (font->getTextHandler()->Advance(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue);
2873 		if(lineWidth < w) {
2874 			pos.x += ((w / 2.f) - (lineWidth / 2.f));
2875 		}
2876 	}
2877 
2878 	if(centeredH) {
2879 		if(font == NULL) {
2880 			throw megaglest_runtime_error("font == NULL (6) text = " + text);
2881 		}
2882 		else if(font->getTextHandler() == NULL) {
2883 			throw megaglest_runtime_error("font->getTextHandler() == NULL (6) text = " + text);
2884 		}
2885 
2886 		//const Metrics &metrics= Metrics::getInstance();
2887 		//float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * Font::scaleFontValue);
2888 		float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue);
2889 		//lineHeight=metrics.toVirtualY(lineHeight);
2890 		//lineHeight= lineHeight / (2.f + 0.2f * FontMetrics::DEFAULT_Y_OFFSET_FACTOR);
2891 		//pos.y += (h / 2.f) - (lineHeight / 2.f);
2892 		//pos.y += (h / 2.f) - (lineHeight);
2893 		//pos.y += (lineHeight / 2.f); // y starts at the middle of the render position, so only move up 1/2 the font height
2894 
2895 		if(lineHeight < h) {
2896 			//printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str());
2897 
2898 			//if(Font::forceFTGLFonts == true) {
2899 				// First go to top of bounding box
2900 				pos.y += (h - lineHeight);
2901 				pos.y -= ((h - lineHeight) / ::Shared::Graphics::Font::scaleFontValueCenterHFactor);
2902 //			}
2903 //			else {
2904 //				pos.y += (float)(((float)h) / 2.0);
2905 //				float heightGap = (float)(((float)h - lineHeight) / 2.0);
2906 //				pos.y -= heightGap;
2907 //
2908 //				//printf("h = %d lineHeight = %f heightGap = %f\n",h,lineHeight,heightGap);
2909 //
2910 //			// Now calculate till we get text to middle
2911 //			//pos.y -= (realHeight / 2);
2912 //			//pos.y += (lineHeight / 2);
2913 //			}
2914 		}
2915 		else if(lineHeight > h) {
2916 			//printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str());
2917 
2918 			pos.y += (std::ceil(lineHeight - h));
2919 		}
2920 	}
2921 	return pos;
2922 }
2923 
renderTextBoundingBox3D(const string & text,Font3D * font,const Vec3f & color,int x,int y,int w,int h,bool centeredW,bool centeredH,bool editModeEnabled,int maxEditWidth,int maxEditRenderWidth)2924 void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font,
2925 		const Vec3f &color, int x, int y, int w, int h, bool centeredW,
2926 		bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) {
2927 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2928 		return;
2929 	}
2930 
2931 	glPushAttrib(GL_CURRENT_BIT);
2932 	glColor3fv(color.ptr());
2933 
2934 	Vec2f pos= Vec2f(x, y);
2935 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2936 
2937 	if(centeredW == true || centeredH == true) {
2938 		getCentered3DPos(text, font, pos, w, h,centeredW,centeredH);
2939 	}
2940 
2941 	if(editModeEnabled) {
2942 		if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) {
2943 			int useWidth = maxEditWidth;
2944 			string temp = "";
2945 			for(int i = 0; i < useWidth; ++i) {
2946 				temp += DEFAULT_CHAR_FOR_WIDTH_CALC;
2947 			}
2948 			float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue);
2949 			useWidth = (int)lineWidth;
2950 
2951 			maxEditWidth = useWidth;
2952 		}
2953 
2954 		renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth);
2955 	}
2956 	glColor3fv(color.ptr());
2957 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
2958 	textRenderer3D->render(text, pos.x, pos.y);
2959 	safeTextRender.end();
2960 
2961 	glPopAttrib();
2962 }
2963 
renderText3D(const string & text,Font3D * font,const Vec3f & color,int x,int y,bool centered)2964 void Renderer::renderText3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, bool centered) {
2965 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2966 		return;
2967 	}
2968 
2969 	glPushAttrib(GL_CURRENT_BIT);
2970 	glColor3fv(color.ptr());
2971 
2972 	Vec2i pos= Vec2i(x, y);
2973 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2974 
2975 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
2976 	textRenderer3D->render(text, pos.x, pos.y, centered);
2977 	safeTextRender.end();
2978 
2979 	glPopAttrib();
2980 }
2981 
renderText(const string & text,Font2D * font,const Vec3f & color,int x,int y,bool centered)2982 void Renderer::renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered){
2983 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
2984 		return;
2985 	}
2986 
2987 	glPushAttrib(GL_CURRENT_BIT);
2988 	glColor3fv(color.ptr());
2989 
2990 	Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
2991 
2992 	TextRendererSafeWrapper safeTextRender(textRenderer,font);
2993 	textRenderer->render(text, pos.x, pos.y);
2994 	safeTextRender.end();
2995 
2996 	glPopAttrib();
2997 }
2998 
renderTextBoundingBox3D(const string & text,Font3D * font,const Vec4f & color,int x,int y,int w,int h,bool centeredW,bool centeredH,bool editModeEnabled,int maxEditWidth,int maxEditRenderWidth)2999 void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font,
3000 		const Vec4f &color, int x, int y, int w, int h, bool centeredW,
3001 		bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) {
3002 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3003 		return;
3004 	}
3005 
3006 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3007 	glEnable(GL_BLEND);
3008 	glColor4fv(color.ptr());
3009 
3010 	Vec2f pos= Vec2f(x, y);
3011 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
3012 
3013 	if(centeredW == true || centeredH == true) {
3014 		getCentered3DPos(text, font, pos, w, h,centeredW,centeredH);
3015 	}
3016 
3017 	if(editModeEnabled) {
3018 		if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) {
3019 			int useWidth = maxEditWidth;
3020 			string temp = "";
3021 			for(int i = 0; i < useWidth; ++i) {
3022 				temp += DEFAULT_CHAR_FOR_WIDTH_CALC;
3023 			}
3024 			float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue);
3025 			useWidth = (int)lineWidth;
3026 
3027 			maxEditWidth = useWidth;
3028 		}
3029 
3030 		renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth);
3031 	}
3032 	glColor4fv(color.ptr());
3033 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
3034 	textRenderer3D->render(text, pos.x, pos.y);
3035 	safeTextRender.end();
3036 
3037 	glDisable(GL_BLEND);
3038 	glPopAttrib();
3039 }
3040 
renderText3D(const string & text,Font3D * font,const Vec4f & color,int x,int y,bool centered)3041 void Renderer::renderText3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered) {
3042 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3043 		return;
3044 	}
3045 
3046 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3047 	glEnable(GL_BLEND);
3048 	glColor4fv(color.ptr());
3049 
3050 	Vec2i pos= Vec2i(x, y);
3051 	//Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
3052 
3053 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
3054 	textRenderer3D->render(text, pos.x, pos.y, centered);
3055 	safeTextRender.end();
3056 
3057 	glDisable(GL_BLEND);
3058 	glPopAttrib();
3059 }
3060 
renderText(const string & text,Font2D * font,const Vec4f & color,int x,int y,bool centered)3061 void Renderer::renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered){
3062 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3063 		return;
3064 	}
3065 
3066 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3067 	glEnable(GL_BLEND);
3068 	glColor4fv(color.ptr());
3069 
3070 	Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
3071 
3072 	TextRendererSafeWrapper safeTextRender(textRenderer,font);
3073 	textRenderer->render(text, pos.x, pos.y);
3074 	safeTextRender.end();
3075 
3076 	glPopAttrib();
3077 }
3078 
renderTextShadow3D(const string & text,Font3D * font,const Vec4f & color,int x,int y,bool centered)3079 void Renderer::renderTextShadow3D(const string &text, Font3D *font,const Vec4f &color, int x, int y, bool centered) {
3080 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3081 		return;
3082 	}
3083 
3084 	if(font == NULL) {
3085 		throw megaglest_runtime_error("font == NULL (3) text = " + text);
3086 	}
3087 
3088 	glPushAttrib(GL_CURRENT_BIT);
3089 
3090 	Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
3091 
3092 	TextRendererSafeWrapper safeTextRender(textRenderer3D,font);
3093 	if(color.w < 0.5)	{
3094 		glColor3f(0.0f, 0.0f, 0.0f);
3095 
3096 		textRenderer3D->render(text, pos.x-1.0f, pos.y-1.0f);
3097 	}
3098 	glColor3f(color.x,color.y,color.z);
3099 
3100 	textRenderer3D->render(text, pos.x, pos.y);
3101 	//textRenderer3D->end();
3102 	safeTextRender.end();
3103 
3104 	glPopAttrib();
3105 }
3106 
renderTextShadow(const string & text,Font2D * font,const Vec4f & color,int x,int y,bool centered)3107 void Renderer::renderTextShadow(const string &text, Font2D *font,const Vec4f &color, int x, int y, bool centered){
3108 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3109 		return;
3110 	}
3111 
3112 	if(font == NULL) {
3113 		throw megaglest_runtime_error("font == NULL (4) text = " + text);
3114 	}
3115 
3116 	glPushAttrib(GL_CURRENT_BIT);
3117 
3118 	Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y);
3119 
3120 	TextRendererSafeWrapper safeTextRender(textRenderer,font);
3121 	if(color.w < 0.5)	{
3122 		glColor3f(0.0f, 0.0f, 0.0f);
3123 
3124 		textRenderer->render(text, pos.x-1.0f, pos.y-1.0f);
3125 	}
3126 	glColor3f(color.x,color.y,color.z);
3127 
3128 	textRenderer->render(text, pos.x, pos.y);
3129 	//textRenderer->end();
3130 	safeTextRender.end();
3131 
3132 	glPopAttrib();
3133 }
3134 
3135 // ============= COMPONENTS =============================
3136 
renderLabel(GraphicLabel * label)3137 void Renderer::renderLabel(GraphicLabel *label) {
3138 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3139 		return;
3140 	}
3141 
3142 	if(label->getEditable() && label->getMaxEditRenderWidth()>0)
3143 	{
3144 	    int x= label->getX();
3145 	    int y= label->getY();
3146 	    int h= label->getH();
3147 	    int w= label->getMaxEditRenderWidth();
3148 	    if(h>0){
3149 	    	//background
3150 	    	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3151 	    	glEnable(GL_BLEND);
3152 
3153 	    	glColor4f(0.2f, 0.2f, 0.2f, 0.6f*label->getFade()) ;
3154 
3155 	    	glBegin(GL_TRIANGLE_STRIP);
3156 	    		glVertex2i(x, y);
3157 	    		glVertex2i(x, y+h);
3158 	    		glVertex2i(x+w, y);
3159 	    		glVertex2i(x+w, y+h);
3160 	    	glEnd();
3161 	    	glPopAttrib();
3162 	    }
3163 	}
3164 
3165 	if(label->getRenderBackground())
3166 	{
3167 	    int x= label->getX();
3168 	    int y= label->getY();
3169 	    int h= label->getH();
3170 	    int w= label->getW();
3171 	    if(label->getMaxEditRenderWidth()>0){
3172 	    	w= label->getMaxEditRenderWidth();
3173 	    }
3174 	    Vec4f color=label->getBackgroundColor();
3175 	    if(h>0){
3176 	    	//background
3177 	    	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3178 	    	glEnable(GL_BLEND);
3179 
3180 	    	glColor4f(color.x, color.y, color.z, color.w*label->getFade()) ;
3181 
3182 	    	glBegin(GL_TRIANGLE_STRIP);
3183 	    		glVertex2i(x, y);
3184 	    		glVertex2i(x, y+h);
3185 	    		glVertex2i(x+w, y);
3186 	    		glVertex2i(x+w, y+h);
3187 	    	glEnd();
3188 	    	glPopAttrib();
3189 	    }
3190 	}
3191 
3192 	if(label->getTexture()!=NULL )
3193 	{
3194 	    int x= label->getX();
3195 	    int y= label->getY();
3196 	    int h= label->getH();
3197 	    int w= label->getW();
3198 	    if(h>0){
3199 	    	//background
3200 			glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3201 			glEnable(GL_BLEND);
3202 			glEnable(GL_TEXTURE_2D);
3203 			glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>( label->getTexture())->getHandle());
3204 	    	glColor4f(1.0f, 1.0f, 1.0f, 1.0f*label->getFade()) ;
3205 	    	glBegin(GL_TRIANGLE_STRIP);
3206 	    		glTexCoord2f(0.f, 0.f);
3207 	    		glVertex2f(x, y);
3208 
3209 	    		glTexCoord2f(0.f, 1.f);
3210 	    		glVertex2f(x, y+h);
3211 
3212 	    		glTexCoord2f(1.f, 0.f);
3213 	    		glVertex2f(x+w, y);
3214 
3215 	    		glTexCoord2f(1.f, 1.f);
3216 	    		glVertex2f(x+w, y+h);
3217 	    	glEnd();
3218 	    	glDisable(GL_TEXTURE_2D);
3219 	    	glPopAttrib();
3220 	    }
3221 	}
3222 	Vec3f labelColor=label->getTextColor();
3223 	Vec4f colorWithAlpha = Vec4f(labelColor.x,labelColor.y,labelColor.z,GraphicComponent::getFade());
3224 	renderLabel(label,&colorWithAlpha);
3225 }
3226 
renderLabel(GraphicLabel * label,const Vec3f * color)3227 void Renderer::renderLabel(GraphicLabel *label,const Vec3f *color) {
3228 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3229 		return;
3230 	}
3231 
3232 	if(color != NULL) {
3233 		Vec4f colorWithAlpha = Vec4f(*color);
3234 		colorWithAlpha.w = GraphicComponent::getFade();
3235 		renderLabel(label,&colorWithAlpha);
3236 	}
3237 	else {
3238 		Vec4f *colorWithAlpha = NULL;
3239 		renderLabel(label,colorWithAlpha);
3240 	}
3241 }
3242 
renderLabel(GraphicLabel * label,const Vec4f * color)3243 void Renderer::renderLabel(GraphicLabel *label,const Vec4f *color) {
3244 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3245 		return;
3246 	}
3247 
3248 	if(label->getVisible() == false) {
3249 		return;
3250 	}
3251 	try {
3252 	glPushAttrib(GL_ENABLE_BIT);
3253 	glEnable(GL_BLEND);
3254 
3255 	vector<string> lines;
3256 	string renderTextString = (label->getTextNativeTranslation() != "" ? label->getTextNativeTranslation() : label->getText());
3257 	if(label->getWordWrap() == true) {
3258 		Tokenize(renderTextString,lines,"\n");
3259 	}
3260 	else {
3261 		lines.push_back(renderTextString);
3262 	}
3263 
3264 	for(unsigned int i = 0; i < lines.size(); ++i) {
3265 		Vec2i textPos;
3266 		int x= label->getX();
3267 		int y= label->getY() - (i * label->getH());
3268 		int h= label->getH();
3269 		int w= label->getW();
3270 		//if(label->getInstanceName() == "modDescrLabel") printf("~~~ lines.size() [%u] i = %d lines[i] [%s] y = %d\n",lines.size(),i,lines[i].c_str(),y);
3271 
3272 		if(label->getCentered()) {
3273 			textPos= Vec2i(x+w/2, y+h/2);
3274 		}
3275 		else {
3276 			textPos= Vec2i(x, y+h/4);
3277 		}
3278 
3279 		string renderTextStr = lines[i];
3280 		if(label->getIsPassword() == true) {
3281 			if(renderTextStr != "") {
3282 				renderTextStr = "*****";
3283 			}
3284 		}
3285 
3286 		if(color != NULL) {
3287 			if(renderText3DEnabled == true) {
3288 				//renderText3D(lines[i], label->getFont3D(), (*color), textPos.x, textPos.y, label->getCentered());
3289 				//printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D());
3290 				//printf("Label render C\n");
3291 
3292 				renderTextBoundingBox3D(renderTextStr, label->getFont3D(), (*color),
3293 						x, y, w, h, label->getCenteredW(),label->getCenteredH(),
3294 						label->getEditModeEnabled(),label->getMaxEditWidth(),
3295 						label->getMaxEditRenderWidth());
3296 			}
3297 			else {
3298 				//printf("Label render D\n");
3299 				renderText(renderTextStr, label->getFont(), (*color), textPos.x, textPos.y, label->getCentered());
3300 			}
3301 		}
3302 		else {
3303 			if(renderText3DEnabled == true) {
3304 				//renderText3D(lines[i], label->getFont3D(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered());
3305 				//printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D());
3306 				//printf("Label render E\n");
3307 				renderTextBoundingBox3D(renderTextStr, label->getFont3D(),
3308 						GraphicComponent::getFade(), x, y, w, h,
3309 						label->getCenteredW(),label->getCenteredH(),
3310 						label->getEditModeEnabled(),label->getMaxEditWidth(),
3311 						label->getMaxEditRenderWidth());
3312 			}
3313 			else {
3314 				//printf("Label render F\n");
3315 				renderText(renderTextStr, label->getFont(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered());
3316 			}
3317 		}
3318 	}
3319 	glPopAttrib();
3320 	}
3321 	catch(const exception &e) {
3322 		char szBuf[8096]="";
3323 		snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s] For Control [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),label->getInstanceName().c_str());
3324 		SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3325 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3326 
3327 		throw megaglest_runtime_error(szBuf);
3328 	}
3329 
3330 }
3331 
renderButton(GraphicButton * button,const Vec4f * fontColorOverride,bool * lightedOverride)3332 void Renderer::renderButton(GraphicButton *button, const Vec4f *fontColorOverride, bool *lightedOverride) {
3333 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3334 		return;
3335 	}
3336 
3337 	if(button->getVisible() == false) {
3338 		return;
3339 	}
3340 
3341 	try {
3342 
3343 	//char szBuf[8096]="";
3344 	//snprintf(szBuf,8096,"In [%s::%s Line: %d]\n For Control container [%s] name [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,button->getContainerName().c_str(), button->getInstanceName().c_str());
3345 	//printf(szBuf);
3346 
3347     int x= button->getX();
3348     int y= button->getY();
3349     int h= button->getH();
3350     int w= button->getW();
3351 
3352 	const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f);
3353 
3354 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
3355 
3356 	//background
3357 	CoreData &coreData= CoreData::getInstance();
3358 	Texture2D *backTexture = NULL;
3359 
3360 	if(button->getUseCustomTexture() == true) {
3361 		backTexture = dynamic_cast<Texture2D *>(button->getCustomTexture());
3362 	}
3363 	else {
3364 		backTexture = w > 3 * h / 2 ? coreData.getButtonBigTexture(): coreData.getButtonSmallTexture();
3365 	}
3366 
3367 	glEnable(GL_TEXTURE_2D);
3368 	glEnable(GL_BLEND);
3369 
3370 	if(backTexture != NULL) {
3371 		glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(backTexture)->getHandle());
3372 	}
3373 	else {
3374 		glBindTexture(GL_TEXTURE_2D, 0);
3375 	}
3376 
3377 	//button
3378 	Vec4f fontColor(GraphicComponent::getCustomTextColor());
3379 
3380 	if(fontColorOverride != NULL) {
3381 		fontColor= *fontColorOverride;
3382 	}
3383 	else {
3384 		// white shadowed is default ( in the menu for example )
3385 		fontColor.w = GraphicComponent::getFade();
3386 	}
3387 
3388 	//Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade());
3389 	Vec4f color= fontColor;
3390 	glColor4fv(color.ptr());
3391 
3392 	glBegin(GL_TRIANGLE_STRIP);
3393 		glTexCoord2f(0.f, 0.f);
3394 		glVertex2f(x, y);
3395 
3396 		glTexCoord2f(0.f, 1.f);
3397 		glVertex2f(x, y+h);
3398 
3399 		glTexCoord2f(1.f, 0.f);
3400 		glVertex2f(x+w, y);
3401 
3402 		glTexCoord2f(1.f, 1.f);
3403 		glVertex2f(x+w, y+h);
3404 
3405 	glEnd();
3406 
3407 	glDisable(GL_TEXTURE_2D);
3408 
3409 	//lighting
3410 	float anim= GraphicComponent::getAnim();
3411 	if(anim>0.5f) anim= 1.f-anim;
3412 
3413 	bool renderLighted = (button->getLighted() && button->getEditable());
3414 	if(lightedOverride != NULL) {
3415 		renderLighted = *lightedOverride;
3416 	}
3417 	if(renderLighted) {
3418 		const int lightSize= 0;
3419 		const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f);
3420 		const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim);
3421 
3422 		glBegin(GL_TRIANGLE_FAN);
3423 
3424 		glColor4fv(color2.ptr());
3425 		glVertex2f(x+w/2, y+h/2);
3426 
3427 		glColor4fv(color1.ptr());
3428 		glVertex2f(x-lightSize, y-lightSize);
3429 
3430 		glColor4fv(color1.ptr());
3431 		glVertex2f(x+w+lightSize, y-lightSize);
3432 
3433 		glColor4fv(color1.ptr());
3434 		glVertex2f(x+w+lightSize, y+h+lightSize);
3435 
3436 		glColor4fv(color1.ptr());
3437 		glVertex2f(x+w+lightSize, y+h+lightSize);
3438 
3439 		glColor4fv(color1.ptr());
3440 		glVertex2f(x-lightSize, y+h+lightSize);
3441 
3442 		glColor4fv(color1.ptr());
3443 		glVertex2f(x-lightSize, y-lightSize);
3444 
3445 		glEnd();
3446 	}
3447 
3448 	//Vec2i textPos= Vec2i(x + w / 2, y + h / 2);
3449 
3450 	if(button->getEditable()) {
3451 		if(renderText3DEnabled == true) {
3452 			//renderText3D(button->getText(), button->getFont3D(), color,x + (w / 2), y + (h / 2), true);
3453 			renderTextBoundingBox3D(button->getText(), button->getFont3D(),
3454 					color, x, y, w, h, true, true,false,-1,-1);
3455 		}
3456 		else {
3457 			renderText(button->getText(), button->getFont(), color,x + (w / 2), y + (h / 2), true);
3458 		}
3459 	}
3460 	else {
3461 		if(renderText3DEnabled == true) {
3462 			//renderText3D(button->getText(), button->getFont3D(),disabledTextColor,
3463 			//       x + (w / 2), y + (h / 2), true);
3464 			renderTextBoundingBox3D(button->getText(), button->getFont3D(),disabledTextColor,
3465 						       x, y, w, h, true, true,false,-1,-1);
3466 		}
3467 		else {
3468 			renderText(button->getText(), button->getFont(),disabledTextColor,
3469 			       x + (w / 2), y + (h / 2), true);
3470 		}
3471 	}
3472 
3473     glPopAttrib();
3474 	}
3475 	catch(const exception &e) {
3476 		char szBuf[8096]="";
3477 		snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s] For Control container [%s] name [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),button->getContainerName().c_str(), button->getInstanceName().c_str());
3478 		SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3479 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3480 
3481 		throw megaglest_runtime_error(szBuf);
3482 	}
3483 }
3484 
renderCheckBox(const GraphicCheckBox * box)3485 void Renderer::renderCheckBox(const GraphicCheckBox *box) {
3486 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3487 		return;
3488 	}
3489 
3490 	if(box->getVisible() == false) {
3491 		return;
3492 	}
3493 
3494     int x= box->getX();
3495     int y= box->getY();
3496     int h= box->getH();
3497     int w= box->getW();
3498 
3499 	//const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f);
3500 
3501 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
3502 
3503 	//background
3504 	CoreData &coreData= CoreData::getInstance();
3505 	Texture2D *backTexture= box->getValue()? coreData.getCheckedCheckBoxTexture(): coreData.getCheckBoxTexture();
3506 
3507 	glEnable(GL_TEXTURE_2D);
3508 	glEnable(GL_BLEND);
3509 
3510 	glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(backTexture)->getHandle());
3511 
3512 	//box
3513 	Vec4f fontColor;
3514 	//if(game!=NULL){
3515 	//	fontColor=game->getGui()->getDisplay()->getColor();
3516 	//	fontColor.w = GraphicComponent::getFade();
3517 	//}
3518 	//else {
3519 		// white shadowed is default ( in the menu for example )
3520 		fontColor=Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade());
3521 	//}
3522 
3523 	//Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade());
3524 	Vec4f color= fontColor;
3525 	glColor4fv(color.ptr());
3526 
3527 	glBegin(GL_TRIANGLE_STRIP);
3528 		glTexCoord2f(0.f, 0.f);
3529 		glVertex2f(x, y);
3530 
3531 		glTexCoord2f(0.f, 1.f);
3532 		glVertex2f(x, y+h);
3533 
3534 		glTexCoord2f(1.f, 0.f);
3535 		glVertex2f(x+w, y);
3536 
3537 		glTexCoord2f(1.f, 1.f);
3538 		glVertex2f(x+w, y+h);
3539 
3540 	glEnd();
3541 
3542 	glDisable(GL_TEXTURE_2D);
3543 
3544 	//lighting
3545 	float anim= GraphicComponent::getAnim();
3546 	if(anim > 0.5f) {
3547 		anim = 1.f - anim;
3548 	}
3549 
3550 	if(box->getLighted() && box->getEditable()) {
3551 		const int lightSize= 0;
3552 		const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f);
3553 		const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim);
3554 
3555 		glBegin(GL_TRIANGLE_FAN);
3556 
3557 		glColor4fv(color2.ptr());
3558 		glVertex2f(x+w/2, y+h/2);
3559 
3560 		glColor4fv(color1.ptr());
3561 		glVertex2f(x-lightSize, y-lightSize);
3562 
3563 		glColor4fv(color1.ptr());
3564 		glVertex2f(x+w+lightSize, y-lightSize);
3565 
3566 		glColor4fv(color1.ptr());
3567 		glVertex2f(x+w+lightSize, y+h+lightSize);
3568 
3569 		glColor4fv(color1.ptr());
3570 		glVertex2f(x+w+lightSize, y+h+lightSize);
3571 
3572 		glColor4fv(color1.ptr());
3573 		glVertex2f(x-lightSize, y+h+lightSize);
3574 
3575 		glColor4fv(color1.ptr());
3576 		glVertex2f(x-lightSize, y-lightSize);
3577 
3578 		glEnd();
3579 	}
3580 
3581     glPopAttrib();
3582 }
3583 
3584 
renderLine(const GraphicLine * line)3585 void Renderer::renderLine(const GraphicLine *line) {
3586 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3587 		return;
3588 	}
3589 
3590 	if(line->getVisible() == false) {
3591 		return;
3592 	}
3593 
3594     int x= line->getX();
3595     int y= line->getY();
3596     int h= line->getH();
3597     int w= line->getW();
3598 
3599 	//const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f);
3600 
3601 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
3602 
3603 	//background
3604 	CoreData &coreData= CoreData::getInstance();
3605 	Texture2D *backTexture= line->getHorizontal()? coreData.getHorizontalLineTexture(): coreData.getVerticalLineTexture();
3606 
3607 	glEnable(GL_TEXTURE_2D);
3608 	glEnable(GL_BLEND);
3609 
3610 	glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(backTexture)->getHandle());
3611 
3612 	glBegin(GL_TRIANGLE_STRIP);
3613 		glTexCoord2f(0.f, 0.f);
3614 		glVertex2f(x, y);
3615 
3616 		glTexCoord2f(0.f, 1.f);
3617 		glVertex2f(x, y+h);
3618 
3619 		glTexCoord2f(1.f, 0.f);
3620 		glVertex2f(x+w, y);
3621 
3622 		glTexCoord2f(1.f, 1.f);
3623 		glVertex2f(x+w, y+h);
3624 
3625 	glEnd();
3626 
3627 	glDisable(GL_TEXTURE_2D);
3628     glPopAttrib();
3629 }
3630 
renderScrollBar(const GraphicScrollBar * sb)3631 void Renderer::renderScrollBar(const GraphicScrollBar *sb) {
3632 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3633 		return;
3634 	}
3635 
3636 	if(sb->getVisible() == false) {
3637 		return;
3638 	}
3639 
3640     int x= sb->getX();
3641     int y= sb->getY();
3642     int h= sb->getH();
3643     int w= sb->getW();
3644 
3645 	//const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f);
3646 
3647 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT);
3648 	/////////////////////
3649 	//background
3650 	////////////////////
3651 	CoreData &coreData= CoreData::getInstance();
3652 	Texture2D *backTexture= coreData.getHorizontalLineTexture();
3653 
3654 	glEnable(GL_TEXTURE_2D);
3655 	glEnable(GL_BLEND);
3656 
3657 	glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(backTexture)->getHandle());
3658 
3659 	glBegin(GL_TRIANGLE_STRIP);
3660 		glTexCoord2f(0.f, 0.f);
3661 		glVertex2f(x, y);
3662 
3663 		glTexCoord2f(0.f, 1.f);
3664 		glVertex2f(x, y+h);
3665 
3666 		glTexCoord2f(1.f, 0.f);
3667 		glVertex2f(x+w, y);
3668 
3669 		glTexCoord2f(1.f, 1.f);
3670 		glVertex2f(x+w, y+h);
3671 
3672 	glEnd();
3673 
3674 	////////////////////
3675 	// selectBlock
3676 	////////////////////
3677 
3678     x= sb->getX();
3679     y= sb->getY();
3680     h= sb->getH();
3681     w= sb->getW();
3682 
3683     if( sb->getHorizontal()) {
3684     	x=x+sb->getVisibleCompPosStart();
3685     	w=sb->getVisibleCompPosEnd()-sb->getVisibleCompPosStart();
3686     }
3687     else {
3688     	y=y+sb->getVisibleCompPosStart();
3689     	h=sb->getVisibleCompPosEnd()-sb->getVisibleCompPosStart();
3690     }
3691 
3692 	Texture2D *selectTexture= coreData.getButtonBigTexture();
3693 	assert(selectTexture != NULL);
3694 
3695 	glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(selectTexture)->getHandle());
3696 
3697 	//button
3698 	Vec4f fontColor;
3699 	//if(game!=NULL){
3700 	//	fontColor=game->getGui()->getDisplay()->getColor();
3701 	//	fontColor.w = GraphicComponent::getFade();
3702 	//}
3703 	//else {
3704 		// white shadowed is default ( in the menu for example )
3705 		fontColor=Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade());
3706 	//}
3707 
3708 	//Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade());
3709 	Vec4f color= fontColor;
3710 	glColor4fv(color.ptr());
3711 
3712 	glBegin(GL_TRIANGLE_STRIP);
3713 		glTexCoord2f(0.f, 0.f);
3714 		glVertex2f(x, y);
3715 
3716 		glTexCoord2f(0.f, 1.f);
3717 		glVertex2f(x, y+h);
3718 
3719 		glTexCoord2f(1.f, 0.f);
3720 		glVertex2f(x+w, y);
3721 
3722 		glTexCoord2f(1.f, 1.f);
3723 		glVertex2f(x+w, y+h);
3724 
3725 	glEnd();
3726 
3727 	glDisable(GL_TEXTURE_2D);
3728 
3729 	//lighting
3730 	float anim= GraphicComponent::getAnim();
3731 	if(anim>0.5f) anim= 1.f-anim;
3732 
3733 	if(sb->getLighted() && sb->getEditable()){
3734 		const int lightSize= 0;
3735 		const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f);
3736 		const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim);
3737 
3738 		glBegin(GL_TRIANGLE_FAN);
3739 
3740 		glColor4fv(color2.ptr());
3741 		glVertex2f(x+w/2, y+h/2);
3742 
3743 		glColor4fv(color1.ptr());
3744 		glVertex2f(x-lightSize, y-lightSize);
3745 
3746 		glColor4fv(color1.ptr());
3747 		glVertex2f(x+w+lightSize, y-lightSize);
3748 
3749 		glColor4fv(color1.ptr());
3750 		glVertex2f(x+w+lightSize, y+h+lightSize);
3751 
3752 		glColor4fv(color1.ptr());
3753 		glVertex2f(x+w+lightSize, y+h+lightSize);
3754 
3755 		glColor4fv(color1.ptr());
3756 		glVertex2f(x-lightSize, y+h+lightSize);
3757 
3758 		glColor4fv(color1.ptr());
3759 		glVertex2f(x-lightSize, y-lightSize);
3760 
3761 		glEnd();
3762 	}
3763 
3764     glPopAttrib();
3765 }
3766 
renderListBox(GraphicListBox * listBox)3767 void Renderer::renderListBox(GraphicListBox *listBox) {
3768 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3769 		return;
3770 	}
3771 
3772 	if(listBox->getVisible() == false) {
3773 		return;
3774 	}
3775 	//if(listBox->getLeftControlled()==true)
3776 	{
3777 	    int x= listBox->getX();
3778 	    int y= listBox->getY();
3779 	    int h= listBox->getH();
3780 	    int w= listBox->getW();
3781 	    if(h>0){
3782 	    	//background
3783 	    	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3784 	    	glEnable(GL_BLEND);
3785 
3786 	    	glColor4f(0.0f, 0.0f, 0.0f, 0.6f*listBox->getFade()) ;
3787 
3788 	    	glBegin(GL_TRIANGLE_STRIP);
3789 	    		glVertex2i(x, y);
3790 	    		glVertex2i(x, y+h);
3791 	    		glVertex2i(x+w, y);
3792 	    		glVertex2i(x+w, y+h);
3793 	    	glEnd();
3794 	    	glPopAttrib();
3795 	    }
3796 	}
3797 	renderButton(listBox->getButton1());
3798     renderButton(listBox->getButton2());
3799 
3800 	glPushAttrib(GL_ENABLE_BIT);
3801 	glEnable(GL_BLEND);
3802 
3803 	GraphicLabel label("ListBox_render_label","label",false);
3804 	//label.setInstanceName("ListBox_render_label");
3805 	if(listBox->getLeftControlled()==true){
3806 		label.init(listBox->getX()+listBox->getButton1()->getW()+listBox->getButton2()->getW()+2, listBox->getY(), listBox->getW(), listBox->getH(), false,listBox->getTextColor());
3807 	}
3808 	else {
3809 		label.init(listBox->getX(), listBox->getY(), listBox->getW(), listBox->getH(), true,listBox->getTextColor());
3810 	}
3811 	label.setText(listBox->getText());
3812 	label.setTextNativeTranslation(listBox->getTextNativeTranslation());
3813 	label.setFont(listBox->getFont());
3814 	label.setFont3D(listBox->getFont3D());
3815 	renderLabel(&label);
3816 
3817 
3818 	//lighting
3819 
3820 		bool renderLighted= (listBox->getLighted());
3821 
3822 
3823 		if(renderLighted) {
3824 			float anim= GraphicComponent::getAnim();
3825 			if(anim>0.5f) anim= 1.f-anim;
3826 
3827 			Vec3f color=listBox->getTextColor();
3828 		    int x= listBox->getX()+listBox->getButton1()->getW();
3829 		    int y= listBox->getY();
3830 		    int h= listBox->getH();
3831 		    int w= listBox->getW()-listBox->getButton1()->getW()-listBox->getButton2()->getW();
3832 
3833 			const int lightSize= 0;
3834 			const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f);
3835 			const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim);
3836 
3837 			glBegin(GL_TRIANGLE_FAN);
3838 
3839 			glColor4fv(color2.ptr());
3840 			glVertex2f(x+w/2, y+h/2);
3841 
3842 			glColor4fv(color1.ptr());
3843 			glVertex2f(x-lightSize, y-lightSize);
3844 
3845 			glColor4fv(color1.ptr());
3846 			glVertex2f(x+w+lightSize, y-lightSize);
3847 
3848 			glColor4fv(color1.ptr());
3849 			glVertex2f(x+w+lightSize, y+h+lightSize);
3850 
3851 			glColor4fv(color1.ptr());
3852 			glVertex2f(x+w+lightSize, y+h+lightSize);
3853 
3854 			glColor4fv(color1.ptr());
3855 			glVertex2f(x-lightSize, y+h+lightSize);
3856 
3857 			glColor4fv(color1.ptr());
3858 			glVertex2f(x-lightSize, y-lightSize);
3859 
3860 			glEnd();
3861 		}
3862 
3863 	glPopAttrib();
3864 }
3865 
renderMessageBox(GraphicMessageBox * messageBox)3866 void Renderer::renderMessageBox(GraphicMessageBox *messageBox) {
3867 	const int headerHeight=25;
3868 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
3869 		return;
3870 	}
3871 
3872 	try {
3873 		if(messageBox->getVisible() == false) {
3874 			return;
3875 		}
3876 
3877 		if((renderText3DEnabled == false && messageBox->getFont() == NULL) ||
3878 		   (renderText3DEnabled == true && messageBox->getFont3D() == NULL)) {
3879 			messageBox->setFont(CoreData::getInstance().getMenuFontNormal());
3880 			messageBox->setFont3D(CoreData::getInstance().getMenuFontNormal3D());
3881 		}
3882 
3883 		string wrappedText = messageBox->getText();
3884 		if(messageBox->getAutoWordWrap() == true) {
3885 			if(renderText3DEnabled == false) {
3886 				wrappedText = messageBox->getFont()->getMetrics()->wordWrapText(wrappedText,messageBox->getW() * 0.90);
3887 			}
3888 			else {
3889 				wrappedText = messageBox->getFont3D()->getMetrics()->wordWrapText(wrappedText,messageBox->getW() * 0.90);
3890 			}
3891 		}
3892 
3893 		//background
3894 		glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
3895 		glEnable(GL_BLEND);
3896 
3897 		glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
3898 		glBegin(GL_TRIANGLE_STRIP);
3899 			glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight);
3900 			glVertex2i(messageBox->getX(), messageBox->getY());
3901 			glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight);
3902 			glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY());
3903 		glEnd();
3904 
3905 		glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
3906 		glBegin(GL_TRIANGLE_STRIP);
3907 			glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH());
3908 			glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight);
3909 			glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH());
3910 			glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+messageBox->getH()-headerHeight);
3911 		glEnd();
3912 
3913 		glBegin(GL_LINE_LOOP);
3914 			glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
3915 			glVertex2i(messageBox->getX(), messageBox->getY());
3916 
3917 			glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ;
3918 			glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY());
3919 
3920 			glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
3921 			glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH());
3922 
3923 			glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ;
3924 			glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH());
3925 		glEnd();
3926 
3927 		glBegin(GL_LINE_STRIP);
3928 			glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ;
3929 			glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()-headerHeight);
3930 
3931 			glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
3932 			glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight);
3933 		glEnd();
3934 
3935 		glPopAttrib();
3936 
3937 
3938 		//buttons
3939 		for(int i=0; i<messageBox->getButtonCount();i++){
3940 
3941 			if((renderText3DEnabled == false && messageBox->getButton(i)->getFont() == NULL) ||
3942 			   (renderText3DEnabled == true && messageBox->getButton(i)->getFont3D() == NULL)) {
3943 				messageBox->getButton(i)->setFont(CoreData::getInstance().getMenuFontNormal());
3944 				messageBox->getButton(i)->setFont3D(CoreData::getInstance().getMenuFontNormal3D());
3945 			}
3946 
3947 			renderButton(messageBox->getButton(i));
3948 		}
3949 
3950 		Vec4f fontColor;
3951 		//if(game!=NULL){
3952 		//	fontColor=game->getGui()->getDisplay()->getColor();
3953 		//}
3954 		//else {
3955 			// white shadowed is default ( in the menu for example )
3956 			fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f);
3957 		//}
3958 
3959 		if(renderText3DEnabled == true) {
3960 			//text
3961 			renderTextShadow3D(
3962 					wrappedText, messageBox->getFont3D(), fontColor,
3963 				messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2,
3964 				false );
3965 
3966 			renderTextShadow3D(
3967 				messageBox->getHeader(), messageBox->getFont3D(),fontColor,
3968 				messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8,
3969 				false );
3970 
3971 		}
3972 		else {
3973 			//text
3974 			renderTextShadow(
3975 					wrappedText, messageBox->getFont(), fontColor,
3976 				messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2,
3977 				false );
3978 
3979 			renderTextShadow(
3980 				messageBox->getHeader(), messageBox->getFont(),fontColor,
3981 				messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8,
3982 				false );
3983 		}
3984 	}
3985 	catch(const exception &e) {
3986 		char szBuf[8096]="";
3987 		snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what());
3988 		SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
3989 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf);
3990 
3991 		throw megaglest_runtime_error(szBuf);
3992 	}
3993 }
3994 
3995 // ==================== complex rendering ====================
3996 
GetSurfaceVBOs(SurfaceData * cellData)3997 VisibleQuadContainerVBOCache * Renderer::GetSurfaceVBOs(SurfaceData *cellData) {
3998 	std::map<uint32,VisibleQuadContainerVBOCache >::iterator iterFind = mapSurfaceVBOCache.find(cellData->uniqueId);
3999 	if(iterFind == mapSurfaceVBOCache.end()) {
4000 		Vec2f *texCoords		= &cellData->texCoords[0];
4001 		Vec2f *texCoordsSurface	= &cellData->texCoordsSurface[0];
4002 		Vec3f *vertices			= &cellData->vertices[0];
4003 		Vec3f *normals			= &cellData->normals[0];
4004 
4005 		VisibleQuadContainerVBOCache vboCache;
4006 
4007 		// Generate And Bind The Vertex Buffer
4008 		glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOVertices );					// Get A Valid Name
4009 		glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOVertices );			// Bind The Buffer
4010 		// Load The Data
4011 		glBufferDataARB( GL_ARRAY_BUFFER_ARB,  sizeof(Vec3f) * cellData->bufferCount, vertices, GL_STATIC_DRAW_ARB );
4012 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
4013 
4014 		assertGl();
4015 		// Generate And Bind The Texture Coordinate Buffer
4016 		glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOFowTexCoords );					// Get A Valid Name
4017 		glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOFowTexCoords );		// Bind The Buffer
4018 		// Load The Data
4019 		glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoords, GL_STATIC_DRAW_ARB );
4020 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
4021 
4022 		assertGl();
4023 		// Generate And Bind The Texture Coordinate Buffer
4024 		glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOSurfaceTexCoords );					// Get A Valid Name
4025 		glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOSurfaceTexCoords );		// Bind The Buffer
4026 		// Load The Data
4027 		glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoordsSurface, GL_STATIC_DRAW_ARB );
4028 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
4029 
4030 		assertGl();
4031 		// Generate And Bind The Normal Buffer
4032 		glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBONormals );					// Get A Valid Name
4033 		glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBONormals );			// Bind The Buffer
4034 		// Load The Data
4035 		glBufferDataARB( GL_ARRAY_BUFFER_ARB,  sizeof(Vec3f) * cellData->bufferCount, normals, GL_STATIC_DRAW_ARB );
4036 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
4037 
4038 		vboCache.hasBuiltVBOs = true;
4039 
4040 		mapSurfaceVBOCache[cellData->uniqueId] = vboCache;
4041 
4042 		// don't need the data in computer RAM anymore its in the GPU now
4043 		cellData->texCoords.clear();
4044 		cellData->texCoordsSurface.clear();
4045 		cellData->vertices.clear();
4046 		cellData->normals.clear();
4047 	}
4048 
4049 	return &mapSurfaceVBOCache[cellData->uniqueId];
4050 }
4051 
ReleaseSurfaceVBOs()4052 void Renderer::ReleaseSurfaceVBOs() {
4053 	for(std::map<uint32,VisibleQuadContainerVBOCache>::iterator iterFind = mapSurfaceVBOCache.begin();
4054 			iterFind != mapSurfaceVBOCache.end(); ++iterFind) {
4055 
4056 		VisibleQuadContainerVBOCache &item = iterFind->second;
4057 		if(item.hasBuiltVBOs == true) {
4058 			glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOVertices );					// Get A Valid Name
4059 			glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOFowTexCoords );					// Get A Valid Name
4060 			glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOSurfaceTexCoords );					// Get A Valid Name
4061 			glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBONormals );					// Get A Valid Name
4062 			//glDeleteBuffersARB( 1, &item.m_nVBOIndexes );					// Get A Valid Name
4063 		}
4064 	}
4065 
4066 	mapSurfaceVBOCache.clear();
4067 }
4068 
~Layer()4069 Renderer::MapRenderer::Layer::~Layer() {
4070 	if(vbo_vertices) glDeleteBuffersARB(1,&vbo_vertices);
4071 	if(vbo_normals) glDeleteBuffersARB(1,&vbo_normals);
4072 	if(vbo_fowTexCoords) glDeleteBuffersARB(1,&vbo_fowTexCoords);
4073 	if(vbo_surfTexCoords) glDeleteBuffersARB(1,&vbo_surfTexCoords);
4074 	if(vbo_indices) glDeleteBuffersARB(1,&vbo_indices);
4075 
4076 }
4077 
_loadVBO(GLuint & vbo,std::vector<T> buf,int target=GL_ARRAY_BUFFER_ARB)4078 template<typename T> void _loadVBO(GLuint &vbo,std::vector<T> buf,int target=GL_ARRAY_BUFFER_ARB) {
4079 	assert(buf.size());
4080 	if(true /* vbo enabled? */) {
4081 		glGenBuffersARB(1,&vbo);
4082 		assert(vbo);
4083 		glBindBufferARB(target,vbo);
4084 		glBufferDataARB(target,sizeof(T)*buf.size(),&buf[0],GL_STATIC_DRAW_ARB);
4085 		glBindBufferARB(target,0);
4086 		assertGl();
4087 		buf.clear();
4088 	}
4089 }
4090 
load_vbos(bool vboEnabled)4091 void Renderer::MapRenderer::Layer::load_vbos(bool vboEnabled) {
4092 	indexCount = (int)indices.size();
4093 	if(vboEnabled) {
4094 		_loadVBO(vbo_vertices,vertices);
4095 		_loadVBO(vbo_normals,normals);
4096 		_loadVBO(vbo_fowTexCoords,fowTexCoords);
4097 		_loadVBO(vbo_surfTexCoords,surfTexCoords);
4098 
4099 		_loadVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB);
4100 	}
4101 	else {
4102 		vbo_vertices = 0;
4103 		vbo_normals = 0;
4104 		vbo_fowTexCoords = 0;
4105 		vbo_surfTexCoords = 0;
4106 		vbo_indices = 0;
4107 	}
4108 }
4109 
loadVisibleLayers(float coordStep,VisibleQuadContainerCache & qCache)4110 void Renderer::MapRenderer::loadVisibleLayers(float coordStep,VisibleQuadContainerCache &qCache) {
4111 	int totalCellCount = 0;
4112 	// we create a layer for each visible texture in the map
4113 	for(int visibleIndex = 0;
4114 			visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) {
4115 		Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
4116 
4117 		totalCellCount++;
4118 
4119 		SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y);
4120 		SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y);
4121 		SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1);
4122 		SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1);
4123 
4124 		const Vec2f &surfCoord= tc00->getSurfTexCoord();
4125 
4126 		SurfaceCell *tc[4] = {
4127 				tc00,
4128 				tc10,
4129 				tc01,
4130 				tc11
4131 		};
4132 		int textureHandle = static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture())->getHandle();
4133 		string texturePath = static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture())->getPath();
4134 		//int32 textureCRC = CalculatePixelsCRC(static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture()));
4135 		Layer* layer = NULL;
4136 		for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) {
4137 			if((*it)->textureHandle == textureHandle) {
4138 			//if((*it)->texturePath == texturePath) {
4139 			//if((*it)->textureCRC == textureCRC) {
4140 				layer = *it;
4141 				break;
4142 			}
4143 		}
4144 		if(!layer) {
4145 			layer = new Layer(textureHandle);
4146 			layer->texturePath = texturePath;
4147 			//layer->textureCRC = textureCRC;
4148 			layers.push_back(layer);
4149 
4150 			//printf("Ading new unique texture [%s]\n",texturePath.c_str());
4151 		}
4152 		// we'll be super-lazy and re-emit all four corners just because its easier
4153 		int index[4];
4154 		int loopIndexes[4] = { 2,0,3,1 };
4155 		for(int i=0; i < 4; i++) {
4156 			index[i] = (int)layer->vertices.size();
4157 			SurfaceCell *corner = tc[loopIndexes[i]];
4158 
4159 			layer->vertices.push_back(corner->getVertex());
4160 			layer->normals.push_back(corner->getNormal());
4161 			layer->fowTexCoords.push_back(corner->getFowTexCoord());
4162 		}
4163 
4164 		layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep));
4165 		layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y));
4166 		layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep));
4167 		layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y));
4168 
4169 		// and make two triangles (no strip, we may be disjoint)
4170 		layer->indices.push_back(index[0]);
4171 		layer->indices.push_back(index[1]);
4172 		layer->indices.push_back(index[2]);
4173 		layer->indices.push_back(index[1]);
4174 		layer->indices.push_back(index[3]);
4175 		layer->indices.push_back(index[2]);
4176 
4177 	}
4178 	// turn them into vbos (actually this method will just calc the index count)
4179 	for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){
4180 		(*layer)->load_vbos(false);
4181 	}
4182 
4183 	//printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size()));
4184 }
4185 
load(float coordStep)4186 void Renderer::MapRenderer::load(float coordStep) {
4187 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4188 		return;
4189 	}
4190 
4191 	int totalCellCount = 0;
4192 	// we create a layer for each texture in the map
4193 	for(int y=0; y<map->getSurfaceH()-1; y++) {
4194 		for(int x=0; x<map->getSurfaceW()-1; x++) {
4195 			totalCellCount++;
4196 
4197 			SurfaceCell *tc[4] = {
4198 				map->getSurfaceCell(x,y),
4199 				map->getSurfaceCell(x+1,y),
4200 				map->getSurfaceCell(x,y+1),
4201 				map->getSurfaceCell(x+1,y+1)
4202 			};
4203 			int textureHandle = static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture())->getHandle();
4204 			string texturePath = static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture())->getPath();
4205 			//int32 textureCRC = CalculatePixelsCRC(static_cast<const Texture2DGl*>(tc[0]->getSurfaceTexture()));
4206 			Layer* layer = NULL;
4207 			for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) {
4208 				if((*it)->textureHandle == textureHandle) {
4209 				//if((*it)->texturePath == texturePath) {
4210 				//if((*it)->textureCRC == textureCRC) {
4211 					layer = *it;
4212 					break;
4213 				}
4214 			}
4215 			if(!layer) {
4216 				layer = new Layer(textureHandle);
4217 				layer->texturePath = texturePath;
4218 				//layer->textureCRC = textureCRC;
4219 				layers.push_back(layer);
4220 
4221 				//printf("Ading new unique texture [%s]\n",texturePath.c_str());
4222 			}
4223 			// we'll be super-lazy and re-emit all four corners just because its easier
4224 			int index[4];
4225 			int loopIndexes[4] = { 2,0,3,1 };
4226 			for(int i=0; i < 4; i++) {
4227 				index[i] = (int)layer->vertices.size();
4228 				SurfaceCell *corner = tc[loopIndexes[i]];
4229 				layer->vertices.push_back(corner->getVertex());
4230 				layer->normals.push_back(corner->getNormal());
4231 			}
4232 
4233 			// the texture coords are all on the current texture obviously
4234 			layer->fowTexCoords.push_back(tc[loopIndexes[0]]->getFowTexCoord());
4235 			layer->fowTexCoords.push_back(tc[loopIndexes[1]]->getFowTexCoord());
4236 			layer->fowTexCoords.push_back(tc[loopIndexes[2]]->getFowTexCoord());
4237 			layer->fowTexCoords.push_back(tc[loopIndexes[3]]->getFowTexCoord());
4238 
4239 			layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,coordStep));
4240 			layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,0));
4241 			layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,coordStep));
4242 			layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,0));
4243 
4244 			layer->cellToIndicesMap[Vec2i(x,y)] = (int)layer->indices.size();
4245 
4246 			// and make two triangles (no strip, we may be disjoint)
4247 			layer->indices.push_back(index[0]);
4248 			layer->indices.push_back(index[1]);
4249 			layer->indices.push_back(index[2]);
4250 			layer->indices.push_back(index[1]);
4251 			layer->indices.push_back(index[3]);
4252 			layer->indices.push_back(index[2]);
4253 		}
4254 	}
4255 	// turn them into vbos
4256 	for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){
4257 		(*layer)->load_vbos(true);
4258 	}
4259 
4260 	//printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size()));
4261 }
4262 
_bindVBO(GLuint vbo,std::vector<T> & buf,int target=GL_ARRAY_BUFFER_ARB)4263 template<typename T> void* _bindVBO(GLuint vbo,std::vector<T> &buf,int target=GL_ARRAY_BUFFER_ARB) {
4264 	void* result = NULL;
4265 	if(vbo) {
4266 		glBindBuffer(target,vbo);
4267 	}
4268 	else {
4269 		result = &buf[0];
4270 	}
4271 	return result;
4272 }
4273 
renderVisibleLayer()4274 void Renderer::MapRenderer::Layer::renderVisibleLayer() {
4275 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4276 		return;
4277 	}
4278 
4279 	//glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
4280 	glClientActiveTexture(Renderer::fowTexUnit);
4281 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4282 	glTexCoordPointer(2, GL_FLOAT, 0,&fowTexCoords[0]);
4283 
4284 	glBindTexture(GL_TEXTURE_2D, textureHandle);
4285 	glClientActiveTexture(Renderer::baseTexUnit);
4286 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4287 	glTexCoordPointer(2, GL_FLOAT, 0, &surfTexCoords[0]);
4288 
4289 	glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
4290 	glNormalPointer(GL_FLOAT, 0, &normals[0]);
4291 
4292 	//glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
4293 	//unsigned short faceIndices[4] = {0, 1, 2, 3};
4294 	//glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]);
4295 	glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,&indices[0]);
4296 
4297 	glClientActiveTexture(Renderer::fowTexUnit);
4298 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4299 	glClientActiveTexture(Renderer::baseTexUnit);
4300 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4301 }
4302 
render(VisibleQuadContainerCache & qCache)4303 void Renderer::MapRenderer::Layer::render(VisibleQuadContainerCache &qCache) {
4304 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4305 		return;
4306 	}
4307 
4308 	const bool renderOnlyVisibleQuad = true;
4309 
4310 	if(renderOnlyVisibleQuad == true) {
4311 		vector<pair<int,int> > rowsToRender;
4312 
4313 		if(rowsToRenderCache.find(qCache.lastVisibleQuad) != rowsToRenderCache.end()) {
4314 			rowsToRender = rowsToRenderCache[qCache.lastVisibleQuad];
4315 		}
4316 		else {
4317 			int startIndex = -1;
4318 			int lastValidIndex = -1;
4319 
4320 			for(int visibleIndex = 0;
4321 					visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) {
4322 				Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
4323 
4324 				if(cellToIndicesMap.find(pos) != cellToIndicesMap.end()) {
4325 					//printf("Layer Render, visibleindex = %d pos [%s] cellToIndicesMap[pos] = %d lastValidIndex = %d\n",visibleIndex,pos.getString().c_str(),cellToIndicesMap[pos],lastValidIndex);
4326 
4327 					if(startIndex < 0 || cellToIndicesMap[pos] == lastValidIndex + 6) {
4328 						lastValidIndex = cellToIndicesMap[pos];
4329 						if(startIndex < 0) {
4330 							startIndex = lastValidIndex;
4331 						}
4332 					}
4333 					else if(startIndex >= 0) {
4334 						rowsToRender.push_back(make_pair(startIndex,lastValidIndex));
4335 
4336 						lastValidIndex = cellToIndicesMap[pos];
4337 						startIndex = lastValidIndex;
4338 					}
4339 				}
4340 			}
4341 			if(startIndex >= 0) {
4342 				rowsToRender.push_back(make_pair(startIndex,lastValidIndex));
4343 			}
4344 
4345 			rowsToRenderCache[qCache.lastVisibleQuad] = rowsToRender;
4346 		}
4347 
4348 		if(rowsToRender.empty() == false) {
4349 			//printf("Layer has %d rows in visible quad, visible quad has %d cells\n",rowsToRender.size(),qCache.visibleScaledCellList.size());
4350 
4351 			glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices));
4352 			glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals));
4353 
4354 			glClientActiveTexture(Renderer::fowTexUnit);
4355 			glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords));
4356 
4357 			glClientActiveTexture(Renderer::baseTexUnit);
4358 			glBindTexture(GL_TEXTURE_2D,textureHandle);
4359 			glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords));
4360 
4361 			for(unsigned int i = 0; i < rowsToRender.size(); ++i) {
4362 				//glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB));
4363 				glDrawRangeElements(GL_TRIANGLES,rowsToRender[i].first,rowsToRender[i].second,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB));
4364 			}
4365 		}
4366 	}
4367 	else {
4368 		glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices));
4369 		glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals));
4370 
4371 		glClientActiveTexture(Renderer::fowTexUnit);
4372 		glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords));
4373 
4374 		glClientActiveTexture(Renderer::baseTexUnit);
4375 		glBindTexture(GL_TEXTURE_2D,textureHandle);
4376 		glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords));
4377 
4378 		glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB));
4379 	}
4380 }
4381 
renderVisibleLayers(const Map * map,float coordStep,VisibleQuadContainerCache & qCache)4382 void Renderer::MapRenderer::renderVisibleLayers(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) {
4383 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4384 		return;
4385 	}
4386 
4387 	if(map != this->map) {
4388 		//printf("New Map loading\n");
4389 		destroy(); // clear any previous map data
4390 		this->map = map;
4391 		loadVisibleLayers(coordStep,qCache);
4392 	}
4393 	else if(lastVisibleQuad != qCache.lastVisibleQuad) {
4394 		//printf("New Visible Quad loading\n");
4395 		destroy(); // clear any previous map data
4396 		this->map = map;
4397 		loadVisibleLayers(coordStep,qCache);
4398 	}
4399 
4400 	lastVisibleQuad = qCache.lastVisibleQuad;
4401 	//printf("About to render %d layers\n",layers.size());
4402 
4403 	glClientActiveTexture(fowTexUnit);
4404 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4405 	glClientActiveTexture(baseTexUnit);
4406 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4407 	glEnableClientState(GL_VERTEX_ARRAY);
4408 	glEnableClientState(GL_NORMAL_ARRAY);
4409 	for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer)
4410 		(*layer)->renderVisibleLayer();
4411 	glDisableClientState(GL_VERTEX_ARRAY);
4412 	glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
4413 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
4414 	glDisableClientState(GL_NORMAL_ARRAY);
4415 	glClientActiveTexture(fowTexUnit);
4416 	glBindTexture(GL_TEXTURE_2D,0);
4417 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4418 	glClientActiveTexture(baseTexUnit);
4419 	glBindTexture(GL_TEXTURE_2D,0);
4420 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4421 	assertGl();
4422 }
4423 
render(const Map * map,float coordStep,VisibleQuadContainerCache & qCache)4424 void Renderer::MapRenderer::render(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) {
4425 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4426 		return;
4427 	}
4428 
4429 	if(map != this->map) {
4430 		destroy(); // clear any previous map data
4431 		this->map = map;
4432 		load(coordStep);
4433 	}
4434 
4435 	//printf("About to render %d layers\n",layers.size());
4436 
4437 	glClientActiveTexture(fowTexUnit);
4438 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4439 	glClientActiveTexture(baseTexUnit);
4440 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4441 	glEnableClientState(GL_VERTEX_ARRAY);
4442 	glEnableClientState(GL_NORMAL_ARRAY);
4443 	for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer)
4444 		(*layer)->render(qCache);
4445 	glDisableClientState(GL_VERTEX_ARRAY);
4446 	glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
4447 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
4448 	glDisableClientState(GL_NORMAL_ARRAY);
4449 	glClientActiveTexture(fowTexUnit);
4450 	glBindTexture(GL_TEXTURE_2D,0);
4451 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4452 	glClientActiveTexture(baseTexUnit);
4453 	glBindTexture(GL_TEXTURE_2D,0);
4454 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4455 	assertGl();
4456 }
4457 
destroy()4458 void Renderer::MapRenderer::destroy() {
4459 	while(layers.empty() == false) {
4460 		delete layers.back();
4461 		layers.pop_back();
4462 	}
4463 	map = NULL;
4464 }
4465 
renderSurface(const int renderFps)4466 void Renderer::renderSurface(const int renderFps) {
4467 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4468 		return;
4469 	}
4470 
4471 	IF_DEBUG_EDITION(
4472 		if (getDebugRenderer().willRenderSurface()) {
4473 			getDebugRenderer().renderSurface(visibleQuad / Map::cellScale);
4474 		} else {
4475 	)
4476 	assertGl();
4477 
4478 	const World *world= game->getWorld();
4479 	const Map *map= world->getMap();
4480 	float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep();
4481 
4482 	const Texture2D *fowTex= world->getMinimap()->getFowTexture();
4483 	if(fowTex == NULL) {
4484 		return;
4485 	}
4486 
4487 	glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT);
4488 
4489 	glEnable(GL_BLEND);
4490 	glEnable(GL_COLOR_MATERIAL);
4491 	glDisable(GL_ALPHA_TEST);
4492 	glEnable(GL_CULL_FACE);
4493 
4494 	//fog of war tex unit
4495 	glActiveTexture(fowTexUnit);
4496 	glEnable(GL_TEXTURE_2D);
4497 	glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
4498 
4499 	glTexSubImage2D(
4500 		GL_TEXTURE_2D, 0, 0, 0,
4501 		fowTex->getPixmapConst()->getW(), fowTex->getPixmapConst()->getH(),
4502 		GL_ALPHA, GL_UNSIGNED_BYTE, fowTex->getPixmapConst()->getPixels());
4503 
4504 	if(shadowsOffDueToMinRender == false) {
4505 		//shadow texture
4506 		if(shadows == sProjected || shadows == sShadowMapping) {
4507 			glActiveTexture(shadowTexUnit);
4508 			glEnable(GL_TEXTURE_2D);
4509 
4510 			glBindTexture(GL_TEXTURE_2D, shadowMapHandle);
4511 
4512 			static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
4513 			enableProjectiveTexturing();
4514 		}
4515 	}
4516 
4517 	const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
4518 
4519 	glActiveTexture(baseTexUnit);
4520 
4521 	VisibleQuadContainerCache &qCache = getQuadCache();
4522 
4523 	bool useVBORendering = getVBOSupported();
4524 	if(useVBORendering == true) {
4525 		VisibleQuadContainerCache &qCache = getQuadCache();
4526 		//mapRenderer.render(map,coordStep,qCache);
4527 		mapRenderer.renderVisibleLayers(map,coordStep,qCache);
4528 	}
4529 	else if(qCache.visibleScaledCellList.empty() == false) {
4530 
4531 		int lastTex=-1;
4532 		//int currTex=-1;
4533 
4534 		//Quad2i snapshotOfvisibleQuad = visibleQuad;
4535 
4536 		//bool useVertexArrayRendering = getVBOSupported();
4537 		//bool useVertexArrayRendering = false;
4538 		//if(useVertexArrayRendering == false) {
4539 		    //printf("\LEGACY qCache.visibleScaledCellList.size() = %d \n",qCache.visibleScaledCellList.size());
4540 
4541 			Vec2f texCoords[4];
4542 			Vec2f texCoordsSurface[4];
4543 			Vec3f vertices[4];
4544 			Vec3f normals[4];
4545 		    glEnableClientState(GL_VERTEX_ARRAY);
4546 		    glEnableClientState(GL_NORMAL_ARRAY);
4547 
4548 		    std::map<int,int> uniqueVisibleTextures;
4549 			for(int visibleIndex = 0;
4550 					visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) {
4551 				Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
4552 				SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y);
4553 				int cellTex= static_cast<const Texture2DGl*>(tc00->getSurfaceTexture())->getHandle();
4554 
4555 				uniqueVisibleTextures[cellTex]++;
4556 			}
4557 
4558 			//printf("Current renders = %d possible = %d\n",qCache.visibleScaledCellList.size(),uniqueVisibleTextures.size());
4559 
4560 			for(int visibleIndex = 0;
4561 					visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) {
4562 				Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
4563 
4564 				SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y);
4565 				SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y);
4566 				SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1);
4567 				SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1);
4568 
4569 				if(tc00 == NULL) {
4570 					throw megaglest_runtime_error("tc00 == NULL");
4571 				}
4572 				if(tc10 == NULL) {
4573 					throw megaglest_runtime_error("tc10 == NULL");
4574 				}
4575 				if(tc01 == NULL) {
4576 					throw megaglest_runtime_error("tc01 == NULL");
4577 				}
4578 				if(tc11 == NULL) {
4579 					throw megaglest_runtime_error("tc11 == NULL");
4580 				}
4581 
4582 				triangleCount+= 2;
4583 				pointCount+= 4;
4584 
4585 				//set texture
4586 				if(tc00->getSurfaceTexture() == NULL) {
4587 					throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL");
4588 				}
4589 				int currTex= static_cast<const Texture2DGl*>(tc00->getSurfaceTexture())->getHandle();
4590 				if(currTex != lastTex) {
4591 					lastTex = currTex;
4592 					//glBindTexture(GL_TEXTURE_2D, lastTex);
4593 				}
4594 
4595 				const Vec2f &surfCoord= tc00->getSurfTexCoord();
4596 
4597 				texCoords[0]		= tc01->getFowTexCoord();
4598 				texCoordsSurface[0]	= Vec2f(surfCoord.x, surfCoord.y + coordStep);
4599 				vertices[0]			= tc01->getVertex();
4600 				normals[0]			= tc01->getNormal();;
4601 
4602 				texCoords[1]		= tc00->getFowTexCoord();
4603 				texCoordsSurface[1]	= Vec2f(surfCoord.x, surfCoord.y);
4604 				vertices[1]			= tc00->getVertex();
4605 				normals[1]			= tc00->getNormal();
4606 
4607 				texCoords[2]		= tc11->getFowTexCoord();
4608 				texCoordsSurface[2]	= Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep);
4609 				vertices[2]			= tc11->getVertex();
4610 				normals[2]			= tc11->getNormal();
4611 
4612 				texCoords[3]		= tc10->getFowTexCoord();
4613 				texCoordsSurface[3]	= Vec2f(surfCoord.x+coordStep, surfCoord.y);
4614 				vertices[3]			= tc10->getVertex();
4615 				normals[3]			= tc10->getNormal();
4616 
4617 				//glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
4618 				glClientActiveTexture(fowTexUnit);
4619 				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4620 				glTexCoordPointer(2, GL_FLOAT, 0,&texCoords[0]);
4621 
4622 				glBindTexture(GL_TEXTURE_2D, lastTex);
4623 				glClientActiveTexture(baseTexUnit);
4624 				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4625 				glTexCoordPointer(2, GL_FLOAT, 0, &texCoordsSurface[0]);
4626 
4627 				glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
4628 				glNormalPointer(GL_FLOAT, 0, &normals[0]);
4629 
4630 				glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4631 				//unsigned short faceIndices[4] = {0, 1, 2, 3};
4632 				//glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]);
4633 
4634 				glClientActiveTexture(fowTexUnit);
4635 				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4636 				glClientActiveTexture(baseTexUnit);
4637 				glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4638 
4639 /*
4640 				glBegin(GL_TRIANGLE_STRIP);
4641 
4642 				//draw quad using immediate mode
4643 				glMultiTexCoord2fv(fowTexUnit, tc01->getFowTexCoord().ptr());
4644 				glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y + coordStep);
4645 				glNormal3fv(tc01->getNormal().ptr());
4646 				glVertex3fv(tc01->getVertex().ptr());
4647 
4648 				glMultiTexCoord2fv(fowTexUnit, tc00->getFowTexCoord().ptr());
4649 				glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y);
4650 				glNormal3fv(tc00->getNormal().ptr());
4651 				glVertex3fv(tc00->getVertex().ptr());
4652 
4653 				glMultiTexCoord2fv(fowTexUnit, tc11->getFowTexCoord().ptr());
4654 				glMultiTexCoord2f(baseTexUnit, surfCoord.x+coordStep, surfCoord.y+coordStep);
4655 				glNormal3fv(tc11->getNormal().ptr());
4656 				glVertex3fv(tc11->getVertex().ptr());
4657 
4658 				glMultiTexCoord2fv(fowTexUnit, tc10->getFowTexCoord().ptr());
4659 				glMultiTexCoord2f(baseTexUnit, surfCoord.x + coordStep, surfCoord.y);
4660 				glNormal3fv(tc10->getNormal().ptr());
4661 				glVertex3fv(tc10->getVertex().ptr());
4662 
4663 				glEnd();
4664 */
4665 			}
4666 
4667 			glDisableClientState(GL_NORMAL_ARRAY);
4668 			glDisableClientState(GL_VERTEX_ARRAY);
4669 
4670 //		}
4671 //		else {
4672 //		    const bool useVBOs = false;
4673 //		    const bool useSurfaceCache = false;
4674 //
4675 //		    std::vector<SurfaceData> surfaceData;
4676 //		    bool recalcSurface = false;
4677 //
4678 //		    if(useSurfaceCache == true) {
4679 //				std::map<string,std::pair<Chrono, std::vector<SurfaceData> > >::iterator iterFind = mapSurfaceData.find(snapshotOfvisibleQuad.getString());
4680 //				if(iterFind == mapSurfaceData.end()) {
4681 //					recalcSurface = true;
4682 //					//printf("#1 Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str());
4683 //				}
4684 ///*
4685 //				else if(iterFind->second.first.getMillis() >= 250) {
4686 //					recalcSurface = true;
4687 //					mapSurfaceData.erase(snapshotOfvisibleQuad.getString());
4688 //					//printf("#2 RE-Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str());
4689 //				}
4690 //*/
4691 //		    }
4692 //		    else {
4693 //		    	recalcSurface = true;
4694 //		    }
4695 //
4696 //		    if(recalcSurface == true) {
4697 //				//printf("Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str());
4698 //
4699 //		    	std::vector<SurfaceData> *surface = &surfaceData;
4700 //		    	if(useSurfaceCache == true) {
4701 //					std::pair<Chrono, std::vector<SurfaceData> > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()];
4702 //					surface = &surfaceCacheEntity.second;
4703 //					//surface.reserve(qCache.visibleScaledCellList.size());
4704 //		    	}
4705 //		    	surface->reserve(qCache.visibleScaledCellList.size());
4706 //
4707 //		    	int lastSurfaceDataIndex = -1;
4708 //				for(int visibleIndex = 0;
4709 //						visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) {
4710 //					Vec2i &pos = qCache.visibleScaledCellList[visibleIndex];
4711 //
4712 //					SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y);
4713 //					SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y);
4714 //					SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1);
4715 //					SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1);
4716 //
4717 //					if(tc00 == NULL) {
4718 //						throw megaglest_runtime_error("tc00 == NULL");
4719 //					}
4720 //					if(tc10 == NULL) {
4721 //						throw megaglest_runtime_error("tc10 == NULL");
4722 //					}
4723 //					if(tc01 == NULL) {
4724 //						throw megaglest_runtime_error("tc01 == NULL");
4725 //					}
4726 //					if(tc11 == NULL) {
4727 //						throw megaglest_runtime_error("tc11 == NULL");
4728 //					}
4729 //
4730 //					triangleCount+= 2;
4731 //					pointCount+= 4;
4732 //
4733 //					//set texture
4734 //					if(tc00->getSurfaceTexture() == NULL) {
4735 //						throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL");
4736 //					}
4737 //
4738 //					int surfaceDataIndex = -1;
4739 //					currTex= static_cast<const Texture2DGl*>(tc00->getSurfaceTexture())->getHandle();
4740 //					if(currTex != lastTex) {
4741 //						lastTex = currTex;
4742 //					}
4743 //					else {
4744 //						surfaceDataIndex = lastSurfaceDataIndex;
4745 //					}
4746 //
4747 //					if(surfaceDataIndex < 0) {
4748 //						SurfaceData newData;
4749 //						newData.uniqueId = SurfaceData::nextUniqueId;
4750 //						SurfaceData::nextUniqueId++;
4751 //						newData.bufferCount=0;
4752 //						newData.textureHandle = currTex;
4753 //						surface->push_back(newData);
4754 //
4755 //						surfaceDataIndex = (int)surface->size() - 1;
4756 //					}
4757 //
4758 //					lastSurfaceDataIndex = surfaceDataIndex;
4759 //
4760 //					SurfaceData *cellData = &(*surface)[surfaceDataIndex];
4761 //
4762 //					const Vec2f &surfCoord= tc00->getSurfTexCoord();
4763 //
4764 //					cellData->texCoords.push_back(tc01->getFowTexCoord());
4765 //					cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep));
4766 //					cellData->vertices.push_back(tc01->getVertex());
4767 //					cellData->normals.push_back(tc01->getNormal());
4768 //					cellData->bufferCount++;
4769 //
4770 //					cellData->texCoords.push_back(tc00->getFowTexCoord());
4771 //					cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y));
4772 //					cellData->vertices.push_back(tc00->getVertex());
4773 //					cellData->normals.push_back(tc00->getNormal());
4774 //					cellData->bufferCount++;
4775 //
4776 //					cellData->texCoords.push_back(tc11->getFowTexCoord());
4777 //					cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep));
4778 //					cellData->vertices.push_back(tc11->getVertex());
4779 //					cellData->normals.push_back(tc11->getNormal());
4780 //					cellData->bufferCount++;
4781 //
4782 //					cellData->texCoords.push_back(tc10->getFowTexCoord());
4783 //					cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y));
4784 //					cellData->vertices.push_back(tc10->getVertex());
4785 //					cellData->normals.push_back(tc10->getNormal());
4786 //					cellData->bufferCount++;
4787 //				}
4788 //			}
4789 //
4790 //		    std::vector<SurfaceData> *surface = &surfaceData;
4791 //		    if(useSurfaceCache == true) {
4792 //		    	std::pair<Chrono, std::vector<SurfaceData> > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()];
4793 //		    	surface = &surfaceCacheEntity.second;
4794 //		    }
4795 //
4796 //		    glEnableClientState(GL_VERTEX_ARRAY);
4797 //		    glEnableClientState(GL_NORMAL_ARRAY);
4798 //
4799 //			for(int i = 0; i < (int)surface->size(); ++i) {
4800 //				SurfaceData &data = (*surface)[i];
4801 //
4802 //				if(useVBOs == true) {
4803 //					VisibleQuadContainerVBOCache *vboCache = GetSurfaceVBOs(&data);
4804 //
4805 //					//glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
4806 //					glClientActiveTexture(fowTexUnit);
4807 //					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4808 //
4809 //					glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOFowTexCoords);
4810 //					glTexCoordPointer(2, GL_FLOAT, 0,(char *) NULL);
4811 //
4812 //					glBindTexture(GL_TEXTURE_2D, data.textureHandle);
4813 //					glClientActiveTexture(baseTexUnit);
4814 //					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4815 //
4816 //					glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOSurfaceTexCoords);
4817 //					glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL);
4818 //
4819 //					glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOVertices);
4820 //					glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
4821 //
4822 //					glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBONormals);
4823 //					glNormalPointer(GL_FLOAT, 0, (char *) NULL);
4824 //
4825 //					glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount);
4826 //
4827 //					glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
4828 //
4829 //					glClientActiveTexture(fowTexUnit);
4830 //					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4831 //					glClientActiveTexture(baseTexUnit);
4832 //					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4833 //
4834 //				}
4835 //				else {
4836 //					Vec2f *texCoords		= &data.texCoords[0];
4837 //					Vec2f *texCoordsSurface	= &data.texCoordsSurface[0];
4838 //					Vec3f *vertices			= &data.vertices[0];
4839 //					Vec3f *normals			= &data.normals[0];
4840 //
4841 //					//glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
4842 //					glClientActiveTexture(fowTexUnit);
4843 //					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4844 //					glTexCoordPointer(2, GL_FLOAT, 0,texCoords);
4845 //
4846 //					glBindTexture(GL_TEXTURE_2D, data.textureHandle);
4847 //					glClientActiveTexture(baseTexUnit);
4848 //					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4849 //					glTexCoordPointer(2, GL_FLOAT, 0, texCoordsSurface);
4850 //
4851 //					glVertexPointer(3, GL_FLOAT, 0, vertices);
4852 //					glNormalPointer(GL_FLOAT, 0, normals);
4853 //
4854 //					glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount);
4855 //
4856 //					glClientActiveTexture(fowTexUnit);
4857 //					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4858 //					glClientActiveTexture(baseTexUnit);
4859 //					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4860 //				}
4861 //			}
4862 //
4863 //			glDisableClientState(GL_NORMAL_ARRAY);
4864 //			glDisableClientState(GL_VERTEX_ARRAY);
4865 //
4866 //			//printf("Surface Render before [%d] after [%d]\n",qCache.visibleScaledCellList.size(),surface.size());
4867 //		}
4868 	}
4869 
4870 	//Restore
4871 	static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(false);
4872 
4873 	glDisable(GL_TEXTURE_2D);
4874 
4875 	glPopAttrib();
4876 
4877 	//assert
4878 	GLenum glresult = glGetError();	//remove when first mtex problem solved
4879 	if(glresult) {
4880 		assertGl();
4881 	}
4882 	assertGl();
4883 
4884 	IF_DEBUG_EDITION(
4885 		} // end else, if not renderering debug textures instead of regular terrain
4886 		getDebugRenderer().renderEffects(visibleQuad / Map::cellScale);
4887 	)
4888 }
4889 
4890 void Renderer::renderObjects(const int renderFps) {
4891 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4892 		return;
4893 	}
4894 
4895 	const World *world= game->getWorld();
4896 	//const Map *map= world->getMap();
4897 
4898 	Config &config= Config::getInstance();
4899 	int tilesetObjectsToAnimate=config.getInt("AnimatedTilesetObjects","-1");
4900 
4901     assertGl();
4902 
4903 	const Texture2D *fowTex = world->getMinimap()->getFowTexture();
4904 	const Pixmap2D *fowTexPixmap = fowTex->getPixmapConst();
4905 	Vec3f baseFogColor = world->getTileset()->getFogColor() * world->getTimeFlow()->computeLightColor();
4906 
4907     bool modelRenderStarted = false;
4908 
4909 	VisibleQuadContainerCache &qCache = getQuadCache();
4910 
4911 	//	for(int visibleIndex = 0;
4912 	//			visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) {
4913 	// render from last to first object so animated objects which are on bottom of screen are
4914 	// rendered first which looks better for limited number of animated tileset objects
4915 	for(int visibleIndex = (int)qCache.visibleObjectList.size()-1;
4916 			visibleIndex >= 0 ; --visibleIndex) {
4917 		Object *o = qCache.visibleObjectList[visibleIndex];
4918 
4919 		Model *objModel= o->getModelPtr();
4920 		//objModel->updateInterpolationData(o->getAnimProgress(), true);
4921 		const Vec3f v= o->getConstPos();
4922 
4923 		if(modelRenderStarted == false) {
4924 			modelRenderStarted = true;
4925 
4926 			glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT);
4927 
4928 			if(shadowsOffDueToMinRender == false &&
4929 				shadows == sShadowMapping) {
4930 				glActiveTexture(shadowTexUnit);
4931 				glEnable(GL_TEXTURE_2D);
4932 
4933 				glBindTexture(GL_TEXTURE_2D, shadowMapHandle);
4934 
4935 				static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
4936 				enableProjectiveTexturing();
4937 			}
4938 
4939 			glActiveTexture(baseTexUnit);
4940 			glEnable(GL_COLOR_MATERIAL);
4941 			glAlphaFunc(GL_GREATER, 0.5f);
4942 
4943 			modelRenderer->begin(true, true, false, false);
4944 		}
4945 		//ambient and diffuse color is taken from cell color
4946 
4947 		float fowFactor= fowTexPixmap->getPixelf(o->getMapPos().x / Map::cellScale, o->getMapPos().y / Map::cellScale);
4948 		Vec4f color= Vec4f(Vec3f(fowFactor), 1.f);
4949 		glColor4fv(color.ptr());
4950 		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (color * ambFactor).ptr());
4951 		glFogfv(GL_FOG_COLOR, (baseFogColor * fowFactor).ptr());
4952 
4953 		glMatrixMode(GL_MODELVIEW);
4954 		glPushMatrix();
4955 		glTranslatef(v.x, v.y, v.z);
4956 		glRotatef(o->getRotation(), 0.f, 1.f, 0.f);
4957 
4958 		//We use OpenGL Lights so no manual action is needed here. In fact this call did bad things on lighting big rocks for example
4959 		//		if(o->getRotation() != 0.0) {
4960 		//			setupLightingForRotatedModel();
4961 		//		}
4962 
4963 		//objModel->updateInterpolationData(0.f, true);
4964 		//if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) {
4965 
4966 
4967 		if (tilesetObjectsToAnimate == -1) {
4968 			objModel->updateInterpolationData(o->getAnimProgress(), true);
4969 		} else if (tilesetObjectsToAnimate > 0 && o->isAnimated()) {
4970 			tilesetObjectsToAnimate--;
4971 			objModel->updateInterpolationData(o->getAnimProgress(), true);
4972 		} else {
4973 			objModel->updateInterpolationData(0, true);
4974 		}
4975 
4976 //		objModel->updateInterpolationData(o->getAnimProgress(), true);
4977 		//}
4978 		modelRenderer->render(objModel);
4979 
4980 		triangleCount+= objModel->getTriangleCount();
4981 		pointCount+= objModel->getVertexCount();
4982 
4983 		glPopMatrix();
4984 	}
4985 
4986 	if(modelRenderStarted == true) {
4987 		modelRenderer->end();
4988 		glPopAttrib();
4989 	}
4990 
4991 	//restore
4992 	static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
4993 
4994 	assertGl();
4995 }
4996 
4997 void Renderer::renderWater() {
4998 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
4999 		return;
5000 	}
5001 
5002 	const World *world= game->getWorld();
5003 	const Map *map= world->getMap();
5004 
5005 	const Texture2D *fowTex= world->getMinimap()->getFowTexture();
5006 	if(fowTex == NULL) {
5007 		return;
5008 	}
5009 
5010 	float waterAnim= world->getWaterEffects()->getAmin();
5011 
5012 	//assert
5013     assertGl();
5014 
5015 	glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);
5016 
5017 	//water texture nit
5018     glDisable(GL_TEXTURE_2D);
5019 
5020 	glEnable(GL_BLEND);
5021 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
5022 
5023 	if(textures3D) {
5024 		Texture3D *waterTex= world->getTileset()->getWaterTex();
5025 		if(waterTex == NULL) {
5026 			throw megaglest_runtime_error("waterTex == NULL");
5027 		}
5028 		glEnable(GL_TEXTURE_3D);
5029 		glBindTexture(GL_TEXTURE_3D, static_cast<Texture3DGl*>(waterTex)->getHandle());
5030 	}
5031 	else{
5032 		glEnable(GL_COLOR_MATERIAL);
5033 		glColor4f(0.5f, 0.5f, 1.0f, 0.5f);
5034 		glBindTexture(GL_TEXTURE_3D, 0);
5035 	}
5036 
5037 	assertGl();
5038 
5039 	//fog of War texture Unit
5040 	//const Texture2D *fowTex= world->getMinimap()->getFowTexture();
5041 	glActiveTexture(fowTexUnit);
5042 	glEnable(GL_TEXTURE_2D);
5043     glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(fowTex)->getHandle());
5044     glActiveTexture(baseTexUnit);
5045 
5046 	assertGl();
5047 
5048 	int thisTeamIndex= world->getThisTeamIndex();
5049 	bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex());
5050 	bool closed= false;
5051 
5052 	Rect2i boundingRect= visibleQuad.computeBoundingRect();
5053 	Rect2i scaledRect= boundingRect/Map::cellScale;
5054 	scaledRect.clamp(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
5055 
5056 	float waterLevel= world->getMap()->getWaterLevel();
5057     for(int j=scaledRect.p[0].y; j<scaledRect.p[1].y; ++j){
5058         glBegin(GL_TRIANGLE_STRIP);
5059 
5060 		for(int i=scaledRect.p[0].x; i<=scaledRect.p[1].x; ++i){
5061 			SurfaceCell *tc0= map->getSurfaceCell(i, j);
5062             SurfaceCell *tc1= map->getSurfaceCell(i, j+1);
5063 			if(tc0 == NULL) {
5064 				throw megaglest_runtime_error("tc0 == NULL");
5065 			}
5066 			if(tc1 == NULL) {
5067 				throw megaglest_runtime_error("tc1 == NULL");
5068 			}
5069 
5070             if(cellExplored == false) {
5071                 cellExplored = (tc0->isExplored(thisTeamIndex) || tc1->isExplored(thisTeamIndex));
5072             }
5073 
5074 			if(cellExplored == true && tc0->getNearSubmerged()) {
5075 				glNormal3f(0.f, 1.f, 0.f);
5076                 closed= false;
5077 
5078                 triangleCount+= 2;
5079 				pointCount+= 2;
5080 
5081                 //vertex 1
5082 				glMaterialfv(
5083 					GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
5084 					computeWaterColor(waterLevel, tc1->getHeight()).ptr());
5085 				glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr());
5086                 glTexCoord3f(i, 1.f, waterAnim);
5087 				glVertex3f(
5088 					static_cast<float>(i)*Map::mapScale,
5089 					waterLevel,
5090 					static_cast<float>(j+1)*Map::mapScale);
5091 
5092                 //vertex 2
5093 				glMaterialfv(
5094 					GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
5095 					computeWaterColor(waterLevel, tc0->getHeight()).ptr());
5096 				glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr());
5097                 glTexCoord3f(i, 0.f, waterAnim);
5098                 glVertex3f(
5099 					static_cast<float>(i)*Map::mapScale,
5100 					waterLevel,
5101 					static_cast<float>(j)*Map::mapScale);
5102 
5103             }
5104             else{
5105 				if(closed == false) {
5106 					pointCount+= 2;
5107 
5108 					//vertex 1
5109 					glMaterialfv(
5110 						GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
5111 						computeWaterColor(waterLevel, tc1->getHeight()).ptr());
5112 					glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr());
5113 					glTexCoord3f(i, 1.f, waterAnim);
5114 					glVertex3f(
5115 						static_cast<float>(i)*Map::mapScale,
5116 						waterLevel,
5117 						static_cast<float>(j+1)*Map::mapScale);
5118 
5119 					//vertex 2
5120 					glMaterialfv(
5121 						GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
5122 						computeWaterColor(waterLevel, tc0->getHeight()).ptr());
5123 					glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr());
5124 					glTexCoord3f(i, 0.f, waterAnim);
5125 					glVertex3f(
5126 						static_cast<float>(i)*Map::mapScale,
5127 						waterLevel,
5128 						static_cast<float>(j)*Map::mapScale);
5129 
5130 					glEnd();
5131 					glBegin(GL_TRIANGLE_STRIP);
5132 					closed= true;
5133 				}
5134            	}
5135         }
5136         glEnd();
5137     }
5138 
5139 	//restore
5140 	glPopAttrib();
5141 
5142 	assertGl();
5143 }
5144 
5145 void Renderer::renderTeamColorCircle(){
5146 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5147 		return;
5148 	}
5149 
5150 	VisibleQuadContainerCache &qCache = getQuadCache();
5151 	if(qCache.visibleQuadUnitList.empty() == false) {
5152 
5153 		glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
5154 		glDisable(GL_LIGHTING);
5155 		glDisable(GL_TEXTURE_2D);
5156 		glDepthFunc(GL_ALWAYS);
5157 		glDisable(GL_STENCIL_TEST);
5158 		glDisable(GL_CULL_FACE);
5159 		glEnable(GL_BLEND);
5160 		glLineWidth(2.f);
5161 
5162 		for(int visibleUnitIndex = 0;
5163 							visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
5164 				Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5165 				Vec3f currVec= unit->getCurrVectorFlat();
5166 				Vec3f color=unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0);
5167 				glColor4f(color.x, color.y, color.z, 0.7f);
5168 				renderSelectionCircle(currVec, unit->getType()->getSize(), 0.8f, 0.05f);
5169 			}
5170 		glPopAttrib();
5171 	}
5172 }
5173 
5174 void Renderer::renderSpecialHighlightUnits(std::map<int,HighlightSpecialUnitInfo> unitHighlightList) {
5175 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true || unitHighlightList.empty() == true) {
5176 		return;
5177 	}
5178 
5179 	VisibleQuadContainerCache &qCache = getQuadCache();
5180 	if(qCache.visibleQuadUnitList.empty() == false) {
5181 
5182 		glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
5183 		glDisable(GL_LIGHTING);
5184 		glDisable(GL_TEXTURE_2D);
5185 		glDepthFunc(GL_ALWAYS);
5186 		glDisable(GL_STENCIL_TEST);
5187 		glDisable(GL_CULL_FACE);
5188 		glEnable(GL_BLEND);
5189 		glLineWidth(2.f);
5190 
5191 		for(int visibleUnitIndex = 0;
5192 							visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
5193 				Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5194 
5195 				std::map<int,HighlightSpecialUnitInfo>::iterator iterFindSpecialUnit = unitHighlightList.find(unit->getId());
5196 				if(iterFindSpecialUnit != unitHighlightList.end()) {
5197 					Vec3f color=unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0);
5198 					float radius = 1.0f;
5199 					float thickness = 0.1f;
5200 					float alpha = 0.65f;
5201 
5202 					HighlightSpecialUnitInfo &specialInfo = iterFindSpecialUnit->second;
5203 					if(specialInfo.color.x >= 0) {
5204 						color.x = specialInfo.color.x;
5205 						color.y = specialInfo.color.y;
5206 						color.z = specialInfo.color.z;
5207 					}
5208 					if(specialInfo.color.w >= 0) {
5209 						alpha = specialInfo.color.w;
5210 					}
5211 					if(specialInfo.radius > 0) {
5212 						radius = specialInfo.radius;
5213 					}
5214 					if(specialInfo.thickness > 0) {
5215 						thickness = specialInfo.thickness;
5216 					}
5217 
5218 					glColor4f(color.x, color.y, color.z, alpha);
5219 
5220 					Vec3f currVec= unit->getCurrVectorFlat();
5221 					renderSelectionCircle(currVec, unit->getType()->getSize(), radius, thickness);
5222 				}
5223 		}
5224 		glPopAttrib();
5225 	}
5226 }
5227 
5228 void Renderer::renderTeamColorPlane(){
5229 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5230 		return;
5231 	}
5232 
5233 	VisibleQuadContainerCache &qCache = getQuadCache();
5234 	if(qCache.visibleQuadUnitList.empty() == false){
5235 		glPushAttrib(GL_ENABLE_BIT);
5236 		glDisable(GL_LIGHTING);
5237 		glEnable(GL_TEXTURE_2D);
5238 		glEnable(GL_BLEND);
5239 		glEnable(GL_COLOR_MATERIAL);
5240 		const Texture2D *texture=CoreData::getInstance().getTeamColorTexture();
5241 		for(int visibleUnitIndex = 0;
5242 				visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex){
5243 			Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5244 			if( unit->isAlive()){
5245 				Vec3f currVec= unit->getCurrVectorFlat();
5246 				renderTeamColorEffect(currVec,visibleUnitIndex,unit->getType()->getSize(),
5247 						unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0),texture);
5248 			}
5249 		}
5250 		glDisable(GL_COLOR_MATERIAL);
5251 		glPopAttrib();
5252 	}
5253 }
5254 
5255 void Renderer::renderGhostModel(const UnitType *building, const Vec2i pos,CardinalDir facing, Vec4f *forceColor) {
5256 	//const UnitType *building= gui->getBuilding();
5257 	//const Vec2i &pos= gui->getPosObjWorld();
5258 
5259 	//const Gui *gui= game->getGui();
5260 	//const Mouse3d *mouse3d= gui->getMouse3d();
5261 	const Map *map= game->getWorld()->getMap();
5262 	if(map == NULL) {
5263 		char szBuf[8096]="";
5264 		snprintf(szBuf,8096,"In [%s::%s] Line: %d map == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
5265 		throw megaglest_runtime_error(szBuf);
5266 	}
5267 
5268 	glPushMatrix();
5269 	Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y);
5270 
5271 	//selection building placement
5272 	float offset= building->getSize()/2.f-0.5f;
5273 	glTranslatef(pos3f.x+offset, pos3f.y, pos3f.z+offset);
5274 
5275 	//choose color
5276 	Vec4f color;
5277 	if(forceColor != NULL) {
5278 		color = *forceColor;
5279 	}
5280 	else {
5281 		if(map->isFreeCells(pos, building->getSize(), fLand)) {
5282 			color= Vec4f(1.f, 1.f, 1.f, 0.5f);
5283 		}
5284 		else {
5285 //			Uint64 tc=game->getTickCount();
5286 //			float red=0.49f+((tc%4*1.0f)/2);
5287 			color= Vec4f(1.0f, 0.f, 0.f, 0.5f);
5288 		}
5289 	}
5290 
5291 	glColor4fv(color.ptr());
5292 	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr());
5293 	Model *buildingModel= building->getFirstStOfClass(scStop)->getAnimation();
5294 
5295 	if(facing != CardinalDir::NORTH) {
5296 		float rotateAmount = facing * 90.f;
5297 		if(rotateAmount > 0) {
5298 			glRotatef(rotateAmount, 0.f, 1.f, 0.f);
5299 		}
5300 	}
5301 
5302 	buildingModel->updateInterpolationData(0.f, false);
5303 	modelRenderer->render(buildingModel);
5304 
5305 	glPopMatrix();
5306 }
5307 
5308 void Renderer::renderUnits(bool airUnits, const int renderFps) {
5309 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5310 		return;
5311 	}
5312 
5313 	//Unit *unit=NULL;
5314 	//const World *world= game->getWorld();
5315 	MeshCallbackTeamColor meshCallbackTeamColor;
5316 
5317 	//assert
5318 	assertGl();
5319 
5320 	if(visibleFrameUnitList.empty() == false) {
5321 		visibleFrameUnitList.clear();
5322 		//visibleFrameUnitListCameraKey = "";
5323 		//if(visibleFrameUnitListCameraKey != game->getGameCamera()->getCameraMovementKey()) {
5324 		//	worldToScreenPosCache.clear();
5325 		//}
5326 	}
5327 
5328 	VisibleQuadContainerCache &qCache = getQuadCache();
5329 	if(qCache.visibleQuadUnitList.empty() == false) {
5330 		bool modelRenderStarted = false;
5331 		for(int visibleUnitIndex = 0;
5332 				visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
5333 			Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5334 
5335 			if(( airUnits==false && unit->getType()->getField()==fAir) || ( airUnits==true && unit->getType()->getField()!=fAir)){
5336 				continue;
5337 			}
5338 			meshCallbackTeamColor.setTeamTexture(unit->getFaction()->getTexture());
5339 
5340 			if(modelRenderStarted == false) {
5341 				modelRenderStarted = true;
5342 
5343 				glPushAttrib(GL_ENABLE_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT);
5344 				glEnable(GL_COLOR_MATERIAL);
5345 
5346 				if(!shadowsOffDueToMinRender) {
5347 					if(shadows == sShadowMapping) {
5348 						glActiveTexture(shadowTexUnit);
5349 						glEnable(GL_TEXTURE_2D);
5350 
5351 						glBindTexture(GL_TEXTURE_2D, shadowMapHandle);
5352 
5353 						static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
5354 						enableProjectiveTexturing();
5355 					}
5356 				}
5357 				glActiveTexture(baseTexUnit);
5358 
5359 				modelRenderer->begin(true, true, true, false, &meshCallbackTeamColor);
5360 			}
5361 
5362 			glMatrixMode(GL_MODELVIEW);
5363 			glPushMatrix();
5364 
5365 			//translate
5366 			Vec3f currVec= unit->getCurrVectorFlat();
5367 			glTranslatef(currVec.x, currVec.y, currVec.z);
5368 
5369 			//rotate
5370 			float zrot=unit->getRotationZ();
5371 			float xrot=unit->getRotationX();
5372 			if(zrot!=.0f){
5373 				glRotatef(zrot, 0.f, 0.f, 1.f);
5374 			}
5375 			if(xrot!=.0f){
5376 				glRotatef(xrot, 1.f, 0.f, 0.f);
5377 			}
5378 			glRotatef(unit->getRotation(), 0.f, 1.f, 0.f);
5379 
5380 			//dead alpha
5381 			const SkillType *st= unit->getCurrSkill();
5382 			if(st->getClass() == scDie && static_cast<const DieSkillType*>(st)->getFade()) {
5383 				float alpha= 1.0f - unit->getAnimProgressAsFloat();
5384 				glDisable(GL_COLOR_MATERIAL);
5385 				glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr());
5386 			}
5387 			else {
5388 				glEnable(GL_COLOR_MATERIAL);
5389 				// we cut off a tiny bit here to avoid problems with fully transparent texture parts cutting units in background rendered later.
5390 				glAlphaFunc(GL_GREATER, 0.02f);
5391 			}
5392 
5393 			//render
5394 			Model *model= unit->getCurrentModelPtr();
5395 			//printf("Rendering model [%d - %s]\n[%s]\nCamera [%s]\nDistance: %f\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrVector().getString().c_str(),this->gameCamera->getPos().getString().c_str(),this->gameCamera->getPos().dist(unit->getCurrVector()));
5396 
5397 			//if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) {
5398 				model->updateInterpolationData(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound());
5399 			//}
5400 
5401 			modelRenderer->render(model);
5402 			triangleCount+= model->getTriangleCount();
5403 			pointCount+= model->getVertexCount();
5404 
5405 			glPopMatrix();
5406 			unit->setVisible(true);
5407 
5408 			if(	showDebugUI == true &&
5409 				(showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) {
5410 
5411 				unit->setScreenPos(computeScreenPosition(currVec));
5412 				visibleFrameUnitList.push_back(unit);
5413 				visibleFrameUnitListCameraKey = game->getGameCamera()->getCameraMovementKey();
5414 			}
5415 		}
5416 
5417 		if(modelRenderStarted == true) {
5418 			modelRenderer->end();
5419 			glPopAttrib();
5420 		}
5421 	}
5422 
5423 	//restore
5424 	static_cast<ModelRendererGl*>(modelRenderer)->setDuplicateTexCoords(true);
5425 
5426 	// reset alpha
5427 	glAlphaFunc(GL_GREATER, 0.0f);
5428 	//assert
5429 	assertGl();
5430 
5431 }
5432 
5433 void Renderer::renderUnitsToBuild(const int renderFps) {
5434 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5435 		return;
5436 	}
5437 
5438 	//assert
5439 	assertGl();
5440 
5441 	VisibleQuadContainerCache &qCache = getQuadCache();
5442 	if(qCache.visibleQuadUnitBuildList.empty() == false) {
5443 
5444 		glMatrixMode(GL_MODELVIEW);
5445 		glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
5446 		glEnable(GL_BLEND);
5447 		glDisable(GL_STENCIL_TEST);
5448 		glDepthFunc(GL_LESS);
5449 		glEnable(GL_COLOR_MATERIAL);
5450 		glDepthMask(GL_FALSE);
5451 
5452 		modelRenderer->begin(true, true, false, false);
5453 
5454 		for(int visibleUnitIndex = 0;
5455 				visibleUnitIndex < (int)qCache.visibleQuadUnitBuildList.size(); ++visibleUnitIndex) {
5456 			const UnitBuildInfo &buildUnit = qCache.visibleQuadUnitBuildList[visibleUnitIndex];
5457 			//Vec4f modelColor= Vec4f(0.f, 1.f, 0.f, 0.5f);
5458 			const Vec3f teamColor = buildUnit.unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0);
5459 			Vec4f modelColor= Vec4f(teamColor.x,teamColor.y,teamColor.z,0.4f);
5460 			renderGhostModel(buildUnit.buildUnit, buildUnit.pos, buildUnit.facing, &modelColor);
5461 
5462 			//printf("Rendering to build unit index = %d\n",visibleUnitIndex);
5463 		}
5464 
5465 		modelRenderer->end();
5466 
5467 		glDisable(GL_COLOR_MATERIAL);
5468 		glPopAttrib();
5469 	}
5470 
5471 	//assert
5472 	assertGl();
5473 
5474 }
5475 
5476 void Renderer::renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture) {
5477 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5478 		return;
5479 	}
5480 
5481 	//GLUquadricObj *disc;
5482 	float halfSize=size;
5483 	//halfSize=halfSize;
5484 	float heigthoffset=0.5+heigth%25*0.004;
5485 	glPushMatrix();
5486 	glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(texture)->getHandle());
5487 	glColor4f(color.x, color.y, color.z, 1.0f);
5488 		glBegin(GL_TRIANGLE_STRIP);
5489 			glTexCoord2i(0, 1);
5490 			glVertex3f(v.x-halfSize,v.y+heigthoffset,v.z+halfSize);
5491 			glTexCoord2i(0, 0);
5492 			glVertex3f(v.x-halfSize,v.y+heigthoffset, v.z-halfSize);
5493 			glTexCoord2i(1, 1);
5494 
5495 			glVertex3f(v.x+halfSize,v.y+heigthoffset, v.z+halfSize);
5496 			glTexCoord2i(1, 0);
5497 			glVertex3f(v.x+halfSize,v.y+heigthoffset, v.z-halfSize);
5498 		glEnd();
5499 	glPopMatrix();
5500 
5501 }
5502 
5503 void Renderer::renderMorphEffects(){
5504 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5505 		return;
5506 	}
5507 
5508 	VisibleQuadContainerCache &qCache = getQuadCache();
5509 	if(qCache.visibleQuadUnitList.empty() == false) {
5510 		bool initialized=false;
5511 		int frameCycle=0;
5512 		for(int visibleUnitIndex = 0;
5513 							visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
5514 			Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5515 			if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() == scMorph) {
5516 				Command *command= unit->getCurrCommand();
5517 				if(command != NULL && command->getCommandType()->commandTypeClass == ccMorph){
5518 					const MorphCommandType *mct= static_cast<const MorphCommandType*>(command->getCommandType());
5519 					const UnitType* mType=mct->getMorphUnit();
5520 
5521 					if(mType->getSize()>unit->getType()->getSize() ||
5522 							mType->getField()!=unit->getType()->getField()){
5523 						if(!initialized){
5524 							const World *world= game->getWorld();
5525 							frameCycle=world->getFrameCount() % 40;
5526 
5527 							glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
5528 							glDisable(GL_LIGHTING);
5529 							glDisable(GL_TEXTURE_2D);
5530 							glDepthFunc(GL_ALWAYS);
5531 							glDisable(GL_STENCIL_TEST);
5532 							glDisable(GL_CULL_FACE);
5533 							glEnable(GL_BLEND);
5534 							glLineWidth(2.f);
5535 							initialized=true;
5536 						}
5537 
5538 						Vec3f currVec= unit->getCurrVectorFlat();
5539 						currVec=Vec3f(currVec.x,currVec.y+0.3f,currVec.z);
5540 						if(mType->getField() == fAir && unit->getType()->getField()== fLand) {
5541 							currVec=Vec3f(currVec.x,currVec.y+game->getWorld()->getTileset()->getAirHeight(),currVec.z);
5542 						}
5543 						if(mType->getField() == fLand && unit->getType()->getField()== fAir) {
5544 							currVec=Vec3f(currVec.x,currVec.y-game->getWorld()->getTileset()->getAirHeight(),currVec.z);
5545 						}
5546 
5547 						float color=frameCycle*0.4f/40;
5548 						glColor4f(color,color, 0.4f, 0.4f);
5549 						renderSelectionCircle(currVec, mType->getSize(), frameCycle*0.85f/40, 0.2f);
5550 					}
5551 				}
5552 			}
5553 		}
5554 		if(initialized) {
5555 			glPopAttrib();
5556 		}
5557 	}
5558 }
5559 
5560 
5561 
5562 void Renderer::renderSelectionEffects(int healthbarMode) {
5563 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5564 		return;
5565 	}
5566 
5567 	Config &config= Config::getInstance();
5568 	if(config.getBool("RecordMode","false") == true) {
5569 		return;
5570 	}
5571 
5572 	const World *world= game->getWorld();
5573 	const Map *map= world->getMap();
5574 	const Selection *selection= game->getGui()->getSelection();
5575 	const Object *selectedResourceObject= game->getGui()->getSelectedResourceObject();
5576 
5577 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
5578 	glDisable(GL_LIGHTING);
5579 	glDisable(GL_TEXTURE_2D);
5580 	glDepthFunc(GL_ALWAYS);
5581 	glDisable(GL_STENCIL_TEST);
5582 	glDisable(GL_CULL_FACE);
5583 	glEnable(GL_BLEND);
5584 	glLineWidth(2.f);
5585 
5586 	//units
5587 	for(int i=0; i<selection->getCount(); ++i){
5588 
5589 		const Unit *unit= selection->getUnit(i);
5590 		if(unit != NULL) {
5591 			//translate
5592 			Vec3f currVec= unit->getCurrVectorFlat();
5593 			currVec.y+= 0.3f;
5594 
5595 			//selection circle
5596 			int finalHealthbarMode = hbvUndefined;
5597 			if(healthbarMode == hbvUndefined) {
5598 				finalHealthbarMode = unit->getFaction()->getType()->getHealthbarVisible();
5599 			}
5600 			else {
5601 				finalHealthbarMode = healthbarMode;
5602 			}
5603 			bool healthbarsVisible =((finalHealthbarMode & hbvAlways)   ||
5604 					                 (finalHealthbarMode & hbvSelected) ||
5605 					                 (finalHealthbarMode & hbvIfNeeded));
5606 			float selectionCircleThickness = 0.2f;
5607 			float hpRatio = unit->getHpRatio();
5608 			if(healthbarsVisible) {
5609 				selectionCircleThickness = 0.05f;
5610 				hpRatio = 1.0f;
5611 			}
5612 
5613 			if(world->getThisFactionIndex() == unit->getFactionIndex()) {
5614 				if(	showDebugUI == true &&
5615 					((showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) &&
5616 					unit->getCommandSize() > 0 &&
5617 					dynamic_cast<const BuildCommandType *>(unit->getCurrCommand()->getCommandType()) != NULL) {
5618 					glColor4f(hpRatio, hpRatio, hpRatio, 0.3f);
5619 				}
5620 				else {
5621 					glColor4f(0, hpRatio, 0, 0.3f);
5622 				}
5623 			}
5624 			else if ( world->getThisTeamIndex() == unit->getTeam()) {
5625 				glColor4f(hpRatio, hpRatio, 0, 0.3f);
5626 			}
5627 			else {
5628 				glColor4f(hpRatio, 0, 0, 0.3f);
5629 			}
5630 			renderSelectionCircle(currVec, unit->getType()->getSize(), selectionCircleRadius,selectionCircleThickness);
5631 
5632 			if(	showDebugUI == true &&
5633 				(showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) {
5634 
5635 				const UnitPathInterface *path= unit->getPath();
5636 				const UnitPathBasic *pathfinder = (path == NULL ? NULL : dynamic_cast<const UnitPathBasic *>(path));
5637 				if(pathfinder != NULL) {
5638 					vector<Vec2i> pathList = pathfinder->getQueue();
5639 
5640 					Vec2i lastPosValue;
5641 					for(int i = 0; i < (int)pathList.size(); ++i) {
5642 						Vec2i curPosValue = pathList[i];
5643 						if(i == 0) {
5644 							lastPosValue = curPosValue;
5645 						}
5646 						Vec3f currVec2 = unit->getVectorFlat(lastPosValue,curPosValue);
5647 						currVec2.y+= 0.3f;
5648 						renderSelectionCircle(currVec2, 1, selectionCircleRadius);
5649 					}
5650 				}
5651 			}
5652 
5653 			//magic circle
5654 			if(!healthbarsVisible && world->getThisFactionIndex() == unit->getFactionIndex() && unit->getType()->getMaxEp() > 0) {
5655 				glColor4f(unit->getEpRatio()/2.f, unit->getEpRatio(), unit->getEpRatio(), 0.5f);
5656 				renderSelectionCircle(currVec, unit->getType()->getSize(), magicCircleRadius);
5657 			}
5658 
5659 			// Render Attack-boost circles
5660 			if(showDebugUI == true) {
5661 				//const std::pair<const SkillType *,std::vector<Unit *> > &currentAttackBoostUnits = unit->getCurrentAttackBoostUnits();
5662 				const UnitAttackBoostEffectOriginator &effect = unit->getAttackBoostOriginatorEffect();
5663 
5664 				if(effect.skillType->isAttackBoostEnabled() == true) {
5665 					glColor4f(MAGENTA.x,MAGENTA.y,MAGENTA.z,MAGENTA.w);
5666 					renderSelectionCircle(currVec, 1, effect.skillType->getAttackBoost()->radius, .25f/effect.skillType->getAttackBoost()->radius);
5667 
5668 					for(unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) {
5669 						// Remove attack boost upgrades from unit
5670 						int findUnitId = effect.currentAttackBoostUnits[i];
5671 						Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId);
5672 						if(affectedUnit != NULL) {
5673 							Vec3f currVecBoost = affectedUnit->getCurrVectorFlat();
5674 							currVecBoost.y += 0.3f;
5675 
5676 							renderSelectionCircle(currVecBoost, affectedUnit->getType()->getSize(), 1.f);
5677 						}
5678 					}
5679 				}
5680 			}
5681 		}
5682 	}
5683 
5684 	if(selectedResourceObject != NULL && selectedResourceObject->getResource() != NULL && selection->getCount() < 1) {
5685 		Resource *r= selectedResourceObject->getResource();
5686 		int defaultValue= r->getType()->getDefResPerPatch();
5687 		float colorValue=static_cast<float>(r->getAmount())/static_cast<float>(defaultValue);
5688 		glColor4f(0.1f, 0.1f , colorValue, 0.4f);
5689 		renderSelectionCircle(selectedResourceObject->getPos(),2, selectionCircleRadius);
5690 	}
5691 	//target arrow
5692 	if(selection->getCount() == 1) {
5693 		const Unit *unit= selection->getUnit(0);
5694 		if(unit != NULL) {
5695 			//comand arrow
5696 			if(focusArrows && unit->anyCommand()) {
5697 				const CommandType *ct= unit->getCurrCommand()->getCommandType();
5698 				if(ct->getClicks() != cOne){
5699 
5700 					//arrow color
5701 					Vec3f arrowColor;
5702 					switch(ct->getClass()) {
5703 					case ccMove:
5704 						arrowColor= Vec3f(0.f, 1.f, 0.f);
5705 						break;
5706 					case ccAttack:
5707 					case ccAttackStopped:
5708 						arrowColor= Vec3f(1.f, 0.f, 0.f);
5709 						break;
5710 					default:
5711 						arrowColor= Vec3f(1.f, 1.f, 0.f);
5712 						break;
5713 					}
5714 
5715 					//arrow target
5716 					Vec3f arrowTarget;
5717 					Command *c= unit->getCurrCommand();
5718 					if(c->getUnit() != NULL) {
5719 						arrowTarget= c->getUnit()->getCurrVectorFlat();
5720 					}
5721 					else {
5722 						Vec2i pos= c->getPos();
5723 						map->clampPos(pos);
5724 
5725 						arrowTarget= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y);
5726 					}
5727 
5728 					renderArrow(unit->getCurrVectorFlat(), arrowTarget, arrowColor, 0.3f);
5729 				}
5730 			}
5731 
5732 			//meeting point arrow
5733 			if(unit->getType()->getMeetingPoint()) {
5734 				Vec2i pos= unit->getMeetingPos();
5735 				map->clampPos(pos);
5736 
5737 				Vec3f arrowTarget= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y);
5738 				renderArrow(unit->getCurrVectorFlat(), arrowTarget, Vec3f(0.f, 0.f, 1.f), 0.3f);
5739 			}
5740 		}
5741 	}
5742 
5743 	//render selection hightlights
5744 	if(game->getGui()->getHighlightedUnit() != NULL)	{
5745 		const Unit *unit=game->getGui()->getHighlightedUnit() ;
5746 
5747 		if(unit->isHighlighted()) {
5748 			float highlight= unit->getHightlight();
5749 			if(game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) {
5750 				glColor4f(0.f, 1.f, 0.f, highlight);
5751 			}
5752 			else{
5753 				glColor4f(1.f, 0.f, 0.f, highlight);
5754 			}
5755 
5756 			Vec3f v= unit->getCurrVectorFlat();
5757 			v.y+= 0.3f;
5758 			renderSelectionCircle(v, unit->getType()->getSize(), 0.5f+0.4f*highlight );
5759 		}
5760 	}
5761 // old inefficient way to render highlights
5762 //	for(int i=0; i < world->getFactionCount(); ++i) {
5763 //		for(int j=0; j < world->getFaction(i)->getUnitCount(); ++j) {
5764 //			const Unit *unit= world->getFaction(i)->getUnit(j);
5765 //
5766 //			if(unit->isHighlighted()) {
5767 //				float highlight= unit->getHightlight();
5768 //				if(game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) {
5769 //					glColor4f(0.f, 1.f, 0.f, highlight);
5770 //				}
5771 //				else{
5772 //					glColor4f(1.f, 0.f, 0.f, highlight);
5773 //				}
5774 //
5775 //				Vec3f v= unit->getCurrVectorFlat();
5776 //				v.y+= 0.3f;
5777 //				renderSelectionCircle(v, unit->getType()->getSize(), 0.5f+0.4f*highlight );
5778 //			}
5779 //		}
5780 //	}
5781 	//render resource selection highlight
5782 	if(game->getGui()->getHighlightedResourceObject() != NULL) {
5783 		const Object* object=game->getGui()->getHighlightedResourceObject();
5784 		if(object->isHighlighted()) {
5785 			float highlight= object->getHightlight();
5786 			glColor4f(0.1f, 0.1f , 1.0f, highlight);
5787 			Vec3f v= object->getPos();
5788 			v.y+= 0.3f;
5789 			renderSelectionCircle(v, 2, 0.4f+0.4f*highlight );
5790 		}
5791 	}
5792 
5793 	glPopAttrib();
5794 }
5795 
5796 void Renderer::renderHealthBars(int healthbarMode){
5797 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5798 		return;
5799 	}
5800 
5801 	Config &config= Config::getInstance();
5802 	if(config.getBool("RecordMode","false") == true) {
5803 		return;
5804 	}
5805 
5806 	if(config.getBool("PhotoMode")) {
5807 		return;
5808 	}
5809 
5810 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
5811 	glDisable(GL_LIGHTING);
5812 	glDisable(GL_TEXTURE_2D);
5813 	glDepthFunc(GL_ALWAYS);
5814 	glDisable(GL_STENCIL_TEST);
5815 	glDisable(GL_CULL_FACE);
5816 	glEnable(GL_BLEND);
5817 	glLineWidth(2.f);
5818 
5819 	VisibleQuadContainerCache &qCache = getQuadCache();
5820 	if(qCache.visibleQuadUnitList.empty() == false) {
5821 		for(int visibleUnitIndex = 0;
5822 				visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
5823 			Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
5824 			if(isHealthBarVisible(unit,healthbarMode)) {
5825 				float healthbarheight;
5826 				float healthbarthickness;
5827 				const Texture2D *healthbarTexture;
5828 				const Texture2D *healthbarBackgroundTexture;
5829 				bool healthbarLineBorder;
5830 
5831 				//get settings of the faction
5832 				healthbarheight=unit->getFaction()->getType()->getHealthbarHeight();
5833 				healthbarthickness=unit->getFaction()->getType()->getHealthbarThickness();
5834 				healthbarLineBorder=unit->getFaction()->getType()->isHealthbarLineBorder();
5835 				CoreData &coreData= CoreData::getInstance();
5836 				//First try faction texture then use core Texture
5837 				if(unit->getFaction()->getType()->isHealthbarBorderTextureEnabled()) {
5838 					healthbarTexture=unit->getFaction()->getType()->getHealthbarTexture();
5839 					if(healthbarTexture==NULL) {
5840 						healthbarTexture=coreData.getHealthbarTexture();
5841 					}
5842 				} else {
5843 					healthbarTexture=NULL;
5844 				}
5845 				if(unit->getFaction()->getType()->isHealthbarBackgroundTextureEnabled()) {
5846 					healthbarBackgroundTexture=unit->getFaction()->getType()->getHealthbarBackgroundTexture();
5847 					if(healthbarBackgroundTexture==NULL) {
5848 						healthbarBackgroundTexture=coreData.getHealthbarBackgroundTexture();
5849 					}
5850 				} else {
5851 					healthbarBackgroundTexture=NULL;
5852 				}
5853 
5854 				//replace them by the ones from the unit if existent
5855 				if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) {
5856 					if(unit->getType()->getHealthbarHeight()!=-100.0f) {
5857 						healthbarheight=unit->getType()->getHealthbarHeight();
5858 					}
5859 					if(unit->getType()->getHealthbarThickness()!=-1.0f) {
5860 						healthbarthickness=unit->getType()->getHealthbarThickness();
5861 					}
5862 				}
5863 
5864 				Vec3f currVec= unit->getCurrVectorFlat();
5865 				if(healthbarheight==-100.0f) {
5866 					currVec.y+=unit->getType()->getHeight();
5867 				} else {
5868 					currVec.y+=healthbarheight;
5869 				}
5870 				renderHealthBar(currVec,unit,healthbarthickness,healthbarLineBorder,healthbarTexture,healthbarBackgroundTexture);
5871 			}
5872 		}
5873 	}
5874 	glPopAttrib();
5875 }
5876 
5877 bool Renderer::isHealthBarVisible(const Unit *unit,int healthbarMode){
5878 	int healthbarVisible=hbvUndefined;
5879 	//check options (hotkey)
5880 	if(healthbarMode==hbvUndefined) {
5881 		healthbarVisible=unit->getFaction()->getType()->getHealthbarVisible();
5882 	} else {
5883 		healthbarVisible=healthbarMode;
5884 	}
5885 
5886 	//replace them by the ones from the unit if existent
5887 	if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) {
5888 		if(healthbarMode==hbvUndefined) { //don't override the visible setting when hotkey is not hbvUndefined
5889 			healthbarVisible=unit->getType()->getHealthbarVisible();
5890 		}
5891 	}
5892 
5893 	bool settingsWantToRenderThem=!(healthbarVisible==hbvUndefined || (healthbarVisible&hbvOff))
5894 			&& ((healthbarVisible&hbvAlways)
5895 			|| ((healthbarVisible&hbvIfNeeded) && unit->getHp()<unit->getType()->getMaxHp()+unit->getTotalUpgrade()->getMaxHp())
5896 			|| ((healthbarVisible&hbvIfNeeded) && unit->getType()->getMaxEp() > 0 && unit->getEp()<unit->getType()->getMaxEp()+unit->getTotalUpgrade()->getMaxEp())
5897 			|| ((healthbarVisible&hbvIfNeeded) && unit->getProductionPercent() > 0)
5898 			|| ((healthbarVisible&hbvSelected) && game->getGui()->isSelected(unit)));
5899 
5900 	if(unit->isAlive() && (settingsWantToRenderThem)) {
5901 		return true;
5902 	}
5903 	return false;
5904 }
5905 
5906 void Renderer::renderWaterEffects(){
5907 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
5908 		return;
5909 	}
5910 
5911 	const World *world= game->getWorld();
5912 	const WaterEffects *we= world->getWaterEffects();
5913 	const Map *map= world->getMap();
5914 	CoreData &coreData= CoreData::getInstance();
5915 	float height= map->getWaterLevel()+0.001f;
5916 
5917 	assertGl();
5918 
5919 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
5920 	glEnable(GL_BLEND);
5921 	glDisable(GL_ALPHA_TEST);
5922 	glDepthMask(GL_FALSE);
5923 	glDepthFunc(GL_LEQUAL);
5924 	glEnable(GL_COLOR_MATERIAL);
5925 
5926 	//glNormal3f(0.f, 1.f, 0.f);
5927 
5928 	//splashes
5929 	glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(coreData.getWaterSplashTexture())->getHandle());
5930 
5931 	//!!!
5932 	Vec2f texCoords[4];
5933 	Vec3f vertices[4];
5934 	Vec3f normals[4];
5935 
5936     glEnableClientState(GL_VERTEX_ARRAY);
5937     glEnableClientState(GL_NORMAL_ARRAY);
5938     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
5939 
5940 	for(int i=0; i<we->getWaterSplashCount(); ++i){
5941 		const WaterSplash *ws= we->getWaterSplash(i);
5942 
5943 		//render only if enabled
5944 		if(ws->getEnabled()){
5945 
5946 			//render only if visible
5947 			Vec2i intPos= Vec2i(static_cast<int>(ws->getPos().x), static_cast<int>(ws->getPos().y));
5948 			const Vec2i &mapPos = Map::toSurfCoords(intPos);
5949 
5950 			bool visible = map->getSurfaceCell(mapPos)->isVisible(world->getThisTeamIndex());
5951 			if(visible == false && world->showWorldForPlayer(world->getThisFactionIndex()) == true) {
5952 				visible = true;
5953 			}
5954 
5955 			if(visible == true) {
5956 				float scale= ws->getAnim()*ws->getSize();
5957 				texCoords[0]		= Vec2f(0.f, 1.f);
5958 				vertices[0]			= Vec3f(ws->getPos().x-scale, height, ws->getPos().y+scale);
5959 				normals[0]			= Vec3f(0.f, 1.f, 0.f);
5960 
5961 				texCoords[1]		= Vec2f(0.f, 0.f);
5962 				vertices[1]			= Vec3f(ws->getPos().x-scale, height, ws->getPos().y-scale);
5963 				normals[1]			= Vec3f(0.f, 1.f, 0.f);
5964 
5965 				texCoords[2]		= Vec2f(1.f, 1.f);
5966 				vertices[2]			= Vec3f(ws->getPos().x+scale, height, ws->getPos().y+scale);
5967 				normals[2]			= Vec3f(0.f, 1.f, 0.f);
5968 
5969 				texCoords[3]		= Vec2f(1.f, 0.f);
5970 				vertices[3]			= Vec3f(ws->getPos().x+scale, height, ws->getPos().y-scale);
5971 				normals[3]			= Vec3f(0.f, 1.f, 0.f);
5972 
5973 				glColor4f(1.f, 1.f, 1.f, 1.f - ws->getAnim());
5974 				glTexCoordPointer(2, GL_FLOAT, 0,&texCoords[0]);
5975 				glVertexPointer(3, GL_FLOAT, 0, &vertices[0]);
5976 				glNormalPointer(GL_FLOAT, 0, &normals[0]);
5977 				glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5978 
5979 
5980 /*
5981 				glBegin(GL_TRIANGLE_STRIP);
5982 					glTexCoord2f(0.f, 1.f);
5983 					glVertex3f(ws->getPos().x-scale, height, ws->getPos().y+scale);
5984 					glTexCoord2f(0.f, 0.f);
5985 					glVertex3f(ws->getPos().x-scale, height, ws->getPos().y-scale);
5986 					glTexCoord2f(1.f, 1.f);
5987 					glVertex3f(ws->getPos().x+scale, height, ws->getPos().y+scale);
5988 					glTexCoord2f(1.f, 0.f);
5989 					glVertex3f(ws->getPos().x+scale, height, ws->getPos().y-scale);
5990 				glEnd();
5991 */
5992 			}
5993 		}
5994 	}
5995 
5996 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
5997 	glDisableClientState(GL_NORMAL_ARRAY);
5998 	glDisableClientState(GL_VERTEX_ARRAY);
5999 
6000 	glPopAttrib();
6001 
6002 	assertGl();
6003 }
6004 
6005 void Renderer::renderHud(){
6006 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6007 		return;
6008 	}
6009 
6010 	Texture2D *hudTexture=game->getGui()->getHudTexture();
6011 	if(hudTexture!=NULL){
6012 		const Metrics &metrics= Metrics::getInstance();
6013 		renderTextureQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(),hudTexture,1.0f);
6014 	}
6015 }
6016 
6017 void Renderer::renderMinimap(){
6018 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6019 		return;
6020 	}
6021 
6022     const World *world= game->getWorld();
6023 	const Minimap *minimap= world->getMinimap();
6024 
6025 	if(minimap == NULL || minimap->getTexture() == NULL) {
6026 		return;
6027 	}
6028 
6029 	const GameCamera *gameCamera= game->getGameCamera();
6030 	const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst();
6031 	const Metrics &metrics= Metrics::getInstance();
6032 	const WaterEffects *attackEffects= world->getAttackEffects();
6033 
6034 	int mx= metrics.getMinimapX();
6035 	int my= metrics.getMinimapY();
6036 	int mw= metrics.getMinimapW();
6037 	int mh= metrics.getMinimapH();
6038 
6039 	Vec2f zoom= Vec2f(
6040 		static_cast<float>(mw)/ pixmap->getW(),
6041 		static_cast<float>(mh)/ pixmap->getH());
6042 
6043 	assertGl();
6044 
6045 	// render minimap border
6046 	Vec4f col= game->getGui()->getDisplay()->getColor();
6047 	glColor4f(col.x*0.5f,col.y*0.5f,col.z*0.5f,1.0 );
6048 
6049 	int borderWidth=2;
6050 	glBegin(GL_QUADS);
6051 	glVertex2i(mx-borderWidth, my-borderWidth);
6052 	glVertex2i(mx-borderWidth, my);
6053 	glVertex2i(mx+mw+borderWidth, my);
6054 	glVertex2i(mx+mw+borderWidth, my-borderWidth);
6055 	glEnd();
6056 
6057 	glBegin(GL_QUADS);
6058 	glVertex2i(mx-borderWidth, my+mh+borderWidth);
6059 	glVertex2i(mx-borderWidth, my+mh);
6060 	glVertex2i(mx+mw+borderWidth, my+mh);
6061 	glVertex2i(mx+mw+borderWidth, my+mh+borderWidth);
6062 	glEnd();
6063 
6064 	glBegin(GL_QUADS);
6065 	glVertex2i(mx-borderWidth, my);
6066 	glVertex2i(mx-borderWidth, my+mh);
6067 	glVertex2i(mx, my+mh);
6068 	glVertex2i(mx, my);
6069 	glEnd();
6070 
6071 	glBegin(GL_QUADS);
6072 	glVertex2i(mx+mw, my);
6073 	glVertex2i(mx+mw, my+mh);
6074 	glVertex2i(mx+mw+borderWidth, my+mh);
6075 	glVertex2i(mx+mw+borderWidth, my);
6076 	glEnd();
6077 
6078 	assertGl();
6079 
6080 	glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_TEXTURE_BIT);
6081 
6082     //draw map
6083 	glEnable(GL_TEXTURE_2D);
6084 	glEnable(GL_BLEND);
6085 
6086 	glActiveTexture(fowTexUnit);
6087 	glEnable(GL_TEXTURE_2D);
6088 	glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(minimap->getFowTexture())->getHandle());
6089 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
6090 
6091 	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
6092 	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
6093 	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
6094 	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
6095 
6096 	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
6097 	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
6098 	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
6099 
6100 	glActiveTexture(baseTexUnit);
6101 	glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(minimap->getTexture())->getHandle());
6102 
6103 	glColor4f(0.5f, 0.5f, 0.5f, 0.2f);
6104 
6105 	glBegin(GL_TRIANGLE_STRIP);
6106 		glTexCoord2f(0.0f, 1.0f);
6107 		glMultiTexCoord2f(fowTexUnit, 0.0f, 1.0f);
6108 		glVertex2i(mx, my);
6109 
6110 		glTexCoord2f(0.0f, 0.0f);
6111 		glMultiTexCoord2f(fowTexUnit, 0.0f, 0.0f);
6112 		glVertex2i(mx, my+mh);
6113 
6114 		glTexCoord2f(1.0f, 1.0f);
6115 		glMultiTexCoord2f(fowTexUnit, 1.0f, 1.0f);
6116 		glVertex2i(mx+mw, my);
6117 
6118 		glTexCoord2f(1.0f, 0.0f);
6119 		glMultiTexCoord2f(fowTexUnit, 1.0f, 0.0f);
6120 		glVertex2i(mx+mw, my+mh);
6121 	glEnd();
6122 
6123     glDisable(GL_BLEND);
6124 
6125 	glActiveTexture(fowTexUnit);
6126 	glDisable(GL_TEXTURE_2D);
6127 	glActiveTexture(baseTexUnit);
6128 	glDisable(GL_TEXTURE_2D);
6129 
6130 	glEnable(GL_BLEND);
6131 
6132 	const int itemCount = attackEffects->getWaterSplashCount() * 12;
6133 	if(itemCount > 0) {
6134 		vector<Vec2f> vertices;
6135 		vertices.resize(itemCount);
6136 		vector<Vec4f> colors;
6137 		colors.resize(itemCount);
6138 
6139 		// draw attack alarm
6140 		int vertexIndex = 0;
6141 		for(int i = 0; i < attackEffects->getWaterSplashCount(); ++i) {
6142 			const WaterSplash *ws = attackEffects->getWaterSplash(i);
6143 			float scale= (1/ws->getAnim()*ws->getSize())*5;
6144 			//glColor4f(1.f, 1.f, 0.f, 1.f-ws->getAnim());
6145 			float alpha=(1.f-ws->getAnim())*0.01f;
6146 			Vec2f pos= ws->getPos()/Map::cellScale;
6147 			float attackX=mx +pos.x*zoom.x;
6148 			float attackY=my +mh -pos.y*zoom.y;
6149 			if(ws->getEnabled()){
6150 	//			glBegin(GL_QUADS);
6151 	//				glVertex2f(attackX-scale, attackY-scale);
6152 	//				glVertex2f(attackX-scale, attackY+scale);
6153 	//				glVertex2f(attackX+scale, attackY+scale);
6154 	//				glVertex2f(attackX+scale, attackY-scale);
6155 	//			glEnd();
6156 
6157 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6158 				vertices[vertexIndex] = Vec2f(attackX-scale, attackY-scale);
6159 				vertexIndex++;
6160 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6161 				vertices[vertexIndex] = Vec2f(attackX-scale, attackY+scale);
6162 				vertexIndex++;
6163 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f);
6164 				vertices[vertexIndex] = Vec2f(attackX, attackY);
6165 				vertexIndex++;
6166 
6167 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6168 				vertices[vertexIndex] = Vec2f(attackX+scale, attackY+scale);
6169 				vertexIndex++;
6170 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6171 				vertices[vertexIndex] = Vec2f(attackX-scale, attackY+scale);
6172 				vertexIndex++;
6173 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f);
6174 				vertices[vertexIndex] = Vec2f(attackX, attackY);
6175 				vertexIndex++;
6176 
6177 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6178 				vertices[vertexIndex] = Vec2f(attackX+scale, attackY+scale);
6179 				vertexIndex++;
6180 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6181 				vertices[vertexIndex] = Vec2f(attackX+scale, attackY-scale);
6182 				vertexIndex++;
6183 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f);
6184 				vertices[vertexIndex] = Vec2f(attackX, attackY);
6185 				vertexIndex++;
6186 
6187 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6188 				vertices[vertexIndex] = Vec2f(attackX+scale, attackY-scale);
6189 				vertexIndex++;
6190 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha);
6191 				vertices[vertexIndex] = Vec2f(attackX-scale, attackY-scale);
6192 				vertexIndex++;
6193 				colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f);
6194 				vertices[vertexIndex] = Vec2f(attackX, attackY);
6195 				vertexIndex++;
6196 
6197 	/*
6198 				glBegin(GL_TRIANGLES);
6199 					glColor4f(1.f, 1.f, 0.f, alpha);
6200 					glVertex2f(attackX-scale, attackY-scale);
6201 					glVertex2f(attackX-scale, attackY+scale);
6202 					glColor4f(1.f, 1.f, 0.f, 0.8f);
6203 					glVertex2f(attackX, attackY);
6204 				glEnd();
6205 				glBegin(GL_TRIANGLES);
6206 					glColor4f(1.f, 1.f, 0.f, alpha);
6207 					glVertex2f(attackX-scale, attackY+scale);
6208 					glVertex2f(attackX+scale, attackY+scale);
6209 					glColor4f(1.f, 1.f, 0.f, 0.8f);
6210 					glVertex2f(attackX, attackY);
6211 				glEnd();
6212 				glBegin(GL_TRIANGLES);
6213 					glColor4f(1.f, 1.f, 0.f, alpha);
6214 					glVertex2f(attackX+scale, attackY+scale);
6215 					glVertex2f(attackX+scale, attackY-scale);
6216 					glColor4f(1.f, 1.f, 0.f, 0.8f);
6217 					glVertex2f(attackX, attackY);
6218 				glEnd();
6219 				glBegin(GL_TRIANGLES);
6220 					glColor4f(1.f, 1.f, 0.f, alpha);
6221 					glVertex2f(attackX+scale, attackY-scale);
6222 					glVertex2f(attackX-scale, attackY-scale);
6223 					glColor4f(1.f, 1.f, 0.f, 0.8f);
6224 					glVertex2f(attackX, attackY);
6225 				glEnd();
6226 	*/
6227 
6228 			}
6229 		}
6230 
6231 		if(vertexIndex > 0) {
6232 			glEnableClientState(GL_COLOR_ARRAY);
6233 			glEnableClientState(GL_VERTEX_ARRAY);
6234 			glColorPointer(4,GL_FLOAT, 0, &colors[0]);
6235 			glVertexPointer(2, GL_FLOAT, 0, &vertices[0]);
6236 			glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexIndex);
6237 			glDisableClientState(GL_COLOR_ARRAY);
6238 			glDisableClientState(GL_VERTEX_ARRAY);
6239 		}
6240 	}
6241 
6242     glDisable(GL_BLEND);
6243 
6244 	//draw units
6245 	VisibleQuadContainerCache &qCache = getQuadCache();
6246 	std::vector<Unit *> visibleUnitList = qCache.visibleUnitList;
6247 
6248 	const bool showAllUnitsInMinimap = Config::getInstance().getBool("DebugGameSynchUI","false");
6249 	if(showAllUnitsInMinimap == true) {
6250 		visibleUnitList.clear();
6251 
6252 		const World *world= game->getWorld();
6253 		for(unsigned int i = 0; i < (unsigned int)world->getFactionCount(); ++i) {
6254 			const Faction *faction = world->getFaction(i);
6255 			for(unsigned int j = 0; j < (unsigned int)faction->getUnitCount(); ++j) {
6256 				Unit *unit = faction->getUnit(j);
6257 				visibleUnitList.push_back(unit);
6258 			}
6259 		}
6260 	}
6261 
6262 	if(visibleUnitList.empty() == false) {
6263 		uint32 unitIdx=0;
6264 		vector<Vec2f> unit_vertices;
6265 		unit_vertices.resize(visibleUnitList.size()*4);
6266 		vector<Vec3f> unit_colors;
6267 		unit_colors.resize(visibleUnitList.size()*4);
6268 
6269 		for(int visibleIndex = 0;
6270 				visibleIndex < (int)visibleUnitList.size(); ++visibleIndex) {
6271 			Unit *unit = visibleUnitList[visibleIndex];
6272 			if (unit->isAlive() == false) {
6273 				continue;
6274 			}
6275 
6276 			Vec2i pos= unit->getPos() / Map::cellScale;
6277 			int size= unit->getType()->getSize();
6278 			Vec3f color=  unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0);
6279 
6280 			unit_colors[unitIdx] = color;
6281 			unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y));
6282 			unitIdx++;
6283 
6284 			unit_colors[unitIdx] = color;
6285 			unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y));
6286 			unitIdx++;
6287 
6288 			unit_colors[unitIdx] = color;
6289 			unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y));
6290 			unitIdx++;
6291 
6292 			unit_colors[unitIdx] = color;
6293 			unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y));
6294 			unitIdx++;
6295 		}
6296 
6297 		if(unitIdx > 0) {
6298 			glEnableClientState(GL_COLOR_ARRAY);
6299 			glEnableClientState(GL_VERTEX_ARRAY);
6300 			glColorPointer(3,GL_FLOAT, 0, &unit_colors[0]);
6301 			glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]);
6302 			glDrawArrays(GL_QUADS, 0, unitIdx);
6303 			glDisableClientState(GL_COLOR_ARRAY);
6304 			glDisableClientState(GL_VERTEX_ARRAY);
6305 		}
6306 
6307 	}
6308 
6309 	renderMarkedCellsOnMinimap();
6310 
6311     //draw camera
6312 	float wRatio= static_cast<float>(metrics.getMinimapW()) / world->getMap()->getW();
6313 	float hRatio= static_cast<float>(metrics.getMinimapH()) / world->getMap()->getH();
6314 
6315     int x= static_cast<int>(gameCamera->getPos().x * wRatio);
6316     int y= static_cast<int>(gameCamera->getPos().z * hRatio);
6317 
6318     float ang= degToRad(gameCamera->getHAng());
6319 
6320     glEnable(GL_BLEND);
6321 
6322     int x1;
6323     int y1;
6324     x1 = mx + x + static_cast<int>(20*std::sin(ang-pi/5));
6325     y1 = my + mh - (y-static_cast<int>(20*std::cos(ang-pi/5)));
6326 
6327     int x2;
6328     int y2;
6329     x2 = mx + x + static_cast<int>(20*std::sin(ang+pi/5));
6330     y2 = my + mh - (y-static_cast<int>(20*std::cos(ang+pi/5)));
6331 
6332     glColor4f(1.f, 1.f, 1.f, 1.f);
6333     glBegin(GL_TRIANGLES);
6334 
6335 	glVertex2i(mx+x, my+mh-y);
6336 	glColor4f(1.f, 1.f, 1.f, 0.0f);
6337 	glVertex2i(x1,y1);
6338 	glColor4f(1.f, 1.f, 1.f, 0.0f);
6339     glVertex2i(x2,y2);
6340 
6341     glEnd();
6342 
6343     glPopAttrib();
6344 
6345 	assertGl();
6346 }
6347 
6348 void Renderer::renderHighlightedCellsOnMinimap() {
6349 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6350 		return;
6351 	}
6352 	// Draw marked cells
6353 	const std::vector<MarkedCell> *highlightedCells = game->getHighlightedCells();
6354 	if(highlightedCells->empty() == false) {
6355 		//const Map *map= game->getWorld()->getMap();
6356 	    const World *world= game->getWorld();
6357 		const Minimap *minimap= world->getMinimap();
6358 		int pointersize=10;
6359 		if(minimap == NULL || minimap->getTexture() == NULL) {
6360 			return;
6361 		}
6362 
6363 		//const GameCamera *gameCamera= game->getGameCamera();
6364 		const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst();
6365 		const Metrics &metrics= Metrics::getInstance();
6366 
6367 
6368 		//int mx= metrics.getMinimapX();
6369 		int my= metrics.getMinimapY();
6370 		int mw= metrics.getMinimapW();
6371 		int mh= metrics.getMinimapH();
6372 
6373 		Vec2f zoom= Vec2f(
6374 			static_cast<float>(mw)/ pixmap->getW()/2,
6375 			static_cast<float>(mh)/ pixmap->getH()/2);
6376 
6377 		for(int i = 0;i < (int)highlightedCells->size(); i++) {
6378 			const MarkedCell *mc=&highlightedCells->at(i);
6379 			if(mc->getFaction() == NULL || (mc->getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) {
6380 				const Texture2D *texture= game->getHighlightCellTexture();
6381 				Vec3f color(MarkedCell::static_system_marker_color);
6382 				if(mc->getFaction() != NULL) {
6383 					color=  mc->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0);
6384 				}
6385 				int lighting=(mc->getAliveCount()%15);
6386 				Vec3f myColor=Vec3f(color.x/2+.5f/lighting,color.y/2+.5f/lighting,color.z/2+.5f/lighting);
6387 
6388 				Vec2i pos=mc->getTargetPos();
6389 				if(texture != NULL) {
6390 					//float alpha = 0.49f+0.5f/(mc->getAliveCount()%15);
6391 					float alpha=1.0f;
6392 					renderTextureQuad((int)(pos.x*zoom.x)+pointersize, my + mh-(int)(pos.y*zoom.y), pointersize, pointersize, texture, alpha,&myColor);
6393 				}
6394 			}
6395 		}
6396 	}
6397 }
6398 
6399 void Renderer::renderMarkedCellsOnMinimap() {
6400 	// Draw marked cells
6401 	std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
6402 	if(markedCells.empty() == false) {
6403 		//const Map *map= game->getWorld()->getMap();
6404 	    const World *world= game->getWorld();
6405 		const Minimap *minimap= world->getMinimap();
6406 
6407 		if(minimap == NULL || minimap->getTexture() == NULL) {
6408 			return;
6409 		}
6410 
6411 		//const GameCamera *gameCamera= game->getGameCamera();
6412 		const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst();
6413 		const Metrics &metrics= Metrics::getInstance();
6414 		//const WaterEffects *attackEffects= world->getAttackEffects();
6415 
6416 		int mx= metrics.getMinimapX();
6417 		int my= metrics.getMinimapY();
6418 		int mw= metrics.getMinimapW();
6419 		int mh= metrics.getMinimapH();
6420 
6421 		Vec2f zoom= Vec2f(
6422 			static_cast<float>(mw)/ pixmap->getW(),
6423 			static_cast<float>(mh)/ pixmap->getH());
6424 
6425 		uint32 unitIdx=0;
6426 		vector<Vec2f> unit_vertices;
6427 		unit_vertices.resize(markedCells.size()*4);
6428 		vector<Vec4f> unit_colors;
6429 		unit_colors.resize(markedCells.size()*4);
6430 
6431 		for(std::map<Vec2i, MarkedCell>::iterator iterMap =markedCells.begin();
6432 				iterMap != markedCells.end(); ++iterMap) {
6433 			MarkedCell &bm = iterMap->second;
6434 			if(bm.getPlayerIndex() < 0 ||
6435 				(bm.getFaction() != NULL &&
6436 				bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) {
6437 				Vec2i pos= bm.getTargetPos() / Map::cellScale;
6438 				float size= 0.5f;
6439 
6440 				Vec3f color(MarkedCell::static_system_marker_color);
6441 				if(bm.getFaction() != NULL) {
6442 					color=  bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0);
6443 				}
6444 				float alpha = 0.65f;
6445 
6446 				unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
6447 				unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y));
6448 				unitIdx++;
6449 
6450 				unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
6451 				unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y));
6452 				unitIdx++;
6453 
6454 				unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
6455 				unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y));
6456 				unitIdx++;
6457 
6458 				unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
6459 				unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y));
6460 				unitIdx++;
6461 			}
6462 		}
6463 
6464 		if(unitIdx > 0) {
6465 			glEnable(GL_BLEND);
6466 
6467 			glEnableClientState(GL_COLOR_ARRAY);
6468 			glEnableClientState(GL_VERTEX_ARRAY);
6469 			glColorPointer(4,GL_FLOAT, 0, &unit_colors[0]);
6470 			glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]);
6471 			glDrawArrays(GL_QUADS, 0, unitIdx);
6472 			//glDrawArrays(GL_TRIANGLE_STRIP, 0, unitIdx);
6473 			glDisableClientState(GL_COLOR_ARRAY);
6474 			glDisableClientState(GL_VERTEX_ARRAY);
6475 
6476 			glDisable(GL_BLEND);
6477 		}
6478 	}
6479 }
6480 void Renderer::renderVisibleMarkedCells(bool renderTextHint,int x, int y) {
6481 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6482 		return;
6483 	}
6484 
6485 	// Draw marked cells
6486 	std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
6487 	if(markedCells.empty() == false) {
6488 		const Texture2D *texture= game->getMarkCellTexture();
6489 		const int yOffset = -40;
6490 
6491 		for(std::map<Vec2i, MarkedCell>::iterator iterMap =markedCells.begin();
6492 				iterMap != markedCells.end(); ++iterMap) {
6493 			MarkedCell &bm = iterMap->second;
6494 			if(bm.getPlayerIndex() < 0 ||
6495 				(bm.getFaction() != NULL &&
6496 				 bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) {
6497 				const Map *map= game->getWorld()->getMap();
6498 				std::pair<bool,Vec3f> bmVisible = posInCellQuadCache(
6499 						map->toSurfCoords(bm.getTargetPos()));
6500 				if(bmVisible.first == true) {
6501 					if(renderTextHint == true) {
6502 						if(bm.getNote() != "") {
6503 							bool validPosObjWorld= x > bmVisible.second.x &&
6504 													y > bmVisible.second.y + yOffset &&
6505 													x < bmVisible.second.x + texture->getTextureWidth() &&
6506 													y < bmVisible.second.y + yOffset + texture->getTextureHeight();
6507 
6508 							if(validPosObjWorld) {
6509 								//printf("Checking for hint text render mouse [%d,%d] marker pos [%d,%d] validPosObjWorld = %d, hint [%s]\n",x,y,bm.getTargetPos().x,bm.getTargetPos().y,validPosObjWorld,bm.getNote().c_str());
6510 
6511 								//Lang &lang= Lang::getInstance();
6512 								Vec4f fontColor = Vec4f(1.0f, 1.0f, 1.0f, 0.25f);
6513 
6514 								if(renderText3DEnabled == true) {
6515 									renderTextShadow3D(bm.getNote(), CoreData::getInstance().getConsoleFont3D(), fontColor,
6516 											bmVisible.second.x, bmVisible.second.y);
6517 								}
6518 								else {
6519 									renderTextShadow(bm.getNote(), CoreData::getInstance().getConsoleFont(), fontColor,
6520 											bmVisible.second.x, bmVisible.second.y);
6521 								}
6522 							}
6523 						}
6524 					}
6525 					else {
6526 
6527 
6528 /*
6529 						//texture 0
6530 						glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
6531 
6532 						//set color to interpolation
6533 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
6534 
6535 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
6536 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
6537 
6538 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1);
6539 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
6540 
6541 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
6542 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
6543 
6544 						//set alpha to 1
6545 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
6546 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
6547 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
6548 
6549 						//texture 1
6550 						glActiveTexture(GL_TEXTURE1);
6551 						glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f);
6552 						glEnable(GL_TEXTURE_2D);
6553 
6554 						glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(bm.getFaction()->getTexture())->getHandle());
6555 						glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
6556 
6557 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
6558 
6559 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
6560 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
6561 
6562 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
6563 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
6564 
6565 						//set alpha to 1
6566 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
6567 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
6568 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
6569 
6570 						glActiveTexture(GL_TEXTURE0);
6571 */
6572 
6573 						glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
6574 						glEnable(GL_BLEND);
6575 						glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6576 
6577 						Vec3f color(MarkedCell::static_system_marker_color);
6578 						if(bm.getFaction() != NULL) {
6579 							color = bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0);
6580 						}
6581 
6582 						renderTextureQuad(
6583 								bmVisible.second.x,bmVisible.second.y + yOffset,
6584 								texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f,&color);
6585 
6586 /*
6587 						glActiveTexture(GL_TEXTURE1);
6588 						glDisable(GL_TEXTURE_2D);
6589 						glActiveTexture(GL_TEXTURE0);
6590 						glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
6591 */
6592 					}
6593 				}
6594 			}
6595 		}
6596 	}
6597 }
6598 
6599 void Renderer::renderDisplay() {
6600 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6601 		return;
6602 	}
6603 
6604 	CoreData &coreData= CoreData::getInstance();
6605 	const Metrics &metrics= Metrics::getInstance();
6606 	const Display *display= game->getGui()->getDisplay();
6607 
6608 	glPushAttrib(GL_ENABLE_BIT);
6609 
6610 	if(renderText3DEnabled == true) {
6611 		//infoString
6612 		renderTextShadow3D(
6613 			display->getInfoText().c_str(),
6614 			coreData.getDisplayFont3D(),
6615 			display->getColor(),
6616 			metrics.getDisplayX(),
6617 			metrics.getDisplayY()+Display::infoStringY);
6618 
6619 		//title
6620 		renderTextShadow3D(
6621 			display->getTitle().c_str(),
6622 			coreData.getDisplayFont3D(),
6623 			display->getColor(),
6624 			metrics.getDisplayX()+40,
6625 			metrics.getDisplayY() + metrics.getDisplayH() - 20);
6626 
6627 		glColor3f(0.0f, 0.0f, 0.0f);
6628 
6629 		//text
6630 		renderTextShadow3D(
6631 			display->getText().c_str(),
6632 			coreData.getDisplayFont3D(),
6633 			display->getColor(),
6634 			metrics.getDisplayX() -1,
6635 			metrics.getDisplayY() + metrics.getDisplayH() - 56);
6636 
6637 		//progress Bar
6638 		if(display->getProgressBar() != -1) {
6639 			renderProgressBar3D(
6640 				display->getProgressBar(),
6641 				metrics.getDisplayX(),
6642 				metrics.getDisplayY() + metrics.getDisplayH()-50,
6643 				coreData.getDisplayFontSmall3D(), 175);
6644 		}
6645 	}
6646 	else {
6647 		//infoString
6648 		renderTextShadow(
6649 			display->getInfoText().c_str(),
6650 			coreData.getDisplayFont(),
6651 			display->getColor(),
6652 			metrics.getDisplayX(),
6653 			metrics.getDisplayY()+Display::infoStringY);
6654 
6655 		//title
6656 		renderTextShadow(
6657 			display->getTitle().c_str(),
6658 			coreData.getDisplayFont(),
6659 			display->getColor(),
6660 			metrics.getDisplayX()+40,
6661 			metrics.getDisplayY() + metrics.getDisplayH() - 20);
6662 
6663 		glColor3f(0.0f, 0.0f, 0.0f);
6664 
6665 		//text
6666 		renderTextShadow(
6667 			display->getText().c_str(),
6668 			coreData.getDisplayFont(),
6669 			display->getColor(),
6670 			metrics.getDisplayX() -1,
6671 			metrics.getDisplayY() + metrics.getDisplayH() - 56);
6672 
6673 		//progress Bar
6674 		if(display->getProgressBar()!=-1){
6675 			renderProgressBar(
6676 				display->getProgressBar(),
6677 				metrics.getDisplayX(),
6678 				metrics.getDisplayY() + metrics.getDisplayH()-50,
6679 				coreData.getDisplayFontSmall());
6680 		}
6681 	}
6682 
6683 	//up images
6684 	glEnable(GL_TEXTURE_2D);
6685 
6686 	glColor3f(1.f, 1.f, 1.f);
6687 	for(int i=0; i<Display::upCellCount; ++i){
6688 		if(display->getUpImage(i)!=NULL){
6689 			renderQuad(
6690 				metrics.getDisplayX()+display->computeUpX(i),
6691 				metrics.getDisplayY()+display->computeUpY(i),
6692 				display->getUpImageSize(), display->getUpImageSize(), display->getUpImage(i));
6693 		}
6694 	}
6695 
6696  	//down images
6697 	for(int i=0; i<Display::downCellCount; ++i){
6698 		if(display->getDownImage(i)!=NULL){
6699 			if(display->getDownLighted(i)){
6700                 glColor3f(1.f, 1.f, 1.f);
6701 			}
6702 			else{
6703                 glColor3f(0.3f, 0.3f, 0.3f);
6704 			}
6705 
6706 			int x= metrics.getDisplayX()+display->computeDownX(i);
6707 			int y= metrics.getDisplayY()+display->computeDownY(i);
6708 			int size= Display::imageSize;
6709 
6710 			if(display->getDownSelectedPos()==i){
6711 				x-= 3;
6712 				y-= 3;
6713 				size+= 6;
6714 			}
6715 
6716 			renderQuad(x, y, size, size, display->getDownImage(i));
6717 		}
6718 	}
6719 
6720 	//selection
6721 	int downPos= display->getDownSelectedPos();
6722 	if(downPos!=Display::invalidPos){
6723 		const Texture2D *texture= display->getDownImage(downPos);
6724 		if(texture!=NULL){
6725 			int x= metrics.getDisplayX()+display->computeDownX(downPos)-3;
6726 			int y= metrics.getDisplayY()+display->computeDownY(downPos)-3;
6727 			int size= Display::imageSize+6;
6728 			renderQuad(x, y, size, size, display->getDownImage(downPos));
6729 		}
6730     }
6731 
6732 	glPopAttrib();
6733 }
6734 
6735 void Renderer::renderMenuBackground(const MenuBackground *menuBackground) {
6736 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6737 		return;
6738 	}
6739 
6740 	assertGl();
6741 
6742 	const Vec3f &cameraPosition= menuBackground->getCamera()->getConstPosition();
6743 
6744 	glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
6745 
6746 	//clear
6747 	Vec4f fogColor= Vec4f(0.4f, 0.4f, 0.4f, 1.f) * menuBackground->getFade();
6748 	glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f);
6749 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6750 	glFogfv(GL_FOG_COLOR, fogColor.ptr());
6751 
6752 	//light
6753 	Vec4f lightPos= Vec4f(10.f, 10.f, 10.f, 1.f)* menuBackground->getFade();
6754 	Vec4f diffLight= Vec4f(0.9f, 0.9f, 0.9f, 1.f)* menuBackground->getFade();
6755 	Vec4f ambLight= Vec4f(0.3f, 0.3f, 0.3f, 1.f)* menuBackground->getFade();
6756 	Vec4f specLight= Vec4f(0.1f, 0.1f, 0.1f, 1.f)* menuBackground->getFade();
6757 
6758 	glEnable(GL_LIGHT0);
6759 	glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr());
6760 	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr());
6761 	glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr());
6762 	glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr());
6763 
6764 	//main model
6765 	glEnable(GL_ALPHA_TEST);
6766 	glAlphaFunc(GL_GREATER, 0.5f);
6767 	modelRenderer->begin(true, true, true, false);
6768 	menuBackground->getMainModelPtr()->updateInterpolationData(menuBackground->getAnim(), true);
6769 	modelRenderer->render(menuBackground->getMainModelPtr());
6770 	modelRenderer->end();
6771 	glDisable(GL_ALPHA_TEST);
6772 
6773 	//characters
6774 	float dist= menuBackground->getAboutPosition().dist(cameraPosition);
6775 	float minDist= 3.f;
6776 	if(dist < minDist) {
6777 
6778 		glAlphaFunc(GL_GREATER, 0.0f);
6779 		float alpha= clamp((minDist-dist) / minDist, 0.f, 1.f);
6780 		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr());
6781 
6782 		std::vector<Vec3f> &characterMenuScreenPositionListCache =
6783 				CacheManager::getCachedItem< std::vector<Vec3f> >(GameConstants::characterMenuScreenPositionListCacheLookupKey);
6784 		characterMenuScreenPositionListCache.clear();
6785 
6786 		modelRenderer->begin(true, true, false, false);
6787 
6788 		for(int i=0; i < MenuBackground::characterCount; ++i) {
6789 			glMatrixMode(GL_MODELVIEW);
6790 			glPushMatrix();
6791 			glLoadIdentity();
6792 
6793 			Vec3f worldPos(i*2.f-4.f, -1.4f, -7.5f);
6794 			glTranslatef(worldPos.x,worldPos.y,worldPos.z);
6795 
6796 			//
6797 			// Get the screen coordinates for each character model - START
6798 			//std::vector<GLdouble> projection(16);
6799 			//std::vector<GLdouble> modelview(16);
6800 			//std::vector<GLdouble> screen_coords(3);
6801 
6802 			//glGetDoublev(GL_PROJECTION_MATRIX, projection.data());
6803 			//glGetDoublev(GL_MODELVIEW_MATRIX, modelview.data());
6804 
6805 			const Metrics &metrics= Metrics::getInstance();
6806 			GLint viewport[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()};
6807 
6808 			//get matrices
6809 			GLdouble projection[16];
6810 			glGetDoublev(GL_PROJECTION_MATRIX, projection);
6811 
6812 			GLdouble modelview[16];
6813 			glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
6814 
6815 			//get the screen coordinates
6816 			GLdouble screen_coords[3];
6817 
6818 			gluProject(worldPos.x, worldPos.y, worldPos.z,
6819 			    modelview, projection, viewport,
6820 			    &screen_coords[0], &screen_coords[1], &screen_coords[2]);
6821 			characterMenuScreenPositionListCache.push_back(Vec3f(screen_coords[0],screen_coords[1],screen_coords[2]));
6822 			// Get the screen coordinates for each character model - END
6823 			//
6824 
6825 			menuBackground->getCharacterModelPtr(i)->updateInterpolationData(menuBackground->getAnim(), true);
6826 			modelRenderer->render(menuBackground->getCharacterModelPtr(i));
6827 
6828 			glPopMatrix();
6829 		}
6830 		modelRenderer->end();
6831 	}
6832 
6833 	//water
6834 	if(menuBackground->getWater()) {
6835 
6836 		//water surface
6837 		const int waterTesselation= 10;
6838 		const int waterSize= 250;
6839 		const int waterQuadSize= 2*waterSize/waterTesselation;
6840 		const float waterHeight= menuBackground->getWaterHeight();
6841 
6842 		glEnable(GL_BLEND);
6843 
6844 		glNormal3f(0.f, 1.f, 0.f);
6845 		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.f, 1.f, 1.f, 1.f).ptr());
6846 		GLuint waterHandle= static_cast<Texture2DGl*>(menuBackground->getWaterTexture())->getHandle();
6847 		glBindTexture(GL_TEXTURE_2D, waterHandle);
6848 		for(int i=1; i < waterTesselation; ++i) {
6849 			glBegin(GL_TRIANGLE_STRIP);
6850 			for(int j=1; j < waterTesselation; ++j) {
6851 				glTexCoord2i(1, 2 % j);
6852 				glVertex3f(-waterSize+i*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize);
6853 				glTexCoord2i(0, 2 % j);
6854 				glVertex3f(-waterSize+(i+1)*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize);
6855 			}
6856 			glEnd();
6857 		}
6858 		glDisable(GL_BLEND);
6859 
6860 		//raindrops
6861 		if(menuBackground->getRain()) {
6862 			const float maxRaindropAlpha= 0.5f;
6863 
6864 			glEnable(GL_BLEND);
6865 			glDisable(GL_LIGHTING);
6866 			glDisable(GL_ALPHA_TEST);
6867 			glDepthMask(GL_FALSE);
6868 
6869 			//splashes
6870 			CoreData &coreData= CoreData::getInstance();
6871 			glBindTexture(GL_TEXTURE_2D, static_cast<Texture2DGl*>(coreData.getWaterSplashTexture())->getHandle());
6872 			for(int i=0; i< MenuBackground::raindropCount; ++i) {
6873 
6874 				Vec2f pos= menuBackground->getRaindropPos(i);
6875 				float scale= menuBackground->getRaindropState(i);
6876 				float alpha= maxRaindropAlpha-scale*maxRaindropAlpha;
6877 
6878 				glMatrixMode(GL_MODELVIEW);
6879 				glPushMatrix();
6880 
6881 				glColor4f(1.f, 1.f, 1.f, alpha);
6882 				glTranslatef(pos.x, waterHeight+0.01f, pos.y);
6883 
6884 				glBegin(GL_TRIANGLE_STRIP);
6885 					glTexCoord2f(0.f, 1.f);
6886 					glVertex3f(-scale, 0, scale);
6887 					glTexCoord2f(0.f, 0.f);
6888 					glVertex3f(-scale, 0, -scale);
6889 					glTexCoord2f(1.f, 1.f);
6890 					glVertex3f(scale, 0, scale);
6891 					glTexCoord2f(1.f, 0.f);
6892 					glVertex3f(scale, 0, -scale);
6893 				glEnd();
6894 
6895 				glPopMatrix();
6896 			}
6897 		}
6898 	}
6899 
6900 	glPopAttrib();
6901 
6902 	assertGl();
6903 }
6904 
6905 void Renderer::renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector<Model *> characterModels,const Vec3f characterPosition, float anim) {
6906 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
6907 		return;
6908 	}
6909 
6910 	assertGl();
6911 
6912 	const Vec3f &cameraPosition= camera->getConstPosition();
6913 
6914 	glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT);
6915 
6916 	//clear
6917 	//Vec4f fogColor= Vec4f(0.4f, 0.4f, 0.4f, 1.f) * fade;
6918 	// Show black bacground
6919 	Vec4f fogColor= Vec4f(0.f, 0.f, 0.f, 1.f);
6920 	glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f);
6921 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6922 	glFogfv(GL_FOG_COLOR, fogColor.ptr());
6923 
6924 	//light
6925 	Vec4f lightPos= Vec4f(10.f, 10.f, 10.f, 1.f)  * fade;
6926 	Vec4f diffLight= Vec4f(0.9f, 0.9f, 0.9f, 1.f) * fade;
6927 	Vec4f ambLight= Vec4f(0.3f, 0.3f, 0.3f, 1.f)  * fade;
6928 	Vec4f specLight= Vec4f(0.1f, 0.1f, 0.1f, 1.f) * fade;
6929 
6930 	glEnable(GL_LIGHT0);
6931 	glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr());
6932 	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr());
6933 	glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr());
6934 	glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr());
6935 
6936 	//main model
6937 	if(mainModel) {
6938 		glEnable(GL_ALPHA_TEST);
6939 		glAlphaFunc(GL_GREATER, 0.5f);
6940 		modelRenderer->begin(true, true, true, false);
6941 		mainModel->updateInterpolationData(anim, true);
6942 		modelRenderer->render(mainModel);
6943 		modelRenderer->end();
6944 		glDisable(GL_ALPHA_TEST);
6945 	}
6946 
6947 	//characters
6948 	if(characterModels.empty() == false) {
6949 		float dist= characterPosition.dist(cameraPosition);
6950 		float minDist= 3.f;
6951 		if(dist < minDist) {
6952 			glAlphaFunc(GL_GREATER, 0.0f);
6953 			float alpha= clamp((minDist-dist) / minDist, 0.f, 1.f);
6954 			glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr());
6955 			modelRenderer->begin(true, true, false, false);
6956 
6957 			for(unsigned int i = 0; i < characterModels.size(); ++i) {
6958 				if(characterModels[i]) {
6959 					glMatrixMode(GL_MODELVIEW);
6960 					glPushMatrix();
6961 					glLoadIdentity();
6962 					glTranslatef(i*2.f-4.f, -1.4f, -7.5f);
6963 					characterModels[i]->updateInterpolationData(anim, true);
6964 					modelRenderer->render(characterModels[i]);
6965 					glPopMatrix();
6966 				}
6967 			}
6968 			modelRenderer->end();
6969 		}
6970 	}
6971 
6972 
6973 	glPopAttrib();
6974 
6975 	assertGl();
6976 }
6977 
6978 // ==================== computing ====================
6979 
6980 bool Renderer::ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) {
6981 	assertGl();
6982 	const Map* map= game->getWorld()->getMap();
6983 	const Metrics &metrics= Metrics::getInstance();
6984 	float depth= 0.0f;
6985 	GLdouble modelviewMatrix[16];
6986 	GLdouble projectionMatrix[16];
6987 	GLint viewport[4]= {0, 0, metrics.getScreenW(), metrics.getScreenH()};
6988 	GLdouble worldX;
6989 	GLdouble worldY;
6990 	GLdouble worldZ;
6991 	GLint screenX= (screenPos.x * metrics.getScreenW() / metrics.getVirtualW());
6992 	GLint screenY= (screenPos.y * metrics.getScreenH() / metrics.getVirtualH());
6993 
6994 	//get the depth in the cursor pixel
6995 	glReadPixels(screenX, screenY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
6996 
6997 	//load matrices
6998 	loadProjectionMatrix();
6999     loadGameCameraMatrix();
7000 
7001 	//get matrices
7002 	glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
7003 	glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
7004 
7005 	//get the world coordinates
7006 	gluUnProject(
7007 		screenX, screenY, depth,
7008 		modelviewMatrix, projectionMatrix, viewport,
7009 		&worldX, &worldY, &worldZ);
7010 
7011 	//conver coords to int
7012 	if(exactCoords == true) {
7013 		worldPos= Vec2i(static_cast<int>(worldX), static_cast<int>(worldZ));
7014 	}
7015 	else {
7016 		worldPos= Vec2i(static_cast<int>(worldX+0.5f), static_cast<int>(worldZ+0.5f));
7017 	}
7018 
7019 	//clamp coords to map size
7020 	return map->isInside(worldPos);
7021 }
7022 
7023 // This method takes world co-ordinates and translates them to screen co-ords
7024 Vec3f Renderer::computeScreenPosition(const Vec3f &worldPos) {
7025 	if(worldToScreenPosCache.find(worldPos) != worldToScreenPosCache.end()) {
7026 		return worldToScreenPosCache[worldPos];
7027 	}
7028 	assertGl();
7029 
7030 	const Metrics &metrics= Metrics::getInstance();
7031 	GLint viewport[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()};
7032 	GLdouble worldX = worldPos.x;
7033 	GLdouble worldY = worldPos.y;
7034 	GLdouble worldZ = worldPos.z;
7035 
7036 	//load matrices
7037 	loadProjectionMatrix();
7038     loadGameCameraMatrix();
7039 
7040 	//get matrices
7041 	GLdouble modelviewMatrix[16];
7042 	glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
7043 	GLdouble projectionMatrix[16];
7044 	glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
7045 
7046 	//get the screen coordinates
7047 	GLdouble screenX;
7048 	GLdouble screenY;
7049 	GLdouble screenZ;
7050 	gluProject(worldX, worldY, worldZ,
7051 		modelviewMatrix, projectionMatrix, viewport,
7052 		&screenX, &screenY, &screenZ);
7053 
7054 	Vec3f screenPos(screenX,screenY,screenZ);
7055 	worldToScreenPosCache[worldPos]=screenPos;
7056 
7057 	return screenPos;
7058 }
7059 
7060 void Renderer::computeSelected(	Selection::UnitContainer &units, const Object *&obj,
7061 								const bool withObjectSelection,
7062 								const Vec2i &posDown, const Vec2i &posUp) {
7063 	const string selectionType=toLower(Config::getInstance().getString("SelectionType",Config::colorPicking));
7064 
7065 	if(selectionType==Config::colorPicking) {
7066 		selectUsingColorPicking(units,obj, withObjectSelection,posDown, posUp);
7067 	}
7068 	/// Frustum approach --> Currently not accurate enough
7069 	else if(selectionType==Config::frustumPicking) {
7070 		selectUsingFrustumSelection(units,obj, withObjectSelection,posDown, posUp);
7071 	}
7072 	else {
7073 		selectUsingSelectionBuffer(units,obj, withObjectSelection,posDown, posUp);
7074 	}
7075 }
7076 
7077 void Renderer::selectUsingFrustumSelection(Selection::UnitContainer &units,
7078 		const Object *&obj, const bool withObjectSelection,
7079 		const Vec2i &posDown, const Vec2i &posUp) {
7080 	glMatrixMode(GL_PROJECTION);
7081 	glPushMatrix();
7082 	glLoadIdentity();
7083 
7084 	const Metrics &metrics= Metrics::getInstance();
7085 	GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()};
7086 
7087 	//compute center and dimensions of selection rectangle
7088 	int x = (posDown.x+posUp.x) / 2;
7089 	int y = (posDown.y+posUp.y) / 2;
7090 	int w = abs(posDown.x-posUp.x);
7091 	int h = abs(posDown.y-posUp.y);
7092 	if(w < 2) {
7093 		w = 2;
7094 	}
7095 	if(h < 2) {
7096 		h = 2;
7097 	}
7098 
7099 	gluPickMatrix(x, y, w, h, view);
7100 	gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane);
7101 	loadGameCameraMatrix();
7102 
7103 	VisibleQuadContainerCache quadSelectionCacheItem;
7104 	ExtractFrustum(quadSelectionCacheItem);
7105 
7106 	//pop matrices
7107 	glMatrixMode(GL_PROJECTION);
7108 	glPopMatrix();
7109 
7110 	VisibleQuadContainerCache &qCache = getQuadCache();
7111 	if(qCache.visibleQuadUnitList.empty() == false) {
7112 		for(int visibleUnitIndex = 0;
7113 				visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
7114 			Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
7115 			if(unit != NULL && unit->isAlive()) {
7116 				Vec3f unitPos = unit->getCurrMidHeightVector();
7117 				bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData,
7118 						unitPos.x, unitPos.y, unitPos.z, unit->getType()->getRenderSize());
7119 				if(insideQuad == true) {
7120 					units.push_back(unit);
7121 				}
7122 			}
7123 		}
7124 	}
7125 
7126 	if(withObjectSelection == true) {
7127 		if(qCache.visibleObjectList.empty() == false) {
7128 			for(int visibleIndex = 0;
7129 					visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) {
7130 				Object *object = qCache.visibleObjectList[visibleIndex];
7131 				if(object != NULL) {
7132 					bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData,
7133 							object->getPos().x, object->getPos().y, object->getPos().z, 1);
7134 					if(insideQuad == true) {
7135 						obj = object;
7136 						if(withObjectSelection == true) {
7137 							break;
7138 						}
7139 					}
7140 				}
7141 			}
7142 		}
7143 	}
7144 }
7145 
7146 void Renderer::selectUsingSelectionBuffer(Selection::UnitContainer &units,
7147 		const Object *&obj, const bool withObjectSelection,
7148 		const Vec2i &posDown, const Vec2i &posUp) {
7149 	//compute center and dimensions of selection rectangle
7150 	int x = (posDown.x+posUp.x) / 2;
7151 	int y = (posDown.y+posUp.y) / 2;
7152 	int w = abs(posDown.x-posUp.x);
7153 	int h = abs(posDown.y-posUp.y);
7154 	if(w < 2) {
7155 		w = 2;
7156 	}
7157 	if(h < 2) {
7158 		h = 2;
7159 	}
7160 
7161 	//declarations
7162 	GLuint selectBuffer[Gui::maxSelBuff];
7163 
7164 	//setup matrices
7165 	glSelectBuffer(Gui::maxSelBuff, selectBuffer);
7166 	//glMatrixMode(GL_PROJECTION);
7167 	//glPushMatrix();
7168 
7169 	GLint renderModeResult = glRenderMode(GL_SELECT);
7170 	if(renderModeResult < 0) {
7171 		const char *errorString= reinterpret_cast<const char*>(gluErrorString(renderModeResult));
7172 		char szBuf[8096]="";
7173 		snprintf(szBuf,8096,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",renderModeResult,renderModeResult,errorString,extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
7174 
7175 		printf("%s\n",szBuf);
7176 	}
7177 
7178 
7179 	glPushMatrix();
7180 	glMatrixMode(GL_PROJECTION);
7181 
7182 	glLoadIdentity();
7183 
7184 	const Metrics &metrics= Metrics::getInstance();
7185 	GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()};
7186 	//GLint view[4];
7187 	//glGetIntegerv(GL_VIEWPORT, view);
7188 
7189 	gluPickMatrix(x, y, w, h, view);
7190 	gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane);
7191 	//gluPerspective(perspFov, metrics.getAspectRatio(), 0.0001, 1000.0);
7192 	//gluPerspective(perspFov, (float)view[2]/(float)view[3], perspNearPlane, perspFarPlane);
7193 	loadGameCameraMatrix();
7194 
7195 	//render units to find which ones should be selected
7196 	renderUnitsFast();
7197 	if(withObjectSelection == true) {
7198 		renderObjectsFast(false,true);
7199 	}
7200 
7201 	//pop matrices
7202 	glPopMatrix();
7203 
7204 	// Added this to ensure all the selection calls are done now
7205 	// (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4])
7206 	//glFlush();
7207 
7208 	//select units by checking the selected buffer
7209 	int selCount= glRenderMode(GL_RENDER);
7210 	if(selCount > 0) {
7211 		VisibleQuadContainerCache &qCache = getQuadCache();
7212 		for(int i = 1; i <= selCount; ++i) {
7213 			int index = selectBuffer[i*4-1];
7214 			if(index >= OBJECT_SELECT_OFFSET) {
7215 				Object *object = qCache.visibleObjectList[index - OBJECT_SELECT_OFFSET];
7216 				if(object != NULL) {
7217 					obj = object;
7218 					if(withObjectSelection == true) {
7219 						break;
7220 					}
7221 				}
7222 			}
7223 			else {
7224 				Unit *unit = qCache.visibleQuadUnitList[index];
7225 				if(unit != NULL && unit->isAlive()) {
7226 					units.push_back(unit);
7227 				}
7228 			}
7229 		}
7230 	}
7231 	else if(selCount < 0) {
7232 		const char *errorString= reinterpret_cast<const char*>(gluErrorString(selCount));
7233 		char szBuf[8096]="";
7234 		snprintf(szBuf,8096,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",selCount,selCount,errorString,extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
7235 
7236 		printf("%s\n",szBuf);
7237 	}
7238 }
7239 
7240 void Renderer::selectUsingColorPicking(Selection::UnitContainer &units,
7241 		const Object *&obj, const bool withObjectSelection,
7242 		const Vec2i &posDown, const Vec2i &posUp) {
7243 	int x1 = posDown.x;
7244 	int y1 = posDown.y;
7245 	int x2 = posUp.x;
7246 	int y2 = posUp.y;
7247 
7248 	int x = min(x1,x2);
7249 	int y = min(y1,y2);
7250 	int w = max(x1,x2) - min(x1,x2);
7251 	int h = max(y1,y2) - min(y1,y2);
7252 	if(w < 2) {
7253 		w = 2;
7254 	}
7255 	if(h < 2) {
7256 		h = 2;
7257 	}
7258 
7259 	const Metrics &metrics= Metrics::getInstance();
7260 	x= (x * metrics.getScreenW() / metrics.getVirtualW());
7261 	y= (y * metrics.getScreenH() / metrics.getVirtualH());
7262 
7263 	w= (w * metrics.getScreenW() / metrics.getVirtualW());
7264 	h= (h * metrics.getScreenH() / metrics.getVirtualH());
7265 
7266 	PixelBufferWrapper::begin();
7267 
7268 
7269 	glPushMatrix();
7270 	glMatrixMode(GL_PROJECTION);
7271 	glLoadIdentity();
7272 	//GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()};
7273 	//gluPickMatrix(x, y, w, h, view);
7274 	gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane);
7275 	loadGameCameraMatrix();
7276 
7277 	//render units to find which ones should be selected
7278 	//printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7279 
7280 	vector<Unit *> rendererUnits = renderUnitsFast(false, true);
7281 	//printf("In [%s::%s] Line: %d rendererUnits = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,rendererUnits.size());
7282 
7283 
7284 	// Added this to ensure all the selection calls are done now
7285 	// (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4])
7286 	//glFlush();
7287 
7288 	//GraphicsInterface::getInstance().getCurrentContext()->swapBuffers();
7289 
7290 	PixelBufferWrapper::end();
7291 
7292 	vector<BaseColorPickEntity *> unitsVector;
7293 	bool unitFound=false;
7294 
7295 	if(rendererUnits.empty() == false) {
7296 		copy(rendererUnits.begin(), rendererUnits.end(), std::inserter(unitsVector, unitsVector.begin()));
7297 	}
7298 
7299 	if(unitsVector.empty() == false) {
7300 		vector<int> pickedList = BaseColorPickEntity::getPickedList(x,y,w,h, unitsVector);
7301 		//printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size());
7302 
7303 		if(pickedList.empty() == false) {
7304 			units.reserve(pickedList.size());
7305 			for(unsigned int i = 0; i < pickedList.size(); ++i) {
7306 				int index = pickedList[i];
7307 				//printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size());
7308 
7309 				if(rendererUnits.empty() == false && index < (int)rendererUnits.size()) {
7310 					Unit *unit = rendererUnits[index];
7311 					if(unit != NULL && unit->isAlive()) {
7312 						unitFound=true;
7313 						units.push_back(unit);
7314 					}
7315 				}
7316 			}
7317 		}
7318 	}
7319 
7320 	if(withObjectSelection == true && unitFound==false) {
7321 		vector<Object *> rendererObjects;
7322 		vector<BaseColorPickEntity *> objectsVector;
7323 		rendererObjects = renderObjectsFast(false,true,true);
7324 		if(rendererObjects.empty() == false) {
7325 			copy(rendererObjects.begin(), rendererObjects.end(), std::inserter(objectsVector, objectsVector.begin()));
7326 		}
7327 
7328 		if(objectsVector.empty() == false) {
7329 			vector<int> pickedList = BaseColorPickEntity::getPickedList(x,y,w,h, objectsVector);
7330 			//printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size());
7331 
7332 			if(pickedList.empty() == false) {
7333 				for(unsigned int i = 0; i < pickedList.size(); ++i) {
7334 					int index = pickedList[i];
7335 					//printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size());
7336 
7337 					if(rendererObjects.empty() == false && index < (int)rendererObjects.size()) {
7338 						Object *object = rendererObjects[index];
7339 						//printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,object);
7340 
7341 						if(object != NULL) {
7342 							obj = object;
7343 							break;
7344 						}
7345 					}
7346 				}
7347 			}
7348 		}
7349 	}
7350 	//pop matrices
7351 	glPopMatrix();
7352 }
7353 
7354 // ==================== shadows ====================
7355 
7356 void Renderer::renderShadowsToTexture(const int renderFps){
7357 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
7358 		return;
7359 	}
7360 
7361 	if(shadowsOffDueToMinRender == false &&
7362 		(shadows == sProjected || shadows == sShadowMapping)) {
7363 
7364 		shadowMapFrame= (shadowMapFrame + 1) % (shadowFrameSkip + 1);
7365 
7366 		if(shadowMapFrame == 0){
7367 			assertGl();
7368 
7369 			glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT | GL_POLYGON_BIT);
7370 
7371 			if(shadows == sShadowMapping) {
7372 				glClear(GL_DEPTH_BUFFER_BIT);
7373 			}
7374 			else {
7375 				float color= 1.0f-shadowIntensity;
7376 				glColor3f(color, color, color);
7377 				glClearColor(1.f, 1.f, 1.f, 1.f);
7378 				glDisable(GL_DEPTH_TEST);
7379 				glClear(GL_COLOR_BUFFER_BIT);
7380 			}
7381 
7382 			//assertGl();
7383 
7384 			//clear color buffer
7385 			//
7386 			//set viewport, we leave one texel always in white to avoid problems
7387 			glViewport(1, 1, shadowTextureSize-2, shadowTextureSize-2);
7388 
7389 			//assertGl();
7390 
7391 			if(nearestLightPos.w == 0.f) {
7392 				//directional light
7393 
7394 				//light pos
7395 				assert(game != NULL);
7396 				assert(game->getWorld() != NULL);
7397 				const TimeFlow *tf= game->getWorld()->getTimeFlow();
7398 				assert(tf != NULL);
7399 				float ang= tf->isDay()? computeSunAngle(tf->getTime()): computeMoonAngle(tf->getTime());
7400 				ang= radToDeg(ang);
7401 
7402 				//push and set projection
7403 				glMatrixMode(GL_PROJECTION);
7404 				glPushMatrix();
7405 				glLoadIdentity();
7406 
7407 				//assertGl();
7408 
7409 				if(game->getGameCamera()->getState()==GameCamera::sGame){
7410 					//glOrtho(-35, 5, -15, 15, -1000, 1000);
7411 					//glOrtho(-30, 30, -20, 20, -1000, 1000);
7412 					glOrtho(-30, 5, -20, 20, -1000, 1000);
7413 				}
7414 				else{
7415 					glOrtho(-30, 30, -20, 20, -1000, 1000);
7416 				}
7417 
7418 				//assertGl();
7419 
7420 				//push and set modelview
7421 				glMatrixMode(GL_MODELVIEW);
7422 				glPushMatrix();
7423 				glLoadIdentity();
7424 
7425 				glRotatef(15, 0, 1, 0);
7426 
7427 				glRotatef(ang, 1, 0, 0);
7428 				glRotatef(90, 0, 1, 0);
7429 				const Vec3f &pos= game->getGameCamera()->getPos();
7430 
7431 				glTranslatef(static_cast<int>(-pos.x), 0, static_cast<int>(-pos.z));
7432 
7433 				//assertGl();
7434 			}
7435 			else {
7436 				//non directional light
7437 
7438 				//push projection
7439 				glMatrixMode(GL_PROJECTION);
7440 				glPushMatrix();
7441 				glLoadIdentity();
7442 
7443 				//assertGl();
7444 
7445 				gluPerspective(perspFov, 1.f, perspNearPlane, perspFarPlane);
7446 				//const Metrics &metrics= Metrics::getInstance();
7447 				//gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane);
7448 
7449 
7450 				assertGl();
7451 
7452 				//push modelview
7453 				glMatrixMode(GL_MODELVIEW);
7454 				glPushMatrix();
7455 				glLoadIdentity();
7456 				glRotatef(-90, -1, 0, 0);
7457 				glTranslatef(-nearestLightPos.x, -nearestLightPos.y-2, -nearestLightPos.z);
7458 
7459 				//assertGl();
7460 			}
7461 
7462 			if(shadows == sShadowMapping) {
7463 				glEnable(GL_POLYGON_OFFSET_FILL);
7464 				glPolygonOffset(1.0f, 16.0f);
7465 
7466 				//assertGl();
7467 			}
7468 
7469 			//render 3d
7470 			renderUnitsFast(true);
7471 			renderObjectsFast(true,false);
7472 
7473 			//assertGl();
7474 
7475 			//read color buffer
7476 			glBindTexture(GL_TEXTURE_2D, shadowMapHandle);
7477 			assertGl();
7478 			glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowTextureSize, shadowTextureSize);
7479 			GLenum error = glGetError();
7480 			// This error can happen when a Linux user switches from an X session
7481 			// back to a running game, and 'seems' to be safe to ignore it
7482 			if(error != GL_INVALID_OPERATION) {
7483 				assertGlWithErrorNumber(error);
7484 			}
7485 
7486 			//get elemental matrices
7487 			static Matrix4f matrix1;
7488 			static bool matrix1Populate = true;
7489 			if(matrix1Populate == true) {
7490 				matrix1Populate = false;
7491 				matrix1[0]= 0.5f;	matrix1[4]= 0.f;	matrix1[8]= 0.f;	matrix1[12]= 0.5f;
7492 				matrix1[1]= 0.f;	matrix1[5]= 0.5f;	matrix1[9]= 0.f;	matrix1[13]= 0.5f;
7493 				matrix1[2]= 0.f;	matrix1[6]= 0.f;	matrix1[10]= 0.5f;	matrix1[14]= 0.5f;
7494 				matrix1[3]= 0.f;	matrix1[7]= 0.f;	matrix1[11]= 0.f;	matrix1[15]= 1.f;
7495 			}
7496 			Matrix4f matrix2;
7497 			glGetFloatv(GL_PROJECTION_MATRIX, matrix2.ptr());
7498 
7499 			//assertGl();
7500 
7501 			Matrix4f matrix3;
7502 			glGetFloatv(GL_MODELVIEW_MATRIX, matrix3.ptr());
7503 
7504 			//pop both matrices
7505 			glPopMatrix();
7506 			glMatrixMode(GL_PROJECTION);
7507 			glPopMatrix();
7508 
7509 			glMatrixMode(GL_PROJECTION);
7510 			glPushMatrix();
7511 
7512 			//assertGl();
7513 
7514 			//compute texture matrix
7515 			glLoadMatrixf(matrix1.ptr());
7516 			glMultMatrixf(matrix2.ptr());
7517 			glMultMatrixf(matrix3.ptr());
7518 			glGetFloatv(GL_TRANSPOSE_PROJECTION_MATRIX_ARB, shadowMapMatrix.ptr());
7519 
7520 			//assertGl();
7521 
7522 			//if(shadows == sShadowMapping) {
7523 			//	glDisable(GL_POLYGON_OFFSET_FILL);
7524 			//	glPolygonOffset(0.0f, 0.0f);
7525 			//}
7526 
7527 			//pop
7528 			glPopMatrix();
7529 
7530 			//assertGl();
7531 
7532 			glPopAttrib();
7533 
7534 			assertGl();
7535 		}
7536 	}
7537 }
7538 
7539 
7540 // ==================== gl wrap ====================
7541 
7542 string Renderer::getGlInfo(){
7543 	string infoStr="";
7544 	Lang &lang= Lang::getInstance();
7545 
7546 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
7547 		infoStr+= lang.getString("OpenGlInfo")+":\n";
7548 		infoStr+= "   "+lang.getString("OpenGlVersion")+": ";
7549 		infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
7550 		infoStr+= "   "+lang.getString("OpenGlRenderer")+": ";
7551 		infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n";
7552 		infoStr+= "   "+lang.getString("OpenGlVendor")+": ";
7553 		infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n";
7554 		infoStr+= "   "+lang.getString("OpenGlMaxLights")+": ";
7555 		infoStr+= intToStr(getGlMaxLights())+"\n";
7556 		infoStr+= "   "+lang.getString("OpenGlMaxTextureSize")+": ";
7557 		infoStr+= intToStr(getGlMaxTextureSize())+"\n";
7558 		infoStr+= "   "+lang.getString("OpenGlMaxTextureUnits")+": ";
7559 		infoStr+= intToStr(getGlMaxTextureUnits())+"\n";
7560 		infoStr+= "   "+lang.getString("OpenGlModelviewStack")+": ";
7561 		infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n";
7562 		infoStr+= "   "+lang.getString("OpenGlProjectionStack")+": ";
7563 		infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n";
7564 	}
7565 	return infoStr;
7566 }
7567 
7568 string Renderer::getGlMoreInfo(){
7569 	string infoStr="";
7570 	Lang &lang= Lang::getInstance();
7571 
7572 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
7573 		//gl extensions
7574 		infoStr+= lang.getString("OpenGlExtensions")+":\n   ";
7575 
7576 		string extensions= getGlExtensions();
7577 		int charCount= 0;
7578 		for(int i = 0; i < (int)extensions.size(); ++i) {
7579 			infoStr+= extensions[i];
7580 			if(charCount>120 && extensions[i]==' '){
7581 				infoStr+= "\n   ";
7582 				charCount= 0;
7583 			}
7584 			++charCount;
7585 		}
7586 
7587 		//platform extensions
7588 		infoStr+= "\n\n";
7589 		infoStr+= lang.getString("OpenGlPlatformExtensions")+":\n   ";
7590 
7591 		charCount= 0;
7592 		string platformExtensions= getGlPlatformExtensions();
7593 		for(int i = 0; i < (int)platformExtensions.size(); ++i) {
7594 			infoStr+= platformExtensions[i];
7595 			if(charCount>120 && platformExtensions[i]==' '){
7596 				infoStr+= "\n   ";
7597 				charCount= 0;
7598 			}
7599 			++charCount;
7600 		}
7601 	}
7602 
7603 	return infoStr;
7604 }
7605 
7606 void Renderer::autoConfig() {
7607 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
7608 		Config &config= Config::getInstance();
7609 
7610 		bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos;
7611 		bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos;
7612 		//bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient");
7613 		bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow");
7614 
7615 		//3D textures
7616 		config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D"));
7617 
7618 		//shadows
7619 		string shadows="";
7620 		if(getGlMaxTextureUnits()>=3){
7621 			if(nvidiaCard && shadowExtensions){
7622 				shadows= shadowsToStr(sShadowMapping);
7623 			}
7624 			else{
7625 				shadows= shadowsToStr(sProjected);
7626 			}
7627 		}
7628 		else{
7629 			shadows=shadowsToStr(sDisabled);
7630 		}
7631 		config.setString("Shadows", shadows);
7632 
7633 		//lights
7634 		config.setInt("MaxLights", atiCard? 1: 4);
7635 
7636 		//filter
7637 		config.setString("Filter", "Bilinear");
7638 	}
7639 }
7640 
7641 void Renderer::clearBuffers() {
7642 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
7643 }
7644 
7645 void Renderer::clearZBuffer() {
7646 	glClear(GL_DEPTH_BUFFER_BIT);
7647 }
7648 
7649 void Renderer::loadConfig() {
7650 	Config &config= Config::getInstance();
7651 
7652 	//cache most used config params
7653 	maxLights= config.getInt("MaxLights");
7654 	photoMode= config.getBool("PhotoMode");
7655 	focusArrows= config.getBool("FocusArrows");
7656 	textures3D= config.getBool("Textures3D");
7657 	float gammaValue=config.getFloat("GammaValue","0.0");
7658 	if(this->program == NULL) {
7659 		throw megaglest_runtime_error("this->program == NULL");
7660 	}
7661 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
7662 		//if(this->program != NULL) {
7663 		if(gammaValue != 0.0) {
7664 			this->program->getWindow()->setGamma(gammaValue);
7665 		}
7666 		//}
7667 	}
7668 	//load shadows
7669 	shadows= strToShadows(config.getString("Shadows"));
7670 	if(shadows==sProjected || shadows==sShadowMapping){
7671 		shadowTextureSize= config.getInt("ShadowTextureSize");
7672 		shadowFrameSkip= config.getInt("ShadowFrameSkip");
7673 		shadowIntensity= config.getFloat("ShadowIntensity","1.0");
7674 	}
7675 
7676 	//load filter settings
7677 	Texture2D::Filter textureFilter= strToTextureFilter(config.getString("Filter"));
7678 	int maxAnisotropy= config.getInt("FilterMaxAnisotropy");
7679 
7680 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
7681 		for(int i=0; i<rsCount; ++i){
7682 			textureManager[i]->setFilter(textureFilter);
7683 			textureManager[i]->setMaxAnisotropy(maxAnisotropy);
7684 		}
7685 	}
7686 }
7687 
7688 Texture2D *Renderer::saveScreenToTexture(int x, int y, int width, int height) {
7689 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7690 
7691 	Config &config= Config::getInstance();
7692 	Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
7693 	int maxAnisotropy				= config.getInt("FilterMaxAnisotropy");
7694 
7695 	Texture2D *texture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
7696 	texture->setForceCompressionDisabled(true);
7697 	texture->setMipmap(false);
7698 	Pixmap2D *pixmapScreenShot = texture->getPixmap();
7699 	pixmapScreenShot->init(width, height, 3);
7700 	texture->init(textureFilter,maxAnisotropy);
7701 
7702 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7703 	//glFinish();
7704 
7705 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7706 	glReadPixels(x, y, pixmapScreenShot->getW(), pixmapScreenShot->getH(),
7707 				 GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels());
7708 
7709 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7710 
7711 	return texture;
7712 }
7713 
7714 void Renderer::saveScreen(const string &path,int w, int h) {
7715 	const Metrics &sm= Metrics::getInstance();
7716 
7717 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7718 
7719 	Pixmap2D *pixmapScreenShot = new Pixmap2D(sm.getScreenW(),sm.getScreenH(), 3);
7720 
7721 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7722 	//glFinish();
7723 
7724 	glPixelStorei(GL_PACK_ALIGNMENT, 1);
7725 
7726 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7727 	glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(),
7728 				 GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels());
7729 
7730 	if(w==0 || h==0){
7731 		h=sm.getScreenH();
7732 		w=sm.getScreenW();
7733 	}
7734 	else{
7735 		pixmapScreenShot->Scale(GL_RGB,w,h);
7736 	}
7737 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7738 
7739 	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7740 
7741 	// Signal the threads queue to add a screenshot save request
7742 	MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
7743 	saveScreenQueue.push_back(make_pair(path,pixmapScreenShot));
7744 	safeMutex.ReleaseLock();
7745 
7746 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
7747 }
7748 
7749 unsigned int Renderer::getSaveScreenQueueSize() {
7750 	MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__));
7751 	int queueSize = (int)saveScreenQueue.size();
7752 	safeMutex.ReleaseLock();
7753 
7754 	return queueSize;
7755 }
7756 
7757 // ==================== PRIVATE ====================
7758 
7759 float Renderer::computeSunAngle(float time) {
7760 
7761 	float dayTime= TimeFlow::dusk-TimeFlow::dawn;
7762 	float fTime= (time-TimeFlow::dawn)/dayTime;
7763 	return clamp(fTime*pi, pi/8.f, 7.f*pi/8.f);
7764 }
7765 
7766 float Renderer::computeMoonAngle(float time) {
7767 	float nightTime= 24-(TimeFlow::dusk-TimeFlow::dawn);
7768 
7769 	if(time<TimeFlow::dawn){
7770 		time+= 24.f;
7771 	}
7772 
7773 	float fTime= (time-TimeFlow::dusk)/nightTime;
7774 	return clamp((1.0f-fTime)*pi, pi/8.f, 7.f*pi/8.f);
7775 }
7776 
7777 Vec4f Renderer::computeSunPos(float time) {
7778 	float ang= computeSunAngle(time);
7779 	return Vec4f(-std::cos(ang)*sunDist, std::sin(ang)*sunDist, 0.f, 0.f);
7780 }
7781 
7782 Vec4f Renderer::computeMoonPos(float time) {
7783 	float ang= computeMoonAngle(time);
7784 	return Vec4f(-std::cos(ang)*moonDist, std::sin(ang)*moonDist, 0.f, 0.f);
7785 }
7786 
7787 // ==================== fast render ====================
7788 
7789 //render units for selection purposes
7790 vector<Unit *> Renderer::renderUnitsFast(bool renderingShadows, bool colorPickingSelection) {
7791 	vector<Unit *> unitsList;
7792 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
7793 		return unitsList;
7794 	}
7795 
7796 	assert(game != NULL);
7797 	//const World *world= game->getWorld();
7798 	//assert(world != NULL);
7799 
7800 	VisibleQuadContainerCache &qCache = getQuadCache();
7801 	if(qCache.visibleQuadUnitList.empty() == false) {
7802 		if(colorPickingSelection == true) {
7803 			unitsList.reserve(qCache.visibleQuadUnitList.size());
7804 		}
7805 
7806 		bool modelRenderStarted = false;
7807 		bool renderOnlyBuildings=true;
7808 		for(int k=0; k<2 ;k++) {
7809 			if(k==0){
7810 				//glDisable(GL_DEPTH_TEST);
7811 				renderOnlyBuildings=true;
7812 			}
7813 			else {
7814 				if(colorPickingSelection == true){
7815 					// clear depth buffer to get units behind buildings rendered in front of them
7816 					glClear(GL_DEPTH_BUFFER_BIT);
7817 				}
7818 				//glEnable(GL_DEPTH_TEST);
7819 				renderOnlyBuildings=false;
7820 			}
7821 			for(int visibleUnitIndex = 0;
7822 					visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) {
7823 				Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex];
7824 
7825 				if(renderingShadows==false && unit->isAlive()==false){
7826 					// no need to render dead units for selection
7827 					continue;
7828 				}
7829 
7830 				if(renderOnlyBuildings==true && unit->getType()->hasSkillClass(scMove)){
7831 					continue;
7832 				}
7833 
7834 				if(renderOnlyBuildings==false && !unit->getType()->hasSkillClass(scMove)){
7835 					continue;
7836 				}
7837 
7838 				if(modelRenderStarted == false) {
7839 					modelRenderStarted = true;
7840 
7841 					if(colorPickingSelection == false) {
7842 						//glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT);
7843 						glDisable(GL_LIGHTING);
7844 						if (renderingShadows == false) {
7845 							glPushAttrib(GL_ENABLE_BIT);
7846 							glDisable(GL_TEXTURE_2D);
7847 						}
7848 						else {
7849 							glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT);
7850 							glEnable(GL_TEXTURE_2D);
7851 							glAlphaFunc(GL_GREATER, 0.4f);
7852 
7853 							glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
7854 
7855 							//set color to the texture alpha
7856 							glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
7857 							glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
7858 							glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
7859 
7860 							//set alpha to the texture alpha
7861 							glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
7862 							glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
7863 							glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
7864 						}
7865 					}
7866 
7867 					modelRenderer->begin(false, renderingShadows, false, colorPickingSelection);
7868 
7869 					if(colorPickingSelection == false) {
7870 						glInitNames();
7871 					}
7872 				}
7873 
7874 				if(colorPickingSelection == false) {
7875 					glPushName(visibleUnitIndex);
7876 				}
7877 
7878 				//assertGl();
7879 
7880 				glMatrixMode(GL_MODELVIEW);
7881 				//debuxar modelo
7882 				glPushMatrix();
7883 
7884 				//translate
7885 				Vec3f currVec= unit->getCurrVectorFlat();
7886 				glTranslatef(currVec.x, currVec.y, currVec.z);
7887 
7888 				//rotate
7889 				glRotatef(unit->getRotation(), 0.f, 1.f, 0.f);
7890 
7891 				//render
7892 				Model *model= unit->getCurrentModelPtr();
7893 				//if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) {
7894 
7895 					// ***MV don't think this is needed below 2013/01/11
7896 					model->updateInterpolationVertices(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound());
7897 
7898 				//}
7899 
7900 				if(colorPickingSelection == true) {
7901 					unit->setUniquePickingColor();
7902 					unitsList.push_back(unit);
7903 				}
7904 
7905 				modelRenderer->render(model,rmSelection);
7906 
7907 				glPopMatrix();
7908 
7909 				if(colorPickingSelection == false) {
7910 					glPopName();
7911 				}
7912 			}
7913 		}
7914 
7915 		if(modelRenderStarted == true) {
7916 			modelRenderer->end();
7917 			if(colorPickingSelection == false) {
7918 				glPopAttrib();
7919 			}
7920 		}
7921 	}
7922 	//glDisable(GL_DEPTH_TEST);
7923 	return unitsList;
7924 }
7925 
7926 //render objects for selection purposes
7927 vector<Object *>  Renderer::renderObjectsFast(bool renderingShadows, bool resourceOnly,
7928 		bool colorPickingSelection) {
7929 	vector<Object *> objectList;
7930 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
7931 		return objectList;
7932 	}
7933 
7934 	VisibleQuadContainerCache &qCache = getQuadCache();
7935 	if(qCache.visibleObjectList.empty() == false) {
7936 		if(colorPickingSelection == true) {
7937 			objectList.reserve(qCache.visibleObjectList.size());
7938 		}
7939 
7940 		bool modelRenderStarted = false;
7941 		for(int visibleIndex = 0;
7942 				visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) {
7943 			Object *o = qCache.visibleObjectList[visibleIndex];
7944 
7945 			if(modelRenderStarted == false) {
7946 				modelRenderStarted = true;
7947 
7948 				if(colorPickingSelection == false) {
7949 					glDisable(GL_LIGHTING);
7950 
7951 					if (renderingShadows == false){
7952 						glPushAttrib(GL_ENABLE_BIT);
7953 						glDisable(GL_TEXTURE_2D);
7954 					}
7955 					else {
7956 						glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT);
7957 						glAlphaFunc(GL_GREATER, 0.5f);
7958 
7959 						glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
7960 
7961 						//set color to the texture alpha
7962 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
7963 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
7964 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
7965 
7966 						//set alpha to the texture alpha
7967 						glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
7968 						glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
7969 						glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
7970 					}
7971 				}
7972 
7973 				modelRenderer->begin(false, renderingShadows, false, colorPickingSelection);
7974 
7975 				if(colorPickingSelection == false) {
7976 					glInitNames();
7977 				}
7978 			}
7979 
7980 			if(resourceOnly == false || o->getResource()!= NULL) {
7981 				Model *objModel= o->getModelPtr();
7982 				//if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) {
7983 
7984 					// ***MV don't think this is needed below 2013/01/11
7985 					//objModel->updateInterpolationData(o->getAnimProgress(), true);
7986 
7987 				//}
7988 				const Vec3f v= o->getConstPos();
7989 
7990 				if(colorPickingSelection == false) {
7991 					glPushName(OBJECT_SELECT_OFFSET+visibleIndex);
7992 				}
7993 
7994 				glMatrixMode(GL_MODELVIEW);
7995 				glPushMatrix();
7996 				glTranslatef(v.x, v.y, v.z);
7997 				glRotatef(o->getRotation(), 0.f, 1.f, 0.f);
7998 
7999 				if(colorPickingSelection == true) {
8000 					o->setUniquePickingColor();
8001 					objectList.push_back(o);
8002 				}
8003 
8004 				modelRenderer->render(objModel,resourceOnly?rmSelection:rmNormal);
8005 
8006 				glPopMatrix();
8007 
8008 				if(colorPickingSelection == false) {
8009 					glPopName();
8010 				}
8011 			}
8012 		}
8013 
8014 		if(modelRenderStarted == true) {
8015 			modelRenderer->end();
8016 
8017 			if(colorPickingSelection == false) {
8018 				glPopAttrib();
8019 			}
8020 		}
8021 	}
8022 
8023 	return objectList;
8024 }
8025 
8026 // ==================== gl caps ====================
8027 
8028 void Renderer::checkGlCaps() {
8029 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8030 		return;
8031 	}
8032 
8033 	if(glActiveTexture == NULL) {
8034 		string message;
8035 
8036 		message += "Your system supports OpenGL version [";
8037  		message += getGlVersion() + string("]\n");
8038  		message += "MegaGlest needs a version that supports\n";
8039  		message += "glActiveTexture (OpenGL 1.3) or the ARB_multitexture extension.";
8040 
8041  		throw megaglest_runtime_error(message.c_str(),true);
8042 	}
8043 
8044 	//opengl 1.3
8045 	//if(!isGlVersionSupported(1, 3, 0)) {
8046 	if(glewIsSupported("GL_VERSION_1_3") == false) {
8047 		string message;
8048 
8049 		message += "Your system supports OpenGL version [";
8050  		message += getGlVersion() + string("]\n");
8051  		message += "MegaGlest needs at least version 1.3 to work\n";
8052  		message += "You may solve this problem by installing your latest video card drivers";
8053 
8054  		throw megaglest_runtime_error(message.c_str(),true);
8055 	}
8056 
8057 	//opengl 1.4 or extension
8058 	//if(!isGlVersionSupported(1, 4, 0)){
8059 	if(glewIsSupported("GL_VERSION_1_4") == false) {
8060 		checkExtension("GL_ARB_texture_env_crossbar", "MegaGlest");
8061 	}
8062 }
8063 
8064 void Renderer::checkGlOptionalCaps() {
8065 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8066 		return;
8067 	}
8068 
8069 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8070 	//shadows
8071 	if(shadows == sProjected || shadows == sShadowMapping) {
8072 		if(getGlMaxTextureUnits() < 3) {
8073 			throw megaglest_runtime_error("Your system doesn't support 3 texture units, required for shadows");
8074 		}
8075 	}
8076 
8077 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8078 	//shadow mapping
8079 	if(shadows == sShadowMapping) {
8080 		checkExtension("GL_ARB_shadow", "Shadow Mapping");
8081 		//checkExtension("GL_ARB_shadow_ambient", "Shadow Mapping");
8082 		//checkExtension("GL_ARB_depth_texture", "Shadow Mapping");
8083 	}
8084 
8085 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8086 }
8087 
8088 void Renderer::checkExtension(const string &extension, const string &msg) {
8089 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8090 		return;
8091 	}
8092 
8093 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8094 	if(!isGlExtensionSupported(extension.c_str())) {
8095 		string str= "OpenGL extension not supported: " + extension +  ", required for " + msg;
8096 		throw megaglest_runtime_error(str);
8097 	}
8098 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8099 }
8100 
8101 // ==================== init 3d lists ====================
8102 
8103 void Renderer::init3dList() {
8104 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8105 		return;
8106 	}
8107 
8108 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8109 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8110 
8111 	render3dSetup();
8112 
8113 	if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8114 
8115 	//const Metrics &metrics= Metrics::getInstance();
8116 
8117     //assertGl();
8118 
8119     //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8120 
8121 	//list3d= glGenLists(1);
8122 	//assertGl();
8123 	//list3dValid=true;
8124 
8125 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8126 
8127 	//glNewList(list3d, GL_COMPILE_AND_EXECUTE);
8128 	//need to execute, because if not gluPerspective takes no effect and gluLoadMatrix is wrong
8129 	//render3dSetup();
8130 	//glEndList();
8131 
8132 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8133 
8134 	//assert
8135 	//assertGl();
8136 }
8137 
8138 void Renderer::render3dSetup() {
8139 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8140 	const Metrics &metrics= Metrics::getInstance();
8141 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8142 
8143 	//misc
8144 	glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH());
8145 	glClearColor(fowColor.x, fowColor.y, fowColor.z, fowColor.w);
8146 	glFrontFace(GL_CW);
8147 	glEnable(GL_CULL_FACE);
8148 	loadProjectionMatrix();
8149 
8150 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8151 
8152 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8153 
8154 	//texture state
8155 	glActiveTexture(shadowTexUnit);
8156 	glDisable(GL_TEXTURE_2D);
8157 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8158 
8159 	glActiveTexture(fowTexUnit);
8160 	glDisable(GL_TEXTURE_2D);
8161 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8162 
8163 	glActiveTexture(baseTexUnit);
8164 	glEnable(GL_TEXTURE_2D);
8165 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8166 
8167 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8168 
8169 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8170 
8171 	//material state
8172 	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr());
8173 	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr());
8174 	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr());
8175 	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
8176 	glColor4fv(defColor.ptr());
8177 
8178 	//blend state
8179 	glDisable(GL_BLEND);
8180 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8181 
8182 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8183 
8184 	//alpha test state
8185 	glEnable(GL_ALPHA_TEST);
8186 	glAlphaFunc(GL_GREATER, 0.f);
8187 
8188 	//depth test state
8189 	glEnable(GL_DEPTH_TEST);
8190 	glDepthMask(GL_TRUE);
8191 	glDepthFunc(GL_LESS);
8192 
8193 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8194 
8195 	//lighting state
8196 	glEnable(GL_LIGHTING);
8197 	glEnable(GL_LIGHT0);
8198 
8199 	//matrix mode
8200 	glMatrixMode(GL_MODELVIEW);
8201 
8202 	//stencil test
8203 	glDisable(GL_STENCIL_TEST);
8204 
8205 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8206 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8207 
8208 	//fog
8209 	const Tileset *tileset= NULL;
8210 	if(game != NULL && game->getWorld() != NULL) {
8211 		//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8212 		tileset = game->getWorld()->getTileset();
8213 	}
8214 
8215 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8216 
8217 	if(tileset != NULL && tileset->getFog()) {
8218 		//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8219 
8220 		glEnable(GL_FOG);
8221 		if(tileset->getFogMode()==fmExp) {
8222 			glFogi(GL_FOG_MODE, GL_EXP);
8223 		}
8224 		else {
8225 			glFogi(GL_FOG_MODE, GL_EXP2);
8226 		}
8227 
8228 		glFogf(GL_FOG_DENSITY, tileset->getFogDensity());
8229 		glFogfv(GL_FOG_COLOR, tileset->getFogColor().ptr());
8230 	}
8231 
8232 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8233 }
8234 
8235 void Renderer::init2dList() {
8236 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8237 		return;
8238 	}
8239 
8240 //	//this list sets the state for the 2d rendering
8241 //	list2d= glGenLists(1);
8242 //	assertGl();
8243 //	list2dValid=true;
8244 //
8245 //	glNewList(list2d, GL_COMPILE);
8246 //	render2dMenuSetup();
8247 //	glEndList();
8248 //
8249 //	assertGl();
8250 }
8251 
8252 void Renderer::render2dMenuSetup() {
8253 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8254 
8255 	const Metrics &metrics= Metrics::getInstance();
8256 	//projection
8257 	glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH());
8258 	glMatrixMode(GL_PROJECTION);
8259 	glLoadIdentity();
8260 	glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1);
8261 
8262 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8263 
8264 	//modelview
8265 	glMatrixMode(GL_MODELVIEW);
8266 	glLoadIdentity();
8267 
8268 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8269 
8270 	//disable everything
8271 	glDisable(GL_BLEND);
8272 	glDisable(GL_LIGHTING);
8273 	glDisable(GL_ALPHA_TEST);
8274 	glDisable(GL_DEPTH_TEST);
8275 	glDisable(GL_STENCIL_TEST);
8276 	glDisable(GL_FOG);
8277 	glDisable(GL_CULL_FACE);
8278 	glFrontFace(GL_CCW);
8279 
8280 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8281 
8282 	if(glActiveTexture != NULL) {
8283 		glActiveTexture(baseTexUnit);
8284 	}
8285 	else {
8286 		char szBuf[8096]="";
8287 		snprintf(szBuf,8096,"In [%s::%s] Line: %d\nglActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8288 		throw megaglest_runtime_error(szBuf);
8289 	}
8290 
8291 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8292 
8293 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8294 	glDisable(GL_TEXTURE_2D);
8295 
8296 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8297 
8298 	//blend func
8299 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8300 
8301 	//color
8302 	glColor4f(1.f, 1.f, 1.f, 1.f);
8303 
8304 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8305 }
8306 
8307 void Renderer::init3dListMenu(const MainMenu *mm) {
8308 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8309 		return;
8310 	}
8311 
8312 	//this->mm3d = mm;
8313 	//printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d);
8314 
8315 /*
8316 	assertGl();
8317 
8318     if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8319 
8320 	const Metrics &metrics= Metrics::getInstance();
8321 	//const MenuBackground *mb= mm->getConstMenuBackground();
8322 	const MenuBackground *mb = NULL;
8323 	if(mm != NULL) {
8324 		mb = mm->getConstMenuBackground();
8325 	}
8326 
8327 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8328 
8329 	if(this->customlist3dMenu != NULL) {
8330 		*this->customlist3dMenu = glGenLists(1);
8331 		assertGl();
8332 	}
8333 	else {
8334 		list3dMenu= glGenLists(1);
8335 		assertGl();
8336 		list3dMenuValid=true;
8337 	}
8338 
8339 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8340 
8341 	if(this->customlist3dMenu != NULL) {
8342 		glNewList(*this->customlist3dMenu, GL_COMPILE);
8343 	}
8344 	else {
8345 		glNewList(list3dMenu, GL_COMPILE);
8346 	}
8347 
8348 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8349 		//misc
8350 		glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH());
8351 		glClearColor(0.4f, 0.4f, 0.4f, 1.f);
8352 		glFrontFace(GL_CW);
8353 		glEnable(GL_CULL_FACE);
8354 		glMatrixMode(GL_PROJECTION);
8355 		glLoadIdentity();
8356 		gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000);
8357 
8358 		//texture state
8359 		glEnable(GL_TEXTURE_2D);
8360 		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8361 
8362 		//material state
8363 		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr());
8364 		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr());
8365 		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr());
8366 		glColor4fv(defColor.ptr());
8367 		glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
8368 
8369 		//blend state
8370 		glDisable(GL_BLEND);
8371 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8372 
8373 		//alpha test state
8374 		glEnable(GL_ALPHA_TEST);
8375 		glAlphaFunc(GL_GREATER, 0.f);
8376 
8377 		//depth test state
8378 		glEnable(GL_DEPTH_TEST);
8379 		glDepthMask(GL_TRUE);
8380 		glDepthFunc(GL_LESS);
8381 
8382 		//lighting state
8383 		glEnable(GL_LIGHTING);
8384 
8385 		//matrix mode
8386 		glMatrixMode(GL_MODELVIEW);
8387 
8388 		//stencil test
8389 		glDisable(GL_STENCIL_TEST);
8390 
8391 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8392 
8393 		//fog
8394 		if(mb != NULL && mb->getFog()){
8395 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8396 
8397 			glEnable(GL_FOG);
8398 			glFogi(GL_FOG_MODE, GL_EXP2);
8399 			glFogf(GL_FOG_DENSITY, mb->getFogDensity());
8400 		}
8401 
8402 		if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8403 
8404 	glEndList();
8405 
8406 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8407 
8408 	//assert
8409 	assertGl();
8410 */
8411 }
8412 
8413 void Renderer::render3dMenuSetup(const MainMenu *mm) {
8414 	//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8415 
8416 	const Metrics &metrics= Metrics::getInstance();
8417 	const MenuBackground *mb = NULL;
8418 	if(mm != NULL) {
8419 		mb = mm->getConstMenuBackground();
8420 	}
8421 
8422 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8423 	//misc
8424 	glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH());
8425 	glClearColor(0.4f, 0.4f, 0.4f, 1.f);
8426 	glFrontFace(GL_CW);
8427 	glEnable(GL_CULL_FACE);
8428 	glMatrixMode(GL_PROJECTION);
8429 	glLoadIdentity();
8430 	gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000);
8431 
8432 	//texture state
8433 	glEnable(GL_TEXTURE_2D);
8434 	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
8435 
8436 	//material state
8437 	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr());
8438 	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr());
8439 	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr());
8440 	glColor4fv(defColor.ptr());
8441 	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
8442 
8443 	//blend state
8444 	glDisable(GL_BLEND);
8445 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8446 
8447 	//alpha test state
8448 	glEnable(GL_ALPHA_TEST);
8449 	glAlphaFunc(GL_GREATER, 0.f);
8450 
8451 	//depth test state
8452 	glEnable(GL_DEPTH_TEST);
8453 	glDepthMask(GL_TRUE);
8454 	glDepthFunc(GL_LESS);
8455 
8456 	//lighting state
8457 	glEnable(GL_LIGHTING);
8458 
8459 	//matrix mode
8460 	glMatrixMode(GL_MODELVIEW);
8461 
8462 	//stencil test
8463 	glDisable(GL_STENCIL_TEST);
8464 
8465 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8466 
8467 	//fog
8468 	if(mb != NULL && mb->getFog()) {
8469 		//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8470 
8471 		glEnable(GL_FOG);
8472 		glFogi(GL_FOG_MODE, GL_EXP2);
8473 		glFogf(GL_FOG_DENSITY, mb->getFogDensity());
8474 	}
8475 
8476 	//assert
8477 	assertGl();
8478 
8479 	//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
8480 }
8481 // ==================== misc ====================
8482 
8483 void Renderer::loadProjectionMatrix() {
8484 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8485 		return;
8486 	}
8487 
8488 	GLdouble clipping;
8489 	const Metrics &metrics= Metrics::getInstance();
8490 
8491     assertGl();
8492 
8493 	clipping= photoMode ? perspFarPlane*100 : perspFarPlane;
8494 
8495 	glMatrixMode(GL_PROJECTION);
8496 	glLoadIdentity();
8497 	gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, clipping);
8498 
8499     assertGl();
8500 }
8501 
8502 void Renderer::enableProjectiveTexturing() {
8503 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8504 		return;
8505 	}
8506 
8507 	glTexGenfv(GL_S, GL_EYE_PLANE, &shadowMapMatrix[0]);
8508 	glTexGenfv(GL_T, GL_EYE_PLANE, &shadowMapMatrix[4]);
8509 	glTexGenfv(GL_R, GL_EYE_PLANE, &shadowMapMatrix[8]);
8510 	glTexGenfv(GL_Q, GL_EYE_PLANE, &shadowMapMatrix[12]);
8511 	glEnable(GL_TEXTURE_GEN_S);
8512 	glEnable(GL_TEXTURE_GEN_T);
8513 	glEnable(GL_TEXTURE_GEN_R);
8514 	glEnable(GL_TEXTURE_GEN_Q);
8515 }
8516 
8517 // ==================== private aux drawing ====================
8518 void Renderer::renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture, const Texture2D *backgroundTexture) {
8519 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8520 		return;
8521 	}
8522 
8523 	int numberOfBars=1;
8524 	int barCount=0;
8525 	float hp=unit->getHpRatio();
8526 	float ep=-1.f;
8527 	if(unit->getType()->getTotalMaxEp(unit->getTotalUpgrade()) !=0 ) {
8528 			ep=unit->getEpRatio();
8529 			numberOfBars++;
8530 	}
8531 	int productionPercent=unit->getProductionPercent();
8532 	if(productionPercent!=-1) {
8533 		numberOfBars++;
8534 	}
8535 	int size=unit->getType()->getSize();
8536 
8537 
8538 	Vec3f rightVector;
8539 	Vec3f upVector;
8540 	Vec3f rightVectorTexture;
8541 	Vec3f upVectorTexture;
8542 	v.y+=1;
8543 	float modelview[16];
8544 	float width=(float)size/6+0.25f;
8545 	float red;
8546 	float green;
8547 	float brightness=0.8f;
8548 
8549 	glMatrixMode(GL_MODELVIEW);
8550     glPushMatrix();
8551 
8552 	// get the current modelview state
8553 	glGetFloatv(GL_MODELVIEW_MATRIX , modelview);
8554 	rightVector= Vec3f(modelview[0], modelview[4], modelview[8]);
8555 	upVector= Vec3f(modelview[1], modelview[5], modelview[9]);
8556 	rightVectorTexture=rightVector*2;
8557 	upVectorTexture=upVector*4;
8558 
8559 	//from green to yellow to red
8560 
8561 	if(hp >= 0.75f) {
8562 		green=1;
8563 		red=1-((2*hp-1)-0.5f);
8564 	} else {
8565 		red=1;
8566 		green=0.5f+(2*hp-1);
8567 	}
8568 
8569 	if(red>1.0f) red=1.0f;
8570 	if(green>1.0f) green=1.0f;
8571 	float yOffset=(float)numberOfBars/2.f;
8572 
8573 	if(backgroundTexture!=NULL) {
8574 		//backgroundTexture
8575 		glEnable(GL_TEXTURE_2D);
8576 		glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(backgroundTexture)->getHandle());
8577 		glColor4f(1.f,1.f,1.f,1.f);
8578 		//glColor4f(red+0.1f,green+0.1f,0.1f,0.5f);
8579 		glBegin(GL_QUADS);
8580 			glTexCoord2i(0,1);
8581 			glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr());
8582 			glTexCoord2i(0,0);
8583 			glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr());
8584 			glTexCoord2i(1,0);
8585 			glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr());
8586 			glTexCoord2i(1,1);
8587 			glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr());
8588 		glEnd();
8589 		glDisable(GL_TEXTURE_2D);
8590 	}
8591 
8592 	//healthbar
8593 	glColor4f(red*brightness,green*brightness,0.0f,0.4f);
8594 	//hpbar
8595 	barCount++;
8596 	internalRenderHp(numberOfBars,barCount,hp,v,width,height,rightVector,upVector);
8597 
8598 
8599 	if(ep > -1.0f) {
8600 		//epbar
8601 		barCount++;
8602 		//glColor4f(brightness,0,brightness,0.5f);
8603 		glColor4f(.15f*brightness,0.3f*brightness,0.8f*brightness,0.7f);
8604 		internalRenderHp(numberOfBars,barCount,ep,v,width,height,rightVector,upVector);
8605 	}
8606 	if(productionPercent!=-1) {
8607 		barCount++;
8608 		glColor4f(brightness,0,brightness,0.6f);
8609 		//glColor4f(0.0f*brightness,0.4f*brightness,0.2f*brightness,0.8f);
8610 		internalRenderHp(numberOfBars,barCount,(float)productionPercent/100,v,width,height,rightVector,upVector);
8611 	}
8612 
8613 
8614 //	glBegin(GL_QUADS);
8615 //		if(ep < -2.0f) {
8616 //			//hpbar
8617 //			glVertex3fv((v - (rightVector*width - upVector*height)).ptr());
8618 //			glVertex3fv((v - (rightVector*width + upVector*height)).ptr());
8619 //			glVertex3fv((v + (rightVector*hp*width - upVector*height)).ptr());
8620 //			glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr());
8621 //
8622 //		} else {
8623 //			//hpbar
8624 //			glVertex3fv((v - (rightVector*width - upVector*height)).ptr());
8625 //			glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr());
8626 //			glVertex3fv((v + (rightVector*hp*width - upVector*height*0.0f)).ptr());
8627 //			glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr());
8628 //			//epbar
8629 //			glColor4f(brightness,0,brightness,0.4f);
8630 //			glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr());
8631 //			glVertex3fv((v - (rightVector*width + upVector*height)).ptr());
8632 //			glVertex3fv((v + (rightVector*ep*width - upVector*height)).ptr());
8633 //			glVertex3fv((v + (rightVector*ep*width - upVector*height*0.0f)).ptr());
8634 //		}
8635 //	glEnd();
8636 
8637 	if(lineBorder) {
8638 		//border
8639 		glColor4f(red*brightness,green*brightness,0.1f*brightness,0.5f);
8640 		glBegin(GL_LINE_LOOP);
8641 			glVertex3fv((v - (rightVector*width - upVector*height*yOffset)).ptr());
8642 			glVertex3fv((v - (rightVector*width + upVector*height*yOffset)).ptr());
8643 			glVertex3fv((v + (rightVector*width - upVector*height*yOffset)).ptr());
8644 			glVertex3fv((v + (rightVector*width + upVector*height*yOffset)).ptr());
8645 		glEnd();
8646 	}
8647 
8648 	if(texture!=NULL) {
8649 		//BorderTexture
8650 		glEnable(GL_TEXTURE_2D);
8651 		glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(texture)->getHandle());
8652 		glColor4f(1.f,1.f,1.f,1.f);
8653 		//glColor4f(red+0.1f,green+0.1f,0.1f,0.5f);
8654 		glBegin(GL_QUADS);
8655 			glTexCoord2i(0,1);
8656 			glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr());
8657 			glTexCoord2i(0,0);
8658 			glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr());
8659 			glTexCoord2i(1,0);
8660 			glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr());
8661 			glTexCoord2i(1,1);
8662 			glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr());
8663 		glEnd();
8664 		glDisable(GL_TEXTURE_2D);
8665 	}
8666 
8667     glPopMatrix();
8668 }
8669 
8670 void Renderer::internalRenderHp(int numberOfBars, int barNumber, float hp,
8671 		Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector) {
8672 
8673 	float yOffset=(float)numberOfBars*singleHPheight/2;
8674 	float offsetTop=yOffset-singleHPheight*(barNumber-1);
8675 	float offsetBottom=yOffset-singleHPheight*barNumber;
8676 	offsetBottom=offsetBottom*-1;
8677 	hp=hp*2-1;
8678 
8679 	glBegin(GL_QUADS);
8680 		glVertex3fv((posVector - (rightVector*width - upVector*offsetTop)).ptr());
8681 		glVertex3fv((posVector - (rightVector*width + upVector*offsetBottom)).ptr());
8682 		glVertex3fv((posVector + (rightVector*hp*width - upVector*offsetBottom)).ptr());
8683 		glVertex3fv((posVector + (rightVector*hp*width + upVector*offsetTop)).ptr());
8684 	glEnd();
8685 }
8686 
8687 void Renderer::renderSelectionCircle(Vec3f v, int size, float radius, float thickness) {
8688 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8689 		return;
8690 	}
8691 
8692 	GLUquadricObj *disc;
8693 
8694 	glMatrixMode(GL_MODELVIEW);
8695     glPushMatrix();
8696 
8697 	glTranslatef(v.x, v.y, v.z);
8698 	glRotatef(90.f, 1.f, 0.f, 0.f);
8699 	disc= gluNewQuadric();
8700 	gluQuadricDrawStyle(disc, GLU_FILL);
8701 	gluCylinder(disc, radius*(size-thickness), radius*size, thickness, 30, 1);
8702 	gluDeleteQuadric(disc);
8703 
8704     glPopMatrix();
8705     //	glBegin (GL_QUAD_STRIP);
8706     //	for (float k = 0; k <= 180; k=k+1) {
8707     //		float j=degToRad(k);
8708     //		glVertex3f(v.x+std::cos(j)*.9*radius*size, v.y+thickness, v.z+std::sin(j)*.9*radius*size);
8709     //		glVertex3f(v.x+std::cos(j)*radius*size, v.y, v.z+std::sin(j)*radius*size);
8710     //	}
8711     //	glEnd();
8712 }
8713 
8714 void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2,
8715 						   const Vec3f &color, float width) {
8716 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8717 		return;
8718 	}
8719 
8720 	Config &config= Config::getInstance();
8721 	if(config.getBool("RecordMode","false") == true) {
8722 		return;
8723 	}
8724 
8725 	const int tesselation= 3;
8726 	const float arrowEndSize= 0.4f;
8727 	const float maxlen= 25;
8728 	const float blendDelay= 5.f;
8729 
8730 	Vec3f dir= Vec3f(pos2-pos1);
8731 	float len= dir.length();
8732 
8733 	if(len>maxlen) {
8734 		return;
8735 	}
8736 	float alphaFactor= clamp((maxlen-len)/blendDelay, 0.f, 1.f);
8737 
8738 	dir.normalize();
8739 	Vec3f normal= dir.cross(Vec3f(0, 1, 0));
8740 
8741 	Vec3f pos2Left= pos2 + normal*(width-0.05f) - dir*arrowEndSize*width;
8742 	Vec3f pos2Right= pos2 - normal*(width-0.05f) - dir*arrowEndSize*width;
8743 	Vec3f pos1Left= pos1 + normal*(width+0.05f);
8744 	Vec3f pos1Right= pos1 - normal*(width+0.05f);
8745 
8746 	//arrow body
8747 	glBegin(GL_TRIANGLE_STRIP);
8748 	for(int i=0; i<=tesselation; ++i) {
8749 		float t= static_cast<float>(i)/tesselation;
8750 		Vec3f a= pos1Left.lerp(t, pos2Left);
8751 		Vec3f b= pos1Right.lerp(t, pos2Right);
8752 		Vec4f c= Vec4f(color, t*0.25f*alphaFactor);
8753 
8754 		glColor4fv(c.ptr());
8755 
8756 		glVertex3fv(a.ptr());
8757 		glVertex3fv(b.ptr());
8758 
8759 	}
8760 
8761 	glEnd();
8762 	//arrow end
8763 	glBegin(GL_TRIANGLES);
8764 		glVertex3fv((pos2Left + normal*(arrowEndSize-0.1f)).ptr());
8765 		glVertex3fv((pos2Right - normal*(arrowEndSize-0.1f)).ptr());
8766 		glVertex3fv((pos2 + dir*(arrowEndSize-0.1f)).ptr());
8767 	glEnd();
8768 }
8769 
8770 void Renderer::renderProgressBar3D(int size, int x, int y, Font3D *font, int customWidth,
8771 		string prefixLabel,bool centeredText,int customHeight) {
8772 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8773 		return;
8774 	}
8775 
8776 	// Makiong this smaller than 14 is a bad idea (since the font size is never smaller than that)
8777 	int progressbarHeight	= (customHeight > 0 ? customHeight : 14);
8778     int currentSize     	= size;
8779     int maxSize         	= maxProgressBar;
8780     string renderText   	= intToStr(static_cast<int>(size)) + "%";
8781     if(customWidth > 0) {
8782         if(size > 0) {
8783             currentSize     = (int)((double)customWidth * ((double)size / 100.0));
8784         }
8785         maxSize         = customWidth;
8786         //if(maxSize <= 0) {
8787         //	maxSize = maxProgressBar;
8788         //}
8789     }
8790     if(prefixLabel != "") {
8791         renderText = prefixLabel + renderText;
8792     }
8793 
8794 	//bar
8795 	glBegin(GL_QUADS);
8796 		glColor4fv(progressBarFront2.ptr());
8797 		glVertex2i(x, y);
8798 		glVertex2i(x, y + progressbarHeight);
8799 		glColor4fv(progressBarFront1.ptr());
8800 		glVertex2i(x + currentSize, y + progressbarHeight);
8801 		glVertex2i(x + currentSize, y);
8802 	glEnd();
8803 
8804 	//transp bar
8805 	glEnable(GL_BLEND);
8806 	glBegin(GL_QUADS);
8807 		glColor4fv(progressBarBack2.ptr());
8808 		glVertex2i(x + currentSize, y);
8809 		glVertex2i(x + currentSize, y + progressbarHeight);
8810 		glColor4fv(progressBarBack1.ptr());
8811 		glVertex2i(x + maxSize, y + progressbarHeight);
8812 		glVertex2i(x + maxSize, y);
8813 	glEnd();
8814 	glDisable(GL_BLEND);
8815 
8816 	//text
8817 	//glColor3fv(defColor.ptr());
8818 	//printf("Render progress bar3d renderText [%s] y = %d, centeredText = %d\n",renderText.c_str(),y, centeredText);
8819 
8820 	renderTextBoundingBox3D(renderText, font, defColor, x, y, maxSize,
8821 			progressbarHeight, true, true, false,-1,-1);
8822 }
8823 
8824 void Renderer::renderProgressBar(int size, int x, int y, Font2D *font, int customWidth,
8825 		string prefixLabel,bool centeredText) {
8826 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8827 		return;
8828 	}
8829 
8830     int currentSize     = size;
8831     int maxSize         = maxProgressBar;
8832     string renderText   = intToStr(static_cast<int>(size)) + "%";
8833     if(customWidth > 0) {
8834         if(size > 0) {
8835             currentSize     = (int)((double)customWidth * ((double)size / 100.0));
8836         }
8837         maxSize         = customWidth;
8838         //if(maxSize <= 0) {
8839         //	maxSize = maxProgressBar;
8840         //}
8841     }
8842     if(prefixLabel != "") {
8843         renderText = prefixLabel + renderText;
8844     }
8845 
8846 	//bar
8847 	glBegin(GL_QUADS);
8848 		glColor4fv(progressBarFront2.ptr());
8849 		glVertex2i(x, y);
8850 		glVertex2i(x, y+10);
8851 		glColor4fv(progressBarFront1.ptr());
8852 		glVertex2i(x + currentSize, y+10);
8853 		glVertex2i(x + currentSize, y);
8854 	glEnd();
8855 
8856 	//transp bar
8857 	glEnable(GL_BLEND);
8858 	glBegin(GL_QUADS);
8859 		glColor4fv(progressBarBack2.ptr());
8860 		glVertex2i(x + currentSize, y);
8861 		glVertex2i(x + currentSize, y+10);
8862 		glColor4fv(progressBarBack1.ptr());
8863 		glVertex2i(x + maxSize, y+10);
8864 		glVertex2i(x + maxSize, y);
8865 	glEnd();
8866 	glDisable(GL_BLEND);
8867 
8868 	//text
8869 	glColor3fv(defColor.ptr());
8870 
8871 	//textRenderer->begin(font);
8872 	TextRendererSafeWrapper safeTextRender(textRenderer,font);
8873 	if(centeredText == true) {
8874 		textRenderer->render(renderText.c_str(), x + maxSize / 2, y, centeredText);
8875 	}
8876 	else {
8877 		textRenderer->render(renderText.c_str(), x, y, centeredText);
8878 	}
8879 	//textRenderer->end();
8880 	safeTextRender.end();
8881 }
8882 
8883 
8884 void Renderer::renderTile(const Vec2i &pos) {
8885 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8886 		return;
8887 	}
8888 
8889 	const Map *map= game->getWorld()->getMap();
8890 	Vec2i scaledPos= pos * Map::cellScale;
8891 
8892 	glMatrixMode(GL_MODELVIEW);
8893 	glPushMatrix();
8894 	glTranslatef(-0.5f, 0.f, -0.5f);
8895 
8896 	glInitNames();
8897 	for(int i=0; i < Map::cellScale; ++i) {
8898 		for(int j=0; j < Map::cellScale; ++j) {
8899 
8900 			Vec2i renderPos= scaledPos + Vec2i(i, j);
8901 
8902 			glPushName(renderPos.y);
8903 			glPushName(renderPos.x);
8904 
8905 			glDisable(GL_CULL_FACE);
8906 
8907 			float h1 = map->getCell(renderPos.x, renderPos.y)->getHeight();
8908 			float h2 = map->getCell(renderPos.x, renderPos.y+1)->getHeight();
8909 			float h3 = map->getCell(renderPos.x+1, renderPos.y)->getHeight();
8910 			float h4 = map->getCell(renderPos.x+1, renderPos.y+1)->getHeight();
8911 
8912 			glBegin(GL_TRIANGLE_STRIP);
8913 			glVertex3f(
8914 				static_cast<float>(renderPos.x),
8915 				h1,
8916 				static_cast<float>(renderPos.y));
8917 			glVertex3f(
8918 				static_cast<float>(renderPos.x),
8919 				h2,
8920 				static_cast<float>(renderPos.y+1));
8921 			glVertex3f(
8922 				static_cast<float>(renderPos.x+1),
8923 				h3,
8924 				static_cast<float>(renderPos.y));
8925 			glVertex3f(
8926 				static_cast<float>(renderPos.x+1),
8927 				h4,
8928 				static_cast<float>(renderPos.y+1));
8929 			glEnd();
8930 
8931 			glPopName();
8932 			glPopName();
8933 		}
8934 	}
8935 
8936 	glPopMatrix();
8937 }
8938 
8939 void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) {
8940 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
8941 		return;
8942 	}
8943 	if(texture == NULL) {
8944 		printf("\n**WARNING** detected a null texture to render in renderQuad!\n");
8945 		return;
8946 	}
8947 
8948 	if(w < 0) {
8949 		w = texture->getPixmapConst()->getW();
8950 	}
8951 	if(h < 0) {
8952 		h = texture->getPixmapConst()->getH();
8953 	}
8954 
8955 	glBindTexture(GL_TEXTURE_2D, static_cast<const Texture2DGl*>(texture)->getHandle());
8956 	glBegin(GL_TRIANGLE_STRIP);
8957 		glTexCoord2i(0, 1);
8958 		glVertex2i(x, y+h);
8959 		glTexCoord2i(0, 0);
8960 		glVertex2i(x, y);
8961 		glTexCoord2i(1, 1);
8962 		glVertex2i(x+w, y+h);
8963 		glTexCoord2i(1, 0);
8964 		glVertex2i(x+w, y);
8965 	glEnd();
8966 }
8967 
8968 Renderer::Shadows Renderer::strToShadows(const string &s){
8969 	if(s=="Projected"){
8970 		return sProjected;
8971 	}
8972 	else if(s=="ShadowMapping"){
8973 		return sShadowMapping;
8974 	}
8975 	return sDisabled;
8976 }
8977 
8978 string Renderer::shadowsToStr(Shadows shadows){
8979 	switch(shadows){
8980 	case sDisabled:
8981 		return "Disabled2";
8982 	case sProjected:
8983 		return "Projected";
8984 	case sShadowMapping:
8985 		return "ShadowMapping";
8986 	default:
8987 		assert(false);
8988 		return "";
8989 	}
8990 }
8991 
8992 Texture2D::Filter Renderer::strToTextureFilter(const string &s){
8993 	if(s=="Bilinear"){
8994 		return Texture2D::fBilinear;
8995 	}
8996 	else if(s=="Trilinear"){
8997 		return Texture2D::fTrilinear;
8998 	}
8999 
9000 	throw megaglest_runtime_error("Error converting from string to FilterType, found: "+s);
9001 }
9002 
9003 void Renderer::setAllowRenderUnitTitles(bool value) {
9004 	allowRenderUnitTitles = value;
9005 }
9006 
9007 // This method renders titles for units
9008 void Renderer::renderUnitTitles3D(Font3D *font, Vec3f color) {
9009 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9010 		return;
9011 	}
9012 
9013 	//std::map<int,bool> unitRenderedList;
9014 
9015 	if(visibleFrameUnitList.empty() == false) {
9016 		//printf("Render Unit titles ON\n");
9017 
9018 		for(int idx = 0; idx < (int)visibleFrameUnitList.size(); idx++) {
9019 			const Unit *unit = visibleFrameUnitList[idx];
9020 			if(unit != NULL) {
9021 				if(unit->getVisible() == true) {
9022 					if(unit->getCurrentUnitTitle() != "") {
9023 						//get the screen coordinates
9024 						Vec3f screenPos = unit->getScreenPos();
9025 						renderText3D(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false);
9026 						//unitRenderedList[unit->getId()] = true;
9027 					}
9028 					else {
9029 						string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]";
9030 						Vec3f screenPos = unit->getScreenPos();
9031 						renderText3D(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false);
9032 					}
9033 				}
9034 			}
9035 		}
9036 		visibleFrameUnitList.clear();
9037 	}
9038 
9039 	/*
9040 	if(renderUnitTitleList.empty() == false) {
9041 		for(int idx = 0; idx < renderUnitTitleList.size(); idx++) {
9042 			std::pair<Unit *,Vec3f> &unitInfo = renderUnitTitleList[idx];
9043 			Unit *unit = unitInfo.first;
9044 
9045 			const World *world= game->getWorld();
9046 			Unit *validUnit = world->findUnitById(unit->getId());
9047 
9048 			if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) {
9049 				string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId());
9050 				//get the screen coordinates
9051 				Vec3f &screenPos = unitInfo.second;
9052 				renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false);
9053 				//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z);
9054 			}
9055 		}
9056 		renderUnitTitleList.clear();
9057 	}
9058 	*/
9059 }
9060 
9061 // This method renders titles for units
9062 void Renderer::renderUnitTitles(Font2D *font, Vec3f color) {
9063 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9064 		return;
9065 	}
9066 
9067 	//std::map<int,bool> unitRenderedList;
9068 
9069 	if(visibleFrameUnitList.empty() == false) {
9070 		//printf("Render Unit titles ON\n");
9071 
9072 		for(int idx = 0; idx < (int)visibleFrameUnitList.size(); idx++) {
9073 			const Unit *unit = visibleFrameUnitList[idx];
9074 			if(unit != NULL) {
9075 				if(unit->getCurrentUnitTitle() != "") {
9076 					//get the screen coordinates
9077 					Vec3f screenPos = unit->getScreenPos();
9078 					renderText(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false);
9079 
9080 					//unitRenderedList[unit->getId()] = true;
9081 				}
9082 				else {
9083 					string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]";
9084 					Vec3f screenPos = unit->getScreenPos();
9085 					renderText(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false);
9086 				}
9087 			}
9088 		}
9089 		visibleFrameUnitList.clear();
9090 	}
9091 
9092 	/*
9093 	if(renderUnitTitleList.empty() == false) {
9094 		for(int idx = 0; idx < renderUnitTitleList.size(); idx++) {
9095 			std::pair<Unit *,Vec3f> &unitInfo = renderUnitTitleList[idx];
9096 			Unit *unit = unitInfo.first;
9097 
9098 			const World *world= game->getWorld();
9099 			Unit *validUnit = world->findUnitById(unit->getId());
9100 
9101 			if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) {
9102 				string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId());
9103 				//get the screen coordinates
9104 				Vec3f &screenPos = unitInfo.second;
9105 				renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false);
9106 				//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z);
9107 			}
9108 		}
9109 		renderUnitTitleList.clear();
9110 	}
9111 	*/
9112 }
9113 
9114 void Renderer::removeObjectFromQuadCache(const Object *o) {
9115 	VisibleQuadContainerCache &qCache = getQuadCache();
9116 	for(int visibleIndex = 0;
9117 			visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) {
9118 		Object *currentObj = qCache.visibleObjectList[visibleIndex];
9119 		if(currentObj == o) {
9120 			qCache.visibleObjectList.erase(qCache.visibleObjectList.begin() + visibleIndex);
9121 			break;
9122 		}
9123 	}
9124 }
9125 
9126 void Renderer::removeUnitFromQuadCache(const Unit *unit) {
9127 	VisibleQuadContainerCache &qCache = getQuadCache();
9128 	for(int visibleIndex = 0;
9129 			visibleIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleIndex) {
9130 		Unit *currentUnit = qCache.visibleQuadUnitList[visibleIndex];
9131 		if(currentUnit == unit) {
9132 			qCache.visibleQuadUnitList.erase(qCache.visibleQuadUnitList.begin() + visibleIndex);
9133 			break;
9134 		}
9135 	}
9136 	for(int visibleIndex = 0;
9137 			visibleIndex < (int)qCache.visibleUnitList.size(); ++visibleIndex) {
9138 		Unit *currentUnit = qCache.visibleUnitList[visibleIndex];
9139 		if(currentUnit == unit) {
9140 			qCache.visibleUnitList.erase(qCache.visibleUnitList.begin() + visibleIndex);
9141 			break;
9142 		}
9143 	}
9144 }
9145 
9146 VisibleQuadContainerCache & Renderer::getQuadCache(	bool updateOnDirtyFrame,
9147 													bool forceNew) {
9148 	//forceNew = true;
9149 	if(game != NULL && game->getWorld() != NULL) {
9150 		const World *world= game->getWorld();
9151 
9152 		if(forceNew == true ||
9153 			(updateOnDirtyFrame == true &&
9154 			(world->getFrameCount() != quadCache.cacheFrame ||
9155 			 visibleQuad != quadCache.lastVisibleQuad))) {
9156 
9157 			// Dump cached info
9158 			//if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) {
9159 			//quadCache.clearCacheData();
9160 			//}
9161 			//else {
9162 			quadCache.clearVolatileCacheData();
9163 			worldToScreenPosCache.clear();
9164 			//}
9165 
9166 			// Unit calculations
9167 			for(int i = 0; i < world->getFactionCount(); ++i) {
9168 				const Faction *faction = world->getFaction(i);
9169 				for(int j = 0; j < faction->getUnitCount(); ++j) {
9170 					Unit *unit= faction->getUnit(j);
9171 
9172 					bool unitCheckedForRender = false;
9173 					if(VisibleQuadContainerCache::enableFrustumCalcs == true) {
9174 						//bool insideQuad 	= PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z );
9175 						bool insideQuad 	= CubeInFrustum(quadCache.frustumData, unit->getCurrMidHeightVector().x, unit->getCurrMidHeightVector().y, unit->getCurrMidHeightVector().z, unit->getType()->getRenderSize());
9176 						bool renderInMap 	= world->toRenderUnit(unit);
9177 						if(insideQuad == false || renderInMap == false) {
9178 							unit->setVisible(false);
9179 							if(renderInMap == true) {
9180 								quadCache.visibleUnitList.push_back(unit);
9181 							}
9182 							unitCheckedForRender = true; // no more need to check any further;
9183 							// Currently don't need this list
9184 							//quadCache.inVisibleUnitList.push_back(unit);
9185 						}
9186 					}
9187 					if(unitCheckedForRender == false) {
9188 						bool insideQuad 	= visibleQuad.isInside(unit->getPos());
9189 						bool renderInMap 	= world->toRenderUnit(unit);
9190 						if(insideQuad == true && renderInMap == true) {
9191 							quadCache.visibleQuadUnitList.push_back(unit);
9192 						}
9193 						else {
9194 							unit->setVisible(false);
9195 							// Currently don't need this list
9196 							//quadCache.inVisibleUnitList.push_back(unit);
9197 						}
9198 
9199 						if(renderInMap == true) {
9200 							quadCache.visibleUnitList.push_back(unit);
9201 						}
9202 					}
9203 
9204 					bool unitBuildPending = unit->isBuildCommandPending();
9205 					if(unitBuildPending == true) {
9206 						const UnitBuildInfo &pendingUnit = unit->getBuildCommandPendingInfo();
9207 						const Vec2i &pos = pendingUnit.pos;
9208 						const Map *map= world->getMap();
9209 
9210 						bool unitBuildCheckedForRender = false;
9211 
9212 						//printf("#1 Unit is about to build another unit\n");
9213 
9214 						if(VisibleQuadContainerCache::enableFrustumCalcs == true) {
9215 							Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y);
9216 							//bool insideQuad 	= PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z );
9217 							bool insideQuad 	= CubeInFrustum(quadCache.frustumData, pos3f.x, pos3f.y, pos3f.z, pendingUnit.buildUnit->getRenderSize());
9218 							bool renderInMap 	= world->toRenderUnit(pendingUnit);
9219 							if(insideQuad == false || renderInMap == false) {
9220 								if(renderInMap == true) {
9221 									quadCache.visibleQuadUnitBuildList.push_back(pendingUnit);
9222 								}
9223 								unitBuildCheckedForRender = true; // no more need to check any further;
9224 								// Currently don't need this list
9225 								//quadCache.inVisibleUnitList.push_back(unit);
9226 							}
9227 
9228 							//printf("#2 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap);
9229 						}
9230 
9231 						if(unitBuildCheckedForRender == false) {
9232 							bool insideQuad 	= visibleQuad.isInside(pos);
9233 							bool renderInMap 	= world->toRenderUnit(pendingUnit);
9234 							if(insideQuad == true && renderInMap == true) {
9235 								quadCache.visibleQuadUnitBuildList.push_back(pendingUnit);
9236 							}
9237 							else {
9238 								//unit->setVisible(false);
9239 								// Currently don't need this list
9240 								//quadCache.inVisibleUnitList.push_back(unit);
9241 							}
9242 
9243 							//printf("#3 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap);
9244 						}
9245 
9246 						//printf("#4 quadCache.visibleQuadUnitBuildList.size() = %d\n",quadCache.visibleQuadUnitBuildList.size());
9247 					}
9248 				}
9249 			}
9250 
9251 			if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) {
9252 				// Object calculations
9253 				const Map *map= world->getMap();
9254 				// clear visibility of old objects
9255 				for(int visibleIndex = 0;
9256 					visibleIndex < (int)quadCache.visibleObjectList.size(); ++visibleIndex){
9257 					quadCache.visibleObjectList[visibleIndex]->setVisible(false);
9258 				}
9259 				quadCache.clearNonVolatileCacheData();
9260 
9261 				//int loops1=0;
9262 				PosQuadIterator pqi(map,visibleQuad, Map::cellScale);
9263 				while(pqi.next()) {
9264 					const Vec2i &pos= pqi.getPos();
9265 					if(map->isInside(pos)) {
9266 						//loops1++;
9267 						const Vec2i &mapPos = Map::toSurfCoords(pos);
9268 
9269 						//quadCache.visibleCellList.push_back(mapPos);
9270 
9271 						SurfaceCell *sc = map->getSurfaceCell(mapPos);
9272 						Object *o = sc->getObject();
9273 
9274 						if(VisibleQuadContainerCache::enableFrustumCalcs == true) {
9275 							if(o != NULL) {
9276 								//bool insideQuad 	= PointInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z );
9277 								bool insideQuad 	= CubeInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z, 1);
9278 								if(insideQuad == false) {
9279 									o->setVisible(false);
9280 									continue;
9281 								}
9282 							}
9283 						}
9284 
9285                         bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex());
9286                         if(cellExplored == false) {
9287                             cellExplored = sc->isExplored(world->getThisTeamIndex());
9288                         }
9289 
9290 						bool isExplored = (cellExplored == true && o != NULL);
9291 						//bool isVisible = (sc->isVisible(world->getThisTeamIndex()) && o != NULL);
9292 						bool isVisible = true;
9293 
9294 						if(isExplored == true && isVisible == true) {
9295 							quadCache.visibleObjectList.push_back(o);
9296 							o->setVisible(true);
9297 						}
9298 					}
9299 				}
9300 
9301 				//printf("Frame # = %d loops1 = %d\n",world->getFrameCount(),loops1);
9302 
9303 				//int loops2=0;
9304 
9305 				std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
9306 
9307 				const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
9308 				Quad2i scaledQuad = visibleQuad / Map::cellScale;
9309 				PosQuadIterator pqis(map,scaledQuad);
9310 				while(pqis.next()) {
9311 					const Vec2i &pos= pqis.getPos();
9312 					if(mapBounds.isInside(pos)) {
9313 						//loops2++;
9314 						if(VisibleQuadContainerCache::enableFrustumCalcs == false) {
9315 							quadCache.visibleScaledCellList.push_back(pos);
9316 
9317 							if(markedCells.empty() == false) {
9318 								if(markedCells.find(pos) != markedCells.end()) {
9319 									//printf("#1 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size());
9320 								//if(markedCells.empty() == false) {
9321 									//SurfaceCell *sc = map->getSurfaceCell(pos);
9322 									//quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
9323 									updateMarkedCellScreenPosQuadCache(pos);
9324 								}
9325 								else {
9326 									//printf("#1 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size());
9327 								}
9328 							}
9329 						}
9330 						else {
9331 							bool insideQuad = false;
9332 
9333 							if( !insideQuad) {
9334 								SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y);
9335 								insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0);
9336 							}
9337 							if( !insideQuad) {
9338 								SurfaceCell *sc = map->getSurfaceCell(pos.x+1, pos.y);
9339 								insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0);
9340 							}
9341 							if( !insideQuad) {
9342 								SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y+1);
9343 								insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0);
9344 							}
9345 							if( !insideQuad) {
9346 								SurfaceCell *sc = map->getSurfaceCell(pos.x+1, pos.y+1);
9347 								insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0);
9348 							}
9349 
9350 							if(insideQuad == true) {
9351 								quadCache.visibleScaledCellList.push_back(pos);
9352 
9353 								if(markedCells.empty() == false) {
9354 									if(markedCells.find(pos) != markedCells.end()) {
9355 										//printf("#2 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size());
9356 									//if(markedCells.empty() == false) {
9357 										//quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
9358 										updateMarkedCellScreenPosQuadCache(pos);
9359 									}
9360 									else {
9361 										//printf("#2 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size());
9362 									}
9363 								}
9364 							}
9365 						}
9366 					}
9367 				}
9368 				//printf("Frame # = %d loops2 = %d\n",world->getFrameCount(),loops2);
9369 			}
9370 			quadCache.cacheFrame = world->getFrameCount();
9371 			quadCache.lastVisibleQuad = visibleQuad;
9372 		}
9373 	}
9374 
9375 	return quadCache;
9376 }
9377 
9378 void Renderer::updateMarkedCellScreenPosQuadCache(Vec2i pos) {
9379 	const World *world= game->getWorld();
9380 	const Map *map= world->getMap();
9381 
9382 	SurfaceCell *sc = map->getSurfaceCell(pos);
9383 	quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
9384 }
9385 
9386 void Renderer::forceQuadCacheUpdate() {
9387 	quadCache.cacheFrame = -1;
9388 
9389 	Vec2i clearPos(-1,-1);
9390 	quadCache.lastVisibleQuad.p[0] = clearPos;
9391 	quadCache.lastVisibleQuad.p[1] = clearPos;
9392 	quadCache.lastVisibleQuad.p[2] = clearPos;
9393 	quadCache.lastVisibleQuad.p[3] = clearPos;
9394 }
9395 
9396 std::pair<bool,Vec3f> Renderer::posInCellQuadCache(Vec2i pos) {
9397 	std::pair<bool,Vec3f> result = make_pair(false,Vec3f());
9398 	if(std::find(
9399 			quadCache.visibleScaledCellList.begin(),
9400 			quadCache.visibleScaledCellList.end(),
9401 			pos) != quadCache.visibleScaledCellList.end()) {
9402 		result.first = true;
9403 		result.second = quadCache.visibleScaledCellToScreenPosList[pos];
9404 	}
9405 	return result;
9406 }
9407 
9408 Vec3f Renderer::getMarkedCellScreenPosQuadCache(Vec2i pos) {
9409 	Vec3f result(-1,-1,-1);
9410 	if(std::find(
9411 			quadCache.visibleScaledCellList.begin(),
9412 			quadCache.visibleScaledCellList.end(),
9413 			pos) != quadCache.visibleScaledCellList.end()) {
9414 		result = quadCache.visibleScaledCellToScreenPosList[pos];
9415 	}
9416 	return result;
9417 }
9418 
9419 void Renderer::beginRenderToTexture(Texture2D **renderToTexture) {
9420 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9421 		return;
9422 	}
9423 
9424 	static bool supportFBOs = Texture2DGl().supports_FBO_RBO();
9425 
9426 	if(supportFBOs == true && renderToTexture != NULL) {
9427 		Config &config= Config::getInstance();
9428 		Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
9429 		int maxAnisotropy				= config.getInt("FilterMaxAnisotropy");
9430 
9431 		const Metrics &metrics	= Metrics::getInstance();
9432 
9433 		*renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
9434 		Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
9435 		texture->setMipmap(false);
9436 		Pixmap2D *pixmapScreenShot = texture->getPixmap();
9437 		pixmapScreenShot->init(metrics.getScreenW(), metrics.getScreenH(), 4);
9438 		texture->setForceCompressionDisabled(true);
9439 		texture->init(textureFilter,maxAnisotropy);
9440 		texture->setup_FBO_RBO();
9441 
9442 		assertGl();
9443 
9444 		if(texture->checkFrameBufferStatus() == false) {
9445 			//printf("******************** WARNING CANNOT Attach to FBO!\n");
9446 			texture->end();
9447 			delete texture;
9448 			*renderToTexture=NULL;
9449 		}
9450 	}
9451 }
9452 
9453 void Renderer::endRenderToTexture(Texture2D **renderToTexture) {
9454 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9455 		return;
9456 	}
9457 
9458 	static bool supportFBOs = Texture2DGl().supports_FBO_RBO();
9459 
9460 	if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) {
9461 		Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
9462 		if(texture != NULL) {
9463 			texture->dettachFrameBufferFromTexture();
9464 		}
9465 
9466 		assertGl();
9467 	}
9468 }
9469 
9470 void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
9471 								 int screenPosX, int screenPosY,
9472 								 Texture2D **renderToTexture) {
9473 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9474 		return;
9475 	}
9476 
9477 	static bool supportFBOs = Texture2DGl().supports_FBO_RBO();
9478 	if(Config::getInstance().getBool("LegacyMapPreviewRendering","false") == true) {
9479 		supportFBOs = false;
9480 	}
9481 
9482 	//static bool supportFBOs = false;
9483 	const Metrics &metrics= Metrics::getInstance();
9484 
9485 	float alt				= 0;
9486 	float showWater			= 0;
9487 	int renderMapHeight		= 64;
9488 	int renderMapWidth		= 64;
9489 	float cellSize			= 2;
9490 	float playerCrossSize	= 2;
9491 	float clientW			= renderMapWidth * cellSize;
9492 	float clientH			= renderMapHeight * cellSize;;
9493 	float minDimension 		= std::min(metrics.getVirtualW(), metrics.getVirtualH());
9494 
9495 	// stretch small maps to 128x128
9496 	if(map->getW() < map->getH()) {
9497 		cellSize = cellSize * renderMapHeight / map->getH();
9498 	}
9499 	else {
9500 		cellSize = cellSize * renderMapWidth / map->getW();
9501 	}
9502 
9503 	assertGl();
9504 
9505 	if(supportFBOs == true && renderToTexture != NULL) {
9506 		Config &config= Config::getInstance();
9507 		Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
9508 		int maxAnisotropy				= config.getInt("FilterMaxAnisotropy");
9509 
9510 		*renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
9511 		Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
9512 		texture->setMipmap(false);
9513 		Pixmap2D *pixmapScreenShot = texture->getPixmap();
9514 		pixmapScreenShot->init(minDimension, minDimension, 4);
9515 		texture->setForceCompressionDisabled(true);
9516 		texture->init(textureFilter,maxAnisotropy);
9517 		texture->setup_FBO_RBO();
9518 
9519 		assertGl();
9520 
9521 		if(texture->checkFrameBufferStatus() == false) {
9522 			//printf("******************** WARNING CANNOT Attach to FBO!\n");
9523 			texture->end();
9524 			delete texture;
9525 			*renderToTexture=NULL;
9526 		}
9527 	}
9528 
9529 	if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) {
9530 		cellSize  =1;
9531 		clientW = minDimension;
9532 		clientH = minDimension;
9533 		int mapMaxDimensionSize = std::max(map->getW(),map->getH());
9534 		switch(mapMaxDimensionSize) {
9535 			case 8:
9536 				cellSize = 96;
9537 				break;
9538 			case 16:
9539 				cellSize = 48;
9540 				break;
9541 			case 32:
9542 				cellSize = 24;
9543 				break;
9544 			case 64:
9545 				cellSize = 12;
9546 				break;
9547 			case 128:
9548 				cellSize = 6;
9549 				break;
9550 			case 256:
9551 				cellSize = 3;
9552 				break;
9553 			case 512:
9554 				cellSize = 2;
9555 				break;
9556 		}
9557 	}
9558 
9559 	glFrontFace(GL_CW);
9560 	glEnable(GL_CULL_FACE);
9561 
9562 	glMatrixMode(GL_PROJECTION);
9563     glPushMatrix();
9564 	glLoadIdentity();
9565 
9566 	assertGl();
9567 
9568 	GLint viewport[4];	// Where The original Viewport Values Will Be Stored
9569 
9570 	if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) {
9571 		glGetIntegerv(GL_VIEWPORT, viewport);
9572 		glOrtho(0, clientW, 0, clientH, 0, 1);
9573 		glViewport(0, 0, clientW, clientH);
9574 	}
9575 	else {
9576 		glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1);
9577 	}
9578 
9579 	glMatrixMode(GL_MODELVIEW);
9580 
9581 	glPushMatrix();
9582 	glLoadIdentity();
9583 
9584 	if(supportFBOs == false || renderToTexture == NULL ||  *renderToTexture == NULL) {
9585 		glTranslatef(static_cast<float>(screenPosX),static_cast<float>(screenPosY)-clientH,0.0f);
9586 	}
9587 
9588 	assertGl();
9589 
9590 	glPushAttrib(GL_CURRENT_BIT);
9591 	glLineWidth(1);
9592 	glColor3f(0, 0, 0);
9593 
9594 	for (int j = 0; j < map->getH(); j++) {
9595 		for (int i = 0; i < map->getW(); i++) {
9596 			//surface
9597 			alt = map->getHeight(i, j) / 20.f;
9598 			showWater = map->getWaterLevel()/ 20.f - alt;
9599 			showWater = (showWater > 0)? showWater:0;
9600 			Vec3f surfColor;
9601 			switch (map->getSurface(i, j)) {
9602 				case st_Grass:
9603 					surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater);
9604 					break;
9605 				case st_Secondary_Grass:
9606 					surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater);
9607 					break;
9608 				case st_Road:
9609 					surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater);
9610 					break;
9611 				case st_Stone:
9612 					surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater);
9613 					break;
9614 				case st_Ground:
9615 					surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater);
9616 					break;
9617 			}
9618 
9619 			glColor3fv(surfColor.ptr());
9620 
9621 			glBegin(GL_TRIANGLE_STRIP);
9622 			glVertex2f(i * cellSize, clientH - j * cellSize - cellSize);
9623 			glVertex2f(i * cellSize, clientH - j * cellSize);
9624 			glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize);
9625 			glVertex2f(i * cellSize + cellSize, clientH - j * cellSize);
9626 			glEnd();
9627 
9628 			//objects
9629 			if(renderAll == true) {
9630 				switch (map->getObject(i, j)) {
9631 					case 0:
9632 						glColor3f(0.f, 0.f, 0.f);
9633 						break;
9634 					case 1:
9635 						glColor3f(1.f, 0.f, 0.f);
9636 						break;
9637 					case 2:
9638 						glColor3f(1.f, 1.f, 1.f);
9639 						break;
9640 					case 3:
9641 						glColor3f(0.5f, 0.5f, 1.f);
9642 						break;
9643 					case 4:
9644 						glColor3f(0.f, 0.f, 1.f);
9645 						break;
9646 					case 5:
9647 						glColor3f(0.5f, 0.5f, 0.5f);
9648 						break;
9649 					case 6:
9650 						glColor3f(1.f, 0.8f, 0.5f);
9651 						break;
9652 					case 7:
9653 						glColor3f(0.f, 1.f, 1.f);
9654 						break;
9655 					case 8:
9656 						glColor3f(0.7f, 0.1f, 0.3f);
9657 						break;
9658 					case 9:
9659 						glColor3f(0.5f, 1.f, 0.1f);
9660 						break;
9661 					case 10:
9662 						glColor3f(1.f, 0.2f, 0.8f);
9663 						break;// we don't render unvisible blocking objects
9664 				}
9665 
9666 				if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) {
9667 					glPointSize(cellSize / 2.f);
9668 					glBegin(GL_POINTS);
9669 					glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f);
9670 					glEnd();
9671 				}
9672 			}
9673 
9674 	//		bool found = false;
9675 
9676 			//height lines
9677 	//		if (!found) {
9678 
9679 				//left
9680 				if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) {
9681 					glColor3fv((surfColor*0.5f).ptr());
9682 					glBegin(GL_LINES);
9683 					glVertex2f(i * cellSize, clientH - (j + 1) * cellSize);
9684 					glVertex2f(i * cellSize, clientH - j * cellSize);
9685 					glEnd();
9686 				}
9687 				//down
9688 				if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) {
9689 					glColor3fv((surfColor*0.5f).ptr());
9690 					glBegin(GL_LINES);
9691 					glVertex2f(i * cellSize, clientH - j * cellSize);
9692 					glVertex2f((i + 1) * cellSize, clientH - j * cellSize);
9693 					glEnd();
9694 				}
9695 
9696 
9697 				//left
9698 				if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) {
9699 					glColor3fv((surfColor*2.f).ptr());
9700 					glBegin(GL_LINES);
9701 					glVertex2f(i * cellSize, clientH - (j + 1)  * cellSize);
9702 					glVertex2f(i * cellSize, clientH - j * cellSize);
9703 					glEnd();
9704 				}
9705 				if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) {
9706 					glColor3fv((surfColor*2.f).ptr());
9707 					glBegin(GL_LINES);
9708 					glVertex2f(i * cellSize, clientH - j * cellSize);
9709 					glVertex2f((i + 1) * cellSize, clientH - j * cellSize);
9710 					glEnd();
9711 				}
9712 	//				}
9713 
9714 				//resources
9715 				if(renderAll == true) {
9716 					switch (map->getResource(i, j)) {
9717 						case 1: glColor3f(1.f, 1.f, 0.f); break;
9718 						case 2: glColor3f(0.5f, 0.5f, 0.5f); break;
9719 						case 3: glColor3f(1.f, 0.f, 0.f); break;
9720 						case 4: glColor3f(0.f, 0.f, 1.f); break;
9721 						case 5: glColor3f(0.5f, 0.5f, 1.f); break;
9722 					}
9723 
9724 					if (renderAll && map->getResource(i, j) != 0) {
9725 						glBegin(GL_LINES);
9726 						glVertex2f(i * cellSize, clientH - j * cellSize - cellSize);
9727 						glVertex2f(i * cellSize + cellSize, clientH - j * cellSize);
9728 						glVertex2f(i * cellSize, clientH - j * cellSize);
9729 						glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize);
9730 						glEnd();
9731 					}
9732 				}
9733 		}
9734 	}
9735 
9736 	//start locations
9737 	glLineWidth(3);
9738 
9739 	assertGl();
9740 
9741 	if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) {
9742 		glLineWidth(14);
9743 		playerCrossSize = 24;
9744 	}
9745 	else {
9746 		// force playerCrossSize to be at least of size 4
9747 		if(cellSize < 4) {
9748 			playerCrossSize = 4;
9749 		}
9750 		else {
9751 			playerCrossSize = cellSize;
9752 		}
9753 	}
9754 
9755 	assertGl();
9756 
9757 	Vec2f *vertices = new Vec2f[map->getMaxFactions() * 4];
9758 	Vec3f *colors = new Vec3f[map->getMaxFactions() * 4];
9759 
9760 	for (int i = 0; i < map->getMaxFactions(); i++) {
9761 		Vec3f color;
9762 		switch (i) {
9763 			case 0:
9764 				color = Vec3f(1.f, 0.f, 0.f);
9765 				break;
9766 			case 1:
9767 				color = Vec3f(0.f, 0.f, 1.f);
9768 				break;
9769 			case 2:
9770 				color = Vec3f(0.f, 1.f, 0.f);
9771 				break;
9772 			case 3:
9773 				color = Vec3f(1.f, 1.f, 0.f);
9774 				break;
9775 			case 4:
9776 				color = Vec3f(1.f, 1.f, 1.f);
9777 				break;
9778 			case 5:
9779 				color = Vec3f(0.f, 1.f, 0.8f);
9780 				break;
9781 			case 6:
9782 				color = Vec3f(1.f, 0.5f, 0.f);
9783 				break;
9784 			case 7:
9785 				color = Vec3f(1.f, 0.5f, 1.f);
9786 				break;
9787    		}
9788 
9789 		colors[i*4]     = color;
9790 		colors[(i*4)+1] = color;
9791 		colors[(i*4)+2] = color;
9792 		colors[(i*4)+3] = color;
9793 
9794 		vertices[i*4] 	= Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize);
9795 		vertices[(i*4)+1] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize);
9796 		vertices[(i*4)+2] = Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize);
9797 		vertices[(i*4)+3] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) - 1) * cellSize);
9798 	}
9799 
9800 	glEnableClientState(GL_COLOR_ARRAY);
9801 	glColorPointer(3, GL_FLOAT, 0, &colors[0]);
9802 	glEnableClientState(GL_VERTEX_ARRAY);
9803 	glVertexPointer(2, GL_FLOAT, 0, &vertices[0]);
9804 	glDrawArrays(GL_LINES, 0, 4 * map->getMaxFactions());
9805 	glDisableClientState(GL_COLOR_ARRAY);
9806     glDisableClientState(GL_VERTEX_ARRAY);
9807 
9808 	assertGl();
9809 
9810 	glLineWidth(1);
9811 
9812 	glPopMatrix();
9813 	glPopAttrib();
9814 	glMatrixMode(GL_PROJECTION);
9815 	glPopMatrix();
9816 
9817 	if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) {
9818 		Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
9819 		if(texture != NULL) {
9820 			texture->dettachFrameBufferFromTexture();
9821 		}
9822 
9823 		glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
9824 
9825 		assertGl();
9826 	}
9827 
9828 	delete [] vertices;
9829 	delete [] colors;
9830 
9831 	assertGl();
9832 }
9833 
9834 // setLastRenderFps and calculate shadowsOffDueToMinRender
9835 void Renderer::setLastRenderFps(int value) {
9836 	 	lastRenderFps = value;
9837 	 	smoothedRenderFps=(MIN_FPS_NORMAL_RENDERING*smoothedRenderFps+lastRenderFps)/(MIN_FPS_NORMAL_RENDERING+1.0f);
9838 
9839 		if(smoothedRenderFps>=MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD){
9840 			shadowsOffDueToMinRender=false;
9841 		}
9842 		if(smoothedRenderFps<=MIN_FPS_NORMAL_RENDERING){
9843 			 shadowsOffDueToMinRender=true;
9844 		}
9845 }
9846 
9847 std::size_t Renderer::getCurrentPixelByteCount(ResourceScope rs) const {
9848 	std::size_t result = 0;
9849 	for(int i = (rs == rsCount ? 0 : rs); i < rsCount; ++i) {
9850 		if(textureManager[i] != NULL) {
9851 			const ::Shared::Graphics::TextureContainer &textures = textureManager[i]->getTextures();
9852 			for(int j = 0; j < (int)textures.size(); ++j) {
9853 				const Texture *texture = textures[j];
9854 				result += texture->getPixelByteCount();
9855 			}
9856 			if(rs != rsCount) {
9857 				break;
9858 			}
9859 		}
9860 	}
9861 
9862 	return result;
9863 }
9864 
9865 Texture2D * Renderer::preloadTexture(string logoFilename) {
9866 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9867 
9868 	Texture2D *result = NULL;
9869 	if(logoFilename != "") {
9870 		// Cache faction preview textures
9871 		string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
9872 		std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
9873 
9874 		if(crcFactionPreviewTextureCache.find(logoFilename) != crcFactionPreviewTextureCache.end()) {
9875 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9876 
9877 			if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] load texture from cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9878 
9879 			result = crcFactionPreviewTextureCache[logoFilename];
9880 		}
9881 		else {
9882 			if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9883 			Renderer &renderer= Renderer::getInstance();
9884 			result = renderer.newTexture2D(rsGlobal);
9885 			if(result) {
9886 				result->setMipmap(true);
9887 				result->load(logoFilename);
9888 				//renderer.initTexture(rsGlobal,result);
9889 			}
9890 
9891 			if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add texture to manager and cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9892 
9893 			crcFactionPreviewTextureCache[logoFilename] = result;
9894 		}
9895 	}
9896 
9897 	return result;
9898 }
9899 
9900 Texture2D * Renderer::findTexture(string logoFilename) {
9901 	if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str());
9902 
9903 	Texture2D *result = preloadTexture(logoFilename);
9904 	if(result != NULL && result->getInited() == false) {
9905 		Renderer &renderer= Renderer::getInstance();
9906 		renderer.initTexture(rsGlobal,result);
9907 	}
9908 
9909 	return result;
9910 }
9911 
9912 void Renderer::cycleShowDebugUILevel() {
9913 	//printf("#1 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles);
9914 
9915 	//if(showDebugUI == false) {
9916 	//	showDebugUI = true;
9917 	//}
9918 	if((showDebugUILevel & debugui_fps) != debugui_fps ||
9919 		(showDebugUILevel & debugui_unit_titles) != debugui_unit_titles) {
9920 		showDebugUILevel  |= debugui_fps;
9921 		showDebugUILevel  |= debugui_unit_titles;
9922 	}
9923 	else {
9924 		showDebugUILevel  = debugui_fps;
9925 	}
9926 
9927 	//printf("#2 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles);
9928 }
9929 
9930 void Renderer::renderFPSWhenEnabled(int lastFps) {
9931 	if(getShowDebugUI() == true) {
9932 		CoreData &coreData= CoreData::getInstance();
9933 		if(Renderer::renderText3DEnabled) {
9934 			renderText3D(
9935 				"FPS: " + intToStr(lastFps),
9936 				coreData.getMenuFontNormal3D(), Vec3f(1.f), 10, 10, false);
9937 		}
9938 		else {
9939 			renderText(
9940 				"FPS: " + intToStr(lastFps),
9941 				coreData.getMenuFontNormal(), Vec3f(1.f), 10, 10, false);
9942 		}
9943 	}
9944 }
9945 
9946 void Renderer::renderPopupMenu(PopupMenu *menu) {
9947 	if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
9948 		return;
9949 	}
9950 
9951 	if(menu->getVisible() == false || menu->getEnabled() == false) {
9952 		return;
9953 	}
9954 
9955 	//background
9956 	glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT);
9957 	glEnable(GL_BLEND);
9958 
9959 	glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
9960 	glBegin(GL_TRIANGLE_STRIP);
9961 		glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10);
9962 		glVertex2i(menu->getX(), menu->getY());
9963 		glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10);
9964 		glVertex2i(menu->getX() + menu->getW(), menu->getY());
9965 	glEnd();
9966 
9967 	glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ;
9968 	glBegin(GL_TRIANGLE_STRIP);
9969 		glVertex2i(menu->getX(), menu->getY() + menu->getH());
9970 		glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10);
9971 		glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH());
9972 		glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10);
9973 	glEnd();
9974 
9975 	glBegin(GL_LINE_LOOP);
9976 		glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
9977 		glVertex2i(menu->getX(), menu->getY());
9978 
9979 		glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ;
9980 		glVertex2i(menu->getX() + menu->getW(), menu->getY());
9981 
9982 		glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
9983 		glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH());
9984 
9985 		glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ;
9986 		glVertex2i(menu->getX(), menu->getY() + menu->getH());
9987 	glEnd();
9988 
9989 	glBegin(GL_LINE_STRIP);
9990 		glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ;
9991 		glVertex2i(menu->getX(), menu->getY() + 90*menu->getH()/100);
9992 
9993 		glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ;
9994 		glVertex2i(menu->getX()+ menu->getW(), menu->getY() + 90*menu->getH()/100);
9995 	glEnd();
9996 
9997 	glPopAttrib();
9998 
9999 	Vec4f fontColor;
10000 	//if(game!=NULL){
10001 	//	fontColor=game->getGui()->getDisplay()->getColor();
10002 	//}
10003 	//else {
10004 		// white shadowed is default ( in the menu for example )
10005 		fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f);
10006 	//}
10007 
10008 	if(renderText3DEnabled == true) {
10009 		//text
10010 		renderTextBoundingBox3D(
10011 				menu->getHeader(), menu->getFont3D(),fontColor,
10012 				menu->getX(), menu->getY()+93*menu->getH()/100,menu->getW(),0,
10013 			true,false, false,-1,-1);
10014 
10015 	}
10016 	else {
10017 		//text
10018 		int renderX = (menu->getX() + (menu->getW() / 2));
10019 		//int renderY = (menu->getY() + (menu->getH() / 2));
10020 		FontMetrics *fontMetrics= menu->getFont()->getMetrics();
10021 		int renderY = menu->getY() + menu->getH() - fontMetrics->getHeight(menu->getHeader());
10022 		renderTextShadow(
10023 				menu->getHeader(), menu->getFont(),fontColor,
10024 				renderX, renderY,
10025 			true);
10026 
10027 		//renderText(button->getText(), button->getFont(), color,x + (w / 2), y + (h / 2), true);
10028 	}
10029 
10030 	//buttons
10031 //	int maxButtonWidth = -1;
10032 	std::vector<GraphicButton> &menuItems = menu->getMenuItems();
10033 //	for(unsigned int i = 0; i < menuItems.size(); ++i) {
10034 //		GraphicButton *button = &menuItems[i];
10035 //		int currentButtonWidth = -1;
10036 //		if(renderText3DEnabled == true) {
10037 //			FontMetrics *fontMetrics= menu->getFont3D()->getMetrics();
10038 //			currentButtonWidth = fontMetrics->getTextWidth(button->getText());
10039 //		}
10040 //		else {
10041 //			FontMetrics *fontMetrics= menu->getFont()->getMetrics();
10042 //			currentButtonWidth = fontMetrics->getTextWidth(button->getText());
10043 //		}
10044 //
10045 //		if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) {
10046 //			maxButtonWidth = currentButtonWidth + 5;
10047 //		}
10048 //	}
10049 
10050 	for(unsigned int i = 0; i < menuItems.size(); ++i) {
10051 		GraphicButton *button = &menuItems[i];
10052 
10053 		//button->setW(maxButtonWidth);
10054 		renderButton(button);
10055 	}
10056 
10057 }
10058 
10059 void Renderer::setupRenderForVideo() {
10060 	clearBuffers();
10061 	//3d
10062 	reset3dMenu();
10063 	clearZBuffer();
10064 	//2d
10065 	reset2d();
10066 	glClearColor(0.f, 0.f, 0.f, 1.f);
10067 }
10068 
10069 void Renderer::renderVideoLoading(int progressPercent) {
10070 	//printf("Rendering progress progressPercent = %d\n",progressPercent);
10071 	setupRenderForVideo();
10072 
10073 	Lang &lang= Lang::getInstance();
10074 	string textToRender = lang.getString("PleaseWait");
10075 	const Metrics &metrics= Metrics::getInstance();
10076 
10077 	static Chrono cycle(true);
10078 	static float anim = 0.0f;
10079 
10080 	if(CoreData::getInstance().getMenuFontBig3D() != NULL) {
10081 
10082 		int w= metrics.getVirtualW();
10083 		int renderX = (w / 2) - (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getTextWidth(textToRender) / 2);
10084 		int h= metrics.getVirtualH();
10085 		int renderY = (h / 2) + (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getHeight(textToRender) / 2);
10086 
10087 		renderText3D(
10088 				textToRender,
10089 				CoreData::getInstance().getMenuFontBig3D(),
10090 				Vec4f(1.f, 1.f, 0.f,anim),
10091 				renderX, renderY, false);
10092 	}
10093 	else {
10094 		renderText(
10095 				textToRender,
10096 				CoreData::getInstance().getMenuFontBig(),
10097 				Vec4f(1.f, 1.f, 0.f,anim), (metrics.getScreenW() / 2),
10098 				(metrics.getScreenH() / 2), true);
10099 	}
10100     swapBuffers();
10101 
10102     if(cycle.getCurMillis() % 50 == 0) {
10103     	static bool animCycleUp = true;
10104     	if(animCycleUp == true) {
10105 			anim += 0.1f;
10106 			if(anim > 1.f) {
10107 				anim= 1.f;
10108 				cycle.reset();
10109 				animCycleUp = false;
10110 			}
10111     	}
10112     	else {
10113 			anim -= 0.1f;
10114 			if(anim < 0.f) {
10115 				anim= 0.f;
10116 				cycle.reset();
10117 				animCycleUp = true;
10118 			}
10119     	}
10120     }
10121 }
10122 
10123 }}//end namespace
10124