1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #include "CGUISpriteBank.h"
\r
6 #ifdef _IRR_COMPILE_WITH_GUI_
\r
8 #include "IGUIEnvironment.h"
\r
9 #include "IVideoDriver.h"
\r
10 #include "ITexture.h"
\r
17 CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) :
\r
18 Environment(env), Driver(0)
\r
21 setDebugName("CGUISpriteBank");
\r
26 Driver = Environment->getVideoDriver();
\r
33 CGUISpriteBank::~CGUISpriteBank()
\r
36 for (u32 i=0; i<Textures.size(); ++i)
\r
38 Textures[i]->drop();
\r
40 // drop video driver
\r
46 core::array< core::rect<s32> >& CGUISpriteBank::getPositions()
\r
52 core::array< SGUISprite >& CGUISpriteBank::getSprites()
\r
58 u32 CGUISpriteBank::getTextureCount() const
\r
60 return Textures.size();
\r
64 video::ITexture* CGUISpriteBank::getTexture(u32 index) const
\r
66 if (index < Textures.size())
\r
67 return Textures[index];
\r
73 void CGUISpriteBank::addTexture(video::ITexture* texture)
\r
78 Textures.push_back(texture);
\r
82 void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture)
\r
84 while (index >= Textures.size())
\r
85 Textures.push_back(0);
\r
90 if (Textures[index])
\r
91 Textures[index]->drop();
\r
93 Textures[index] = texture;
\r
97 //! clear everything
\r
98 void CGUISpriteBank::clear()
\r
101 for (u32 i=0; i<Textures.size(); ++i)
\r
104 Textures[i]->drop();
\r
108 Rectangles.clear();
\r
111 //! Add the texture and use it for a single non-animated sprite.
\r
112 s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture)
\r
117 addTexture(texture);
\r
118 u32 textureIndex = getTextureCount() - 1;
\r
120 u32 rectangleIndex = Rectangles.size();
\r
121 Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
\r
124 sprite.frameTime = 0;
\r
126 SGUISpriteFrame frame;
\r
127 frame.textureNumber = textureIndex;
\r
128 frame.rectNumber = rectangleIndex;
\r
129 sprite.Frames.push_back( frame );
\r
131 Sprites.push_back( sprite );
\r
133 return Sprites.size() - 1;
\r
136 //! draws a sprite in 2d with scale and color
\r
137 void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
\r
138 const core::rect<s32>* clip, const video::SColor& color,
\r
139 u32 starttime, u32 currenttime, bool loop, bool center)
\r
141 if (index >= Sprites.size() || Sprites[index].Frames.empty() )
\r
144 u32 frame = getFrameNr(index, currenttime - starttime, loop);
\r
145 const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
\r
149 const u32 rn = Sprites[index].Frames[frame].rectNumber;
\r
150 if (rn >= Rectangles.size())
\r
153 const core::rect<s32>& r = Rectangles[rn];
\r
154 core::position2di p(pos);
\r
157 p -= r.getSize() / 2;
\r
159 Driver->draw2DImage(tex, p, r, clip, color, true);
\r
162 void CGUISpriteBank::draw2DSprite(u32 index, const core::rect<s32>& destRect,
\r
163 const core::rect<s32>* clip, const video::SColor * const colors,
\r
164 u32 timeTicks, bool loop)
\r
166 if (index >= Sprites.size() || Sprites[index].Frames.empty() )
\r
169 u32 frame = getFrameNr(index, timeTicks, loop);
\r
170 const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
\r
174 const u32 rn = Sprites[index].Frames[frame].rectNumber;
\r
175 if (rn >= Rectangles.size())
\r
178 Driver->draw2DImage(tex, destRect, Rectangles[rn], clip, colors, true);
\r
181 void CGUISpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
\r
182 const core::array<core::position2di>& pos,
\r
183 const core::rect<s32>* clip,
\r
184 const video::SColor& color,
\r
185 u32 starttime, u32 currenttime,
\r
186 bool loop, bool center)
\r
188 const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
\r
190 if (!getTextureCount())
\r
192 core::array<SDrawBatch> drawBatches(getTextureCount());
\r
193 for (u32 i=0; i < Textures.size(); ++i)
\r
195 drawBatches.push_back(SDrawBatch());
\r
196 drawBatches[i].positions.reallocate(drawCount);
\r
197 drawBatches[i].sourceRects.reallocate(drawCount);
\r
200 for (u32 i = 0; i < drawCount; ++i)
\r
202 const u32 index = indices[i];
\r
204 if (index >= Sprites.size() || Sprites[index].Frames.empty() )
\r
207 // work out frame number
\r
209 if (Sprites[index].frameTime)
\r
211 u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
\r
213 frame = f % Sprites[index].Frames.size();
\r
215 frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
\r
218 const u32 texNum = Sprites[index].Frames[frame].textureNumber;
\r
219 SDrawBatch& currentBatch = drawBatches[texNum];
\r
221 const u32 rn = Sprites[index].Frames[frame].rectNumber;
\r
222 if (rn >= Rectangles.size())
\r
225 const core::rect<s32>& r = Rectangles[rn];
\r
229 core::position2di p = pos[i];
\r
230 p -= r.getSize() / 2;
\r
232 currentBatch.positions.push_back(p);
\r
233 currentBatch.sourceRects.push_back(r);
\r
237 currentBatch.positions.push_back(pos[i]);
\r
238 currentBatch.sourceRects.push_back(r);
\r
242 for(u32 i = 0;i < drawBatches.size();i++)
\r
244 if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
\r
245 Driver->draw2DImageBatch(getTexture(i), drawBatches[i].positions,
\r
246 drawBatches[i].sourceRects, clip, color, true);
\r
253 #endif // _IRR_COMPILE_WITH_GUI_
\r