use crate::graphics::{gl_wrapper::*, texture::Texture};
use cgmath::*;
use super::{camera::Camera, light::Light};
pub struct Scene<'a> {
pub objects: Vec<&'a mut SceneObject>,
pub camera: &'a mut Camera,
pub lights: Vec<&'a mut Light>,
}
impl<'a> Scene<'a> {
pub fn new(camera: &'a mut Camera, lights: Vec<&'a mut Light>) -> Self {
Self {
objects: Vec::new(),
camera,
lights,
}
}
pub fn add_object(&mut self, object: &'a mut SceneObject) {
self.objects.push(object);
}
pub fn draw(&self) {
for object in &self.objects {
object.draw();
}
}
}
pub struct SceneObject {
pub transform: Transform,
pub vao: Vao,
pub shader_program: ShaderProgram,
pub vertex_count: usize,
pub texture: Option<Texture>,
}
impl SceneObject {
pub fn new(vao: Vao, shader_program: ShaderProgram, vertex_count: usize) -> Self {
Self {
transform: Transform::default(),
vao,
shader_program,
vertex_count,
texture: None,
}
}
pub fn draw(&self) {
self.vao.bind();
self.shader_program.bind();
if let Some(texture) = &self.texture {
texture.bind(gl::TEXTURE0);
}
unsafe {
gl::DrawArrays(gl::TRIANGLES, 0, self.vertex_count as i32);
}
}
}
#[derive(Copy, Clone)]
pub struct Transform {
pub position: Vector3<f32>,
pub rotation: Quaternion<f32>,
pub scale: Vector3<f32>,
}
impl Default for Transform {
fn default() -> Self {
Self {
position: Vector3::new(0.0, 0.0, 0.0),
rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0),
scale: Vector3::new(1.0, 1.0, 1.0),
}
}
}
impl Transform {
pub fn new() -> Self {
Self::default()
}
pub fn to_matrix(&self) -> Matrix4<f32> {
Matrix4::from_translation(self.position)
* Matrix4::from(self.rotation)
* Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z)
}
}