lib.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. use std::iter;
  2. use debug_triangle::DEBUG_VERT;
  3. use simple_plane::generate_square;
  4. use wgpu::util::DeviceExt;
  5. mod vertex;
  6. use vertex::Vertex;
  7. mod simple_plane;
  8. use simple_plane::generate_simple_plane;
  9. mod debug_triangle;
  10. mod camera;
  11. use camera::Camera;
  12. use camera::CameraUniform;
  13. mod wave;
  14. mod texture;
  15. use winit::{
  16. event::*,
  17. event_loop::EventLoop,
  18. keyboard::{KeyCode, PhysicalKey},
  19. window::{Window, WindowBuilder},
  20. };
  21. impl Vertex {
  22. fn desc() -> wgpu::VertexBufferLayout<'static> {
  23. wgpu::VertexBufferLayout {
  24. array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
  25. step_mode: wgpu::VertexStepMode::Vertex,
  26. attributes: &[
  27. wgpu::VertexAttribute {
  28. offset: 0,
  29. shader_location: 0,
  30. format: wgpu::VertexFormat::Float32x3,
  31. },
  32. wgpu::VertexAttribute {
  33. offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
  34. shader_location: 1,
  35. format: wgpu::VertexFormat::Float32x3,
  36. },
  37. ],
  38. }
  39. }
  40. }
  41. // // Changed
  42. // const VERTICES: &[Vertex] = &[
  43. // // Changed
  44. // Vertex { position: [-0.0868241, 0.49240386, 0.0], tex_coords: [0.4131759, 0.00759614], }, // A
  45. // Vertex { position: [-0.49513406, 0.06958647, 0.0], tex_coords: [0.0048659444, 0.43041354], }, // B
  46. // Vertex { position: [-0.21918549, -0.44939706, 0.0], tex_coords: [0.28081453, 0.949397], }, // C
  47. // Vertex { position: [0.35966998, -0.3473291, 0.0], tex_coords: [0.85967, 0.84732914], }, // D
  48. // Vertex { position: [0.44147372, 0.2347359, 0.0], tex_coords: [0.9414737, 0.2652641], }, // E
  49. // ];
  50. // const INDICES: &[u16] = &[
  51. // 0, 1, 4,
  52. // 1, 2, 4,
  53. // 2, 3, 4,
  54. // ];
  55. fn creer_plan_simple(largeur: f32, hauteur: f32) -> Vec<Vertex> {
  56. // Vecteur pour stocker les vertices
  57. let mut vertices: Vec<Vertex> = Vec::new();
  58. // Coordonnées des quatre coins du plan
  59. let coin_sup_gauche = [0.0, hauteur, 0.0];
  60. let coin_sup_droit = [largeur, hauteur, 0.0];
  61. let coin_inf_droit = [largeur, 0.0, 0.0];
  62. let coin_inf_gauche = [0.0, 0.0, 0.0];
  63. // Couleur par défaut (ajustez selon vos besoins)
  64. let couleur = [1.0, 1.0, 1.0];
  65. // Ajout des vertices
  66. vertices.push(Vertex { position: coin_sup_gauche, color: couleur });
  67. vertices.push(Vertex { position: coin_sup_droit, color: couleur });
  68. vertices.push(Vertex { position: coin_inf_droit, color: couleur });
  69. vertices.push(Vertex { position: coin_inf_gauche, color: couleur });
  70. // Retourne le vecteur de vertices
  71. vertices
  72. }
  73. struct State<'a> {
  74. surface: wgpu::Surface<'a>,
  75. device: wgpu::Device,
  76. queue: wgpu::Queue,
  77. config: wgpu::SurfaceConfiguration,
  78. size: winit::dpi::PhysicalSize<u32>,
  79. // The window must be declared after the surface so
  80. // it gets dropped after it as the surface contains
  81. // unsafe references to the window's resources.
  82. window: &'a Window,
  83. render_pipeline: wgpu::RenderPipeline,
  84. vertex_buffer: wgpu::Buffer,
  85. //index_buffer: wgpu::Buffer,
  86. num_vertices: u32,
  87. //num_indices: u32,
  88. diffuse_bind_group: wgpu::BindGroup,
  89. diffuse_texture: texture::Texture,
  90. camera: Camera,
  91. camera_uniform: CameraUniform,
  92. camera_buffer: wgpu::Buffer,
  93. camera_bind_group: wgpu::BindGroup,
  94. }
  95. impl<'a> State<'a> {
  96. async fn new(window: &'a Window) -> State<'a> {
  97. let size = window.inner_size();
  98. // The instance is a handle to our GPU
  99. // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
  100. let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
  101. backends: wgpu::Backends::all(),
  102. ..Default::default()
  103. });
  104. let surface = instance.create_surface(window).unwrap();
  105. let adapter = instance
  106. .request_adapter(&wgpu::RequestAdapterOptions {
  107. power_preference: wgpu::PowerPreference::default(),
  108. compatible_surface: Some(&surface),
  109. force_fallback_adapter: false,
  110. })
  111. .await
  112. .unwrap();
  113. let (device, queue) = adapter
  114. .request_device(
  115. &wgpu::DeviceDescriptor {
  116. label: None,
  117. required_features: wgpu::Features::empty(),
  118. // WebGL doesn't support all of wgpu's features, so if
  119. // we're building for the web we'll have to disable some.
  120. required_limits: if cfg!(target_arch = "wasm32") {
  121. wgpu::Limits::downlevel_webgl2_defaults()
  122. } else {
  123. wgpu::Limits::default()
  124. },
  125. },
  126. // Some(&std::path::Path::new("trace")), // Trace path
  127. None,
  128. )
  129. .await
  130. .unwrap();
  131. let surface_caps = surface.get_capabilities(&adapter);
  132. //println!("{:?}", &surface_caps.present_modes);
  133. // Shader code in this tutorial assumes an Srgb surface texture. Using a different
  134. // one will result all the colors comming out darker. If you want to support non
  135. // Srgb surfaces, you'll need to account for that when drawing to the frame.
  136. let surface_format = surface_caps
  137. .formats
  138. .iter()
  139. .copied()
  140. .find(|f| f.is_srgb())
  141. .unwrap_or(surface_caps.formats[0]);
  142. let config = wgpu::SurfaceConfiguration {
  143. usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
  144. format: surface_format,
  145. width: size.width,
  146. height: size.height,
  147. present_mode: surface_caps.present_modes[0],
  148. alpha_mode: surface_caps.alpha_modes[0],
  149. desired_maximum_frame_latency: 2,
  150. view_formats: vec![],
  151. };
  152. surface.configure(&device, &config);
  153. //Camera
  154. let camera = Camera{
  155. eye: glam::Vec3::new(0.0, 1.0, 2.0),
  156. target: glam::Vec3::new(0.0, 0.0, 0.0),
  157. up: glam::Vec3::new(0.0, 1.0, 0.0),
  158. aspect: config.width as f32 / config.height as f32,
  159. fovy: 45.0,
  160. znear: 0.1,
  161. zfar: 100.0,
  162. };
  163. //Camera buffer
  164. let mut camera_uniform = CameraUniform::new();
  165. camera_uniform.update_view_proj(&camera);
  166. let camera_buffer = device.create_buffer_init(
  167. &wgpu::util::BufferInitDescriptor{
  168. label: Some("Camera Buffer"),
  169. contents: bytemuck::cast_slice(&[camera_uniform]),
  170. usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
  171. }
  172. );
  173. //Camera Bind Group Layout
  174. let camera_bind_group_layout = device.create_bind_group_layout(
  175. &wgpu::BindGroupLayoutDescriptor{
  176. entries: &[
  177. wgpu::BindGroupLayoutEntry{
  178. binding: 0,
  179. visibility: wgpu::ShaderStages::VERTEX,
  180. ty: wgpu::BindingType::Buffer{
  181. min_binding_size: None,
  182. ty: wgpu::BufferBindingType::Uniform,
  183. has_dynamic_offset: false,
  184. },
  185. count: None,
  186. }
  187. ],
  188. label: Some("camera_bind_group_layout"),
  189. }
  190. );
  191. //Camera Bind Group
  192. let camera_bind_group = device.create_bind_group(
  193. &wgpu::BindGroupDescriptor{
  194. layout: &camera_bind_group_layout,
  195. entries: &[
  196. wgpu::BindGroupEntry{
  197. binding: 0,
  198. resource: camera_buffer.as_entire_binding(),
  199. }
  200. ],
  201. label: Some("camera_bind_group"),
  202. }
  203. );
  204. //Texture
  205. let diffuse_bytes = include_bytes!("happy-tree.png");
  206. let diffuse_texture = texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "happy-tree.png").unwrap();
  207. //BindGroup
  208. let texture_bind_group_layout =
  209. device.create_bind_group_layout(
  210. &wgpu::BindGroupLayoutDescriptor{
  211. label: Some("Texture Bind Group Layout"),
  212. entries: &[
  213. wgpu::BindGroupLayoutEntry{
  214. binding: 0,
  215. visibility: wgpu::ShaderStages::FRAGMENT,
  216. ty: wgpu::BindingType::Texture{
  217. sample_type: wgpu::TextureSampleType::Float{filterable: true},
  218. view_dimension: wgpu::TextureViewDimension::D2,
  219. multisampled: false,
  220. },
  221. count: None,
  222. },
  223. wgpu::BindGroupLayoutEntry{
  224. binding: 1,
  225. visibility: wgpu::ShaderStages::FRAGMENT,
  226. ty: wgpu::BindingType::Sampler(
  227. wgpu::SamplerBindingType::Filtering,
  228. ),
  229. count: None,
  230. }
  231. ]
  232. }
  233. );
  234. //Creation of the real bind group
  235. let diffuse_bind_group = device.create_bind_group(
  236. &wgpu::BindGroupDescriptor {
  237. layout: &texture_bind_group_layout,
  238. entries: &[
  239. wgpu::BindGroupEntry {
  240. binding: 0,
  241. resource: wgpu::BindingResource::TextureView(&diffuse_texture.view), // CHANGED!
  242. },
  243. wgpu::BindGroupEntry {
  244. binding: 1,
  245. resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), // CHANGED!
  246. }
  247. ],
  248. label: Some("diffuse_bind_group"),
  249. }
  250. );
  251. //Shader and Pipeline
  252. let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
  253. label: Some("Shader"),
  254. source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
  255. });
  256. let render_pipeline_layout =
  257. device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
  258. label: Some("Render Pipeline Layout"),
  259. bind_group_layouts: &[
  260. &texture_bind_group_layout,
  261. &camera_bind_group_layout,
  262. ],
  263. push_constant_ranges: &[],
  264. });
  265. let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor{
  266. label: Some("Render Pipeline"),
  267. layout: Some(&render_pipeline_layout),
  268. vertex: wgpu::VertexState{
  269. module: &shader,
  270. entry_point: "vs_main",
  271. buffers: &[
  272. Vertex::desc()
  273. ],
  274. },
  275. fragment: Some(wgpu::FragmentState{
  276. module: &shader,
  277. entry_point: "fs_main",
  278. targets: &[Some(wgpu::ColorTargetState{
  279. format: config.format,
  280. blend: Some(wgpu::BlendState::REPLACE),
  281. write_mask: wgpu::ColorWrites::ALL,
  282. })],
  283. }),
  284. primitive: wgpu::PrimitiveState{
  285. topology: wgpu::PrimitiveTopology::TriangleList,
  286. strip_index_format: None,
  287. front_face: wgpu::FrontFace::Ccw,
  288. cull_mode: Some(wgpu::Face::Back),
  289. polygon_mode: wgpu::PolygonMode::Fill,
  290. unclipped_depth: false,
  291. conservative: false,
  292. },
  293. depth_stencil: None,
  294. multisample: wgpu::MultisampleState{
  295. count: 1,
  296. mask: !0,
  297. alpha_to_coverage_enabled: false,
  298. },
  299. multiview: None,
  300. });
  301. //let (vertices, indices) = creer_plan_subdivise(1.0, 1.0, 10);
  302. //let vert = creer_plan_simple(1.0, 1.0);
  303. //let vert = generate_simple_plane(0.5, 1);
  304. //let vert = generate_square();
  305. let vert = DEBUG_VERT;
  306. // Create a buffer with the vertex data
  307. let vertex_buffer = device.create_buffer_init(
  308. &wgpu::util::BufferInitDescriptor{
  309. label: Some("Vertex Buffer"),
  310. contents: bytemuck::cast_slice(&vert),
  311. usage: wgpu::BufferUsages::VERTEX,
  312. }
  313. );
  314. // let index_buffer = device.create_buffer_init(
  315. // &wgpu::util::BufferInitDescriptor{
  316. // label: Some("Indice Buffer"),
  317. // usage: wgpu::BufferUsages::INDEX,
  318. // contents: bytemuck::cast_slice(&indices),
  319. // }
  320. // );
  321. let num_vertices = vert.len() as u32;
  322. //let num_indices = indices.len() as u32;
  323. Self {
  324. surface,
  325. device,
  326. queue,
  327. config,
  328. size,
  329. window,
  330. render_pipeline,
  331. vertex_buffer,
  332. //index_buffer,
  333. num_vertices,
  334. //num_indices,
  335. diffuse_bind_group,
  336. diffuse_texture,
  337. //Camera
  338. camera,
  339. camera_uniform,
  340. camera_buffer,
  341. camera_bind_group,
  342. }
  343. }
  344. fn window(&self) -> &Window {
  345. self.window
  346. }
  347. pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
  348. if new_size.width > 0 && new_size.height > 0 {
  349. self.size = new_size;
  350. self.config.width = new_size.width;
  351. self.config.height = new_size.height;
  352. self.surface.configure(&self.device, &self.config);
  353. }
  354. }
  355. #[allow(unused_variables)]
  356. fn input(&mut self, event: &WindowEvent) -> bool {
  357. false
  358. }
  359. fn update(&mut self) {}
  360. fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
  361. let output = self.surface.get_current_texture()?;
  362. let view = output
  363. .texture
  364. .create_view(&wgpu::TextureViewDescriptor::default());
  365. let mut encoder = self
  366. .device
  367. .create_command_encoder(&wgpu::CommandEncoderDescriptor {
  368. label: Some("Render Encoder"),
  369. });
  370. {
  371. let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
  372. label: Some("Render Pass"),
  373. color_attachments: &[Some(wgpu::RenderPassColorAttachment {
  374. view: &view,
  375. resolve_target: None,
  376. ops: wgpu::Operations {
  377. load: wgpu::LoadOp::Clear(wgpu::Color {
  378. r: 0.1,
  379. g: 0.2,
  380. b: 0.3,
  381. a: 1.0,
  382. }),
  383. store: wgpu::StoreOp::Store,
  384. },
  385. })],
  386. depth_stencil_attachment: None,
  387. occlusion_query_set: None,
  388. timestamp_writes: None,
  389. });
  390. //Add the pipeline
  391. render_pass.set_pipeline(&self.render_pipeline);
  392. //Add the bind group for the texture
  393. render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
  394. //Add the camera bind group
  395. render_pass.set_bind_group(1, &self.camera_bind_group, &[]);
  396. render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
  397. //render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
  398. //render_pass.draw_indexed(0..self.num_indices,0, 0..1);
  399. render_pass.draw(0..self.num_vertices, 0..1);
  400. }
  401. self.queue.submit(iter::once(encoder.finish()));
  402. output.present();
  403. Ok(())
  404. }
  405. }
  406. pub async fn run() {
  407. env_logger::init();
  408. let event_loop = EventLoop::new().unwrap();
  409. let window = WindowBuilder::new().build(&event_loop).unwrap();
  410. // State::new uses async code, so we're going to wait for it to finish
  411. let mut state = State::new(&window).await;
  412. event_loop
  413. .run(move |event, control_flow| {
  414. match event {
  415. Event::WindowEvent {
  416. ref event,
  417. window_id,
  418. } if window_id == state.window().id() => {
  419. if !state.input(event) {
  420. // UPDATED!
  421. match event {
  422. WindowEvent::CloseRequested
  423. | WindowEvent::KeyboardInput {
  424. event:
  425. KeyEvent {
  426. state: ElementState::Pressed,
  427. physical_key: PhysicalKey::Code(KeyCode::Escape),
  428. ..
  429. },
  430. ..
  431. } => control_flow.exit(),
  432. WindowEvent::Resized(physical_size) => {
  433. state.resize(*physical_size);
  434. }
  435. WindowEvent::RedrawRequested => {
  436. // This tells winit that we want another frame after this one
  437. state.window().request_redraw();
  438. state.update();
  439. match state.render() {
  440. Ok(_) => {}
  441. // Reconfigure the surface if it's lost or outdated
  442. Err(
  443. wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
  444. ) => state.resize(state.size),
  445. // The system is out of memory, we should probably quit
  446. Err(wgpu::SurfaceError::OutOfMemory) => {
  447. log::error!("OutOfMemory");
  448. control_flow.exit();
  449. }
  450. // This happens when the a frame takes too long to present
  451. Err(wgpu::SurfaceError::Timeout) => {
  452. log::warn!("Surface timeout")
  453. }
  454. }
  455. }
  456. _ => {}
  457. }
  458. }
  459. }
  460. _ => {}
  461. }
  462. })
  463. .unwrap();
  464. }