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;
}
Exemple #3
0
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);
}
Exemple #7
0
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);
}
Exemple #10
0
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;
}