rafx-plugins 0.0.16

Rendering framework built on an extensible asset pipeline
Documentation
use rafx::render_feature_extract_job_predule::*;

use super::*;
use crate::components::TransformComponent;
use hydrate_base::handle::Handle;
use legion::{EntityStore, World};
use rafx::assets::{AssetManagerExtractRef, AssetManagerRenderResource, MaterialAsset};
use rafx::base::resource_ref_map::ResourceRefBorrow;

pub struct SpriteExtractJob<'extract> {
    world: ResourceRefBorrow<'extract, World>,
    asset_manager: AssetManagerExtractRef,
    sprite_material: Handle<MaterialAsset>,
    render_objects: SpriteRenderObjectSet,
}

impl<'extract> SpriteExtractJob<'extract> {
    pub fn new(
        extract_context: &RenderJobExtractContext<'extract>,
        frame_packet: Box<SpriteFramePacket>,
        sprite_material: Handle<MaterialAsset>,
        render_objects: SpriteRenderObjectSet,
    ) -> Arc<dyn RenderFeatureExtractJob<'extract> + 'extract> {
        Arc::new(ExtractJob::new(
            Self {
                world: extract_context.extract_resources.fetch::<World>(),
                asset_manager: extract_context
                    .render_resources
                    .fetch::<AssetManagerRenderResource>()
                    .extract_ref(),
                sprite_material,
                render_objects,
            },
            extract_context,
            frame_packet,
        ))
    }
}

impl<'extract> ExtractJobEntryPoints<'extract> for SpriteExtractJob<'extract> {
    fn begin_per_frame_extract(
        &self,
        context: &ExtractPerFrameContext<'extract, '_, Self>,
    ) {
        context
            .frame_packet()
            .per_frame_data()
            .set(SpritePerFrameData {
                sprite_material_pass: self
                    .asset_manager
                    .committed_asset(&self.sprite_material)
                    .unwrap()
                    .get_single_material_pass()
                    .ok(),
            });
    }

    fn extract_render_object_instance(
        &self,
        job_context: &mut RenderObjectsJobContext<'extract, SpriteRenderObject>,
        context: &ExtractRenderObjectInstanceContext<'extract, '_, Self>,
    ) {
        let render_object_static_data = job_context
            .render_objects
            .get_id(context.render_object_id());

        let image_asset = self
            .asset_manager
            .committed_asset(&render_object_static_data.image);

        context.set_render_object_instance_data(image_asset.and_then(|image_asset| {
            let entry = self.world.entry_ref(context.object_id().into()).unwrap();
            let transform_component = entry.get_component::<TransformComponent>().unwrap();
            let texture_extents = image_asset.image.get_raw().image.texture_def().extents;
            Some(SpriteRenderObjectInstanceData {
                position: transform_component.translation,
                texture_size: glam::Vec2::new(
                    texture_extents.width as f32,
                    texture_extents.height as f32,
                ),
                scale: transform_component.scale,
                rotation: transform_component.rotation,
                color: render_object_static_data
                    .tint
                    .extend(render_object_static_data.alpha),
                image_view: image_asset.image_view.clone(),
            })
        }));
    }

    fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
        super::render_feature_debug_constants()
    }

    fn feature_index(&self) -> RenderFeatureIndex {
        super::render_feature_index()
    }

    fn new_render_object_instance_job_context(
        &'extract self
    ) -> Option<RenderObjectsJobContext<'extract, SpriteRenderObject>> {
        Some(RenderObjectsJobContext::new(self.render_objects.read()))
    }

    type RenderObjectInstanceJobContextT = RenderObjectsJobContext<'extract, SpriteRenderObject>;
    type RenderObjectInstancePerViewJobContextT = DefaultJobContext;

    type FramePacketDataT = SpriteRenderFeatureTypes;
}