dfg.rs 32 KB

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