Impl transform/origin shader loading/usage

This commit is contained in:
Stephen Seo 2023-02-21 12:33:28 +09:00
parent ad1d2536a3
commit 29a32f590d
3 changed files with 175 additions and 15 deletions

View file

@ -12,8 +12,9 @@ use std::{
collections::HashMap, collections::HashMap,
ffi::CString, ffi::CString,
os::raw::{c_char, c_int}, os::raw::{c_char, c_int},
path::Path, path::{Path, PathBuf},
rc::Rc, rc::Rc,
str::FromStr,
}; };
use crate::{ use crate::{
@ -56,25 +57,18 @@ impl RaylibShader {
pub fn get_shader_id(&self) -> ::std::os::raw::c_uint { pub fn get_shader_id(&self) -> ::std::os::raw::c_uint {
self.shader.id as ::std::os::raw::c_uint self.shader.id as ::std::os::raw::c_uint
} }
}
#[derive(Clone, Debug)]
struct RaylibShaderHandler {
shader: Rc<RefCell<RaylibShader>>,
}
impl ShaderInterface for RaylibShaderHandler {
fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String> { fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String> {
let transform_cstr = CString::new("transform") let transform_cstr = CString::new("transform")
.map_err(|_| String::from("Failed to create \"transform\" CString!"))?; .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); set_transform_3f(attr_loc, transform);
Ok(()) Ok(())
} }
fn begin_draw_shader(&self) -> Result<(), String> { fn begin_draw_shader(&self) -> Result<(), String> {
unsafe { unsafe {
ffi::BeginShaderMode(self.shader.borrow().shader); ffi::BeginShaderMode(self.shader);
} }
Ok(()) Ok(())
} }
@ -89,12 +83,35 @@ impl ShaderInterface for RaylibShaderHandler {
fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> { fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> {
let origin_cstr = CString::new("origin") let origin_cstr = CString::new("origin")
.map_err(|_| String::from("Failed to create \"origin\" CString!"))?; .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); set_origin_2f(attr_loc, origin);
Ok(()) Ok(())
} }
} }
#[derive(Clone, Debug)]
struct RaylibShaderHandler {
shader: Rc<RefCell<RaylibShader>>,
}
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 { impl RaylibShaderHandler {
pub fn load_shader(vs: &Path, fs: &Path) -> Result<Self, String> { pub fn load_shader(vs: &Path, fs: &Path) -> Result<Self, String> {
unsafe { unsafe {
@ -128,6 +145,7 @@ struct RaylibImage {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct RaylibImageHandler { struct RaylibImageHandler {
image: Rc<RefCell<RaylibImage>>, image: Rc<RefCell<RaylibImage>>,
shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
} }
impl RaylibImageHandler { impl RaylibImageHandler {
@ -199,7 +217,41 @@ impl ImageInterface for RaylibImageHandler {
transform: crate::faux_quicksilver::Transform, transform: crate::faux_quicksilver::Transform,
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> 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( fn draw_sub_transform(
@ -210,7 +262,45 @@ impl ImageInterface for RaylibImageHandler {
transform: crate::faux_quicksilver::Transform, transform: crate::faux_quicksilver::Transform,
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> 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 { fn get_w(&self) -> usize {
@ -278,6 +368,7 @@ struct RaylibSoundHandler {
impl SoundInterface for RaylibSoundHandler { impl SoundInterface for RaylibSoundHandler {
fn play(&mut self, vol: f32) -> Result<(), String> { fn play(&mut self, vol: f32) -> Result<(), String> {
unsafe { unsafe {
ffi::SetSoundVolume(self.sound.sound, vol);
ffi::PlaySound(self.sound.sound); ffi::PlaySound(self.sound.sound);
} }
Ok(()) Ok(())
@ -480,7 +571,30 @@ impl GameInterface for RaylibGame {
transform: crate::faux_quicksilver::Transform, transform: crate::faux_quicksilver::Transform,
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> 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( fn draw_rect(
@ -525,7 +639,32 @@ impl GameInterface for RaylibGame {
transform: crate::faux_quicksilver::Transform, transform: crate::faux_quicksilver::Transform,
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> 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( fn load_image(
@ -539,11 +678,20 @@ impl GameInterface for RaylibGame {
let path_buf: Vec<u8> = path_str.as_bytes().into(); let path_buf: Vec<u8> = path_str.as_bytes().into();
let cstring: CString = CString::from_vec_unchecked(path_buf); let cstring: CString = CString::from_vec_unchecked(path_buf);
let image = ffi::LoadImage(cstring.as_ptr()); let image = ffi::LoadImage(cstring.as_ptr());
let shader: Option<RaylibShaderHandler> =
if let Some(shader) = self.shaders.get("transform_origin") {
Some(RaylibShaderHandler {
shader: shader.clone(),
})
} else {
None
};
let raylib_image_handler = RaylibImageHandler { let raylib_image_handler = RaylibImageHandler {
image: Rc::new(RefCell::new(RaylibImage { image: Rc::new(RefCell::new(RaylibImage {
image, image,
texture: None, texture: None,
})), })),
shader: Rc::new(RefCell::new(shader)),
}; };
self.images self.images
.insert(path_str.to_owned(), raylib_image_handler.image.clone()); .insert(path_str.to_owned(), raylib_image_handler.image.clone());
@ -634,3 +782,15 @@ impl GameInterface for RaylibGame {
todo!() todo!()
} }
} }
impl RaylibGame {
pub fn load_transform_origin_shader(&mut self) -> Result<Box<dyn ShaderInterface>, 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!"))?,
)
}
}