1use cgmath::Quaternion;
2use forte_engine::{component_app::EngineComponent, create_app, egui::EguiEngine, math::{quaternion::QuaternionExt, transforms::Transform}, primitives::{cameras::Camera, mesh::Mesh, textures::Texture, transforms::TransformRaw, vertices::Vertex}, render::pipelines::Pipeline, run_app, ui::{elements::UIElement, style::{Color, PositionSetting, Sizing, Style}, UIEngine}, utils::resources::Handle};
3
4const VERTICES: &[Vertex] = &[
5 Vertex { position: [ 0.5, -0.5, -0.5], tex_coords: [0.4131759, 0.00759614], normal: [0.0, 0.0, 0.0] },
6 Vertex { position: [ 0.5, -0.5, 0.5], tex_coords: [0.0048659444, 0.43041354], normal: [0.0, 0.0, 0.0] },
7 Vertex { position: [-0.5, -0.5, 0.5], tex_coords: [0.28081453, 0.949397], normal: [0.0, 0.0, 0.0] },
8 Vertex { position: [-0.5, -0.5, -0.5], tex_coords: [0.85967, 0.84732914], normal: [0.0, 0.0, 0.0] },
9 Vertex { position: [ 0.5, 0.5, -0.5], tex_coords: [0.9414737, 0.2652641], normal: [0.0, 0.0, 0.0] },
10 Vertex { position: [ 0.5, 0.5, 0.5], tex_coords: [0.28081453, 0.949397], normal: [0.0, 0.0, 0.0] },
11 Vertex { position: [-0.5, 0.5, 0.5], tex_coords: [0.85967, 0.84732914], normal: [0.0, 0.0, 0.0] },
12 Vertex { position: [-0.5, 0.5, -0.5], tex_coords: [0.9414737, 0.2652641], normal: [0.0, 0.0, 0.0] },
13];
14
15const INDICES: &[u16] = &[
16 1, 2, 3,
17 4, 7, 6,
18 4, 5, 1,
19 1, 5, 6,
20 6, 7, 3,
21 4, 0, 3,
22 0, 1, 3,
23 5, 4, 6,
24 0, 4, 1,
25 2, 1, 6,
26 2, 6, 3,
27 7, 4, 3
28];
29
30pub struct TestComponent {
31 mesh: Handle<Mesh>,
32 texture: Handle<Texture>,
33 camera: Camera,
34 instances: Vec<Transform>,
35 instance_buffer: wgpu::Buffer,
36 test: String
37}
38
39impl EngineComponent<(&mut RenderEngine, &mut UIEngine, &mut EguiEngine)> for TestComponent {
40
41 fn create(engine: &mut RenderEngine) -> Self {
42 let mut camera = Camera::new(
44 &engine,
45 engine.config.width as f32 / engine.config.height as f32,
46 45.0, 0.1, 100.0
47 );
48 camera.position = (0.0, 0.0, 5.0).into();
49 camera.update(engine);
50
51 let instances = vec![Transform {
53 position: cgmath::Vector3 { x: 0.0, y: 0.0, z: 0.0 },
54 rotation: cgmath::Quaternion::euler_deg_z(0.0),
55 scale: (1.0, 1.0, 1.0).into()
56 }];
57
58 engine.verify_pipeline_exists("forte.test", |engine| {
59 Pipeline::new(
60 "std", &engine, include_str!("rotating_cube.wgsl"),
61 &[Vertex::desc(), TransformRaw::desc()],
62 &[
63 &engine.device.create_bind_group_layout(&Camera::BIND_LAYOUT),
64 &engine.device.create_bind_group_layout(&Texture::BIND_LAYOUT),
65 ],
66 true
67 )
68 });
69
70 Self {
71 instance_buffer: TransformRaw::buffer_from_generic(engine, &instances),
72 mesh: engine.create_mesh("test", VERTICES, INDICES),
73 texture: engine.create_texture("test", include_bytes!("rotating_cube.png")),
74 camera, instances,
75 test: "".to_string()
76 }
77 }
78
79 fn start(&mut self, (engine, ui, _): (&mut RenderEngine, &mut UIEngine, &mut EguiEngine)) {
80 let mut a = UIElement::container(
81 &engine,
82 Style {
83 width: Sizing::Px(200.0),
84 height: Sizing::Px(200.0),
85 color: Color { red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0 },
86 top: Sizing::Px(10.0),
87 left: Sizing::Px(10.0),
88 border: Sizing::Px(5.0),
89 round: Sizing::Px(15.0),
90 ..Default::default()
91 }
92 );
93 a.children.push(UIElement::container(
94 &engine,
95 Style {
96 width: Sizing::Px(100.0),
97 height: Sizing::Px(100.0),
98 position_setting: PositionSetting::Parent,
99 top: Sizing::Px(10.0),
100 left: Sizing::Px(10.0),
101 border: Sizing::Px(5.0),
102 round: Sizing::Px(10.0),
103 color: Color { red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0 },
104 ..Default::default()
105 }
106 ));
107 ui.elements.push(a);
108 }
109
110 fn update(&mut self, (engine, _, egui): (&mut RenderEngine, &mut UIEngine, &mut EguiEngine)) {
111 TransformRaw::update_buffer_generic(
113 engine, &self.instance_buffer,
114 &[Transform {
115 rotation: Quaternion::euler_deg(0.0, engine.time_since_start * 45.0, engine.time_since_start * 45.0),
116 ..Default::default()
117 }]
118 );
119
120 egui::Window::new("Test")
122 .show(egui.context(), |ui| {
123 ui.label("Hi from test window!");
124 ui.text_edit_singleline(&mut self.test);
125 if ui.button("Search").clicked() {
126 println!("Search for {}", self.test);
127 }
128 });
129 }
130
131 fn render<'rpass>(&'rpass mut self, engine: &'rpass RenderEngine, pass: &mut wgpu::RenderPass<'rpass>) {
132 self.camera.bind(pass, engine, 0);
134 engine.draw_textured_mesh(pass, &self.mesh, &self.texture, &self.instance_buffer, self.instances.len() as u32);
135 }
136
137 fn exit(&mut self, _: (&mut RenderEngine, &mut UIEngine, &mut EguiEngine)) {}
138}
139
140create_app! {
141 CLEAR_COLOR = wgpu::Color { r: 0.0, g: 0.0, b: 0.0, a: 0.0 },
142
143 APP {
144 ui_engine: UIEngine[render_engine],
145 test: TestComponent[render_engine, ui_engine, egui],
146 egui: EguiEngine[render_engine, inputs]
147 },
148
149 PASSES {
150 0: {
151 PARTS: [
152 {
153 PIPELINE: "forte.test",
154 PREPARE: [],
155 RENDER: test,
156 }
157 ],
158 DEPTH: true
159 },
160 1: {
161 PARTS: [
162 {
163 PIPELINE: "forte.ui",
164 PREPARE: [],
165 RENDER: ui_engine,
166 },
167 {
168 PIPELINE: "forte.ui",
169 PREPARE: [],
170 RENDER: egui,
171 }
172 ],
173 DEPTH: false
174 }
175 }
176}
177
178fn main() { pollster::block_on(run_app::<App>()) }