mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +02:00
add scene and rendering order
This commit is contained in:
parent
9c8f2e5787
commit
44483daa72
@ -6,19 +6,15 @@ use std::{marker::PhantomData, time::Duration};
|
|||||||
|
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
|
||||||
pub trait Object<R: Renderer> {
|
pub trait Io<R: Renderer, G: Game<R>> {
|
||||||
fn update(&mut self, delta: Duration);
|
fn run(&mut self, game: &mut G);
|
||||||
fn render(&mut self, r: &mut R);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Io<R: Renderer, O: Object<R>> {
|
|
||||||
fn run(&mut self, game: &mut Game<R, O>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Renderer {
|
pub trait Renderer {
|
||||||
fn draw_rect(&mut self, pos: V2, size: V2, color: Color);
|
fn draw_rect(&mut self, pos: V2, size: V2, color: Color);
|
||||||
fn draw_point(&mut self, pos: V2, color: Color);
|
fn draw_point(&mut self, pos: V2, color: Color);
|
||||||
fn draw_line(&mut self, from: V2, to: V2, color: Color);
|
fn draw_line(&mut self, from: V2, to: V2, color: Color);
|
||||||
|
fn draw_triangle(&mut self, triangle: Triangle2, color: Color);
|
||||||
fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color);
|
fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,34 +32,8 @@ pub enum Event {
|
|||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Game<R: Renderer, O: Object<R>> {
|
pub trait Game<R: Renderer> {
|
||||||
_phantom_data: PhantomData<R>,
|
fn update(&mut self, delta_time: Duration);
|
||||||
objects: Vec<O>,
|
fn render(&mut self, r: &mut R);
|
||||||
}
|
fn event(&mut self, event: Event);
|
||||||
|
|
||||||
impl<R: Renderer, O: Object<R>> Game<R, O> {
|
|
||||||
pub fn new() -> Result<Self, Error> {
|
|
||||||
Ok(Self {
|
|
||||||
_phantom_data: PhantomData,
|
|
||||||
objects: Vec::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn(&mut self, object: O) {
|
|
||||||
self.objects.push(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, delta_time: Duration) {
|
|
||||||
for object in self.objects.iter_mut() {
|
|
||||||
object.update(delta_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render(&mut self, r: &mut R) {
|
|
||||||
for object in self.objects.iter_mut() {
|
|
||||||
object.render(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn event(&mut self, event: Event) {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ impl V3 {
|
|||||||
f64::sqrt(self.0.powi(2) + self.1.powi(2) + self.2.powi(2))
|
f64::sqrt(self.0.powi(2) + self.1.powi(2) + self.2.powi(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unit(&self) -> V3 {
|
pub fn unit(&self) -> Self {
|
||||||
self.map(|v| v / self.len())
|
self.map(|v| v / self.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,10 +39,14 @@ impl V3 {
|
|||||||
V3(func(self.0), func(self.1), func(self.2))
|
V3(func(self.0), func(self.1), func(self.2))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate(&self, rot: V3) -> Self {
|
pub fn rotate(&self, rot: Self) -> Self {
|
||||||
M3x3::new_rotate_z(rot.2)
|
M3x3::new_rotate_z(rot.2)
|
||||||
* (M3x3::new_rotate_y(rot.1) * (M3x3::new_rotate_x(rot.0) * *self))
|
* (M3x3::new_rotate_y(rot.1) * (M3x3::new_rotate_x(rot.0) * *self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn distance(&self, rhs: Self) -> f64 {
|
||||||
|
(*self - rhs).len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for V3 {
|
impl Add for V3 {
|
||||||
@ -125,6 +129,10 @@ impl Triangle3 {
|
|||||||
pub fn middle(&self) -> V3 {
|
pub fn middle(&self) -> V3 {
|
||||||
(self.0 + self.1 + self.2).map(|v| v / 3.0)
|
(self.0 + self.1 + self.2).map(|v| v / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn points(&self) -> [V3; 3] {
|
||||||
|
[self.0, self.1, self.2]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct M3x3([f64; 9]);
|
struct M3x3([f64; 9]);
|
||||||
|
|||||||
@ -4,14 +4,14 @@ mod error;
|
|||||||
mod game;
|
mod game;
|
||||||
mod math;
|
mod math;
|
||||||
mod r3d;
|
mod r3d;
|
||||||
|
mod scene;
|
||||||
mod sdl_io;
|
mod sdl_io;
|
||||||
mod shapes;
|
mod shapes;
|
||||||
mod system;
|
|
||||||
|
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub use game::*;
|
pub use game::*;
|
||||||
pub use math::*;
|
pub use math::*;
|
||||||
pub use r3d::*;
|
pub use r3d::*;
|
||||||
|
pub use scene::*;
|
||||||
pub use sdl_io::*;
|
pub use sdl_io::*;
|
||||||
pub use shapes::*;
|
pub use shapes::*;
|
||||||
pub use system::*;
|
|
||||||
|
|||||||
59
game/src/engine/scene.rs
Normal file
59
game/src/engine/scene.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use crate::engine::{Color, Renderer, Shape, Triangle3, V3};
|
||||||
|
|
||||||
|
pub struct DrawnTriangle {
|
||||||
|
triangle: Triangle3,
|
||||||
|
outline_color: Color,
|
||||||
|
fill_color: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Scene {
|
||||||
|
objects: Vec<DrawnTriangle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scene {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
objects: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render<R: Renderer>(&mut self, r: &mut R, camera: V3) {
|
||||||
|
self.objects.sort_by(|a, b| {
|
||||||
|
let a = a
|
||||||
|
.triangle
|
||||||
|
.points()
|
||||||
|
.map(|p| p.distance(camera))
|
||||||
|
.into_iter()
|
||||||
|
.min_by(|a, b| a.total_cmp(b))
|
||||||
|
.unwrap();
|
||||||
|
let b = b
|
||||||
|
.triangle
|
||||||
|
.points()
|
||||||
|
.map(|p| p.distance(camera))
|
||||||
|
.into_iter()
|
||||||
|
.min_by(|a, b| a.total_cmp(b))
|
||||||
|
.unwrap();
|
||||||
|
b.total_cmp(&a)
|
||||||
|
});
|
||||||
|
|
||||||
|
let drawn_triangles = self
|
||||||
|
.objects
|
||||||
|
.iter()
|
||||||
|
.map(|v| (v.triangle.project_2d(), v.outline_color, v.fill_color));
|
||||||
|
for (triangle, outline_color, fill_color) in drawn_triangles {
|
||||||
|
r.draw_triangle(triangle.clone(), fill_color);
|
||||||
|
r.draw_line(triangle.0, triangle.1, outline_color);
|
||||||
|
r.draw_line(triangle.0, triangle.2, outline_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_shape(&mut self, pos: V3, shape: &Shape, outline_color: Color, fill_color: Color) {
|
||||||
|
for triangle in shape.faces() {
|
||||||
|
self.objects.push(DrawnTriangle {
|
||||||
|
triangle: triangle.translate(pos),
|
||||||
|
outline_color,
|
||||||
|
fill_color,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -48,7 +48,7 @@ impl SdlIo {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<O: game::Object<Self>>(&mut self, game: &mut game::Game<Self, O>) {
|
pub fn run(&mut self, game: &mut impl game::Game<Self>) {
|
||||||
let mut event_pump = self.sdl_context.event_pump().unwrap();
|
let mut event_pump = self.sdl_context.event_pump().unwrap();
|
||||||
|
|
||||||
let mut time_before = Instant::now();
|
let mut time_before = Instant::now();
|
||||||
@ -154,6 +154,21 @@ impl Renderer for SdlIo {
|
|||||||
.render_geometry(&vertices, None, VertexIndices::Sequential)
|
.render_geometry(&vertices, None, VertexIndices::Sequential)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_triangle(&mut self, triangle: Triangle2, color: Color) {
|
||||||
|
let vertices = [triangle.0, triangle.1, triangle.2]
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| self.point_w2s(p))
|
||||||
|
.map(|p| Vertex {
|
||||||
|
position: p.into(),
|
||||||
|
color: color.into(),
|
||||||
|
tex_coord: FPoint::new(0.0, 0.0),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
self.canvas
|
||||||
|
.render_geometry(&vertices, None, VertexIndices::Sequential)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<V2> for FPoint {
|
impl From<V2> for FPoint {
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
use super::error::Error;
|
|
||||||
|
|
||||||
|
|
||||||
pub trait System {
|
|
||||||
|
|
||||||
fn on_add(&self) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_update(&self) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_remove(&self) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +1,80 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::{f64, time::Duration};
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::engine::{Color, R3d, Shape, V3};
|
use crate::engine::{Color, Renderer, Scene, Shape, V3};
|
||||||
|
|
||||||
mod engine;
|
mod engine;
|
||||||
mod vermiparous;
|
mod vermiparous;
|
||||||
|
|
||||||
enum MyObject {
|
struct Game {
|
||||||
Player { pos: V3, vel: V3 },
|
objects: Vec<Object>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: engine::Renderer> engine::Object<R> for MyObject {
|
impl Game {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
objects: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn(&mut self, object: Object) {
|
||||||
|
self.objects.push(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Renderer> engine::Game<R> for Game {
|
||||||
|
fn update(&mut self, delta_time: Duration) {
|
||||||
|
for object in &mut self.objects {
|
||||||
|
object.update(delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, r: &mut R) {
|
||||||
|
let mut scene = Scene::new();
|
||||||
|
for object in &mut self.objects {
|
||||||
|
object.render(&mut scene);
|
||||||
|
}
|
||||||
|
scene.render(r, V3(0.0, 0.0, -1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(&mut self, event: engine::Event) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Object {
|
||||||
|
Player { pos: V3, vel: V3 },
|
||||||
|
Obstacle { pos: V3, vel_z: f64 },
|
||||||
|
Ground { pos: V3, vel_z: f64 },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object {
|
||||||
fn update(&mut self, delta_time: Duration) {
|
fn update(&mut self, delta_time: Duration) {
|
||||||
match self {
|
match self {
|
||||||
MyObject::Player { pos, vel } => {
|
Object::Player { pos, vel } => {
|
||||||
*pos += *vel * delta_time.as_secs_f64();
|
*pos += *vel * delta_time.as_secs_f64();
|
||||||
if pos.0 >= 2.1 {
|
if pos.0 >= 2.1 {
|
||||||
pos.0 = -2.0;
|
pos.0 = -2.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Object::Obstacle { pos, vel_z } => {
|
||||||
|
pos.2 += *vel_z * delta_time.as_secs_f64();
|
||||||
|
}
|
||||||
|
Object::Ground { pos, vel_z } => {
|
||||||
|
pos.2 += *vel_z * delta_time.as_secs_f64();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, r: &mut R) {
|
fn render(&mut self, scene: &mut Scene) {
|
||||||
match self {
|
match self {
|
||||||
MyObject::Player { pos, .. } => {
|
Object::Player { pos, .. } => {
|
||||||
let mut r3d = R3d::new(r);
|
scene.draw_shape(
|
||||||
|
|
||||||
for z in 0..10 {
|
|
||||||
for x in -10..10 {
|
|
||||||
r3d.draw_shape(
|
|
||||||
V3(x as f64 * 0.1, -0.5, z as f64 * 0.1),
|
|
||||||
&Shape::new_plane(V3(0.1, 0.0, 0.1)),
|
|
||||||
Color::Cyan,
|
|
||||||
Color::Black,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r3d.draw_shape(
|
|
||||||
*pos + V3(0.0, 0.2, 0.0),
|
*pos + V3(0.0, 0.2, 0.0),
|
||||||
&Shape::new_cube(V3(0.2, 0.1, 0.2)),
|
&Shape::new_cube(V3(0.2, 0.1, 0.2)),
|
||||||
Color::Green,
|
Color::Green,
|
||||||
Color::Black,
|
Color::Black,
|
||||||
);
|
);
|
||||||
r3d.draw_shape(
|
scene.draw_shape(
|
||||||
*pos + V3(-0.8, -0.2, 0.0),
|
*pos + V3(-0.8, -0.2, 0.0),
|
||||||
&Shape::new_cube(V3(0.2, 0.2, 0.2))
|
&Shape::new_cube(V3(0.2, 0.2, 0.2))
|
||||||
.translate(V3(-0.1, -0.1, -0.1))
|
.translate(V3(-0.1, -0.1, -0.1))
|
||||||
@ -54,19 +83,37 @@ impl<R: engine::Renderer> engine::Object<R> for MyObject {
|
|||||||
Color::Black,
|
Color::Black,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Object::Obstacle { pos, vel_z } => todo!(),
|
||||||
|
Object::Ground { pos, .. } => {
|
||||||
|
for z in 0..10 {
|
||||||
|
for x in -10..10 {
|
||||||
|
scene.draw_shape(
|
||||||
|
V3(x as f64 * 0.1 + pos.0, pos.1, z as f64 * 0.1 + pos.2),
|
||||||
|
&Shape::new_plane(V3(0.1, 0.0, 0.1)),
|
||||||
|
Color::Cyan,
|
||||||
|
Color::Black,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut sdl_io = engine::SdlIo::new()?;
|
let mut sdl_io = engine::SdlIo::new()?;
|
||||||
let mut game = engine::Game::<engine::SdlIo, MyObject>::new()?;
|
let mut game = Game::new();
|
||||||
|
|
||||||
let player = MyObject::Player {
|
let player = Object::Player {
|
||||||
pos: V3(-1.0, -0.1, 0.0),
|
pos: V3(-1.0, -0.1, 0.0),
|
||||||
vel: V3(0.4, 0.0, 0.0),
|
vel: V3(0.4, 0.0, 0.0),
|
||||||
};
|
};
|
||||||
game.spawn(player);
|
game.spawn(player);
|
||||||
|
let ground = Object::Ground {
|
||||||
|
pos: V3(0.0, -0.3, -0.5),
|
||||||
|
vel_z: -0.1,
|
||||||
|
};
|
||||||
|
game.spawn(ground);
|
||||||
|
|
||||||
sdl_io.run(&mut game);
|
sdl_io.run(&mut game);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user