summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-11-12 23:27:26 +0100
committerHampusM <hampus@hampusmat.com>2023-11-12 23:27:26 +0100
commit04e778802c0d9fd84ffd68ba7f7b9a26ea7640b8 (patch)
treea5bb6aa08013027860930fb04cb8884bc15bb182
parentd3f35b7be8398f9027eeb3f7f6a78d51b1627375 (diff)
feat: replace rectable & triangle with lighted cubes
-rw-r--r--src/cube.rs522
-rw-r--r--src/main.rs170
-rwxr-xr-xvent.pngbin0 -> 1573477 bytes
3 files changed, 638 insertions, 54 deletions
diff --git a/src/cube.rs b/src/cube.rs
new file mode 100644
index 0000000..d81eb76
--- /dev/null
+++ b/src/cube.rs
@@ -0,0 +1,522 @@
+use engine::math::calc_triangle_surface_normal;
+use engine::object::Builder as ObjectBuilder;
+use engine::vector::Vec3;
+use engine::vertex::{Builder as VertexBuilder, Vertex};
+
+pub enum Side
+{
+ Front,
+ Back,
+ Left,
+ Right,
+ Top,
+ Bottom,
+}
+
+pub enum Corner
+{
+ TopRight,
+ TopLeft,
+ BottomRight,
+ BottomLeft,
+}
+
+pub fn create_cube(
+ vertex_builder_cb: impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder,
+) -> ObjectBuilder
+{
+ let mut vertices: [Option<Vertex>; VertexIndex::VARIANT_CNT] =
+ [(); VertexIndex::VARIANT_CNT].map(|()| None);
+
+ let front_top_right_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 };
+ let front_bottom_right_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 };
+ let front_bottom_left_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 };
+ let front_top_left_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 };
+
+ let front_normal = calc_triangle_surface_normal(
+ &front_top_right_pos,
+ &front_bottom_right_pos,
+ &front_top_left_pos,
+ );
+
+ vertices[VertexIndex::FrontTopRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(front_top_right_pos)
+ .normal(front_normal.clone()),
+ Side::Front,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::FrontBottomRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(front_bottom_right_pos)
+ .normal(front_normal.clone()),
+ Side::Front,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::FrontBottomLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(front_bottom_left_pos)
+ .normal(front_normal.clone()),
+ Side::Front,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::FrontTopLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(front_top_left_pos)
+ .normal(front_normal.clone()),
+ Side::Front,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let back_top_right_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 };
+ let back_bottom_right_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 };
+ let back_bottom_left_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 };
+ let back_top_left_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 };
+
+ let back_normal = -calc_triangle_surface_normal(
+ &back_top_right_pos,
+ &back_bottom_right_pos,
+ &back_top_left_pos,
+ );
+
+ vertices[VertexIndex::BackTopRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(back_top_right_pos)
+ .normal(back_normal.clone()),
+ Side::Back,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BackBottomRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(back_bottom_right_pos)
+ .normal(back_normal.clone()),
+ Side::Back,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BackBottomLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(back_bottom_left_pos)
+ .normal(back_normal.clone()),
+ Side::Back,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BackTopLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(back_top_left_pos)
+ .normal(back_normal),
+ Side::Back,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let right_back_top_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 };
+ let right_back_bottom_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 };
+ let right_front_top_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 };
+ let right_front_bottom_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 };
+
+ let right_normal = calc_triangle_surface_normal(
+ &right_back_top_pos,
+ &right_back_bottom_pos,
+ &right_front_top_pos,
+ );
+
+ vertices[VertexIndex::RightBackTop as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(right_back_top_pos)
+ .normal(right_normal.clone()),
+ Side::Right,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::RightBackBottom as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(right_back_bottom_pos)
+ .normal(right_normal.clone()),
+ Side::Right,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::RightFrontTop as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(right_front_top_pos)
+ .normal(right_normal.clone()),
+ Side::Right,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::RightFrontBottom as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(right_front_bottom_pos)
+ .normal(right_normal),
+ Side::Right,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let left_back_top_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 };
+ let left_back_bottom_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 };
+ let left_front_top_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 };
+ let left_front_bottom_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 };
+
+ let left_normal = -calc_triangle_surface_normal(
+ &left_back_top_pos,
+ &left_back_bottom_pos,
+ &left_front_top_pos,
+ );
+
+ vertices[VertexIndex::LeftBackTop as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(left_back_top_pos)
+ .normal(left_normal.clone()),
+ Side::Left,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::LeftBackBottom as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(left_back_bottom_pos)
+ .normal(left_normal.clone()),
+ Side::Left,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::LeftFrontTop as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(left_front_top_pos)
+ .normal(left_normal.clone()),
+ Side::Left,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::LeftFrontBottom as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(left_front_bottom_pos)
+ .normal(left_normal),
+ Side::Left,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let top_back_right_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 };
+ let top_back_left_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 };
+ let top_front_left_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 };
+ let top_front_right_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 };
+
+ let top_normal = -calc_triangle_surface_normal(
+ &top_back_right_pos,
+ &top_back_left_pos,
+ &top_front_right_pos,
+ );
+
+ vertices[VertexIndex::TopBackRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(top_back_right_pos)
+ .normal(top_normal.clone()),
+ Side::Top,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::TopBackLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(top_back_left_pos)
+ .normal(top_normal.clone()),
+ Side::Top,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::TopFrontLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(top_front_left_pos)
+ .normal(top_normal.clone()),
+ Side::Top,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::TopFrontRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(top_front_right_pos)
+ .normal(top_normal),
+ Side::Top,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let bottom_back_right_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 };
+ let bottom_back_left_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 };
+ let bottom_front_right_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 };
+ let bottom_front_left_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 };
+
+ let bottom_normal = calc_triangle_surface_normal(
+ &bottom_back_right_pos,
+ &bottom_back_left_pos,
+ &bottom_front_right_pos,
+ );
+
+ vertices[VertexIndex::BottomBackRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(bottom_back_right_pos)
+ .normal(bottom_normal.clone()),
+ Side::Bottom,
+ Corner::BottomRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BottomBackLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(bottom_back_left_pos)
+ .normal(bottom_normal.clone()),
+ Side::Bottom,
+ Corner::BottomLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BottomFrontRight as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(bottom_front_right_pos)
+ .normal(bottom_normal.clone()),
+ Side::Bottom,
+ Corner::TopRight,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ vertices[VertexIndex::BottomFrontLeft as usize] = Some(
+ vertex_builder_cb(
+ VertexBuilder::new()
+ .pos(bottom_front_left_pos)
+ .normal(bottom_normal),
+ Side::Bottom,
+ Corner::TopLeft,
+ )
+ .build()
+ .unwrap(),
+ );
+
+ let front = [
+ // 🮝
+ VertexIndex::FrontTopRight,
+ VertexIndex::FrontBottomRight,
+ VertexIndex::FrontTopLeft,
+ //
+ // 🮟
+ VertexIndex::FrontBottomRight,
+ VertexIndex::FrontBottomLeft,
+ VertexIndex::FrontTopLeft,
+ ];
+
+ let back = [
+ // 🮝
+ VertexIndex::BackTopRight,
+ VertexIndex::BackBottomRight,
+ VertexIndex::BackTopLeft,
+ //
+ // 🮟
+ VertexIndex::BackBottomRight,
+ VertexIndex::BackBottomLeft,
+ VertexIndex::BackTopLeft,
+ ];
+
+ let right = [
+ // 🮝
+ VertexIndex::RightBackTop,
+ VertexIndex::RightBackBottom,
+ VertexIndex::RightFrontTop,
+ //
+ // 🮟
+ VertexIndex::RightBackBottom,
+ VertexIndex::RightFrontBottom,
+ VertexIndex::RightFrontTop,
+ ];
+
+ let left = [
+ // 🮝
+ VertexIndex::LeftBackTop,
+ VertexIndex::LeftBackBottom,
+ VertexIndex::LeftFrontTop,
+ //
+ // 🮟
+ VertexIndex::LeftBackBottom,
+ VertexIndex::LeftFrontBottom,
+ VertexIndex::LeftFrontTop,
+ ];
+
+ let top = [
+ // 🮝
+ VertexIndex::TopBackRight,
+ VertexIndex::TopBackLeft,
+ VertexIndex::TopFrontRight,
+ //
+ // 🮟
+ VertexIndex::TopBackLeft,
+ VertexIndex::TopFrontLeft,
+ VertexIndex::TopFrontRight,
+ ];
+
+ let bottom = [
+ // 🮝
+ VertexIndex::BottomBackRight,
+ VertexIndex::BottomBackLeft,
+ VertexIndex::BottomFrontRight,
+ //
+ // 🮟
+ VertexIndex::BottomBackLeft,
+ VertexIndex::BottomFrontLeft,
+ VertexIndex::BottomFrontRight,
+ ];
+
+ let indices = [front, back, right, left, top, bottom];
+
+ ObjectBuilder::new()
+ .vertices(vertices.map(Option::unwrap))
+ .indices(indices.into_iter().flatten().map(|index| index as u32))
+}
+
+macro_rules! one {
+ ($tt: tt) => {
+ 1
+ };
+}
+
+macro_rules! enum_with_variant_cnt {
+ (
+ $(#[$attr: meta])*
+ enum $name: ident {
+ $($variant: ident,)*
+ }
+ ) => {
+ $(#[$attr])*
+ enum $name {
+ $($variant,)*
+ }
+
+ impl $name {
+ const VARIANT_CNT: usize = 0 $(+ one!($variant))*;
+ }
+ };
+}
+
+enum_with_variant_cnt! {
+#[repr(u32)]
+enum VertexIndex
+{
+ FrontTopRight,
+ FrontBottomRight,
+ FrontBottomLeft,
+ FrontTopLeft,
+
+ BackTopRight,
+ BackBottomRight,
+ BackBottomLeft,
+ BackTopLeft,
+
+ RightBackTop,
+ RightBackBottom,
+ RightFrontTop,
+ RightFrontBottom,
+
+ LeftBackTop,
+ LeftBackBottom,
+ LeftFrontTop,
+ LeftFrontBottom,
+
+ TopBackRight,
+ TopBackLeft,
+ TopFrontRight,
+ TopFrontLeft,
+
+ BottomBackRight,
+ BottomBackLeft,
+ BottomFrontRight,
+ BottomFrontLeft,
+}
+}
diff --git a/src/main.rs b/src/main.rs
index f594c7c..9171b35 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,16 +1,27 @@
use std::error::Error;
+use std::path::Path;
use engine::color::Color;
-use engine::object::{Builder as ObjectBuilder, Id as ObjectId};
-use engine::vector::Vec3;
-use engine::vertex::Builder as VertexBuilder;
+use engine::lighting::{LightSettings, LightSourceBuilder};
+use engine::object::Id as ObjectId;
+use engine::texture::Texture;
+use engine::vector::{Vec2, Vec3};
use engine::{Engine, Key, WindowSize};
use tracing::Level;
use tracing_subscriber::FmtSubscriber;
+use crate::cube::{create_cube, Corner as CubeCorner, Side as CubeSide};
+
+mod cube;
+
const WINDOW_SIZE: WindowSize = WindowSize { width: 500, height: 600 };
const BLUE: Color<f32> = Color { red: 0.0, blue: 1.0, green: 0.0 };
+const RED: Color<f32> = Color { red: 1.0, green: 0.0, blue: 0.0 };
+const GREEN: Color<f32> = Color { red: 0.0, green: 1.0, blue: 0.0 };
+const ORANGE: Color<f32> = Color { red: 1.0, green: 0.5, blue: 0.0 };
+const PURPLE: Color<f32> = Color { red: 0.5, green: 0.0, blue: 1.0 };
+const CYAN: Color<f32> = Color { red: 0.0, green: 1.0, blue: 1.0 };
fn main() -> Result<(), Box<dyn Error>>
{
@@ -22,60 +33,53 @@ fn main() -> Result<(), Box<dyn Error>>
let mut engine = Engine::new(&WINDOW_SIZE, "Yaaay lmao")?;
- let mut triangle = ObjectBuilder::new()
- .vertices([
- VertexBuilder::new()
- .pos(Vec3 { x: -0.5, y: -0.5, z: 0.0 })
- .color(Color { red: 1.0, green: 0.0, blue: 0.0 })
- .build()
- .unwrap(),
- VertexBuilder::new()
- .pos(Vec3 { x: 0.5, y: -0.5, z: 0.0 })
- .color(Color { red: 0.0, green: 1.0, blue: 0.0 })
- .build()
- .unwrap(),
- VertexBuilder::new()
- .pos(Vec3 { x: 0.0, y: 0.5, z: 0.0 })
- .color(Color { red: 0.0, green: 0.0, blue: 1.0 })
- .build()
- .unwrap(),
- ])
- .build(ObjectId::new(1))?;
-
- triangle.translate(Vec3 { x: 0.0, y: 0.4, z: 0.0 });
-
- engine.add_object(triangle);
-
- let square = ObjectBuilder::new()
- .vertices([
- VertexBuilder::new()
- .pos(Vec3 { x: 0.5, y: 0.5, z: 0.0 })
- .color(BLUE)
- .build()
- .unwrap(),
- VertexBuilder::new()
- .pos(Vec3 { x: 0.5, y: -0.5, z: 0.0 })
- .color(BLUE)
- .build()
- .unwrap(),
- VertexBuilder::new()
- .pos(Vec3 { x: -0.5, y: -0.5, z: 0.0 })
- .color(BLUE)
- .build()
- .unwrap(),
- VertexBuilder::new()
- .pos(Vec3 { x: -0.5, y: 0.5, z: 0.0 })
- .color(BLUE)
- .build()
- .unwrap(),
- ])
- .indices([0, 1, 3, 1, 2, 3])
- .build(ObjectId::new(2))?;
-
- engine.add_object(square);
+ engine.set_light_settings(LightSettings {
+ ambient_light_strength: 0.1,
+ specular_light_strength: 0.5,
+ specular_shininess: 32,
+ });
+
+ let cube = create_cube(|vertex_builder, side, _| {
+ vertex_builder.color(match side {
+ CubeSide::Top => BLUE,
+ CubeSide::Back => RED,
+ CubeSide::Left => PURPLE,
+ CubeSide::Front => ORANGE,
+ CubeSide::Right => GREEN,
+ CubeSide::Bottom => CYAN,
+ })
+ })
+ .build(ObjectId::new(3))?;
+
+ engine.add_object(cube);
+
+ let texture = Texture::open(Path::new("vent.png"))?;
+
+ let mut textured_cube = create_cube(|vertex_builder, _, corner| {
+ vertex_builder.texture_coords(match corner {
+ CubeCorner::TopRight => Vec2 { x: 1.0, y: 1.0 },
+ CubeCorner::TopLeft => Vec2 { x: 0.0, y: 1.0 },
+ CubeCorner::BottomRight => Vec2 { x: 1.0, y: 0.0 },
+ CubeCorner::BottomLeft => Vec2 { x: 0.0, y: 0.0 },
+ })
+ })
+ .texture(texture)
+ .build(ObjectId::new(4))?;
+
+ textured_cube.translate(Vec3 { x: 1.6, y: 0.0, z: 0.0 });
+
+ engine.add_object(textured_cube);
+
+ let light_source = LightSourceBuilder::new()
+ .position(Vec3 { x: 1.2, y: 1.0, z: 1.5 })
+ .build();
+
+ engine.set_light_source(light_source);
let cam_speed = 3.0;
+ let light_source_speed = 1.2;
+
engine.start(|engine| {
let delta_time = *engine.delta_time();
@@ -113,6 +117,64 @@ fn main() -> Result<(), Box<dyn Error>>
*engine.camera_mut().position_mut() +=
cam_right * cam_speed_dist_adj * delta_time.as_secs_f32();
}
+ if engine.is_key_pressed(Key::K).unwrap() {
+ let cam_up = engine.camera().up().clone();
+
+ // Camera speed adjusted to be same no matter how far the distance is to the
+ // camera target
+ let cam_speed_dist_adj = cam_speed
+ * (engine.camera().position() - engine.camera().target()).length();
+
+ *engine.camera_mut().position_mut() +=
+ cam_up * cam_speed_dist_adj * delta_time.as_secs_f32();
+ }
+ if engine.is_key_pressed(Key::J).unwrap() {
+ let cam_up = engine.camera().down().clone();
+
+ // Camera speed adjusted to be same no matter how far the distance is to the
+ // camera target
+ let cam_speed_dist_adj = cam_speed
+ * (engine.camera().position() - engine.camera().target()).length();
+
+ *engine.camera_mut().position_mut() +=
+ cam_up * cam_speed_dist_adj * delta_time.as_secs_f32();
+ }
+
+ if engine.is_key_pressed(Key::O).unwrap() {
+ let light_source = engine.light_source_mut().unwrap();
+
+ let front_right = Vec3 { x: 1.0, y: 0.0, z: 1.0 };
+
+ light_source
+ .translate(front_right * light_source_speed * delta_time.as_secs_f32());
+ }
+
+ if engine.is_key_pressed(Key::L).unwrap() {
+ let light_source = engine.light_source_mut().unwrap();
+
+ let back_left = Vec3 { x: -1.0, y: 0.0, z: -1.0 };
+
+ light_source
+ .translate(back_left * light_source_speed * delta_time.as_secs_f32());
+ }
+
+ if engine.is_key_pressed(Key::KpAdd).unwrap() {
+ let light_settings = engine.light_settings().unwrap().clone();
+
+ engine.set_light_settings(LightSettings {
+ ambient_light_strength: light_settings.ambient_light_strength + 0.2,
+ ..light_settings
+ })
+ }
+
+ if engine.is_key_pressed(Key::KpSubtract).unwrap() {
+ let light_settings = engine.light_settings().unwrap().clone();
+
+ engine.set_light_settings(LightSettings {
+ ambient_light_strength: light_settings.ambient_light_strength - 0.2,
+ ..light_settings
+ })
+ }
})?;
Ok(())
diff --git a/vent.png b/vent.png
new file mode 100755
index 0000000..d78be7d
--- /dev/null
+++ b/vent.png
Binary files differ