void Texture2dData::store(const util::Path& file) const { log::log(MSG(info) << "Saving texture data to " << file); if (this->info.get_format() != pixel_format::rgba8) { throw Error(MSG(err) << "Storing 2D textures into files is unimplemented. PRs welcome :D"); } auto size = this->info.get_size(); // If an older SDL2 is used, we have to specify the format manually. #ifndef SDL_PIXELFORMAT_RGBA32 uint32_t rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else // little endian, like x86 rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf( SDL_CreateRGBSurfaceFrom( // const_cast is okay, because the surface doesn't modify data const_cast<void*>(static_cast<void const*>(this->data.data())), size.first, size.second, 32, this->info.get_row_size(), rmask, gmask, bmask, amask ), &SDL_FreeSurface ); #else std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf( SDL_CreateRGBSurfaceWithFormatFrom( // const_cast is okay, because the surface doesn't modify data const_cast<void*>(static_cast<void const*>(this->data.data())), size.first, size.second, 32, this->info.get_row_size(), SDL_PIXELFORMAT_RGBA32 ), &SDL_FreeSurface ); #endif // Call sdl_image for saving the screenshot to PNG std::string path = file.resolve_native_path_w(); IMG_SavePNG(surf.get(), path.c_str()); }
SDL_Surface *Surface::createSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t format) { #if SDL_VERSION_ATLEAST(2, 0, 5) return SDL_CreateRGBSurfaceWithFormatFrom(pixels, width, height, depth, pitch, format); #else SDL_Surface *surface = Surface::createSurfaceWithFormat(width, height, depth, format); SDL_memcpy(surface->pixels, pixels, height * pitch); return surface; #endif }