use crate::gl;
use scopeguard::defer;
pub fn with_renderer_gl_data<R>(f: impl FnOnce() -> R) -> R {
macro_rules! get_gl_int {
($name:ident = $expr:expr) => {
let mut $name = 0;
gl::GetIntegerv($expr, &mut $name);
let $name = $name as u32;
};
}
macro_rules! is_gl_enabled {
($name:ident = $expr:expr) => {
let $name = gl::IsEnabled($expr) == gl::TRUE;
};
}
unsafe {
let mut last_viewport = [0_i32; 4];
gl::GetIntegerv(gl::VIEWPORT, last_viewport.as_mut_ptr());
get_gl_int!(last_active_texture = gl::ACTIVE_TEXTURE);
get_gl_int!(last_program = gl::CURRENT_PROGRAM);
get_gl_int!(last_texture = gl::TEXTURE_BINDING_2D);
get_gl_int!(last_array_buffer = gl::ARRAY_BUFFER_BINDING);
get_gl_int!(last_vertex_array_object = gl::VERTEX_ARRAY_BINDING);
get_gl_int!(last_blend_src_rgb = gl::BLEND_SRC_RGB);
get_gl_int!(last_blend_dst_rgb = gl::BLEND_DST_RGB);
get_gl_int!(last_blend_src_alpha = gl::BLEND_SRC_ALPHA);
get_gl_int!(last_blend_dst_alpha = gl::BLEND_DST_ALPHA);
get_gl_int!(last_blend_equation_rgb = gl::BLEND_EQUATION_RGB);
get_gl_int!(last_blend_equation_alpha = gl::BLEND_EQUATION_ALPHA);
is_gl_enabled!(last_blend = gl::BLEND);
is_gl_enabled!(last_cull_face = gl::CULL_FACE);
is_gl_enabled!(last_depth_test = gl::DEPTH_TEST);
is_gl_enabled!(last_stencil = gl::STENCIL_TEST);
is_gl_enabled!(last_scissor_test = gl::SCISSOR_TEST);
defer!({
if last_program == 0 || gl::IsProgram(last_program) != 0 {
gl::UseProgram(last_program);
}
gl::BindTexture(gl::TEXTURE_2D, last_texture);
if last_active_texture != gl::TEXTURE0 {
gl::ActiveTexture(last_active_texture);
}
gl::BindBuffer(gl::ARRAY_BUFFER, last_array_buffer);
gl::BindVertexArray(last_vertex_array_object);
gl::BlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
gl::BlendFuncSeparate(
last_blend_src_rgb,
last_blend_dst_rgb,
last_blend_src_alpha,
last_blend_dst_alpha,
);
if !last_blend {
gl::Disable(gl::BLEND);
}
if last_cull_face {
gl::Enable(gl::CULL_FACE);
}
if last_depth_test {
gl::Enable(gl::DEPTH_TEST);
}
if last_stencil {
gl::Enable(gl::STENCIL_TEST);
}
if last_scissor_test {
gl::Enable(gl::SCISSOR_TEST);
}
if last_viewport[2] != 0 || last_viewport[3] != 0 {
gl::Viewport(
last_viewport[0],
last_viewport[1],
last_viewport[2],
last_viewport[3],
);
}
});
f()
}
}