mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-26 21:27:38 +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
|
||||
.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::event::Event;
|
||||
use sdl3::keyboard::Keycode;
|
||||
|
||||
use crate::engine::math::{V2, V3};
|
||||
use std::{marker::PhantomData, time::Duration};
|
||||
|
||||
use super::error::Error;
|
||||
use super::object::Object;
|
||||
|
||||
pub struct Game<Io, O: Object> {
|
||||
sdl_context: Sdl,
|
||||
video_subsystem: VideoSubsystem,
|
||||
canvas: Canvas<Window>,
|
||||
event_pump: EventPump,
|
||||
io: Io,
|
||||
pub trait Object<R: Renderer> {
|
||||
fn update(&mut self, delta: Duration);
|
||||
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 {
|
||||
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>,
|
||||
}
|
||||
|
||||
impl<Io, O: Object> Game<Io, O> {
|
||||
pub fn new(io: Io) -> 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();
|
||||
|
||||
impl<R: Renderer, O: Object<R>> Game<R, O> {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
sdl_context,
|
||||
video_subsystem,
|
||||
canvas,
|
||||
event_pump,
|
||||
io,
|
||||
objects: Vec::new()
|
||||
_phantom_data: PhantomData,
|
||||
objects: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
let mut time_before = Instant::now();
|
||||
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 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) {}
|
||||
}
|
||||
|
||||
@ -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 error;
|
||||
mod game;
|
||||
pub mod math;
|
||||
mod sdl_io;
|
||||
mod system;
|
||||
mod error;
|
||||
|
||||
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;
|
||||
|
||||
use crate::engine::game::Game;
|
||||
|
||||
fn main() {
|
||||
// let mut game: Game<(), _> = Game::new(todo!()).unwrap();
|
||||
// game.run();
|
||||
println!("Hello, world!");
|
||||
enum Object {
|
||||
Player { pos: V3, vel: V3 },
|
||||
}
|
||||
|
||||
impl<R: engine::Renderer> engine::Object<R> for Object {
|
||||
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