| @@ -0,0 +1,28 @@ | |||||
| #version 450 core | |||||
| #pragma include ./shared.glsl | |||||
| #pragma include ../misc/glow.glsl | |||||
| #pragma include ../misc/global.glsl | |||||
| const GlowArgs GLOW_ARGS = { | |||||
| /* step0 */ 0.480, | |||||
| /* step1 */ 0.975, | |||||
| /* pulseSize0 */ 0.010, | |||||
| /* pulseSize1 */ 0.050, | |||||
| /* pulseTime */ 2.000, | |||||
| }; | |||||
| in FragmentData fragmentData; | |||||
| uniform vec4 uGlowColor; | |||||
| uniform sampler2D uTexture; | |||||
| out vec4 outColor; | |||||
| void main() { | |||||
| float alpha = glow(GLOW_ARGS, fragmentData.texCoords - vec2(0.5), uGlobal.time); | |||||
| vec4 glow = vec4(uGlowColor.rgb, uGlowColor.a * alpha); | |||||
| vec4 tex = texture(uTexture, fragmentData.texCoords); | |||||
| outColor = tex * tex.a + glow * (1.0 - tex.a); | |||||
| } | |||||
| @@ -0,0 +1,3 @@ | |||||
| struct FragmentData { | |||||
| vec2 texCoords; | |||||
| }; | |||||
| @@ -0,0 +1,17 @@ | |||||
| #version 450 core | |||||
| #pragma include ./shared.glsl | |||||
| #pragma include ../misc/camera.glsl | |||||
| const float GLOW_SIZE_FACTOR = 2.00; | |||||
| in vec3 inPosition; | |||||
| uniform mat4 uModel; | |||||
| out FragmentData fragmentData; | |||||
| void main() { | |||||
| fragmentData.texCoords = inPosition.xy * GLOW_SIZE_FACTOR + vec2(0.5); | |||||
| gl_Position = uCamera.projection * uCamera.view * uModel * vec4(2.0 * inPosition * GLOW_SIZE_FACTOR, 1.0); | |||||
| } | |||||
| @@ -12,7 +12,7 @@ pub use error::Error; | |||||
| use debug::{Fleets as DebugFleets, Ships as DebugShips, Summary as DebugSummary}; | use debug::{Fleets as DebugFleets, Ships as DebugShips, Summary as DebugSummary}; | ||||
| use misc::{Events, TextManager, Window}; | use misc::{Events, TextManager, Window}; | ||||
| use render::{Init, Planets, Ships}; | |||||
| use render::{Asteroids, Init, Planets, Ships}; | |||||
| use resources::{Camera, Config, Geometry, State, Uniform}; | use resources::{Camera, Config, Geometry, State, Uniform}; | ||||
| use systems::StateUpdate; | use systems::StateUpdate; | ||||
| @@ -46,6 +46,7 @@ impl<'a, 'b> App<'a, 'b> { | |||||
| .with(StateUpdate::new(world)?, "state_update", &[]) | .with(StateUpdate::new(world)?, "state_update", &[]) | ||||
| .with_thread_local(Init::new(world)?) | .with_thread_local(Init::new(world)?) | ||||
| .with_thread_local(Planets::new(world)?) | .with_thread_local(Planets::new(world)?) | ||||
| .with_thread_local(Asteroids::new(world)?) | |||||
| .with_thread_local(Ships::new(world)?) | .with_thread_local(Ships::new(world)?) | ||||
| .with_thread_local(DebugShips::default()) | .with_thread_local(DebugShips::default()) | ||||
| .with_thread_local(DebugFleets::default()) | .with_thread_local(DebugFleets::default()) | ||||
| @@ -28,6 +28,8 @@ fn main() -> Result<(), Error> { | |||||
| } | } | ||||
| fn run(vfs: Vfs) -> Result<(), Error> { | fn run(vfs: Vfs) -> Result<(), Error> { | ||||
| info!("Application initialization"); | |||||
| let mut world = World::new(); | let mut world = World::new(); | ||||
| world.insert(vfs); | world.insert(vfs); | ||||
| @@ -38,6 +40,8 @@ fn run(vfs: Vfs) -> Result<(), Error> { | |||||
| create_world(&mut world); | create_world(&mut world); | ||||
| } | } | ||||
| info!("Application initialized"); | |||||
| while app.is_running() { | while app.is_running() { | ||||
| world.maintain(); | world.maintain(); | ||||
| @@ -56,7 +60,10 @@ fn create_world(world: &mut World) { | |||||
| vector::{Vector2f, Vector4f}, | vector::{Vector2f, Vector4f}, | ||||
| }; | }; | ||||
| use space_crush_common::{ | use space_crush_common::{ | ||||
| components::{Fleet, Owned, Planet, Player, Position, Ship, ShipType, Velocity}, | |||||
| components::{ | |||||
| Asteroid, AsteroidType, Fleet, Owned, Planet, Player, Position, Ship, ShipType, | |||||
| Velocity, | |||||
| }, | |||||
| misc::{PersistWorld, Persistence}, | misc::{PersistWorld, Persistence}, | ||||
| }; | }; | ||||
| use specs::{saveload::MarkedBuilder, Builder}; | use specs::{saveload::MarkedBuilder, Builder}; | ||||
| @@ -68,6 +75,38 @@ fn create_world(world: &mut World) { | |||||
| }) | }) | ||||
| .build(); | .build(); | ||||
| world | |||||
| .create_entity() | |||||
| .marked::<<PersistWorld as Persistence>::Marker>() | |||||
| .with(Position { | |||||
| pos: Vector2f::new(500.0, -500.0), | |||||
| size: 100.0, | |||||
| }) | |||||
| .with(Fleet { | |||||
| orbit_min: 125.0, | |||||
| orbit_max: 175.0, | |||||
| }) | |||||
| .with(Asteroid { | |||||
| type_: AsteroidType::Metal, | |||||
| }) | |||||
| .build(); | |||||
| world | |||||
| .create_entity() | |||||
| .marked::<<PersistWorld as Persistence>::Marker>() | |||||
| .with(Position { | |||||
| pos: Vector2f::new(500.0, 500.0), | |||||
| size: 100.0, | |||||
| }) | |||||
| .with(Fleet { | |||||
| orbit_min: 125.0, | |||||
| orbit_max: 175.0, | |||||
| }) | |||||
| .with(Asteroid { | |||||
| type_: AsteroidType::Crystal, | |||||
| }) | |||||
| .build(); | |||||
| let planet = world | let planet = world | ||||
| .create_entity() | .create_entity() | ||||
| .marked::<<PersistWorld as Persistence>::Marker>() | .marked::<<PersistWorld as Persistence>::Marker>() | ||||
| @@ -0,0 +1,119 @@ | |||||
| use glc::{ | |||||
| matrix::Matrix4f, | |||||
| misc::{BindGuard, Bindable}, | |||||
| shader::{Program, Type, Uniform}, | |||||
| texture::Texture, | |||||
| vector::Vector4f, | |||||
| }; | |||||
| use space_crush_common::{ | |||||
| components::{Asteroid, AsteroidType, Owned, Player, Position}, | |||||
| misc::LogResult, | |||||
| }; | |||||
| use specs::{prelude::*, ReadExpect, ReadStorage, System, World}; | |||||
| use crate::{ | |||||
| constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM}, | |||||
| misc::WorldHelper, | |||||
| resources::Geometry, | |||||
| Error, | |||||
| }; | |||||
| pub struct Asteroids { | |||||
| program: Program, | |||||
| texture_metal: Texture, | |||||
| texture_crystal: Texture, | |||||
| location_model: gl::GLint, | |||||
| location_glow_color: gl::GLint, | |||||
| } | |||||
| impl Asteroids { | |||||
| pub fn new(world: &World) -> Result<Self, Error> { | |||||
| let program = world.load_program(vec![ | |||||
| (Type::Vertex, "resources/shader/asteroid/vert.glsl"), | |||||
| (Type::Fragment, "resources/shader/asteroid/frag.glsl"), | |||||
| ])?; | |||||
| program.uniform_block_binding("Camera", UNIFORM_BUFFER_INDEX_CAMERA)?; | |||||
| program.uniform_block_binding("Global", UNIFORM_BUFFER_INDEX_UNIFORM)?; | |||||
| let location_model = program.uniform_location("uModel")?; | |||||
| let location_glow_color = program.uniform_location("uGlowColor")?; | |||||
| program.bind(); | |||||
| program.uniform("uTexture", Uniform::Texture(0))?; | |||||
| program.unbind(); | |||||
| let texture_metal = world.load_texture("resources/textures/asteroid_metal.png")?; | |||||
| let texture_crystal = world.load_texture("resources/textures/asteroid_crystal.png")?; | |||||
| Ok(Self { | |||||
| program, | |||||
| texture_metal, | |||||
| texture_crystal, | |||||
| location_model, | |||||
| location_glow_color, | |||||
| }) | |||||
| } | |||||
| } | |||||
| #[derive(SystemData)] | |||||
| pub struct AsteroidsData<'a> { | |||||
| geometry: ReadExpect<'a, Geometry>, | |||||
| position: ReadStorage<'a, Position>, | |||||
| asteroid: ReadStorage<'a, Asteroid>, | |||||
| owned: ReadStorage<'a, Owned>, | |||||
| player: ReadStorage<'a, Player>, | |||||
| } | |||||
| impl<'a> System<'a> for Asteroids { | |||||
| type SystemData = AsteroidsData<'a>; | |||||
| fn run(&mut self, data: Self::SystemData) { | |||||
| let AsteroidsData { | |||||
| geometry, | |||||
| position, | |||||
| asteroid, | |||||
| owned, | |||||
| player, | |||||
| } = data; | |||||
| gl::enable(gl::BLEND); | |||||
| gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); | |||||
| let _guard = BindGuard::new(&self.program); | |||||
| for (position, asteroid, owned) in (&position, &asteroid, owned.maybe()).join() { | |||||
| let p_x = position.pos.x; | |||||
| let p_y = position.pos.y; | |||||
| let s = position.size; | |||||
| let _guard = match asteroid.type_ { | |||||
| AsteroidType::Metal => BindGuard::new(&self.texture_metal), | |||||
| AsteroidType::Crystal => BindGuard::new(&self.texture_crystal), | |||||
| }; | |||||
| let c = match owned.and_then(|owned| player.get(owned.owner)) { | |||||
| Some(pv) => &pv.color, | |||||
| None => &*PLAYER_COLOR_DEFAULT, | |||||
| }; | |||||
| let m = Matrix4f::new( | |||||
| Vector4f::new(s, 0.0, 0.0, 0.0), | |||||
| Vector4f::new(0.0, s, 0.0, 0.0), | |||||
| Vector4f::new(0.0, 0.0, s, 0.0), | |||||
| Vector4f::new(p_x, p_y, 0.0, 1.0), | |||||
| ); | |||||
| self.program | |||||
| .uniform(self.location_glow_color, Uniform::Vector4f(&c)) | |||||
| .error("Error while updating glow color"); | |||||
| self.program | |||||
| .uniform(self.location_model, Uniform::Matrix4f(&m)) | |||||
| .error("Error while updating model matrix"); | |||||
| geometry.render_quad(); | |||||
| } | |||||
| gl::disable(gl::BLEND); | |||||
| } | |||||
| } | |||||
| @@ -1,7 +1,9 @@ | |||||
| mod asteroids; | |||||
| mod init; | mod init; | ||||
| mod planets; | mod planets; | ||||
| mod ships; | mod ships; | ||||
| pub use asteroids::Asteroids; | |||||
| pub use init::Init; | pub use init::Init; | ||||
| pub use planets::Planets; | pub use planets::Planets; | ||||
| pub use ships::Ships; | pub use ships::Ships; | ||||
| @@ -0,0 +1,17 @@ | |||||
| use serde::{Deserialize, Serialize}; | |||||
| use specs::{Component, HashMapStorage}; | |||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | |||||
| pub struct Asteroid { | |||||
| pub type_: Type, | |||||
| } | |||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | |||||
| pub enum Type { | |||||
| Metal, | |||||
| Crystal, | |||||
| } | |||||
| impl Component for Asteroid { | |||||
| type Storage = HashMapStorage<Self>; | |||||
| } | |||||
| @@ -1,3 +1,4 @@ | |||||
| mod asteroid; | |||||
| mod fleet; | mod fleet; | ||||
| mod owned; | mod owned; | ||||
| mod planet; | mod planet; | ||||
| @@ -6,6 +7,7 @@ mod position; | |||||
| mod ship; | mod ship; | ||||
| mod velocity; | mod velocity; | ||||
| pub use asteroid::{Asteroid, Type as AsteroidType}; | |||||
| pub use fleet::Fleet; | pub use fleet::Fleet; | ||||
| pub use owned::Owned; | pub use owned::Owned; | ||||
| pub use planet::Planet; | pub use planet::Planet; | ||||