scena 1.7.1

A Rust-native scene-graph renderer with typed scene state, glTF assets, and explicit prepare/render lifecycles.
Documentation
use super::instancing::INSTANCE_BYTE_LEN;
use super::output;
use super::resource_encoding::encode_draw_resources;
use super::{GpuDeviceState, GpuPreparedResources};
use crate::render::RasterTarget;
use crate::render::prepare::{
    PreparedGpuLightUniform, PreparedInstanceSet, PreparedPrimitive, PreparedStrokeSegment,
};

impl GpuDeviceState {
    pub(in crate::render) fn update_dynamic_draw_state(
        &mut self,
        target: RasterTarget,
        light_uniform: PreparedGpuLightUniform,
        light_from_world: [f32; 16],
        draw_primitives: &[PreparedPrimitive],
        draw_instances: &[PreparedInstanceSet],
        draw_strokes: &[PreparedStrokeSegment],
    ) -> Result<(), &'static str> {
        let encoded = encode_draw_resources(draw_primitives, draw_instances, draw_strokes);
        let Some(resources) = self.resources.as_mut() else {
            return Err("no GPU resources");
        };
        validate_dynamic_capacity(
            resources,
            target,
            &encoded.draw_uniforms,
            &encoded.instance_bytes,
        )?;
        self.queue.write_buffer(
            &resources.draw_uniform_buffer,
            0,
            &output::encode_draw_uniform_bytes(&encoded.draw_uniforms),
        );
        self.queue
            .write_buffer(&resources.instance_buffer, 0, &encoded.instance_bytes);
        resources.draw_uniforms = encoded.draw_uniforms;
        resources.draw_batches = encoded.draw_batches;
        resources.instance_batches = encoded.instance_batches;
        resources.instance_count = encoded.instance_count;
        resources.identity_instance = encoded.identity_instance;
        if let Some(strokes) = resources.strokes.as_mut() {
            strokes.batches = encoded.stroke_batches;
        }
        resources.light_uniform = light_uniform;
        resources.light_from_world = light_from_world;
        Ok(())
    }
}

fn validate_dynamic_capacity(
    resources: &GpuPreparedResources,
    target: RasterTarget,
    draw_uniforms: &[super::vertices::DrawUniformValue],
    instance_bytes: &[u8],
) -> Result<(), &'static str> {
    if resources.target != target {
        return Err("target changed");
    }
    if draw_uniforms.len() > resources.draw_uniform_capacity {
        return Err("draw uniform capacity exceeded");
    }
    if instance_bytes.len() > resources.instance_buffer_capacity * INSTANCE_BYTE_LEN {
        return Err("instance buffer capacity exceeded");
    }
    Ok(())
}