Offscreen rendering with view swap

This commit is contained in:
hodasemi 2023-05-15 08:48:46 +02:00
parent 13a912d228
commit 87cf72bbe5
2 changed files with 95 additions and 185 deletions

View file

@ -106,9 +106,6 @@ fn update_ui_side_panel(
mut global_state: ResMut<GlobalState>,
mut object_infos: ResMut<ObjectInfos>,
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut standard_materials: ResMut<Assets<StandardMaterial>>,
mut color_materials: ResMut<Assets<ColorMaterial>>,
) {
let offscreen_texture_id = contexts.image_id(&global_state.offscreen_image).unwrap();
@ -127,32 +124,53 @@ fn update_ui_side_panel(
if ui.button("Change to 3D View").clicked() {
global_state.view_2d = false;
// object_infos.iter_mut().for_each(|polygon| {
// polygon.swap_to_3d(
// &global_state,
// &mut commands,
// &mut meshes,
// &mut standard_materials,
// )
// });
// remove render layer and add camera with default render target
let mut cam_3d = commands.entity(global_state.camera_3d);
cam_3d.remove::<RenderLayers>();
cam_3d.remove::<Camera>();
cam_3d.insert(Camera::default());
// add render layer and add camera with offscreen render target
let mut cam_2d = commands.entity(global_state.camera_2d);
cam_2d.insert(global_state.offscreen_render_layer);
cam_2d.remove::<Camera>();
cam_2d.insert(Camera {
target: RenderTarget::Image(global_state.offscreen_image.clone()),
..default()
});
object_infos
.iter_mut()
.for_each(|polygon| polygon.swap_to_3d(&global_state, &mut commands));
}
} else {
if ui.button("Change to 2D View").clicked() {
global_state.view_2d = true;
// object_infos.iter_mut().for_each(|polygon| {
// polygon.swap_to_2d(
// &global_state,
// &mut commands,
// &mut meshes,
// &mut color_materials,
// )
// });
// add render layer and add camera with offscreen render target
let mut cam_3d = commands.entity(global_state.camera_3d);
cam_3d.insert(global_state.offscreen_render_layer);
cam_3d.remove::<Camera>();
cam_3d.insert(Camera {
target: RenderTarget::Image(global_state.offscreen_image.clone()),
..default()
});
// remove render layer and add camera with default render target
let mut cam_2d = commands.entity(global_state.camera_2d);
cam_2d.remove::<RenderLayers>();
cam_2d.remove::<Camera>();
cam_2d.insert(Camera::default());
object_infos
.iter_mut()
.for_each(|polygon| polygon.swap_to_2d(&global_state, &mut commands));
}
}
if global_state.view_2d {
if global_state.polygon_started {
// print list of coordinates of current polygon
if let Some(polygon) = object_infos.active_polygon() {
for (index, point) in polygon.points().iter().enumerate() {
ui.label(&format!("{}: ({}, {})", index, point.x, point.y));
@ -228,9 +246,11 @@ fn on_resize_system(
// When resolution is being changed
global_state.window_extent = Vec2::new(e.width, e.height);
let center = (global_state.window_extent * 0.5).extend(0.0);
for mut transform in &mut camera {
*transform = Transform::from_xyz(200.0, -600.0, 600.0)
.looking_at((global_state.window_extent * 0.5).extend(0.0), Vec3::Z);
*transform = Transform::from_xyz(center.x + 200.0, center.y - 600.0, 600.0)
.looking_at(center, Vec3::Z);
}
}
}

View file

@ -2,7 +2,7 @@ use std::slice::IterMut;
use bevy::{
prelude::*,
render::{mesh::Indices, render_resource::PrimitiveTopology},
render::{mesh::Indices, render_resource::PrimitiveTopology, view::RenderLayers},
sprite::MaterialMesh2dBundle,
};
@ -16,7 +16,10 @@ struct CollectionIDs {
#[derive(Debug, PartialEq)]
struct FinishedIDs {
// 2d plane
plane: Entity,
// 3d object
object: Entity,
}
@ -50,178 +53,65 @@ pub struct Polygon {
impl Polygon {
const PROXIMITY_THRESHOLD: f32 = 10.0;
// pub fn swap_to_3d(
// &mut self,
// global_state: &GlobalState,
// commands: &mut Commands,
// meshes: &mut ResMut<Assets<Mesh>>,
// materials: &mut ResMut<Assets<StandardMaterial>>,
// ) {
// debug_assert!(self.state.is_2d());
pub fn swap_to_3d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
match &self.state {
PolygonState::Collection(collection_ids) => {
// add render layer to all points
for point in collection_ids.points.iter() {
let mut handle = commands.entity(*point);
// // clear all 2d entities
// let finished = match self.state.two_dimensional_mut() {
// PolygonState::Collection(collection_ids) => {
// for point in collection_ids.points.iter() {
// commands.entity(*point).despawn();
// }
handle.insert(global_state.offscreen_render_layer);
}
// for line in collection_ids.lines.iter() {
// commands.entity(*line).despawn();
// }
// also add render layer to all lines
for line in collection_ids.points.iter() {
let mut handle = commands.entity(*line);
// false
// }
// PolygonState::Finished(mesh) => {
// commands.entity(*mesh).despawn();
handle.insert(global_state.offscreen_render_layer);
}
}
PolygonState::Finished(finished_ids) => {
// add render layer to 2d plane
commands
.entity(finished_ids.plane)
.insert(global_state.offscreen_render_layer);
// true
// }
// };
// remove render layer from 3d object
commands
.entity(finished_ids.object)
.remove::<RenderLayers>();
}
}
}
// self.state = PolygonView::ThreeDimensional(if finished {
// let vertices: Vec<Vec3> = self
// .points
// .iter()
// .map(|p| vec![p.extend(0.0), p.extend(global_state.extrusion_height)])
// .flatten()
// .collect();
pub fn swap_to_2d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
match &self.state {
PolygonState::Collection(collection_ids) => {
// remove render layer from all points
for point in collection_ids.points.iter() {
let mut handle = commands.entity(*point);
// let indices = Indices::U32({
// let mut v = Vec::new();
handle.remove::<RenderLayers>();
}
// for i in 0..self.points.len() {
// let index = (i as u32) * 2;
// remove render layer from all lines
for line in collection_ids.points.iter() {
let mut handle = commands.entity(*line);
// // create quads from 4 adjacent points
// v.push(index);
// v.push((index + 2) % vertices.len() as u32);
// v.push(index + 1);
// v.push(index + 1);
// v.push((index + 2) % vertices.len() as u32);
// v.push((index + 3) % vertices.len() as u32);
// }
handle.remove::<RenderLayers>();
}
}
PolygonState::Finished(finished_ids) => {
// remove render layer from 2d plane
commands.entity(finished_ids.plane).remove::<RenderLayers>();
// // TODO: proper ear cutting algo
// for i in 2..self.points.len() as u32 {
// let index = (i as u32) * 2 + 1;
// v.push(1);
// v.push(index - 2);
// v.push(index);
// }
// v
// });
// let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
// mesh.set_indices(Some(indices));
// mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
// let mesh_id = commands
// .spawn(MaterialMeshBundle {
// mesh: meshes.add(mesh).into(),
// transform: Transform::default(),
// material: materials.add(StandardMaterial::from(Color::BLACK)),
// ..default()
// })
// .id();
// Some(mesh_id)
// } else {
// None
// });
// }
// pub fn swap_to_2d(
// &mut self,
// global_state: &GlobalState,
// commands: &mut Commands,
// meshes: &mut ResMut<Assets<Mesh>>,
// materials: &mut ResMut<Assets<ColorMaterial>>,
// ) {
// debug_assert!(self.state.is_3d());
// // clear 3d entity
// let finished = match self.state.three_dimensional_mut() {
// Some(mesh_id) => {
// commands.entity(*mesh_id).despawn();
// true
// }
// None => false,
// };
// self.state = PolygonView::TwoDimensional(if finished {
// // create triangle mesh
// let triangle_mesh = self.create_triangulated_mesh();
// let triangle_id = commands
// .spawn(MaterialMesh2dBundle {
// mesh: meshes.add(triangle_mesh).into(),
// transform: Transform::default()
// .with_translation((-global_state.window_extent * 0.5).extend(0.0)),
// material: materials.add(ColorMaterial::from(Color::BLACK)),
// ..default()
// })
// .id();
// // store triangle entity id in state
// PolygonState::Finished(triangle_id)
// } else {
// // create point meshes for every point
// let point_ids = self
// .points
// .iter()
// .map(|&point| {
// commands
// .spawn(MaterialMesh2dBundle {
// mesh: meshes.add(Mesh::from(shape::Quad::default())).into(),
// transform: Transform::default()
// .with_scale(Vec3::splat(4.0))
// .with_translation(
// (point - (global_state.window_extent * 0.5)).extend(0.0),
// ),
// material: materials.add(ColorMaterial::from(Color::BLACK)),
// ..default()
// })
// .id()
// })
// .collect();
// // draw lines between the points
// let line_ids = (1..self.points.len())
// .map(|i| {
// let previous_point = self.points[i - 1];
// let point = self.points[i];
// let a = Vec2::X.angle_between((point - previous_point).normalize());
// commands
// .spawn(MaterialMesh2dBundle {
// mesh: meshes
// .add(Self::create_line_mesh(previous_point, point))
// .into(),
// transform: Transform::default()
// .with_translation(
// (previous_point - (global_state.window_extent * 0.5))
// .extend(0.0),
// )
// .with_rotation(Quat::from_rotation_z(a)),
// material: materials.add(ColorMaterial::from(Color::BLACK)),
// ..default()
// })
// .id()
// })
// .collect();
// PolygonState::Collection(CollectionIDs {
// points: point_ids,
// lines: line_ids,
// })
// });
// }
// add render layer to 3d object
commands
.entity(finished_ids.object)
.insert(global_state.offscreen_render_layer);
}
}
}
pub fn points(&self) -> &[Vec2] {
&self.points