Ticket #1984: gui_sprite_patch.diff
File gui_sprite_patch.diff, 17.3 KB (added by , 11 years ago) |
---|
-
source/gui/CGUI.cpp
483 483 { 484 484 // We can use the map to delete all 485 485 // 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) 488 487 { 489 488 try 490 489 { … … 500 499 delete it->second; 501 500 } 502 501 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 507 502 // Clear all 508 503 m_pAllObjects.clear(); 504 for(std::map<CStr, CGUISprite*>::iterator it = m_Sprites.begin(); it != m_Sprites.end(); ++it) 505 delete it->second; 509 506 m_Sprites.clear(); 510 507 m_Icons.clear(); 511 508 } … … 1448 1445 void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) 1449 1446 { 1450 1447 // Sprite object we're adding 1451 CGUISprite sprite;1448 CGUISprite* Sprite = new CGUISprite; 1452 1449 1453 1450 // and what will be its reference name 1454 1451 CStr name; … … 1481 1478 1482 1479 if (ElementName == "image") 1483 1480 { 1484 Xeromyces_ReadImage(child, pFile, sprite);1481 Xeromyces_ReadImage(child, pFile, *Sprite); 1485 1482 } 1486 1483 else if (ElementName == "effect") 1487 1484 { … … 1504 1501 // Apply the effects to every image (unless the image overrides it with 1505 1502 // different effects) 1506 1503 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 later1504 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 1510 1507 1511 1508 delete effects; 1512 1509 … … 1514 1511 // Add Sprite 1515 1512 // 1516 1513 1517 m_Sprites[name] = sprite;1514 m_Sprites[name] = Sprite; 1518 1515 } 1519 1516 1520 1517 void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent) 1521 1518 { 1522 1519 1523 1520 // Image object we're adding 1524 SGUIImage image;1521 SGUIImage* Image = new SGUIImage; 1525 1522 1526 1523 // 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)); 1529 1526 1530 1527 // TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor) 1531 1528 … … 1543 1540 1544 1541 if (attr_name == "texture") 1545 1542 { 1546 image.m_TextureName = VfsPath("art/textures/ui") / attr_value;1543 Image->m_TextureName = VfsPath("art/textures/ui") / attr_value; 1547 1544 } 1548 1545 else 1549 1546 if (attr_name == "size") … … 1551 1548 CClientArea ca; 1552 1549 if (!GUI<CClientArea>::ParseString(attr_value, ca)) 1553 1550 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; 1555 1552 } 1556 1553 else 1557 1554 if (attr_name == "texture_size") … … 1559 1556 CClientArea ca; 1560 1557 if (!GUI<CClientArea>::ParseString(attr_value, ca)) 1561 1558 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; 1563 1560 } 1564 1561 else 1565 1562 if (attr_name == "real_texture_placement") … … 1567 1564 CRect rect; 1568 1565 if (!GUI<CRect>::ParseString(attr_value, rect)) 1569 1566 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; 1571 1568 } 1572 1569 else 1573 1570 if (attr_name == "cell_size") … … 1575 1572 CSize size; 1576 1573 if (!GUI<CSize>::ParseString(attr_value, size)) 1577 1574 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; 1579 1576 } 1580 1577 else 1581 1578 if (attr_name == "fixed_h_aspect_ratio") … … 1583 1580 float val; 1584 1581 if (!GUI<float>::ParseString(attr_value, val)) 1585 1582 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; 1587 1584 } 1588 1585 else 1589 1586 if (attr_name == "round_coordinates") … … 1591 1588 bool b; 1592 1589 if (!GUI<bool>::ParseString(attr_value, b)) 1593 1590 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; 1595 1592 } 1596 1593 else 1597 1594 if (attr_name == "wrap_mode") 1598 1595 { 1599 1596 if (attr_value == L"repeat") 1600 image.m_WrapMode = GL_REPEAT;1597 Image->m_WrapMode = GL_REPEAT; 1601 1598 else if (attr_value == L"mirrored_repeat") 1602 image.m_WrapMode = GL_MIRRORED_REPEAT;1599 Image->m_WrapMode = GL_MIRRORED_REPEAT; 1603 1600 else if (attr_value == L"clamp_to_edge") 1604 image.m_WrapMode = GL_CLAMP_TO_EDGE;1601 Image->m_WrapMode = GL_CLAMP_TO_EDGE; 1605 1602 else 1606 1603 LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); 1607 1604 } … … 1611 1608 float z_level; 1612 1609 if (!GUI<float>::ParseString(attr_value, z_level)) 1613 1610 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; 1615 1612 } 1616 1613 else 1617 1614 if (attr_name == "backcolor") … … 1619 1616 CColor color; 1620 1617 if (!GUI<CColor>::ParseString(attr_value, color)) 1621 1618 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; 1623 1620 } 1624 1621 else 1625 1622 if (attr_name == "bordercolor") … … 1627 1624 CColor color; 1628 1625 if (!GUI<CColor>::ParseString(attr_value, color)) 1629 1626 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; 1631 1628 } 1632 1629 else 1633 1630 if (attr_name == "border") … … 1635 1632 bool b; 1636 1633 if (!GUI<bool>::ParseString(attr_value, b)) 1637 1634 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; 1639 1636 } 1640 1637 else 1641 1638 { … … 1651 1648 CStr ElementName (pFile->GetElementString(child.GetNodeName())); 1652 1649 if (ElementName == "effect") 1653 1650 { 1654 if ( image.m_Effects)1651 if (Image->m_Effects) 1655 1652 { 1656 1653 LOGERROR(L"GUI <image> must not have more than one <effect>"); 1657 1654 } 1658 1655 else 1659 1656 { 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); 1662 1659 } 1663 1660 } 1664 1661 else … … 1671 1668 // Input 1672 1669 // 1673 1670 1674 parent.AddImage( image);1671 parent.AddImage(Image); 1675 1672 } 1676 1673 1677 1674 void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImageEffects &effects) -
source/gui/CGUI.h
670 670 //-------------------------------------------------------- 671 671 672 672 // Sprites 673 std::map<CStr, CGUISprite > m_Sprites;673 std::map<CStr, CGUISprite*> m_Sprites; 674 674 675 675 // Styles 676 676 std::map<CStr, SGUIStyle> m_Styles; -
source/gui/CGUISprite.cpp
18 18 #include "precompiled.h" 19 19 #include "CGUISprite.h" 20 20 21 void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map<CStr, CGUISprite> &Sprites, float Z) const 21 CGUISprite::~CGUISprite() 22 22 { 23 for (std::vector<SGUIImage*>::iterator it = m_Images.begin(); it != m_Images.end(); it++) 24 { 25 delete *it; 26 } 27 } 28 29 void CGUISprite::AddImage(SGUIImage* image) 30 { 31 m_Images.push_back(image); 32 } 33 34 void CGUISpriteInstance::Draw(CRect Size, int CellID, std::map<CStr, CGUISprite*> &Sprites, float Z) const 35 { 23 36 if (m_CachedSize != Size || m_CachedCellID != CellID) 24 37 { 25 38 GUIRenderer::UpdateDrawCallCache(m_DrawCallCache, m_SpriteName, Size, CellID, Sprites); -
source/gui/CGUISprite.h
69 69 bool m_Greyscale; 70 70 }; 71 71 72 73 72 /** 74 73 * A CGUISprite is actually a collage of several <b>real</b> 75 74 * sprites, this struct represents is such real sprite. … … 81 80 m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) 82 81 { 83 82 } 83 84 ~SGUIImage() 85 { 86 delete m_Effects; 87 } 84 88 85 89 // Filename of the texture 86 90 VfsPath m_TextureName; … … 135 139 * way of declaring delta-z. 136 140 */ 137 141 float m_DeltaZ; 142 143 NONCOPYABLE(SGUIImage); 138 144 }; 139 145 140 141 146 /** 142 147 * The GUI sprite, is actually several real sprites (images) 143 148 * like a collage. View the section \<sprites\> in the GUI … … 151 156 { 152 157 public: 153 158 CGUISprite() {} 154 virtual ~CGUISprite() {}159 virtual ~CGUISprite(); 155 160 156 161 /** 157 162 * Adds an image to the sprite collage. 158 163 * 159 164 * @param image Adds this image to the sprite collage. 160 165 */ 161 void AddImage( const SGUIImage &image) { m_Images.push_back(image); }166 void AddImage(SGUIImage*); 162 167 163 168 /// List of images 164 std::vector<SGUIImage> m_Images; 169 std::vector<SGUIImage*> m_Images; 170 171 NONCOPYABLE(CGUISprite); 165 172 }; 166 173 167 174 #include "GUIRenderer.h" … … 176 183 CGUISpriteInstance(const CStr& SpriteName); 177 184 CGUISpriteInstance(const CGUISpriteInstance &Sprite); 178 185 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; 180 187 void Invalidate(); 181 188 bool IsEmpty() const; 182 189 const CStr& GetName() { return m_SpriteName; } -
source/gui/GUIRenderer.cpp
56 56 } 57 57 58 58 59 void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map<CStr, CGUISprite > &Sprites)59 void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, const CRect &Size, int CellID, std::map<CStr, CGUISprite*> &Sprites) 60 60 { 61 61 // This is called only when something has changed (like the size of the 62 62 // sprite), so it doesn't need to be particularly efficient. … … 71 71 return; 72 72 73 73 74 std::map<CStr, CGUISprite >::iterator it (Sprites.find(SpriteName));74 std::map<CStr, CGUISprite*>::iterator it (Sprites.find(SpriteName)); 75 75 if (it == Sprites.end()) 76 76 { 77 77 // Sprite not found. Check whether this a special sprite: … … 84 84 if (SpriteName.substr(0, 10) == "stretched:") 85 85 { 86 86 // TODO: Should check (nicely) that this is a valid file? 87 SGUIImage 87 SGUIImage* Image = new SGUIImage; 88 88 89 89 // Allow grayscale images for disabled portraits 90 90 if (SpriteName.substr(10, 10) == "grayscale:") 91 91 { 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; 95 95 } 96 96 else 97 97 { 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)); 99 99 } 100 100 101 101 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; 104 104 105 CGUISprite 106 Sprite .AddImage(Image);105 CGUISprite* Sprite = new CGUISprite; 106 Sprite->AddImage(Image); 107 107 108 108 Sprites[SpriteName] = Sprite; 109 109 … … 113 113 else if (SpriteName.substr(0, 8) == "cropped:") 114 114 { 115 115 // TODO: Should check (nicely) that this is a valid file? 116 SGUIImage 116 SGUIImage* Image = new SGUIImage; 117 117 118 118 double xRatio = SpriteName.BeforeFirst(",").AfterLast("(").ToDouble(); 119 119 double yRatio = SpriteName.BeforeFirst(")").AfterLast(",").ToDouble(); 120 120 121 121 int PathStart = SpriteName.Find(")") + 1; 122 122 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)); 124 124 125 125 CClientArea ca(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); 126 126 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; 129 129 130 CGUISprite 131 Sprite .AddImage(Image);130 CGUISprite* Sprite = new CGUISprite; 131 Sprite->AddImage(Image); 132 132 133 133 Sprites[SpriteName] = Sprite; 134 134 … … 147 147 return; 148 148 } 149 149 150 SGUIImage image;150 SGUIImage* Image = new SGUIImage; 151 151 152 image.m_BackColor = color;152 Image->m_BackColor = color; 153 153 154 154 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; 157 157 158 CGUISprite 159 Sprite .AddImage(image);158 CGUISprite* Sprite = new CGUISprite; 159 Sprite->AddImage(Image); 160 160 161 161 Sprites[SpriteName] = Sprite; 162 162 … … 171 171 } 172 172 } 173 173 174 Calls.reserve(it->second .m_Images.size());174 Calls.reserve(it->second->m_Images.size()); 175 175 176 176 // Iterate through all the sprite's images, loading the texture and 177 177 // 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) 180 180 { 181 SDrawCall Call( &*cit); // pointers are safe since we never modify sprites/images after startup181 SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup 182 182 183 CRect ObjectSize = cit->m_Size.GetClientArea(Size);183 CRect ObjectSize = (*cit)->m_Size.GetClientArea(Size); 184 184 185 185 if (ObjectSize.GetWidth() == 0.0 || ObjectSize.GetHeight() == 0.0) 186 186 { … … 189 189 } 190 190 191 191 Call.m_Vertices = ObjectSize; 192 if ( cit->m_RoundCoordinates)192 if ((*cit)->m_RoundCoordinates) 193 193 { 194 194 // Round the vertex coordinates to integers, to avoid ugly filtering artifacts 195 195 Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f); … … 198 198 Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f); 199 199 } 200 200 201 if (! cit->m_TextureName.empty())201 if (!(*cit)->m_TextureName.empty()) 202 202 { 203 CTextureProperties textureProps( cit->m_TextureName);204 textureProps.SetWrap( cit->m_WrapMode);203 CTextureProperties textureProps((*cit)->m_TextureName); 204 textureProps.SetWrap((*cit)->m_WrapMode); 205 205 CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps); 206 206 texture->Prefetch(); 207 207 Call.m_HasTexture = true; … … 216 216 { 217 217 Call.m_HasTexture = false; 218 218 // 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); 220 220 } 221 221 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; 225 225 226 226 if (!Call.m_HasTexture) 227 227 { 228 228 Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect("gui_solid"); 229 229 } 230 else if ( cit->m_Effects)230 else if ((*cit)->m_Effects) 231 231 { 232 if ( cit->m_Effects->m_AddColor != CColor())232 if ((*cit)->m_Effects->m_AddColor != CColor()) 233 233 { 234 234 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; 236 236 // Always enable blending if something's being subtracted from 237 237 // the alpha channel 238 if ( cit->m_Effects->m_AddColor.a < 0.f)238 if ((*cit)->m_Effects->m_AddColor.a < 0.f) 239 239 Call.m_EnableBlending = true; 240 240 } 241 else if ( cit->m_Effects->m_Greyscale)241 else if ((*cit)->m_Effects->m_Greyscale) 242 242 { 243 243 Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect("gui_grayscale"); 244 244 } -
source/gui/GUIRenderer.h
77 77 78 78 namespace GUIRenderer 79 79 { 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); 81 81 82 82 void Draw(DrawCalls &Calls, float Z); 83 83 }