Accedi
IT
games/open-lemmings / src / Service / Effects.php · commit 04e2e2a
<?phpnamespace App\Service;use JumPHP\Kernel\Engine;/** * The glow of the whole picture: a post-processing shader (OpenGL on the desktop, WebGL in the browser) that makes * what is bright bleed light around it (flames, halos, the exit, lava), with a soft colour grade. Option "bloom", off by default: it also makes texts and buttons bleed. * Without a GL context (headless tests) nothing happens: the game looks the same, without the bloom. */final class Effects{    private const BLOOM = <<<'GLSL'        vec3 glow(vec2 uv) {            vec3 c = texture2D(u_frame, uv).rgb;            float l = max(c.r, max(c.g, c.b));            return c * smoothstep(0.55, 1.0, l);        }        void main() {            vec2 px = 1.0 / u_resolution;            float s = max(1.0, u_viewport.z / max(1.0, u_view.x));            vec3 c = texture2D(u_frame, v_uv).rgb;            vec3 b = vec3(0.0);            for (int i = 0; i < 8; i++) {                float a = 0.7854 * float(i);                vec2 d = vec2(cos(a), sin(a)) * px * s;                b += glow(v_uv + d * 1.6) * 0.9 + glow(v_uv + d * 3.6) * 0.6 + glow(v_uv + d * 6.5) * 0.35;            }            c += b * 0.055;            c = mix(c, c * c * (3.0 - 2.0 * c), 0.25);            gl_FragColor = vec4(c, 1.0);        }        GLSL;    private ?bool $on = null;    public function isOn(Engine $engine): bool    {        return (bool)$engine->options->get('bloom', false);    }    public function available(Engine $engine): bool    {        return $engine->gl()->isAvailable();    }    /** Puts the shader on or off as the option says (call from enter()). */    public function apply(Engine $engine): void    {        $want = $this->isOn($engine) && $this->available($engine);        if ($this->on === $want) {            return;        }        $this->on = $want;        $engine->gl()->setPostShader($want ? self::BLOOM : null);    }    public function toggle(Engine $engine): void    {        $engine->options->set('bloom', !$this->isOn($engine));        $this->apply($engine);    }}