Ticket #1984: gui_sprite_patch.diff

File gui_sprite_patch.diff, 17.3 KB (added by Jonas Platte, 11 years ago)
  • source/gui/CGUI.cpp

     
    483483{
    484484    // We can use the map to delete all
    485485    //  now we don't want to cancel all if one Destroy fails
    486     map_pObjects::iterator it;
    487     for (it = m_pAllObjects.begin(); it != m_pAllObjects.end(); ++it)
     486    for (map_pObjects::iterator it = m_pAllObjects.begin(); it != m_pAllObjects.end(); ++it)
    488487    {
    489488        try
    490489        {
     
    500499        delete it->second;
    501500    }
    502501
    503     for (std::map<CStr, CGUISprite>::iterator it2 = m_Sprites.begin(); it2 != m_Sprites.end(); ++it2)
    504         for (std::vector<SGUIImage>::iterator it3 = it2->second.m_Images.begin(); it3 != it2->second.m_Images.end(); ++it3)
    505             delete it3->m_Effects;
    506 
    507502    // Clear all
    508503    m_pAllObjects.clear();
     504    for(std::map<CStr, CGUISprite*>::iterator it = m_Sprites.begin(); it != m_Sprites.end(); ++it)
     505        delete it->second;
    509506    m_Sprites.clear();
    510507    m_Icons.clear();
    511508}
     
    14481445void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile)
    14491446{
    14501447    // Sprite object we're adding
    1451     CGUISprite sprite;
     1448    CGUISprite* Sprite = new CGUISprite;
    14521449   
    14531450    // and what will be its reference name
    14541451    CStr name;
     
    14811478
    14821479        if (ElementName == "image")
    14831480        {
    1484             Xeromyces_ReadImage(child, pFile, sprite);
     1481            Xeromyces_ReadImage(child, pFile, *Sprite);
    14851482        }
    14861483        else if (ElementName == "effect")
    14871484        {
     
    15041501    // Apply the effects to every image (unless the image overrides it with
    15051502    // different effects)
    15061503    if (effects)
    1507         for (std::vector<SGUIImage>::iterator it = sprite.m_Images.begin(); it != sprite.m_Images.end(); ++it)
    1508             if (! it->m_Effects)
    1509                 it->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later
     1504        for (std::vector<SGUIImage*>::iterator it = Sprite->m_Images.begin(); it != Sprite->m_Images.end(); ++it)
     1505            if (! (*it)->m_Effects)
     1506                (*it)->m_Effects = new SGUIImageEffects(*effects); // do a copy just so it can be deleted correctly later
    15101507
    15111508    delete effects;
    15121509
     
    15141511    //  Add Sprite
    15151512    //
    15161513
    1517     m_Sprites[name] = sprite;
     1514    m_Sprites[name] = Sprite;
    15181515}
    15191516
    15201517void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent)
    15211518{
    15221519
    15231520    // Image object we're adding
    1524     SGUIImage image;
     1521    SGUIImage* Image = new SGUIImage;
    15251522   
    15261523    // Set defaults to "0 0 100% 100%"
    1527     image.m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
    1528     image.m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
     1524    Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
     1525    Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
    15291526   
    15301527    // TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor)
    15311528
     
    15431540
    15441541        if (attr_name == "texture")
    15451542        {
    1546             image.m_TextureName = VfsPath("art/textures/ui") / attr_value;
     1543            Image->m_TextureName = VfsPath("art/textures/ui") / attr_value;
    15471544        }
    15481545        else
    15491546        if (attr_name == "size")
     
    15511548            CClientArea ca;
    15521549            if (!GUI<CClientArea>::ParseString(attr_value, ca))
    15531550                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1554             else image.m_Size = ca;
     1551            else Image->m_Size = ca;
    15551552        }
    15561553        else
    15571554        if (attr_name == "texture_size")
     
    15591556            CClientArea ca;
    15601557            if (!GUI<CClientArea>::ParseString(attr_value, ca))
    15611558                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1562             else image.m_TextureSize = ca;
     1559            else Image->m_TextureSize = ca;
    15631560        }
    15641561        else
    15651562        if (attr_name == "real_texture_placement")
     
    15671564            CRect rect;
    15681565            if (!GUI<CRect>::ParseString(attr_value, rect))
    15691566                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1570             else image.m_TexturePlacementInFile = rect;
     1567            else Image->m_TexturePlacementInFile = rect;
    15711568        }
    15721569        else
    15731570        if (attr_name == "cell_size")
     
    15751572            CSize size;
    15761573            if (!GUI<CSize>::ParseString(attr_value, size))
    15771574                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1578             else image.m_CellSize = size;
     1575            else Image->m_CellSize = size;
    15791576        }
    15801577        else
    15811578        if (attr_name == "fixed_h_aspect_ratio")
     
    15831580            float val;
    15841581            if (!GUI<float>::ParseString(attr_value, val))
    15851582                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1586             else image.m_FixedHAspectRatio = val;
     1583            else Image->m_FixedHAspectRatio = val;
    15871584        }
    15881585        else
    15891586        if (attr_name == "round_coordinates")
     
    15911588            bool b;
    15921589            if (!GUI<bool>::ParseString(attr_value, b))
    15931590                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1594             else image.m_RoundCoordinates = b;
     1591            else Image->m_RoundCoordinates = b;
    15951592        }
    15961593        else
    15971594        if (attr_name == "wrap_mode")
    15981595        {
    15991596            if (attr_value == L"repeat")
    1600                 image.m_WrapMode = GL_REPEAT;
     1597                Image->m_WrapMode = GL_REPEAT;
    16011598            else if (attr_value == L"mirrored_repeat")
    1602                 image.m_WrapMode = GL_MIRRORED_REPEAT;
     1599                Image->m_WrapMode = GL_MIRRORED_REPEAT;
    16031600            else if (attr_value == L"clamp_to_edge")
    1604                 image.m_WrapMode = GL_CLAMP_TO_EDGE;
     1601                Image->m_WrapMode = GL_CLAMP_TO_EDGE;
    16051602            else
    16061603                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    16071604        }
     
    16111608            float z_level;
    16121609            if (!GUI<float>::ParseString(attr_value, z_level))
    16131610                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1614             else image.m_DeltaZ = z_level/100.f;
     1611            else Image->m_DeltaZ = z_level/100.f;
    16151612        }
    16161613        else
    16171614        if (attr_name == "backcolor")
     
    16191616            CColor color;
    16201617            if (!GUI<CColor>::ParseString(attr_value, color))
    16211618                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1622             else image.m_BackColor = color;
     1619            else Image->m_BackColor = color;
    16231620        }
    16241621        else
    16251622        if (attr_name == "bordercolor")
     
    16271624            CColor color;
    16281625            if (!GUI<CColor>::ParseString(attr_value, color))
    16291626                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1630             else image.m_BorderColor = color;
     1627            else Image->m_BorderColor = color;
    16311628        }
    16321629        else
    16331630        if (attr_name == "border")
     
    16351632            bool b;
    16361633            if (!GUI<bool>::ParseString(attr_value, b))
    16371634                LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str());
    1638             else image.m_Border = b;
     1635            else Image->m_Border = b;
    16391636        }
    16401637        else
    16411638        {
     
    16511648        CStr ElementName (pFile->GetElementString(child.GetNodeName()));
    16521649        if (ElementName == "effect")
    16531650        {
    1654             if (image.m_Effects)
     1651            if (Image->m_Effects)
    16551652            {
    16561653                LOGERROR(L"GUI <image> must not have more than one <effect>");
    16571654            }
    16581655            else
    16591656            {
    1660                 image.m_Effects = new SGUIImageEffects;
    1661                 Xeromyces_ReadEffects(child, pFile, *image.m_Effects);
     1657                Image->m_Effects = new SGUIImageEffects;
     1658                Xeromyces_ReadEffects(child, pFile, *Image->m_Effects);
    16621659            }
    16631660        }
    16641661        else
     
    16711668    //  Input
    16721669    //
    16731670
    1674     parent.AddImage(image);
     1671    parent.AddImage(Image);
    16751672}
    16761673
    16771674void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImageEffects &effects)
  • source/gui/CGUI.h

     
    670670    //--------------------------------------------------------
    671671
    672672    // Sprites
    673     std::map<CStr, CGUISprite> m_Sprites;
     673    std::map<CStr, CGUISprite*> m_Sprites;
    674674
    675675    // Styles
    676676    std::map<CStr, SGUIStyle> m_Styles;
  • source/gui/CGUISprite.cpp

     
    1818#include "precompiled.h"
    1919#include "CGUISprite.h"
    2020
    21 void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map<CStr, CGUISprite> &Sprites, float Z) const
     21CGUISprite::~CGUISprite()
    2222{
     23    for (std::vector<SGUIImage*>::iterator it = m_Images.begin(); it != m_Images.end(); it++)
     24    {
     25        delete *it;
     26    }
     27}
     28
     29void CGUISprite::AddImage(SGUIImage* image)
     30{
     31    m_Images.push_back(image);
     32}
     33
     34void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map<CStr, CGUISprite*> &Sprites, float Z) const
     35{
    2336    if (m_CachedSize != Size || m_CachedCellID != CellID)
    2437    {
    2538        GUIRenderer::UpdateDrawCallCache(m_DrawCallCache, m_SpriteName, Size, CellID, Sprites);
  • source/gui/CGUISprite.h

     
    6969    bool m_Greyscale;
    7070};
    7171
    72 
    7372/**
    7473 * A CGUISprite is actually a collage of several <b>real</b>
    7574 * sprites, this struct represents is such real sprite.
     
    8180        m_Effects(NULL), m_Border(false), m_DeltaZ(0.f)
    8281    {
    8382    }
     83   
     84    ~SGUIImage()
     85    {
     86        delete m_Effects;
     87    }
    8488
    8589    // Filename of the texture
    8690    VfsPath         m_TextureName;
     
    135139     * way of declaring delta-z.
    136140     */
    137141    float           m_DeltaZ;
     142
     143    NONCOPYABLE(SGUIImage);
    138144};
    139145
    140 
    141146/**
    142147 * The GUI sprite, is actually several real sprites (images)
    143148 * like a collage. View the section \<sprites\> in the GUI
     
    151156{
    152157public:
    153158    CGUISprite() {}
    154     virtual ~CGUISprite() {}
     159    virtual ~CGUISprite();
    155160
    156161    /**
    157162     * Adds an image to the sprite collage.
    158163     *
    159164     * @param image Adds this image to the sprite collage.
    160165     */
    161     void AddImage(const SGUIImage &image) { m_Images.push_back(image); }
     166    void AddImage(SGUIImage*);
    162167
    163168    /// List of images
    164     std::vector<SGUIImage> m_Images;
     169    std::vector<SGUIImage*> m_Images;
     170
     171    NONCOPYABLE(CGUISprite);
    165172};
    166173
    167174#include "GUIRenderer.h"
     
    176183    CGUISpriteInstance(const CStr& SpriteName);
    177184    CGUISpriteInstance(const CGUISpriteInstance &Sprite);
    178185    CGUISpriteInstance &operator=(const CStr& SpriteName);
    179     void Draw(CRect Size, int CellID, std::map<CStr, CGUISprite> &Sprites, float Z) const;
     186    void Draw(CRect Size, int CellID, std::map<CStr, CGUISprite*>& Sprites, float Z) const;
    180187    void Invalidate();
    181188    bool IsEmpty() const;
    182189    const CStr& GetName() { return m_SpriteName; }
  • source/gui/GUIRenderer.cpp

     
    5656}
    5757
    5858
    59 void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map<CStr, CGUISprite> &Sprites)
     59void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map<CStr, CGUISprite*> &Sprites)
    6060{
    6161    // This is called only when something has changed (like the size of the
    6262    // sprite), so it doesn't need to be particularly efficient.
     
    7171        return;
    7272
    7373
    74     std::map<CStr, CGUISprite>::iterator it (Sprites.find(SpriteName));
     74    std::map<CStr, CGUISprite*>::iterator it (Sprites.find(SpriteName));
    7575    if (it == Sprites.end())
    7676    {
    7777        // Sprite not found. Check whether this a special sprite:
     
    8484        if (SpriteName.substr(0, 10) == "stretched:")
    8585        {
    8686            // TODO: Should check (nicely) that this is a valid file?
    87             SGUIImage Image;
     87            SGUIImage* Image = new SGUIImage;
    8888           
    8989            // Allow grayscale images for disabled portraits
    9090            if (SpriteName.substr(10, 10) == "grayscale:")
    9191            {
    92                 Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(20));
    93                 Image.m_Effects = new SGUIImageEffects;
    94                 Image.m_Effects->m_Greyscale = true;
     92                Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(20));
     93                Image->m_Effects = new SGUIImageEffects;
     94                Image->m_Effects->m_Greyscale = true;
    9595            }
    9696            else
    9797            {
    98                 Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(10));
     98                Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(10));
    9999            }
    100100
    101101            CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
    102             Image.m_Size = ca;
    103             Image.m_TextureSize = ca;
     102            Image->m_Size = ca;
     103            Image->m_TextureSize = ca;
    104104
    105             CGUISprite Sprite;
    106             Sprite.AddImage(Image);
     105            CGUISprite* Sprite = new CGUISprite;
     106            Sprite->AddImage(Image);
    107107
    108108            Sprites[SpriteName] = Sprite;
    109109           
     
    113113        else if (SpriteName.substr(0, 8) == "cropped:")
    114114        {
    115115            // TODO: Should check (nicely) that this is a valid file?
    116             SGUIImage Image;
     116            SGUIImage* Image = new SGUIImage;
    117117
    118118            double xRatio = SpriteName.BeforeFirst(",").AfterLast("(").ToDouble();
    119119            double yRatio = SpriteName.BeforeFirst(")").AfterLast(",").ToDouble();
    120120           
    121121            int PathStart = SpriteName.Find(")") + 1;
    122122           
    123             Image.m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(PathStart));
     123            Image->m_TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.substr(PathStart));
    124124
    125125            CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
    126126            CClientArea cb(CRect(0, 0, 0, 0), CRect(0, 0, 100/xRatio, 100/yRatio));
    127             Image.m_Size = ca;
    128             Image.m_TextureSize = cb;
     127            Image->m_Size = ca;
     128            Image->m_TextureSize = cb;
    129129
    130             CGUISprite Sprite;
    131             Sprite.AddImage(Image);
     130            CGUISprite* Sprite = new CGUISprite;
     131            Sprite->AddImage(Image);
    132132
    133133            Sprites[SpriteName] = Sprite;
    134134           
     
    147147                return;
    148148            }
    149149
    150             SGUIImage image;
     150            SGUIImage* Image = new SGUIImage;
    151151
    152             image.m_BackColor = color;
     152            Image->m_BackColor = color;
    153153
    154154            CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100));
    155             image.m_Size = ca;
    156             image.m_TextureSize = ca;
     155            Image->m_Size = ca;
     156            Image->m_TextureSize = ca;
    157157
    158             CGUISprite Sprite;
    159             Sprite.AddImage(image);
     158            CGUISprite* Sprite = new CGUISprite;
     159            Sprite->AddImage(Image);
    160160
    161161            Sprites[SpriteName] = Sprite;
    162162
     
    171171        }
    172172    }
    173173
    174     Calls.reserve(it->second.m_Images.size());
     174    Calls.reserve(it->second->m_Images.size());
    175175
    176176    // Iterate through all the sprite's images, loading the texture and
    177177    // calculating the texture coordinates
    178     std::vector<SGUIImage>::const_iterator cit;
    179     for (cit = it->second.m_Images.begin(); cit != it->second.m_Images.end(); ++cit)
     178    std::vector<SGUIImage*>::const_iterator cit;
     179    for (cit = it->second->m_Images.begin(); cit != it->second->m_Images.end(); ++cit)
    180180    {
    181         SDrawCall Call(&*cit); // pointers are safe since we never modify sprites/images after startup
     181        SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup
    182182
    183         CRect ObjectSize = cit->m_Size.GetClientArea(Size);
     183        CRect ObjectSize = (*cit)->m_Size.GetClientArea(Size);
    184184
    185185        if (ObjectSize.GetWidth() == 0.0 || ObjectSize.GetHeight() == 0.0)
    186186        {
     
    189189        }
    190190
    191191        Call.m_Vertices = ObjectSize;
    192         if (cit->m_RoundCoordinates)
     192        if ((*cit)->m_RoundCoordinates)
    193193        {
    194194            // Round the vertex coordinates to integers, to avoid ugly filtering artifacts
    195195            Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f);
     
    198198            Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f);
    199199        }
    200200
    201         if (! cit->m_TextureName.empty())
     201        if (!(*cit)->m_TextureName.empty())
    202202        {
    203             CTextureProperties textureProps(cit->m_TextureName);
    204             textureProps.SetWrap(cit->m_WrapMode);
     203            CTextureProperties textureProps((*cit)->m_TextureName);
     204            textureProps.SetWrap((*cit)->m_WrapMode);
    205205            CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
    206206            texture->Prefetch();
    207207            Call.m_HasTexture = true;
     
    216216        {
    217217            Call.m_HasTexture = false;
    218218            // Enable blending if it's transparent (allowing a little error in the calculations)
    219             Call.m_EnableBlending = !(fabs(cit->m_BackColor.a - 1.0f) < 0.0000001f);
     219            Call.m_EnableBlending = !(fabs((*cit)->m_BackColor.a - 1.0f) < 0.0000001f);
    220220        }
    221221
    222         Call.m_BackColor = cit->m_BackColor;
    223         Call.m_BorderColor = cit->m_Border ? cit->m_BorderColor : CColor();
    224         Call.m_DeltaZ = cit->m_DeltaZ;
     222        Call.m_BackColor = (*cit)->m_BackColor;
     223        Call.m_BorderColor = (*cit)->m_Border ? (*cit)->m_BorderColor : CColor();
     224        Call.m_DeltaZ = (*cit)->m_DeltaZ;
    225225
    226226        if (!Call.m_HasTexture)
    227227        {
    228228            Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect("gui_solid");
    229229        }
    230         else if (cit->m_Effects)
     230        else if ((*cit)->m_Effects)
    231231        {
    232             if (cit->m_Effects->m_AddColor != CColor())
     232            if ((*cit)->m_Effects->m_AddColor != CColor())
    233233            {
    234234                Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect("gui_add");
    235                 Call.m_ShaderColorParameter = cit->m_Effects->m_AddColor;
     235                Call.m_ShaderColorParameter = (*cit)->m_Effects->m_AddColor;
    236236                // Always enable blending if something's being subtracted from
    237237                // the alpha channel
    238                 if (cit->m_Effects->m_AddColor.a < 0.f)
     238                if ((*cit)->m_Effects->m_AddColor.a < 0.f)
    239239                    Call.m_EnableBlending = true;
    240240            }
    241             else if (cit->m_Effects->m_Greyscale)
     241            else if ((*cit)->m_Effects->m_Greyscale)
    242242            {
    243243                Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect("gui_grayscale");
    244244            }
  • source/gui/GUIRenderer.h

     
    7777
    7878namespace GUIRenderer
    7979{
    80     void UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map<CStr, CGUISprite> &Sprites);
     80    void UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect& Size, int CellID, std::map<CStr, CGUISprite*> &Sprites);
    8181
    8282    void Draw(DrawCalls &Calls, float Z);
    8383}