SHARE
TWEET

Simple Cube Viewer

a guest Jun 26th, 2019 85 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use amethyst::{
  2.     assets::{Loader, Handle},
  3.     core::{
  4.         transform::{TransformBundle, Transform},
  5.         timing::Time,
  6.     },
  7.     ecs::{
  8.         prelude::*,
  9.         Join,
  10.     },
  11.     input::{Axis, Button, Bindings, InputBundle, InputHandler, StringBindings, VirtualKeyCode},
  12.     controls::{FlyControlBundle, FlyControlTag},
  13.     prelude::*,
  14.     renderer::{
  15.         Camera,
  16.         camera::Projection,
  17.         palette::rgb::Rgb,
  18.         Material,
  19.         MaterialDefaults,
  20.         Mesh,
  21.         light::{Light, DirectionalLight},
  22.         pass::{
  23.             DrawPbrDesc,
  24.             DrawShadedDesc,
  25.         },
  26.         rendy::{
  27.             factory::Factory,
  28.             graph::{
  29.                 render::{RenderGroupDesc, SubpassBuilder},
  30.                 GraphBuilder,
  31.             },
  32.             hal::{format::Format, image},
  33.             util::types::vertex::*,
  34.         },
  35.         shape::Shape,
  36.         types::DefaultBackend,
  37.         GraphCreator, RenderingSystem,
  38.     },
  39.     utils::application_root_dir,
  40.     window::{ScreenDimensions, Window, WindowBundle},
  41. };
  42.  
  43. struct Cube;
  44. impl Component for Cube {
  45.     type Storage = DenseVecStorage<Cube>;
  46. }
  47.  
  48. struct MyState;
  49.  
  50. impl SimpleState for MyState {
  51.     fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
  52.        let world = data.world;
  53.  
  54.        let (mesh, mat) = {
  55.            let loader = world.read_resource::<Loader>();
  56.  
  57.            let cube = Shape::Cube.generate::<(
  58.                Vec<Position>,
  59.                Vec<Normal>,
  60.                Vec<TexCoord>,
  61.                Vec<Tangent>,
  62.            )>(Some((0.25, 0.25, 0.25)));
  63.            let mesh: Handle<Mesh> = loader.load_from_data(
  64.                cube.into(),
  65.                (),
  66.                &world.read_resource(),
  67.            );
  68.  
  69.            let mat_default = world.read_resource::<MaterialDefaults>();
  70.            let mat: Handle<Material> = loader.load_from_data(
  71.                Material {
  72.                    ..mat_default.0.clone()
  73.                },
  74.                (),
  75.                &world.read_resource(),
  76.            );
  77.  
  78.            (mesh, mat)
  79.        };
  80.  
  81.        let mut transform = Transform::default();
  82.        transform.set_translation_xyz(0.0, -0.15, -1.0);
  83.  
  84.        world.create_entity()
  85.            .with(mesh)
  86.            .with(mat)
  87.            .with(transform)
  88.            .with(Cube)
  89.            .build();
  90.  
  91.        world.create_entity()
  92.            .with(Light::from(DirectionalLight {
  93.                color: Rgb::new(1.0, 1.0, 1.0),
  94.                direction: [0.0, -1.0, 0.0].into(),
  95.                intensity: 1.0,
  96.            }))
  97.            .build();
  98.  
  99.        let mut transform = Transform::default();
  100.        transform.set_translation_xyz(0.0, 0.0, 0.0);
  101.        let camera = Camera::from(Projection::perspective(
  102.            1.0,
  103.            std::f32::consts::FRAC_PI_3,
  104.            0.1,
  105.            1000.0,
  106.        ));
  107.        world.create_entity()
  108.            .with(transform)
  109.            .with(camera)
  110.            .with(FlyControlTag)
  111.            .build();
  112.    }
  113. }
  114.  
  115. #[derive(Default)]
  116. struct MySystem {
  117.    x_angle: f32,
  118.    y_angle: f32,
  119.    z_angle: f32,
  120. }
  121.  
  122. impl<'a> System<'a> for MySystem {
  123.    type SystemData = (
  124.        Read<'a, InputHandler<StringBindings>>,
  125.         Read<'a, Time>,
  126.        ReadStorage<'a, Cube>,
  127.         WriteStorage<'a, Transform>
  128.    );
  129.  
  130.    fn run(&mut self, (input, time, cubes, mut transforms): Self::SystemData) {
  131.        self.x_angle += input.axis_value("rotate_x").unwrap() as f32 * time.delta_seconds();
  132.        self.y_angle += input.axis_value("rotate_y").unwrap() as f32 * time.delta_seconds();
  133.        self.z_angle += input.axis_value("rotate_z").unwrap() as f32 * time.delta_seconds();
  134.  
  135.        for (_, transform) in (&cubes, &mut transforms).join() {
  136.            transform.set_rotation_euler(self.x_angle, self.y_angle, self.z_angle);
  137.        }
  138.    }
  139. }
  140.  
  141. fn main() -> amethyst::Result<()> {
  142.    amethyst::start_logger(Default::default());
  143.  
  144.    let app_root = application_root_dir()?;
  145.  
  146.    let resources_dir = app_root.join("resources");
  147.    let display_config_path = resources_dir.join("display_config.ron");
  148.  
  149.    let mut bindings = Bindings::new();
  150.  
  151.    // Camera controls
  152.    bindings.insert_axis(
  153.        "right",
  154.        Axis::Emulated {
  155.            neg: Button::Key(VirtualKeyCode::A),
  156.            pos: Button::Key(VirtualKeyCode::D),
  157.        },
  158.    ).unwrap();
  159.    bindings.insert_axis(
  160.        "up",
  161.        Axis::Emulated {
  162.            neg: Button::Key(VirtualKeyCode::F),
  163.            pos: Button::Key(VirtualKeyCode::R),
  164.        },
  165.    ).unwrap();
  166.    bindings.insert_axis(
  167.        "forward",
  168.        Axis::Emulated {
  169.            neg: Button::Key(VirtualKeyCode::W),
  170.            pos: Button::Key(VirtualKeyCode::S),
  171.        },
  172.    ).unwrap();
  173.  
  174.    // Cube controls
  175.    bindings.insert_axis(
  176.        "rotate_x",
  177.        Axis::Emulated {
  178.            neg: Button::Key(VirtualKeyCode::T),
  179.            pos: Button::Key(VirtualKeyCode::Y),
  180.        },
  181.    ).unwrap();
  182.    bindings.insert_axis(
  183.        "rotate_y",
  184.        Axis::Emulated {
  185.            neg: Button::Key(VirtualKeyCode::G),
  186.            pos: Button::Key(VirtualKeyCode::H),
  187.        },
  188.    ).unwrap();
  189.    bindings.insert_axis(
  190.        "rotate_z",
  191.        Axis::Emulated {
  192.            neg: Button::Key(VirtualKeyCode::B),
  193.            pos: Button::Key(VirtualKeyCode::N),
  194.        },
  195.    ).unwrap();
  196.  
  197.    let input_bundle = InputBundle::<StringBindings>::new()
  198.        .with_bindings(bindings);
  199.  
  200.    let game_data = GameDataBuilder::default()
  201.        .with_bundle(WindowBundle::from_config_path(display_config_path))?
  202.        .with_bundle(TransformBundle::new())?
  203.        .with_bundle(FlyControlBundle::<StringBindings>::new(
  204.            Some(String::from("right")),
  205.            Some(String::from("up")),
  206.            Some(String::from("forward")),
  207.        ))?
  208.        .with_bundle(input_bundle)?
  209.        .with(MySystem::default(), "my_system", &["input_system"])
  210.        .with_thread_local(RenderingSystem::<DefaultBackend, _>::new(
  211.            RenderingGraph::default(),
  212.        ));
  213.  
  214.    let mut game = Application::new(resources_dir, MyState, game_data)?;
  215.    game.run();
  216.  
  217.    Ok(())
  218. }
  219.  
  220. #[derive(Default)]
  221. struct RenderingGraph {
  222.    dimensions: Option<ScreenDimensions>,
  223.    surface_format: Option<Format>,
  224.    dirty: bool,
  225. }
  226.  
  227. impl GraphCreator<DefaultBackend> for RenderingGraph {
  228.    fn rebuild(&mut self, res: &Resources) -> bool {
  229.        // Rebuild when dimensions change, but wait until at least two frames have the same.
  230.        let new_dimensions = res.try_fetch::<ScreenDimensions>();
  231.        use std::ops::Deref;
  232.        if self.dimensions.as_ref() != new_dimensions.as_ref().map(|d| d.deref()) {
  233.            self.dirty = true;
  234.            self.dimensions = new_dimensions.map(|d| d.clone());
  235.            return false;
  236.        }
  237.  
  238.        self.dirty
  239.    }
  240.  
  241.    fn builder(
  242.        &mut self,
  243.        factory: &mut Factory<DefaultBackend>,
  244.        res: &Resources,
  245.    ) -> GraphBuilder<DefaultBackend, Resources> {
  246.        use amethyst::renderer::rendy::{
  247.            graph::present::PresentNode,
  248.            hal::command::{ClearDepthStencil, ClearValue},
  249.        };
  250.  
  251.        self.dirty = false;
  252.        let window = <ReadExpect<'_, Window>>::fetch(res);
  253.         let surface = factory.create_surface(&window);
  254.         // cache surface format to speed things up
  255.         let surface_format = *self
  256.             .surface_format
  257.             .get_or_insert_with(|| factory.get_surface_format(&surface));
  258.         let dimensions = self.dimensions.as_ref().unwrap();
  259.         let window_kind =
  260.             image::Kind::D2(dimensions.width() as u32, dimensions.height() as u32, 1, 1);
  261.  
  262.         let mut graph_builder = GraphBuilder::new();
  263.         let color = graph_builder.create_image(
  264.             window_kind,
  265.             1,
  266.             surface_format,
  267.             Some(ClearValue::Color([0.00, 0.01, 0.02, 1.0].into())),
  268.         );
  269.  
  270.         let depth = graph_builder.create_image(
  271.             window_kind,
  272.             1,
  273.             Format::D32Sfloat,
  274.             Some(ClearValue::DepthStencil(ClearDepthStencil(1.0, 0))),
  275.         );
  276.  
  277.         let opaque = graph_builder.add_node(
  278.             SubpassBuilder::new()
  279.                 //.with_group(DrawShadedDesc::new().builder())
  280.                 .with_group(DrawPbrDesc::new().builder())
  281.                 .with_color(color)
  282.                 .with_depth_stencil(depth)
  283.                 .into_pass(),
  284.         );
  285.  
  286.         let _present = graph_builder
  287.             .add_node(PresentNode::builder(factory, surface, color).with_dependency(opaque));
  288.  
  289.         graph_builder
  290.     }
  291. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top