roast2d_internal 0.4.0

Roast2D internal crate
Documentation
use glam::Mat4;

use crate::color::Color;
use crate::engine::Engine;
use crate::mesh3d::{Mesh3D, Mesh3DShader};
use crate::platform::types::TextureResource;
use crate::renderer::shader3d::draw3d::Draw3D;

/// Resolved 3D draw call with texture resource
pub struct ResolvedDraw3D {
    pub draw: Draw3D,
    pub texture: Option<TextureResource>,
}

/// Frame executor used by the platform to render queued 3D draws.
pub struct Shader3DRunner {
    mesh_shader: Mesh3DShader,
}

impl Shader3DRunner {
    pub fn new(g: &Engine) -> Self {
        Self {
            mesh_shader: Mesh3DShader::new(g),
        }
    }

    /// Record 3D draws into the provided encoder.
    /// If `should_clear` is true, clears color and depth at start of pass.
    pub fn record(
        &mut self,
        g: &Engine,
        color_target: &wgpu::Texture,
        depth_view: &wgpu::TextureView,
        draws: &[ResolvedDraw3D],
        encoder: &mut wgpu::CommandEncoder,
        should_clear: bool,
    ) {
        if draws.is_empty() {
            return;
        }
        // Clear bind group cache at frame start
        self.mesh_shader.frame_start();
        let size = color_target.size();
        let aspect = if size.height == 0 {
            1.0
        } else {
            size.width as f32 / size.height as f32
        };
        let view_proj = g.camera3d().view_proj(aspect);
        // Build a temporary slice of (&Mesh3D, Mat4, Option<&TextureResource>, Color, &Material3D, DrawMode)
        #[allow(clippy::type_complexity)]
        let tmp: Vec<(
            &Mesh3D,
            Mat4,
            Option<&TextureResource>,
            Color,
            &crate::light3d::Material3D,
            crate::mesh3d::DrawMode,
        )> = draws
            .iter()
            .map(|d| {
                (
                    &d.draw.mesh,
                    d.draw.model,
                    d.texture.as_ref(),
                    d.draw.color,
                    &d.draw.material,
                    d.draw.draw_mode,
                )
            })
            .collect();
        self.mesh_shader.record_to_encoder(
            g,
            color_target,
            depth_view,
            view_proj,
            &tmp,
            encoder,
            should_clear,
        );
    }
}