void blend(drawable_type dw, const rectangle& area, pixel_color_t color, double fade_rate)
	{
		if (fade_rate <= 0) return;
		if (fade_rate > 1) fade_rate = 1;

		rectangle r;
		if (false == ::nana::overlap(rectangle{ drawable_size(dw) }, area, r))
			return;

		unsigned red = static_cast<unsigned>((color.value & 0xFF0000) * fade_rate);
		unsigned green = static_cast<unsigned>((color.value & 0xFF00) * fade_rate);
		unsigned blue = static_cast<unsigned>((color.value & 0xFF) * fade_rate);

		double lrate = 1 - fade_rate;
		pixel_buffer pixbuf(dw, r.y, r.height);

		for (std::size_t row = 0; row < r.height; ++row)
		{
			auto i = pixbuf.raw_ptr(row) + r.x;
			const auto end = i + r.width;
			for (; i < end; ++i)
			{
				unsigned px_r = ((static_cast<unsigned>((i->value & 0xFF0000) * lrate) + red) & 0xFF0000);
				unsigned px_g = ((static_cast<unsigned>((i->value & 0xFF00) * lrate) + green) & 0xFF00);
				unsigned px_b = ((static_cast<unsigned>((i->value & 0xFF) * lrate) + blue) & 0xFF);
				i->value = (px_r | px_g | px_b);
			}
		}
		pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, point{r.x, r.y});
	}
Example #2
0
SDLContext::SDLContext(const rainbow::Config& config)
    : window_(nullptr), vsync_(false), fullscreen_(0), context_(nullptr)
{
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
    {
        LOGF("SDL: Unable to initialise video: %s", SDL_GetError());
        return;
    }

#ifdef RAINBOW_OS_MACOS
    // Prevent the full screen window from being minimized when losing focus.
    SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
#endif

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
    if (config.msaa() > 0)
    {
        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config.msaa());
    }

    const uint32_t flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
                           (config.high_dpi() ? SDL_WINDOW_ALLOW_HIGHDPI : 0);
    const Vec2i& size = ::window_size(config);
    window_ = SDL_CreateWindow(RAINBOW_BUILD,
                               SDL_WINDOWPOS_CENTERED,
                               SDL_WINDOWPOS_CENTERED,
                               size.x,
                               size.y,
                               flags);
    if (!window_)
    {
        R_ABORT("SDL: Failed to create window: %s", SDL_GetError());
        return;
    }

    context_ = SDL_GL_CreateContext(window_);
    if (!context_)
    {
        R_ABORT("SDL: Failed to create GL context: %s", SDL_GetError());
        return;
    }

#ifdef RAINBOW_JS
    vsync_ = true;
#else
    SDL_GL_SetSwapInterval(1);
    vsync_ = SDL_GL_GetSwapInterval() == 1;
#endif

#ifndef NDEBUG
    const Vec2i& resolution = drawable_size();
    LOGI("SDL: Resolution: %ix%i", resolution.x, resolution.y);
    int msaa = 0;
    SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa);
    if (msaa > 0)
        LOGI("SDL: Anti-aliasing: %ix MSAA", msaa);
    else
        LOGI("SDL: Anti-aliasing: Disabled");
    LOGI("SDL: Vertical sync: %s", (vsync_ ? "Enabled" : "Disabled"));
#endif
}