mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-13 14:38:36 +00:00
Fix sRGB support, now when initialising a Renderer you can explicitly choose whether to output colors in linear or sRGB color spaces. Fix examples to show how to render these properly. Fix comments in examples
163 lines
4.8 KiB
Rust
163 lines
4.8 KiB
Rust
use glow::HasContext;
|
|
use glutin::{event_loop::EventLoop, GlRequest};
|
|
use imgui_winit_support::WinitPlatform;
|
|
|
|
pub type Window = glutin::WindowedContext<glutin::PossiblyCurrent>;
|
|
|
|
pub fn create_window(title: &str, gl_request: GlRequest) -> (EventLoop<()>, Window) {
|
|
let event_loop = glutin::event_loop::EventLoop::new();
|
|
let window = glutin::window::WindowBuilder::new()
|
|
.with_title(title)
|
|
.with_inner_size(glutin::dpi::LogicalSize::new(1024, 768));
|
|
let window = glutin::ContextBuilder::new()
|
|
.with_gl(gl_request)
|
|
.with_vsync(true)
|
|
.build_windowed(window, &event_loop)
|
|
.expect("could not create window");
|
|
let window = unsafe {
|
|
window
|
|
.make_current()
|
|
.expect("could not make window context current")
|
|
};
|
|
(event_loop, window)
|
|
}
|
|
|
|
pub fn glow_context(window: &Window) -> glow::Context {
|
|
unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s).cast()) }
|
|
}
|
|
|
|
pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
|
let mut imgui_context = imgui::Context::create();
|
|
imgui_context.set_ini_filename(None);
|
|
|
|
let mut winit_platform = WinitPlatform::init(&mut imgui_context);
|
|
winit_platform.attach_window(
|
|
imgui_context.io_mut(),
|
|
window.window(),
|
|
imgui_winit_support::HiDpiMode::Rounded,
|
|
);
|
|
|
|
imgui_context
|
|
.fonts()
|
|
.add_font(&[imgui::FontSource::DefaultFontData { config: None }]);
|
|
|
|
imgui_context.io_mut().font_global_scale = (1.0 / winit_platform.hidpi_factor()) as f32;
|
|
|
|
(winit_platform, imgui_context)
|
|
}
|
|
|
|
pub struct Triangler {
|
|
pub program: <glow::Context as HasContext>::Program,
|
|
pub vertex_array: <glow::Context as HasContext>::VertexArray,
|
|
}
|
|
|
|
impl Triangler {
|
|
pub fn new(gl: &glow::Context, shader_header: &str) -> Self {
|
|
const VERTEX_SHADER_SOURCE: &str = r#"
|
|
const vec2 verts[3] = vec2[3](
|
|
vec2(0.5f, 1.0f),
|
|
vec2(0.0f, 0.0f),
|
|
vec2(1.0f, 0.0f)
|
|
);
|
|
|
|
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() {
|
|
vert = verts[gl_VertexID];
|
|
color = srgb_to_linear(vec4(vert, 0.5, 1.0));
|
|
gl_Position = vec4(vert - 0.5, 0.0, 1.0);
|
|
}
|
|
"#;
|
|
const FRAGMENT_SHADER_SOURCE: &str = r#"
|
|
in vec2 vert;
|
|
in vec4 color;
|
|
|
|
out vec4 frag_color;
|
|
|
|
vec4 linear_to_srgb(vec4 linear_color) {
|
|
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
|
|
);
|
|
}
|
|
|
|
void main() {
|
|
frag_color = linear_to_srgb(color);
|
|
}
|
|
"#;
|
|
|
|
let mut shaders = [
|
|
(glow::VERTEX_SHADER, VERTEX_SHADER_SOURCE, 0),
|
|
(glow::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE, 0),
|
|
];
|
|
|
|
unsafe {
|
|
let vertex_array = gl
|
|
.create_vertex_array()
|
|
.expect("Cannot create vertex array");
|
|
|
|
let program = gl.create_program().expect("Cannot create program");
|
|
|
|
for (kind, source, handle) in &mut shaders {
|
|
let shader = gl.create_shader(*kind).expect("Cannot create shader");
|
|
gl.shader_source(shader, &format!("{}\n{}", shader_header, *source));
|
|
gl.compile_shader(shader);
|
|
if !gl.get_shader_compile_status(shader) {
|
|
panic!("{}", gl.get_shader_info_log(shader));
|
|
}
|
|
gl.attach_shader(program, shader);
|
|
*handle = shader;
|
|
}
|
|
|
|
gl.link_program(program);
|
|
if !gl.get_program_link_status(program) {
|
|
panic!("{}", gl.get_program_info_log(program));
|
|
}
|
|
|
|
for &(_, _, shader) in &shaders {
|
|
gl.detach_shader(program, shader);
|
|
gl.delete_shader(shader);
|
|
}
|
|
|
|
Self {
|
|
program,
|
|
vertex_array,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn render(&self, gl: &glow::Context) {
|
|
unsafe {
|
|
gl.clear_color(0.05, 0.05, 0.1, 1.0);
|
|
gl.clear(glow::COLOR_BUFFER_BIT);
|
|
gl.use_program(Some(self.program));
|
|
gl.bind_vertex_array(Some(self.vertex_array));
|
|
gl.draw_arrays(glow::TRIANGLES, 0, 3);
|
|
}
|
|
}
|
|
|
|
pub fn destroy(&self, gl: &glow::Context) {
|
|
unsafe {
|
|
gl.delete_program(self.program);
|
|
gl.delete_vertex_array(self.vertex_array);
|
|
}
|
|
}
|
|
}
|