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
115
116
117
118
119
120
121
122
123
124
125
126
|
use std::error::Error;
use std::fs::read_to_string;
use std::path::Path;
use engine::camera::fly::{
Extension as FlyCameraExtension,
Fly as FlyCamera,
Options as FlyCameraOptions,
};
use engine::camera::{Active as ActiveCamera, Camera};
use engine::color::Color;
use engine::data_types::dimens::Dimens;
use engine::ecs::phase::START as START_PHASE;
use engine::ecs::sole::Single;
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::{AttenuationParams, GlobalLight, PointLight};
use engine::material::{Builder as MaterialBuilder, Flags as MaterialFlags};
use engine::renderer::opengl::Extension as OpenglRendererExtension;
use engine::transform::Position;
use engine::vector::Vec3;
use engine::window::{
Builder as WindowBuilder,
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 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,
Position::from(Vec3 { x: 1.6, y: 0.0, z: 0.0 }),
));
engine.spawn((
PointLight::builder()
.position(Vec3 { x: -6.0, y: 3.0, z: 3.0 })
.diffuse(YELLOW)
.attenuation_params(AttenuationParams {
linear: 0.045,
quadratic: 0.0075,
..Default::default()
})
.build(),
Position::from(Vec3 { x: -6.0, y: 3.0, z: 3.0 }),
parse_obj(&read_to_string(Path::new(RESOURCE_DIR).join("cube.obj"))?)?
.to_mesh()?,
MaterialBuilder::new().ambient(YELLOW * 5.0).build(),
MaterialFlags::builder().use_ambient_color(true).build(),
));
engine.spawn((
Camera::default(),
Position {
position: Vec3 { x: 0.0, y: 0.0, z: 3.0 },
},
ActiveCamera,
FlyCamera::default(),
));
engine.add_sole(GlobalLight::default())?;
engine.register_system(*START_PHASE, prepare_window);
engine.add_extension(OpenglRendererExtension::default());
engine.add_extension(
WindowExtension::new(WindowBuilder::default().multisampling_sample_count(8))
.window_title("Game")
.window_size(WINDOW_SIZE),
);
engine.add_extension(FlyCameraExtension(FlyCameraOptions {
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();
}
|