Last active
June 6, 2019 05:20
-
-
Save piedoom/7e9fd7f47399903c0aa4ad5d53c5e152 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Pong Tutorial 2 | |
mod assets; | |
mod components; | |
mod data; | |
mod states; | |
mod systems; | |
use crate::systems as s; | |
use crate::assets::config::GameConfig; | |
use crate::assets::prefab::EntityPrefabData; | |
use amethyst::{ | |
assets::{PrefabLoaderSystem, Processor}, | |
core::TransformBundle, | |
ecs::{ReadExpect, Resources, SystemData}, | |
gltf::GltfSceneLoaderSystem, | |
input::InputBundle, | |
prelude::*, | |
renderer::{ | |
palette::Srgb, | |
pass::{ | |
DrawDebugLinesDesc, DrawFlat2DDesc, DrawFlat2DTransparentDesc, DrawFlatDesc, | |
DrawPbrDesc, DrawPbrTransparentDesc, DrawShadedDesc, DrawSkyboxDesc, | |
}, | |
rendy::{ | |
factory::Factory, | |
graph::{ | |
present::PresentNode, | |
render::{RenderGroupDesc, SubpassBuilder}, | |
GraphBuilder, | |
}, | |
hal::{ | |
command::{ClearDepthStencil, ClearValue}, | |
format::Format, | |
image, | |
}, | |
}, | |
sprite::SpriteSheet, | |
sprite_visibility::SpriteVisibilitySortingSystem, | |
system::{GraphCreator, RenderingSystem}, | |
transparent::Transparent, | |
types::{Backend, DefaultBackend}, | |
visibility::VisibilitySortingSystem, | |
}, | |
utils::application_root_dir, | |
window::{ScreenDimensions, Window, WindowBundle}, | |
}; | |
use data::GameBindings; | |
use std::sync::Arc; | |
fn main() -> amethyst::Result<()> { | |
amethyst::start_logger(Default::default()); | |
let app_path = application_root_dir()?; | |
let (assets_path, config_path) = (app_path.join("resources"), app_path.join("resources/config")); | |
let game_data = GameDataBuilder::default() | |
// The WindowBundle provides all the scaffolding for opening a window and drawing to it | |
.with_bundle(WindowBundle::from_config_path( | |
config_path.join("display.ron"), | |
))? | |
// Add the transform bundle which handles tracking entity positions | |
.with_bundle(TransformBundle::new())? | |
.with_bundle( | |
InputBundle::<GameBindings>::new() | |
.with_bindings_from_file(config_path.join("bindings.ron"))?, | |
)? | |
.with( | |
VisibilitySortingSystem::new(), | |
"visibility_system", | |
&["transform_system"], | |
) | |
.with( | |
PrefabLoaderSystem::<EntityPrefabData>::default(), | |
"prefab_loader", | |
&[], | |
) | |
.with( | |
GltfSceneLoaderSystem::default(), | |
"gltf_loader", | |
&["prefab_loader"], // This is important so that entity instantiation is performed in a single frame. | |
) | |
.with( | |
Processor::<SpriteSheet>::new(), | |
"sprite_sheet_processor", | |
&[], | |
) | |
.with( | |
SpriteVisibilitySortingSystem::new(), | |
"sprite_visibility_system", | |
&["transform_system"], | |
) | |
.with(Processor::<GameConfig>::new(), "config_processor", &[]) | |
.with( | |
s::InputSystem::default(), | |
"game_input_system", | |
&[], | |
) | |
.with( | |
s::ControllerSystem::default(), | |
"controller_system", | |
&["game_input_system"], | |
) | |
// The renderer must be executed on the same thread consecutively, so we initialize it as thread_local | |
// which will always execute on the main thread. | |
.with_thread_local(RenderingSystem::<DefaultBackend, _>::new(Graph::default())); | |
let mut game = Application::new( | |
assets_path, | |
states::load::LoadConfigState::default(), | |
game_data, | |
)?; | |
game.run(); | |
Ok(()) | |
} | |
#[derive(Default)] | |
struct Graph { | |
dimensions: Option<ScreenDimensions>, | |
surface_format: Option<Format>, | |
dirty: bool, | |
} | |
impl<B: Backend> GraphCreator<B> for Graph { | |
fn rebuild(&mut self, res: &Resources) -> bool { | |
// Rebuild when dimensions change, but wait until at least two frames have the same. | |
let new_dimensions = res.try_fetch::<ScreenDimensions>(); | |
use std::ops::Deref; | |
if self.dimensions.as_ref() != new_dimensions.as_ref().map(|d| d.deref()) { | |
self.dirty = true; | |
self.dimensions = new_dimensions.map(|d| d.clone()); | |
return false; | |
} | |
return self.dirty; | |
} | |
fn builder(&mut self, factory: &mut Factory<B>, res: &Resources) -> GraphBuilder<B, Resources> { | |
self.dirty = false; | |
let window = <(ReadExpect<'_, Arc<Window>>)>::fetch(res); | |
let surface = factory.create_surface(&window); | |
// cache surface format to speed things up | |
let surface_format = *self | |
.surface_format | |
.get_or_insert_with(|| factory.get_surface_format(&surface)); | |
let dimensions = self.dimensions.as_ref().unwrap(); | |
let window_kind = image::Kind::D2( | |
dbg!(dimensions.width()) as u32, | |
dimensions.height() as u32, | |
1, | |
1, | |
); | |
let mut graph_builder = GraphBuilder::new(); | |
let color = graph_builder.create_image( | |
window_kind, | |
1, | |
surface_format, | |
Some(ClearValue::Color([0.34, 0.36, 0.52, 1.0].into())), | |
); | |
let depth = graph_builder.create_image( | |
window_kind, | |
1, | |
Format::D32Sfloat, | |
Some(ClearValue::DepthStencil(ClearDepthStencil(1.0, 0))), | |
); | |
let mut opaque_subpass = SubpassBuilder::new(); | |
let mut transparent_subpass = SubpassBuilder::new(); | |
opaque_subpass.add_group(DrawPbrDesc::skinned().builder()); | |
transparent_subpass.add_group(DrawPbrTransparentDesc::skinned().builder()); | |
let opaque = graph_builder.add_node( | |
opaque_subpass | |
.with_group(DrawFlat2DDesc::new().builder()) | |
.with_group(DrawDebugLinesDesc::new().builder()) | |
.with_group( | |
DrawSkyboxDesc::with_colors( | |
Srgb::new(0.82, 0.51, 0.50), | |
Srgb::new(0.18, 0.11, 0.85), | |
) | |
.builder(), | |
) | |
.with_color(color) | |
.with_depth_stencil(depth) | |
.into_pass(), | |
); | |
let transparent = graph_builder.add_node( | |
transparent_subpass | |
.with_group( | |
DrawFlat2DTransparentDesc::default() | |
.builder() | |
.with_dependency(opaque), | |
) | |
.with_color(color) | |
.with_depth_stencil(depth) | |
.into_pass(), | |
); | |
let _present = graph_builder.add_node( | |
PresentNode::builder(factory, surface, color) | |
.with_dependency(opaque) | |
.with_dependency(transparent), | |
); | |
graph_builder | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment