Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Renderer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * higher level interface on top of OpenGL to render basic objects:
20  * terrain, models, sprites, particles etc.
21  */
22 
23 #include "precompiled.h"
24 
25 #include <map>
26 #include <set>
27 #include <algorithm>
28 
29 #include <boost/algorithm/string.hpp>
30 
31 #include "Renderer.h"
32 
33 #include "lib/bits.h" // is_pow2
36 #include "maths/Matrix3D.h"
37 #include "maths/MathUtil.h"
38 #include "ps/CLogger.h"
39 #include "ps/ConfigDB.h"
40 #include "ps/Game.h"
41 #include "ps/Profile.h"
42 #include "ps/Filesystem.h"
43 #include "ps/World.h"
44 #include "ps/Loader.h"
45 #include "ps/ProfileViewer.h"
46 #include "graphics/Camera.h"
47 #include "graphics/GameView.h"
48 #include "graphics/LightEnv.h"
49 #include "graphics/LOSTexture.h"
51 #include "graphics/Model.h"
52 #include "graphics/ModelDef.h"
54 #include "graphics/ShaderManager.h"
55 #include "graphics/Terrain.h"
56 #include "graphics/Texture.h"
60 #include "renderer/ModelRenderer.h"
64 #include "renderer/ShadowMap.h"
65 #include "renderer/SkyManager.h"
68 #include "renderer/TimeManager.h"
70 #include "renderer/WaterManager.h"
71 
72 extern bool g_GameRestarted;
73 
74 ///////////////////////////////////////////////////////////////////////////////////
75 // CRendererStatsTable - Profile display of rendering stats
76 
77 /**
78  * Class CRendererStatsTable: Implementation of AbstractProfileTable to
79  * display the renderer stats in-game.
80  *
81  * Accesses CRenderer::m_Stats by keeping the reference passed to the
82  * constructor.
83  */
85 {
87 public:
89 
90  // Implementation of AbstractProfileTable interface
91  CStr GetName();
92  CStr GetTitle();
93  size_t GetNumberRows();
94  const std::vector<ProfileColumn>& GetColumns();
95  CStr GetCellText(size_t row, size_t col);
96  AbstractProfileTable* GetChild(size_t row);
97 
98 private:
99  /// Reference to the renderer singleton's stats
101 
102  /// Column descriptions
103  std::vector<ProfileColumn> columnDescriptions;
104 
105  enum {
116 
117  // Must be last to count number of rows
119  };
120 };
121 
122 // Construction
124  : Stats(st)
125 {
126  columnDescriptions.push_back(ProfileColumn("Name", 230));
127  columnDescriptions.push_back(ProfileColumn("Value", 100));
128 }
129 
130 // Implementation of AbstractProfileTable interface
132 {
133  return "renderer";
134 }
135 
137 {
138  return "Renderer statistics";
139 }
140 
142 {
143  return NumberRows;
144 }
145 
146 const std::vector<ProfileColumn>& CRendererStatsTable::GetColumns()
147 {
148  return columnDescriptions;
149 }
150 
151 CStr CRendererStatsTable::GetCellText(size_t row, size_t col)
152 {
153  char buf[256];
154 
155  switch(row)
156  {
157  case Row_DrawCalls:
158  if (col == 0)
159  return "# draw calls";
160  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_DrawCalls);
161  return buf;
162 
163  case Row_TerrainTris:
164  if (col == 0)
165  return "# terrain tris";
166  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_TerrainTris);
167  return buf;
168 
169  case Row_WaterTris:
170  if (col == 0)
171  return "# water tris";
172  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_WaterTris);
173  return buf;
174 
175  case Row_ModelTris:
176  if (col == 0)
177  return "# model tris";
178  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_ModelTris);
179  return buf;
180 
181  case Row_OverlayTris:
182  if (col == 0)
183  return "# overlay tris";
184  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_OverlayTris);
185  return buf;
186 
187  case Row_BlendSplats:
188  if (col == 0)
189  return "# blend splats";
190  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_BlendSplats);
191  return buf;
192 
193  case Row_Particles:
194  if (col == 0)
195  return "# particles";
196  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_Particles);
197  return buf;
198 
199  case Row_VBReserved:
200  if (col == 0)
201  return "VB bytes reserved";
202  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)g_VBMan.GetBytesReserved());
203  return buf;
204 
205  case Row_VBAllocated:
206  if (col == 0)
207  return "VB bytes allocated";
208  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)g_VBMan.GetBytesAllocated());
209  return buf;
210 
211  case Row_ShadersLoaded:
212  if (col == 0)
213  return "shader effects loaded";
214  sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)g_Renderer.GetShaderManager().GetNumEffectsLoaded());
215  return buf;
216 
217  default:
218  return "???";
219  }
220 }
221 
223 {
224  return 0;
225 }
226 
227 
228 ///////////////////////////////////////////////////////////////////////////////////
229 // CRenderer implementation
230 
231 /**
232  * Struct CRendererInternals: Truly hide data that is supposed to be hidden
233  * in this structure so it won't even appear in header files.
234  */
236 {
238 public:
239  /// true if CRenderer::Open has been called
240  bool IsOpen;
241 
242  /// true if shaders need to be reloaded
244 
245  /// Table to display renderer stats in-game via profile system
247 
248  /// Shader manager
250 
251  /// Water manager
253 
254  /// Sky manager
256 
257  /// Texture manager
259 
260  /// Terrain renderer
262 
263  /// Overlay renderer
265 
266  /// Particle manager
268 
269  /// Particle renderer
271 
272  /// Material manager
274 
275  /// Time manager
277 
278  /// Shadow map
280 
281  /// Postprocessing effect manager
283 
284  /// Various model renderers
285  struct Models
286  {
287  // NOTE: The current renderer design (with ModelRenderer, ModelVertexRenderer,
288  // RenderModifier, etc) is mostly a relic of an older design that implemented
289  // the different materials and rendering modes through extensive subclassing
290  // and hooking objects together in various combinations.
291  // The new design uses the CShaderManager API to abstract away the details
292  // of rendering, and uses a data-driven approach to materials, so there are
293  // now a small number of generic subclasses instead of many specialised subclasses,
294  // but most of the old infrastructure hasn't been refactored out yet and leads to
295  // some unwanted complexity.
296 
297  // Submitted models are split on two axes:
298  // - Normal vs Transp[arent] - alpha-blended models are stored in a separate
299  // list so we can draw them above/below the alpha-blended water plane correctly
300  // - Skinned vs Unskinned - with hardware lighting we don't need to
301  // duplicate mesh data per model instance (except for skinned models),
302  // so non-skinned models get different ModelVertexRenderers
303 
305  ModelRendererPtr NormalUnskinned; // == NormalSkinned if unskinned shader instancing not supported
307  ModelRendererPtr TranspUnskinned; // == TranspSkinned if unskinned shader instancing not supported
308 
312 
314  } Model;
315 
317 
319  IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats), textureManager(g_VFS, false, false)
320  {
321  }
322 
323  /**
324  * Load the OpenGL projection and modelview matrices and the viewport according
325  * to the given camera.
326  */
327  void SetOpenGLCamera(const CCamera& camera)
328  {
329  CMatrix3D view;
330  camera.m_Orientation.GetInverse(view);
331  const CMatrix3D& proj = camera.GetProjection();
332 
333 #if CONFIG2_GLES
334 #warning TODO: fix CRenderer camera handling for GLES (do not use global matrixes)
335 #else
336  glMatrixMode(GL_PROJECTION);
337  glLoadMatrixf(&proj._11);
338 
339  glMatrixMode(GL_MODELVIEW);
340  glLoadMatrixf(&view._11);
341 #endif
342 
343  const SViewPort &vp = camera.GetViewPort();
344  glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
345  }
346 
347  /**
348  * Renders all non-alpha-blended models with the given context.
349  */
350  void CallModelRenderers(const CShaderDefines& context, int flags)
351  {
352  CShaderDefines contextSkinned = context;
353  if (g_Renderer.m_Options.m_GPUSkinning)
354  {
355  contextSkinned.Add(str_USE_INSTANCING, str_1);
356  contextSkinned.Add(str_USE_GPU_SKINNING, str_1);
357  }
358  Model.NormalSkinned->Render(Model.ModShader, contextSkinned, flags);
359 
361  {
362  CShaderDefines contextUnskinned = context;
363  contextUnskinned.Add(str_USE_INSTANCING, str_1);
364  Model.NormalUnskinned->Render(Model.ModShader, contextUnskinned, flags);
365  }
366  }
367 
368  /**
369  * Renders all alpha-blended models with the given context.
370  */
371  void CallTranspModelRenderers(const CShaderDefines& context, int flags)
372  {
373  CShaderDefines contextSkinned = context;
374  if (g_Renderer.m_Options.m_GPUSkinning)
375  {
376  contextSkinned.Add(str_USE_INSTANCING, str_1);
377  contextSkinned.Add(str_USE_GPU_SKINNING, str_1);
378  }
379  Model.TranspSkinned->Render(Model.ModShader, contextSkinned, flags);
380 
382  {
383  CShaderDefines contextUnskinned = context;
384  contextUnskinned.Add(str_USE_INSTANCING, str_1);
385  Model.TranspUnskinned->Render(Model.ModShader, contextUnskinned, flags);
386  }
387  }
388 
389  /**
390  * Filters all non-alpha-blended models.
391  */
392  void FilterModels(CModelFilter& filter, int passed, int flags = 0)
393  {
394  Model.NormalSkinned->Filter(filter, passed, flags);
396  Model.NormalUnskinned->Filter(filter, passed, flags);
397  }
398 
399  /**
400  * Filters all alpha-blended models.
401  */
402  void FilterTranspModels(CModelFilter& filter, int passed, int flags = 0)
403  {
404  Model.TranspSkinned->Filter(filter, passed, flags);
406  Model.TranspUnskinned->Filter(filter, passed, flags);
407  }
408 };
409 
410 ///////////////////////////////////////////////////////////////////////////////////
411 // CRenderer constructor
413 {
414  m = new CRendererInternals;
417 
418  g_ProfileViewer.AddRootTable(&m->profileTable);
419 
420  m_Width = 0;
421  m_Height = 0;
424  m_ClearColor[0] = m_ClearColor[1] = m_ClearColor[2] = m_ClearColor[3] = 0;
425 
426  m_DisplayFrustum = false;
428  m_SkipSubmit = false;
429 
430  m_Options.m_NoVBO = false;
432  m_Options.m_Shadows = false;
435  m_Options.m_ShadowPCF = false;
436  m_Options.m_Particles = false;
437  m_Options.m_Silhouettes = false;
438  m_Options.m_PreferGLSL = false;
439  m_Options.m_ForceAlphaTest = false;
440  m_Options.m_GPUSkinning = false;
441  m_Options.m_GenTangents = false;
442  m_Options.m_SmoothLOS = false;
443  m_Options.m_Postproc = false;
444  m_Options.m_ShowSky = false;
445 
446  // TODO: be more consistent in use of the config system
447  CFG_GET_VAL("preferglsl", Bool, m_Options.m_PreferGLSL);
448  CFG_GET_VAL("forcealphatest", Bool, m_Options.m_ForceAlphaTest);
449  CFG_GET_VAL("gpuskinning", Bool, m_Options.m_GPUSkinning);
450  CFG_GET_VAL("gentangents", Bool, m_Options.m_GenTangents);
451  CFG_GET_VAL("smoothlos", Bool, m_Options.m_SmoothLOS);
452  CFG_GET_VAL("postproc", Bool, m_Options.m_Postproc);
453 
454  CStr skystring = "0 0 0";
455  CColor skycolor;
456  CFG_GET_VAL("skycolor", String, skystring);
457  if (skycolor.ParseString(skystring, 255.f))
458  SetClearColor(skycolor.AsSColor4ub());
459 
460 #if CONFIG2_GLES
461  // Override config option since GLES only supports GLSL
462  m_Options.m_PreferGLSL = true;
463 #endif
464 
465  m_ShadowZBias = 0.02f;
466  m_ShadowMapSize = 0;
467 
468  m_LightEnv = NULL;
469 
470  m_CurrentScene = NULL;
471 
473 
474  m_Stats.Reset();
475 
477 }
478 
479 ///////////////////////////////////////////////////////////////////////////////////
480 // CRenderer destructor
482 {
484 
485  // we no longer UnloadAlphaMaps / UnloadWaterTextures here -
486  // that is the responsibility of the module that asked for
487  // them to be loaded (i.e. CGameView).
488  delete m;
489 }
490 
491 
492 ///////////////////////////////////////////////////////////////////////////////////
493 // EnumCaps: build card cap bits
495 {
496  // assume support for nothing
497  m_Caps.m_VBO = false;
498  m_Caps.m_ARBProgram = false;
499  m_Caps.m_ARBProgramShadow = false;
500  m_Caps.m_VertexShader = false;
501  m_Caps.m_FragmentShader = false;
502  m_Caps.m_Shadows = false;
503 
504  // now start querying extensions
505  if (!m_Options.m_NoVBO) {
506  if (ogl_HaveExtension("GL_ARB_vertex_buffer_object")) {
507  m_Caps.m_VBO=true;
508  }
509  }
510 
511  if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL))
512  {
513  m_Caps.m_ARBProgram = true;
514  if (ogl_HaveExtension("GL_ARB_fragment_program_shadow"))
515  m_Caps.m_ARBProgramShadow = true;
516  }
517 
518  if (0 == ogl_HaveExtensions(0, "GL_ARB_shader_objects", "GL_ARB_shading_language_100", NULL))
519  {
520  if (ogl_HaveExtension("GL_ARB_vertex_shader"))
521  m_Caps.m_VertexShader = true;
522  if (ogl_HaveExtension("GL_ARB_fragment_shader"))
523  m_Caps.m_FragmentShader = true;
524  }
525 
526 #if CONFIG2_GLES
527  m_Caps.m_Shadows = true;
528 #else
529  if (0 == ogl_HaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", "GL_EXT_framebuffer_object", NULL))
530  {
531  if (ogl_max_tex_units >= 4)
532  m_Caps.m_Shadows = true;
533  }
534 #endif
535 }
536 
538 {
539  CShaderDefines defines;
540 
542  defines.Add(str_SYS_HAS_ARB, str_1);
543 
545  defines.Add(str_SYS_HAS_GLSL, str_1);
546 
548  defines.Add(str_SYS_PREFER_GLSL, str_1);
549 
550  m_SystemShaderDefines = defines;
551 }
552 
554 {
555  ENSURE(m->IsOpen);
556 
558 
560  {
561  m->globalContext.Add(str_USE_SHADOW, str_1);
563  m->globalContext.Add(str_USE_FP_SHADOW, str_1);
565  m->globalContext.Add(str_USE_SHADOW_PCF, str_1);
566 #if !CONFIG2_GLES
567  m->globalContext.Add(str_USE_SHADOW_SAMPLER, str_1);
568 #endif
569  }
570 
571  if (m_LightEnv)
572  m->globalContext.Add(CStrIntern("LIGHTING_MODEL_" + m_LightEnv->GetLightingModel()), str_1);
573 
575 
576  bool cpuLighting = (GetRenderPath() == RP_FIXED);
579 
580  if (GetRenderPath() == RP_SHADER && m_Options.m_GPUSkinning) // TODO: should check caps and GLSL etc too
581  {
585  }
586  else
587  {
591  }
592 
593  // Use instancing renderers in shader mode
594  if (GetRenderPath() == RP_SHADER)
595  {
598  }
599  else
600  {
603  }
604 
605  m->ShadersDirty = false;
606 }
607 
608 bool CRenderer::Open(int width, int height)
609 {
610  m->IsOpen = true;
611 
612  // Must query card capabilities before creating renderers that depend
613  // on card capabilities.
614  EnumCaps();
615 
616  // Dimensions
617  m_Width = width;
618  m_Height = height;
619 
620  // set packing parameters
621  glPixelStorei(GL_PACK_ALIGNMENT,1);
622  glPixelStorei(GL_UNPACK_ALIGNMENT,1);
623 
624  // setup default state
625  glDepthFunc(GL_LEQUAL);
626  glEnable(GL_DEPTH_TEST);
627  glCullFace(GL_BACK);
628  glFrontFace(GL_CCW);
629  glEnable(GL_CULL_FACE);
630 
631  GLint bits;
632  glGetIntegerv(GL_DEPTH_BITS,&bits);
633  LOGMESSAGE(L"CRenderer::Open: depth bits %d",bits);
634  glGetIntegerv(GL_STENCIL_BITS,&bits);
635  LOGMESSAGE(L"CRenderer::Open: stencil bits %d",bits);
636  glGetIntegerv(GL_ALPHA_BITS,&bits);
637  LOGMESSAGE(L"CRenderer::Open: alpha bits %d",bits);
638 
639  // Validate the currently selected render path
641 
643 
644  // Let component renderers perform one-time initialization after graphics capabilities and
645  // the shader path have been determined.
647 
648  if (m_Options.m_Postproc)
650 
651  return true;
652 }
653 
654 // resize renderer view
655 void CRenderer::Resize(int width,int height)
656 {
657  // need to recreate the shadow map object to resize the shadow texture
659 
660  m_Width = width;
661  m_Height = height;
662 
663  if (m_Options.m_Postproc)
665 }
666 
667 //////////////////////////////////////////////////////////////////////////////////////////
668 // SetOptionBool: set boolean renderer option
669 void CRenderer::SetOptionBool(enum Option opt,bool value)
670 {
671  switch (opt) {
672  case OPT_NOVBO:
673  m_Options.m_NoVBO = value;
674  break;
675  case OPT_SHADOWS:
676  m_Options.m_Shadows = value;
678  break;
679  case OPT_WATERNORMAL:
680  m_Options.m_WaterNormal = value;
681  break;
682  case OPT_WATERREALDEPTH:
683  m_Options.m_WaterRealDepth = value;
684  break;
685  case OPT_WATERFOAM:
686  m_Options.m_WaterFoam = value;
687  break;
690  break;
691  case OPT_WATERREFLECTION:
693  break;
694  case OPT_WATERREFRACTION:
696  break;
697  case OPT_WATERSHADOW:
698  m_Options.m_WaterShadow = value;
699  break;
700  case OPT_SHADOWPCF:
701  m_Options.m_ShadowPCF = value;
703  break;
704  case OPT_PARTICLES:
705  m_Options.m_Particles = value;
706  break;
707  case OPT_PREFERGLSL:
708  m_Options.m_PreferGLSL = value;
711  break;
712  case OPT_SILHOUETTES:
713  m_Options.m_Silhouettes = value;
714  break;
715  case OPT_SHOWSKY:
716  m_Options.m_ShowSky = value;
717  break;
718  default:
719  debug_warn(L"CRenderer::SetOptionBool: unknown option");
720  break;
721  }
722 }
723 
724 //////////////////////////////////////////////////////////////////////////////////////////
725 // GetOptionBool: get boolean renderer option
726 bool CRenderer::GetOptionBool(enum Option opt) const
727 {
728  switch (opt) {
729  case OPT_NOVBO:
730  return m_Options.m_NoVBO;
731  case OPT_SHADOWS:
732  return m_Options.m_Shadows;
733  case OPT_WATERNORMAL:
734  return m_Options.m_WaterNormal;
735  case OPT_WATERREALDEPTH:
737  case OPT_WATERFOAM:
738  return m_Options.m_WaterFoam;
741  case OPT_WATERREFLECTION:
743  case OPT_WATERREFRACTION:
745  case OPT_WATERSHADOW:
746  return m_Options.m_WaterShadow;
747  case OPT_SHADOWPCF:
748  return m_Options.m_ShadowPCF;
749  case OPT_PARTICLES:
750  return m_Options.m_Particles;
751  case OPT_PREFERGLSL:
752  return m_Options.m_PreferGLSL;
753  case OPT_SILHOUETTES:
754  return m_Options.m_Silhouettes;
755  case OPT_SHOWSKY:
756  return m_Options.m_ShowSky;
757  default:
758  debug_warn(L"CRenderer::GetOptionBool: unknown option");
759  break;
760  }
761 
762  return false;
763 }
764 
765 //////////////////////////////////////////////////////////////////////////////////////////
766 // SetRenderPath: Select the preferred render path.
767 // This may only be called before Open(), because the layout of vertex arrays and other
768 // data may depend on the chosen render path.
770 {
771  if (!m->IsOpen)
772  {
773  // Delay until Open() is called.
774  m_Options.m_RenderPath = rp;
775  return;
776  }
777 
778  // Renderer has been opened, so validate the selected renderpath
779  if (rp == RP_DEFAULT)
780  {
782  rp = RP_SHADER;
783  else
784  rp = RP_FIXED;
785  }
786 
787  if (rp == RP_SHADER)
788  {
790  {
791  LOGWARNING(L"Falling back to fixed function\n");
792  rp = RP_FIXED;
793  }
794  }
795 
796  m_Options.m_RenderPath = rp;
797 
800 
801  // We might need to regenerate some render data after changing path
802  if (g_Game)
804 }
805 
806 
808 {
809  switch(rp) {
810  case RP_DEFAULT: return "default";
811  case RP_FIXED: return "fixed";
812  case RP_SHADER: return "shader";
813  default: return "(invalid)";
814  }
815 }
816 
818 {
819  if (name == "fixed")
820  return RP_FIXED;
821  if (name == "shader")
822  return RP_SHADER;
823  if (name == "default")
824  return RP_DEFAULT;
825 
826  LOGWARNING(L"Unknown render path name '%hs', assuming 'default'", name.c_str());
827  return RP_DEFAULT;
828 }
829 
830 
831 //////////////////////////////////////////////////////////////////////////////////////////
832 // BeginFrame: signal frame start
834 {
835  PROFILE("begin frame");
836 
837  // zero out all the per-frame stats
838  m_Stats.Reset();
839 
840  // choose model renderers for this frame
841 
842  if (m->ShadersDirty)
843  ReloadShaders();
844 
845  m->Model.ModShader->SetShadowMap(&m->shadow);
846  m->Model.ModShader->SetLightEnv(m_LightEnv);
847 }
848 
849 //////////////////////////////////////////////////////////////////////////////////////////
851 {
852  // set current simulation context for terrain renderer
853  m->terrainRenderer.SetSimulation(simulation);
854 }
855 
856 // SetClearColor: set color used to clear screen in BeginFrame()
858 {
859  m_ClearColor[0] = float(color.R) / 255.0f;
860  m_ClearColor[1] = float(color.G) / 255.0f;
861  m_ClearColor[2] = float(color.B) / 255.0f;
862  m_ClearColor[3] = float(color.A) / 255.0f;
863 }
864 
866 {
867  PROFILE3_GPU("shadow map");
868 
869  m->shadow.BeginRender();
870 
871  {
872  PROFILE("render patches");
873  glCullFace(GL_FRONT);
874  glEnable(GL_CULL_FACE);
876  glCullFace(GL_BACK);
877  }
878 
879  CShaderDefines contextCast = context;
880  contextCast.Add(str_MODE_SHADOWCAST, str_1);
881 
882  {
883  PROFILE("render models");
885  }
886 
887  {
888  PROFILE("render transparent models");
889  // disable face-culling for two-sided models
890  glDisable(GL_CULL_FACE);
892  glEnable(GL_CULL_FACE);
893  }
894 
895  m->shadow.EndRender();
896 
898 }
899 
900 void CRenderer::RenderPatches(const CShaderDefines& context, const CFrustum* frustum)
901 {
902  PROFILE3_GPU("patches");
903 
904  bool filtered = false;
905  if (frustum)
906  {
907  if (!m->terrainRenderer.CullPatches(frustum))
908  return;
909 
910  filtered = true;
911  }
912 
913 #if CONFIG2_GLES
914 #warning TODO: implement wireface/edged rendering mode GLES
915 #else
916  // switch on wireframe if we need it
918  {
919  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
920  }
921 #endif
922 
923  // render all the patches, including blend pass
924  if (GetRenderPath() == RP_SHADER)
925  m->terrainRenderer.RenderTerrainShader(context, (m_Caps.m_Shadows && m_Options.m_Shadows) ? &m->shadow : 0, filtered);
926  else
927  m->terrainRenderer.RenderTerrain(filtered);
928 
929 
930 #if !CONFIG2_GLES
932  {
933  // switch wireframe off again
934  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
935  }
936  else if (m_TerrainRenderMode == EDGED_FACES)
937  {
938  // edged faces: need to make a second pass over the data:
939  // first switch on wireframe
940  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
941 
942  // setup some renderstate ..
943  pglActiveTextureARB(GL_TEXTURE0);
944  glDisable(GL_TEXTURE_2D);
945  glColor3f(0.5f, 0.5f, 1.0f);
946  glLineWidth(2.0f);
947 
948  // render tiles edges
949  m->terrainRenderer.RenderPatches(filtered);
950 
951  // set color for outline
952  glColor3f(0, 0, 1);
953  glLineWidth(4.0f);
954 
955  // render outline of each patch
956  m->terrainRenderer.RenderOutlines(filtered);
957 
958  // .. and restore the renderstates
959  glLineWidth(1.0f);
960  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
961  }
962 #endif
963 }
964 
966 {
967 public:
968  CModelCuller(const CFrustum& frustum) : m_Frustum(frustum) { }
969 
971  {
972  return m_Frustum.IsBoxVisible(CVector3D(0, 0, 0), model->GetWorldBoundsRec());
973  }
974 
975 private:
977 };
978 
979 void CRenderer::RenderModels(const CShaderDefines& context, const CFrustum* frustum)
980 {
981  PROFILE3_GPU("models");
982 
983  int flags = 0;
984  if (frustum)
985  {
986  flags = MODELFLAG_FILTERED;
987  CModelCuller culler(*frustum);
988  m->FilterModels(culler, flags);
989  }
990 
991 #if !CONFIG2_GLES
993  {
994  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
995  }
996 #endif
997 
998  m->CallModelRenderers(context, flags);
999 
1000 #if !CONFIG2_GLES
1002  {
1003  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1004  }
1005  else if (m_ModelRenderMode == EDGED_FACES)
1006  {
1007  CShaderDefines contextWireframe = context;
1008  contextWireframe.Add(str_MODE_WIREFRAME, str_1);
1009 
1010  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1011  glDisable(GL_TEXTURE_2D);
1012 
1013  m->CallModelRenderers(contextWireframe, flags);
1014 
1015  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1016  }
1017 #endif
1018 }
1019 
1020 void CRenderer::RenderTransparentModels(const CShaderDefines& context, ETransparentMode transparentMode, const CFrustum* frustum)
1021 {
1022  PROFILE3_GPU("transparent models");
1023 
1024  int flags = 0;
1025  if (frustum)
1026  {
1027  flags = MODELFLAG_FILTERED;
1028  CModelCuller culler(*frustum);
1029  m->FilterTranspModels(culler, flags);
1030  }
1031 
1032 #if !CONFIG2_GLES
1033  // switch on wireframe if we need it
1035  {
1036  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1037  }
1038 #endif
1039 
1040  // disable face culling for two-sided models in sub-renders
1041  if (flags)
1042  glDisable(GL_CULL_FACE);
1043 
1044  CShaderDefines contextOpaque = context;
1045  contextOpaque.Add(str_ALPHABLEND_PASS_OPAQUE, str_1);
1046 
1047  CShaderDefines contextBlend = context;
1048  contextBlend.Add(str_ALPHABLEND_PASS_BLEND, str_1);
1049 
1050  if (transparentMode == TRANSPARENT || transparentMode == TRANSPARENT_OPAQUE)
1051  m->CallTranspModelRenderers(contextOpaque, flags);
1052 
1053  if (transparentMode == TRANSPARENT || transparentMode == TRANSPARENT_BLEND)
1054  m->CallTranspModelRenderers(contextBlend, flags);
1055 
1056  if (flags)
1057  glEnable(GL_CULL_FACE);
1058 
1059 #if !CONFIG2_GLES
1061  {
1062  // switch wireframe off again
1063  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1064  }
1065  else if (m_ModelRenderMode == EDGED_FACES)
1066  {
1067  CShaderDefines contextWireframe = contextOpaque;
1068  contextWireframe.Add(str_MODE_WIREFRAME, str_1);
1069 
1070  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1071  glDisable(GL_TEXTURE_2D);
1072 
1073  m->CallTranspModelRenderers(contextWireframe, flags);
1074 
1075  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1076  }
1077 #endif
1078 }
1079 
1080 
1081 ///////////////////////////////////////////////////////////////////////////////////////////////////
1082 // SetObliqueFrustumClipping: change the near plane to the given clip plane (in world space)
1083 // Based on code from Game Programming Gems 5, from http://www.terathon.com/code/oblique.html
1084 // - worldPlane is a clip plane in world space (worldPlane.Dot(v) >= 0 for any vector v passing the clipping test)
1086 {
1087  // First, we'll convert the given clip plane to camera space, then we'll
1088  // Get the view matrix and normal matrix (top 3x3 part of view matrix)
1090  CVector4D camPlane = normalMatrix.Transform(worldPlane);
1091 
1093 
1094  // Calculate the clip-space corner point opposite the clipping plane
1095  // as (sgn(camPlane.x), sgn(camPlane.y), 1, 1) and
1096  // transform it into camera space by multiplying it
1097  // by the inverse of the projection matrix
1098 
1099  CVector4D q;
1100  q.X = (sgn(camPlane.X) - matrix[8]/matrix[11]) / matrix[0];
1101  q.Y = (sgn(camPlane.Y) - matrix[9]/matrix[11]) / matrix[5];
1102  q.Z = 1.0f/matrix[11];
1103  q.W = (1.0f - matrix[10]/matrix[11]) / matrix[14];
1104 
1105  // Calculate the scaled plane vector
1106  CVector4D c = camPlane * (2.0f * matrix[11] / camPlane.Dot(q));
1107 
1108  // Replace the third row of the projection matrix
1109  matrix[2] = c.X;
1110  matrix[6] = c.Y;
1111  matrix[10] = c.Z - matrix[11];
1112  matrix[14] = c.W;
1113 
1114  // Load it back into the camera
1115  m_ViewCamera.SetProjection(matrix);
1117 }
1118 
1119 ///////////////////////////////////////////////////////////////////////////////////////////////////
1120 // RenderReflections: render the water reflections to the reflection texture
1122 {
1123  PROFILE3_GPU("water reflections");
1124 
1125  WaterManager& wm = m->waterManager;
1126 
1127  // Remember old camera
1128  CCamera normalCamera = m_ViewCamera;
1129 
1130  // Temporarily change the camera to one that is reflected.
1131  // Also, for texturing purposes, make it render to a view port the size of the
1132  // water texture, stretch the image according to our aspect ratio so it covers
1133  // the whole screen despite being rendered into a square, and cover slightly more
1134  // of the view so we can see wavy reflections of slightly off-screen objects.
1135  m_ViewCamera.m_Orientation.Scale(1, -1, 1);
1137  m_ViewCamera.UpdateFrustum(scissor);
1139 
1140  SViewPort vp;
1143  vp.m_X = 0;
1144  vp.m_Y = 0;
1146  m_ViewCamera.SetProjection(normalCamera.GetNearPlane(), normalCamera.GetFarPlane(), normalCamera.GetFOV()*1.05f); // Slightly higher than view FOV
1147  CMatrix3D scaleMat;
1148  scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
1150 
1152 
1153  CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight);
1154  SetObliqueFrustumClipping(camPlane);
1155 
1156  // Save the model-view-projection matrix so the shaders can use it for projective texturing
1158 
1159  SScreenRect screenScissor;
1160  screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
1161  screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
1162  screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
1163  screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
1164 
1165  if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
1166  {
1167  glEnable(GL_SCISSOR_TEST);
1168  glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
1169 
1170  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1171 
1172  glFrontFace(GL_CW);
1173 
1174  // Render sky, terrain and models
1175  m->skyManager.RenderSky();
1176  ogl_WarnIfError();
1177  RenderPatches(context, &m_ViewCamera.GetFrustum());
1178  ogl_WarnIfError();
1179  RenderModels(context, &m_ViewCamera.GetFrustum());
1180  ogl_WarnIfError();
1182  ogl_WarnIfError();
1183 
1184  glFrontFace(GL_CCW);
1185 
1186  glDisable(GL_SCISSOR_TEST);
1187 
1188  // Copy the image to a texture
1189  pglActiveTextureARB(GL_TEXTURE0);
1190  glEnable(GL_TEXTURE_2D);
1191  glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture);
1192  glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
1193  screenScissor.x1, screenScissor.y1,
1194  screenScissor.x1, screenScissor.y1,
1195  screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
1196  }
1197 
1198  // Reset old camera
1199  m_ViewCamera = normalCamera;
1201 
1202  return screenScissor;
1203 }
1204 
1205 
1206 ///////////////////////////////////////////////////////////////////////////////////////////////////
1207 // RenderRefractions: render the water refractions to the refraction texture
1209 {
1210  PROFILE3_GPU("water refractions");
1211 
1212  WaterManager& wm = m->waterManager;
1213 
1214  // Remember old camera
1215  CCamera normalCamera = m_ViewCamera;
1216 
1217  // Temporarily change the camera to make it render to a view port the size of the
1218  // water texture, stretch the image according to our aspect ratio so it covers
1219  // the whole screen despite being rendered into a square, and cover slightly more
1220  // of the view so we can see wavy refractions of slightly off-screen objects.
1221  m_ViewCamera.UpdateFrustum(scissor);
1223 
1224  SViewPort vp;
1227  vp.m_X = 0;
1228  vp.m_Y = 0;
1230  m_ViewCamera.SetProjection(normalCamera.GetNearPlane(), normalCamera.GetFarPlane(), normalCamera.GetFOV()*1.05f); // Slightly higher than view FOV
1231  CMatrix3D scaleMat;
1232  scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f);
1234 
1236 
1237  CVector4D camPlane(0, -1, 0, wm.m_WaterHeight);
1238  SetObliqueFrustumClipping(camPlane);
1239 
1240  // Save the model-view-projection matrix so the shaders can use it for projective texturing
1242 
1243  SScreenRect screenScissor;
1244  screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width);
1245  screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height);
1246  screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width);
1247  screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height);
1248  if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2)
1249  {
1250  glEnable(GL_SCISSOR_TEST);
1251  glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
1252 
1253  glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // a neutral gray to blend in with shores
1254  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1255 
1256  // Render terrain and models
1257  RenderPatches(context, &m_ViewCamera.GetFrustum());
1258  ogl_WarnIfError();
1259  RenderModels(context, &m_ViewCamera.GetFrustum());
1260  ogl_WarnIfError();
1262  ogl_WarnIfError();
1263 
1264  glDisable(GL_SCISSOR_TEST);
1265 
1266  // Copy the image to a texture
1267  pglActiveTextureARB(GL_TEXTURE0);
1268  glEnable(GL_TEXTURE_2D);
1269  glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture);
1270  glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
1271  screenScissor.x1, screenScissor.y1,
1272  screenScissor.x1, screenScissor.y1,
1273  screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1);
1274  }
1275 
1276  // Reset old camera
1277  m_ViewCamera = normalCamera;
1279 
1280  return screenScissor;
1281 }
1282 
1283 
1285 {
1286  PROFILE3_GPU("silhouettes");
1287 
1288  CShaderDefines contextOccluder = context;
1289  contextOccluder.Add(str_MODE_SILHOUETTEOCCLUDER, str_1);
1290 
1291  CShaderDefines contextDisplay = context;
1292  contextDisplay.Add(str_MODE_SILHOUETTEDISPLAY, str_1);
1293 
1294  // Render silhouettes of units hidden behind terrain or occluders.
1295  // To avoid breaking the standard rendering of alpha-blended objects, this
1296  // has to be done in a separate pass.
1297  // First we render all occluders into depth, then render all units with
1298  // inverted depth test so any behind an occluder will get drawn in a constant
1299  // colour.
1300 
1301  float silhouetteAlpha = 0.75f;
1302 
1303  // Silhouette blending requires an almost-universally-supported extension;
1304  // fall back to non-blended if unavailable
1305  if (!ogl_HaveExtension("GL_EXT_blend_color"))
1306  silhouetteAlpha = 1.f;
1307 
1308  glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1309 
1310  glColorMask(0, 0, 0, 0);
1311 
1312  // Render occluders:
1313 
1314  {
1315  PROFILE("render patches");
1316 
1317  // To prevent units displaying silhouettes when parts of their model
1318  // protrude into the ground, only occlude with the back faces of the
1319  // terrain (so silhouettes will still display when behind hills)
1320  glCullFace(GL_FRONT);
1322  glCullFace(GL_BACK);
1323  }
1324 
1325  {
1326  PROFILE("render model occluders");
1328  }
1329 
1330  {
1331  PROFILE("render transparent occluders");
1333  }
1334 
1335  glDepthFunc(GL_GEQUAL);
1336  glColorMask(1, 1, 1, 1);
1337 
1338  // Render more efficiently if alpha == 1
1339  if (silhouetteAlpha == 1.f)
1340  {
1341  // Ideally we'd render objects back-to-front so nearer silhouettes would
1342  // appear on top, but sorting has non-zero cost. So we'll keep the depth
1343  // write enabled, to do the opposite - far objects will consistently appear
1344  // on top.
1345  glDepthMask(0);
1346  }
1347  else
1348  {
1349  // Since we can't sort, we'll use the stencil buffer to ensure we only draw
1350  // a pixel once (using the colour of whatever model happens to be drawn first).
1351  glEnable(GL_BLEND);
1352  glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
1353  pglBlendColorEXT(0, 0, 0, silhouetteAlpha);
1354 
1355  glEnable(GL_STENCIL_TEST);
1356  glStencilFunc(GL_NOTEQUAL, 1, (GLuint)-1);
1357  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1358  }
1359 
1360  // TODO: For performance, we probably ought to do a quick raycasting check
1361  // to see which units are likely blocked by occluders and not bother
1362  // rendering any of the others
1363 
1364  {
1365  PROFILE("render models");
1367  // (This won't render transparent objects with SILHOUETTE_DISPLAY - will
1368  // we have any units that need that?)
1369  }
1370 
1371  // Restore state
1372  glDepthFunc(GL_LEQUAL);
1373  if (silhouetteAlpha == 1.f)
1374  {
1375  glDepthMask(1);
1376  }
1377  else
1378  {
1379  glDisable(GL_BLEND);
1380  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1381  pglBlendColorEXT(0, 0, 0, 0);
1382  glDisable(GL_STENCIL_TEST);
1383  }
1384 }
1385 
1387 {
1388  // Only supported in shader modes
1389  if (GetRenderPath() != RP_SHADER)
1390  return;
1391 
1392  PROFILE3_GPU("particles");
1393 
1395 
1396 #if !CONFIG2_GLES
1398  {
1399  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1400 
1401  glDisable(GL_TEXTURE_2D);
1402  glColor3f(0.0f, 0.5f, 0.0f);
1403 
1405 
1406  CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid);
1407  shaderTech->BeginPass();
1408  CShaderProgramPtr shader = shaderTech->GetShader();
1409  shader->Uniform(str_color, 0.0f, 1.0f, 0.0f, 1.0f);
1410  shader->Uniform(str_transform, m_ViewCamera.GetViewProjection());
1411 
1412  m->particleRenderer.RenderBounds(shader);
1413 
1414  shaderTech->EndPass();
1415 
1416  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1417  }
1418 #endif
1419 }
1420 
1421 ///////////////////////////////////////////////////////////////////////////////////////////////////
1422 // RenderSubmissions: force rendering of any batched objects
1424 {
1425  PROFILE3("render submissions");
1426 
1428 
1429  if (m_Options.m_Postproc)
1431 
1432  CShaderDefines context = m->globalContext;
1433 
1434  ogl_WarnIfError();
1435 
1436  // Set the camera
1438 
1439  // Prepare model renderers
1440  {
1441  PROFILE3("prepare models");
1442  m->Model.NormalSkinned->PrepareModels();
1443  m->Model.TranspSkinned->PrepareModels();
1445  m->Model.NormalUnskinned->PrepareModels();
1447  m->Model.TranspUnskinned->PrepareModels();
1448  }
1449 
1451 
1453 
1455 
1457  {
1458  RenderShadowMap(context);
1459  }
1460 
1461  {
1462  PROFILE3_GPU("clear buffers");
1463  glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);
1464  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1465  }
1466 
1467  ogl_WarnIfError();
1468 
1469  CBoundingBoxAligned waterScissor;
1471  {
1473  if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater())
1474  {
1475  PROFILE3_GPU("water scissor");
1476  SScreenRect dirty = { 0, 0, 0, 0 };
1478  {
1479  SScreenRect reflectionScissor = RenderReflections(context, waterScissor);
1480  SScreenRect refractionScissor = RenderRefractions(context, waterScissor);
1481  dirty.x1 = std::min(reflectionScissor.x1, refractionScissor.x1);
1482  dirty.y1 = std::min(reflectionScissor.y1, refractionScissor.y1);
1483  dirty.x2 = std::max(reflectionScissor.x2, refractionScissor.x2);
1484  dirty.y2 = std::max(reflectionScissor.y2, refractionScissor.y2);
1485  }
1486  else if (m_Options.m_WaterRefraction)
1487  {
1488  SScreenRect refractionScissor = RenderRefractions(context, waterScissor);
1489  dirty.x1 = refractionScissor.x1;
1490  dirty.y1 = refractionScissor.y1;
1491  dirty.x2 = refractionScissor.x2;
1492  dirty.y2 = refractionScissor.y2;
1493  }
1494  else if (m_Options.m_WaterReflection)
1495  {
1496  SScreenRect reflectionScissor = RenderReflections(context, waterScissor);
1497  dirty.x1 = reflectionScissor.x1;
1498  dirty.y1 = reflectionScissor.y1;
1499  dirty.x2 = reflectionScissor.x2;
1500  dirty.y2 = reflectionScissor.y2;
1501  }
1502  if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2)
1503  {
1504  glEnable(GL_SCISSOR_TEST);
1505  glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1);
1506  glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]);
1507  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1508  glDisable(GL_SCISSOR_TEST);
1509  }
1510  }
1511  }
1512 
1513  if (m_Options.m_ShowSky)
1514  {
1515  m->skyManager.RenderSky();
1516  }
1517 
1518  // render submitted patches and models
1519  RenderPatches(context);
1520  ogl_WarnIfError();
1521 
1522  // render debug-related terrain overlays
1524  ogl_WarnIfError();
1525 
1526  // render other debug-related overlays before water (so they can be seen when underwater)
1528  ogl_WarnIfError();
1529 
1530  RenderModels(context);
1531  ogl_WarnIfError();
1532 
1533  // render water
1534  if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0)
1535  {
1536  // render transparent stuff, but only the solid parts that can occlude block water
1538  ogl_WarnIfError();
1539 
1540  m->terrainRenderer.RenderWater(context, &m->shadow);
1541  ogl_WarnIfError();
1542 
1543  // render transparent stuff again, but only the blended parts that overlap water
1545  ogl_WarnIfError();
1546  }
1547  else
1548  {
1549  // render transparent stuff, so it can overlap models/terrain
1551  ogl_WarnIfError();
1552  }
1553 
1554  // render debug-related terrain overlays
1556  ogl_WarnIfError();
1557 
1558  // render some other overlays after water (so they can be displayed on top of water)
1560  ogl_WarnIfError();
1561 
1562  // particles are transparent so render after water
1563  if (m_Options.m_Particles)
1564  {
1565  RenderParticles();
1566  ogl_WarnIfError();
1567  }
1568 
1569  if (m_Options.m_Postproc)
1570  {
1573  }
1574 
1576  {
1577  RenderSilhouettes(context);
1578  }
1579 
1580 #if !CONFIG2_GLES
1581  // Clean up texture blend mode so particles and other things render OK
1582  // (really this should be cleaned up by whoever set it)
1583  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1584 #endif
1585 
1586  // render debug lines
1587  if (m_DisplayFrustum)
1588  {
1589  DisplayFrustum();
1592  ogl_WarnIfError();
1593  }
1594 
1595  // render overlays that should appear on top of all other objects
1597  ogl_WarnIfError();
1598 
1599 }
1600 
1601 ///////////////////////////////////////////////////////////////////////////////////////////////////
1602 // EndFrame: signal frame end
1604 {
1605  PROFILE3("end frame");
1606 
1607  // empty lists
1611 
1612  // Finish model renderers
1613  m->Model.NormalSkinned->EndFrame();
1614  m->Model.TranspSkinned->EndFrame();
1616  m->Model.NormalUnskinned->EndFrame();
1618  m->Model.TranspUnskinned->EndFrame();
1619 
1620  ogl_tex_bind(0, 0);
1621 
1622  {
1623  PROFILE3("error check");
1624  if (glGetError())
1625  {
1626  ONCE(LOGERROR(L"CRenderer::EndFrame: GL errors occurred"));
1627  }
1628  }
1629 }
1630 
1631 
1632 ///////////////////////////////////////////////////////////////////////////////////////////////////
1633 // DisplayFrustum: debug displays
1634 // - white: cull camera frustum
1635 // - red: bounds of shadow casting objects
1637 {
1638 #if CONFIG2_GLES
1639 #warning TODO: implement CRenderer::DisplayFrustum for GLES
1640 #else
1641  glDepthMask(0);
1642  glDisable(GL_CULL_FACE);
1643  glDisable(GL_TEXTURE_2D);
1644 
1645  glEnable(GL_BLEND);
1646  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1647  glColor4ub(255,255,255,64);
1648  m_CullCamera.Render(2);
1649  glDisable(GL_BLEND);
1650 
1651  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1652  glColor3ub(255,255,255);
1653  m_CullCamera.Render(2);
1654  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1655 
1656  glEnable(GL_CULL_FACE);
1657  glDepthMask(1);
1658 #endif
1659 }
1660 
1661 ///////////////////////////////////////////////////////////////////////////////////////////////////
1662 // Text overlay rendering
1664 {
1665  PROFILE3_GPU("text overlays");
1666 
1669 
1670  ogl_WarnIfError();
1671 }
1672 
1673 ///////////////////////////////////////////////////////////////////////////////////////////////////
1674 // SetSceneCamera: setup projection and transform of camera and adjust viewport to current view
1675 // The camera always represents the actual camera used to render a scene, not any virtual camera
1676 // used for shadow rendering or reflections.
1677 void CRenderer::SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera)
1678 {
1679  m_ViewCamera = viewCamera;
1680  m_CullCamera = cullCamera;
1681 
1684 }
1685 
1686 
1688 {
1689  glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
1690 }
1691 
1693 {
1694  m->terrainRenderer.Submit(patch);
1695 }
1696 
1698 {
1699  m->overlayRenderer.Submit(overlay);
1700 }
1701 
1703 {
1704  m->overlayRenderer.Submit(overlay);
1705 }
1706 
1708 {
1709  m->overlayRenderer.Submit(overlay);
1710 }
1711 
1713 {
1714  m->overlayRenderer.Submit(overlay);
1715 }
1716 
1718 {
1719  m->terrainRenderer.Submit(decal);
1720 }
1721 
1723 {
1724  m->particleRenderer.Submit(emitter);
1725 }
1726 
1728 {
1729  if (model->GetFlags() & MODELFLAG_CASTSHADOWS)
1730  {
1732  }
1733 
1734  // Tricky: The call to GetWorldBounds() above can invalidate the position
1735  model->ValidatePosition();
1736 
1737  bool requiresSkinning = (model->GetModelDef()->GetNumBones() != 0);
1738 
1739  if (model->GetMaterial().UsesAlphaBlending())
1740  {
1741  if (requiresSkinning)
1742  m->Model.TranspSkinned->Submit(model);
1743  else
1744  m->Model.TranspUnskinned->Submit(model);
1745  }
1746  else
1747  {
1748  if (requiresSkinning)
1749  m->Model.NormalSkinned->Submit(model);
1750  else
1751  m->Model.NormalUnskinned->Submit(model);
1752  }
1753 }
1754 
1755 
1756 ///////////////////////////////////////////////////////////
1757 // Render the given scene
1759 {
1760  m_CurrentScene = &scene;
1761 
1762  CFrustum frustum = m_CullCamera.GetFrustum();
1763 
1764  scene.EnumerateObjects(frustum, this);
1765 
1766  m->particleManager.RenderSubmit(*this, frustum);
1767 
1768  ogl_WarnIfError();
1769 
1771 
1772  m_CurrentScene = NULL;
1773 }
1774 
1776 {
1778  return *m_CurrentScene;
1779 }
1780 
1781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1782 // BindTexture: bind a GL texture object to current active unit
1783 void CRenderer::BindTexture(int unit, GLuint tex)
1784 {
1785  pglActiveTextureARB(GL_TEXTURE0+unit);
1786 
1787  glBindTexture(GL_TEXTURE_2D, tex);
1788 #if !CONFIG2_GLES
1789  if (tex) {
1790  glEnable(GL_TEXTURE_2D);
1791  } else {
1792  glDisable(GL_TEXTURE_2D);
1793  }
1794 #endif
1795 }
1796 
1797 ///////////////////////////////////////////////////////////////////////////////////////////////////
1798 // LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and
1799 // calculate the coordinate of each alphamap within this packed texture
1800 // NB: A variant of this function is duplicated in TerrainTextureEntry.cpp, for use with the Shader
1801 // renderpath. This copy is kept to load the 'standard' maps for the fixed pipeline and should
1802 // be removed if/when the fixed pipeline goes.
1804 {
1805  const wchar_t* const key = L"(alpha map composite)";
1806  Handle ht = ogl_tex_find(key);
1807  // alpha map texture had already been created and is still in memory:
1808  // reuse it, do not load again.
1809  if(ht > 0)
1810  {
1811  m_hCompositeAlphaMap = ht;
1812  return 0;
1813  }
1814 
1815  //
1816  // load all textures and store Handle in array
1817  //
1818  Handle textures[NumAlphaMaps] = {0};
1819  VfsPath path(L"art/textures/terrain/alphamaps/standard");
1820  const wchar_t* fnames[NumAlphaMaps] = {
1821  L"blendcircle.png",
1822  L"blendlshape.png",
1823  L"blendedge.png",
1824  L"blendedgecorner.png",
1825  L"blendedgetwocorners.png",
1826  L"blendfourcorners.png",
1827  L"blendtwooppositecorners.png",
1828  L"blendlshapecorner.png",
1829  L"blendtwocorners.png",
1830  L"blendcorner.png",
1831  L"blendtwoedges.png",
1832  L"blendthreecorners.png",
1833  L"blendushape.png",
1834  L"blendbad.png"
1835  };
1836  size_t base = 0; // texture width/height (see below)
1837  // for convenience, we require all alpha maps to be of the same BPP
1838  // (avoids another ogl_tex_get_size call, and doesn't hurt)
1839  size_t bpp = 0;
1840  for(size_t i=0;i<NumAlphaMaps;i++)
1841  {
1842  // note: these individual textures can be discarded afterwards;
1843  // we cache the composite.
1844  textures[i] = ogl_tex_load(g_VFS, path / fnames[i]);
1845  RETURN_STATUS_IF_ERR(textures[i]);
1846 
1847  // get its size and make sure they are all equal.
1848  // (the packing algo assumes this)
1849  size_t this_width = 0, this_height = 0, this_bpp = 0; // fail-safe
1850  (void)ogl_tex_get_size(textures[i], &this_width, &this_height, &this_bpp);
1851  if(this_width != this_height)
1852  DEBUG_DISPLAY_ERROR(L"Alpha maps are not square");
1853  // .. first iteration: establish size
1854  if(i == 0)
1855  {
1856  base = this_width;
1857  bpp = this_bpp;
1858  }
1859  // .. not first: make sure texture size matches
1860  else if(base != this_width || bpp != this_bpp)
1861  DEBUG_DISPLAY_ERROR(L"Alpha maps are not identically sized (including pixel depth)");
1862  }
1863 
1864  //
1865  // copy each alpha map (tile) into one buffer, arrayed horizontally.
1866  //
1867  size_t tile_w = 2+base+2; // 2 pixel border (avoids bilinear filtering artifacts)
1868  size_t total_w = round_up_to_pow2(tile_w * NumAlphaMaps);
1869  size_t total_h = base; ENSURE(is_pow2(total_h));
1870  shared_ptr<u8> data;
1871  AllocateAligned(data, total_w*total_h, maxSectorSize);
1872  // for each tile on row
1873  for (size_t i = 0; i < NumAlphaMaps; i++)
1874  {
1875  // get src of copy
1876  u8* src = 0;
1877  (void)ogl_tex_get_data(textures[i], &src);
1878 
1879  size_t srcstep = bpp/8;
1880 
1881  // get destination of copy
1882  u8* dst = data.get() + (i*tile_w);
1883 
1884  // for each row of image
1885  for (size_t j = 0; j < base; j++)
1886  {
1887  // duplicate first pixel
1888  *dst++ = *src;
1889  *dst++ = *src;
1890 
1891  // copy a row
1892  for (size_t k = 0; k < base; k++)
1893  {
1894  *dst++ = *src;
1895  src += srcstep;
1896  }
1897 
1898  // duplicate last pixel
1899  *dst++ = *(src-srcstep);
1900  *dst++ = *(src-srcstep);
1901 
1902  // advance write pointer for next row
1903  dst += total_w-tile_w;
1904  }
1905 
1906  m_AlphaMapCoords[i].u0 = float(i*tile_w+2) / float(total_w);
1907  m_AlphaMapCoords[i].u1 = float((i+1)*tile_w-2) / float(total_w);
1908  m_AlphaMapCoords[i].v0 = 0.0f;
1909  m_AlphaMapCoords[i].v1 = 1.0f;
1910  }
1911 
1912  for (size_t i = 0; i < NumAlphaMaps; i++)
1913  (void)ogl_tex_free(textures[i]);
1914 
1915  // upload the composite texture
1916  Tex t;
1917  (void)tex_wrap(total_w, total_h, 8, TEX_GREY, data, 0, &t);
1918 
1919  /*VfsPath filename("blendtex.png");
1920 
1921  DynArray da;
1922  RETURN_STATUS_IF_ERR(tex_encode(&t, filename.Extension(), &da));
1923 
1924  // write to disk
1925  //Status ret = INFO::OK;
1926  {
1927  shared_ptr<u8> file = DummySharedPtr(da.base);
1928  const ssize_t bytes_written = g_VFS->CreateFile(filename, file, da.pos);
1929  if(bytes_written > 0)
1930  ENSURE(bytes_written == (ssize_t)da.pos);
1931  //else
1932  // ret = (Status)bytes_written;
1933  }
1934 
1935  (void)da_free(&da);*/
1936 
1938  (void)ogl_tex_set_filter(m_hCompositeAlphaMap, GL_LINEAR);
1939  (void)ogl_tex_set_wrap (m_hCompositeAlphaMap, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
1940  int ret = ogl_tex_upload(m_hCompositeAlphaMap, GL_ALPHA, 0, 0);
1941 
1942  return ret;
1943 }
1944 
1945 ///////////////////////////////////////////////////////////////////////////////////////////////////
1946 // UnloadAlphaMaps: frees the resources allocates by LoadAlphaMaps
1948 {
1951 }
1952 
1953 
1954 
1956 {
1957  CRenderer* renderer = static_cast<CRenderer*>(param);
1958 
1959  // If an alpha map changed, and we already loaded them, then reload them
1960  if (boost::algorithm::starts_with(path.string(), L"art/textures/terrain/alphamaps/"))
1961  {
1962  if (renderer->m_hCompositeAlphaMap)
1963  {
1964  renderer->UnloadAlphaMaps();
1965  renderer->LoadAlphaMaps();
1966  }
1967  }
1968 
1969  return INFO::OK;
1970 }
1971 
1973 {
1974  m->ShadersDirty = true;
1975 }
1976 
1978 {
1979  return m->textureManager;
1980 }
1981 
1983 {
1984  return m->shaderManager;
1985 }
1986 
1988 {
1989  return m->particleManager;
1990 }
1991 
1993 {
1994  return m->terrainRenderer;
1995 }
1996 
1998 {
1999  return m->timeManager;
2000 }
2001 
2003 {
2004  return m->materialManager;
2005 }
2006 
2008 {
2009  return m->postprocManager;
2010 }
CParticleManager particleManager
Particle manager.
Definition: Renderer.cpp:267
void SetOpenGLCamera(const CCamera &camera)
Load the OpenGL projection and modelview matrices and the viewport according to the given camera...
Definition: Renderer.cpp:327
void RenderSky()
RenderSky: Render the sky.
Definition: SkyManager.cpp:220
bool m_ARBProgram
Definition: Renderer.h:158
void Translate(float x, float y, float z)
Definition: Matrix3D.cpp:172
GLint y2
Definition: Renderer.h:65
void Add(CStrIntern name, CStrIntern value)
Add a name and associated value to the map of defines.
#define u8
Definition: types.h:39
Handle ogl_tex_find(const VfsPath &pathname)
Find and return an existing texture object, if it has already been loaded and is still in memory...
Definition: ogl_tex.cpp:551
void CallModelRenderers(const CShaderDefines &context, int flags)
Renders all non-alpha-blended models with the given context.
Definition: Renderer.cpp:350
ERenderMode m_TerrainRenderMode
Definition: Renderer.h:390
void SetObliqueFrustumClipping(const CVector4D &clipPlane)
Definition: Renderer.cpp:1085
WaterManager waterManager
Water manager.
Definition: Renderer.cpp:252
void ReloadShaders()
Definition: Renderer.cpp:553
ModelRendererPtr TranspUnskinned
Definition: Renderer.cpp:307
const CVector3D & GetSunDir() const
Definition: LightEnv.h:84
Definition: Decompose.h:22
u8 G
Definition: SColor.h:33
void SetClearColor(SColor4ub color)
Definition: Renderer.cpp:857
Class CRendererStatsTable: Implementation of AbstractProfileTable to display the renderer stats in-ga...
Definition: Renderer.cpp:84
bool m_ARBProgramShadow
Definition: Renderer.h:143
void RenderOutlines(bool filtered=false)
RenderOutlines: Render the outline of patches as lines.
void RenderWater(const CShaderDefines &context, ShadowMap *shadow)
RenderWater: Render water for all patches that have been submitted this frame.
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
int m_Height
Definition: Renderer.h:388
Line-based overlay, with world-space coordinates, rendered in the world potentially behind other obje...
Definition: Overlay.h:36
void MakeDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1, int dirtyFlags)
Definition: Terrain.cpp:598
void RenderBounds(CShaderProgramPtr &shader)
Render bounding boxes for all the submitted emitters.
CStr GetTitle()
GetTitle: Longer, explanatory text (can be dynamic).
Definition: Renderer.cpp:136
CTimeManager & GetTimeManager()
Definition: Renderer.cpp:1997
Particle emitter.
void PrepareForRendering()
PrepareForRendering: Prepare internal data structures like vertex buffers for rendering.
ModelRendererPtr TranspSkinned
Definition: Renderer.cpp:306
Definition: Decompose.h:22
const Status OK
Definition: status.h:386
#define LOGERROR
Definition: CLogger.h:35
bool UsesAlphaBlending()
Definition: Material.h:48
void SetupFrame(const CCamera &camera, const CVector3D &lightdir)
SetupFrame: Configure light space for the given camera and light direction, create the shadow texture...
Definition: ShadowMap.cpp:153
virtual const CBoundingBoxAligned GetWorldBoundsRec()
Returns world space bounds of this object and all child objects.
Definition: Model.cpp:195
void RenderParticles(bool solidColor=false)
Render all the submitted particles.
CRendererStatsTable(const CRenderer::Stats &st)
Definition: Renderer.cpp:123
Handle ogl_tex_wrap(Tex *t, const PIVFS &vfs, const VfsPath &pathname, size_t flags)
Make the Tex object ready for use as an OpenGL texture and return a handle to it. ...
Definition: ogl_tex.cpp:570
Definition: Overlay.h:34
Status ogl_tex_free(Handle &ht)
Release this texture reference.
Definition: ogl_tex.cpp:586
void AddShadowedBound(const CBoundingBoxAligned &bounds)
AddShadowedBound: Add the bounding box of an object that has to be shadowed.
Definition: ShadowMap.cpp:213
Class AbstractProfileTable: Profile table data model.
Definition: ProfileViewer.h:60
size_t m_RefractionTextureSize
Definition: WaterManager.h:108
CVertexBufferManager g_VBMan
friend class InstancingModelRenderer
Definition: Renderer.h:334
Class OverlayRenderer: Render various bits of data that overlay the game world (selection circles...
void FilterModels(CModelFilter &filter, int passed, int flags=0)
Filters all non-alpha-blended models.
Definition: Renderer.cpp:392
bool Filter(CModel *model)
Definition: Renderer.cpp:970
ShadowMap shadow
Shadow map.
Definition: Renderer.cpp:279
static const uintptr_t maxSectorSize
Definition: alignment.h:82
void Resize(int width, int height)
Definition: Renderer.cpp:655
static void RenderOverlaysBeforeWater()
Draw all ITerrainOverlay objects that exist and that should be drawn before water.
int m_Y
Definition: Camera.h:34
#define CFG_GET_VAL(name, type, destination)
Definition: ConfigDB.h:147
#define LOGMESSAGE
Definition: CLogger.h:32
const std::string & GetLightingModel() const
Definition: LightEnv.h:85
void EnumCaps()
Definition: Renderer.cpp:494
size_t GetNumberRows()
GetNumberRows.
Definition: Renderer.cpp:141
static void RenderOverlaysAfterWater()
Draw all ITerrainOverlay objects that exist and that should be drawn after water. ...
float GetVolume() const
void EndFrame()
Reset the list of submitted overlays.
static RenderPath GetRenderPathByName(const CStr &name)
Definition: Renderer.cpp:817
bool ShadersDirty
true if shaders need to be reloaded
Definition: Renderer.cpp:243
indicates the image is 8bpp greyscale.
Definition: tex.h:178
void RenderTerrainShader(const CShaderDefines &context, ShadowMap *shadow, bool filtered=false)
Render textured terrain, as with RenderTerrain, but using shaders instead of multitexturing.
const CFrustum & GetFrustum() const
Definition: Camera.h:62
bool IsBoxVisible(const CVector3D &position, const CBoundingBoxAligned &bounds) const
Definition: Frustum.cpp:116
CVector3D Transform(const CVector3D &vector) const
Definition: Matrix3D.h:272
size_t m_ReflectionTextureSize
Definition: WaterManager.h:107
const std::vector< ProfileColumn > & GetColumns()
GetColumnDescriptions.
Definition: Renderer.cpp:146
Definition: Renderer.h:55
shared_ptr< CShaderTechnique > CShaderTechniquePtr
CMatrix3D GetTranspose() const
Definition: Matrix3D.cpp:230
CStr GetName()
GetName: Short descriptive name of this table (should be static).
Definition: Renderer.cpp:131
Billboard sprite overlay, with world-space coordinates, rendered on top of all other objects...
Definition: Overlay.h:137
CCamera m_CullCamera
m_CullCamera: determines the frustum for culling and shadowmap calculations
Definition: Renderer.h:408
void RecomputeSystemShaderDefines()
Definition: Renderer.cpp:537
Implementation of ModelRenderer that loads the appropriate shaders for rendering each model...
void SetSceneCamera(const CCamera &viewCamera, const CCamera &cullCamera)
Set up the camera used for rendering the next scene; this includes setting OpenGL state like viewport...
Definition: Renderer.cpp:1677
#define RENDERDATA_UPDATE_COLOR
CModelCuller(const CFrustum &frustum)
Definition: Renderer.cpp:968
bool m_ARBProgramShadow
Definition: Renderer.h:159
void SetViewport(const SViewPort &)
Definition: Renderer.cpp:1687
GLuint m_RefractionTexture
Definition: WaterManager.h:106
void RenderTerrain(bool filtered=false)
RenderTerrain: Render textured terrain (including blends between different terrain types)...
Class ShadowMap: Maintain the shadow map texture and perform necessary OpenGL setup, including matrix calculations.
Definition: ShadowMap.h:39
ModelVertexRendererPtr VertexGPUSkinningShader
Definition: Renderer.cpp:311
virtual CLOSTexture & GetLOSTexture()=0
Return the LOS texture to be used for rendering this scene.
float _11
Definition: Matrix3D.h:42
u8 B
Definition: SColor.h:34
int m_Height
Definition: Camera.h:36
CMaterialManager materialManager
Material manager.
Definition: Renderer.cpp:273
float m_WaterHeight
Definition: WaterManager.h:91
CShaderDefines m_SystemShaderDefines
Definition: Renderer.h:394
void Submit(SOverlayLine *overlay)
Add a line overlay for rendering in this frame.
int sprintf_s(char *buf, size_t max_chars, const char *fmt,...) PRINTF_ARGS(3)
float Y
Definition: Vector4D.h:128
void RenderTransparentModels(const CShaderDefines &context, ETransparentMode transparentMode, const CFrustum *frustum=0)
Definition: Renderer.cpp:1020
CMatrix3D m_ReflectionMatrix
Definition: WaterManager.h:112
bool m_DisplayTerrainPriorities
Enable rendering of terrain tile priority text overlay, for debugging.
Definition: Renderer.h:452
bool ParseString(const CStr8 &Value, float DefaultAlpha)
Definition: Overlay.cpp:30
Public API for simulation system.
Definition: Simulation2.h:46
static CStr GetRenderPathName(RenderPath rp)
Definition: Renderer.cpp:807
SColor4ub AsSColor4ub() const
Definition: Overlay.h:52
#define g_Renderer
Definition: Renderer.h:61
ModelRendererPtr NormalSkinned
Definition: Renderer.cpp:304
AbstractProfileTable * GetChild(size_t row)
GetChild: Return a row&#39;s child table if the child is expandable.
Definition: Renderer.cpp:222
CCamera m_ViewCamera
m_ViewCamera: determines the eye position for rendering
Definition: Renderer.h:401
void EndFrame()
Reset the list of submitted overlays.
GLint y1
Definition: Renderer.h:65
SkyManager * m_SkyManager
m_SkyManager: the SkyManager object used for sky textures and settings
Definition: Renderer.h:439
CRendererInternals * m
Private data that is not needed by inline functions.
Definition: Renderer.h:384
u8 A
Definition: SColor.h:35
const CFrustum & m_Frustum
Definition: Renderer.cpp:976
#define LOGWARNING
Definition: CLogger.h:34
CTerrain * GetTerrain()
Get the pointer to the terrain object.
Definition: World.h:88
bool m_WaterReflection
Definition: Renderer.h:138
Status ogl_tex_bind(Handle ht, size_t unit)
Bind texture to the specified unit in preparation for using it in rendering.
Definition: ogl_tex.cpp:1054
Render particles.
Texture manager with asynchronous loading and automatic DDS conversion/compression.
bool m_DisplayFrustum
m_DisplayFrustum: Render the cull frustum and other data that may be interesting to evaluate culling ...
Definition: Renderer.h:447
RenderPath m_RenderPath
Definition: Renderer.h:141
void RenderPatches(bool filtered=false)
RenderPatches: Render all patches un-textured as polygons.
CPostprocManager postprocManager
Postprocessing effect manager.
Definition: Renderer.cpp:282
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
Handle m_hCompositeAlphaMap
Definition: Renderer.h:418
T round_up_to_pow2(T x)
round up to next larger power of two.
Definition: bits.h:244
GLint ogl_max_tex_units
[pixels]
Definition: ogl.cpp:469
CMaterialManager & GetMaterialManager()
Definition: Renderer.cpp:2002
CLightEnv * m_LightEnv
Definition: Renderer.h:416
TerrainRenderer terrainRenderer
Terrain renderer.
Definition: Renderer.cpp:261
Textured line overlay, with world-space coordinates, rendered in the world onto the terrain...
Definition: Overlay.h:62
void RenderPriorities()
Render priority text for all submitted patches, for debugging.
bool CullPatches(const CFrustum *frustum)
CullPatches: Culls patches and decals against a frustum, and stores the results in a special filtered...
void DisplayFrustum()
Definition: Renderer.cpp:1636
float Z
Definition: Vector4D.h:128
Interned 8-bit strings.
Definition: CStrIntern.h:37
bool m_RenderWater
Definition: WaterManager.h:75
struct CRendererInternals::Models Model
CTimeManager timeManager
Time manager.
Definition: Renderer.cpp:276
void UnregisterFileReloadFunc(FileReloadFunc func, void *obj)
delete a callback function registered with RegisterFileReloadFunc (removes any with the same func and...
Definition: Filesystem.cpp:44
ModelVertexRendererPtr VertexInstancingShader
Definition: Renderer.cpp:310
void RenderDebugTexture()
Visualize shadow map texture to help in debugging.
Definition: ShadowMap.cpp:648
void RegisterFileReloadFunc(FileReloadFunc func, void *obj)
register a callback function to be called by ReloadChangedFiles
Definition: Filesystem.cpp:39
shared_ptr< ModelRenderer > ModelRendererPtr
Definition: ModelRenderer.h:43
Status ogl_tex_set_wrap(Handle ht, GLint wrap_s, GLint wrap_t)
Override default wrap mode (GL_REPEAT) for this texture.
Definition: ogl_tex.cpp:657
Various model renderers.
Definition: Renderer.cpp:285
Definition: path.h:75
CMatrix3D m_RefractionMatrix
Definition: WaterManager.h:113
CTextureManager textureManager
Texture manager.
Definition: Renderer.cpp:258
void PrepareForRendering(const CShaderDefines &context)
Prepare internal data structures for rendering.
float m_ShadowZBias
m_ShadowZBias: Z bias used when rendering shadows into a depth texture.
Definition: Renderer.h:462
bool GetOptionBool(enum Option opt) const
Definition: Renderer.cpp:726
shared_ptr< ModelVertexRenderer > ModelVertexRendererPtr
Definition: ModelRenderer.h:40
const String & string() const
Definition: path.h:123
#define ONCE(ONCE_code__)
execute the code passed as a parameter only the first time this is reached.
friend struct CRendererInternals
Definition: Renderer.h:323
void Initialize()
Performs one-time initialization.
bool m_VertexShader
Definition: Renderer.h:160
std::vector< ProfileColumn > columnDescriptions
Column descriptions.
Definition: Renderer.cpp:103
bool m_WaterCoastalWaves
Definition: Renderer.h:136
pthread_key_t key
Definition: wpthread.cpp:140
void SetSimulation(CSimulation2 *simulation)
Set simulation context for rendering purposes.
Definition: Renderer.cpp:850
Definition: Camera.h:39
virtual void ValidatePosition()
Ensure that both the transformation and the bone matrices are correct for this model and all its prop...
Definition: Model.cpp:319
int m_ShadowMapSize
m_ShadowMapSize: Size of shadow map, or 0 for default.
Definition: Renderer.h:471
void Scale(float x_scale, float y_scale, float z_scale)
Definition: Matrix3D.cpp:210
void EndFrame()
EndFrame: Remove all patches from the list of submitted patches.
void UnloadAlphaMaps()
Definition: Renderer.cpp:1947
CShaderManager shaderManager
Shader manager.
Definition: Renderer.cpp:249
bool g_GameRestarted
Definition: MiniMap.cpp:46
bool m_WaterRefraction
Definition: Renderer.h:137
Definition: Patch.h:48
CGame * g_Game
Globally accessible pointer to the CGame object.
Definition: Game.cpp:56
void FilterTranspModels(CModelFilter &filter, int passed, int flags=0)
Filters all alpha-blended models.
Definition: Renderer.cpp:402
#define PROFILE(name)
Definition: Profile.h:195
void ClipFrustum(const CPlane &clipPlane)
Definition: Camera.cpp:131
CMatrix3D & GetProjection()
Definition: Camera.h:49
#define MODELFLAG_FILTERED
Definition: Model.h:45
i64 Status
Error handling system.
Definition: status.h:171
void CallTranspModelRenderers(const CShaderDefines &context, int flags)
Renders all alpha-blended models with the given context.
Definition: Renderer.cpp:371
u8 R
Definition: SColor.h:32
static Status ReloadChangedFileCB(void *param, const VfsPath &path)
Definition: Renderer.cpp:1955
float GetFOV() const
Definition: Camera.h:70
i64 Handle
`handle&#39; representing a reference to a resource (sound, texture, etc.)
Definition: handle.h:41
void Submit(CPatch *patch)
Submit a terrain patch that is part of the scene.
Definition: Renderer.cpp:1692
#define MODELFLAG_CASTSHADOWS
Definition: Model.h:40
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
Definition: bits.h:97
GLint x2
Definition: Renderer.h:65
int LoadAlphaMaps()
Definition: Renderer.cpp:1803
void Submit(CParticleEmitter *emitter)
Add an emitter for rendering in this frame.
RenderPath GetRenderPath() const
Definition: Renderer.h:180
stores all data describing an image.
Definition: tex.h:210
SScreenRect RenderReflections(const CShaderDefines &context, const CBoundingBoxAligned &scissor)
Definition: Renderer.cpp:1121
void Submit(CPatch *patch)
Submit: Add a patch for rendering in this frame.
float Dot(const CVector4D &a) const
Definition: Vector4D.h:122
void EndFrame()
Definition: Renderer.cpp:1603
Handle ogl_tex_load(const PIVFS &vfs, const VfsPath &pathname, size_t flags)
Load and return a handle to the texture.
Definition: ogl_tex.cpp:542
void SetViewPort(const SViewPort &viewport)
Definition: Camera.cpp:136
bool IsOpen
true if CRenderer::Open has been called
Definition: Renderer.cpp:240
void RenderParticles()
Definition: Renderer.cpp:1386
CTextureManager & GetTextureManager()
Definition: Renderer.cpp:1977
A RenderModifier that sets uniforms and textures appropriately for rendering models.
float GetNearPlane() const
Definition: Camera.h:68
void BeginRender()
BeginRender: Set OpenGL state for rendering into the shadow map texture.
Definition: ShadowMap.cpp:455
void RenderSilhouettes(const CShaderDefines &context)
Definition: Renderer.cpp:1284
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
TerrainRenderer & GetTerrainRenderer()
Definition: Renderer.cpp:1992
void MakeShadersDirty()
Definition: Renderer.cpp:1972
struct CRenderer::@49 m_AlphaMapCoords[NumAlphaMaps]
#define MODELFLAG_SILHOUETTE_DISPLAY
Definition: Model.h:42
NONCOPYABLE(CRendererInternals)
void RenderForegroundOverlays(const CCamera &viewCamera)
Render all the submitted overlays that should appear on top of everything in the world.
Struct CRendererInternals: Truly hide data that is supposed to be hidden in this structure so it won&#39;...
Definition: Renderer.cpp:235
Rectangular single-quad terrain overlay, in world space coordinates.
Definition: Overlay.h:149
void UpdateFrustum(const CBoundingBoxAligned &scissor=CBoundingBoxAligned(CVector3D(-1.0f,-1.0f,-1.0f), CVector3D(1.0f, 1.0f, 1.0f)))
Definition: Camera.cpp:83
CRendererStatsTable profileTable
Table to display renderer stats in-game via profile system.
Definition: Renderer.cpp:246
WaterManager * m_WaterManager
m_WaterManager: the WaterManager object used for water textures and settings (e.g.
Definition: Renderer.h:434
CShaderManager & GetShaderManager()
Definition: Renderer.cpp:1982
const SViewPort & GetViewPort() const
Definition: Camera.h:65
float W
Definition: Vector4D.h:128
bool WillRenderFancyWater()
Returns true if fancy water shaders will be used (i.e.
bool ogl_HaveExtension(const char *ext)
check if an extension is supported by the OpenGL implementation.
Definition: ogl.cpp:187
GLint x1
Definition: Renderer.h:65
OverlayRenderer overlayRenderer
Overlay renderer.
Definition: Renderer.cpp:264
static Status AllocateAligned(shared_ptr< T > &p, size_t size, size_t alignment=cacheLineSize)
Definition: shared_ptr.h:66
#define PROFILE3(name)
Definition: Profile.h:201
void RenderDebugBounds()
Visualize shadow mapping calculations to help in debugging and optimal shadow map usage...
Definition: ShadowMap.cpp:571
GLuint m_ReflectionTexture
Definition: WaterManager.h:105
bool Open(int width, int height)
Definition: Renderer.cpp:608
static size_t model
Definition: x86_x64.cpp:211
ModelRendererPtr NormalUnskinned
Definition: Renderer.cpp:305
LitRenderModifierPtr ModShader
Definition: Renderer.cpp:313
Scene & GetScene()
Return the scene that is currently being rendered.
Definition: Renderer.cpp:1775
Status ogl_tex_set_filter(Handle ht, GLint filter)
Override default filter (see ogl_tex_set_defaults) for this texture.
Definition: ogl_tex.cpp:638
Status ogl_tex_get_data(Handle ht, u8 **p)
Retrieve pixel data of the texture.
Definition: ogl_tex.cpp:1021
CParticleManager & GetParticleManager()
Definition: Renderer.cpp:1987
void SetScaling(float x_scale, float y_scale, float z_scale)
Definition: Matrix3D.cpp:201
void GetInverse(CMatrix3D &dst) const
Definition: Matrix3D.cpp:277
float sgn(float a)
Definition: MathUtil.h:39
NONCOPYABLE(CRendererStatsTable)
int m_Width
Definition: Camera.h:35
ETransparentMode
Definition: Renderer.h:58
Struct ProfileColumn: Describes one column of an AbstractProfileTable.
Definition: ProfileViewer.h:35
#define g_ProfileViewer
void RenderShadowMap(const CShaderDefines &context)
Definition: Renderer.cpp:865
This interface describes a scene to the renderer.
Definition: Scene.h:51
void RenderOverlaysAfterWater()
Render all the submitted overlays that are embedded in the world (i.e.
bool is_pow2(T n)
Definition: bits.h:164
void SubmitNonRecursive(CModel *model)
Submit a model that is part of the scene, without submitting attached models.
Definition: Renderer.cpp:1727
void RecreateTexture()
RecreateTexture: Destroy the current shadow texture and force creation of a new one.
Definition: ShadowMap.cpp:135
CMatrix3D GetViewProjection() const
Definition: Camera.h:55
shared_ptr< LitRenderModifier > LitRenderModifierPtr
Definition: ModelRenderer.h:37
ERenderMode m_ModelRenderMode
Definition: Renderer.h:392
Status tex_wrap(size_t w, size_t h, size_t bpp, size_t flags, const shared_ptr< u8 > &data, size_t ofs, Tex *t)
store the given image data into a Tex object; this will be as if it had been loaded via tex_load...
Definition: tex.cpp:593
#define DEBUG_DISPLAY_ERROR(description)
Definition: debug.h:197
void SetRenderPath(RenderPath rp)
Definition: Renderer.cpp:769
CMatrix3D m_Orientation
Definition: Camera.h:112
SkyManager skyManager
Sky manager.
Definition: Renderer.cpp:255
Class TerrainRenderer: Render everything related to the terrain, especially patches and water...
float GetFarPlane() const
Definition: Camera.h:69
float m_ClearColor[4]
Definition: Renderer.h:414
CWorld * GetWorld()
Get the pointer to the game world object.
Definition: Game.h:120
void SetOptionBool(enum Option opt, bool value)
Definition: Renderer.cpp:669
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending.
Definition: ogl.cpp:398
#define PROFILE3_GPU(name)
Definition: Profile.h:204
#define debug_warn(expr)
display the error dialog with the given text.
Definition: debug.h:324
CMatrix3D m_ProjMat
Definition: Camera.h:115
void RenderScene(Scene &scene)
Render the given scene immediately.
Definition: Renderer.cpp:1758
Definition: Model.h:50
const CModelDefPtr & GetModelDef()
Definition: Model.h:99
CShaderDefines globalContext
Definition: Renderer.cpp:316
void Render(int intermediates=0) const
Render: Renders the camera&#39;s frustum in world space.
Definition: Camera.cpp:370
CStr GetCellText(size_t row, size_t col)
GetCellText.
Definition: Renderer.cpp:151
int m_Width
Definition: Renderer.h:386
void RenderModels(const CShaderDefines &context, const CFrustum *frustum=0)
Definition: Renderer.cpp:979
CMaterial & GetMaterial()
Definition: Model.h:108
SScreenRect RenderRefractions(const CShaderDefines &context, const CBoundingBoxAligned &scissor)
Definition: Renderer.cpp:1208
void InterpolateLOS()
Definition: LOSTexture.cpp:114
#define MODELFLAG_SILHOUETTE_OCCLUDER
Definition: Model.h:43
const CBoundingBoxAligned & GetWorldBounds()
Returns the world-space axis-aligned bounds of this object.
int m_X
Definition: Camera.h:33
PIVFS g_VFS
Definition: Filesystem.cpp:30
friend class ShaderModelVertexRenderer
Definition: Renderer.h:333
bool m_FragmentShader
Definition: Renderer.h:161
Stats m_Stats
Definition: Renderer.h:428
CBoundingBoxAligned ScissorWater(const CMatrix3D &viewproj)
Calculate a scissor rectangle for the visible water patches.
void EndRender()
EndRender: Finish rendering into the shadow map.
Definition: ShadowMap.cpp:505
const CRenderer::Stats & Stats
Reference to the renderer singleton&#39;s stats.
Definition: Renderer.cpp:100
void RenderOverlaysBeforeWater()
Render all the submitted overlays that are embedded in the world (i.e.
bool m_SkipSubmit
m_SkipSubmit: Disable the actual submission of rendering commands to OpenGL.
Definition: Renderer.h:479
shared_ptr< CShaderProgram > CShaderProgramPtr
void PrepareForRendering()
Prepare internal data structures for rendering.
int GetFlags() const
Definition: Model.h:123
ModelVertexRendererPtr VertexRendererShader
Definition: Renderer.cpp:309
void RenderTextOverlays()
Render text overlays on top of the scene.
Definition: Renderer.cpp:1663
void SetProjection(float nearp, float farp, float fov)
Definition: Camera.cpp:51
void SetSimulation(CSimulation2 *simulation)
Set the simulation context for this frame.
Shader manager: loads and caches shader programs.
Definition: ShaderManager.h:42
Scene * m_CurrentScene
Definition: Renderer.h:411
virtual void EnumerateObjects(const CFrustum &frustum, SceneCollector *c)=0
Send all objects that can be seen when rendering the given frustum to the scene collector.
void RenderSubmit(SceneCollector &collector, const CFrustum &frustum)
void BeginFrame()
Definition: Renderer.cpp:833
void BindTexture(int unit, unsigned int tex)
Definition: Renderer.cpp:1783
Status ogl_tex_upload(const Handle ht, GLenum fmt_ovr, int q_flags_ovr, GLint int_fmt_ovr)
Upload texture to OpenGL.
Definition: ogl_tex.cpp:912
Caps m_Caps
Definition: Renderer.h:424
float X
Definition: Vector4D.h:128
struct CRenderer::Options m_Options
void RenderPatches(const CShaderDefines &context, const CFrustum *frustum=0)
Definition: Renderer.cpp:900
CPostprocManager & GetPostprocManager()
Definition: Renderer.cpp:2007
#define RETURN_STATUS_IF_ERR(expression)
Definition: status.h:276
Class WaterManager: Maintain water settings and textures.
Definition: WaterManager.h:49
Status ogl_tex_get_size(Handle ht, size_t *w, size_t *h, size_t *bpp)
Retrieve dimensions and bit depth of the texture.
Definition: ogl_tex.cpp:982
void RenderSubmissions()
Definition: Renderer.cpp:1423
const char * ogl_HaveExtensions(int dummy,...)
check if a list of extensions are all supported (as determined by ogl_HaveExtension).
Definition: ogl.cpp:266
ParticleRenderer particleRenderer
Particle renderer.
Definition: Renderer.cpp:270
Class SkyManager: Maintain sky settings and textures, and render the sky.
Definition: SkyManager.h:30