#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DepthPrepassConfig {
pub enabled: bool,
pub write_depth: bool,
pub test_depth: bool,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DepthPrepassState {
pub config: DepthPrepassConfig,
pub draw_count: u32,
}
#[allow(dead_code)]
pub fn default_depth_prepass_config() -> DepthPrepassConfig {
DepthPrepassConfig {
enabled: true,
write_depth: true,
test_depth: true,
}
}
#[allow(dead_code)]
pub fn new_depth_prepass_state() -> DepthPrepassState {
DepthPrepassState {
config: default_depth_prepass_config(),
draw_count: 0,
}
}
#[allow(dead_code)]
pub fn dp_set_enabled(state: &mut DepthPrepassState, enabled: bool) {
state.config.enabled = enabled;
}
#[allow(dead_code)]
pub fn dp_is_enabled(state: &DepthPrepassState) -> bool {
state.config.enabled
}
#[allow(dead_code)]
pub fn dp_increment_draw_count(state: &mut DepthPrepassState) {
state.draw_count += 1;
}
#[allow(dead_code)]
pub fn dp_reset_draw_count(state: &mut DepthPrepassState) {
state.draw_count = 0;
}
#[allow(dead_code)]
pub fn dp_draw_count(state: &DepthPrepassState) -> u32 {
state.draw_count
}
#[allow(dead_code)]
pub fn dp_to_json(state: &DepthPrepassState) -> String {
format!(
r#"{{"enabled":{},"write_depth":{},"test_depth":{},"draw_count":{}}}"#,
state.config.enabled,
state.config.write_depth,
state.config.test_depth,
state.draw_count
)
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DepthPrepass {
pub width: u32,
pub height: u32,
pub near: f32,
pub far: f32,
pub enabled: bool,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DepthBuffer {
pub width: u32,
pub height: u32,
pub data: Vec<f32>,
}
#[allow(dead_code)]
pub fn new_depth_prepass(width: u32, height: u32, near: f32, far: f32) -> DepthPrepass {
DepthPrepass { width, height, near, far, enabled: true }
}
#[allow(dead_code)]
pub fn clear_depth(buf: &mut DepthBuffer, value: f32) {
buf.data.fill(value);
}
#[allow(dead_code)]
pub fn write_depth(buf: &mut DepthBuffer, x: u32, y: u32, value: f32) {
let idx = (y * buf.width + x) as usize;
if idx < buf.data.len() {
buf.data[idx] = value;
}
}
#[allow(dead_code)]
pub fn read_depth(buf: &DepthBuffer, x: u32, y: u32) -> f32 {
let idx = (y * buf.width + x) as usize;
buf.data.get(idx).copied().unwrap_or(1.0)
}
#[allow(dead_code)]
pub fn depth_test(buf: &DepthBuffer, x: u32, y: u32, d: f32) -> bool {
d < read_depth(buf, x, y)
}
#[allow(dead_code)]
pub fn prepass_width(dp: &DepthPrepass) -> u32 {
dp.width
}
#[allow(dead_code)]
pub fn prepass_height(dp: &DepthPrepass) -> u32 {
dp.height
}
#[allow(dead_code)]
pub fn depth_to_linear(dp: &DepthPrepass, ndc_depth: f32) -> f32 {
let n = dp.near;
let f = dp.far;
(2.0 * n * f) / (f + n - ndc_depth * (f - n))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let cfg = default_depth_prepass_config();
assert!(cfg.enabled);
assert!(cfg.write_depth);
assert!(cfg.test_depth);
}
#[test]
fn test_new_state_draw_count_zero() {
let s = new_depth_prepass_state();
assert_eq!(s.draw_count, 0);
}
#[test]
fn test_set_enabled_false() {
let mut s = new_depth_prepass_state();
dp_set_enabled(&mut s, false);
assert!(!dp_is_enabled(&s));
}
#[test]
fn test_increment_draw_count() {
let mut s = new_depth_prepass_state();
dp_increment_draw_count(&mut s);
dp_increment_draw_count(&mut s);
assert_eq!(dp_draw_count(&s), 2);
}
#[test]
fn test_reset_draw_count() {
let mut s = new_depth_prepass_state();
dp_increment_draw_count(&mut s);
dp_reset_draw_count(&mut s);
assert_eq!(dp_draw_count(&s), 0);
}
#[test]
fn test_to_json_contains_fields() {
let s = new_depth_prepass_state();
let j = dp_to_json(&s);
assert!(j.contains("enabled"));
assert!(j.contains("draw_count"));
}
#[test]
fn test_set_enabled_true() {
let mut s = new_depth_prepass_state();
dp_set_enabled(&mut s, false);
dp_set_enabled(&mut s, true);
assert!(dp_is_enabled(&s));
}
#[test]
fn test_multiple_increments() {
let mut s = new_depth_prepass_state();
for _ in 0..10 {
dp_increment_draw_count(&mut s);
}
assert_eq!(dp_draw_count(&s), 10);
}
#[test]
fn test_new_depth_prepass() {
let dp = new_depth_prepass(800, 600, 0.1, 100.0);
assert_eq!(prepass_width(&dp), 800);
assert_eq!(prepass_height(&dp), 600);
assert!(dp.enabled);
}
#[test]
fn test_clear_depth() {
let mut buf = DepthBuffer { width: 2, height: 2, data: vec![0.0; 4] };
clear_depth(&mut buf, 1.0);
assert!(buf.data.iter().all(|&v| (v - 1.0).abs() < 1e-6));
}
#[test]
fn test_write_read_depth() {
let mut buf = DepthBuffer { width: 4, height: 4, data: vec![1.0; 16] };
write_depth(&mut buf, 1, 2, 0.5);
assert!((read_depth(&buf, 1, 2) - 0.5).abs() < 1e-6);
}
#[test]
fn test_depth_test_pass() {
let buf = DepthBuffer { width: 1, height: 1, data: vec![0.8] };
assert!(depth_test(&buf, 0, 0, 0.5));
}
#[test]
fn test_depth_test_fail() {
let buf = DepthBuffer { width: 1, height: 1, data: vec![0.3] };
assert!(!depth_test(&buf, 0, 0, 0.5));
}
#[test]
fn test_depth_to_linear_near() {
let dp = new_depth_prepass(1, 1, 0.1, 100.0);
let lin = depth_to_linear(&dp, -1.0);
assert!(lin > 0.0);
}
}