void OpenGLImageHelper::copySurfaceToImage(const Image *const image, const int x, const int y, SDL_Surface *surface) const { if (!surface || !image) return; SDL_Surface *const oldSurface = surface; surface = convertSurface(surface, surface->w, surface->h); if (!surface) return; // +++ probably need combine // mglTextureSubImage2D and mglTextureSubImage2DEXT if (mglTextureSubImage2D) { mglTextureSubImage2D(image->mGLImage, 0, x, y, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); } else { mglTextureSubImage2DEXT(image->mGLImage, mTextureType, 0, x, y, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); } if (surface != oldSurface) MSDL_FreeSurface(surface); }
bool Game::saveScreenshot(SDL_Surface *const screenshot) { std::string screenshotDirectory = client->getScreenshotDirectory(); if (mkdir_r(screenshotDirectory.c_str()) != 0) { logger->log("Directory %s doesn't exist and can't be created! " "Setting screenshot directory to home.", screenshotDirectory.c_str()); screenshotDirectory = std::string(PhysFs::getUserDir()); } // Search for an unused screenshot name std::stringstream filenameSuffix; std::stringstream filename; std::fstream testExists; bool found = false; static unsigned int screenshotCount = 0; do { screenshotCount++; filenameSuffix.str(""); filename.str(""); filename << screenshotDirectory << "/"; filenameSuffix << branding.getValue("appName", "ManaPlus") << "_Screenshot_" << screenshotCount << ".png"; filename << filenameSuffix.str(); testExists.open(filename.str().c_str(), std::ios::in); found = !testExists.is_open(); testExists.close(); } while (!found); const bool success = ImageWriter::writePNG(screenshot, filename.str()); if (success) { std::stringstream chatlogentry; // TRANSLATORS: save file message chatlogentry << strprintf(_("Screenshot saved as %s"), filenameSuffix.str().c_str()); if (localChatTab) localChatTab->chatLog(chatlogentry.str(), BY_SERVER); } else { if (localChatTab) { // TRANSLATORS: save file message localChatTab->chatLog(_("Saving screenshot failed!"), BY_SERVER); } logger->log1("Error: could not save screenshot."); } MSDL_FreeSurface(screenshot); return success; }
void Minimap::setMap(const Map *const map) { BLOCK_START("Minimap::setMap") std::string caption; if (map) caption = map->getName(); if (caption.empty()) { // TRANSLATORS: mini map window name caption = _("Map"); } setCaption(caption); deleteMapImage(); if (map) { if (config.getBoolValue("showExtMinimaps")) { SDL_Surface *const surface = MSDL_CreateRGBSurface(SDL_SWSURFACE, map->getWidth(), map->getHeight(), 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); if (!surface) { if (!isSticky()) setVisible(Visible_false); BLOCK_END("Minimap::setMap") return; } // I'm not sure if the locks are necessary since it's a SWSURFACE SDL_LockSurface(surface); int* data = static_cast<int*>(surface->pixels); if (!data) { if (!isSticky()) setVisible(Visible_false); BLOCK_END("Minimap::setMap") return; } const int size = surface->h * surface->w; const int mask = (BlockMask::WALL | BlockMask::AIR | BlockMask::WATER); for (int ptr = 0; ptr < size; ptr ++) *(data ++) = -!(map->mMetaTiles[ptr].blockmask & mask); SDL_UnlockSurface(surface); mMapImage = imageHelper->load(surface); mMapImage->setAlpha(settings.guiAlpha); mCustomMapImage = true; MSDL_FreeSurface(surface); } else {
Image *OpenGLImageHelper::load(SDL_RWops *const rw, Dye const &dye) { SDL_Surface *const tmpImage = loadPng(rw); if (!tmpImage) { reportAlways("Error, image load failed: %s", IMG_GetError()); return nullptr; } SDL_Surface *const surf = convertTo32Bit(tmpImage); MSDL_FreeSurface(tmpImage); if (!surf) return nullptr; uint32_t *pixels = static_cast<uint32_t *>(surf->pixels); const int type = dye.getType(); switch (type) { case 1: { const DyePalette *const pal = dye.getSPalete(); if (pal) pal->replaceSOGLColor(pixels, surf->w * surf->h); break; } case 2: { const DyePalette *const pal = dye.getAPalete(); if (pal) pal->replaceAOGLColor(pixels, surf->w * surf->h); break; } case 0: default: { dye.normalOGLDye(pixels, surf->w * surf->h); break; } } Image *const image = loadSurface(surf); MSDL_FreeSurface(surf); return image; }
Image *ImageHelper::load(SDL_RWops *const rw) { SDL_Surface *const tmpImage = loadPng(rw); if (!tmpImage) { logger->log("Error, image load failed: %s", IMG_GetError()); return nullptr; } Image *const image = loadSurface(tmpImage); MSDL_FreeSurface(tmpImage); return image; }
void OpenGLImageHelper::copySurfaceToImage(const Image *const image, const int x, const int y, SDL_Surface *surface) const { if (!surface || !image) return; SDL_Surface *const oldSurface = surface; surface = convertSurface(surface, surface->w, surface->h); mglTextureSubImage2D(image->mGLImage, mTextureType, 0, x, y, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); if (surface != oldSurface) MSDL_FreeSurface(surface); }
void WindowManager::deleteIcon() { MSDL_FreeSurface(mIcon); }
SDL_Surface *MobileOpenGLScreenshotHelper::getScreenshot() { const int h = mainGraphics->mHeight; const int w = mainGraphics->mWidth - (mainGraphics->mWidth % 4); GLint pack = 1; SDL_Surface *const tmpImage = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (tmpImage == nullptr) return nullptr; // Grap the pixel buffer and write it to the SDL surface mglGetIntegerv(GL_PACK_ALIGNMENT, &pack); mglPixelStorei(GL_PACK_ALIGNMENT, 1); mglReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); const size_t lineSize = 3 * w; GLubyte *const buf = new GLubyte[lineSize]; SDL_Surface *const screenshot = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); if (screenshot == nullptr) { MSDL_FreeSurface(tmpImage); delete [] buf; return nullptr; } #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); SDL_SetSurfaceBlendMode(tmpImage, SDL_BLENDMODE_NONE); #else // USE_SDL2 // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // USE_SDL2 if (SDL_MUSTLOCK(screenshot)) SDL_LockSurface(screenshot); SDL_BlitSurface(tmpImage, nullptr, screenshot, nullptr); MSDL_FreeSurface(tmpImage); // Flip the screenshot, as OpenGL has 0,0 in bottom left const int h2 = h / 2; for (int i = 0; i < h2; i++) { GLubyte *const top = static_cast<GLubyte*>( screenshot->pixels) + lineSize * i; GLubyte *const bot = static_cast<GLubyte*>( screenshot->pixels) + lineSize * (h - 1 - i); memcpy(buf, top, lineSize); memcpy(top, bot, lineSize); memcpy(bot, buf, lineSize); } delete [] buf; if (config.getBoolValue("usefbo")) graphicsManager.deleteFBO(&mFbo); mglPixelStorei(GL_PACK_ALIGNMENT, pack); if (SDL_MUSTLOCK(screenshot)) SDL_UnlockSurface(screenshot); return screenshot; }
Image *OpenGLImageHelper::glLoad(SDL_Surface *tmpImage, int width, int height) { if (!tmpImage) return nullptr; BLOCK_START("OpenGLImageHelper::glLoad") // Flush current error flag. graphicsManager.getLastError(); if (!width) width = tmpImage->w; if (!height) height = tmpImage->h; SDL_Surface *oldImage = tmpImage; tmpImage = convertSurface(tmpImage, width, height); const int realWidth = tmpImage->w; const int realHeight = tmpImage->h; const GLuint texture = getNewTexture(); bindTexture(texture); if (SDL_MUSTLOCK(tmpImage)) SDL_LockSurface(tmpImage); if (mUseOpenGL != RENDER_MODERN_OPENGL && mUseOpenGL != RENDER_GLES_OPENGL) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (!mUseTextureSampler) { if (mBlur) { glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } #ifndef ANDROID glTexParameteri(mTextureType, GL_TEXTURE_MAX_LEVEL, 0); #endif glTexImage2D(mTextureType, 0, mInternalTextureType, tmpImage->w, tmpImage->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); #ifdef DEBUG_OPENGL // disabled for now, because debugger can't show it // if (isGLNotNull(mglLabelObject)) // { // const char *const text = "image text"; // mglLabelObject(GL_TEXTURE, texture, strlen(text), text); // } #endif /* GLint compressed; glGetTexLevelParameteriv(mTextureType, 0, GL_TEXTURE_COMPRESSED_ARB, &compressed); if (compressed) logger->log("image compressed"); else logger->log("image not compressed"); */ #ifdef DEBUG_OPENGL_LEAKS textures_count ++; #endif if (SDL_MUSTLOCK(tmpImage)) SDL_UnlockSurface(tmpImage); if (oldImage != tmpImage) MSDL_FreeSurface(tmpImage); GLenum error = graphicsManager.getLastError(); if (error) { std::string errmsg = GraphicsManager::errorToString(error); logger->log("Error: Image GL import failed: %s (%u)", errmsg.c_str(), error); // return nullptr; } BLOCK_END("OpenGLImageHelper::glLoad") return new Image(texture, width, height, realWidth, realHeight); }
bool Game::saveScreenshot(SDL_Surface *const screenshot) { std::string screenshotDirectory = settings.screenshotDir; if (mkdir_r(screenshotDirectory.c_str()) != 0) { logger->log("Directory %s doesn't exist and can't be created! " "Setting screenshot directory to home.", screenshotDirectory.c_str()); screenshotDirectory = std::string(PhysFs::getUserDir()); } // Search for an unused screenshot name std::stringstream filename; std::fstream testExists; bool found = false; static unsigned int screenshotCount = 0; time_t rawtime; char buffer [100]; time(&rawtime); struct tm *const timeinfo = localtime(&rawtime); strftime(buffer, 99, "%Y-%m-%d_%H-%M-%S", timeinfo); const std::string serverName = settings.serverName; std::string screenShortStr; if (serverName.empty()) { screenShortStr = strprintf("%s_Screenshot_%s_", branding.getValue("appName", "Elmlor").c_str(), buffer); } else { screenShortStr = strprintf("%s_Screenshot_%s_%s_", branding.getValue("appName", "Elmlor").c_str(), serverName.c_str(), buffer); } do { screenshotCount++; filename.str(""); filename << screenshotDirectory << "/"; filename << screenShortStr << screenshotCount << ".png"; testExists.open(filename.str().c_str(), std::ios::in); found = !testExists.is_open(); testExists.close(); } while (!found); const std::string fileNameStr = filename.str(); const bool success = ImageWriter::writePNG(screenshot, fileNameStr); if (success) { if (localChatTab) { // TRANSLATORS: save file message std::string str = strprintf(_("Screenshot saved as %s"), fileNameStr.c_str()); localChatTab->chatLog(str, ChatMsgType::BY_SERVER); } } else { if (localChatTab) { // TRANSLATORS: save file message localChatTab->chatLog(_("Saving screenshot failed!"), ChatMsgType::BY_SERVER); } logger->log1("Error: could not save screenshot."); } MSDL_FreeSurface(screenshot); return success; }