1use cgmath::{Rotation3, Quaternion};
2use forte_engine::{end_render, inputs::winit_input::EngineInput, math::transforms::Transform, pass, primitives::{cameras::Camera, mesh::Mesh, textures::Texture, transforms::TransformRaw, vertices::Vertex}, render::{pipelines::Pipeline, render_engine::*}, run_app, start_render, utils::{camera_controller::CameraController, resources::Handle}, EngineApp};
3use wgpu::util::DeviceExt;
4use winit::event::ElementState;
5
6const VERTICES: &[Vertex] = &[
7 Vertex { position: [ 0.5, -0.5, -0.5], tex_coords: [0.4131759, 0.00759614], normal: [0.0, 0.0, 0.0] },
8 Vertex { position: [ 0.5, -0.5, 0.5], tex_coords: [0.0048659444, 0.43041354], normal: [0.0, 0.0, 0.0] },
9 Vertex { position: [-0.5, -0.5, 0.5], tex_coords: [0.28081453, 0.949397], normal: [0.0, 0.0, 0.0] },
10 Vertex { position: [-0.5, -0.5, -0.5], tex_coords: [0.85967, 0.84732914], normal: [0.0, 0.0, 0.0] },
11 Vertex { position: [ 0.5, 0.5, -0.5], tex_coords: [0.9414737, 0.2652641], normal: [0.0, 0.0, 0.0] },
12 Vertex { position: [ 0.5, 0.5, 0.5], tex_coords: [0.28081453, 0.949397], normal: [0.0, 0.0, 0.0] },
13 Vertex { position: [-0.5, 0.5, 0.5], tex_coords: [0.85967, 0.84732914], normal: [0.0, 0.0, 0.0] },
14 Vertex { position: [-0.5, 0.5, -0.5], tex_coords: [0.9414737, 0.2652641], normal: [0.0, 0.0, 0.0] },
15];
16
17const INDICES: &[u16] = &[
18 1, 2, 3,
19 4, 7, 6,
20 4, 5, 1,
21 1, 5, 6,
22 6, 7, 3,
23 4, 0, 3,
24 0, 1, 3,
25 5, 4, 6,
26 0, 4, 1,
27 2, 1, 6,
28 2, 6, 3,
29 7, 4, 3
30];
31
32#[derive(Debug)]
33pub struct MainApp {
34 render_engine: RenderEngine,
35 pipeline: Pipeline,
36 mesh: Handle<Mesh>,
37 texture: Handle<Texture>,
38 camera: Camera,
39 controller: CameraController,
40
41 instances: Vec<Transform>,
42 instance_buffer: wgpu::Buffer
43}
44
45impl EngineApp for MainApp {
46 fn create(mut engine: RenderEngine) -> Self {
47 let pipeline = Pipeline::new(
49 "std", &engine, include_str!("rotating_cube.wgsl"),
50 &[Vertex::desc(), TransformRaw::desc()],
51 &[
52 &engine.device.create_bind_group_layout(&Camera::BIND_LAYOUT),
53 &engine.device.create_bind_group_layout(&Texture::BIND_LAYOUT),
54 ],
55 true
56 );
57
58 let mut camera = Camera::new(
60 &engine,
61 engine.config.width as f32 / engine.config.height as f32,
62 45.0, 0.1, 100.0
63 );
64 camera.position = (0.0, 0.0, 5.0).into();
65 camera.update(&mut engine);
66 let camera_controller = CameraController::new(0.02);
67
68 let instances = vec![Transform {
70 position: cgmath::Vector3 { x: 0.0, y: 0.0, z: 0.0 },
71 rotation: cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), cgmath::Deg(0.0)),
72 scale: (1.0, 1.0, 1.0).into()
73 }];
74
75 let instance_data = instances.iter().map(TransformRaw::from_generic).collect::<Vec<_>>();
77 let instance_buffer = engine.device.create_buffer_init(
78 &wgpu::util::BufferInitDescriptor {
79 label: Some("Instance Buffer"),
80 contents: bytemuck::cast_slice(&instance_data),
81 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST
82 }
83 );
84
85 let mesh = engine.create_mesh("test", VERTICES, INDICES);
86 let texture = engine.create_texture("test", include_bytes!("rotating_cube.png"));
87
88 Self {
90 render_engine: engine,
91 mesh, texture,
92 camera, pipeline,
93 controller: camera_controller,
94 instances, instance_buffer
95 }
96 }
97
98 fn start(&mut self) {}
99
100 fn input(&mut self, input: EngineInput) {
101 match input {
103 EngineInput::KeyInput(key_code, state) => {
104 let pressed = matches!(state, ElementState::Pressed);
105 self.controller.key_input(key_code, pressed);
106 }
107 EngineInput::MouseMove(..) => {}
108 _ => println!("Received input {:?}", input)
109 }
110 }
111
112 fn update(&mut self) {
113 self.controller.update_camera(&mut self.camera);
115 self.camera.update(&mut self.render_engine);
116
117 let mut resources = start_render!(self.render_engine);
119
120 {
121 let mut pass = pass!(self.render_engine, resources);
123
124 let transform = self.instances.get_mut(0).unwrap();
126 transform.rotation = Quaternion::from_angle_y(cgmath::Deg(self.render_engine.time_since_start * 45.0)) * Quaternion::from_angle_z(cgmath::Deg(self.render_engine.time_since_start * 45.0));
127 let instance_data = self.instances.iter().map(TransformRaw::from_generic).collect::<Vec<_>>();
128 self.render_engine.queue.write_buffer(&self.instance_buffer, 0, bytemuck::cast_slice(&instance_data));
129
130 self.pipeline.bind(&mut pass);
132 self.camera.bind(&mut pass, &self.render_engine, 0);
133 self.render_engine.draw_textured_mesh(&mut pass, &self.mesh, &self.texture, &self.instance_buffer, self.instances.len() as u32);
134 }
135
136 end_render!(self.render_engine, resources);
138 self.render_engine.next_frame();
139 }
140
141 fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { self.render_engine.resize(new_size); }
142
143 fn exit(&mut self) {}
144}
145
146fn main() { run_app::<MainApp>(); }