bracket_terminal/hal/native/
init.rs

1use super::BACKEND;
2use crate::hal::native::{shader_strings, WrappedContext};
3use crate::hal::scaler::ScreenScaler;
4use crate::hal::{setup_quad, Framebuffer, Shader};
5use crate::prelude::{BTerm, InitHints, BACKEND_INTERNAL};
6use crate::BResult;
7use glow::HasContext;
8use glutin::{event_loop::EventLoop, window::WindowBuilder, ContextBuilder};
9
10pub fn init_raw<S: ToString>(
11    width_pixels: u32,
12    height_pixels: u32,
13    window_title: S,
14    platform_hints: InitHints,
15) -> BResult<BTerm> {
16    let mut scaler = ScreenScaler::new(platform_hints.desired_gutter, width_pixels, height_pixels);
17    let el = EventLoop::new();
18    let window_size = scaler.new_window_size();
19    let window_size = glutin::dpi::LogicalSize::new(window_size.width, window_size.height);
20    let wb = WindowBuilder::new()
21        .with_title(window_title.to_string())
22        .with_resizable(platform_hints.fitscreen)
23        .with_min_inner_size(window_size)
24        .with_inner_size(window_size);
25    let windowed_context = ContextBuilder::new()
26        .with_gl(platform_hints.gl_version)
27        .with_gl_profile(platform_hints.gl_profile)
28        .with_hardware_acceleration(Some(true))
29        .with_vsync(platform_hints.vsync)
30        .with_srgb(platform_hints.srgb)
31        .build_windowed(wb, &el)?;
32    let windowed_context = unsafe { windowed_context.make_current().unwrap() };
33
34    if platform_hints.fullscreen {
35        if let Some(mh) = el.available_monitors().next() {
36            windowed_context
37                .window()
38                .set_fullscreen(Some(glutin::window::Fullscreen::Borderless(Some(mh))));
39        } else {
40            return Err("No available monitor found".into());
41        }
42    }
43
44    let gl = unsafe {
45        glow::Context::from_loader_function(|ptr| {
46            windowed_context.get_proc_address(ptr) as *const _
47        })
48    };
49
50    #[cfg(debug_assertions)]
51    unsafe {
52        let gl_version = gl.get_parameter_string(glow::VERSION);
53        let shader_version = gl.get_parameter_string(glow::SHADING_LANGUAGE_VERSION);
54        println!(
55            "Initialized OpenGL with: {}, Shader Language Version: {}",
56            gl_version, shader_version
57        );
58    }
59
60    // Load our basic shaders
61    let mut shaders: Vec<Shader> = Vec::new();
62
63    shaders.push(Shader::new(
64        &gl,
65        shader_strings::CONSOLE_WITH_BG_VS,
66        shader_strings::CONSOLE_WITH_BG_FS,
67    ));
68    shaders.push(Shader::new(
69        &gl,
70        shader_strings::CONSOLE_NO_BG_VS,
71        shader_strings::CONSOLE_NO_BG_FS,
72    ));
73    shaders.push(Shader::new(
74        &gl,
75        shader_strings::BACKING_VS,
76        shader_strings::BACKING_FS,
77    ));
78    shaders.push(Shader::new(
79        &gl,
80        shader_strings::SCANLINES_VS,
81        shader_strings::SCANLINES_FS,
82    ));
83    shaders.push(Shader::new(
84        &gl,
85        shader_strings::FANCY_CONSOLE_VS,
86        shader_strings::FANCY_CONSOLE_FS,
87    ));
88    shaders.push(Shader::new(
89        &gl,
90        shader_strings::SPRITE_CONSOLE_VS,
91        shader_strings::SPRITE_CONSOLE_FS,
92    ));
93
94    // Build the backing frame-buffer
95    let initial_dpi_factor = windowed_context.window().scale_factor();
96    scaler.change_logical_size(width_pixels, height_pixels, initial_dpi_factor as f32);
97    let backing_fbo = Framebuffer::build_fbo(
98        &gl,
99        scaler.logical_size.0 as i32,
100        scaler.logical_size.1 as i32,
101    )?;
102
103    // Build a simple quad rendering VAO
104    let quad_vao = setup_quad(&gl);
105
106    let mut be = BACKEND.lock();
107    be.gl = Some(gl);
108    be.quad_vao = Some(quad_vao);
109    be.context_wrapper = Some(WrappedContext {
110        el,
111        wc: windowed_context,
112    });
113    be.backing_buffer = Some(backing_fbo);
114    be.frame_sleep_time = crate::hal::convert_fps_to_wait(platform_hints.frame_sleep_time);
115    be.resize_scaling = platform_hints.resize_scaling;
116    be.screen_scaler = scaler;
117
118    BACKEND_INTERNAL.lock().shaders = shaders;
119
120    let bterm = BTerm {
121        width_pixels,
122        height_pixels,
123        original_width_pixels: width_pixels,
124        original_height_pixels: height_pixels,
125        fps: 0.0,
126        frame_time_ms: 0.0,
127        active_console: 0,
128        key: None,
129        mouse_pos: (0, 0),
130        left_click: false,
131        shift: false,
132        control: false,
133        alt: false,
134        web_button: None,
135        quitting: false,
136        post_scanlines: false,
137        post_screenburn: false,
138        screen_burn_color: bracket_color::prelude::RGB::from_f32(0.0, 1.0, 1.0),
139        mouse_visible: true,
140    };
141    Ok(bterm)
142}