summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 6dc72a2e066f5d2e0cac4317804c3a79526f0d1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::error::Error;
use std::fs::read_to_string;
use std::path::Path;

use engine::camera::fly::{Extension as FlyCameraExtension, Options as FlyCameraOptions};
use engine::camera::Camera;
use engine::color::Color;
use engine::data_types::dimens::Dimens;
use engine::ecs::sole::Single;
use engine::event::Start as StartEvent;
use engine::file_format::wavefront::mtl::parse as parse_mtl;
use engine::file_format::wavefront::obj::parse as parse_obj;
use engine::input::Extension as InputExtension;
use engine::lighting::{GlobalLight, PointLight};
use engine::material::{Builder as MaterialBuilder, Flags as MaterialFlags};
use engine::renderer::Extension as RendererExtension;
use engine::shader::Program as ShaderProgram;
use engine::transform::Transform;
use engine::vector::Vec3;
use engine::window::{CursorMode, Extension as WindowExtension, Window};
use engine::Engine;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;

const WINDOW_SIZE: Dimens<u32> = Dimens { width: 1920, height: 1080 };

const YELLOW: Color<f32> = Color {
    red: 0.988235294118,
    green: 0.941176470588,
    blue: 0.0274509803922,
};

const RESOURCE_DIR: &str = "res";

fn main() -> Result<(), Box<dyn Error>>
{
    let subscriber = FmtSubscriber::builder()
        .with_max_level(Level::TRACE)
        .finish();

    tracing::subscriber::set_global_default(subscriber)?;

    let mut engine = Engine::new();

    let transform = Transform {
        position: Vec3 { x: 1.6, y: 0.0, z: 0.0 },
        ..Default::default()
    };

    let teapot_obj =
        parse_obj(&read_to_string(Path::new(RESOURCE_DIR).join("teapot.obj"))?)?;

    let teapot_mat_name = teapot_obj
        .faces
        .first()
        .and_then(|face| face.material_name.as_ref());

    let teapot_mats = teapot_obj.read_and_parse_material_libs(parse_mtl)?;

    let teapot_mat = teapot_mats
        .into_iter()
        .find(|mat| Some(&mat.name) == teapot_mat_name)
        .ok_or("Teapot material was not found")?;

    engine.spawn((
        teapot_obj.to_mesh()?,
        teapot_mat.material,
        transform,
        ShaderProgram::new()?,
    ));

    engine.spawn((
        PointLight::builder().diffuse(YELLOW).build(),
        Transform {
            position: Vec3 { x: -6.0, y: 3.0, z: 3.0 },
            ..Default::default()
        },
        parse_obj(&read_to_string(Path::new(RESOURCE_DIR).join("cube.obj"))?)?
            .to_mesh()?,
        MaterialBuilder::new().ambient(YELLOW * 5.0).build(),
        ShaderProgram::new()?,
        MaterialFlags::builder().use_ambient_color(true).build(),
    ));

    engine.spawn((Camera { current: true, ..Default::default() },));

    engine.add_sole(GlobalLight::default())?;

    engine.register_system(StartEvent, prepare_window);

    engine.add_extension(RendererExtension::default());

    engine.add_extension(
        WindowExtension::default()
            .window_title("Game")
            .window_size(WINDOW_SIZE),
    );

    engine.add_extension(FlyCameraExtension(FlyCameraOptions {
        camera_speed: 3.0,
        mouse_sensitivity: 0.2,
    }));

    engine.add_extension(InputExtension::default());

    engine.start();

    Ok(())
}

fn prepare_window(window: Single<Window>)
{
    window.set_cursor_mode(CursorMode::Disabled).unwrap();
}