mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-26 04:48:29 +00:00
Handle sRGB colours properly
This commit is contained in:
parent
0cafc5c22d
commit
84020a6bc0
@ -20,6 +20,8 @@ fn main() {
|
|||||||
|
|
||||||
// OpenGL context from glow
|
// OpenGL context from glow
|
||||||
let gl = glow_context(&window);
|
let gl = glow_context(&window);
|
||||||
|
// Outputting to screen, we want an sRGB framebuffer
|
||||||
|
unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) };
|
||||||
|
|
||||||
// OpenGL renderer from this crate
|
// OpenGL renderer from this crate
|
||||||
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
|
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use utils::Triangler;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (event_loop, window) = utils::create_window(
|
let (event_loop, window) = utils::create_window(
|
||||||
"Hello, triangle!",
|
"Hello, triangle! (GLES 3.0)",
|
||||||
glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)),
|
glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)),
|
||||||
);
|
);
|
||||||
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
||||||
@ -23,7 +23,10 @@ fn main() {
|
|||||||
imgui_glow_renderer::Renderer::initialize(&gl, &mut imgui_context, &mut texture_map)
|
imgui_glow_renderer::Renderer::initialize(&gl, &mut imgui_context, &mut texture_map)
|
||||||
.expect("failed to create renderer");
|
.expect("failed to create renderer");
|
||||||
// Note the shader header now needs a precision specifier
|
// Note the shader header now needs a precision specifier
|
||||||
let tri_renderer = Triangler::new(&gl, "#version 300 es\nprecision mediump float;");
|
let tri_renderer = Triangler::new(
|
||||||
|
&gl,
|
||||||
|
"#version 300 es\nprecision mediump float;\n#define IS_GLES",
|
||||||
|
);
|
||||||
|
|
||||||
let mut last_frame = Instant::now();
|
let mut last_frame = Instant::now();
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
|||||||
@ -262,7 +262,7 @@ impl Lenna {
|
|||||||
gl.tex_image_2d(
|
gl.tex_image_2d(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
glow::RGB as _,
|
glow::SRGB as _,
|
||||||
width as _,
|
width as _,
|
||||||
height as _,
|
height as _,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@ -23,7 +23,11 @@ pub fn create_window(title: &str, gl_request: GlRequest) -> (EventLoop<()>, Wind
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn glow_context(window: &Window) -> glow::Context {
|
pub fn glow_context(window: &Window) -> glow::Context {
|
||||||
unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s).cast()) }
|
unsafe {
|
||||||
|
let gl = glow::Context::from_loader_function(|s| window.get_proc_address(s).cast());
|
||||||
|
gl.enable(glow::FRAMEBUFFER_SRGB);
|
||||||
|
gl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
||||||
@ -49,6 +53,7 @@ pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
|||||||
pub struct Triangler {
|
pub struct Triangler {
|
||||||
pub program: <glow::Context as HasContext>::Program,
|
pub program: <glow::Context as HasContext>::Program,
|
||||||
pub vertex_array: <glow::Context as HasContext>::VertexArray,
|
pub vertex_array: <glow::Context as HasContext>::VertexArray,
|
||||||
|
is_gles: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Triangler {
|
impl Triangler {
|
||||||
@ -61,18 +66,50 @@ const vec2 verts[3] = vec2[3](
|
|||||||
);
|
);
|
||||||
|
|
||||||
out vec2 vert;
|
out vec2 vert;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
vec4 srgb_to_linear(vec4 srgb_color) {
|
||||||
|
// Calcuation as documented by OpenGL
|
||||||
|
vec3 srgb = srgb_color.rgb;
|
||||||
|
vec3 selector = ceil(srgb - 0.04045);
|
||||||
|
vec3 less_than_branch = srgb / 12.92;
|
||||||
|
vec3 greater_than_branch = pow((srgb + 0.055) / 1.055, vec3(2.4));
|
||||||
|
return vec4(
|
||||||
|
mix(less_than_branch, greater_than_branch, selector),
|
||||||
|
srgb_color.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vert = verts[gl_VertexID];
|
vert = verts[gl_VertexID];
|
||||||
|
color = srgb_to_linear(vec4(vert, 0.5, 1.0));
|
||||||
gl_Position = vec4(vert - 0.5, 0.0, 1.0);
|
gl_Position = vec4(vert - 0.5, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
const FRAGMENT_SHADER_SOURCE: &str = r#"
|
const FRAGMENT_SHADER_SOURCE: &str = r#"
|
||||||
in vec2 vert;
|
in vec2 vert;
|
||||||
out vec4 colour;
|
in vec4 color;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
vec4 linear_to_srgb(vec4 linear_color) {
|
||||||
|
#ifdef IS_GLES
|
||||||
|
vec3 linear = linear_color.rgb;
|
||||||
|
vec3 selector = ceil(linear - 0.0031308);
|
||||||
|
vec3 less_than_branch = linear * 12.92;
|
||||||
|
vec3 greater_than_branch = pow(linear, vec3(1.0/2.4)) * 1.055 - 0.055;
|
||||||
|
return vec4(
|
||||||
|
mix(less_than_branch, greater_than_branch, selector),
|
||||||
|
linear_color.a
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
// For non-GLES, GL_FRAMEBUFFER_SRGB handles this for free
|
||||||
|
return linear_color;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
colour = vec4(vert, 0.5, 1.0);
|
frag_color = linear_to_srgb(color);
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -112,13 +149,21 @@ void main() {
|
|||||||
Self {
|
Self {
|
||||||
program,
|
program,
|
||||||
vertex_array,
|
vertex_array,
|
||||||
|
is_gles: imgui_glow_renderer::versions::GlVersion::read(gl).is_gles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, gl: &glow::Context) {
|
pub fn render(&self, gl: &glow::Context) {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.clear_color(0.05, 0.05, 0.1, 1.0);
|
if self.is_gles {
|
||||||
|
// Specify clear color in sRGB space, since GL_FRAMEBUFFER_SRGB
|
||||||
|
// is not supported
|
||||||
|
gl.clear_color(0.05, 0.05, 0.1, 1.0);
|
||||||
|
} else {
|
||||||
|
// Specify clear color in linear space
|
||||||
|
gl.clear_color(0.004, 0.004, 0.01, 1.0);
|
||||||
|
}
|
||||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||||
gl.use_program(Some(self.program));
|
gl.use_program(Some(self.program));
|
||||||
gl.bind_vertex_array(Some(self.vertex_array));
|
gl.bind_vertex_array(Some(self.vertex_array));
|
||||||
|
|||||||
@ -793,9 +793,22 @@ uniform mat4 matrix;
|
|||||||
out vec2 fragment_uv;
|
out vec2 fragment_uv;
|
||||||
out vec4 fragment_color;
|
out vec4 fragment_color;
|
||||||
|
|
||||||
|
// Because imgui only specifies linear colors
|
||||||
|
vec4 srgb_to_linear(vec4 srgb_color) {
|
||||||
|
// Calcuation as documented by OpenGL
|
||||||
|
vec3 srgb = srgb_color.rgb;
|
||||||
|
vec3 selector = ceil(srgb - 0.04045);
|
||||||
|
vec3 less_than_branch = srgb / 12.92;
|
||||||
|
vec3 greater_than_branch = pow((srgb + 0.055) / 1.055, vec3(2.4));
|
||||||
|
return vec4(
|
||||||
|
mix(less_than_branch, greater_than_branch, selector),
|
||||||
|
srgb_color.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fragment_uv = uv;
|
fragment_uv = uv;
|
||||||
fragment_color = color;
|
fragment_color = srgb_to_linear(color);
|
||||||
gl_Position = matrix * vec4(position.xy, 0, 1);
|
gl_Position = matrix * vec4(position.xy, 0, 1);
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
@ -806,8 +819,24 @@ in vec4 fragment_color;
|
|||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
layout (location = 0) out vec4 out_color;
|
layout (location = 0) out vec4 out_color;
|
||||||
|
|
||||||
|
vec4 linear_to_srgb(vec4 linear_color) {
|
||||||
|
#ifdef IS_GLES
|
||||||
|
vec3 linear = linear_color.rgb;
|
||||||
|
vec3 selector = ceil(linear - 0.0031308);
|
||||||
|
vec3 less_than_branch = linear * 12.92;
|
||||||
|
vec3 greater_than_branch = pow(linear, vec3(1.0/2.4)) * 1.055 - 0.055;
|
||||||
|
return vec4(
|
||||||
|
mix(less_than_branch, greater_than_branch, selector),
|
||||||
|
linear_color.a
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
// For non-GLES, GL_FRAMEBUFFER_SRGB handles this for free
|
||||||
|
return linear_color;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
out_color = fragment_color * texture(tex, fragment_uv.st);
|
out_color = linear_to_srgb(fragment_color * texture(tex, fragment_uv.st));
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -854,7 +883,7 @@ void main() {
|
|||||||
major = major,
|
major = major,
|
||||||
minor = minor * 10,
|
minor = minor * 10,
|
||||||
es_extras = if is_gles {
|
es_extras = if is_gles {
|
||||||
" es\nprecision mediump float;"
|
" es\nprecision mediump float;\n#define IS_GLES"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
@ -968,14 +997,14 @@ fn prepare_font_atlas<G: Gl, T: TextureMap>(
|
|||||||
gl.tex_image_2d(
|
gl.tex_image_2d(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
glow::RGBA as _,
|
glow::SRGB8_ALPHA8 as _,
|
||||||
atlas_texture.width as _,
|
atlas_texture.width as _,
|
||||||
atlas_texture.height as _,
|
atlas_texture.height as _,
|
||||||
0,
|
0,
|
||||||
glow::RGBA,
|
glow::RGBA,
|
||||||
glow::UNSIGNED_BYTE,
|
glow::UNSIGNED_BYTE,
|
||||||
Some(atlas_texture.data),
|
Some(atlas_texture.data),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fonts.tex_id = texture_map
|
fonts.tex_id = texture_map
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user