void ImageLoader::load(IResource* res) { VFS* vfs = VFS::instance(); Image* img = dynamic_cast<Image*>(res); //Have to save the images x and y shift or it gets lost when it's //loaded again. int32_t xShiftSave = img->getXShift(); int32_t yShiftSave = img->getYShift(); if(!img->isSharedImage()) { const std::string& filename = img->getName(); boost::scoped_ptr<RawData> data (vfs->open(filename)); size_t datalen = data->getDataLength(); boost::scoped_array<uint8_t> darray(new uint8_t[datalen]); data->readInto(darray.get(), datalen); SDL_RWops* rwops = SDL_RWFromConstMem(darray.get(), static_cast<int>(datalen)); SDL_Surface* surface = IMG_Load_RW(rwops, false); if (!surface) { throw SDLException(std::string("Fatal Error when loading image into a SDL_Surface: ") + SDL_GetError()); } RenderBackend* rb = RenderBackend::instance(); // in case of SDL we don't need to convert the surface if (rb->getName() == "SDL") { img->setSurface(surface); // in case of OpenGL we need a 32bit surface } else { SDL_PixelFormat dst_format = rb->getPixelFormat(); SDL_PixelFormat src_format = *surface->format; uint8_t dstbits = dst_format.BitsPerPixel; uint8_t srcbits = src_format.BitsPerPixel; if (srcbits != 32 || dst_format.Rmask != src_format.Rmask || dst_format.Gmask != src_format.Gmask || dst_format.Bmask != src_format.Bmask || dst_format.Amask != src_format.Amask) { dst_format.BitsPerPixel = 32; SDL_Surface* conv = SDL_ConvertSurface(surface, &dst_format, 0); dst_format.BitsPerPixel = dstbits; if (!conv) { throw SDLException(std::string("Fatal Error when converting surface to the screen format: ") + SDL_GetError()); } img->setSurface(conv); SDL_FreeSurface(surface); } else { img->setSurface(surface); } } SDL_FreeRW(rwops); } //restore saved x and y shifts img->setXShift(xShiftSave); img->setYShift(yShiftSave); }
fcn::Image* GuiImageLoader::load(const std::string& filename, bool convertToDisplayFormat) { ImageManager* imgManager = ImageManager::instance(); if(imgManager->exists(filename)) { return new GuiImage(imgManager->get(filename)); } // load demanded image ImagePtr tmpimg = imgManager->load(filename); if(tmpimg->getWidth() >= ATLAS_SIZE || tmpimg->getHeight() >= ATLAS_SIZE) { return new GuiImage(tmpimg); } // look for a place for an image of given size AtlasBlock* block = m_atlasbook->getBlock(tmpimg->getWidth(), tmpimg->getHeight()); // if it can't fit, we need to add new 'page' if(block->page >= m_atlases.size()) { m_atlases.push_back(imgManager->loadBlank(ATLAS_SIZE, ATLAS_SIZE)); // because we gonna update texture on-the fly (via TexSubImage) // we cant really use compressed texture RenderBackend* rb = RenderBackend::instance(); bool prev = rb->isImageCompressingEnabled(); rb->setImageCompressingEnabled(false); m_atlases[block->page]->forceLoadInternal(); rb->setImageCompressingEnabled(prev); } // update atlas page with given image m_atlases[block->page]->copySubimage(block->left, block->top, tmpimg); // we dont really need this image anymore tmpimg->free(); imgManager->remove(tmpimg); // create shared image and return it ImagePtr img = imgManager->create(filename); Rect region(block->left, block->top, block->getWidth(), block->getHeight()); img->useSharedImage(m_atlases[block->page], region); return new GuiImage(img); }
void test_gui_image(RenderBackend& renderbackend, gcn::Graphics& graphics, ImagePool& pool) { boost::scoped_ptr<VFS> vfs(new VFS()); vfs->addSource(new VFSDirectory(vfs.get())); pool.addResourceLoader(new SubImageLoader()); pool.addResourceLoader(new ImageLoader(vfs.get())); GuiImageLoader imageloader(pool); gcn::Image::setImageLoader(&imageloader); gcn::Container* top = new gcn::Container(); top->setDimension(gcn::Rectangle(0, 0, 200, 300)); gcn::Gui* gui = new gcn::Gui(); gui->setGraphics(&graphics); gui->setTop(top); gcn::Label* label = new gcn::Label("Label"); gcn::Image* guiimage = gcn::Image::load(IMAGE_FILE); gcn::Icon* icon = new gcn::Icon(guiimage); top->add(label, 10, 10); top->add(icon, 10, 30); ImageLoader provider(vfs.get()); boost::scoped_ptr<Image> img(dynamic_cast<Image*>(provider.loadResource(ImageLocation(IMAGE_FILE)))); int h = img->getHeight(); int w = img->getWidth(); for (int i = 0; i < 100; i+=2) { renderbackend.startFrame(); img->render(Rect(i, i, w, h)); gui->logic(); gui->draw(); renderbackend.endFrame(); } delete label; delete icon; delete guiimage; }
void test_subimage(VFS* vfs, RenderBackend& renderbackend) { renderbackend.init(); renderbackend.createMainScreen(800, 600, 0, false, "FIFE", ""); ImageLoader imgprovider(vfs); boost::scoped_ptr<Image> img(dynamic_cast<Image*>(imgprovider.loadResource(ImageLocation(SUBIMAGE_FILE)))); ImageLocation location(SUBIMAGE_FILE); location.setParentSource(&*img); int W = img->getWidth(); int w = W / 12; int H = img->getHeight(); int h = H / 12; location.setWidth(w); location.setHeight(h); std::vector<Image*> subimages; SubImageLoader subprovider; for (int x = 0; x < (W - w); x+=w) { for (int y = 0; y < (H - h); y+=h) { location.setXShift(x); location.setYShift(y); Image* sub = dynamic_cast<Image*>(subprovider.loadResource(location)); subimages.push_back(sub); } } for (unsigned int i = 0; i < 200; i++) { renderbackend.startFrame(); subimages[i / 40]->render(Rect(200, 200, w, h)); renderbackend.endFrame(); } std::vector<Image*>::iterator i = subimages.begin(); while (i != subimages.end()) { delete *i; i++; } }
void test_image(VFS* vfs, RenderBackend& renderbackend) { renderbackend.init(); renderbackend.createMainScreen(800, 600, 0, false, "FIFE", ""); ImageLoader provider(vfs); boost::scoped_ptr<Image> img(dynamic_cast<Image*>(provider.loadResource(ImageLocation(IMAGE_FILE)))); int h = img->getHeight(); int w = img->getWidth(); for (int i = 0; i < 100; i++) { renderbackend.startFrame(); img->render(Rect(i, i, w, h)); renderbackend.endFrame(); } for (int j = 0; j < 5; j++) { for (int i = -10; i < 10; i++) { renderbackend.startFrame(); img->setXShift(i); img->setYShift(i); img->render(Rect(200, 200, w, h)); renderbackend.endFrame(); } } }