// SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2026 Martino Ferrari #include #include namespace plot::render { bool LineProgram::create(Status* st) noexcept { // plot::gl::Program::from_source() reports Unsupported while // plot::gl::available() is false and GLFailure when the driver rejects the // GLSL. Propagating it is the whole point of returning a bool here: the // caller must not end up drawing with a program that never linked. program_ = gl::Program::from_source(kLineVS, kLineFS, st); return program_.id() != 0; } void LineProgram::set_scale(Vec2 data_to_px) const noexcept { program_.set_uniform("u_scale", data_to_px); } void LineProgram::set_offset(Vec2 px) const noexcept { program_.set_uniform("u_offset", px); } void LineProgram::set_viewport(Vec2 px) const noexcept { program_.set_uniform("u_viewport", px); } void LineProgram::set_width(f32 px) const noexcept { program_.set_uniform("u_width", px); } void LineProgram::set_dash(Vec2 on_off) const noexcept { program_.set_uniform("u_dash", on_off); } void LineProgram::set_color(Color color) const noexcept { program_.set_uniform("u_color", color); } void LineProgram::set_aa(f32 px) const noexcept { program_.set_uniform("u_aa", px); } void LineProgram::set_snap(bool on) const noexcept { program_.set_uniform("u_snap", on ? 1.0f : 0.0f); } bool TextProgram::create(Status* st) noexcept { program_ = gl::Program::from_source(kTextVS, kTextFS, st); if (program_.id() == 0) { return false; } // The atlas is bound to texture unit 0 by plot::gl::Texture::bind(), so the // sampler has to point there. It is set once, here, not per frame. program_.use(); program_.set_uniform_int("u_atlas", 0); return true; } void TextProgram::set_viewport(Vec2 px) const noexcept { program_.set_uniform("u_viewport", px); } void TextProgram::set_px_range(Vec2 px) const noexcept { program_.set_uniform("u_px_range", px); } void TextProgram::set_glyph_uv(Vec2 uv) const noexcept { program_.set_uniform("u_glyph_uv", uv); } void TextProgram::set_texture_size(Vec2 texels) const noexcept { program_.set_uniform("u_tex_size", texels); } bool DensityProgram::create(Status* st) noexcept { program_ = gl::Program::from_source(kDensityVS, kDensityFS, st); if (program_.id() == 0) { return false; } // The grid texture is bound to texture unit 0 by plot::gl::Texture::bind(), so the sampler // has to point there. Set once, here, not per frame -- the same shape as the text program's. program_.use(); program_.set_uniform_int("u_density", 0); return true; } void DensityProgram::set_viewport(Vec2 px) const noexcept { program_.set_uniform("u_viewport", px); } void DensityProgram::set_rect(Vec2 origin, Vec2 size) const noexcept { program_.set_uniform("u_origin", origin); program_.set_uniform("u_size", size); } void DensityProgram::set_color(Color color) const noexcept { program_.set_uniform("u_color", color); } } // namespace plot::render