Skip to content

Commit

Permalink
feat: Switch to winit and wgpu (#35)
Browse files Browse the repository at this point in the history
* feat: Switch to winit and wgpu

* feat: Add colors to the vertices

* feat: fmt

* feat: Rework on the pipeline to make things more abstract

* feat: Add transform as an uniform

AND CLOSES #16
  • Loading branch information
suspistew authored Mar 17, 2021
1 parent e4dcb4c commit 4ad3a49
Show file tree
Hide file tree
Showing 29 changed files with 1,023 additions and 414 deletions.
13 changes: 11 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@ parallel = ["legion/parallel"]
legion = { git = "https://github.com/grzi/legion", branch = "feat/uuid_as_optional", default-features = false, features = ["codegen"]}

# window & rendering
miniquad = "0.3.0-alpha.26"
winit = "0.24.0"
wgpu = "0.7.0"
futures = "0.3"

# maths
ultraviolet = "0.7"

# serialization
serde = { version = "1.0.124", features = ["derive"] }
toml = "0.5.8"
bytemuck = { version = "1.4", features = [ "derive" ] }
image = {version = "0.23", default-features = false, features = ["png"]}

# logging
log = { version = "0.4.14", features = ["serde"] }
fern = { version = "0.6.0", features = ["colored"] }
fern = { version = "0.6.0", features = ["colored"] }

[build-dependencies]
anyhow = "1.0"
fs_extra = "1.1"
glob = "0.3"
shaderc = "0.7"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<img src="repo/banner.png" alt="Scion Engine" />

Scion is a minimalist, **easy** to use, modulable game engine built on top of legion and miniquad.
Scion is a minimalist, **easy** to use, modulable game engine built on top of legion, wgpu and winit.



81 changes: 81 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use anyhow::*;
use glob::glob;
use std::fs::{read_to_string, write};
use std::path::PathBuf;

struct ShaderData {
src: String,
src_path: PathBuf,
spv_path: PathBuf,
kind: shaderc::ShaderKind,
}

impl ShaderData {
pub fn load(src_path: PathBuf) -> Result<Self> {
let extension = src_path
.extension()
.context("File has no extension")?
.to_str()
.context("Extension cannot be converted to &str")?;
let kind = match extension {
"vert" => shaderc::ShaderKind::Vertex,
"frag" => shaderc::ShaderKind::Fragment,
"comp" => shaderc::ShaderKind::Compute,
_ => bail!("Unsupported shader: {}", src_path.display()),
};

let src = read_to_string(src_path.clone())?;
let spv_path = src_path.with_extension(format!("{}.spv", extension));

Ok(Self {
src,
src_path,
spv_path,
kind,
})
}
}

fn main() -> Result<()> {
// Collect all shaders recursively within /src/
let mut shader_paths = [
glob("./src/**/*.vert")?,
glob("./src/**/*.frag")?,
glob("./src/**/*.comp")?,
];

// This could be parallelized
let shaders = shader_paths
.iter_mut()
.flatten()
.map(|glob_result| ShaderData::load(glob_result?))
.collect::<Vec<Result<_>>>()
.into_iter()
.collect::<Result<Vec<_>>>()?;

let mut compiler = shaderc::Compiler::new().context("Unable to create shader compiler")?;

// This can't be parallelized. The [shaderc::Compiler] is not
// thread safe. Also, it creates a lot of resources. You could
// spawn multiple processes to handle this, but it would probably
// be better just to only compile shaders that have been changed
// recently.
for shader in shaders {
// This tells cargo to rerun this script if something in /src/ changes.
println!(
"cargo:rerun-if-changed={}",
shader.src_path.as_os_str().to_str().unwrap()
);

let compiled = compiler.compile_into_spirv(
&shader.src,
shader.kind,
&shader.src_path.to_str().unwrap(),
"main",
None,
)?;
write(shader.spv_path, compiled.as_binary_u8())?;
}

Ok(())
}
46 changes: 30 additions & 16 deletions examples/hello-world/main.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,65 @@
use scion::application::Scion;
use scion::game_layer::{GameLayer, SimpleGameLayer};
use scion::legion::{system, Resources, World};
use scion::utils::time::Time;
use scion::game_layer::{SimpleGameLayer, GameLayer};

use scion::renderer::bidimensional::material::{Material2D, Texture2D};
use scion::renderer::bidimensional::transform::{Position2D, Transform2D};
use scion::renderer::bidimensional::triangle::Triangle;
use scion::renderer::bidimensional::material::{Material2D};
use scion::renderer::color::Color;
use scion::renderer::bidimensional::transform::{Transform2D, Position2D};
use scion::utils::time::Time;
use std::path::Path;

fn triangle() -> Triangle {
Triangle {
vertices: [
Position2D { x: -0.5, y: -0.5 },
Position2D { x: 0.5, y: -0.5 },
Position2D { x: 0., y: 0.5 }
Position2D { x: 0., y: 0.5 },
],
uvs: None,
}
}

#[system(for_each)]
fn color(#[state] timer: &mut f32, #[resource] time: &Time, material: &mut Material2D, transform: &mut Transform2D) {
fn color(
#[state] timer: &mut f32,
#[resource] time: &Time,
material: &mut Material2D,
transform: &mut Transform2D,
) {
*timer += time.delta_duration().as_secs_f32();
if *timer > 0.01 {
*timer = 0.;
match material {
Material2D::Color(color) => {
let new_red = if color.red() < 255 { color.red() + 1 } else { 0 };
let new_red = if color.red() < 255 {
color.red() + 1
} else {
0
};
color.replace(Color::new_rgb(new_red, color.green(), color.blue()));
}
_ => {}
}
transform.append_angle(0.1);
}
transform.append_angle(0.1);
}

#[derive(Default)]
struct Layer;

impl SimpleGameLayer for Layer {
fn on_start(&mut self, world: &mut World, _resource: &mut Resources) {
let triangle1 =
(triangle(),
Material2D::Color(Color::new(0, 47, 110, 1.0)),
Transform2D::new(Position2D { x: 0.0, y: 0.0 }, 0.5, 0.)
);
world.extend(vec![triangle1]);
let triangle1 = (
triangle(),
Material2D::Texture(Texture2D::from_png(Path::new("Yo"))),
Transform2D::new(Position2D { x: -1.0, y: 0.0 }, 0.5, 0.),
);
let triangle2 = (
triangle(),
Material2D::Texture(Texture2D::from_png(Path::new("Yo"))),
Transform2D::new(Position2D { x: 1.0, y: 0.0 }, 0.5, 0.),
);
world.extend(vec![triangle1, triangle2]);
}
}

Expand All @@ -54,4 +68,4 @@ fn main() {
.with_system(color_system(0.))
.with_game_layer(GameLayer::weak::<Layer>())
.run();
}
}
Loading

0 comments on commit 4ad3a49

Please # to comment.