#include "irrlichtwrapper.h" #include "constants.h" IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device) { m_main_thread = get_current_thread_id(); m_device_mutex.Init(); m_device = device; } void IrrlichtWrapper::Run() { /* Fetch textures */ if(m_get_texture_queue.size() > 0) { GetRequest request = m_get_texture_queue.pop(); dstream<<"got texture request with key.name=" < result; result.key = request.key; result.callers = request.callers; result.item = getTextureDirect(request.key); request.dest->push_back(result); } } video::ITexture* IrrlichtWrapper::getTexture(TextureSpec spec) { video::ITexture *t = m_texturecache.get(spec.name); if(t != NULL) return t; if(get_current_thread_id() == m_main_thread) { dstream<<"Getting texture directly: name=" < result_queue; // Throw a request in m_get_texture_queue.add(spec, 0, 0, &result_queue); dstream<<"Waiting for texture from main thread: " < result = result_queue.pop_front(1000); // Check that at least something worked OK assert(result.key.name == spec.name); t = result.item; } catch(ItemNotFoundException &e) { dstream<<"Waiting for texture timed out."<getVideoDriver(); if(spec.mod == NULL) { dstream<<"IrrlichtWrapper::getTextureDirect: Loading texture " <getTexture(spec.path.c_str()); } dstream<<"IrrlichtWrapper::getTextureDirect: Loading and modifying " "texture "<getTexture(spec.path.c_str()); video::ITexture *result = spec.mod->make(base, spec.name.c_str(), driver); delete spec.mod; return result; } video::ITexture * CrackTextureMod::make(video::ITexture *original, const char *newname, video::IVideoDriver* driver) { core::dimension2d dim(16, 16); core::position2d pos_base(0, 0); core::position2d pos_other(0, 16 * progression); video::IImage *baseimage = driver->createImage(original, pos_base, dim); assert(baseimage); video::ITexture *other = driver->getTexture("../data/crack.png"); // We have to get the whole texture because getting a smaller area // messes the whole thing. It is probably a bug in Irrlicht. // NOTE: This doesn't work probably because some systems scale // the image to fit a texture or something... /*video::IImage *otherimage = driver->createImage( other, core::position2d(0,0), other->getSize());*/ // This should work on more systems video::IImage *otherimage = driver->createImage( other, core::position2d(0,0), v2u32(16, CRACK_ANIMATION_LENGTH * 16)); assert(otherimage); /*core::rect clip_rect(v2s32(0,0), dim); otherimage->copyToWithAlpha(baseimage, v2s32(0,0), core::rect(pos_other, dim), video::SColor(255,255,255,255), &clip_rect);*/ otherimage->copyToWithAlpha(baseimage, v2s32(0,0), core::rect(pos_other, dim), video::SColor(255,255,255,255), NULL); otherimage->drop(); video::ITexture *newtexture = driver->addTexture(newname, baseimage); baseimage->drop(); return newtexture; } video::ITexture * ProgressBarTextureMod::make(video::ITexture *original, const char *newname, video::IVideoDriver* driver) { core::position2d pos_base(0, 0); core::dimension2d dim = original->getOriginalSize(); video::IImage *baseimage = driver->createImage(original, pos_base, dim); assert(baseimage); core::dimension2d size = baseimage->getDimension(); u32 barheight = 1; u32 barpad_x = 1; u32 barpad_y = 1; u32 barwidth = size.Width - barpad_x*2; v2u32 barpos(barpad_x, size.Height - barheight - barpad_y); u32 barvalue_i = (u32)(((float)barwidth * value) + 0.5); video::SColor active(255,255,0,0); video::SColor inactive(255,0,0,0); for(u32 x0=0; x0setPixel(x,y, *c); } } video::ITexture *newtexture = driver->addTexture(newname, baseimage); baseimage->drop(); return newtexture; }