Ticket #2027: CTextRenderer_allocs.patch

File CTextRenderer_allocs.patch, 15.9 KB (added by Jorma Rebane, 11 years ago)

Initial release, waiting for review.

  • graphics/TextRenderer.cpp

     
    2525
    2626extern int g_xres, g_yres;
    2727
    28 CTextRenderer::CTextRenderer(const CShaderProgramPtr& shader) :
    29     m_Shader(shader)
     28static CTextRenderer* g_TextRenderer = NULL;
     29
     30CTextRenderer& CTextRenderer::Singleton()
    3031{
    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;
    3443}
    3544
     45CTextRenderer::CTextRenderer()
     46{
     47}
     48
     49CTextRenderer::~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
    3658void CTextRenderer::ResetTransform()
    3759{
    3860    m_Transform.SetIdentity();
     
    4466    m_Transform = proj * m_Transform;
    4567}
    4668
    47 CMatrix3D CTextRenderer::GetTransform()
     69void CTextRenderer::GetTransform(CMatrix3D& out)
    4870{
    49     return m_Transform;
     71    out = m_Transform;
    5072}
    5173
    5274void CTextRenderer::SetTransform(const CMatrix3D& transform)
     
    5678
    5779void CTextRenderer::Translate(float x, float y, float z)
    5880{
    59     CMatrix3D m;
    60     m.SetTranslation(x, y, z);
    61     m_Transform = m_Transform * m;
     81    m_Transform.PostTranslate(x, y, z);
    6282}
    6383
    6484void CTextRenderer::Color(const CColor& color)
     
    7393
    7494void CTextRenderer::Font(const CStrW& font)
    7595{
    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
    78101
    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    }
    80111}
    81112
    82113void CTextRenderer::PrintfAdvance(const wchar_t* fmt, ...)
    83114{
    84     wchar_t buf[1024] = {0};
     115    wchar_t buf[1024];
    85116
    86117    va_list args;
    87118    va_start(args, fmt);
     
    90121
    91122    if (ret < 0)
    92123        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);
    95126}
    96127
    97128
    98129void CTextRenderer::PrintfAt(float x, float y, const wchar_t* fmt, ...)
    99130{
    100     wchar_t buf[1024] = {0};
     131    wchar_t buf[1024];
    101132
    102133    va_list args;
    103134    va_start(args, fmt);
     
    106137
    107138    if (ret < 0)
    108139        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);
    111142}
    112143
    113144void CTextRenderer::PutAdvance(const wchar_t* buf)
     
    127158    CMatrix3D translate;
    128159    translate.SetTranslation(x, y, 0.0f);
    129160
     161    int text_index = m_TextBuffer.size();
     162    int text_length = wcslen(buf);
     163
    130164    SBatch batch;
    131165    batch.transform = m_Transform * translate;
    132166    batch.color = m_Color;
    133167    batch.font = m_Font;
    134     batch.text = buf;
     168    batch.text_index = text_index;
     169    batch.text_length = text_length;
    135170    m_Batches.push_back(batch);
     171
     172    m_TextBuffer.resize(text_index + text_length);
     173    wmemcpy(&m_TextBuffer[text_index], buf, text_length);
    136174}
    137175
    138 struct t2f_v2i
    139 {
    140     t2f_v2i() : u(0), v(0), x(0), y(0) { }
    141     float u, v;
    142     i16 x, y;
    143 };
    144176
    145 void CTextRenderer::Render()
     177void CTextRenderer::Render(CShaderProgramPtr shader)
    146178{
    147     std::vector<u16> indexes;
    148     std::vector<t2f_v2i> vertexes;
    149 
    150179    for (size_t i = 0; i < m_Batches.size(); ++i)
    151180    {
    152         SBatch& batch = m_Batches[i];
     181        const SBatch& batch = m_Batches[i];
    153182
    154         if (batch.text.empty()) // avoid zero-length arrays
     183        if (batch.text_length == 0) // avoid zero-length arrays
    155184            continue;
    156185
    157186        const std::map<u16, UnifontGlyphData>& glyphs = batch.font->GetGlyphs();
    158187
    159         m_Shader->BindTexture("tex", batch.font->GetTexture());
     188        shader->BindTexture("tex", batch.font->GetTexture());
     189        shader->Uniform("transform", batch.transform);
    160190
    161         m_Shader->Uniform("transform", batch.transform);
    162 
    163191        // ALPHA-only textures will have .rgb sampled as 0, so we need to
    164192        // replace it with white (but not affect RGBA textures)
    165193        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));
    167195        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));
    169197
    170         m_Shader->Uniform("colorMul", batch.color);
     198        shader->Uniform("colorMul", batch.color);
    171199
    172         vertexes.clear();
    173         vertexes.resize(batch.text.size()*4);
    174200
    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);
    177203
     204        const wchar_t* text = &m_TextBuffer[batch.text_index];
     205        SGlyphVertex* vertices = &m_VertexBuffer[0];
     206        u16* indices = &m_IndexBuffer[0];
     207
    178208        i16 x = 0;
    179         for (size_t i = 0; i < batch.text.size(); ++i)
     209        for (int i = 0; i < batch.text_length; ++i)
    180210        {
    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]);
    182212
    183213            if (it == glyphs.end())
    184214                it = glyphs.find(0xFFFD); // Use the missing glyph symbol
     
    188218
    189219            const UnifontGlyphData& g = it->second;
    190220
    191             vertexes[i*4].u = g.u1;
    192             vertexes[i*4].v = g.v0;
    193             vertexes[i*4].x = g.x1 + x;
    194             vertexes[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;
    195225
    196             vertexes[i*4+1].u = g.u0;
    197             vertexes[i*4+1].v = g.v0;
    198             vertexes[i*4+1].x = g.x0 + x;
    199             vertexes[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;
    200230
    201             vertexes[i*4+2].u = g.u0;
    202             vertexes[i*4+2].v = g.v1;
    203             vertexes[i*4+2].x = g.x0 + x;
    204             vertexes[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;
    205235
    206             vertexes[i*4+3].u = g.u1;
    207             vertexes[i*4+3].v = g.v1;
    208             vertexes[i*4+3].x = g.x1 + x;
    209             vertexes[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;
    210240
    211             indexes[i*6+0] = i*4+0;
    212             indexes[i*6+1] = i*4+1;
    213             indexes[i*6+2] = i*4+2;
    214             indexes[i*6+3] = i*4+2;
    215             indexes[i*6+4] = i*4+3;
    216             indexes[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;
    217247
    218248            x += g.xadvance;
    219249        }
    220250
    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);
    223253
    224         glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, &indexes[0]);
     254        glDrawElements(GL_TRIANGLES, m_IndexBuffer.size(), GL_UNSIGNED_SHORT, indices);
    225255    }
    226256
    227257    m_Batches.clear();
     258    m_VertexBuffer.clear();
     259    m_IndexBuffer.clear();
    228260}
  • graphics/TextRenderer.h

     
    2727
    2828class CTextRenderer
    2929{
     30    NONCOPYABLE(CTextRenderer);
     31    CTextRenderer();
     32    ~CTextRenderer();
    3033public:
    31     CTextRenderer(const CShaderProgramPtr& shader);
    3234
    3335    /**
     36     * @return Pointer to the TextRenderer
     37     */
     38    static CTextRenderer& Singleton();
     39
     40    /**
    3441     * Reset the text transform to the default, with (0,0) in the top-left of the screen.
    3542     */
    3643    void ResetTransform();
    3744
    38     CMatrix3D GetTransform();
     45    /**
     46     * Gets the transformation matrix
     47     */
     48    void GetTransform(CMatrix3D& out);
    3949   
     50    /**
     51     * Sets the transformation matrix
     52     */
    4053    void SetTransform(const CMatrix3D& transform);
    4154
    4255    void Translate(float x, float y, float z);
     
    8396    /**
    8497     * Render all of the previously printed text calls.
    8598     */
    86     void Render();
     99    void Render(CShaderProgramPtr shader);
    87100
    88101private:
     102
    89103    struct SBatch
    90104    {
    91105        CMatrix3D transform;
    92106        CColor color;
    93         shared_ptr<CFont> font;
    94         std::wstring text;
     107        CFont* font;
     108        int text_index;
     109        int text_length;
    95110    };
    96111
    97     CShaderProgramPtr m_Shader;
     112    struct SGlyphVertex
     113    {
     114        float u, v; // 2x float uvs
     115        i16 x, y; // 2x int screen xy
     116    };
    98117
    99     CMatrix3D m_Transform;
    100118
    101     CColor m_Color;
    102     shared_ptr<CFont> m_Font;
     119    CMatrix3D   m_Transform;
     120    CColor      m_Color;
     121    CFont*      m_Font; // current font
    103122
    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
    105125
    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;
    107130};
    108131
    109132#endif // INCLUDED_TEXTRENDERER
  • gui/CGUI.cpp

     
    951951        glScissor(clipping.left, g_yres - clipping.bottom, clipping.GetWidth(), clipping.GetHeight());
    952952    }
    953953
    954     CTextRenderer textRenderer(tech->GetShader());
     954    CTextRenderer& textRenderer = CTextRenderer::Singleton();
    955955    textRenderer.Translate(0.0f, 0.0f, z);
    956956
    957957    for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin();
     
    969969        textRenderer.Put((float)(int)(pos.x+it->m_Pos.x), (float)(int)(pos.y+it->m_Pos.y), it->m_String.c_str());
    970970    }
    971971
    972     textRenderer.Render();
     972    textRenderer.Render(tech->GetShader());
    973973
    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();
    976976         ++it)
    977977    {
    978978        DrawSprite(it->m_Sprite, it->m_CellID, z, it->m_Area + pos);
  • gui/CInput.cpp

     
    11041104
    11051105        CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
    11061106       
    1107         CTextRenderer textRenderer(tech->GetShader());
     1107        CTextRenderer& textRenderer = CTextRenderer::Singleton();
    11081108        textRenderer.Font(font_name);
    11091109
    11101110        // Set the Z to somewhat more, so we can draw a selected area between the
     
    12851285                        break;
    12861286                }
    12871287
    1288                 CMatrix3D savedTransform = textRenderer.GetTransform();
     1288                CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform);
    12891289               
    12901290                // Text must always be drawn in integer values. So we have to convert scroll
    12911291                if (multiline)
     
    13661366            textRenderer.Translate(0.f, ls, 0.f);   
    13671367        }
    13681368
    1369         textRenderer.Render();
     1369        textRenderer.Render(tech->GetShader());
    13701370
    13711371        if (cliparea != CRect())
    13721372            glDisable(GL_SCISSOR_TEST);
     
    13901390    m_iBufferPos = std::min(m_iBufferPos, (int)caption.size());
    13911391    m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, (int)caption.size());
    13921392
    1393     if (font_name == CStrW())
     1393    if (font_name.empty())
    13941394    {
    13951395        // Destroy everything stored, there's no font, so there can be
    13961396        //  no data.
     
    14371437        //  when continuing to see how much more after 'to' we need to remake.
    14381438        int i=0;
    14391439        for (std::list<SRow>::iterator it=m_CharacterPositions.begin();
    1440              it!=m_CharacterPositions.end(); ++it, ++i)
     1440             it != m_CharacterPositions.end(); ++it, ++i)
    14411441        {
    14421442            if (destroy_row_from_used == false &&
    14431443                it->m_ListStart > from)
     
    15341534        int delta = to_after - to_before;
    15351535        if (delta != 0)
    15361536        {
    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();
    15391539                 ++it)
    15401540            {
    15411541                it->m_ListStart += delta;
  • ps/CConsole.cpp

     
    213213   
    214214    CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
    215215    textTech->BeginPass();
    216     CTextRenderer textRenderer(textTech->GetShader());
     216
     217    CTextRenderer& textRenderer = CTextRenderer::Singleton();
    217218    textRenderer.Font(CONSOLE_FONT);
    218219    textRenderer.SetTransform(transform);
    219220
    220221    DrawHistory(textRenderer);
    221222    DrawBuffer(textRenderer);
     223    textRenderer.Render(textTech->GetShader());
    222224
    223     textRenderer.Render();
    224 
    225225    textTech->EndPass();
    226226
    227227    glDisable(GL_BLEND);
     
    292292    if (m_fHeight < m_iFontHeight)
    293293        return;
    294294
    295     CMatrix3D savedTransform = textRenderer.GetTransform();
     295    CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform);
    296296
    297297    textRenderer.Translate(2.0f, m_fHeight - (float)m_iFontOffset + 1.0f, 0.0f);
    298298
  • ps/CLogger.cpp

     
    287287    CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
    288288    textTech->BeginPass();
    289289
    290     CTextRenderer textRenderer(textTech->GetShader());
     290    CTextRenderer& textRenderer = CTextRenderer::Singleton();
    291291    textRenderer.Font(font_name);
    292292    textRenderer.Color(1.0f, 1.0f, 1.0f);
    293293
     
    317317            textRenderer.Color(1.0f, 0.0f, 0.0f);
    318318        }
    319319
    320         CMatrix3D savedTransform = textRenderer.GetTransform();
     320        CMatrix3D savedTransform; textRenderer.GetTransform(savedTransform);
    321321
    322322        textRenderer.PrintfAdvance(L"[%8.3f] %ls: ", it->time, type);
    323323        // Display the actual message in white so it's more readable
     
    329329        textRenderer.Translate(0.0f, (float)lineSpacing, 0.0f);
    330330    }
    331331
    332     textRenderer.Render();
     332    textRenderer.Render(textTech->GetShader());
    333333
    334334    textTech->EndPass();
    335335}
  • ps/ProfileViewer.cpp

     
    243243    CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
    244244    textTech->BeginPass();
    245245
    246     CTextRenderer textRenderer(textTech->GetShader());
     246    CTextRenderer& textRenderer = CTextRenderer::Singleton();
    247247    textRenderer.Font(font_name);
    248248    textRenderer.Color(1.0f, 1.0f, 1.0f);
    249249
     
    311311        textRenderer.Put(0.0f, 0.0f, L"back to parent");
    312312    }
    313313
    314     textRenderer.Render();
     314    textRenderer.Render(textTech->GetShader());
    315315    textTech->EndPass();
    316316
    317317    glDisable(GL_BLEND);
  • renderer/TerrainRenderer.cpp

     
    10061006
    10071007    CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
    10081008    tech->BeginPass();
    1009     CTextRenderer textRenderer(tech->GetShader());
    10101009
     1010    CTextRenderer& textRenderer = CTextRenderer::Singleton();
    10111011    textRenderer.Font(L"mono-stroke-10");
    10121012    textRenderer.Color(1.0f, 1.0f, 0.0f);
    10131013
     
    10141014    for (size_t i = 0; i < m->visiblePatches.size(); ++i)
    10151015        m->visiblePatches[i]->RenderPriorities(textRenderer);
    10161016
    1017     textRenderer.Render();
     1017    textRenderer.Render(tech->GetShader());
    10181018    tech->EndPass();
    10191019}