use crate::cx::*;
#[derive(Default, Clone)]
pub struct Pass {
pub pass_id: Option<usize>
}
impl Pass {
pub fn begin_pass(&mut self, cx: &mut Cx) {
if self.pass_id.is_none() { self.pass_id = Some(if cx.passes_free.len() != 0 {
cx.passes_free.pop().unwrap()
} else {
cx.passes.push(CxPass::default());
cx.passes.len() - 1
});
}
let pass_id = self.pass_id.unwrap();
if let Some(window_id) = cx.window_stack.last() {
if cx.windows[*window_id].main_pass_id.is_none() { let cxpass = &mut cx.passes[pass_id];
cx.windows[*window_id].main_pass_id = Some(pass_id);
cxpass.dep_of = CxPassDepOf::Window(*window_id);
cxpass.pass_size = cx.windows[*window_id].get_inner_size();
cx.current_dpi_factor = cx.get_delegated_dpi_factor(pass_id);
}
else if let Some(dep_of_pass_id) = cx.pass_stack.last() {
let dep_of_pass_id = *dep_of_pass_id;
cx.passes[pass_id].dep_of = CxPassDepOf::Pass(dep_of_pass_id);
cx.passes[pass_id].pass_size = cx.passes[dep_of_pass_id].pass_size;
cx.current_dpi_factor = cx.get_delegated_dpi_factor(dep_of_pass_id);
}
else {
cx.passes[pass_id].dep_of = CxPassDepOf::None;
cx.passes[pass_id].override_dpi_factor = Some(1.0);
cx.current_dpi_factor = 1.0;
}
}
else {
cx.passes[pass_id].dep_of = CxPassDepOf::None;
cx.passes[pass_id].override_dpi_factor = Some(1.0);
cx.current_dpi_factor = 1.0;
}
let cxpass = &mut cx.passes[pass_id];
cxpass.main_view_id = None;
cxpass.color_textures.truncate(0);
cx.pass_stack.push(pass_id);
}
pub fn override_dpi_factor(&mut self, cx: &mut Cx, dpi_factor:f32){
if let Some(pass_id) = self.pass_id {
cx.passes[pass_id].override_dpi_factor = Some(dpi_factor);
cx.current_dpi_factor = dpi_factor;
}
}
pub fn make_dep_of_pass(&mut self, cx: &mut Cx, pass: &Pass) {
let cxpass = &mut cx.passes[self.pass_id.unwrap()];
if let Some(pass_id) = pass.pass_id {
cxpass.dep_of = CxPassDepOf::Pass(pass_id)
}
else {
cxpass.dep_of = CxPassDepOf::None
}
}
pub fn set_size(&mut self, cx: &mut Cx, pass_size: Vec2) {
let cxpass = &mut cx.passes[self.pass_id.unwrap()];
cxpass.pass_size = pass_size;
}
pub fn add_color_texture(&mut self, cx: &mut Cx, texture: &mut Texture, clear_color: ClearColor) {
texture.set_desc(cx, None);
let pass_id = self.pass_id.expect("Please call add_color_texture after begin_pass");
let cxpass = &mut cx.passes[pass_id];
cxpass.color_textures.push(CxPassColorTexture {
texture_id: texture.texture_id.unwrap(),
clear_color: clear_color
})
}
pub fn set_depth_texture(&mut self, cx: &mut Cx, texture: &mut Texture, clear_depth: ClearDepth) {
texture.set_desc(cx, None);
let pass_id = self.pass_id.expect("Please call set_depth_texture after begin_pass");
let cxpass = &mut cx.passes[pass_id];
cxpass.depth_texture = texture.texture_id;
cxpass.clear_depth = clear_depth;
}
pub fn end_pass(&mut self, cx: &mut Cx) {
cx.pass_stack.pop();
if cx.pass_stack.len()>0{
cx.current_dpi_factor = cx.get_delegated_dpi_factor(*cx.pass_stack.last().unwrap());
}
}
pub fn redraw_pass_area(&mut self, cx: &mut Cx) {
if let Some(pass_id) = self.pass_id {
cx.redraw_pass_and_sub_passes(pass_id);
}
}
}
#[derive(Clone)]
pub enum ClearColor {
InitWith(Color),
ClearWith(Color)
}
impl Default for ClearColor {
fn default() -> Self {
ClearColor::ClearWith(Color::default())
}
}
#[derive(Clone)]
pub enum ClearDepth {
InitWith(f64),
ClearWith(f64)
}
#[derive(Default, Clone)]
pub struct CxPassColorTexture {
pub clear_color: ClearColor,
pub texture_id: usize
}
#[derive(Default, Clone)]
#[repr(C)]
pub struct PassUniforms{
camera_projection:[f32;16],
camera_view:[f32;16],
dpi_factor:f32,
dpi_dilate:f32,
pad1:f32,
pad2:f32
}
impl PassUniforms{
pub fn as_slice(&self)->&[f32;std::mem::size_of::<PassUniforms>()]{
unsafe{std::mem::transmute(self)}
}
}
#[derive(Clone)]
pub struct CxPass {
pub color_textures: Vec<CxPassColorTexture>,
pub depth_texture: Option<usize>,
pub clear_depth: ClearDepth,
pub depth_init: f64,
pub override_dpi_factor: Option<f32>,
pub main_view_id: Option<usize>,
pub dep_of: CxPassDepOf,
pub paint_dirty: bool,
pub pass_size: Vec2,
pub pass_uniforms: PassUniforms,
pub zbias_step: f32,
pub platform: CxPlatformPass,
}
impl Default for CxPass {
fn default() -> Self {
CxPass {
zbias_step: 0.001,
pass_uniforms: PassUniforms::default(),
color_textures: Vec::new(),
depth_texture: None,
override_dpi_factor: None,
clear_depth: ClearDepth::ClearWith(1.0),
depth_init: 1.0,
main_view_id: None,
dep_of: CxPassDepOf::None,
paint_dirty: false,
pass_size: Vec2::default(),
platform: CxPlatformPass::default()
}
}
}
#[derive(Clone, Debug)]
pub enum CxPassDepOf {
Window(usize),
Pass(usize),
None
}
impl CxPass {
pub fn def_uniforms(sg: ShaderGen) -> ShaderGen {
sg.compose(shader_ast!({
let camera_projection: mat4<PassUniform>;
let camera_view: mat4<PassUniform>;
let dpi_factor: float<PassUniform>;
let dpi_dilate: float<PassUniform>;
}))
}
pub fn uniform_camera_projection(&mut self, v: &Mat4) {
for i in 0..16 {
self.pass_uniforms.camera_projection[i] = v.v[i];
}
}
pub fn uniform_camera_view(&mut self, v: &Mat4) {
for i in 0..16 {
self.pass_uniforms.camera_view[i] = v.v[i];
}
}
pub fn set_dpi_factor(&mut self, dpi_factor: f32) {
let dpi_dilate = (2. - dpi_factor).max(0.).min(1.);
self.pass_uniforms.dpi_factor = dpi_factor;
self.pass_uniforms.dpi_dilate = dpi_dilate;
}
pub fn set_ortho_matrix(&mut self, offset: Vec2, size: Vec2) {
let ortho_matrix = Mat4::ortho(
offset.x,
offset.x + size.x,
offset.y,
offset.y + size.y,
100.,
-100.,
1.0,
1.0
);
self.uniform_camera_projection(&ortho_matrix);
}
}