dfg.rs 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  1. use std::iter;
  2. use rand::Rng;
  3. use cgmath::prelude::*;
  4. use wgpu::util::DeviceExt;
  5. use winit::{
  6. event::*,
  7. event_loop::{ControlFlow, EventLoop},
  8. window::Window,
  9. };
  10. use sapvi::gfx::{model, texture};
  11. use model::{DrawLight, DrawModel, Vertex};
  12. use std::time::Instant;
  13. #[macro_use]
  14. extern crate lazy_static;
  15. lazy_static! {
  16. static ref START: Instant = Instant::now();
  17. }
  18. fn get_time() -> f32 {
  19. START.elapsed().as_secs_f32()
  20. }
  21. const FONT_BYTES: &[u8] = include_bytes!("../../res/font/PressStart2P-Regular.ttf");
  22. #[rustfmt::skip]
  23. pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
  24. 1.0, 0.0, 0.0, 0.0,
  25. 0.0, 1.0, 0.0, 0.0,
  26. 0.0, 0.0, 0.5, 0.0,
  27. 0.0, 0.0, 0.5, 1.0,
  28. );
  29. const NUM_INSTANCES_PER_ROW: u32 = 10;
  30. struct Camera {
  31. eye: cgmath::Point3<f32>,
  32. target: cgmath::Point3<f32>,
  33. up: cgmath::Vector3<f32>,
  34. aspect: f32,
  35. fovy: f32,
  36. znear: f32,
  37. zfar: f32,
  38. }
  39. impl Camera {
  40. fn build_view_projection_matrix(&self) -> cgmath::Matrix4<f32> {
  41. let view = cgmath::Matrix4::look_at(self.eye, self.target, self.up);
  42. let proj = cgmath::perspective(cgmath::Deg(self.fovy), self.aspect, self.znear, self.zfar);
  43. proj * view
  44. }
  45. }
  46. #[repr(C)]
  47. #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
  48. struct Uniforms {
  49. view_position: [f32; 4],
  50. view_proj: [[f32; 4]; 4],
  51. }
  52. impl Uniforms {
  53. fn new() -> Self {
  54. Self {
  55. view_position: [0.0; 4],
  56. view_proj: cgmath::Matrix4::identity().into(),
  57. }
  58. }
  59. fn update_view_proj(&mut self, camera: &Camera) {
  60. // We don't specifically need homogeneous coordinates since we're just using
  61. // a vec3 in the shader. We're using Point3 for the camera.eye, and this is
  62. // the easiest way to convert to Vector4. We're using Vector4 because of
  63. // the uniforms 16 byte spacing requirement
  64. self.view_position = camera.eye.to_homogeneous().into();
  65. // self.view_proj = OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix();
  66. self.view_proj = camera.build_view_projection_matrix().into();
  67. }
  68. }
  69. struct CameraController {
  70. speed: f32,
  71. is_up_pressed: bool,
  72. is_down_pressed: bool,
  73. is_forward_pressed: bool,
  74. is_backward_pressed: bool,
  75. is_left_pressed: bool,
  76. is_right_pressed: bool,
  77. }
  78. impl CameraController {
  79. fn new(speed: f32) -> Self {
  80. Self {
  81. speed,
  82. is_up_pressed: false,
  83. is_down_pressed: false,
  84. is_forward_pressed: false,
  85. is_backward_pressed: false,
  86. is_left_pressed: false,
  87. is_right_pressed: false,
  88. }
  89. }
  90. fn process_events(&mut self, event: &WindowEvent) -> bool {
  91. match event {
  92. WindowEvent::KeyboardInput {
  93. input:
  94. KeyboardInput {
  95. state,
  96. virtual_keycode: Some(keycode),
  97. ..
  98. },
  99. ..
  100. } => {
  101. let is_pressed = *state == ElementState::Pressed;
  102. match keycode {
  103. VirtualKeyCode::Space => {
  104. self.is_up_pressed = is_pressed;
  105. true
  106. }
  107. VirtualKeyCode::LShift => {
  108. self.is_down_pressed = is_pressed;
  109. true
  110. }
  111. VirtualKeyCode::W | VirtualKeyCode::Up => {
  112. self.is_forward_pressed = is_pressed;
  113. true
  114. }
  115. VirtualKeyCode::A | VirtualKeyCode::Left => {
  116. self.is_left_pressed = is_pressed;
  117. true
  118. }
  119. VirtualKeyCode::S | VirtualKeyCode::Down => {
  120. self.is_backward_pressed = is_pressed;
  121. true
  122. }
  123. VirtualKeyCode::D | VirtualKeyCode::Right => {
  124. self.is_right_pressed = is_pressed;
  125. true
  126. }
  127. _ => false,
  128. }
  129. }
  130. _ => false,
  131. }
  132. }
  133. fn update_camera(&self, camera: &mut Camera) {
  134. let forward = camera.target - camera.eye;
  135. let forward_norm = forward.normalize();
  136. let forward_mag = forward.magnitude();
  137. // Prevents glitching when camera gets too close to the
  138. // center of the scene.
  139. if self.is_forward_pressed && forward_mag > self.speed {
  140. camera.eye += forward_norm * self.speed;
  141. }
  142. if self.is_backward_pressed {
  143. camera.eye -= forward_norm * self.speed;
  144. }
  145. let right = forward_norm.cross(camera.up);
  146. // Redo radius calc in case the up/ down is pressed.
  147. let forward = camera.target - camera.eye;
  148. let forward_mag = forward.magnitude();
  149. if self.is_right_pressed {
  150. // Rescale the distance between the target and eye so
  151. // that it doesn't change. The eye therefore still
  152. // lies on the circle made by the target and eye.
  153. camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag;
  154. }
  155. if self.is_left_pressed {
  156. camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag;
  157. }
  158. }
  159. }
  160. struct Instance {
  161. position: cgmath::Vector3<f32>,
  162. rotation: cgmath::Quaternion<f32>,
  163. }
  164. impl Instance {
  165. fn to_raw(&self) -> InstanceRaw {
  166. InstanceRaw {
  167. model: (cgmath::Matrix4::from_translation(self.position)
  168. * cgmath::Matrix4::from(self.rotation))
  169. .into(),
  170. }
  171. }
  172. }
  173. #[repr(C)]
  174. #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
  175. struct InstanceRaw {
  176. #[allow(dead_code)]
  177. model: [[f32; 4]; 4],
  178. }
  179. impl model::Vertex for InstanceRaw {
  180. fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
  181. use std::mem;
  182. wgpu::VertexBufferLayout {
  183. array_stride: mem::size_of::<InstanceRaw>() as wgpu::BufferAddress,
  184. // We need to switch from using a step mode of Vertex to Instance
  185. // This means that our shaders will only change to use the next
  186. // instance when the shader starts processing a new instance
  187. step_mode: wgpu::InputStepMode::Instance,
  188. attributes: &[
  189. wgpu::VertexAttribute {
  190. offset: 0,
  191. // While our vertex shader only uses locations 0, and 1 now, in later tutorials we'll
  192. // be using 2, 3, and 4, for Vertex. We'll start at slot 5 not conflict with them later
  193. shader_location: 5,
  194. format: wgpu::VertexFormat::Float4,
  195. },
  196. // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot
  197. // for each vec4. We don't have to do this in code though.
  198. wgpu::VertexAttribute {
  199. offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
  200. shader_location: 6,
  201. format: wgpu::VertexFormat::Float4,
  202. },
  203. wgpu::VertexAttribute {
  204. offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
  205. shader_location: 7,
  206. format: wgpu::VertexFormat::Float4,
  207. },
  208. wgpu::VertexAttribute {
  209. offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
  210. shader_location: 8,
  211. format: wgpu::VertexFormat::Float4,
  212. },
  213. ],
  214. }
  215. }
  216. }
  217. #[repr(C)]
  218. #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
  219. struct Light {
  220. position: [f32; 3],
  221. // Due to uniforms requiring 16 byte (4 float) spacing, we need to use a padding field here
  222. _padding: u32,
  223. color: [f32; 3],
  224. }
  225. pub const UNBOUNDED_F32: f32 = std::f32::INFINITY;
  226. #[derive(Debug)]
  227. pub struct Text {
  228. pub position: cgmath::Vector2<f32>,
  229. pub bounds: cgmath::Vector2<f32>,
  230. pub color: cgmath::Vector4<f32>,
  231. pub text: String,
  232. pub size: f32,
  233. pub visible: bool,
  234. pub focused: bool,
  235. pub centered: bool,
  236. }
  237. impl Default for Text {
  238. fn default() -> Self {
  239. Self {
  240. position: (0.0, 0.0).into(),
  241. bounds: (UNBOUNDED_F32, UNBOUNDED_F32).into(),
  242. color: (1.0, 1.0, 1.0, 1.0).into(),
  243. text: String::new(),
  244. size: 16.0,
  245. visible: false,
  246. focused: false,
  247. centered: false,
  248. }
  249. }
  250. }
  251. const VERTEX_Z: f32 = 0.0;
  252. // (-1, 1) (1, 1)
  253. // +-----------------------+
  254. // | |
  255. // | |
  256. // | |
  257. // | |
  258. // | |
  259. // | |
  260. // | |
  261. // +-----------------------+
  262. // (-1, -1) (1, -1)
  263. const VERTICES: &[model::ModelVertex] = &[
  264. // top left
  265. model::ModelVertex {
  266. position: [-1.0, 1.0, VERTEX_Z],
  267. tex_coords: [0.0, 0.0],
  268. },
  269. // bottom left
  270. model::ModelVertex {
  271. position: [-1.0, 0.5, VERTEX_Z],
  272. tex_coords: [0.0, 1.0],
  273. },
  274. // bottom right
  275. model::ModelVertex {
  276. position: [-0.5, 0.5, VERTEX_Z],
  277. tex_coords: [1.0, 1.0],
  278. },
  279. // top right
  280. model::ModelVertex {
  281. position: [-0.5, 1.0, VERTEX_Z],
  282. tex_coords: [1.0, 0.0],
  283. },
  284. ];
  285. //const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4];
  286. const INDICES: &[u16] = &[0, 1, 2, 0, 2, 3];
  287. struct State {
  288. surface: wgpu::Surface,
  289. device: wgpu::Device,
  290. queue: wgpu::Queue,
  291. sc_desc: wgpu::SwapChainDescriptor,
  292. swap_chain: wgpu::SwapChain,
  293. render_pipeline: wgpu::RenderPipeline,
  294. obj_model: model::Model,
  295. camera: Camera,
  296. camera_controller: CameraController,
  297. uniforms: Uniforms,
  298. uniform_buffer: wgpu::Buffer,
  299. uniform_bind_group: wgpu::BindGroup,
  300. instances: Vec<Instance>,
  301. #[allow(dead_code)]
  302. instance_buffer: wgpu::Buffer,
  303. depth_texture: texture::Texture,
  304. size: winit::dpi::PhysicalSize<u32>,
  305. light: Light,
  306. light_buffer: wgpu::Buffer,
  307. light_bind_group: wgpu::BindGroup,
  308. light_render_pipeline: wgpu::RenderPipeline,
  309. ui_render_pipeline: wgpu::RenderPipeline,
  310. vertex_buffer: wgpu::Buffer,
  311. index_buffer: wgpu::Buffer,
  312. num_indices: u32,
  313. #[allow(dead_code)]
  314. diffuse_texture: texture::Texture,
  315. diffuse_bind_group: wgpu::BindGroup,
  316. #[allow(dead_code)]
  317. cartoon_texture: texture::Texture,
  318. cartoon_bind_group: wgpu::BindGroup,
  319. glyph_brush: wgpu_glyph::GlyphBrush<()>,
  320. staging_belt: wgpu::util::StagingBelt,
  321. is_space_pressed: bool,
  322. }
  323. fn create_render_pipeline(
  324. device: &wgpu::Device,
  325. layout: &wgpu::PipelineLayout,
  326. color_format: wgpu::TextureFormat,
  327. depth_format: Option<wgpu::TextureFormat>,
  328. vertex_layouts: &[wgpu::VertexBufferLayout],
  329. vs_src: wgpu::ShaderModuleDescriptor,
  330. fs_src: wgpu::ShaderModuleDescriptor,
  331. ) -> wgpu::RenderPipeline {
  332. let vs_module = device.create_shader_module(&vs_src);
  333. let fs_module = device.create_shader_module(&fs_src);
  334. device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
  335. label: Some("Render Pipeline"),
  336. layout: Some(&layout),
  337. vertex: wgpu::VertexState {
  338. module: &vs_module,
  339. entry_point: "main",
  340. buffers: vertex_layouts,
  341. },
  342. fragment: Some(wgpu::FragmentState {
  343. module: &fs_module,
  344. entry_point: "main",
  345. targets: &[wgpu::ColorTargetState {
  346. format: color_format,
  347. alpha_blend: wgpu::BlendState::REPLACE,
  348. color_blend: wgpu::BlendState::REPLACE,
  349. write_mask: wgpu::ColorWrite::ALL,
  350. }],
  351. }),
  352. primitive: wgpu::PrimitiveState {
  353. topology: wgpu::PrimitiveTopology::TriangleList,
  354. strip_index_format: None,
  355. front_face: wgpu::FrontFace::Ccw,
  356. cull_mode: wgpu::CullMode::Back,
  357. // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE
  358. polygon_mode: wgpu::PolygonMode::Fill,
  359. },
  360. depth_stencil: depth_format.map(|format| wgpu::DepthStencilState {
  361. format,
  362. depth_write_enabled: true,
  363. depth_compare: wgpu::CompareFunction::Less,
  364. stencil: wgpu::StencilState::default(),
  365. bias: wgpu::DepthBiasState::default(),
  366. // Setting this to true requires Features::DEPTH_CLAMPING
  367. clamp_depth: false,
  368. }),
  369. multisample: wgpu::MultisampleState {
  370. count: 1,
  371. mask: !0,
  372. alpha_to_coverage_enabled: false,
  373. },
  374. })
  375. }
  376. impl State {
  377. async fn new(window: &Window) -> Self {
  378. let size = window.inner_size();
  379. // The instance is a handle to our GPU
  380. // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
  381. let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
  382. let surface = unsafe { instance.create_surface(window) };
  383. let adapter = instance
  384. .request_adapter(&wgpu::RequestAdapterOptions {
  385. power_preference: wgpu::PowerPreference::default(),
  386. compatible_surface: Some(&surface),
  387. })
  388. .await
  389. .unwrap();
  390. let (device, queue) = adapter
  391. .request_device(
  392. &wgpu::DeviceDescriptor {
  393. label: None,
  394. features: wgpu::Features::empty(),
  395. limits: wgpu::Limits::default(),
  396. },
  397. None, // Trace path
  398. )
  399. .await
  400. .unwrap();
  401. let sc_desc = wgpu::SwapChainDescriptor {
  402. usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
  403. format: adapter.get_swap_chain_preferred_format(&surface),
  404. width: size.width,
  405. height: size.height,
  406. present_mode: wgpu::PresentMode::Fifo,
  407. };
  408. let swap_chain = device.create_swap_chain(&surface, &sc_desc);
  409. let texture_bind_group_layout =
  410. device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
  411. entries: &[
  412. wgpu::BindGroupLayoutEntry {
  413. binding: 0,
  414. visibility: wgpu::ShaderStage::FRAGMENT,
  415. ty: wgpu::BindingType::Texture {
  416. multisampled: false,
  417. view_dimension: wgpu::TextureViewDimension::D2,
  418. sample_type: wgpu::TextureSampleType::Float { filterable: false },
  419. },
  420. count: None,
  421. },
  422. wgpu::BindGroupLayoutEntry {
  423. binding: 1,
  424. visibility: wgpu::ShaderStage::FRAGMENT,
  425. ty: wgpu::BindingType::Sampler {
  426. comparison: false,
  427. filtering: true,
  428. },
  429. count: None,
  430. },
  431. ],
  432. label: Some("texture_bind_group_layout"),
  433. });
  434. let camera = Camera {
  435. eye: (0.0, 5.0, -10.0).into(),
  436. target: (0.0, 0.0, 0.0).into(),
  437. up: cgmath::Vector3::unit_y(),
  438. aspect: sc_desc.width as f32 / sc_desc.height as f32,
  439. fovy: 45.0,
  440. znear: 0.1,
  441. zfar: 100.0,
  442. };
  443. let camera_controller = CameraController::new(0.2);
  444. let mut uniforms = Uniforms::new();
  445. uniforms.update_view_proj(&camera);
  446. let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
  447. label: Some("Uniform Buffer"),
  448. contents: bytemuck::cast_slice(&[uniforms]),
  449. usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
  450. });
  451. const SPACE_BETWEEN: f32 = 3.0;
  452. let instances = (0..NUM_INSTANCES_PER_ROW)
  453. .flat_map(|z| {
  454. (0..NUM_INSTANCES_PER_ROW).map(move |x| {
  455. let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
  456. let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
  457. let time = get_time() * 100.0;
  458. println!("{} {} {}", x, z, time);
  459. let y = ((x + time).sin() + (z + time).sin()) * 20.0;
  460. let position = cgmath::Vector3 { x, y, z };
  461. let rotation =
  462. cgmath::Quaternion::from_axis_angle(
  463. cgmath::Vector3::unit_z(),
  464. cgmath::Deg(180.0 + 0.0),
  465. );
  466. /*
  467. let rotation = if position.is_zero() {
  468. cgmath::Quaternion::from_axis_angle(
  469. cgmath::Vector3::unit_z(),
  470. cgmath::Deg(180.0 + 0.0),
  471. )
  472. } else {
  473. cgmath::Quaternion::from_axis_angle(
  474. position.clone().normalize(),
  475. cgmath::Deg(180.0 + 45.0),
  476. )
  477. };
  478. */
  479. Instance { position, rotation }
  480. })
  481. })
  482. .collect::<Vec<_>>();
  483. let instance_data = instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
  484. let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
  485. label: Some("Instance Buffer"),
  486. contents: bytemuck::cast_slice(&instance_data),
  487. usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
  488. });
  489. let uniform_bind_group_layout =
  490. device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
  491. entries: &[wgpu::BindGroupLayoutEntry {
  492. binding: 0,
  493. visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
  494. ty: wgpu::BindingType::Buffer {
  495. ty: wgpu::BufferBindingType::Uniform,
  496. has_dynamic_offset: false,
  497. min_binding_size: None,
  498. },
  499. count: None,
  500. }],
  501. label: Some("uniform_bind_group_layout"),
  502. });
  503. let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
  504. layout: &uniform_bind_group_layout,
  505. entries: &[wgpu::BindGroupEntry {
  506. binding: 0,
  507. resource: uniform_buffer.as_entire_binding(),
  508. }],
  509. label: Some("uniform_bind_group"),
  510. });
  511. let res_dir = std::path::Path::new("res/model/");
  512. let obj_model = model::Model::load(
  513. &device,
  514. &queue,
  515. &texture_bind_group_layout,
  516. res_dir.join("earth.obj"),
  517. )
  518. .unwrap();
  519. let light = Light {
  520. position: [4.0, 4.0, 2.0],
  521. _padding: 0,
  522. color: [1.0, 1.0, 1.0],
  523. };
  524. let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
  525. label: Some("Light VB"),
  526. contents: bytemuck::cast_slice(&[light]),
  527. usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
  528. });
  529. let light_bind_group_layout =
  530. device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
  531. entries: &[wgpu::BindGroupLayoutEntry {
  532. binding: 0,
  533. visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
  534. ty: wgpu::BindingType::Buffer {
  535. ty: wgpu::BufferBindingType::Uniform,
  536. has_dynamic_offset: false,
  537. min_binding_size: None,
  538. },
  539. count: None,
  540. }],
  541. label: None,
  542. });
  543. let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
  544. layout: &light_bind_group_layout,
  545. entries: &[wgpu::BindGroupEntry {
  546. binding: 0,
  547. resource: light_buffer.as_entire_binding(),
  548. }],
  549. label: None,
  550. });
  551. let depth_texture =
  552. texture::Texture::create_depth_texture(&device, &sc_desc, "depth_texture");
  553. let render_pipeline_layout =
  554. device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
  555. label: Some("Render Pipeline Layout"),
  556. bind_group_layouts: &[
  557. &texture_bind_group_layout,
  558. &uniform_bind_group_layout,
  559. &light_bind_group_layout,
  560. ],
  561. push_constant_ranges: &[],
  562. });
  563. let render_pipeline = create_render_pipeline(
  564. &device,
  565. &render_pipeline_layout,
  566. sc_desc.format,
  567. Some(texture::Texture::DEPTH_FORMAT),
  568. &[model::ModelVertex::desc(), InstanceRaw::desc()],
  569. wgpu::include_spirv!("../../res/shader/shader.vert.spv"),
  570. wgpu::include_spirv!("../../res/shader/shader.frag.spv"),
  571. );
  572. let light_render_pipeline = {
  573. let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
  574. label: Some("Light Pipeline Layout"),
  575. bind_group_layouts: &[&uniform_bind_group_layout, &light_bind_group_layout],
  576. push_constant_ranges: &[],
  577. });
  578. create_render_pipeline(
  579. &device,
  580. &layout,
  581. sc_desc.format,
  582. Some(texture::Texture::DEPTH_FORMAT),
  583. &[model::ModelVertex::desc()],
  584. wgpu::include_spirv!("../../res/shader/light.vert.spv"),
  585. wgpu::include_spirv!("../../res/shader/light.frag.spv"),
  586. )
  587. };
  588. //-------------------
  589. let texture_bind_group_layout =
  590. device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
  591. entries: &[
  592. wgpu::BindGroupLayoutEntry {
  593. binding: 0,
  594. visibility: wgpu::ShaderStage::FRAGMENT,
  595. ty: wgpu::BindingType::Texture {
  596. multisampled: false,
  597. view_dimension: wgpu::TextureViewDimension::D2,
  598. sample_type: wgpu::TextureSampleType::Float { filterable: false },
  599. },
  600. count: None,
  601. },
  602. wgpu::BindGroupLayoutEntry {
  603. binding: 1,
  604. visibility: wgpu::ShaderStage::FRAGMENT,
  605. ty: wgpu::BindingType::Sampler {
  606. comparison: false,
  607. filtering: true,
  608. },
  609. count: None,
  610. },
  611. ],
  612. label: Some("texture_bind_group_layout"),
  613. });
  614. let diffuse_bytes = include_bytes!("../../res/img/absolutely-proprietary.png");
  615. let diffuse_texture =
  616. texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "stallman1").unwrap();
  617. let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
  618. layout: &texture_bind_group_layout,
  619. entries: &[
  620. wgpu::BindGroupEntry {
  621. binding: 0,
  622. resource: wgpu::BindingResource::TextureView(&diffuse_texture.view),
  623. },
  624. wgpu::BindGroupEntry {
  625. binding: 1,
  626. resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
  627. },
  628. ],
  629. label: Some("diffuse_bind_group"),
  630. });
  631. let cartoon_bytes = include_bytes!("../../res/img/absolutely-proprietary2.png");
  632. let cartoon_texture =
  633. texture::Texture::from_bytes(&device, &queue, cartoon_bytes, "stallman2")
  634. .unwrap();
  635. let cartoon_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
  636. layout: &texture_bind_group_layout,
  637. entries: &[
  638. wgpu::BindGroupEntry {
  639. binding: 0,
  640. resource: wgpu::BindingResource::TextureView(&cartoon_texture.view),
  641. },
  642. wgpu::BindGroupEntry {
  643. binding: 1,
  644. resource: wgpu::BindingResource::Sampler(&cartoon_texture.sampler),
  645. },
  646. ],
  647. label: Some("cartoon_bind_group"),
  648. });
  649. let vs_module = device.create_shader_module(&wgpu::include_spirv!("../../res/shader/ui_shader.vert.spv"));
  650. let fs_module = device.create_shader_module(&wgpu::include_spirv!("../../res/shader/ui_shader.frag.spv"));
  651. let render_pipeline_layout =
  652. device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
  653. label: Some("Render Pipeline Layout"),
  654. bind_group_layouts: &[&texture_bind_group_layout],
  655. push_constant_ranges: &[],
  656. });
  657. let ui_render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
  658. label: Some("Render Pipeline"),
  659. layout: Some(&render_pipeline_layout),
  660. vertex: wgpu::VertexState {
  661. module: &vs_module,
  662. entry_point: "main",
  663. buffers: &[model::ModelVertex::desc()],
  664. },
  665. fragment: Some(wgpu::FragmentState {
  666. module: &fs_module,
  667. entry_point: "main",
  668. targets: &[wgpu::ColorTargetState {
  669. format: sc_desc.format,
  670. alpha_blend: wgpu::BlendState::REPLACE,
  671. color_blend: wgpu::BlendState::REPLACE,
  672. write_mask: wgpu::ColorWrite::ALL,
  673. }],
  674. }),
  675. primitive: wgpu::PrimitiveState {
  676. topology: wgpu::PrimitiveTopology::TriangleList,
  677. strip_index_format: None,
  678. front_face: wgpu::FrontFace::Ccw,
  679. cull_mode: wgpu::CullMode::Back,
  680. // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE
  681. polygon_mode: wgpu::PolygonMode::Fill,
  682. },
  683. depth_stencil: Some(wgpu::DepthStencilState {
  684. format: texture::Texture::DEPTH_FORMAT,
  685. depth_write_enabled: true,
  686. depth_compare: wgpu::CompareFunction::Less,
  687. stencil: wgpu::StencilState::default(),
  688. bias: wgpu::DepthBiasState::default(),
  689. // Setting this to true requires Features::DEPTH_CLAMPING
  690. clamp_depth: false,
  691. }),
  692. multisample: wgpu::MultisampleState {
  693. count: 1,
  694. mask: !0,
  695. alpha_to_coverage_enabled: false,
  696. },
  697. });
  698. let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
  699. label: Some("Vertex Buffer"),
  700. contents: bytemuck::cast_slice(VERTICES),
  701. usage: wgpu::BufferUsage::VERTEX,
  702. });
  703. let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
  704. label: Some("Index Buffer"),
  705. contents: bytemuck::cast_slice(INDICES),
  706. usage: wgpu::BufferUsage::INDEX,
  707. });
  708. let num_indices = INDICES.len() as u32;
  709. let font = wgpu_glyph::ab_glyph::FontArc::try_from_slice(FONT_BYTES).unwrap();
  710. let glyph_brush =
  711. wgpu_glyph::GlyphBrushBuilder::using_font(font).build(&device, sc_desc.format);
  712. let staging_belt = wgpu::util::StagingBelt::new(1024);
  713. Self {
  714. surface,
  715. device,
  716. queue,
  717. sc_desc,
  718. swap_chain,
  719. render_pipeline,
  720. obj_model,
  721. camera,
  722. camera_controller,
  723. uniform_buffer,
  724. uniform_bind_group,
  725. uniforms,
  726. instances,
  727. instance_buffer,
  728. depth_texture,
  729. size,
  730. light,
  731. light_buffer,
  732. light_bind_group,
  733. light_render_pipeline,
  734. ui_render_pipeline,
  735. vertex_buffer,
  736. index_buffer,
  737. num_indices,
  738. diffuse_texture,
  739. diffuse_bind_group,
  740. cartoon_texture,
  741. cartoon_bind_group,
  742. glyph_brush,
  743. staging_belt,
  744. is_space_pressed: true,
  745. }
  746. }
  747. fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
  748. self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32;
  749. self.size = new_size;
  750. self.sc_desc.width = new_size.width;
  751. self.sc_desc.height = new_size.height;
  752. self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
  753. self.depth_texture =
  754. texture::Texture::create_depth_texture(&self.device, &self.sc_desc, "depth_texture");
  755. }
  756. fn input(&mut self, event: &WindowEvent) -> bool {
  757. self.camera_controller.process_events(event)
  758. }
  759. fn update(&mut self) {
  760. if rand::thread_rng().gen_range(0, 5) == 0 {
  761. self.is_space_pressed = !self.is_space_pressed;
  762. }
  763. self.camera_controller.update_camera(&mut self.camera);
  764. self.uniforms.update_view_proj(&self.camera);
  765. self.queue.write_buffer(
  766. &self.uniform_buffer,
  767. 0,
  768. bytemuck::cast_slice(&[self.uniforms]),
  769. );
  770. let time = get_time();
  771. const SPACE_BETWEEN: f32 = 3.0;
  772. let instances = (0..NUM_INSTANCES_PER_ROW)
  773. .flat_map(|z| {
  774. (0..NUM_INSTANCES_PER_ROW).map(move |x| {
  775. let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
  776. let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
  777. //println!("{} {} {}", x, z, time);
  778. let y = ((x/3.0 + time).sin() + (z/3.0 + time).cos()) * 1.5;
  779. let position = cgmath::Vector3 { x, y, z };
  780. let rotation =
  781. cgmath::Quaternion::from_axis_angle(
  782. cgmath::Vector3::unit_z(),
  783. cgmath::Deg(180.0 + 0.0),
  784. );
  785. Instance { position, rotation }
  786. })
  787. })
  788. .collect::<Vec<_>>();
  789. let instance_data = instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
  790. self.queue.write_buffer(&self.instance_buffer, 0,
  791. bytemuck::cast_slice(&instance_data));
  792. // Update the light
  793. let old_position: cgmath::Vector3<_> = self.light.position.into();
  794. self.light.position =
  795. (cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
  796. * old_position)
  797. .into();
  798. self.queue
  799. .write_buffer(&self.light_buffer, 0, bytemuck::cast_slice(&[self.light]));
  800. }
  801. fn render(&mut self) -> Result<(), wgpu::SwapChainError> {
  802. let frame = self.swap_chain.get_current_frame()?.output;
  803. let mut encoder = self
  804. .device
  805. .create_command_encoder(&wgpu::CommandEncoderDescriptor {
  806. label: Some("Render Encoder"),
  807. });
  808. {
  809. let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
  810. label: Some("Render Pass"),
  811. color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
  812. attachment: &frame.view,
  813. resolve_target: None,
  814. ops: wgpu::Operations {
  815. load: wgpu::LoadOp::Clear(wgpu::Color {
  816. r: 0.1,
  817. g: 0.2,
  818. b: 0.3,
  819. a: 1.0,
  820. }),
  821. store: true,
  822. },
  823. }],
  824. depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
  825. attachment: &self.depth_texture.view,
  826. depth_ops: Some(wgpu::Operations {
  827. load: wgpu::LoadOp::Clear(1.0),
  828. store: true,
  829. }),
  830. stencil_ops: None,
  831. }),
  832. });
  833. render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
  834. //render_pass.set_pipeline(&self.light_render_pipeline);
  835. //render_pass.draw_light_model(
  836. // &self.obj_model,
  837. // &self.uniform_bind_group,
  838. // &self.light_bind_group,
  839. //);
  840. render_pass.set_pipeline(&self.render_pipeline);
  841. render_pass.draw_model_instanced(
  842. &self.obj_model,
  843. 0..self.instances.len() as u32,
  844. &self.uniform_bind_group,
  845. &self.light_bind_group,
  846. );
  847. let bind_group = if self.is_space_pressed {
  848. &self.cartoon_bind_group
  849. } else {
  850. &self.diffuse_bind_group
  851. };
  852. render_pass.set_pipeline(&self.ui_render_pipeline);
  853. render_pass.set_bind_group(0, bind_group, &[]);
  854. render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
  855. render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
  856. render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
  857. }
  858. let play_text = Text {
  859. position: (40.0, 40.0).into(),
  860. color: (1.0, 1.0, 1.0, 1.0).into(),
  861. text: String::from("Absolutely Proprietary"),
  862. size: 32.0,
  863. centered: false,
  864. ..Default::default()
  865. };
  866. draw_text(&play_text, &mut self.glyph_brush);
  867. self.glyph_brush
  868. .draw_queued(
  869. &self.device,
  870. &mut self.staging_belt,
  871. &mut encoder,
  872. &frame.view,
  873. self.sc_desc.width,
  874. self.sc_desc.height,
  875. )
  876. .unwrap();
  877. self.staging_belt.finish();
  878. self.queue.submit(iter::once(encoder.finish()));
  879. Ok(())
  880. }
  881. }
  882. fn draw_text(text: &Text, glyph_brush: &mut wgpu_glyph::GlyphBrush<()>) {
  883. let layout = wgpu_glyph::Layout::default().h_align(if text.centered {
  884. wgpu_glyph::HorizontalAlign::Center
  885. } else {
  886. wgpu_glyph::HorizontalAlign::Left
  887. });
  888. let section =
  889. wgpu_glyph::Section {
  890. screen_position: text.position.into(),
  891. bounds: text.bounds.into(),
  892. layout,
  893. ..Default::default()
  894. }
  895. .add_text(wgpu_glyph::Text::new(&text.text).with_color(text.color).with_scale(
  896. if text.focused {
  897. text.size + 8.0
  898. } else {
  899. text.size
  900. },
  901. ));
  902. glyph_brush.queue(section);
  903. }
  904. fn main() {
  905. env_logger::init();
  906. let event_loop = EventLoop::new();
  907. let title = env!("CARGO_PKG_NAME");
  908. let window = winit::window::WindowBuilder::new()
  909. .with_title(title)
  910. .build(&event_loop)
  911. .unwrap();
  912. use futures::executor::block_on;
  913. let mut state = block_on(State::new(&window));
  914. event_loop.run(move |event, _, control_flow| {
  915. *control_flow = ControlFlow::Poll;
  916. match event {
  917. Event::MainEventsCleared => window.request_redraw(),
  918. Event::WindowEvent {
  919. ref event,
  920. window_id,
  921. } if window_id == window.id() => {
  922. if !state.input(event) {
  923. match event {
  924. WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
  925. WindowEvent::KeyboardInput { input, .. } => match input {
  926. KeyboardInput {
  927. state: ElementState::Pressed,
  928. virtual_keycode: Some(VirtualKeyCode::Escape),
  929. ..
  930. } => {
  931. *control_flow = ControlFlow::Exit;
  932. }
  933. _ => {}
  934. },
  935. WindowEvent::Resized(physical_size) => {
  936. state.resize(*physical_size);
  937. }
  938. WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
  939. state.resize(**new_inner_size);
  940. }
  941. _ => {}
  942. }
  943. }
  944. }
  945. Event::RedrawRequested(_) => {
  946. state.update();
  947. match state.render() {
  948. Ok(_) => {}
  949. // Recreate the swap_chain if lost
  950. Err(wgpu::SwapChainError::Lost) => state.resize(state.size),
  951. // The system is out of memory, we should probably quit
  952. Err(wgpu::SwapChainError::OutOfMemory) => *control_flow = ControlFlow::Exit,
  953. // All other errors (Outdated, Timeout) should be resolved by the next frame
  954. Err(e) => eprintln!("{:?}", e),
  955. }
  956. }
  957. _ => {}
  958. }
  959. });
  960. }