Impl camera and camera shader

At this point, the agnostic_interface is implemented with Raylib. What's
left is testing. Currently the main function does nothing.
This commit is contained in:
Stephen Seo 2023-02-21 14:10:51 +09:00
parent 29a32f590d
commit 31465d0923
6 changed files with 333 additions and 66 deletions

View file

@ -52,14 +52,13 @@ pub trait MusicInterface {
pub trait ShaderInterface { pub trait ShaderInterface {
fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String>; fn set_transform_attrib(&mut self, transform: Transform) -> Result<(), String>;
fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String>; fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String>;
fn set_camera_attrib(&mut self, camera: Vector) -> Result<(), String>;
fn begin_draw_shader(&self) -> Result<(), String>; fn begin_draw_shader(&self) -> Result<(), String>;
fn end_draw_shader(&self) -> Result<(), String>; fn end_draw_shader(&self) -> Result<(), String>;
} }
pub trait CameraInterface { pub trait CameraInterface {
fn get_view(&self) -> Result<Rectangle, String>;
fn get_view_xy(&self) -> Result<(f32, f32), String>; fn get_view_xy(&self) -> Result<(f32, f32), String>;
fn set_view(&mut self, rect: Rectangle) -> Result<(), String>;
fn set_view_xy(&mut self, x: f32, y: f32) -> Result<(), String>; fn set_view_xy(&mut self, x: f32, y: f32) -> Result<(), String>;
} }
@ -113,4 +112,5 @@ pub trait GameInterface {
fn get_camera(&mut self) -> Result<Box<dyn CameraInterface>, String>; fn get_camera(&mut self) -> Result<Box<dyn CameraInterface>, String>;
fn get_default_camera(&mut self) -> Result<Box<dyn CameraInterface>, String>; fn get_default_camera(&mut self) -> Result<Box<dyn CameraInterface>, String>;
fn set_camera(&mut self, camera: &Box<dyn CameraInterface>) -> Result<(), String>; fn set_camera(&mut self, camera: &Box<dyn CameraInterface>) -> Result<(), String>;
fn set_camera_xy(&mut self, x: f32, y: f32) -> Result<(), String>;
} }

View file

@ -19,11 +19,12 @@ use std::{
use crate::{ use crate::{
faux_quicksilver::{Transform, Vector}, 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::{ 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 { fn fqcolor_to_color(c: crate::faux_quicksilver::Color) -> ffi::Color {
@ -84,7 +85,15 @@ impl RaylibShader {
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, &origin_cstr); 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(()) Ok(())
} }
} }
@ -110,6 +119,10 @@ impl ShaderInterface for RaylibShaderHandler {
fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> { fn set_origin_attrib(&mut self, origin: Vector) -> Result<(), String> {
self.shader.borrow_mut().set_origin_attrib(origin) 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 { impl RaylibShaderHandler {
@ -145,7 +158,9 @@ 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>>>, tr_or_cam_shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
cam_shader: Rc<RefCell<Option<RaylibShaderHandler>>>,
camera: Rc<RefCell<Camera>>,
} }
impl RaylibImageHandler { impl RaylibImageHandler {
@ -168,18 +183,37 @@ impl ImageInterface for RaylibImageHandler {
color: crate::faux_quicksilver::Color, color: crate::faux_quicksilver::Color,
) -> Result<(), String> { ) -> Result<(), String> {
self.image_to_texture()?; self.image_to_texture()?;
unsafe { if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
ffi::DrawTexture( cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
*self cam_shader.begin_draw_shader()?;
.image unsafe {
.borrow() ffi::DrawTexture(
.texture *self
.as_ref() .image
.ok_or_else(|| String::from("RaylibImage has no Texture!"))?, .borrow()
x.round() as i32, .texture
y.round() as i32, .as_ref()
fqcolor_to_color(color), .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(()) Ok(())
} }
@ -191,20 +225,41 @@ impl ImageInterface for RaylibImageHandler {
color: crate::faux_quicksilver::Color, color: crate::faux_quicksilver::Color,
) -> Result<(), String> { ) -> Result<(), String> {
self.image_to_texture()?; self.image_to_texture()?;
unsafe { if let Some(cam_shader) = self.cam_shader.borrow_mut().as_mut() {
ffi::DrawTexturePro( cam_shader.set_camera_attrib(self.camera.borrow().pos)?;
*self cam_shader.begin_draw_shader()?;
.image unsafe {
.borrow() ffi::DrawTexturePro(
.texture *self
.as_ref() .image
.ok_or_else(|| String::from("RaylibImage has no Texture!"))?, .borrow()
fqrect_to_rect(sub_rect), .texture
fqrect_to_rect(dest_rect), .as_ref()
ffi::Vector2 { x: 0.0, y: 0.0 }, .ok_or_else(|| String::from("RaylibImage has no Texture!"))?,
0.0, fqrect_to_rect(sub_rect),
fqcolor_to_color(color), 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(()) Ok(())
} }
@ -218,9 +273,10 @@ impl ImageInterface for RaylibImageHandler {
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> Result<(), String> {
self.image_to_texture()?; 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_origin_attrib(origin)?;
shader.set_transform_attrib(transform)?; shader.set_transform_attrib(transform)?;
shader.set_camera_attrib(self.camera.borrow().pos)?;
shader.begin_draw_shader()?; shader.begin_draw_shader()?;
unsafe { unsafe {
ffi::DrawTexture( ffi::DrawTexture(
@ -236,6 +292,23 @@ impl ImageInterface for RaylibImageHandler {
); );
} }
shader.end_draw_shader()?; 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 { } else {
unsafe { unsafe {
ffi::DrawTexture( ffi::DrawTexture(
@ -263,9 +336,10 @@ impl ImageInterface for RaylibImageHandler {
origin: Vector, origin: Vector,
) -> Result<(), String> { ) -> Result<(), String> {
self.image_to_texture()?; 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_origin_attrib(origin)?;
shader.set_transform_attrib(transform)?; shader.set_transform_attrib(transform)?;
shader.set_camera_attrib(self.camera.borrow().pos)?;
shader.begin_draw_shader()?; shader.begin_draw_shader()?;
unsafe { unsafe {
ffi::DrawTexturePro( ffi::DrawTexturePro(
@ -283,6 +357,25 @@ impl ImageInterface for RaylibImageHandler {
); );
} }
shader.end_draw_shader()?; 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 { } else {
unsafe { unsafe {
ffi::DrawTexturePro( ffi::DrawTexturePro(
@ -427,12 +520,38 @@ impl MusicInterface for RaylibMusicHandler {
} }
} }
#[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 { struct RaylibGame {
images: HashMap<String, Rc<RefCell<RaylibImage>>>, images: HashMap<String, Rc<RefCell<RaylibImage>>>,
fonts: HashMap<String, Rc<RaylibFont>>, fonts: HashMap<String, Rc<RaylibFont>>,
sounds: HashMap<String, Rc<RaylibSound>>, sounds: HashMap<String, Rc<RaylibSound>>,
music: HashMap<String, Rc<RefCell<RaylibMusic>>>, music: HashMap<String, Rc<RefCell<RaylibMusic>>>,
shaders: HashMap<String, Rc<RefCell<RaylibShader>>>, shaders: HashMap<String, Rc<RefCell<RaylibShader>>>,
camera: Rc<RefCell<Camera>>,
} }
impl RaylibGame { impl RaylibGame {
@ -445,13 +564,21 @@ impl RaylibGame {
string.as_ptr() as *const c_char, string.as_ptr() as *const c_char,
); );
} }
Box::new(Self { let mut self_unboxed = Self {
images: HashMap::new(), images: HashMap::new(),
fonts: HashMap::new(), fonts: HashMap::new(),
sounds: HashMap::new(), sounds: HashMap::new(),
music: HashMap::new(), music: HashMap::new(),
shaders: 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)
} }
} }
@ -553,13 +680,29 @@ impl GameInterface for RaylibGame {
circle: crate::faux_quicksilver::Circle, circle: crate::faux_quicksilver::Circle,
color: crate::faux_quicksilver::Color, color: crate::faux_quicksilver::Color,
) -> Result<(), String> { ) -> Result<(), String> {
unsafe { if let Some(cam_shader) = self.shaders.get_mut("camera") {
ffi::DrawCircle( cam_shader
circle.x.round() as i32, .borrow_mut()
circle.y.round() as i32, .set_camera_attrib(self.camera.borrow().pos)?;
circle.r, cam_shader.borrow().begin_draw_shader()?;
fqcolor_to_color(color), 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(()) Ok(())
} }
@ -574,6 +717,9 @@ impl GameInterface for RaylibGame {
if let Some(shader) = self.shaders.get_mut("transform_origin") { if let Some(shader) = self.shaders.get_mut("transform_origin") {
shader.borrow_mut().set_origin_attrib(origin)?; shader.borrow_mut().set_origin_attrib(origin)?;
shader.borrow_mut().set_transform_attrib(transform)?; shader.borrow_mut().set_transform_attrib(transform)?;
shader
.borrow_mut()
.set_camera_attrib(self.camera.borrow().pos)?;
shader.borrow().begin_draw_shader()?; shader.borrow().begin_draw_shader()?;
unsafe { unsafe {
ffi::DrawCircle( ffi::DrawCircle(
@ -584,6 +730,20 @@ impl GameInterface for RaylibGame {
); );
} }
shader.borrow().end_draw_shader()?; 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 { } else {
unsafe { unsafe {
ffi::DrawCircle( ffi::DrawCircle(
@ -602,14 +762,31 @@ impl GameInterface for RaylibGame {
rect: crate::faux_quicksilver::Rectangle, rect: crate::faux_quicksilver::Rectangle,
color: crate::faux_quicksilver::Color, color: crate::faux_quicksilver::Color,
) -> Result<(), String> { ) -> Result<(), String> {
unsafe { if let Some(cam_shader) = self.shaders.get_mut("camera") {
ffi::DrawRectangle( cam_shader
rect.x.round() as i32, .borrow_mut()
rect.y.round() as i32, .set_camera_attrib(self.camera.borrow().pos)?;
rect.w.round() as i32, cam_shader.borrow().begin_draw_shader()?;
rect.h.round() as i32, unsafe {
fqcolor_to_color(color), 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(()) Ok(())
} }
@ -621,13 +798,29 @@ impl GameInterface for RaylibGame {
origin: crate::faux_quicksilver::Vector, origin: crate::faux_quicksilver::Vector,
rot: f32, rot: f32,
) -> Result<(), String> { ) -> Result<(), String> {
unsafe { if let Some(cam_shader) = self.shaders.get_mut("camera") {
ffi::DrawRectanglePro( cam_shader
fqrect_to_rect(rect), .borrow_mut()
fqvector_to_vector2(origin), .set_camera_attrib(self.camera.borrow().pos)?;
rot, cam_shader.borrow().begin_draw_shader()?;
fqcolor_to_color(color), 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(()) Ok(())
} }
@ -642,6 +835,9 @@ impl GameInterface for RaylibGame {
if let Some(shader) = self.shaders.get_mut("transform_origin") { if let Some(shader) = self.shaders.get_mut("transform_origin") {
shader.borrow_mut().set_origin_attrib(origin)?; shader.borrow_mut().set_origin_attrib(origin)?;
shader.borrow_mut().set_transform_attrib(transform)?; shader.borrow_mut().set_transform_attrib(transform)?;
shader
.borrow_mut()
.set_camera_attrib(self.camera.borrow().pos)?;
shader.borrow().begin_draw_shader()?; shader.borrow().begin_draw_shader()?;
unsafe { unsafe {
ffi::DrawRectangle( ffi::DrawRectangle(
@ -653,6 +849,21 @@ impl GameInterface for RaylibGame {
); );
} }
shader.borrow().end_draw_shader()?; 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 { } else {
unsafe { unsafe {
ffi::DrawRectangle( ffi::DrawRectangle(
@ -678,7 +889,7 @@ 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> = let tr_or_cam_shader: Option<RaylibShaderHandler> =
if let Some(shader) = self.shaders.get("transform_origin") { if let Some(shader) = self.shaders.get("transform_origin") {
Some(RaylibShaderHandler { Some(RaylibShaderHandler {
shader: shader.clone(), shader: shader.clone(),
@ -686,12 +897,22 @@ impl GameInterface for RaylibGame {
} else { } else {
None 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 { 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)), 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 self.images
.insert(path_str.to_owned(), raylib_image_handler.image.clone()); .insert(path_str.to_owned(), raylib_image_handler.image.clone());
@ -771,20 +992,26 @@ impl GameInterface for RaylibGame {
} }
fn get_camera(&mut self) -> Result<Box<dyn super::CameraInterface>, String> { 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> { 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> { 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 { 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( self.load_shader(
String::from("transform_origin"), String::from("transform_origin"),
&PathBuf::from_str("static/transform.vs") &PathBuf::from_str("static/transform.vs")
@ -793,4 +1020,14 @@ impl RaylibGame {
.map_err(|_| String::from("Failed to convert \"static/simple.fs\" to path!"))?, .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!"))?,
)
}
} }

View file

@ -143,6 +143,12 @@ impl Vector {
} }
} }
impl From<(f32, f32)> for Vector {
fn from(t: (f32, f32)) -> Self {
Self { x: t.0, y: t.1 }
}
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Transform { pub struct Transform {
pub mat: [f32; 9], pub mat: [f32; 9],

View file

@ -40,7 +40,7 @@ pub fn set_transform_3f(index: ::std::os::raw::c_uint, transform: Transform) {
} }
} }
pub fn set_origin_2f(index: ::std::os::raw::c_uint, origin: Vector) { pub fn set_attr_2f(index: ::std::os::raw::c_uint, origin: Vector) {
unsafe { unsafe {
glVertexAttrib2f(index, origin.x, origin.y); glVertexAttrib2f(index, origin.x, origin.y);
} }

23
static/camera.vs Normal file
View file

@ -0,0 +1,23 @@
#version 100
// Input vertex attributes
attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord;
attribute vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
// Output vertex attributes (to fragment shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// custom
attribute vec2 camera;
void main() {
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
gl_Position = mvp * vec4(vertexPosition - vec3(camera, 0.0), 1.0);
}

View file

@ -13,6 +13,7 @@ varying vec2 fragTexCoord;
varying vec4 fragColor; varying vec4 fragColor;
// custom // custom
attribute vec2 camera;
attribute vec2 origin; attribute vec2 origin;
attribute mat3 transform; attribute mat3 transform;
@ -21,5 +22,5 @@ void main() {
fragColor = vertexColor; fragColor = vertexColor;
vec3 pos = transform * (vertexPosition - vec3(origin, 0.0)) + vec3(origin, 0.0); vec3 pos = transform * (vertexPosition - vec3(origin, 0.0)) + vec3(origin, 0.0);
gl_Position = mvp * vec4(pos, 1.0); gl_Position = mvp * vec4(pos - camera, 1.0);
} }