Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

129 Zeilen
3.9 KiB

  1. use glc::{
  2. matrix::Matrix4f,
  3. misc::{BindGuard, Bindable},
  4. shader::{Program, Type, Uniform},
  5. texture::Texture,
  6. vector::Vector4f,
  7. };
  8. use space_crush_common::{
  9. components::{Owned, Position, Ship, ShipType, Velocity},
  10. misc::LogResult,
  11. };
  12. use specs::{prelude::*, ReadExpect, ReadStorage, System, World};
  13. use crate::{
  14. components::PlayerVisual,
  15. constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
  16. misc::WorldHelper,
  17. resources::Geometry,
  18. Error,
  19. };
  20. pub struct Ships {
  21. program: Program,
  22. texture_bomber: Texture,
  23. texture_fighter: Texture,
  24. texture_transporter: Texture,
  25. location_model: gl::GLint,
  26. location_glow_color: gl::GLint,
  27. }
  28. impl Ships {
  29. pub fn new(world: &World) -> Result<Self, Error> {
  30. let program = world.load_program(vec![
  31. (Type::Vertex, "resources/shader/ship/vert.glsl"),
  32. (Type::Fragment, "resources/shader/ship/frag.glsl"),
  33. ])?;
  34. program.uniform_block_binding("Camera", UNIFORM_BUFFER_INDEX_CAMERA)?;
  35. program.uniform_block_binding("Global", UNIFORM_BUFFER_INDEX_UNIFORM)?;
  36. let location_model = program.uniform_location("uModel")?;
  37. let location_glow_color = program.uniform_location("uGlowColor")?;
  38. program.bind();
  39. program.uniform("uTexture", Uniform::Texture(0))?;
  40. program.unbind();
  41. let texture_bomber = world.load_texture("resources/textures/ship_bomber.png")?;
  42. let texture_fighter = world.load_texture("resources/textures/ship_fighter.png")?;
  43. let texture_transporter = world.load_texture("resources/textures/ship_transporter.png")?;
  44. Ok(Self {
  45. program,
  46. texture_bomber,
  47. texture_fighter,
  48. texture_transporter,
  49. location_model,
  50. location_glow_color,
  51. })
  52. }
  53. }
  54. #[derive(SystemData)]
  55. pub struct ShipsData<'a> {
  56. geometry: ReadExpect<'a, Geometry>,
  57. position: ReadStorage<'a, Position>,
  58. velocity: ReadStorage<'a, Velocity>,
  59. ship: ReadStorage<'a, Ship>,
  60. owned: ReadStorage<'a, Owned>,
  61. player_visual: ReadStorage<'a, PlayerVisual>,
  62. }
  63. impl<'a> System<'a> for Ships {
  64. type SystemData = ShipsData<'a>;
  65. fn run(&mut self, data: Self::SystemData) {
  66. let ShipsData {
  67. geometry,
  68. position,
  69. velocity,
  70. ship,
  71. owned,
  72. player_visual,
  73. } = data;
  74. gl::enable(gl::BLEND);
  75. gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
  76. let _guard = BindGuard::new(&self.program);
  77. for (p, v, ship, owned) in (&position, &velocity, &ship, owned.maybe()).join() {
  78. let _guard = match ship.type_ {
  79. ShipType::Fighter => BindGuard::new(&self.texture_fighter),
  80. ShipType::Bomber => BindGuard::new(&self.texture_bomber),
  81. ShipType::Transporter => BindGuard::new(&self.texture_transporter),
  82. };
  83. let c = match owned.and_then(|owned| player_visual.get(owned.owner)) {
  84. Some(pv) => &pv.color,
  85. None => &*PLAYER_COLOR_DEFAULT,
  86. };
  87. let p_x = p.pos.x;
  88. let p_y = p.pos.y;
  89. let d_x = v.dir.x;
  90. let d_y = v.dir.y;
  91. let s = p.size;
  92. let m = Matrix4f::new(
  93. Vector4f::new(-s * d_y, s * d_x, 0.0, 0.0),
  94. Vector4f::new(-s * d_x, -s * d_y, 0.0, 0.0),
  95. Vector4f::new(0.0, 0.0, s, 0.0),
  96. Vector4f::new(p_x, p_y, 0.0, 1.0),
  97. );
  98. self.program
  99. .uniform(self.location_glow_color, Uniform::Vector4f(&c))
  100. .error("Error while updating glow color");
  101. self.program
  102. .uniform(self.location_model, Uniform::Matrix4f(&m))
  103. .error("Error while updating model matrix");
  104. geometry.render_quad();
  105. }
  106. gl::disable(gl::BLEND);
  107. }
  108. }