Offscreen rendering with view swap
This commit is contained in:
parent
13a912d228
commit
87cf72bbe5
2 changed files with 95 additions and 185 deletions
62
src/main.rs
62
src/main.rs
|
@ -106,9 +106,6 @@ fn update_ui_side_panel(
|
||||||
mut global_state: ResMut<GlobalState>,
|
mut global_state: ResMut<GlobalState>,
|
||||||
mut object_infos: ResMut<ObjectInfos>,
|
mut object_infos: ResMut<ObjectInfos>,
|
||||||
mut commands: Commands,
|
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();
|
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() {
|
if ui.button("Change to 3D View").clicked() {
|
||||||
global_state.view_2d = false;
|
global_state.view_2d = false;
|
||||||
|
|
||||||
// object_infos.iter_mut().for_each(|polygon| {
|
// remove render layer and add camera with default render target
|
||||||
// polygon.swap_to_3d(
|
let mut cam_3d = commands.entity(global_state.camera_3d);
|
||||||
// &global_state,
|
cam_3d.remove::<RenderLayers>();
|
||||||
// &mut commands,
|
cam_3d.remove::<Camera>();
|
||||||
// &mut meshes,
|
cam_3d.insert(Camera::default());
|
||||||
// &mut standard_materials,
|
|
||||||
// )
|
// 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 {
|
} else {
|
||||||
if ui.button("Change to 2D View").clicked() {
|
if ui.button("Change to 2D View").clicked() {
|
||||||
global_state.view_2d = true;
|
global_state.view_2d = true;
|
||||||
|
|
||||||
// object_infos.iter_mut().for_each(|polygon| {
|
// add render layer and add camera with offscreen render target
|
||||||
// polygon.swap_to_2d(
|
let mut cam_3d = commands.entity(global_state.camera_3d);
|
||||||
// &global_state,
|
cam_3d.insert(global_state.offscreen_render_layer);
|
||||||
// &mut commands,
|
cam_3d.remove::<Camera>();
|
||||||
// &mut meshes,
|
cam_3d.insert(Camera {
|
||||||
// &mut color_materials,
|
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.view_2d {
|
||||||
if global_state.polygon_started {
|
if global_state.polygon_started {
|
||||||
|
// print list of coordinates of current polygon
|
||||||
if let Some(polygon) = object_infos.active_polygon() {
|
if let Some(polygon) = object_infos.active_polygon() {
|
||||||
for (index, point) in polygon.points().iter().enumerate() {
|
for (index, point) in polygon.points().iter().enumerate() {
|
||||||
ui.label(&format!("{}: ({}, {})", index, point.x, point.y));
|
ui.label(&format!("{}: ({}, {})", index, point.x, point.y));
|
||||||
|
@ -228,9 +246,11 @@ fn on_resize_system(
|
||||||
// When resolution is being changed
|
// When resolution is being changed
|
||||||
global_state.window_extent = Vec2::new(e.width, e.height);
|
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 {
|
for mut transform in &mut camera {
|
||||||
*transform = Transform::from_xyz(200.0, -600.0, 600.0)
|
*transform = Transform::from_xyz(center.x + 200.0, center.y - 600.0, 600.0)
|
||||||
.looking_at((global_state.window_extent * 0.5).extend(0.0), Vec3::Z);
|
.looking_at(center, Vec3::Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
218
src/polygon.rs
218
src/polygon.rs
|
@ -2,7 +2,7 @@ use std::slice::IterMut;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::{mesh::Indices, render_resource::PrimitiveTopology},
|
render::{mesh::Indices, render_resource::PrimitiveTopology, view::RenderLayers},
|
||||||
sprite::MaterialMesh2dBundle,
|
sprite::MaterialMesh2dBundle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,10 @@ struct CollectionIDs {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct FinishedIDs {
|
struct FinishedIDs {
|
||||||
|
// 2d plane
|
||||||
plane: Entity,
|
plane: Entity,
|
||||||
|
|
||||||
|
// 3d object
|
||||||
object: Entity,
|
object: Entity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,178 +53,65 @@ pub struct Polygon {
|
||||||
impl Polygon {
|
impl Polygon {
|
||||||
const PROXIMITY_THRESHOLD: f32 = 10.0;
|
const PROXIMITY_THRESHOLD: f32 = 10.0;
|
||||||
|
|
||||||
// pub fn swap_to_3d(
|
pub fn swap_to_3d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
|
||||||
// &mut self,
|
match &self.state {
|
||||||
// global_state: &GlobalState,
|
PolygonState::Collection(collection_ids) => {
|
||||||
// commands: &mut Commands,
|
// add render layer to all points
|
||||||
// meshes: &mut ResMut<Assets<Mesh>>,
|
for point in collection_ids.points.iter() {
|
||||||
// materials: &mut ResMut<Assets<StandardMaterial>>,
|
let mut handle = commands.entity(*point);
|
||||||
// ) {
|
|
||||||
// debug_assert!(self.state.is_2d());
|
|
||||||
|
|
||||||
// // clear all 2d entities
|
handle.insert(global_state.offscreen_render_layer);
|
||||||
// let finished = match self.state.two_dimensional_mut() {
|
}
|
||||||
// PolygonState::Collection(collection_ids) => {
|
|
||||||
// for point in collection_ids.points.iter() {
|
|
||||||
// commands.entity(*point).despawn();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for line in collection_ids.lines.iter() {
|
// also add render layer to all lines
|
||||||
// commands.entity(*line).despawn();
|
for line in collection_ids.points.iter() {
|
||||||
// }
|
let mut handle = commands.entity(*line);
|
||||||
|
|
||||||
// false
|
handle.insert(global_state.offscreen_render_layer);
|
||||||
// }
|
}
|
||||||
// PolygonState::Finished(mesh) => {
|
}
|
||||||
// commands.entity(*mesh).despawn();
|
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 {
|
pub fn swap_to_2d(&mut self, global_state: &GlobalState, commands: &mut Commands) {
|
||||||
// let vertices: Vec<Vec3> = self
|
match &self.state {
|
||||||
// .points
|
PolygonState::Collection(collection_ids) => {
|
||||||
// .iter()
|
// remove render layer from all points
|
||||||
// .map(|p| vec![p.extend(0.0), p.extend(global_state.extrusion_height)])
|
for point in collection_ids.points.iter() {
|
||||||
// .flatten()
|
let mut handle = commands.entity(*point);
|
||||||
// .collect();
|
|
||||||
|
|
||||||
// let indices = Indices::U32({
|
handle.remove::<RenderLayers>();
|
||||||
// let mut v = Vec::new();
|
}
|
||||||
|
|
||||||
// for i in 0..self.points.len() {
|
// remove render layer from all lines
|
||||||
// let index = (i as u32) * 2;
|
for line in collection_ids.points.iter() {
|
||||||
|
let mut handle = commands.entity(*line);
|
||||||
|
|
||||||
// // create quads from 4 adjacent points
|
handle.remove::<RenderLayers>();
|
||||||
// v.push(index);
|
}
|
||||||
// v.push((index + 2) % vertices.len() as u32);
|
}
|
||||||
// v.push(index + 1);
|
PolygonState::Finished(finished_ids) => {
|
||||||
// v.push(index + 1);
|
// remove render layer from 2d plane
|
||||||
// v.push((index + 2) % vertices.len() as u32);
|
commands.entity(finished_ids.plane).remove::<RenderLayers>();
|
||||||
// v.push((index + 3) % vertices.len() as u32);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // TODO: proper ear cutting algo
|
// add render layer to 3d object
|
||||||
// for i in 2..self.points.len() as u32 {
|
commands
|
||||||
// let index = (i as u32) * 2 + 1;
|
.entity(finished_ids.object)
|
||||||
|
.insert(global_state.offscreen_render_layer);
|
||||||
// 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,
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn points(&self) -> &[Vec2] {
|
pub fn points(&self) -> &[Vec2] {
|
||||||
&self.points
|
&self.points
|
||||||
|
|
Loading…
Reference in a new issue