All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BatchedTextRenderableCache.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "Text.h"
6 #include "Types.h"
7 #include "IdTypes.h"
8 #include "Fonts.h"
9 #include "Rendering.h"
10 #include "VectorMath.h"
11 #include "BatchedTextRenderable.h"
12 
13 #include "IBatchedTextRenderableFactory.h"
14 #include "ITextMaterialFactory.h"
15 #include "FontInstance.h"
16 #include "FontCharacter.h"
17 #include "FontMaterialSetBuilder.h"
18 #include "FontMaterialSet.h"
19 
20 #include <string>
21 #include <vector>
22 #include <map>
23 
24 
25 
26 namespace Eegeo
27 {
28  namespace Text
29  {
30  template <typename TBatchedTextRenderable, typename TBatchedTextRenderableFactory>
32  {
33  public:
35  typedef TBatchedTextRenderableFactory BatchedTextRenderableFactoryType;
38  private:
39  typedef std::pair<Rendering::SortKey, Rendering::SortKey> SortKeyPair;
40  typedef std::map<SortKeyPair, BatchedTextRenderableType*> TSortKeyToTextRenderable;
41 
42  public:
43 
44  typedef typename TSortKeyToTextRenderable::const_iterator TextRenderableIterator;
45 
47  TBatchedTextRenderableFactory& batchedTextRenderableFactory,
48  VertexBufferType& vertexBuffer)
49  : m_batchedTextRenderableFactory(batchedTextRenderableFactory)
50  , m_vertexBuffer(vertexBuffer)
51  {}
52 
54  {
55  for (typename TSortKeyToTextRenderable::const_iterator iter = m_sortKeyToTextRenderable.begin(); iter != m_sortKeyToTextRenderable.end(); ++iter)
56  {
57  BatchedTextRenderable* pTextRenderable = iter->second;
58  Eegeo_DELETE pTextRenderable;
59  }
60  }
61 
62  void SetupCurrentFont(const Fonts::FontMaterialSet& fontMaterialSetNonHalo, const Fonts::FontMaterialSet& fontMaterialSetHalo, Rendering::LayerIds::Values layerId, int subLayer)
63  {
64  const Fonts::FontMaterialSet::TMaterialVector& foregroundMaterials = fontMaterialSetNonHalo.GetMaterials();
65  const Fonts::FontMaterialSet::TMaterialVector& haloMaterials = fontMaterialSetHalo.GetMaterials();
66  Eegeo_ASSERT(foregroundMaterials.size() == haloMaterials.size());
67 
68  m_foregroundLayerTextRenderables.clear();
69  m_foregroundLayerTextRenderables.reserve(foregroundMaterials.size());
70  m_haloLayerTextRenderables.clear();
71  m_haloLayerTextRenderables.reserve(haloMaterials.size());
72 
73  const Rendering::SortKey& sortKeyForegroundLayer = BatchedTextRenderable::MakeSortKeyForLayer(layerId, subLayer, false);
74  const Rendering::SortKey& sortKeyHaloLayer = BatchedTextRenderable::MakeSortKeyForLayer(layerId, subLayer, true);
75 
76  for (int i = 0; i < foregroundMaterials.size(); ++i)
77  {
78  Rendering::Materials::IMaterial& foregroundMaterial = *foregroundMaterials.at(i);
79  const Rendering::SortKey& sortKeyForeground = BatchedTextRenderable::MakeSortKey(foregroundMaterial, sortKeyForegroundLayer);
80  BatchedTextRenderableType* pForegroundBatchedTextRenderable = GetRenderableForSortKeyOrNull(sortKeyForeground, Rendering::SortKey());
81  if (pForegroundBatchedTextRenderable == NULL)
82  {
83  pForegroundBatchedTextRenderable = CreateAndAddRenderable(sortKeyForeground, foregroundMaterial, NULL);
84  }
85  m_foregroundLayerTextRenderables.push_back(pForegroundBatchedTextRenderable);
86 
87 
88  Rendering::Materials::IMaterial& haloMaterial = *haloMaterials.at(i);
89  const Rendering::SortKey& sortKeyHalo = BatchedTextRenderable::MakeSortKey(haloMaterial, sortKeyHaloLayer);
90  BatchedTextRenderableType* pHaloBatchedTextRenderable = GetRenderableForSortKeyOrNull(sortKeyHalo, sortKeyForeground);
91  if (pHaloBatchedTextRenderable == NULL)
92  {
93  pHaloBatchedTextRenderable = CreateAndAddRenderable(sortKeyHalo, haloMaterial, pForegroundBatchedTextRenderable);
94  }
95  m_haloLayerTextRenderables.push_back(pHaloBatchedTextRenderable);
96  }
97  }
98 
99  void ClearCurrentFont()
100  {
101  m_foregroundLayerTextRenderables.clear();
102  m_haloLayerTextRenderables.clear();
103  }
104 
105  typename BatchedTextRenderableType::VertexListType& GetTextVertexList(int texturePage) const
106  {
107  return m_foregroundLayerTextRenderables[texturePage]->GetVertexList();
108  }
109 
110  void UpdateTextAppearanceOnCurrentRenderables(const BatchedTextAppearance& batchedTextAppearance)
111  {
112  UpdateTextAppearanceOnRenderables(batchedTextAppearance, m_foregroundLayerTextRenderables);
113  UpdateTextAppearanceOnRenderables(batchedTextAppearance, m_haloLayerTextRenderables);
114  }
115 
116 
117  TextRenderableIterator TextRenderablesBegin() const { return m_sortKeyToTextRenderable.begin(); }
118  TextRenderableIterator TextRenderablesEnd() const { return m_sortKeyToTextRenderable.end(); }
119 
120  void Reset()
121  {
122  m_vertexBuffer.Reset();
123 
124  for (TextRenderableIterator iter = TextRenderablesBegin(); iter != TextRenderablesEnd(); ++iter)
125  {
126  BatchedTextRenderableType& textRenderable = *(iter->second);
127  textRenderable.Reset();
128  }
129  }
130 
131  void Finalize()
132  {
133  m_vertexBuffer.Swap();
134  m_vertexBuffer.Reset();
135 
136  int totalVertexCount = 0;
137  for (TextRenderableIterator iter = TextRenderablesBegin(); iter != TextRenderablesEnd(); ++iter)
138  {
139  BatchedTextRenderableType& textRenderable = *(iter->second);
140  textRenderable.Finalize();
141 
142  if (textRenderable.IsPrimary())
143  {
144  totalVertexCount += static_cast<int>(textRenderable.GetVertexList().size());
145  }
146  }
147 
148  m_vertexBuffer.Reserve(totalVertexCount);
149  }
150 
151  void Upload()
152  {
153  m_vertexBuffer.Bind();
154 
155  for (TextRenderableIterator iter = TextRenderablesBegin(); iter != TextRenderablesEnd(); ++iter)
156  {
157  BatchedTextRenderableType& textRenderable = *(iter->second);
158  textRenderable.Upload();
159  }
160 
161  m_vertexBuffer.Unbind();
162  }
163 
164  private:
165 
166 
167  void UpdateTextAppearanceOnRenderables(const BatchedTextAppearance& batchedTextAppearance, typename std::vector<TBatchedTextRenderable*>& renderables)
168  {
169  for (typename std::vector<TBatchedTextRenderable*>::const_iterator iter = renderables.begin(); iter != renderables.end(); ++iter)
170  {
171  BatchedTextRenderable* pTextRenderable = *iter;
172  pTextRenderable->SetTextAppearance(batchedTextAppearance);
173  }
174  }
175 
176 
177  BatchedTextRenderableType* GetRenderableForSortKeyOrNull(const Rendering::SortKey& sortKey, const Rendering::SortKey& sortKeyPrimary)
178  {
179  typename TSortKeyToTextRenderable::const_iterator iter = m_sortKeyToTextRenderable.find(std::make_pair(sortKey, sortKeyPrimary));
180 
181  if (iter == m_sortKeyToTextRenderable.end())
182  {
183  return NULL;
184  }
185 
186  return iter->second;
187  }
188 
189  BatchedTextRenderableType* CreateAndAddRenderable(const Rendering::SortKey& sortKey, Rendering::Materials::IMaterial& material, BatchedTextRenderableType* pPrimaryRenderable)
190  {
191  BatchedTextRenderableType* pBatchedTextRenderableType = m_batchedTextRenderableFactory.Create(material, sortKey, pPrimaryRenderable);
192 
193  const Rendering::SortKey& sortKeyPrimary = (pPrimaryRenderable != NULL) ? pPrimaryRenderable->GetSortKey() : Rendering::SortKey();
194 
195  const SortKeyPair sortKeyPair(std::make_pair(sortKey, sortKeyPrimary));
196 
197  m_sortKeyToTextRenderable.insert(std::make_pair(sortKeyPair, pBatchedTextRenderableType));
198  return pBatchedTextRenderableType;
199  }
200 
201 
202  TBatchedTextRenderableFactory& m_batchedTextRenderableFactory;
203  VertexBufferType& m_vertexBuffer;
204 
205  std::vector<TBatchedTextRenderable*> m_foregroundLayerTextRenderables;
206  std::vector<TBatchedTextRenderable*> m_haloLayerTextRenderables;
207 
208  TSortKeyToTextRenderable m_sortKeyToTextRenderable;
209 
210 
211  };
212 
213  }
214 }