pub mod camera;
pub mod color;
pub mod depth;
pub mod light;
pub mod raster;
pub mod shapes;
pub mod vtex;
#[cfg(target_arch = "wasm32")]
pub mod audio_web;
#[cfg(target_arch = "wasm32")]
pub mod webgl;
pub use camera::Camera3D;
pub use depth::DepthQueue;
pub use light::Light;
#[derive(Clone, Copy)]
pub struct ShadowParams {
pub base: f32,
pub grow: f32,
pub alpha: f32,
pub fade: f32,
pub soft: f32,
}
impl Default for ShadowParams {
fn default() -> Self {
Self { base: 14.0, grow: 0.6, alpha: 0.55, fade: 0.012, soft: 0.45 }
}
}
#[cfg(not(target_arch = "wasm32"))]
pub struct GfxState {
pub window: Option<minifb::Window>,
pub buffer: Vec<u32>,
pub width: usize,
pub height: usize,
pub color: u32,
pub camera: Camera3D,
pub lights: Vec<Light>,
pub ambient: f32,
pub depth_queue: DepthQueue,
pub mouse_dx: f32,
pub mouse_dy: f32,
pub last_mx: f32,
pub last_my: f32,
pub mouse_captured: bool,
pub shade_mode: u8,
pub shade: ling_graphics::shading::ShadeParams,
pub blend: u8,
pub alpha: f32,
pub shadow: ShadowParams,
pub linear_blend: bool,
pub grad_oklab: bool,
pub depth_test: bool,
pub depth_buf: Vec<f32>,
pub fog_color: u32,
pub fog_start: f32,
pub fog_end: f32,
}
#[cfg(not(target_arch = "wasm32"))]
impl GfxState {
pub fn new() -> Self {
Self {
window: None,
buffer: Vec::new(),
width: 0,
height: 0,
color: 0x00FF_FFFF,
camera: Camera3D::default(),
lights: Vec::new(),
ambient: 0.15,
depth_queue: DepthQueue::default(),
mouse_dx: 0.0,
mouse_dy: 0.0,
last_mx: f32::NAN,
last_my: f32::NAN,
mouse_captured: false,
shade_mode: 2, shade: ling_graphics::shading::ShadeParams::default(),
blend: 0, alpha: 1.0,
shadow: ShadowParams::default(),
linear_blend: false,
grad_oklab: true,
depth_test: false,
depth_buf: Vec::new(),
fog_color: 0x0000_0000,
fog_start: 0.0,
fog_end: 0.0, }
}
#[inline]
pub fn fog_apply(&self, color: u32, depth: f32) -> u32 {
if self.fog_end <= 0.0 {
return color;
}
let span = self.fog_end - self.fog_start;
if span <= 0.0 {
return color;
}
let f = ((depth - self.fog_start) / span).clamp(0.0, 1.0);
if f <= 0.0 {
return color;
}
let lerp = |a: u32, b: u32| -> u32 { (a as f32 + (b as f32 - a as f32) * f) as u32 & 0xff };
let r = lerp((color >> 16) & 0xff, (self.fog_color >> 16) & 0xff);
let g = lerp((color >> 8) & 0xff, (self.fog_color >> 8) & 0xff);
let b = lerp(color & 0xff, self.fog_color & 0xff);
(r << 16) | (g << 8) | b
}
pub fn sync_projection(&mut self) {
self.camera.cx = self.width as f32 / 2.0;
self.camera.cy = self.height as f32 / 2.0;
self.camera.focal = self.height as f32;
self.camera.zdist = 5.0;
}
}
#[cfg(target_arch = "wasm32")]
pub struct GfxState {
pub width: usize,
pub height: usize,
pub color: u32,
pub fill_r: f32,
pub fill_g: f32,
pub fill_b: f32,
pub camera: Camera3D,
pub lights: Vec<Light>,
pub ambient: f32,
pub depth_queue: DepthQueue,
pub shade_mode: u8,
pub shade: ling_graphics::shading::ShadeParams,
pub buffer: Vec<u32>,
pub blend: u8,
pub alpha: f32,
pub shadow: ShadowParams,
pub linear_blend: bool,
pub grad_oklab: bool,
pub depth_test: bool,
pub depth_buf: Vec<f32>,
pub fog_color: u32,
pub fog_start: f32,
pub fog_end: f32,
}
#[cfg(target_arch = "wasm32")]
impl GfxState {
pub fn new() -> Self {
Self {
width: 800,
height: 600,
color: 0x00FF_FFFF,
fill_r: 0.0,
fill_g: 0.0,
fill_b: 0.0,
camera: Camera3D::default(),
lights: Vec::new(),
ambient: 0.15,
depth_queue: DepthQueue::default(),
shade_mode: 2,
shade: ling_graphics::shading::ShadeParams::default(),
buffer: vec![0u32; 800 * 600],
blend: 0,
alpha: 1.0,
shadow: ShadowParams::default(),
linear_blend: false,
grad_oklab: true,
depth_test: false,
depth_buf: Vec::new(),
fog_color: 0x0000_0000,
fog_start: 0.0,
fog_end: 0.0,
}
}
#[inline]
pub fn fog_apply(&self, color: u32, depth: f32) -> u32 {
if self.fog_end <= 0.0 {
return color;
}
let span = self.fog_end - self.fog_start;
if span <= 0.0 {
return color;
}
let f = ((depth - self.fog_start) / span).clamp(0.0, 1.0);
if f <= 0.0 {
return color;
}
let lerp = |a: u32, b: u32| -> u32 { (a as f32 + (b as f32 - a as f32) * f) as u32 & 0xff };
let r = lerp((color >> 16) & 0xff, (self.fog_color >> 16) & 0xff);
let g = lerp((color >> 8) & 0xff, (self.fog_color >> 8) & 0xff);
let b = lerp(color & 0xff, self.fog_color & 0xff);
(r << 16) | (g << 8) | b
}
pub fn sync_projection(&mut self) {
self.camera.cx = self.width as f32 / 2.0;
self.camera.cy = self.height as f32 / 2.0;
self.camera.focal = self.height as f32;
self.camera.zdist = 5.0;
}
}