1#![allow(dead_code)]
6
7use std::fmt;
8
9pub use rokol_ffi::gfx::sg_context_desc as SgContextDesc;
10
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14use crate::gfx as rg;
15
16#[derive(Debug, Clone, Copy)]
20#[repr(u32)]
21pub enum ColorFormat {
22 Rgba8 = rg::PixelFormat::Rgba8 as u32,
23 Bgra8 = rg::PixelFormat::Bgra8 as u32,
24}
25
26impl ColorFormat {
27 pub fn to_ffi(self) -> rokol_ffi::gfx::sg_pixel_format {
28 match self {
29 Self::Rgba8 => rokol_ffi::gfx::sg_pixel_format::SG_PIXELFORMAT_RGBA8,
30 Self::Bgra8 => rokol_ffi::gfx::sg_pixel_format::SG_PIXELFORMAT_BGRA8,
31 }
32 }
33}
34
35#[derive(Debug, Clone, Copy)]
39#[repr(u32)]
40pub enum DepthFormat {
41 Depth = rg::PixelFormat::Depth as u32,
42 DepthStencil = rg::PixelFormat::DepthStencil as u32,
43}
44
45impl DepthFormat {
46 pub fn to_ffi(self) -> rokol_ffi::gfx::sg_pixel_format {
47 match self {
48 Self::Depth => rokol_ffi::gfx::sg_pixel_format::SG_PIXELFORMAT_DEPTH,
49 Self::DepthStencil => rokol_ffi::gfx::sg_pixel_format::SG_PIXELFORMAT_DEPTH_STENCIL,
50 }
51 }
52}
53
54#[derive(Debug, Clone)]
55pub struct ResourceSettings {
56 pub color_format: ColorFormat,
57 pub depth_format: DepthFormat,
58 pub sample_count: u32,
60}
61
62impl Default for ResourceSettings {
63 fn default() -> Self {
64 Self {
65 color_format: ColorFormat::Rgba8,
66 depth_format: DepthFormat::Depth,
67 sample_count: 1,
68 }
69 }
70}
71
72impl ResourceSettings {
73 fn apply(&self, desc: &mut SgContextDesc) {
74 desc.color_format = self.color_format.to_ffi();
75 desc.depth_format = self.depth_format.to_ffi();
76 desc.sample_count = self.sample_count as i32;
77 }
78
79 #[cfg(rokol_gfx = "glcore33")]
80 fn create_context(&self) -> SgContextDesc {
81 let mut desc = SgContextDesc::default();
82 self.apply(&mut desc);
83 desc
99 }
100
101 pub fn init_gfx(&self) {
102 let desc = rokol_ffi::gfx::sg_desc {
103 context: self.create_context(),
104 ..Default::default()
105 };
106
107 unsafe {
108 rokol_ffi::gfx::sg_setup(&desc as *const _);
109 }
110 }
111}
112
113pub struct WindowHandle {
117 pub sdl: sdl2::Sdl,
119 pub vid: sdl2::VideoSubsystem,
121 pub win: sdl2::video::Window,
123 #[cfg(rokol_gfx = "glcore33")]
125 pub gcx: sdl2::video::GLContext,
126}
127
128impl WindowHandle {
129 #[cfg(rokol_gfx = "glcore33")]
131 pub fn swap_window(&self) {
132 self.win.gl_swap_window();
133 }
134}
135
136impl fmt::Debug for WindowHandle {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.debug_struct("WindowHandle")
139 .field("sdl", &"<sdl2::Sdl>")
140 .field("vid", &self.vid)
141 .field("win", &"<sdl2::video::Window>")
142 .field("gcx", &"<sdl2::video::GLContext>")
143 .finish()
144 }
145}
146
147#[derive(Debug)]
148#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
149pub struct Init {
150 pub title: String,
151 pub w: u32,
152 pub h: u32,
153 pub use_high_dpi: bool,
154 #[cfg_attr(feature = "serde", serde(skip))]
155 pub settings: ResourceSettings,
156}
157
158impl Default for Init {
159 fn default() -> Self {
160 Self {
161 title: "unnamed".to_string(),
162 w: 1280,
163 h: 720,
164 use_high_dpi: false,
165 settings: Default::default(),
166 }
167 }
168}
169
170impl Init {
171 #[cfg(rokol_gfx = "glcore33")]
176 pub fn init(
177 &self,
178 mut f: impl FnMut(&mut sdl2::video::WindowBuilder),
179 ) -> Result<WindowHandle, String> {
180 let sdl = sdl2::init()?;
182 let vid = sdl.video()?;
183
184 {
185 let attr = vid.gl_attr();
187 attr.set_context_profile(sdl2::video::GLProfile::Core);
188 attr.set_context_version(3, 3);
189 }
190
191 let win = {
192 let mut b = vid.window(&self.title, self.w, self.h);
193 b.opengl();
194 if self.use_high_dpi {
195 b.allow_highdpi();
196 }
197 f(&mut b);
198 b.build().map_err(|e| e.to_string())?
199 };
200
201 let gcx = win.gl_create_context()?;
202
203 self.settings.init_gfx();
205
206 Ok(WindowHandle { sdl, vid, win, gcx })
207 }
208}