use crate::{
faux_quicksilver::{Transform, Vector},
- shaders::{get_attrib_location, set_origin_2f, set_transform_3f},
+ shaders::{get_attrib_location, set_attr_2f, set_transform_3f},
};
use super::{
- FontInterface, GameInterface, ImageInterface, MusicInterface, ShaderInterface, SoundInterface,
+ CameraInterface, FontInterface, GameInterface, ImageInterface, MusicInterface, ShaderInterface,
+ SoundInterface,
};
fn fqcolor_to_color(c: crate::faux_quicksilver::Color) -> ffi::Color {
let origin_cstr = CString::new("origin")
.map_err(|_| String::from("Failed to create \"origin\" CString!"))?;
let attr_loc = get_attrib_location(self, &origin_cstr);
- set_origin_2f(attr_loc, origin);
+ set_attr_2f(attr_loc, origin);
+ Ok(())
+ }
+
+ fn set_camera_attrib(&mut self, camera: Vector) -> Result<(), String> {
+ let camera_cstr = CString::new("camera")
+ .map_err(|_| String::from("Failed to create \"camera\" CString!"))?;
+ let attr_loc = get_attrib_location(self, &camera_cstr);
+ set_attr_2f(attr_loc, camera);
Ok(())
}
}
fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> {
self.shader.borrow_mut().set_origin_attrib(origin)
}
+
+ fn set_camera_attrib(&mut self, camera: Vector) -> Result<(), String> {
+ self.shader.borrow_mut().set_camera_attrib(camera)
+ }
}
impl RaylibShaderHandler {
#[derive(Clone, Debug)]
struct RaylibImageHandler {
image: Rc<RefCell<RaylibImage>>,
- shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
+ tr_or_cam_shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
+ cam_shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
+ camera: Rc<RefCell<Camera>>,
}
impl RaylibImageHandler {
color: crate::faux_quicksilver::Color,
) -> Result<(), String> {
self.image_to_texture()?;
- 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),
- );
+ if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
+ cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_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(())
}
color: crate::faux_quicksilver::Color,
) -> Result<(), String> {
self.image_to_texture()?;
- 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),
- );
+ if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
+ cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_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(())
}
origin: Vector,
) -> Result<(), String> {
self.image_to_texture()?;
- if let Some(shader) = self.shader.borrow_mut().as_mut() {
+ if let Some(shader) = self.tr_or_cam_shader.borrow_mut().as_mut() {
shader.set_origin_attrib(origin)?;
shader.set_transform_attrib(transform)?;
+ shader.set_camera_attrib(self.camera.borrow().pos)?;
shader.begin_draw_shader()?;
unsafe {
ffi::DrawTexture(
);
}
shader.end_draw_shader()?;
+ } else if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
+ cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_shader.end_draw_shader()?;
} else {
unsafe {
ffi::DrawTexture(
origin: Vector,
) -> Result<(), String> {
self.image_to_texture()?;
- if let Some(shader) = self.shader.borrow_mut().as_mut() {
+ if let Some(shader) = self.tr_or_cam_shader.borrow_mut().as_mut() {
shader.set_origin_attrib(origin)?;
shader.set_transform_attrib(transform)?;
+ shader.set_camera_attrib(self.camera.borrow().pos)?;
shader.begin_draw_shader()?;
unsafe {
ffi::DrawTexturePro(
);
}
shader.end_draw_shader()?;
+ } else if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
+ cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_shader.end_draw_shader()?;
} else {
unsafe {
ffi::DrawTexturePro(
}
}
+#[derive(Debug, Clone)]
+struct Camera {
+ pos: Vector,
+}
+
+impl Default for Camera {
+ fn default() -> Self {
+ Self {
+ pos: Vector { x: 0.0, y: 0.0 },
+ }
+ }
+}
+
+impl CameraInterface for Camera {
+ fn get_view_xy(&self) -> Result<(f32, f32), String> {
+ Ok((self.pos.x, self.pos.y))
+ }
+
+ fn set_view_xy(&mut self, x: f32, y: f32) -> Result<(), String> {
+ self.pos.x = x;
+ self.pos.y = y;
+ Ok(())
+ }
+}
+
struct RaylibGame {
images: HashMap<String, Rc<RefCell<RaylibImage>>>,
fonts: HashMap<String, Rc<RaylibFont>>,
sounds: HashMap<String, Rc<RaylibSound>>,
music: HashMap<String, Rc<RefCell<RaylibMusic>>>,
shaders: HashMap<String, Rc<RefCell<RaylibShader>>>,
+ camera: Rc<RefCell<Camera>>,
}
impl RaylibGame {
string.as_ptr() as *const c_char,
);
}
- Box::new(Self {
+ let mut self_unboxed = Self {
images: HashMap::new(),
fonts: HashMap::new(),
sounds: HashMap::new(),
music: HashMap::new(),
shaders: HashMap::new(),
- })
+ camera: Rc::new(RefCell::new(Camera::default())),
+ };
+ if let Err(e) = self_unboxed.load_transform_origin_shader() {
+ println!("WARNING: {e:?}");
+ }
+ if let Err(e) = self_unboxed.load_camera_shader() {
+ println!("WARNING: {e:?}");
+ }
+ Box::new(self_unboxed)
}
}
circle: crate::faux_quicksilver::Circle,
color: crate::faux_quicksilver::Color,
) -> Result<(), String> {
- unsafe {
- ffi::DrawCircle(
- circle.x.round() as i32,
- circle.y.round() as i32,
- circle.r,
- fqcolor_to_color(color),
- );
+ if let Some(cam_shader) = self.shaders.get_mut("camera") {
+ cam_shader
+ .borrow_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
+ cam_shader.borrow().begin_draw_shader()?;
+ unsafe {
+ ffi::DrawCircle(
+ circle.x.round() as i32,
+ circle.y.round() as i32,
+ circle.r,
+ fqcolor_to_color(color),
+ );
+ }
+ cam_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(())
}
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_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
shader.borrow().begin_draw_shader()?;
unsafe {
ffi::DrawCircle(
);
}
shader.borrow().end_draw_shader()?;
+ } else if let Some(cam_shader) = self.shaders.get_mut("camera") {
+ cam_shader
+ .borrow_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
+ cam_shader.borrow().begin_draw_shader()?;
+ unsafe {
+ ffi::DrawCircle(
+ circle.x.round() as i32,
+ circle.y.round() as i32,
+ circle.r,
+ fqcolor_to_color(color),
+ );
+ }
+ cam_shader.borrow().end_draw_shader()?;
} else {
unsafe {
ffi::DrawCircle(
rect: crate::faux_quicksilver::Rectangle,
color: crate::faux_quicksilver::Color,
) -> Result<(), String> {
- 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),
- );
+ if let Some(cam_shader) = self.shaders.get_mut("camera") {
+ cam_shader
+ .borrow_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_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(())
}
origin: crate::faux_quicksilver::Vector,
rot: f32,
) -> Result<(), String> {
- unsafe {
- ffi::DrawRectanglePro(
- fqrect_to_rect(rect),
- fqvector_to_vector2(origin),
- rot,
- fqcolor_to_color(color),
- );
+ if let Some(cam_shader) = self.shaders.get_mut("camera") {
+ cam_shader
+ .borrow_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
+ cam_shader.borrow().begin_draw_shader()?;
+ unsafe {
+ ffi::DrawRectanglePro(
+ fqrect_to_rect(rect),
+ fqvector_to_vector2(origin),
+ rot,
+ fqcolor_to_color(color),
+ );
+ }
+ cam_shader.borrow().end_draw_shader()?;
+ } else {
+ unsafe {
+ ffi::DrawRectanglePro(
+ fqrect_to_rect(rect),
+ fqvector_to_vector2(origin),
+ rot,
+ fqcolor_to_color(color),
+ );
+ }
}
Ok(())
}
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_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
shader.borrow().begin_draw_shader()?;
unsafe {
ffi::DrawRectangle(
);
}
shader.borrow().end_draw_shader()?;
+ } else if let Some(cam_shader) = self.shaders.get_mut("camera") {
+ cam_shader
+ .borrow_mut()
+ .set_camera_attrib(self.camera.borrow().pos)?;
+ cam_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),
+ );
+ }
+ cam_shader.borrow().end_draw_shader()?;
} else {
unsafe {
ffi::DrawRectangle(
let path_buf: Vec<u8> = path_str.as_bytes().into();
let cstring: CString = CString::from_vec_unchecked(path_buf);
let image = ffi::LoadImage(cstring.as_ptr());
- let shader: Option<RaylibShaderHandler> =
+ let tr_or_cam_shader: Option<RaylibShaderHandler> =
if let Some(shader) = self.shaders.get("transform_origin") {
Some(RaylibShaderHandler {
shader: shader.clone(),
} else {
None
};
+ let cam_shader: Option<RaylibShaderHandler> =
+ if let Some(shader) = self.shaders.get("camera") {
+ 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)),
+ tr_or_cam_shader: Rc::new(RefCell::new(tr_or_cam_shader)),
+ cam_shader: Rc::new(RefCell::new(cam_shader)),
+ camera: self.camera.clone(),
};
self.images
.insert(path_str.to_owned(), raylib_image_handler.image.clone());
}
fn get_camera(&mut self) -> Result<Box<dyn super::CameraInterface>, String> {
- todo!()
+ Ok(Box::new(self.camera.borrow().clone()))
}
fn get_default_camera(&mut self) -> Result<Box<dyn super::CameraInterface>, String> {
- todo!()
+ Ok(Box::new(Camera::default()))
}
fn set_camera(&mut self, camera: &Box<dyn super::CameraInterface>) -> Result<(), String> {
- todo!()
+ self.camera.borrow_mut().pos = camera.as_ref().get_view_xy()?.into();
+ Ok(())
+ }
+
+ fn set_camera_xy(&mut self, x: f32, y: f32) -> Result<(), String> {
+ self.camera.borrow_mut().pos = Vector { x, y };
+ Ok(())
}
}
impl RaylibGame {
- pub fn load_transform_origin_shader(&mut self) -> Result<Box<dyn ShaderInterface>, String> {
+ 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/simple.fs\" to path!"))?,
)
}
+
+ fn load_camera_shader(&mut self) -> Result<Box<dyn ShaderInterface>, String> {
+ self.load_shader(
+ String::from("camera"),
+ &PathBuf::from_str("static/camera.vs")
+ .map_err(|_| String::from("Failed to convert \"static/camera.vs\" to path!"))?,
+ &PathBuf::from_str("static/simple.fs")
+ .map_err(|_| String::from("Failed to convert \"static/camera.vs\" to path!"))?,
+ )
+ }
}