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 *> > ¤tAttackBoostUnits = 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