Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

85 lignes
2.4 KiB

  1. use std::iter::Iterator;
  2. use glc::{
  3. error::Error as GlcError,
  4. shader::{Program, Shader, Type},
  5. texture::{Data, FilterMag, FilterMin, Target, Texture, Wrap},
  6. };
  7. use space_crush_common::misc::Vfs;
  8. use specs::World;
  9. use crate::Error;
  10. /* WorldHelper */
  11. pub trait WorldHelper {
  12. fn load_program<I>(&self, iter: I) -> Result<Program, Error>
  13. where
  14. I: IntoIterator<Item = (Type, &'static str)>;
  15. fn load_shader(&self, type_: Type, file: &str) -> Result<Shader, Error>;
  16. fn load_texture(&self, path: &str) -> Result<Texture, Error>;
  17. }
  18. impl WorldHelper for World {
  19. fn load_program<I>(&self, iter: I) -> Result<Program, Error>
  20. where
  21. I: IntoIterator<Item = (Type, &'static str)>,
  22. {
  23. Program::from_shaders_result(iter.into_iter().map(|(t, p)| self.load_shader(t, p)))
  24. }
  25. fn load_shader(&self, type_: Type, path: &str) -> Result<Shader, Error> {
  26. let vfs = self.fetch::<Vfs>();
  27. let path = vfs.join(path)?;
  28. let mut file = path.open_file()?;
  29. let path = path.parent().unwrap();
  30. let shader = Shader::from_reader(type_, &mut file, |include| {
  31. let p = if include.starts_with('.') {
  32. path.join(include)
  33. } else {
  34. vfs.join(include)
  35. };
  36. let p = match p {
  37. Ok(p) => p,
  38. Err(err) => return Err(GlcError::ShaderInclude(format!("{}", err))),
  39. };
  40. let mut r = match p.open_file() {
  41. Ok(r) => r,
  42. Err(err) => return Err(GlcError::ShaderInclude(format!("{}", err))),
  43. };
  44. let mut code = String::default();
  45. if let Err(err) = r.read_to_string(&mut code) {
  46. return Err(GlcError::ShaderInclude(format!("{}", err)));
  47. }
  48. Ok(code)
  49. })?;
  50. Ok(shader)
  51. }
  52. fn load_texture(&self, path: &str) -> Result<Texture, Error> {
  53. let vfs = self.fetch::<Vfs>();
  54. let mut file = vfs.join(path)?.open_file()?;
  55. let mut data = Data::from_reader(&mut file)?;
  56. data.convert_to(data.format().info().format_gl_support)?;
  57. let mut texture = Texture::new(Target::Texture2D)?;
  58. texture.upload(&data, true)?;
  59. texture.set_filter(FilterMin::LinearMipmapLinear, FilterMag::Linear)?;
  60. texture.set_wrap(
  61. Wrap::ClampToBorder,
  62. Wrap::ClampToBorder,
  63. Wrap::ClampToBorder,
  64. )?;
  65. Ok(texture)
  66. }
  67. }