From 29a32f590d8124261c67cbdce8d839241b48ad9b Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Tue, 21 Feb 2023 12:33:28 +0900 Subject: [PATCH] Impl transform/origin shader loading/usage --- src/agnostic_interface/raylib_impl.rs | 190 ++++++++++++++++++++++++-- {raylib => static}/simple.fs | 0 {raylib => static}/transform.vs | 0 3 files changed, 175 insertions(+), 15 deletions(-) rename {raylib => static}/simple.fs (100%) rename {raylib => static}/transform.vs (100%) diff --git a/src/agnostic_interface/raylib_impl.rs b/src/agnostic_interface/raylib_impl.rs index c8b7e09..cdaf8cb 100644 --- a/src/agnostic_interface/raylib_impl.rs +++ b/src/agnostic_interface/raylib_impl.rs @@ -12,8 +12,9 @@ use std::{ collections::HashMap, ffi::CString, os::raw::{c_char, c_int}, - path::Path, + path::{Path, PathBuf}, rc::Rc, + str::FromStr, }; use crate::{ @@ -56,25 +57,18 @@ impl RaylibShader { pub fn get_shader_id(&self) -> ::std::os::raw::c_uint { self.shader.id as ::std::os::raw::c_uint } -} -#[derive(Clone, Debug)] -struct RaylibShaderHandler { - shader: Rc>, -} - -impl ShaderInterface for RaylibShaderHandler { fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String> { let transform_cstr = CString::new("transform") .map_err(|_| String::from("Failed to create \"transform\" CString!"))?; - let attr_loc = get_attrib_location(&self.shader.borrow(), &transform_cstr); + let attr_loc = get_attrib_location(self, &transform_cstr); set_transform_3f(attr_loc, transform); Ok(()) } fn begin_draw_shader(&self) -> Result<(), String> { unsafe { - ffi::BeginShaderMode(self.shader.borrow().shader); + ffi::BeginShaderMode(self.shader); } Ok(()) } @@ -89,12 +83,35 @@ impl ShaderInterface for RaylibShaderHandler { fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> { let origin_cstr = CString::new("origin") .map_err(|_| String::from("Failed to create \"origin\" CString!"))?; - let attr_loc = get_attrib_location(&self.shader.borrow(), &origin_cstr); + let attr_loc = get_attrib_location(self, &origin_cstr); set_origin_2f(attr_loc, origin); Ok(()) } } +#[derive(Clone, Debug)] +struct RaylibShaderHandler { + shader: Rc>, +} + +impl ShaderInterface for RaylibShaderHandler { + fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String> { + self.shader.borrow_mut().set_transform_attrib(transform) + } + + fn begin_draw_shader(&self) -> Result<(), String> { + self.shader.borrow().begin_draw_shader() + } + + fn end_draw_shader(&self) -> Result<(), String> { + self.shader.borrow().end_draw_shader() + } + + fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> { + self.shader.borrow_mut().set_origin_attrib(origin) + } +} + impl RaylibShaderHandler { pub fn load_shader(vs: &Path, fs: &Path) -> Result { unsafe { @@ -128,6 +145,7 @@ struct RaylibImage { #[derive(Clone, Debug)] struct RaylibImageHandler { image: Rc>, + shader: Rc>>, } impl RaylibImageHandler { @@ -199,7 +217,41 @@ impl ImageInterface for RaylibImageHandler { transform: crate::faux_quicksilver::Transform, origin: Vector, ) -> Result<(), String> { - todo!() + self.image_to_texture()?; + if let Some(shader) = self.shader.borrow_mut().as_mut() { + shader.set_origin_attrib(origin)?; + shader.set_transform_attrib(transform)?; + shader.begin_draw_shader()?; + unsafe { + ffi::DrawTexture( + *self + .image + .borrow() + .texture + .as_ref() + .ok_or_else(|| String::from("RaylibImage has no Texture!"))?, + x.round() as i32, + y.round() as i32, + fqcolor_to_color(color), + ); + } + shader.end_draw_shader()?; + } else { + unsafe { + ffi::DrawTexture( + *self + .image + .borrow() + .texture + .as_ref() + .ok_or_else(|| String::from("RaylibImage has no Texture!"))?, + x.round() as i32, + y.round() as i32, + fqcolor_to_color(color), + ); + } + } + Ok(()) } fn draw_sub_transform( @@ -210,7 +262,45 @@ impl ImageInterface for RaylibImageHandler { transform: crate::faux_quicksilver::Transform, origin: Vector, ) -> Result<(), String> { - todo!() + self.image_to_texture()?; + if let Some(shader) = self.shader.borrow_mut().as_mut() { + shader.set_origin_attrib(origin)?; + shader.set_transform_attrib(transform)?; + shader.begin_draw_shader()?; + unsafe { + ffi::DrawTexturePro( + *self + .image + .borrow() + .texture + .as_ref() + .ok_or_else(|| String::from("RaylibImage has no Texture!"))?, + fqrect_to_rect(sub_rect), + fqrect_to_rect(dest_rect), + ffi::Vector2 { x: 0.0, y: 0.0 }, + 0.0, + fqcolor_to_color(color), + ); + } + shader.end_draw_shader()?; + } else { + unsafe { + ffi::DrawTexturePro( + *self + .image + .borrow() + .texture + .as_ref() + .ok_or_else(|| String::from("RaylibImage has no Texture!"))?, + fqrect_to_rect(sub_rect), + fqrect_to_rect(dest_rect), + ffi::Vector2 { x: 0.0, y: 0.0 }, + 0.0, + fqcolor_to_color(color), + ); + } + } + Ok(()) } fn get_w(&self) -> usize { @@ -278,6 +368,7 @@ struct RaylibSoundHandler { impl SoundInterface for RaylibSoundHandler { fn play(&mut self, vol: f32) -> Result<(), String> { unsafe { + ffi::SetSoundVolume(self.sound.sound, vol); ffi::PlaySound(self.sound.sound); } Ok(()) @@ -480,7 +571,30 @@ impl GameInterface for RaylibGame { transform: crate::faux_quicksilver::Transform, origin: Vector, ) -> Result<(), String> { - todo!() + if let Some(shader) = self.shaders.get_mut("transform_origin") { + shader.borrow_mut().set_origin_attrib(origin)?; + shader.borrow_mut().set_transform_attrib(transform)?; + shader.borrow().begin_draw_shader()?; + unsafe { + ffi::DrawCircle( + circle.x.round() as i32, + circle.y.round() as i32, + circle.r, + fqcolor_to_color(color), + ); + } + shader.borrow().end_draw_shader()?; + } else { + unsafe { + ffi::DrawCircle( + circle.x.round() as i32, + circle.y.round() as i32, + circle.r, + fqcolor_to_color(color), + ); + } + } + Ok(()) } fn draw_rect( @@ -525,7 +639,32 @@ impl GameInterface for RaylibGame { transform: crate::faux_quicksilver::Transform, origin: Vector, ) -> Result<(), String> { - todo!() + if let Some(shader) = self.shaders.get_mut("transform_origin") { + shader.borrow_mut().set_origin_attrib(origin)?; + shader.borrow_mut().set_transform_attrib(transform)?; + shader.borrow().begin_draw_shader()?; + unsafe { + ffi::DrawRectangle( + rect.x.round() as i32, + rect.y.round() as i32, + rect.w.round() as i32, + rect.h.round() as i32, + fqcolor_to_color(color), + ); + } + shader.borrow().end_draw_shader()?; + } else { + unsafe { + ffi::DrawRectangle( + rect.x.round() as i32, + rect.y.round() as i32, + rect.w.round() as i32, + rect.h.round() as i32, + fqcolor_to_color(color), + ); + } + } + Ok(()) } fn load_image( @@ -539,11 +678,20 @@ impl GameInterface for RaylibGame { let path_buf: Vec = path_str.as_bytes().into(); let cstring: CString = CString::from_vec_unchecked(path_buf); let image = ffi::LoadImage(cstring.as_ptr()); + let shader: Option = + if let Some(shader) = self.shaders.get("transform_origin") { + Some(RaylibShaderHandler { + shader: shader.clone(), + }) + } else { + None + }; let raylib_image_handler = RaylibImageHandler { image: Rc::new(RefCell::new(RaylibImage { image, texture: None, })), + shader: Rc::new(RefCell::new(shader)), }; self.images .insert(path_str.to_owned(), raylib_image_handler.image.clone()); @@ -634,3 +782,15 @@ impl GameInterface for RaylibGame { todo!() } } + +impl RaylibGame { + pub fn load_transform_origin_shader(&mut self) -> Result, String> { + self.load_shader( + String::from("transform_origin"), + &PathBuf::from_str("static/transform.vs") + .map_err(|_| String::from("Failed to convert \"static/transform.vs\" to path!"))?, + &PathBuf::from_str("static/simple.fs") + .map_err(|_| String::from("Failed to convert \"static/simple.fs\" to path!"))?, + ) + } +} diff --git a/raylib/simple.fs b/static/simple.fs similarity index 100% rename from raylib/simple.fs rename to static/simple.fs diff --git a/raylib/transform.vs b/static/transform.vs similarity index 100% rename from raylib/transform.vs rename to static/transform.vs