Beispiel #1
0
	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);
	}
Beispiel #3
0
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;
	}
Beispiel #4
0
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++;
	}

}
Beispiel #5
0
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();
		}	
	}
}