lib.rs 19 KB

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