lib.rs 19 KB

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