1 #include "irrlichtwrapper.h"
6 IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
8 m_main_thread = get_current_thread_id();
13 void IrrlichtWrapper::Run()
18 if(m_get_texture_queue.size() > 0)
20 GetRequest<TextureSpec, video::ITexture*, u8, u8>
21 request = m_get_texture_queue.pop();
23 dstream<<"got texture request with"
24 <<" key.tids[0]="<<request.key.tids[0]
25 <<" [1]="<<request.key.tids[1]
28 GetResult<TextureSpec, video::ITexture*, u8, u8>
30 result.key = request.key;
31 result.callers = request.callers;
32 result.item = getTextureDirect(request.key);
34 request.dest->push_back(result);
38 textureid_t IrrlichtWrapper::getTextureId(const std::string &name)
40 u32 id = m_namecache.getId(name);
44 std::string IrrlichtWrapper::getTextureName(textureid_t id)
47 m_namecache.getValue(id, name);
48 // In case it was found, return the name; otherwise return an empty name.
52 video::ITexture* IrrlichtWrapper::getTexture(const std::string &name)
54 TextureSpec spec(getTextureId(name));
55 return getTexture(spec);
58 video::ITexture* IrrlichtWrapper::getTexture(const TextureSpec &spec)
63 video::ITexture *t = m_texturecache.get(spec);
67 if(get_current_thread_id() == m_main_thread)
69 dstream<<"Getting texture directly: spec.tids[0]="
70 <<spec.tids[0]<<std::endl;
72 t = getTextureDirect(spec);
76 // We're gonna ask the result to be put into here
77 ResultQueue<TextureSpec, video::ITexture*, u8, u8> result_queue;
80 m_get_texture_queue.add(spec, 0, 0, &result_queue);
82 dstream<<"Waiting for texture from main thread: spec.tids[0]="
83 <<spec.tids[0]<<std::endl;
87 // Wait result for a second
88 GetResult<TextureSpec, video::ITexture*, u8, u8>
89 result = result_queue.pop_front(1000);
91 // Check that at least something worked OK
92 assert(result.key == spec);
96 catch(ItemNotFoundException &e)
98 dstream<<"Waiting for texture timed out."<<std::endl;
103 // Add to cache and return
104 m_texturecache.set(spec, t);
108 // Draw a progress bar on the image
109 void make_progressbar(float value, video::IImage *image);
112 Texture fetcher/maker function, called always from the main thread
115 video::ITexture* IrrlichtWrapper::getTextureDirect(const TextureSpec &spec)
117 // This would result in NULL image
121 // Don't generate existing stuff
122 video::ITexture *t = m_texturecache.get(spec);
125 dstream<<"WARNING: Existing stuff requested from "
126 "getTextureDirect()"<<std::endl;
130 video::IVideoDriver* driver = m_device->getVideoDriver();
133 An image will be built from files and then converted into a texture.
135 video::IImage *baseimg = NULL;
138 Irrlicht requires a name for every texture, with which it
139 will be stored internally in irrlicht.
141 std::string texture_name;
143 for(u32 i=0; i<TEXTURE_SPEC_TEXTURE_COUNT; i++)
145 textureid_t tid = spec.tids[i];
149 std::string name = getTextureName(tid);
151 // Add something to the name so that it is a unique identifier.
153 texture_name += name;
158 // A normal texture; load it from a file
159 std::string path = porting::getDataPath(name.c_str());
160 dstream<<"getTextureDirect(): Loading path \""<<path
162 video::IImage *image = driver->createImageFromFile(path.c_str());
166 dstream<<"WARNING: Could not load image \""<<name
167 <<"\" from path \""<<path<<"\""
168 <<" while building texture"<<std::endl;
172 // If base image is NULL, load as base.
175 dstream<<"Setting "<<name<<" as base"<<std::endl;
177 Copy it this way to get an alpha channel.
178 Otherwise images with alpha cannot be blitted on
179 images that don't have alpha in the original file.
181 // This is a deprecated method
182 //baseimg = driver->createImage(video::ECF_A8R8G8B8, image);
183 core::dimension2d<u32> dim = image->getDimension();
184 baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
185 image->copyTo(baseimg);
189 // Else blit on base.
192 dstream<<"Blitting "<<name<<" on base"<<std::endl;
193 // Size of the copied area
194 core::dimension2d<u32> dim = image->getDimension();
195 //core::dimension2d<u32> dim(16,16);
196 // Position to copy the blitted to in the base image
197 core::position2d<s32> pos_to(0,0);
198 // Position to copy the blitted from in the blitted image
199 core::position2d<s32> pos_from(0,0);
201 image->copyToWithAlpha(baseimg, pos_to,
202 core::rect<s32>(pos_from, dim),
203 video::SColor(255,255,255,255),
211 // A special texture modification
212 dstream<<"getTextureDirect(): generating \""<<name<<"\""
214 if(name.substr(0,6) == "[crack")
216 u16 progression = stoi(name.substr(6));
217 // Size of the base image
218 core::dimension2d<u32> dim(16, 16);
219 // Size of the crack image
220 //core::dimension2d<u32> dim_crack(16, 16 * CRACK_ANIMATION_LENGTH);
221 // Position to copy the crack to in the base image
222 core::position2d<s32> pos_base(0, 0);
223 // Position to copy the crack from in the crack image
224 core::position2d<s32> pos_other(0, 16 * progression);
226 video::IImage *crackimage = driver->createImageFromFile(
227 porting::getDataPath("crack.png").c_str());
228 crackimage->copyToWithAlpha(baseimg, v2s32(0,0),
229 core::rect<s32>(pos_other, dim),
230 video::SColor(255,255,255,255),
234 else if(name.substr(0,12) == "[progressbar")
236 float value = stof(name.substr(12));
237 make_progressbar(value, baseimg);
241 dstream<<"WARNING: getTextureDirect(): Invalid "
242 " texture: \""<<name<<"\""<<std::endl;
247 // If no resulting image, return NULL
250 dstream<<"getTextureDirect(): baseimg is NULL (attempted to"
251 " create texture \""<<texture_name<<"\""<<std::endl;
255 /*// DEBUG: Paint some pixels
256 video::SColor c(255,255,0,0);
257 baseimg->setPixel(1,1, c);
258 baseimg->setPixel(1,14, c);
259 baseimg->setPixel(14,1, c);
260 baseimg->setPixel(14,14, c);*/
262 // Create texture from resulting image
263 t = driver->addTexture(texture_name.c_str(), baseimg);
266 dstream<<"getTextureDirect(): created texture \""<<texture_name
273 void make_progressbar(float value, video::IImage *image)
278 core::dimension2d<u32> size = image->getDimension();
283 u32 barwidth = size.Width - barpad_x*2;
284 v2u32 barpos(barpad_x, size.Height - barheight - barpad_y);
286 u32 barvalue_i = (u32)(((float)barwidth * value) + 0.5);
288 video::SColor active(255,255,0,0);
289 video::SColor inactive(255,0,0,0);
290 for(u32 x0=0; x0<barwidth; x0++)
297 u32 x = x0 + barpos.X;
298 for(u32 y=barpos.Y; y<barpos.Y+barheight; y++)
300 image->setPixel(x,y, *c);