Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OverlayRenderer.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 #include "precompiled.h"
19 
20 #include "OverlayRenderer.h"
21 
22 #include <boost/unordered_map.hpp>
23 #include "graphics/LOSTexture.h"
24 #include "graphics/Overlay.h"
25 #include "graphics/Terrain.h"
27 #include "lib/ogl.h"
28 #include "maths/MathUtil.h"
29 #include "maths/Quaternion.h"
30 #include "ps/Game.h"
31 #include "ps/Profile.h"
32 #include "renderer/Renderer.h"
34 #include "renderer/VertexArray.h"
35 #include "renderer/VertexBuffer.h"
40 
41 /**
42  * Key used to group quads into batches for more efficient rendering. Currently groups by the combination
43  * of the main texture and the texture mask, to minimize texture swapping during rendering.
44  */
46 {
47  QuadBatchKey (const CTexturePtr& texture, const CTexturePtr& textureMask)
48  : m_Texture(texture), m_TextureMask(textureMask)
49  { }
50 
51  bool operator==(const QuadBatchKey& other) const
52  {
53  return (m_Texture == other.m_Texture && m_TextureMask == other.m_TextureMask);
54  }
55 
58 };
59 
60 /**
61  * Holds information about a single quad rendering batch.
62  */
63 class QuadBatchData : public CRenderData
64 {
65 public:
67 
68  /// Holds the quad overlay structures requested to be rendered in this batch. Must be cleared
69  /// after each frame.
70  std::vector<SOverlayQuad*> m_Quads;
71 
72  /// Start index of this batch into the dedicated quad indices VertexArray (see OverlayInternals).
73  size_t m_IndicesBase;
74  /// Amount of quads to actually render in this batch. Potentially (although unlikely to be)
75  /// different from m_Quads.size() due to restrictions on the total amount of quads that can be
76  /// rendered. Must be reset after each frame.
78 };
79 
81 {
82  typedef boost::unordered_map<QuadBatchKey, QuadBatchData> QuadBatchMap;
83 
86 
87  std::vector<SOverlayLine*> lines;
88  std::vector<SOverlayTexturedLine*> texlines;
89  std::vector<SOverlaySprite*> sprites;
90  std::vector<SOverlayQuad*> quads;
91 
93 
94  // Dedicated vertex/index buffers for rendering all quads (to within the limits set by
95  // MAX_QUAD_OVERLAYS).
101 
102  /// Maximum amount of quad overlays we support for rendering. This limit is set to be able to
103  /// render all quads from a single dedicated VB without having to reallocate it, which is much
104  /// faster in the typical case of rendering only a handful of quads. When modifying this value,
105  /// you must take care for the new amount of quads to fit in a single VBO (which is not likely
106  /// to be a problem).
107  static const size_t MAX_QUAD_OVERLAYS = 1024;
108 
109  // Sets of commonly-(re)used shader defines.
113 
114  /// Performs one-time setup. Called from CRenderer::Open, after graphics capabilities have
115  /// been detected. Note that no VBOs must be created before this is called, since the shader
116  /// path and graphics capabilities are not guaranteed to be stable before this point.
117  void Initialize();
118 };
119 
120 const float OverlayRenderer::OVERLAY_VOFFSET = 0.2f;
121 
123  : quadVertices(GL_DYNAMIC_DRAW), quadIndices(GL_DYNAMIC_DRAW)
124 {
126  quadAttributePos.type = GL_FLOAT;
128 
130  quadAttributeColor.type = GL_FLOAT;
132 
134  quadAttributeUV.type = GL_SHORT; // don't use GL_UNSIGNED_SHORT here, TexCoordPointer won't accept it
136 
137  // Note that we're reusing the textured overlay line shader for the quad overlay rendering. This
138  // is because their code is almost identical; the only difference is that for the quad overlays
139  // we want to use a vertex color stream as opposed to an objectColor uniform. To this end, the
140  // shader has been set up to switch between the two behaviours based on the USE_OBJECTCOLOR define.
141  defsOverlayLineNormal.Add(str_USE_OBJECTCOLOR, str_1);
142  defsOverlayLineAlwaysVisible.Add(str_USE_OBJECTCOLOR, str_1);
143  defsOverlayLineAlwaysVisible.Add(str_IGNORE_LOS, str_1);
144 }
145 
147 {
148  // Perform any initialization after graphics capabilities have been detected. Notably,
149  // only at this point can we safely allocate VBOs (in contrast to e.g. in the constructor),
150  // because their creation depends on the shader path, which is not reliably set before this point.
151 
153  quadVertices.Layout(); // allocate backing store
154 
156  quadIndices.Layout(); // allocate backing store
157 
158  // Since the quads in the vertex array are independent and always consist of exactly 4 vertices per quad, the
159  // indices are always the same; we can therefore fill in all the indices once and pretty much forget about
160  // them. We then also no longer need its backing store, since we never change any indices afterwards.
162  for (size_t i = 0; i < MAX_QUAD_OVERLAYS; ++i)
163  {
164  *index++ = i*4 + 0;
165  *index++ = i*4 + 1;
166  *index++ = i*4 + 2;
167  *index++ = i*4 + 2;
168  *index++ = i*4 + 3;
169  *index++ = i*4 + 0;
170  }
173 }
174 
175 static size_t hash_value(const QuadBatchKey& d)
176 {
177  size_t seed = 0;
178  boost::hash_combine(seed, d.m_Texture);
179  boost::hash_combine(seed, d.m_TextureMask);
180  return seed;
181 }
182 
184 {
185  m = new OverlayRendererInternals();
186 }
187 
189 {
190  delete m;
191 }
192 
194 {
195  m->Initialize();
196 }
197 
199 {
200  ENSURE(line->m_Coords.size() % 3 == 0);
201 
202  m->lines.push_back(line);
203 }
204 
206 {
207  // Simplify the rest of the code by guaranteeing non-empty lines
208  if (line->m_Coords.empty())
209  return;
210 
211  ENSURE(line->m_Coords.size() % 2 == 0);
212 
213  m->texlines.push_back(line);
214 }
215 
217 {
218  m->sprites.push_back(overlay);
219 }
220 
222 {
223  m->quads.push_back(overlay);
224 }
225 
227 {
228  m->lines.clear();
229  m->texlines.clear();
230  m->sprites.clear();
231  m->quads.clear();
232  // this should leave the capacity unchanged, which is okay since it
233  // won't be very large or very variable
234 
235  // Empty the batch rendering data structures, but keep their key mappings around for the next frames
236  for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
237  {
238  QuadBatchData& quadBatchData = (it->second);
239  quadBatchData.m_Quads.clear();
240  quadBatchData.m_NumRenderQuads = 0;
241  quadBatchData.m_IndicesBase = 0;
242  }
243 }
244 
246 {
247  PROFILE3("prepare overlays");
248 
249  // This is where we should do something like sort the overlays by
250  // colour/sprite/etc for more efficient rendering
251 
252  for (size_t i = 0; i < m->texlines.size(); ++i)
253  {
254  SOverlayTexturedLine* line = m->texlines[i];
255  if (!line->m_RenderData)
256  {
257  line->m_RenderData = shared_ptr<CTexturedLineRData>(new CTexturedLineRData());
258  line->m_RenderData->Update(*line);
259  // We assume the overlay line will get replaced by the caller
260  // if terrain changes, so we don't need to detect that here and
261  // call Update again. Also we assume the caller won't change
262  // any of the parameters after first submitting the line.
263  }
264  }
265 
266  // Group quad overlays by their texture/mask combination for efficient rendering
267  // TODO: consider doing this directly in Submit()
268  for (size_t i = 0; i < m->quads.size(); ++i)
269  {
270  SOverlayQuad* const quad = m->quads[i];
271 
272  QuadBatchKey textures(quad->m_Texture, quad->m_TextureMask);
273  QuadBatchData& batchRenderData = m->quadBatchMap[textures]; // will create entry if it doesn't already exist
274 
275  // add overlay to list of quads
276  batchRenderData.m_Quads.push_back(quad);
277  }
278 
279  const CVector3D vOffset(0, OverlayRenderer::OVERLAY_VOFFSET, 0);
280 
281  // Write quad overlay vertices/indices to VA backing store
285 
286  size_t indicesIdx = 0;
287  size_t totalNumQuads = 0;
288 
289  for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
290  {
291  QuadBatchData& batchRenderData = (it->second);
292  batchRenderData.m_NumRenderQuads = 0;
293 
294  if (batchRenderData.m_Quads.empty())
295  continue;
296 
297  // Remember the current index into the (entire) indices array as our base offset for this batch
298  batchRenderData.m_IndicesBase = indicesIdx;
299 
300  // points to the index where each iteration's vertices will be appended
301  for (size_t i = 0; i < batchRenderData.m_Quads.size() && totalNumQuads < OverlayRendererInternals::MAX_QUAD_OVERLAYS; i++)
302  {
303  const SOverlayQuad* quad = batchRenderData.m_Quads[i];
304 
305  // TODO: this is kind of ugly, the iterator should use a type that can have quad->m_Color assigned
306  // to it directly
307  const CVector4D quadColor(quad->m_Color.r, quad->m_Color.g, quad->m_Color.b, quad->m_Color.a);
308 
309  *vertexPos++ = quad->m_Corners[0] + vOffset;
310  *vertexPos++ = quad->m_Corners[1] + vOffset;
311  *vertexPos++ = quad->m_Corners[2] + vOffset;
312  *vertexPos++ = quad->m_Corners[3] + vOffset;
313 
314  (*vertexUV)[0] = 0;
315  (*vertexUV)[1] = 0;
316  ++vertexUV;
317  (*vertexUV)[0] = 0;
318  (*vertexUV)[1] = 1;
319  ++vertexUV;
320  (*vertexUV)[0] = 1;
321  (*vertexUV)[1] = 1;
322  ++vertexUV;
323  (*vertexUV)[0] = 1;
324  (*vertexUV)[1] = 0;
325  ++vertexUV;
326 
327  *vertexColor++ = quadColor;
328  *vertexColor++ = quadColor;
329  *vertexColor++ = quadColor;
330  *vertexColor++ = quadColor;
331 
332  indicesIdx += 6;
333 
334  totalNumQuads++;
335  batchRenderData.m_NumRenderQuads++;
336  }
337  }
338 
339  m->quadVertices.Upload();
340  // don't free the backing store! we'll overwrite it on the next frame to save a reallocation.
341 }
342 
344 {
345  PROFILE3_GPU("overlays (before)");
346 
347 #if CONFIG2_GLES
348 #warning TODO: implement OverlayRenderer::RenderOverlaysBeforeWater for GLES
349 #else
350  pglActiveTextureARB(GL_TEXTURE0);
351  glDisable(GL_TEXTURE_2D);
352  glEnable(GL_BLEND);
353 
354  // Ignore z so that we draw behind terrain (but don't disable GL_DEPTH_TEST
355  // since we still want to write to the z buffer)
356  glDepthFunc(GL_ALWAYS);
357 
358  for (size_t i = 0; i < m->lines.size(); ++i)
359  {
360  SOverlayLine* line = m->lines[i];
361  if (line->m_Coords.empty())
362  continue;
363 
364  ENSURE(line->m_Coords.size() % 3 == 0);
365 
366  glColor4fv(line->m_Color.FloatArray());
367  glLineWidth((float)line->m_Thickness);
368 
369  glInterleavedArrays(GL_V3F, sizeof(float)*3, &line->m_Coords[0]);
370  glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)line->m_Coords.size()/3);
371  }
372 
373  glDisableClientState(GL_VERTEX_ARRAY);
374 
375  glLineWidth(1.f);
376  glDepthFunc(GL_LEQUAL);
377  glDisable(GL_BLEND);
378 #endif
379 }
380 
382 {
383  PROFILE3_GPU("overlays (after)");
384 
387 }
388 
390 {
391 #if CONFIG2_GLES
392 #warning TODO: implement OverlayRenderer::RenderTexturedOverlayLines for GLES
393  return;
394 #endif
395  if (m->texlines.empty())
396  return;
397 
398  ogl_WarnIfError();
399 
400  glEnable(GL_TEXTURE_2D);
401  glEnable(GL_BLEND);
402  glDepthMask(0);
403 
404  const char* shaderName;
405  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
406  shaderName = "arb/overlayline";
407  else
408  shaderName = "fixed:overlayline";
409 
410  CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture();
411 
412  CShaderManager& shaderManager = g_Renderer.GetShaderManager();
413  CShaderProgramPtr shaderTexLineNormal(shaderManager.LoadProgram(shaderName, m->defsOverlayLineNormal));
414  CShaderProgramPtr shaderTexLineAlwaysVisible(shaderManager.LoadProgram(shaderName, m->defsOverlayLineAlwaysVisible));
415 
416  // ----------------------------------------------------------------------------------------
417 
418  if (shaderTexLineNormal)
419  {
420  shaderTexLineNormal->Bind();
421  shaderTexLineNormal->BindTexture(str_losTex, los.GetTexture());
422  shaderTexLineNormal->Uniform(str_losTransform, los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
423 
424  // batch render only the non-always-visible overlay lines using the normal shader
425  RenderTexturedOverlayLines(shaderTexLineNormal, false);
426 
427  shaderTexLineNormal->Unbind();
428  }
429 
430  // ----------------------------------------------------------------------------------------
431 
432  if (shaderTexLineAlwaysVisible)
433  {
434  shaderTexLineAlwaysVisible->Bind();
435  // TODO: losTex and losTransform are unused in the always visible shader; see if these can be safely omitted
436  shaderTexLineAlwaysVisible->BindTexture(str_losTex, los.GetTexture());
437  shaderTexLineAlwaysVisible->Uniform(str_losTransform, los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
438 
439  // batch render only the always-visible overlay lines using the LoS-ignored shader
440  RenderTexturedOverlayLines(shaderTexLineAlwaysVisible, true);
441 
442  shaderTexLineAlwaysVisible->Unbind();
443  }
444 
445  // ----------------------------------------------------------------------------------------
446 
447  // TODO: the shaders should probably be responsible for unbinding their textures
448  g_Renderer.BindTexture(1, 0);
449  g_Renderer.BindTexture(0, 0);
450 
452 
453  glDepthMask(1);
454  glDisable(GL_BLEND);
455 }
456 
458 {
459  for (size_t i = 0; i < m->texlines.size(); ++i)
460  {
461  SOverlayTexturedLine* line = m->texlines[i];
462 
463  // render only those lines matching the requested alwaysVisible status
464  if (!line->m_RenderData || line->m_AlwaysVisible != alwaysVisible)
465  continue;
466 
467  ENSURE(line->m_RenderData);
468  line->m_RenderData->Render(*line, shader);
469  }
470 }
471 
473 {
474  if (m->quadBatchMap.empty())
475  return;
476 
477  ogl_WarnIfError();
478 
479  glEnable(GL_TEXTURE_2D);
480  glEnable(GL_BLEND);
481  glDepthMask(0);
482 
483  const char* shaderName;
484  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
485  shaderName = "arb/overlayline";
486  else
487  shaderName = "fixed:overlayline";
488 
489  CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture();
490 
491  CShaderManager& shaderManager = g_Renderer.GetShaderManager();
492  CShaderProgramPtr shader(shaderManager.LoadProgram(shaderName, m->defsQuadOverlay));
493 
494  // ----------------------------------------------------------------------------------------
495 
496  if (shader)
497  {
498  shader->Bind();
499  shader->BindTexture(str_losTex, los.GetTexture());
500  shader->Uniform(str_losTransform, los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
501 
502  // Base offsets (in bytes) of the two backing stores relative to their owner VBO
503  u8* indexBase = m->quadIndices.Bind();
504  u8* vertexBase = m->quadVertices.Bind();
505  GLsizei indexStride = m->quadIndices.GetStride();
506  GLsizei vertexStride = m->quadVertices.GetStride();
507 
508  for (OverlayRendererInternals::QuadBatchMap::iterator it = m->quadBatchMap.begin(); it != m->quadBatchMap.end(); ++it)
509  {
510  QuadBatchData& batchRenderData = it->second;
511  const size_t batchNumQuads = batchRenderData.m_NumRenderQuads;
512 
513  // Careful; some drivers don't like drawing calls with 0 stuff to draw.
514  if (batchNumQuads == 0)
515  continue;
516 
517  const QuadBatchKey& maskPair = it->first;
518 
519  shader->BindTexture(str_baseTex, maskPair.m_Texture->GetHandle());
520  shader->BindTexture(str_maskTex, maskPair.m_TextureMask->GetHandle());
521 
522  int streamflags = shader->GetStreamFlags();
523 
524  if (streamflags & STREAM_POS)
525  shader->VertexPointer(m->quadAttributePos.elems, m->quadAttributePos.type, vertexStride, vertexBase + m->quadAttributePos.offset);
526 
527  if (streamflags & STREAM_UV0)
528  shader->TexCoordPointer(GL_TEXTURE0, m->quadAttributeUV.elems, m->quadAttributeUV.type, vertexStride, vertexBase + m->quadAttributeUV.offset);
529 
530  if (streamflags & STREAM_UV1)
531  shader->TexCoordPointer(GL_TEXTURE1, m->quadAttributeUV.elems, m->quadAttributeUV.type, vertexStride, vertexBase + m->quadAttributeUV.offset);
532 
533  if (streamflags & STREAM_COLOR)
534  shader->ColorPointer(m->quadAttributeColor.elems, m->quadAttributeColor.type, vertexStride, vertexBase + m->quadAttributeColor.offset);
535 
536  shader->AssertPointersBound();
537  glDrawElements(GL_TRIANGLES, (GLsizei)(batchNumQuads * 6), GL_UNSIGNED_SHORT, indexBase + indexStride * batchRenderData.m_IndicesBase);
538 
539  g_Renderer.GetStats().m_DrawCalls++;
540  g_Renderer.GetStats().m_OverlayTris += batchNumQuads*2;
541  }
542 
543  shader->Unbind();
544  }
545 
546  // ----------------------------------------------------------------------------------------
547 
548  // TODO: the shader should probably be responsible for unbinding its textures
549  g_Renderer.BindTexture(1, 0);
550  g_Renderer.BindTexture(0, 0);
551 
553 
554  glDepthMask(1);
555  glDisable(GL_BLEND);
556 }
557 
559 {
560  PROFILE3_GPU("overlays (fg)");
561 
562 #if CONFIG2_GLES
563 #warning TODO: implement OverlayRenderer::RenderForegroundOverlays for GLES
564 #else
565  glEnable(GL_TEXTURE_2D);
566  glEnable(GL_BLEND);
567  glDisable(GL_DEPTH_TEST);
568 
569  CVector3D right = -viewCamera.m_Orientation.GetLeft();
570  CVector3D up = viewCamera.m_Orientation.GetUp();
571 
572  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
573 
574  glEnableClientState(GL_VERTEX_ARRAY);
575  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
576 
577  CShaderProgramPtr shader;
578  CShaderTechniquePtr tech;
579 
580  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
581  {
582  tech = g_Renderer.GetShaderManager().LoadEffect(str_foreground_overlay);
583  tech->BeginPass();
584  shader = tech->GetShader();
585  }
586 
587  float uvs[8] = { 0,0, 1,0, 1,1, 0,1 };
588 
589  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
590  shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, sizeof(float)*2, &uvs[0]);
591  else
592  glTexCoordPointer(2, GL_FLOAT, sizeof(float)*2, &uvs);
593 
594  for (size_t i = 0; i < m->sprites.size(); ++i)
595  {
596  SOverlaySprite* sprite = m->sprites[i];
597 
598  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
599  shader->BindTexture(str_baseTex, sprite->m_Texture);
600  else
601  sprite->m_Texture->Bind();
602 
603  CVector3D pos[4] = {
604  sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y0,
605  sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y0,
606  sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y1,
607  sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y1
608  };
609 
610  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
611  shader->VertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X);
612  else
613  glVertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X);
614 
615  glDrawArrays(GL_QUADS, 0, (GLsizei)4);
616 
617  g_Renderer.GetStats().m_DrawCalls++;
618  g_Renderer.GetStats().m_OverlayTris += 2;
619  }
620 
621  if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
622  tech->EndPass();
623 
624  glDisableClientState(GL_VERTEX_ARRAY);
625  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
626 
627  glEnable(GL_DEPTH_TEST);
628  glDisable(GL_BLEND);
629  glDisable(GL_TEXTURE_2D);
630 #endif
631 }
CVector3D m_Corners[4]
Definition: Overlay.h:153
void Add(CStrIntern name, CStrIntern value)
Add a name and associated value to the map of defines.
#define u8
Definition: types.h:39
std::vector< SOverlayQuad * > m_Quads
Holds the quad overlay structures requested to be rendered in this batch.
size_t m_IndicesBase
Start index of this batch into the dedicated quad indices VertexArray (see OverlayInternals).
VertexArray::Attribute quadAttributeColor
float g
Definition: Overlay.h:57
Line-based overlay, with world-space coordinates, rendered in the world potentially behind other obje...
Definition: Overlay.h:36
void Initialize()
Performs one-time setup.
CShaderDefines defsOverlayLineNormal
Definition: Decompose.h:22
float m_X1
Definition: Overlay.h:141
CTexturePtr m_Texture
size_t m_NumRenderQuads
Amount of quads to actually render in this batch.
VertexArrayIterator< u16 > GetIterator() const
Gets the iterator over the (only) attribute in this array, i.e. a u16.
size_t hash_value(const CStrIntern &v)
bool operator==(const QuadBatchKey &other) const
bool m_AlwaysVisible
Should this line be rendered fully visible at all times, even under the SoD?
Definition: Overlay.h:96
CColor m_Color
Definition: Overlay.h:154
void AddAttribute(Attribute *attr)
Definition: VertexArray.cpp:75
shared_ptr< CShaderTechnique > CShaderTechniquePtr
std::vector< SOverlayLine * > lines
void RenderQuadOverlays()
Helper method; batch-renders all registered quad overlays, batched by their texture for effiency...
Billboard sprite overlay, with world-space coordinates, rendered on top of all other objects...
Definition: Overlay.h:137
void FreeBackingStore()
CTexturePtr m_TextureMask
void Submit(SOverlayLine *overlay)
Add a line overlay for rendering in this frame.
A VertexArray that is specialised to handle 16-bit array indices.
Definition: VertexArray.h:212
CVector3D m_Position
Definition: Overlay.h:140
#define g_Renderer
Definition: Renderer.h:61
void EndFrame()
Reset the list of submitted overlays.
float m_X0
Definition: Overlay.h:141
std::vector< SOverlayQuad * > quads
std::vector< SOverlaySprite * > sprites
std::vector< float > m_Coords
Definition: Overlay.h:41
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
float m_Y1
Definition: Overlay.h:141
float b
Definition: Overlay.h:57
CTexturePtr m_Texture
Definition: Overlay.h:151
Textured line overlay, with world-space coordinates, rendered in the world onto the terrain...
Definition: Overlay.h:62
float X
Definition: Vector3D.h:31
Holds information about a single quad rendering batch.
void Initialize()
Performs one-time initialization.
std::vector< SOverlayTexturedLine * > texlines
Definition: Camera.h:39
float a
Definition: Overlay.h:57
GLuint GetTexture()
Recomputes the LOS texture if necessary, and returns the texture handle.
Definition: LOSTexture.cpp:173
void SetNumVertices(size_t num)
Definition: VertexArray.cpp:64
Rendering data for an STexturedOverlayLine.
CShaderDefines defsOverlayLineAlwaysVisible
VertexArray::Attribute quadAttributePos
std::vector< float > m_Coords
(x, z) vertex coordinate pairs; y is computed automatically.
Definition: Overlay.h:90
Key used to group quads into batches for more efficient rendering.
VertexArrayIterator< T > GetIterator() const
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
void RenderForegroundOverlays(const CCamera &viewCamera)
Render all the submitted overlays that should appear on top of everything in the world.
QuadBatchKey(const CTexturePtr &texture, const CTexturePtr &textureMask)
Rectangular single-quad terrain overlay, in world space coordinates.
Definition: Overlay.h:149
VertexArray::Attribute quadAttributeUV
#define PROFILE3(name)
Definition: Profile.h:201
u8 m_Thickness
Definition: Overlay.h:42
void RenderOverlaysAfterWater()
Render all the submitted overlays that are embedded in the world (i.e.
const float * FloatArray() const
Definition: Overlay.h:49
CVector3D GetLeft() const
Definition: Matrix3D.cpp:241
boost::unordered_map< QuadBatchKey, QuadBatchData > QuadBatchMap
CMatrix3D m_Orientation
Definition: Camera.h:112
Maintains the LOS (fog-of-war / shroud-of-darkness) texture, used for rendering and for the minimap...
Definition: LOSTexture.h:32
OverlayRendererInternals * m
VertexIndexArray quadIndices
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
float m_Y0
Definition: Overlay.h:141
CShaderProgramPtr LoadProgram(const char *name, const CShaderDefines &defines)
Load a shader program.
CVector3D GetUp() const
Definition: Matrix3D.cpp:247
CTexturePtr m_Texture
Definition: Overlay.h:139
const CMatrix3D & GetTextureMatrix()
Returns a matrix to map (x,y,z) world coordinates onto (u,v) LOS texture coordinates, in the form expected by glLoadMatrixf.
Definition: LOSTexture.cpp:184
static void Unbind()
Unbind any currently-bound buffer, so glVertexPointer etc calls will not attempt to use it...
CColor m_Color
Definition: Overlay.h:40
static const float OVERLAY_VOFFSET
Small vertical offset of overlays from terrain to prevent visual glitches.
void RenderOverlaysBeforeWater()
Render all the submitted overlays that are embedded in the world (i.e.
shared_ptr< CShaderProgram > CShaderProgramPtr
void PrepareForRendering()
Prepare internal data structures for rendering.
size_t GetStride() const
Definition: VertexArray.h:169
shared_ptr< CTexturedLineRData > m_RenderData
Cached renderer data, because expensive to compute.
Definition: Overlay.h:115
Shader manager: loads and caches shader programs.
Definition: ShaderManager.h:42
float r
Definition: Overlay.h:57
CTexturePtr m_TextureMask
Definition: Overlay.h:152
static const size_t MAX_QUAD_OVERLAYS
Maximum amount of quad overlays we support for rendering.
shared_ptr< CTexture > CTexturePtr
Definition: Texture.h:22
void RenderTexturedOverlayLines()
Helper method; renders all overlay lines currently registered in the internals.