M Cargo.lock => Cargo.lock +1 -0
@@ 3427,6 3427,7 @@ version = "0.1.0"
dependencies = [
"amethyst",
"amethyst_gltf",
+ "derivative 2.2.0",
"lazy_static",
"serde",
]
M Cargo.toml => Cargo.toml +1 -0
@@ 11,3 11,4 @@ amethyst_gltf = { path = "amethyst/amethyst_gltf", version = "0.15.3" }
amethyst = { path = "amethyst", version = "0.15.3", features = ["vulkan"]}
serde = { version = "1.0.104", features = ["derive"] }
lazy_static = { version = "1.4" }
+derivative = { version = "2.1.1" }
M rustfmt.toml => rustfmt.toml +1 -1
@@ 1,4 1,4 @@
-max_width = 60
+max_width = 100
hard_tabs = false
tab_spaces = 2
newline_style = "Auto"
M src/main.rs => src/main.rs +16 -29
@@ 4,36 4,31 @@ use amethyst::{
core::transform::TransformBundle,
input::{InputBundle, StringBindings},
prelude::*,
- renderer::{
- plugins::RenderToWindow,
- types::DefaultBackend,
- RenderingBundle,
- },
+ renderer::{bundle::Target, plugins::RenderToWindow, types::DefaultBackend, RenderingBundle},
ui::{RenderUi, UiBundle},
- utils::{application_root_dir, auto_fov::AutoFovSystem}
+ utils::{application_root_dir, auto_fov::AutoFovSystem},
};
use amethyst_gltf::GltfSceneLoaderSystemDesc;
mod body;
mod prefab;
+mod render;
mod systems;
-mod universe;
mod ui;
-mod render;
+mod universe;
use crate::{
prefab::{GLTFPrefab, PlanetPrefab, UiPrefab},
- systems::{BodySystem, GravitySystem, ui::IndicatorSystem},
- universe::Universe,
render::RenderCustom3D,
+ systems::{ui::IndicatorSystem, BodySystem, GravitySystem},
+ universe::Universe,
};
fn main() -> amethyst::Result<()> {
amethyst::start_logger(Default::default());
let app_root = application_root_dir()?;
- let display_config_path =
- app_root.join("config/display.ron");
+ let display_config_path = app_root.join("config/display.ron");
let key_bindings_path = app_root.join("config/keys.ron");
let assets_dir = app_root.join("assets");
@@ 71,34 66,26 @@ fn main() -> amethyst::Result<()> {
.with_sensitivity(0.1, 0.1)
.with_speed(5000f32),
)?
- .with_bundle(
- TransformBundle::new().with_dep(&["fly_movement"]),
- )?
- .with_bundle(
- InputBundle::<StringBindings>::new()
- .with_bindings_from_file(&key_bindings_path)?,
- )?
+ .with_bundle(TransformBundle::new().with_dep(&["fly_movement"]))?
+ .with_bundle(InputBundle::<StringBindings>::new().with_bindings_from_file(&key_bindings_path)?)?
.with_bundle(UiBundle::<StringBindings>::new())?
.with_bundle(
RenderingBundle::<DefaultBackend>::new()
.with_plugin(
- RenderToWindow::from_config_path(
- display_config_path,
- )?
- .with_clear([0.0, 0.0, 0.0, 1.0]),
+ RenderToWindow::from_config_path(display_config_path)?.with_clear([0.0, 0.0, 0.0, 1.0]),
)
.with_plugin(RenderCustom3D::default())
.with_plugin(RenderUi::default()),
)?
.with(AutoFovSystem::default(), "auto_fov", &[])
- .with(GravitySystem::new(time_scale, length_scale, mass_scale), "gravity_system", &[])
+ .with(
+ GravitySystem::new(time_scale, length_scale, mass_scale),
+ "gravity_system",
+ &[],
+ )
.with(BodySystem, "body_system", &[])
.with(IndicatorSystem::default(), "indicator_system", &[]);
- let mut game = Application::new(
- assets_dir,
- Universe::new(),
- game_data,
- )?;
+ let mut game = Application::new(assets_dir, Universe::new(), game_data)?;
game.run();
Ok(())
}
M src/render/mod.rs => src/render/mod.rs +4 -3
@@ 8,13 8,14 @@ use amethyst::renderer::{
},
shader::SpirvShader,
},
- skinning::JointCombined,
- RenderBase3D,
+ skinning::JointCombined
};
+mod plugin;
+
use lazy_static::lazy_static;
-pub type RenderCustom3D = RenderBase3D<CustomPassDef>;
+pub type RenderCustom3D = plugin::CustomRenderPlugin3D<CustomPassDef>;
lazy_static! {
static ref CUSTOM_VERTEX: SpirvShader =
A src/render/plugin.rs => src/render/plugin.rs +93 -0
@@ 0,0 1,93 @@
+use amethyst::{
+ core::ecs::{DispatcherBuilder, World},
+ error::Error,
+ renderer::{
+ bundle::{
+ ImageOptions, OutputColor, RenderOrder, RenderPlan, RenderPlugin, Target, TargetPlanOutputs,
+ },
+ mtl::StaticTextureSet,
+ pass::{Base3DPassDef, DrawBase3DDesc, DrawBase3DTransparentDesc},
+ rendy::{mesh::VertexFormat, shader::SpirvShader},
+ visibility::VisibilitySortingSystem,
+ Backend, Factory, Format, Kind, RenderGroupDesc,
+ },
+ window::ScreenDimensions,
+};
+
+pub trait Custom3DPassDef: 'static + std::fmt::Debug + Send + Sync {
+ const NAME: &'static str;
+ type TextureSet: for<'a> StaticTextureSet<'a>;
+ fn vertex_shader() -> &'static SpirvShader;
+ fn fragment_shader() -> &'static SpirvShader;
+ fn base_format() -> Vec<VertexFormat>;
+ fn skinned_format() -> Vec<VertexFormat>;
+}
+
+#[derive(derivative::Derivative)]
+#[derivative(Default(bound = ""), Debug(bound = ""))]
+pub struct CustomRenderPlugin3D<D: Base3DPassDef> {
+ dimensions: Option<ScreenDimensions>,
+ dirty: bool,
+ _phantomdata: std::marker::PhantomData<D>,
+}
+
+impl<B: Backend, D: Base3DPassDef> RenderPlugin<B> for CustomRenderPlugin3D<D> {
+ fn on_build<'a, 'b>(
+ &mut self,
+ _world: &mut World,
+ builder: &mut DispatcherBuilder<'a, 'b>,
+ ) -> Result<(), Error> {
+ builder.add(VisibilitySortingSystem::new(), "visibility_system", &[]);
+ Ok(())
+ }
+
+ #[allow(clippy::map_clone)]
+ fn should_rebuild(&mut self, world: &World) -> bool {
+ let new_dimensions = world.try_fetch::<ScreenDimensions>();
+ if self.dimensions.as_ref() != new_dimensions.as_deref() {
+ self.dirty = true;
+ self.dimensions = new_dimensions.map(|d| (*d).clone());
+ return false;
+ }
+ self.dirty
+ }
+
+ fn on_plan(
+ &mut self,
+ plan: &mut RenderPlan<B>,
+ _factory: &mut Factory<B>,
+ _world: &World,
+ ) -> Result<(), Error> {
+ use amethyst::renderer::rendy::hal::command::{ClearColor, ClearDepthStencil, ClearValue};
+
+ let dimensions = self.dimensions.as_ref().unwrap();
+ let image_options = ImageOptions {
+ kind: Kind::D2(dimensions.width() as u32, dimensions.height() as u32, 1, 1),
+ levels: 1,
+ format: Format::D32Sfloat,
+ clear: None,
+ };
+ plan.define_pass(
+ Target::Custom("3D"),
+ TargetPlanOutputs {
+ colors: vec![OutputColor::Image(ImageOptions {
+ clear: Some(ClearValue::Color(ClearColor::Sfloat([0., 0., 0., 1.]))),
+ ..image_options
+ })],
+ depth: Some(ImageOptions {
+ clear: Some(ClearValue::DepthStencil(ClearDepthStencil(0.0, 0))),
+ ..image_options
+ }),
+ },
+ )?;
+ plan.extend_target(Target::Custom("3D"), move |ctx| {
+ ctx.add(RenderOrder::Opaque, DrawBase3DDesc::<B, D>::new().builder())?;
+ ctx.add(
+ RenderOrder::Transparent,
+ DrawBase3DTransparentDesc::<B, D>::new().builder(),
+ )?;
+ Ok(())
+ });
+ Ok(())
+ }
+}