Ticket #2027: CTextRenderer_allocs.patch
File CTextRenderer_allocs.patch, 15.9 KB (added by , 11 years ago) |
---|
-
graphics/TextRenderer.cpp
25 25 26 26 extern int g_xres, g_yres; 27 27 28 CTextRenderer::CTextRenderer(const CShaderProgramPtr& shader) : 29 m_Shader(shader) 28 static CTextRenderer* g_TextRenderer = NULL; 29 30 CTextRenderer& CTextRenderer::Singleton() 30 31 { 31 ResetTransform(); 32 Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); 33 Font(L"sans-10"); 32 if(g_TextRenderer == NULL) 33 g_TextRenderer = new CTextRenderer(); 34 35 // need to reset the state 36 g_TextRenderer->ResetTransform(); 37 g_TextRenderer->Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); // white 38 if(g_TextRenderer->m_Fonts.empty()) 39 g_TextRenderer->Font(L"sans-10"); // set the default font 40 else 41 g_TextRenderer->m_Font = g_TextRenderer->m_Fonts[0].second; // sans-10 is the first and default font 42 return *g_TextRenderer; 34 43 } 35 44 45 CTextRenderer::CTextRenderer() 46 { 47 } 48 49 CTextRenderer::~CTextRenderer() 50 { 51 for(size_t i = 0; i < m_Fonts.size(); ++i) 52 { 53 delete m_Fonts[i].second; // delete all the cached fonts 54 } 55 } 56 57 36 58 void CTextRenderer::ResetTransform() 37 59 { 38 60 m_Transform.SetIdentity(); … … 44 66 m_Transform = proj * m_Transform; 45 67 } 46 68 47 CMatrix3D CTextRenderer::GetTransform()69 void CTextRenderer::GetTransform(CMatrix3D& out) 48 70 { 49 returnm_Transform;71 out = m_Transform; 50 72 } 51 73 52 74 void CTextRenderer::SetTransform(const CMatrix3D& transform) … … 56 78 57 79 void CTextRenderer::Translate(float x, float y, float z) 58 80 { 59 CMatrix3D m; 60 m.SetTranslation(x, y, z); 61 m_Transform = m_Transform * m; 81 m_Transform.PostTranslate(x, y, z); 62 82 } 63 83 64 84 void CTextRenderer::Color(const CColor& color) … … 73 93 74 94 void CTextRenderer::Font(const CStrW& font) 75 95 { 76 if (!m_Fonts[font]) 77 m_Fonts[font] = shared_ptr<CFont>(new CFont(font)); 96 size_t hash = font.GetHashCode(); 97 FontsMap::iterator end = m_Fonts.end(); 98 FontsMap::iterator it = m_Fonts.begin(); 99 for(; it != end; ++it) if(it->first == hash) 100 break; // found it 78 101 79 m_Font = m_Fonts[font]; 102 if (it == end) // does not exist 103 { 104 m_Font = new CFont(font); 105 m_Fonts.push_back(std::make_pair(hash, m_Font)); 106 } 107 else 108 { 109 m_Font = it->second; 110 } 80 111 } 81 112 82 113 void CTextRenderer::PrintfAdvance(const wchar_t* fmt, ...) 83 114 { 84 wchar_t buf[1024] = {0};115 wchar_t buf[1024]; 85 116 86 117 va_list args; 87 118 va_start(args, fmt); … … 90 121 91 122 if (ret < 0) 92 123 debug_printf(L"CTextRenderer::Printf vswprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno); 93 94 PutAdvance(buf);124 else 125 PutAdvance(buf); 95 126 } 96 127 97 128 98 129 void CTextRenderer::PrintfAt(float x, float y, const wchar_t* fmt, ...) 99 130 { 100 wchar_t buf[1024] = {0};131 wchar_t buf[1024]; 101 132 102 133 va_list args; 103 134 va_start(args, fmt); … … 106 137 107 138 if (ret < 0) 108 139 debug_printf(L"CTextRenderer::PrintfAt vswprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno); 109 110 Put(x, y, buf);140 else 141 Put(x, y, buf); 111 142 } 112 143 113 144 void CTextRenderer::PutAdvance(const wchar_t* buf) … … 127 158 CMatrix3D translate; 128 159 translate.SetTranslation(x, y, 0.0f); 129 160 161 int text_index = m_TextBuffer.size(); 162 int text_length = wcslen(buf); 163 130 164 SBatch batch; 131 165 batch.transform = m_Transform * translate; 132 166 batch.color = m_Color; 133 167 batch.font = m_Font; 134 batch.text = buf; 168 batch.text_index = text_index; 169 batch.text_length = text_length; 135 170 m_Batches.push_back(batch); 171 172 m_TextBuffer.resize(text_index + text_length); 173 wmemcpy(&m_TextBuffer[text_index], buf, text_length); 136 174 } 137 175 138 struct t2f_v2i139 {140 t2f_v2i() : u(0), v(0), x(0), y(0) { }141 float u, v;142 i16 x, y;143 };144 176 145 void CTextRenderer::Render( )177 void CTextRenderer::Render(CShaderProgramPtr shader) 146 178 { 147 std::vector<u16> indexes;148 std::vector<t2f_v2i> vertexes;149 150 179 for (size_t i = 0; i < m_Batches.size(); ++i) 151 180 { 152 SBatch& batch = m_Batches[i];181 const SBatch& batch = m_Batches[i]; 153 182 154 if (batch.text .empty()) // avoid zero-length arrays183 if (batch.text_length == 0) // avoid zero-length arrays 155 184 continue; 156 185 157 186 const std::map<u16, UnifontGlyphData>& glyphs = batch.font->GetGlyphs(); 158 187 159 m_Shader->BindTexture("tex", batch.font->GetTexture()); 188 shader->BindTexture("tex", batch.font->GetTexture()); 189 shader->Uniform("transform", batch.transform); 160 190 161 m_Shader->Uniform("transform", batch.transform);162 163 191 // ALPHA-only textures will have .rgb sampled as 0, so we need to 164 192 // replace it with white (but not affect RGBA textures) 165 193 if (batch.font->HasRGB()) 166 m_Shader->Uniform("colorAdd", CColor(0.0f, 0.0f, 0.0f, 0.0f));194 shader->Uniform("colorAdd", CColor(0.0f, 0.0f, 0.0f, 0.0f)); 167 195 else 168 m_Shader->Uniform("colorAdd", CColor(1.0f, 1.0f, 1.0f, 0.0f));196 shader->Uniform("colorAdd", CColor(1.0f, 1.0f, 1.0f, 0.0f)); 169 197 170 m_Shader->Uniform("colorMul", batch.color);198 shader->Uniform("colorMul", batch.color); 171 199 172 vertexes.clear();173 vertexes.resize(batch.text.size()*4);174 200 175 indexes.clear();176 indexes.resize(batch.text.size()*6);201 m_VertexBuffer.resize(batch.text_length*4); 202 m_IndexBuffer.resize(batch.text_length*6); 177 203 204 const wchar_t* text = &m_TextBuffer[batch.text_index]; 205 SGlyphVertex* vertices = &m_VertexBuffer[0]; 206 u16* indices = &m_IndexBuffer[0]; 207 178 208 i16 x = 0; 179 for ( size_t i = 0; i < batch.text.size(); ++i)209 for (int i = 0; i < batch.text_length; ++i) 180 210 { 181 std::map<u16, UnifontGlyphData>::const_iterator it = glyphs.find( batch.text[i]);211 std::map<u16, UnifontGlyphData>::const_iterator it = glyphs.find(text[i]); 182 212 183 213 if (it == glyphs.end()) 184 214 it = glyphs.find(0xFFFD); // Use the missing glyph symbol … … 188 218 189 219 const UnifontGlyphData& g = it->second; 190 220 191 vert exes[i*4].u = g.u1;192 vert exes[i*4].v = g.v0;193 vert exes[i*4].x = g.x1 + x;194 vert exes[i*4].y = g.y0;221 vertices[i*4].u = g.u1; 222 vertices[i*4].v = g.v0; 223 vertices[i*4].x = g.x1 + x; 224 vertices[i*4].y = g.y0; 195 225 196 vert exes[i*4+1].u = g.u0;197 vert exes[i*4+1].v = g.v0;198 vert exes[i*4+1].x = g.x0 + x;199 vert exes[i*4+1].y = g.y0;226 vertices[i*4+1].u = g.u0; 227 vertices[i*4+1].v = g.v0; 228 vertices[i*4+1].x = g.x0 + x; 229 vertices[i*4+1].y = g.y0; 200 230 201 vert exes[i*4+2].u = g.u0;202 vert exes[i*4+2].v = g.v1;203 vert exes[i*4+2].x = g.x0 + x;204 vert exes[i*4+2].y = g.y1;231 vertices[i*4+2].u = g.u0; 232 vertices[i*4+2].v = g.v1; 233 vertices[i*4+2].x = g.x0 + x; 234 vertices[i*4+2].y = g.y1; 205 235 206 vert exes[i*4+3].u = g.u1;207 vert exes[i*4+3].v = g.v1;208 vert exes[i*4+3].x = g.x1 + x;209 vert exes[i*4+3].y = g.y1;236 vertices[i*4+3].u = g.u1; 237 vertices[i*4+3].v = g.v1; 238 vertices[i*4+3].x = g.x1 + x; 239 vertices[i*4+3].y = g.y1; 210 240 211 ind exes[i*6+0] = i*4+0;212 ind exes[i*6+1] = i*4+1;213 ind exes[i*6+2] = i*4+2;214 ind exes[i*6+3] = i*4+2;215 ind exes[i*6+4] = i*4+3;216 ind exes[i*6+5] = i*4+0;241 indices[i*6+0] = i*4+0; 242 indices[i*6+1] = i*4+1; 243 indices[i*6+2] = i*4+2; 244 indices[i*6+3] = i*4+2; 245 indices[i*6+4] = i*4+3; 246 indices[i*6+5] = i*4+0; 217 247 218 248 x += g.xadvance; 219 249 } 220 250 221 m_Shader->VertexPointer(2, GL_SHORT, sizeof(t2f_v2i), &vertexes[0].x);222 m_Shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, sizeof(t2f_v2i), &vertexes[0].u);251 shader->VertexPointer(2, GL_SHORT, sizeof(SGlyphVertex), &vertices[0].x); 252 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, sizeof(SGlyphVertex), &vertices[0].u); 223 253 224 glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, &indexes[0]);254 glDrawElements(GL_TRIANGLES, m_IndexBuffer.size(), GL_UNSIGNED_SHORT, indices); 225 255 } 226 256 227 257 m_Batches.clear(); 258 m_VertexBuffer.clear(); 259 m_IndexBuffer.clear(); 228 260 } -
graphics/TextRenderer.h
27 27 28 28 class CTextRenderer 29 29 { 30 NONCOPYABLE(CTextRenderer); 31 CTextRenderer(); 32 ~CTextRenderer(); 30 33 public: 31 CTextRenderer(const CShaderProgramPtr& shader);32 34 33 35 /** 36 * @return Pointer to the TextRenderer 37 */ 38 static CTextRenderer& Singleton(); 39 40 /** 34 41 * Reset the text transform to the default, with (0,0) in the top-left of the screen. 35 42 */ 36 43 void ResetTransform(); 37 44 38 CMatrix3D GetTransform(); 45 /** 46 * Gets the transformation matrix 47 */ 48 void GetTransform(CMatrix3D& out); 39 49 50 /** 51 * Sets the transformation matrix 52 */ 40 53 void SetTransform(const CMatrix3D& transform); 41 54 42 55 void Translate(float x, float y, float z); … … 83 96 /** 84 97 * Render all of the previously printed text calls. 85 98 */ 86 void Render( );99 void Render(CShaderProgramPtr shader); 87 100 88 101 private: 102 89 103 struct SBatch 90 104 { 91 105 CMatrix3D transform; 92 106 CColor color; 93 shared_ptr<CFont> font; 94 std::wstring text; 107 CFont* font; 108 int text_index; 109 int text_length; 95 110 }; 96 111 97 CShaderProgramPtr m_Shader; 112 struct SGlyphVertex 113 { 114 float u, v; // 2x float uvs 115 i16 x, y; // 2x int screen xy 116 }; 98 117 99 CMatrix3D m_Transform;100 118 101 CColor m_Color; 102 shared_ptr<CFont> m_Font; 119 CMatrix3D m_Transform; 120 CColor m_Color; 121 CFont* m_Font; // current font 103 122 104 std::map<CStrW, shared_ptr<CFont> > m_Fonts; 123 typedef std::vector<std::pair<size_t, CFont*> > FontsMap; 124 FontsMap m_Fonts; // cached fonts 105 125 106 std::vector<SBatch> m_Batches; 126 std::vector<SBatch> m_Batches; 127 std::vector<wchar_t> m_TextBuffer; 128 std::vector<u16> m_IndexBuffer; 129 std::vector<SGlyphVertex> m_VertexBuffer; 107 130 }; 108 131 109 132 #endif // INCLUDED_TEXTRENDERER -
gui/CGUI.cpp
951 951 glScissor(clipping.left, g_yres - clipping.bottom, clipping.GetWidth(), clipping.GetHeight()); 952 952 } 953 953 954 CTextRenderer textRenderer(tech->GetShader());954 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 955 955 textRenderer.Translate(0.0f, 0.0f, z); 956 956 957 957 for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin(); … … 969 969 textRenderer.Put((float)(int)(pos.x+it->m_Pos.x), (float)(int)(pos.y+it->m_Pos.y), it->m_String.c_str()); 970 970 } 971 971 972 textRenderer.Render( );972 textRenderer.Render(tech->GetShader()); 973 973 974 for (std::list<SGUIText::SSpriteCall>::iterator it =Text.m_SpriteCalls.begin();975 it !=Text.m_SpriteCalls.end();974 for (std::list<SGUIText::SSpriteCall>::iterator it = Text.m_SpriteCalls.begin(); 975 it != Text.m_SpriteCalls.end(); 976 976 ++it) 977 977 { 978 978 DrawSprite(it->m_Sprite, it->m_CellID, z, it->m_Area + pos); -
gui/CInput.cpp
1104 1104 1105 1105 CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); 1106 1106 1107 CTextRenderer textRenderer(tech->GetShader());1107 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 1108 1108 textRenderer.Font(font_name); 1109 1109 1110 1110 // Set the Z to somewhat more, so we can draw a selected area between the … … 1285 1285 break; 1286 1286 } 1287 1287 1288 CMatrix3D savedTransform = textRenderer.GetTransform();1288 CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform); 1289 1289 1290 1290 // Text must always be drawn in integer values. So we have to convert scroll 1291 1291 if (multiline) … … 1366 1366 textRenderer.Translate(0.f, ls, 0.f); 1367 1367 } 1368 1368 1369 textRenderer.Render( );1369 textRenderer.Render(tech->GetShader()); 1370 1370 1371 1371 if (cliparea != CRect()) 1372 1372 glDisable(GL_SCISSOR_TEST); … … 1390 1390 m_iBufferPos = std::min(m_iBufferPos, (int)caption.size()); 1391 1391 m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, (int)caption.size()); 1392 1392 1393 if (font_name == CStrW())1393 if (font_name.empty()) 1394 1394 { 1395 1395 // Destroy everything stored, there's no font, so there can be 1396 1396 // no data. … … 1437 1437 // when continuing to see how much more after 'to' we need to remake. 1438 1438 int i=0; 1439 1439 for (std::list<SRow>::iterator it=m_CharacterPositions.begin(); 1440 it !=m_CharacterPositions.end(); ++it, ++i)1440 it != m_CharacterPositions.end(); ++it, ++i) 1441 1441 { 1442 1442 if (destroy_row_from_used == false && 1443 1443 it->m_ListStart > from) … … 1534 1534 int delta = to_after - to_before; 1535 1535 if (delta != 0) 1536 1536 { 1537 for (std::list<SRow>::iterator it =current_line;1538 it !=m_CharacterPositions.end();1537 for (std::list<SRow>::iterator it = current_line; 1538 it != m_CharacterPositions.end(); 1539 1539 ++it) 1540 1540 { 1541 1541 it->m_ListStart += delta; -
ps/CConsole.cpp
213 213 214 214 CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); 215 215 textTech->BeginPass(); 216 CTextRenderer textRenderer(textTech->GetShader()); 216 217 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 217 218 textRenderer.Font(CONSOLE_FONT); 218 219 textRenderer.SetTransform(transform); 219 220 220 221 DrawHistory(textRenderer); 221 222 DrawBuffer(textRenderer); 223 textRenderer.Render(textTech->GetShader()); 222 224 223 textRenderer.Render();224 225 225 textTech->EndPass(); 226 226 227 227 glDisable(GL_BLEND); … … 292 292 if (m_fHeight < m_iFontHeight) 293 293 return; 294 294 295 CMatrix3D savedTransform = textRenderer.GetTransform();295 CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform); 296 296 297 297 textRenderer.Translate(2.0f, m_fHeight - (float)m_iFontOffset + 1.0f, 0.0f); 298 298 -
ps/CLogger.cpp
287 287 CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); 288 288 textTech->BeginPass(); 289 289 290 CTextRenderer textRenderer(textTech->GetShader());290 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 291 291 textRenderer.Font(font_name); 292 292 textRenderer.Color(1.0f, 1.0f, 1.0f); 293 293 … … 317 317 textRenderer.Color(1.0f, 0.0f, 0.0f); 318 318 } 319 319 320 CMatrix3D savedTransform = textRenderer.GetTransform();320 CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform); 321 321 322 322 textRenderer.PrintfAdvance(L"[%8.3f] %ls: ", it->time, type); 323 323 // Display the actual message in white so it's more readable … … 329 329 textRenderer.Translate(0.0f, (float)lineSpacing, 0.0f); 330 330 } 331 331 332 textRenderer.Render( );332 textRenderer.Render(textTech->GetShader()); 333 333 334 334 textTech->EndPass(); 335 335 } -
ps/ProfileViewer.cpp
243 243 CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); 244 244 textTech->BeginPass(); 245 245 246 CTextRenderer textRenderer(textTech->GetShader());246 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 247 247 textRenderer.Font(font_name); 248 248 textRenderer.Color(1.0f, 1.0f, 1.0f); 249 249 … … 311 311 textRenderer.Put(0.0f, 0.0f, L"back to parent"); 312 312 } 313 313 314 textRenderer.Render( );314 textRenderer.Render(textTech->GetShader()); 315 315 textTech->EndPass(); 316 316 317 317 glDisable(GL_BLEND); -
renderer/TerrainRenderer.cpp
1006 1006 1007 1007 CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); 1008 1008 tech->BeginPass(); 1009 CTextRenderer textRenderer(tech->GetShader());1010 1009 1010 CTextRenderer& textRenderer = CTextRenderer::Singleton(); 1011 1011 textRenderer.Font(L"mono-stroke-10"); 1012 1012 textRenderer.Color(1.0f, 1.0f, 0.0f); 1013 1013 … … 1014 1014 for (size_t i = 0; i < m->visiblePatches.size(); ++i) 1015 1015 m->visiblePatches[i]->RenderPriorities(textRenderer); 1016 1016 1017 textRenderer.Render( );1017 textRenderer.Render(tech->GetShader()); 1018 1018 tech->EndPass(); 1019 1019 }