Implement conversion to gpu for different renderable types

This commit is contained in:
Dennis Kobert
2025-12-21 22:53:11 +01:00
parent aade019019
commit 0393dd057a
@@ -3,14 +3,18 @@ use core_types::bounds::{BoundingBox, RenderBoundingBox};
use core_types::ops::Convert; use core_types::ops::Convert;
use core_types::table::Table; use core_types::table::Table;
use core_types::transform::Footprint; use core_types::transform::Footprint;
use core_types::Color;
use glam::{DAffine2, DVec2, UVec2}; use glam::{DAffine2, DVec2, UVec2};
use graphic_types::Vector;
use graphic_types::raster_types::{GPU, Raster}; use graphic_types::raster_types::{GPU, Raster};
use graphic_types::vector_types::GradientStops;
use graphic_types::{Artboard, Graphic, Vector};
use rendering::{Render, RenderOutputType, RenderParams}; use rendering::{Render, RenderOutputType, RenderParams};
use wgpu::{CommandEncoderDescriptor, TextureFormat, TextureViewDescriptor}; use wgpu::{CommandEncoderDescriptor, TextureFormat, TextureViewDescriptor};
/// Converts Table<Vector> to Table<Raster<GPU>> by rendering each vector to Vello scene and then to texture macro_rules! impl_convert {
impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> { ($ty:ty) => {
/// Converts Table<T> to Table<Raster<GPU>> by rendering each item to Vello scene and then to texture
impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<$ty> {
async fn convert(self, footprint: Footprint, executor: &'i WgpuExecutor) -> Table<Raster<GPU>> { async fn convert(self, footprint: Footprint, executor: &'i WgpuExecutor) -> Table<Raster<GPU>> {
// Create render parameters for Vello rendering // Create render parameters for Vello rendering
let render_params = RenderParams { let render_params = RenderParams {
@@ -24,6 +28,7 @@ impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> {
let vector = &self; let vector = &self;
let bounding_box = vector.bounding_box(DAffine2::IDENTITY, true); let bounding_box = vector.bounding_box(DAffine2::IDENTITY, true);
// TODO: Add cases for infinite bounding boxes
let RenderBoundingBox::Rectangle(rect) = bounding_box else { let RenderBoundingBox::Rectangle(rect) = bounding_box else {
panic!("did not find valid bounding box") panic!("did not find valid bounding box")
}; };
@@ -33,18 +38,13 @@ impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> {
let mut context = crate::RenderContext::default(); let mut context = crate::RenderContext::default();
let viewport_bounds = footprint.viewport_bounds_in_local_space(); let viewport_bounds = footprint.viewport_bounds_in_local_space();
log::debug!("viewport bounds: {viewport_bounds:?}");
log::debug!("vector bounds: {bounding_box:?}");
let image_bounds = core_types::math::bbox::AxisAlignedBbox { start: rect[0], end: rect[1] }; let image_bounds = core_types::math::bbox::AxisAlignedBbox { start: rect[0], end: rect[1] };
let intersection = viewport_bounds.intersect(&image_bounds); let intersection = viewport_bounds.intersect(&image_bounds);
log::debug!("intersection: {intersection:?}");
let size = intersection.size(); let size = intersection.size();
// let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO);
let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO) + image_bounds.start; let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO) + image_bounds.start;
log::debug!("size: {size} offset: {offset}");
// If the image would not be visible, return an empty image // If the image would not be visible, return an empty image
if size.x <= 0. || size.y <= 0. { if size.x <= 0. || size.y <= 0. {
@@ -52,17 +52,14 @@ impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> {
} }
let scale = footprint.scale(); let scale = footprint.scale();
log::debug!("scale: {scale:?}");
let width = (size.x * scale.x) as u32; let width = (size.x * scale.x) as u32;
let height = (size.y * scale.y) as u32; let height = (size.y * scale.y) as u32;
// Render the scene to a GPU texture // Render the scene to a GPU texture
let resolution = UVec2::new(width, height); let resolution = UVec2::new(width, height);
log::debug!("resolution: {resolution:?}");
let background = core_types::Color::TRANSPARENT; let background = core_types::Color::TRANSPARENT;
let render_transform = DAffine2::from_scale(scale) * DAffine2::from_translation(-offset); let render_transform = DAffine2::from_scale(scale) * DAffine2::from_translation(-offset);
log::debug!("render transform: {render_transform:?}");
// Render the vector to the Vello scene with the row's transform // Render the vector to the Vello scene with the row's transform
vector.render_to_vello(&mut scene, render_transform, &mut context, &render_params); vector.render_to_vello(&mut scene, render_transform, &mut context, &render_params);
@@ -102,4 +99,12 @@ impl<'i> Convert<Table<Raster<GPU>>, &'i WgpuExecutor> for Table<Vector> {
texture.destroy(); texture.destroy();
table table
} }
}
};
} }
impl_convert!(Vector);
impl_convert!(Graphic);
impl_convert!(Artboard);
impl_convert!(GradientStops);
impl_convert!(Color);