#include #include #include #include namespace psemek::gfx { static char const gamma_vs[] = R"(#version 330 const vec4 vertices[6] = vec4[6]( vec4(-1.0, -1.0, 0.0, 1.0), vec4( 1.0, -1.0, 0.0, 1.0), vec4( 1.0, 1.0, 0.0, 1.0), vec4(-1.0, -1.0, 0.0, 1.0), vec4( 1.0, 1.0, 0.0, 1.0), vec4(-1.0, 1.0, 0.0, 1.0) ); out vec2 texcoord; void main() { gl_Position = vertices[gl_VertexID]; texcoord = vertices[gl_VertexID].xy * 0.5 + vec2(0.5); } )"; static char const gamma_fs[] = R"(#version 330 uniform float u_gamma; uniform sampler2D u_input; in vec2 texcoord; out vec4 out_color; void main() { vec4 color = texture(u_input, texcoord); color.rgb = pow(color.rgb, vec3(u_gamma)); out_color = color; } )"; struct gamma_correction::impl { gfx::program program{gamma_vs, gamma_fs}; gfx::array array; }; gamma_correction::gamma_correction() : pimpl_{make_impl()} { impl().program.bind(); impl().program["u_input"] = 0; } gamma_correction::~gamma_correction() = default; void gamma_correction::invoke(texture_2d const & src, render_target const & dst, options const & opts) { gl::Disable(gl::BLEND); gl::Disable(gl::DEPTH_TEST); gl::Disable(gl::CULL_FACE); dst.bind(); gl::ActiveTexture(gl::TEXTURE0); src.bind(); impl().array.bind(); impl().program.bind(); impl().program["u_gamma"] = opts.gamma; gl::DrawArrays(gl::TRIANGLES, 0, 6); } }