mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +02:00
worked on 3d rendering
This commit is contained in:
parent
2e14d79962
commit
67608a3aff
1
game/.gitignore
vendored
1
game/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
.vscode
|
||||||
@ -1,69 +1,58 @@
|
|||||||
|
|
||||||
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use sdl3::render::Canvas;
|
|
||||||
use sdl3::{EventPump, Sdl, VideoSubsystem};
|
|
||||||
use sdl3::video::Window;
|
|
||||||
use sdl3::pixels::Color;
|
use sdl3::pixels::Color;
|
||||||
use sdl3::event::Event;
|
|
||||||
use sdl3::keyboard::Keycode;
|
use crate::engine::math::{V2, V3};
|
||||||
|
use std::{marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
use super::object::Object;
|
|
||||||
|
|
||||||
pub struct Game<Io, O: Object> {
|
pub trait Object<R: Renderer> {
|
||||||
sdl_context: Sdl,
|
fn update(&mut self, delta: Duration);
|
||||||
video_subsystem: VideoSubsystem,
|
fn render(&mut self, r: &mut R);
|
||||||
canvas: Canvas<Window>,
|
}
|
||||||
event_pump: EventPump,
|
|
||||||
io: Io,
|
pub trait Io<R: Renderer, O: Object<R>> {
|
||||||
|
fn run(&mut self, game: &mut Game<R, O>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Renderer {
|
||||||
|
fn draw_rect(&mut self, pos: V2, size: V2, color: Color);
|
||||||
|
fn point(&mut self, pos: V2, color: Color);
|
||||||
|
fn draw_line(&mut self, from: V2, to: V2, color: Color);
|
||||||
|
fn draw_cube(&mut self, pos: V3, size: V3, outline_colors: Color, fill_color: Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Event {
|
||||||
|
Exit,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Game<R: Renderer, O: Object<R>> {
|
||||||
|
_phantom_data: PhantomData<R>,
|
||||||
objects: Vec<O>,
|
objects: Vec<O>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Io, O: Object> Game<Io, O> {
|
impl<R: Renderer, O: Object<R>> Game<R, O> {
|
||||||
pub fn new(io: Io) -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
let sdl_context = sdl3::init().unwrap();
|
|
||||||
let video_subsystem = sdl_context.video().unwrap();
|
|
||||||
let window = video_subsystem.window("Game", 1280, 720).position_centered().build().unwrap();
|
|
||||||
let mut canvas = window.into_canvas();
|
|
||||||
|
|
||||||
canvas.set_draw_color(Color::BLACK);
|
|
||||||
canvas.clear();
|
|
||||||
canvas.present();
|
|
||||||
|
|
||||||
let event_pump = sdl_context.event_pump().unwrap();
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
sdl_context,
|
_phantom_data: PhantomData,
|
||||||
video_subsystem,
|
objects: Vec::new(),
|
||||||
canvas,
|
|
||||||
event_pump,
|
|
||||||
io,
|
|
||||||
objects: Vec::new()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn spawn(&mut self, object: O) {
|
||||||
let mut time_before = Instant::now();
|
self.objects.push(object);
|
||||||
let time_per_frame = 1_000_000_000 / 60;
|
}
|
||||||
'running: loop {
|
|
||||||
for event in self.event_pump.poll_iter() {
|
|
||||||
match event {
|
|
||||||
Event::Quit {..} |
|
|
||||||
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
|
||||||
break 'running
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let now = Instant::now();
|
|
||||||
let delta = now - time_before;
|
|
||||||
time_before = now;
|
|
||||||
for object in self.objects.iter_mut() {
|
|
||||||
object.update(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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) {}
|
||||||
}
|
}
|
||||||
@ -1,10 +0,0 @@
|
|||||||
|
|
||||||
pub trait GameObject {
|
|
||||||
fn update(deltaTime: Duration);
|
|
||||||
fn render();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Game<GameObjectTypeetc: GameObject> {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
79
game/src/engine/math.rs
Normal file
79
game/src/engine/math.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
use std::ops::{Add, AddAssign, Mul, MulAssign};
|
||||||
|
|
||||||
|
pub struct V2(pub f64, pub f64);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct V3(pub f64, pub f64, pub f64);
|
||||||
|
|
||||||
|
impl Add for V3 {
|
||||||
|
type Output = V3;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign for V3 {
|
||||||
|
fn add_assign(&mut self, rhs: Self) {
|
||||||
|
*self = *self + rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f64> for V3 {
|
||||||
|
type Output = V3;
|
||||||
|
|
||||||
|
fn mul(self, rhs: f64) -> Self::Output {
|
||||||
|
Self(self.0 * rhs, self.1 * rhs, self.2 * rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<f64> for V3 {
|
||||||
|
fn mul_assign(&mut self, rhs: f64) {
|
||||||
|
*self = *self * rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl V3 {
|
||||||
|
pub fn as_2d(&self) -> V2 {
|
||||||
|
V2(self.0 / self.2, self.1 / self.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Vertex(V3, V3, V3);
|
||||||
|
|
||||||
|
pub struct Cube {
|
||||||
|
vertices: [Vertex; 12],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cube {
|
||||||
|
pub fn new(V3(x, y, z): V3, V3(w, h, d): V3) -> Self {
|
||||||
|
Self {
|
||||||
|
vertices: [
|
||||||
|
Vertex(V3(x, y, z), V3(x, y + h, z), V3(x + w, y + h, z)),
|
||||||
|
Vertex(V3(x + w, y + h, z), V3(x + w, y, z), V3(x, y + h, z)),
|
||||||
|
Vertex(V3(x + w, y, z), V3(x + w, y + h, z), V3(x + w, y, z + d)),
|
||||||
|
Vertex(
|
||||||
|
V3(x + w, y + h, z + d),
|
||||||
|
V3(x + w, y, z + d),
|
||||||
|
V3(x, y + h, z + d),
|
||||||
|
),
|
||||||
|
Vertex(V3(x, y + h, z), V3(x + w, y + h, z), V3(x, y + h, z + d)),
|
||||||
|
Vertex(
|
||||||
|
V3(x + w, y + h, z),
|
||||||
|
V3(x + w, y + h, z + d),
|
||||||
|
V3(x, y + h, z + d),
|
||||||
|
),
|
||||||
|
Vertex(V3(x, y, z), V3(x, y + h, z), V3(x, y, z + d)),
|
||||||
|
Vertex(V3(x, y + h, z), V3(x, y + h, z + d), V3(x, y, z + d)),
|
||||||
|
Vertex(V3(x, y, z), V3(x + w, y, z), V3(x, y, z + d)),
|
||||||
|
Vertex(V3(x + w, y, z), V3(x + w, y, z + d), V3(x, y, z + d)),
|
||||||
|
Vertex(V3(x, y, z + d), V3(x + w, y, z + d), V3(x, y + h, z + d)),
|
||||||
|
Vertex(
|
||||||
|
V3(x + w, y, z + d),
|
||||||
|
V3(x + w, y + h, z + d),
|
||||||
|
V3(x, y + h, z + d),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,9 @@
|
|||||||
pub mod object;
|
|
||||||
pub mod game;
|
|
||||||
mod system;
|
|
||||||
mod error;
|
mod error;
|
||||||
|
mod game;
|
||||||
|
pub mod math;
|
||||||
|
mod sdl_io;
|
||||||
|
mod system;
|
||||||
|
|
||||||
|
pub use game::{Event, Game, Io, Object, Renderer};
|
||||||
|
pub use math::V3;
|
||||||
|
pub use sdl_io::SdlIo;
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
pub trait Object {
|
|
||||||
fn update(&mut self, delta: Duration);
|
|
||||||
fn render(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
134
game/src/engine/sdl_io.rs
Normal file
134
game/src/engine/sdl_io.rs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use sdl3::{
|
||||||
|
event::Event,
|
||||||
|
keyboard::Keycode,
|
||||||
|
pixels::{Color, PixelFormat},
|
||||||
|
render::{Canvas, FRect},
|
||||||
|
video::Window,
|
||||||
|
Sdl, VideoSubsystem,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::engine::{
|
||||||
|
error::Error,
|
||||||
|
game,
|
||||||
|
math::{V2, V3},
|
||||||
|
Object,
|
||||||
|
};
|
||||||
|
|
||||||
|
static WIDTH: f64 = 1280.0;
|
||||||
|
static HEIGHT: f64 = 720.0;
|
||||||
|
|
||||||
|
pub struct SdlIo {
|
||||||
|
sdl_context: Sdl,
|
||||||
|
video_subsystem: VideoSubsystem,
|
||||||
|
canvas: Canvas<Window>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SdlIo {
|
||||||
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
let sdl_context = sdl3::init().unwrap();
|
||||||
|
let video_subsystem = sdl_context.video().unwrap();
|
||||||
|
let window = video_subsystem
|
||||||
|
.window("Game", WIDTH as u32, HEIGHT as u32)
|
||||||
|
.position_centered()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
let mut canvas = window.into_canvas();
|
||||||
|
|
||||||
|
canvas.set_draw_color(Color::BLACK);
|
||||||
|
canvas.clear();
|
||||||
|
canvas.present();
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
sdl_context,
|
||||||
|
video_subsystem,
|
||||||
|
canvas,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run<O: game::Object<Self>>(&mut self, game: &mut game::Game<Self, O>) {
|
||||||
|
let mut event_pump = self.sdl_context.event_pump().unwrap();
|
||||||
|
|
||||||
|
let mut time_before = Instant::now();
|
||||||
|
let time_per_frame = 1_000_000_000 / 60;
|
||||||
|
|
||||||
|
'running: loop {
|
||||||
|
for event in event_pump.poll_iter() {
|
||||||
|
match event {
|
||||||
|
Event::Quit { .. }
|
||||||
|
| Event::KeyDown {
|
||||||
|
keycode: Some(Keycode::Escape),
|
||||||
|
..
|
||||||
|
} => break 'running,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let time_now = Instant::now();
|
||||||
|
let delta_time = time_now - time_before;
|
||||||
|
time_before = time_now;
|
||||||
|
game.update(delta_time);
|
||||||
|
|
||||||
|
self.canvas.set_draw_color(Color::BLACK);
|
||||||
|
self.canvas.clear();
|
||||||
|
game.render(self);
|
||||||
|
self.canvas.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn world_to_screen(&self, v: V2) -> V2 {
|
||||||
|
V2(v.0 + WIDTH / 2.0, HEIGHT / 2.0 - v.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl game::Renderer for SdlIo {
|
||||||
|
fn draw_rect(&mut self, pos: V2, size: V2, color: Color) {
|
||||||
|
let pos = self.world_to_screen(pos);
|
||||||
|
self.canvas.set_draw_color(color);
|
||||||
|
self.canvas
|
||||||
|
.fill_rect(FRect::new(
|
||||||
|
(pos.0 - size.0 / 2.0) as _,
|
||||||
|
(pos.1 - size.1 / 2.0) as _,
|
||||||
|
size.0 as _,
|
||||||
|
size.1 as _,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn point(&mut self, pos: V2, color: Color) {
|
||||||
|
let pos = self.world_to_screen(pos);
|
||||||
|
let size = V2(10.0, 10.0);
|
||||||
|
self.canvas.set_draw_color(color);
|
||||||
|
self.canvas
|
||||||
|
.fill_rect(FRect::new(
|
||||||
|
(pos.0 - size.0 / 2.0) as _,
|
||||||
|
(pos.1 - size.1 / 2.0) as _,
|
||||||
|
10.0,
|
||||||
|
10.0,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_line(&mut self, from: V2, to: V2, color: Color) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_cube(&mut self, pos: V3, size: V3, outline_color: Color, fill_color: Color) {
|
||||||
|
let V3(x, y, z) = pos;
|
||||||
|
let V3(w, h, d) = size;
|
||||||
|
let points = [
|
||||||
|
pos,
|
||||||
|
V3(x + w, y, z),
|
||||||
|
V3(x, y + h, z),
|
||||||
|
V3(x + w, y + h, z),
|
||||||
|
V3(x, y, z + d / 100.0),
|
||||||
|
V3(x + w, y, z + d / 100.0),
|
||||||
|
V3(x, y + h, z + d / 100.0),
|
||||||
|
V3(x + w, y + h, z + d / 100.0),
|
||||||
|
];
|
||||||
|
for point in points {
|
||||||
|
self.point(point.as_2d(), outline_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,46 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use sdl3::pixels::Color;
|
||||||
|
|
||||||
|
use crate::engine::math::{V2, V3};
|
||||||
|
|
||||||
mod engine;
|
mod engine;
|
||||||
|
|
||||||
use crate::engine::game::Game;
|
enum Object {
|
||||||
|
Player { pos: V3, vel: V3 },
|
||||||
fn main() {
|
}
|
||||||
// let mut game: Game<(), _> = Game::new(todo!()).unwrap();
|
|
||||||
// game.run();
|
impl<R: engine::Renderer> engine::Object<R> for Object {
|
||||||
println!("Hello, world!");
|
fn update(&mut self, delta_time: Duration) {
|
||||||
|
match self {
|
||||||
|
Object::Player { pos, vel } => {
|
||||||
|
*pos += *vel * delta_time.as_secs_f64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, r: &mut R) {
|
||||||
|
match self {
|
||||||
|
Object::Player { pos, .. } => {
|
||||||
|
// r.draw_rect(V2(pos.0, pos.1), V2(400.0, 400.0));
|
||||||
|
r.draw_cube(*pos, V3(100.0, 100.0, 100.0), Color::GREEN, Color::WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut sdl_io = engine::SdlIo::new()?;
|
||||||
|
let mut game = engine::Game::<engine::SdlIo, Object>::new()?;
|
||||||
|
|
||||||
|
let player = Object::Player {
|
||||||
|
pos: V3(-50.0, -50.0, 0.0),
|
||||||
|
vel: V3(0.0, 0.0, 1.0),
|
||||||
|
};
|
||||||
|
game.spawn(player);
|
||||||
|
|
||||||
|
sdl_io.run(&mut game);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user