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