use crate::camera::Camera2d;
use crate::camera::Camera3d;
use crate::light::LightCollection;
use crate::resource::{GpuMesh2d, GpuMesh3d};
use crate::scene::{InstancesBuffer2d, InstancesBuffer3d, ObjectData2d, ObjectData3d};
use glamx::{Pose2, Pose3, Vec2, Vec3};
use std::any::Any;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
pub enum RenderPhase {
Prepass,
#[default]
Opaque,
Transparent,
Transmission,
}
pub struct RenderContext {
pub phase: RenderPhase,
pub surface_format: wgpu::TextureFormat,
pub sample_count: u32,
pub viewport_width: u32,
pub viewport_height: u32,
pub render_layers: u32,
pub force_no_cull: bool,
pub shadow: Option<ShadowResources>,
}
#[derive(Clone)]
pub struct ShadowResources {
pub atlas: wgpu::TextureView,
pub compare_sampler: wgpu::Sampler,
pub uniform: wgpu::Buffer,
pub transmittance: wgpu::TextureView,
pub transmittance_sampler: wgpu::Sampler,
}
pub struct EnvLight<'a> {
pub view: &'a wgpu::TextureView,
pub sampler: &'a wgpu::Sampler,
pub mip_count: u32,
pub intensity: f32,
pub rotation: f32,
}
#[derive(Copy, Clone, Debug)]
pub struct ProbeData {
pub center: Vec3,
pub half_extents: Vec3,
pub falloff: f32,
pub intensity: f32,
pub rotation: f32,
pub layer: u32,
}
pub struct ProbeLighting<'a> {
pub array_view: &'a wgpu::TextureView,
pub probes: &'a [ProbeData],
pub max_lod: f32,
}
pub trait GpuData: Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
pub trait Material3d {
fn create_gpu_data(&self) -> Box<dyn GpuData>;
fn begin_frame(&mut self) {}
fn prepare(
&mut self,
_pass: usize,
_transform: Pose3,
_scale: Vec3,
_camera: &mut dyn Camera3d,
_lights: &LightCollection,
_data: &ObjectData3d,
_gpu_data: &mut dyn GpuData,
_viewport_width: u32,
_viewport_height: u32,
) {
}
fn flush(&mut self) {}
fn renders_in_transparent_phase(&self) -> bool {
false
}
fn set_environment_lighting(&mut self, _env: Option<EnvLight<'_>>) {}
fn set_reflection_probes(&mut self, _probes: Option<ProbeLighting<'_>>) {}
fn set_ssao(&mut self, _ao: Option<&wgpu::TextureView>) {}
fn set_transmission_background(&mut self, _bg: Option<&wgpu::TextureView>) {}
fn set_capture_mode(&mut self, _on: bool) {}
fn set_clip_plane(&mut self, _plane: Option<[f32; 4]>) {}
fn set_clustered_buffers(
&mut self,
_lights: &wgpu::Buffer,
_grid: &wgpu::Buffer,
_index: &wgpu::Buffer,
_force_rebind: bool,
) {
}
fn render(
&mut self,
pass: usize,
transform: Pose3,
scale: Vec3,
camera: &mut dyn Camera3d,
lights: &LightCollection,
data: &ObjectData3d,
mesh: &mut GpuMesh3d,
instances: &mut InstancesBuffer3d,
gpu_data: &mut dyn GpuData,
render_pass: &mut wgpu::RenderPass<'_>,
context: &RenderContext,
);
}
pub struct RenderContext2d {
pub surface_format: wgpu::TextureFormat,
pub sample_count: u32,
pub viewport_width: u32,
pub viewport_height: u32,
}
pub struct RenderContext2dEncoder<'a> {
pub encoder: &'a mut wgpu::CommandEncoder,
pub color_view: &'a wgpu::TextureView,
pub surface_format: wgpu::TextureFormat,
pub sample_count: u32,
pub viewport_width: u32,
pub viewport_height: u32,
}
pub trait Material2d {
fn create_gpu_data(&self) -> Box<dyn GpuData>;
fn begin_frame(&mut self) {}
fn prepare(
&mut self,
_transform: Pose2,
_scale: Vec2,
_camera: &mut dyn Camera2d,
_data: &ObjectData2d,
_mesh: &mut GpuMesh2d,
_instances: &mut InstancesBuffer2d,
_gpu_data: &mut dyn GpuData,
_context: &RenderContext2d,
) {
}
fn flush(&mut self) {}
fn render(
&mut self,
transform: Pose2,
scale: Vec2,
camera: &mut dyn Camera2d,
data: &ObjectData2d,
mesh: &mut GpuMesh2d,
instances: &mut InstancesBuffer2d,
gpu_data: &mut dyn GpuData,
render_pass: &mut wgpu::RenderPass<'_>,
context: &RenderContext2d,
);
}