]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CGUISpriteBank.cpp
c89bb26eaca62632ebc61e9a853573b597773459
[irrlicht.git] / source / Irrlicht / CGUISpriteBank.cpp
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
4 \r
5 #include "CGUISpriteBank.h"\r
6 #ifdef _IRR_COMPILE_WITH_GUI_\r
7 \r
8 #include "IGUIEnvironment.h"\r
9 #include "IVideoDriver.h"\r
10 #include "ITexture.h"\r
11 \r
12 namespace irr\r
13 {\r
14 namespace gui\r
15 {\r
16 \r
17 CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) :\r
18         Environment(env), Driver(0)\r
19 {\r
20         #ifdef _DEBUG\r
21         setDebugName("CGUISpriteBank");\r
22         #endif\r
23 \r
24         if (Environment)\r
25         {\r
26                 Driver = Environment->getVideoDriver();\r
27                 if (Driver)\r
28                         Driver->grab();\r
29         }\r
30 }\r
31 \r
32 \r
33 CGUISpriteBank::~CGUISpriteBank()\r
34 {\r
35         // drop textures\r
36         for (u32 i=0; i<Textures.size(); ++i)\r
37                 if (Textures[i])\r
38                         Textures[i]->drop();\r
39 \r
40         // drop video driver\r
41         if (Driver)\r
42                 Driver->drop();\r
43 }\r
44 \r
45 \r
46 core::array< core::rect<s32> >& CGUISpriteBank::getPositions()\r
47 {\r
48         return Rectangles;\r
49 }\r
50 \r
51 \r
52 core::array< SGUISprite >& CGUISpriteBank::getSprites()\r
53 {\r
54         return Sprites;\r
55 }\r
56 \r
57 \r
58 u32 CGUISpriteBank::getTextureCount() const\r
59 {\r
60         return Textures.size();\r
61 }\r
62 \r
63 \r
64 video::ITexture* CGUISpriteBank::getTexture(u32 index) const\r
65 {\r
66         if (index < Textures.size())\r
67                 return Textures[index];\r
68         else\r
69                 return 0;\r
70 }\r
71 \r
72 \r
73 void CGUISpriteBank::addTexture(video::ITexture* texture)\r
74 {\r
75         if (texture)\r
76                 texture->grab();\r
77 \r
78         Textures.push_back(texture);\r
79 }\r
80 \r
81 \r
82 void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture)\r
83 {\r
84         while (index >= Textures.size())\r
85                 Textures.push_back(0);\r
86 \r
87         if (texture)\r
88                 texture->grab();\r
89 \r
90         if (Textures[index])\r
91                 Textures[index]->drop();\r
92 \r
93         Textures[index] = texture;\r
94 }\r
95 \r
96 \r
97 //! clear everything\r
98 void CGUISpriteBank::clear()\r
99 {\r
100         // drop textures\r
101         for (u32 i=0; i<Textures.size(); ++i)\r
102         {\r
103                 if (Textures[i])\r
104                         Textures[i]->drop();\r
105         }\r
106         Textures.clear();\r
107         Sprites.clear();\r
108         Rectangles.clear();\r
109 }\r
110 \r
111 //! Add the texture and use it for a single non-animated sprite.\r
112 s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture)\r
113 {\r
114         if ( !texture )\r
115                 return -1;\r
116 \r
117         addTexture(texture);\r
118         u32 textureIndex = getTextureCount() - 1;\r
119 \r
120         u32 rectangleIndex = Rectangles.size();\r
121         Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );\r
122 \r
123         SGUISprite sprite;\r
124         sprite.frameTime = 0;\r
125 \r
126         SGUISpriteFrame frame;\r
127         frame.textureNumber = textureIndex;\r
128         frame.rectNumber = rectangleIndex;\r
129         sprite.Frames.push_back( frame );\r
130 \r
131         Sprites.push_back( sprite );\r
132 \r
133         return Sprites.size() - 1;\r
134 }\r
135 \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
140 {\r
141         if (index >= Sprites.size() || Sprites[index].Frames.empty() )\r
142                 return;\r
143 \r
144         u32 frame = getFrameNr(index, currenttime - starttime, loop);\r
145         const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);\r
146         if (!tex)\r
147                 return;\r
148 \r
149         const u32 rn = Sprites[index].Frames[frame].rectNumber;\r
150         if (rn >= Rectangles.size())\r
151                 return;\r
152 \r
153         const core::rect<s32>& r = Rectangles[rn];\r
154         core::position2di p(pos);\r
155         if (center)\r
156         {\r
157                 p -= r.getSize() / 2;\r
158         }\r
159         Driver->draw2DImage(tex, p, r, clip, color, true);\r
160 }\r
161 \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
165 {\r
166         if (index >= Sprites.size() || Sprites[index].Frames.empty() )\r
167                 return;\r
168 \r
169         u32 frame = getFrameNr(index, timeTicks, loop);\r
170         const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);\r
171         if (!tex)\r
172                 return;\r
173 \r
174         const u32 rn = Sprites[index].Frames[frame].rectNumber;\r
175         if (rn >= Rectangles.size())\r
176                 return;\r
177 \r
178         Driver->draw2DImage(tex, destRect, Rectangles[rn], clip, colors, true);\r
179 }\r
180 \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
187 {\r
188         const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());\r
189 \r
190         if (!getTextureCount())\r
191                 return;\r
192         core::array<SDrawBatch> drawBatches(getTextureCount());\r
193         for (u32 i=0; i < Textures.size(); ++i)\r
194         {\r
195                 drawBatches.push_back(SDrawBatch());\r
196                 drawBatches[i].positions.reallocate(drawCount);\r
197                 drawBatches[i].sourceRects.reallocate(drawCount);\r
198         }\r
199 \r
200         for (u32 i = 0; i < drawCount; ++i)\r
201         {\r
202                 const u32 index = indices[i];\r
203 \r
204                 if (index >= Sprites.size() || Sprites[index].Frames.empty() )\r
205                         continue;\r
206 \r
207                 // work out frame number\r
208                 u32 frame = 0;\r
209                 if (Sprites[index].frameTime)\r
210                 {\r
211                         u32 f = ((currenttime - starttime) / Sprites[index].frameTime);\r
212                         if (loop)\r
213                                 frame = f % Sprites[index].Frames.size();\r
214                         else\r
215                                 frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;\r
216                 }\r
217 \r
218                 const u32 texNum = Sprites[index].Frames[frame].textureNumber;\r
219                 SDrawBatch& currentBatch = drawBatches[texNum];\r
220 \r
221                 const u32 rn = Sprites[index].Frames[frame].rectNumber;\r
222                 if (rn >= Rectangles.size())\r
223                         return;\r
224 \r
225                 const core::rect<s32>& r = Rectangles[rn];\r
226 \r
227                 if (center)\r
228                 {\r
229                         core::position2di p = pos[i];\r
230                         p -= r.getSize() / 2;\r
231 \r
232                         currentBatch.positions.push_back(p);\r
233                         currentBatch.sourceRects.push_back(r);\r
234                 }\r
235                 else\r
236                 {\r
237                         currentBatch.positions.push_back(pos[i]);\r
238                         currentBatch.sourceRects.push_back(r);\r
239                 }\r
240         }\r
241 \r
242         for(u32 i = 0;i < drawBatches.size();i++)\r
243         {\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
247         }\r
248 }\r
249 \r
250 } // namespace gui\r
251 } // namespace irr\r
252 \r
253 #endif // _IRR_COMPILE_WITH_GUI_\r