Replace everything with a basic Bevy setup
This commit is contained in:
		
							parent
							
								
									1e98a40a72
								
							
						
					
					
						commit
						c0fe39f56a
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								Cargo.toml
								
								
								
								
							
							
						
						
									
										10
									
								
								Cargo.toml
								
								
								
								
							|  | @ -6,9 +6,7 @@ edition = "2021" | |||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||
| 
 | ||||
| [dependencies] | ||||
| bytemuck = { version = "1.14.0", features = ["derive"] } | ||||
| env_logger = "0.10.0" | ||||
| log = "0.4.20" | ||||
| pollster = "0.3.0" | ||||
| wgpu = "0.17.1" | ||||
| winit = "0.28.7" | ||||
| bevy = "0.12.1" | ||||
| 
 | ||||
| [profile.dev.package."*"] | ||||
| opt-level = 3 | ||||
							
								
								
									
										13
									
								
								src/gfx.rs
								
								
								
								
							
							
						
						
									
										13
									
								
								src/gfx.rs
								
								
								
								
							|  | @ -1,13 +0,0 @@ | |||
| mod bind_group; | ||||
| mod buffer; | ||||
| mod context; | ||||
| mod renderer; | ||||
| mod texture; | ||||
| 
 | ||||
| pub use self::{ | ||||
|     bind_group::{BindGroupBuilder, BindGroupLayoutBuilder}, | ||||
|     buffer::BulkBufferBuilder, | ||||
|     context::Context, | ||||
|     renderer::Renderer, | ||||
|     texture::{Texture, TextureBuilder}, | ||||
| }; | ||||
|  | @ -1,135 +0,0 @@ | |||
| use std::num::NonZeroU32; | ||||
| 
 | ||||
| use super::Context; | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct BindGroupLayoutBuilder<'a> { | ||||
|     next_binding: u32, | ||||
|     entries: Vec<wgpu::BindGroupLayoutEntry>, | ||||
|     label: Option<&'a str>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> BindGroupLayoutBuilder<'a> { | ||||
|     pub fn new() -> Self { | ||||
|         Self::default() | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_label(mut self, label: &'a str) -> Self { | ||||
|         self.label = Some(label); | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_entry( | ||||
|         mut self, | ||||
|         visibility: wgpu::ShaderStages, | ||||
|         ty: wgpu::BindingType, | ||||
|         count: Option<NonZeroU32>, | ||||
|     ) -> Self { | ||||
|         self.entries.push(wgpu::BindGroupLayoutEntry { | ||||
|             binding: self.next_binding, | ||||
|             visibility, | ||||
|             ty, | ||||
|             count, | ||||
|         }); | ||||
|         self.next_binding += 1; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_uniform_entry(self, visibility: wgpu::ShaderStages) -> Self { | ||||
|         self.with_entry( | ||||
|             visibility, | ||||
|             wgpu::BindingType::Buffer { | ||||
|                 ty: wgpu::BufferBindingType::Uniform, | ||||
|                 has_dynamic_offset: false, | ||||
|                 min_binding_size: None, | ||||
|             }, | ||||
|             None, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_rw_storage_entry(self, visibility: wgpu::ShaderStages) -> Self { | ||||
|         self.with_entry( | ||||
|             visibility, | ||||
|             wgpu::BindingType::Buffer { | ||||
|                 ty: wgpu::BufferBindingType::Storage { read_only: false }, | ||||
|                 has_dynamic_offset: false, | ||||
|                 min_binding_size: None, | ||||
|             }, | ||||
|             None, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_ro_storage_entry(self, visibility: wgpu::ShaderStages) -> Self { | ||||
|         self.with_entry( | ||||
|             visibility, | ||||
|             wgpu::BindingType::Buffer { | ||||
|                 ty: wgpu::BufferBindingType::Storage { read_only: true }, | ||||
|                 has_dynamic_offset: false, | ||||
|                 min_binding_size: None, | ||||
|             }, | ||||
|             None, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn build(self, context: &Context) -> wgpu::BindGroupLayout { | ||||
|         context | ||||
|             .device | ||||
|             .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { | ||||
|                 label: self.label, | ||||
|                 entries: &self.entries, | ||||
|             }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct BindGroupBuilder<'a> { | ||||
|     next_binding: u32, | ||||
|     label: Option<&'a str>, | ||||
|     entries: Vec<wgpu::BindGroupEntry<'a>>, | ||||
|     layout: Option<&'a wgpu::BindGroupLayout>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> BindGroupBuilder<'a> { | ||||
|     pub fn new() -> Self { | ||||
|         Self::default() | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_label(mut self, label: &'a str) -> Self { | ||||
|         self.label = Some(label); | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_entry(mut self, resource: wgpu::BindingResource<'a>) -> Self { | ||||
|         self.entries.push(wgpu::BindGroupEntry { | ||||
|             binding: self.next_binding, | ||||
|             resource, | ||||
|         }); | ||||
|         self.next_binding += 1; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_layout(mut self, layout: &'a wgpu::BindGroupLayout) -> Self { | ||||
|         self.layout = Some(layout); | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn build(self, context: &Context) -> wgpu::BindGroup { | ||||
|         context | ||||
|             .device | ||||
|             .create_bind_group(&wgpu::BindGroupDescriptor { | ||||
|                 label: self.label, | ||||
|                 layout: self.layout.unwrap(), | ||||
|                 entries: self.entries.as_slice(), | ||||
|             }) | ||||
|     } | ||||
| } | ||||
|  | @ -1,73 +0,0 @@ | |||
| use bytemuck::NoUninit; | ||||
| use wgpu::util::DeviceExt; | ||||
| 
 | ||||
| use super::Context; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct BulkBufferBuilder<'a> { | ||||
|     order: Vec<(bool, usize)>, | ||||
|     init_descriptors: Vec<wgpu::util::BufferInitDescriptor<'a>>, | ||||
|     descriptors: Vec<wgpu::BufferDescriptor<'a>>, | ||||
|     current_usage: wgpu::BufferUsages, | ||||
| } | ||||
| 
 | ||||
| impl<'a> BulkBufferBuilder<'a> { | ||||
|     pub fn new() -> Self { | ||||
|         Self { | ||||
|             order: vec![], | ||||
|             init_descriptors: vec![], | ||||
|             descriptors: vec![], | ||||
|             current_usage: wgpu::BufferUsages::UNIFORM, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_usage(mut self, usage: wgpu::BufferUsages) -> Self { | ||||
|         self.current_usage = usage; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_buffer(mut self, label: &'a str, size: u64, mapped: bool) -> Self { | ||||
|         let descriptor = wgpu::BufferDescriptor { | ||||
|             label: Some(label), | ||||
|             size, | ||||
|             usage: self.current_usage, | ||||
|             mapped_at_creation: mapped, | ||||
|         }; | ||||
| 
 | ||||
|         self.order.push((false, self.descriptors.len())); | ||||
|         self.descriptors.push(descriptor); | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_init_buffer(mut self, label: &'a str, contents: &'a [u8]) -> Self { | ||||
|         let descriptor = wgpu::util::BufferInitDescriptor { | ||||
|             label: Some(label), | ||||
|             contents, | ||||
|             usage: self.current_usage, | ||||
|         }; | ||||
| 
 | ||||
|         self.order.push((true, self.init_descriptors.len())); | ||||
|         self.init_descriptors.push(descriptor); | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     pub fn with_init_buffer_bm<A: NoUninit>(self, label: &'a str, contents: &'a [A]) -> Self { | ||||
|         self.with_init_buffer(label, bytemuck::cast_slice(contents)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn build(self, context: &Context) -> Vec<wgpu::Buffer> { | ||||
|         let device = &context.device; | ||||
|         let mut buffers = vec![]; | ||||
|         for (init, index) in self.order { | ||||
|             let buffer = if init { | ||||
|                 device.create_buffer_init(&(self.init_descriptors[index])) | ||||
|             } else { | ||||
|                 device.create_buffer(&(self.descriptors[index])) | ||||
|             }; | ||||
| 
 | ||||
|             buffers.push(buffer); | ||||
|         } | ||||
| 
 | ||||
|         buffers | ||||
|     } | ||||
| } | ||||
|  | @ -1,80 +0,0 @@ | |||
| use winit::{dpi::PhysicalSize, window::Window}; | ||||
| 
 | ||||
| pub struct Context { | ||||
|     pub window: Window, | ||||
|     pub instance: wgpu::Instance, | ||||
|     pub size: PhysicalSize<u32>, | ||||
|     pub surface: wgpu::Surface, | ||||
|     pub surface_config: wgpu::SurfaceConfiguration, | ||||
|     pub adapter: wgpu::Adapter, | ||||
|     pub device: wgpu::Device, | ||||
|     pub queue: wgpu::Queue, | ||||
| } | ||||
| 
 | ||||
| impl Context { | ||||
|     pub async fn new(window: Window, limits: wgpu::Limits) -> Self { | ||||
|         log::info!("Initialising WGPU context..."); | ||||
|         let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { | ||||
|             backends: wgpu::Backends::VULKAN, | ||||
|             dx12_shader_compiler: Default::default(), | ||||
|         }); | ||||
| 
 | ||||
|         // To be able to start drawing we need a few things:
 | ||||
|         // - A surface
 | ||||
|         // - A GPU device to draw to the surface
 | ||||
|         // - A draw command queue
 | ||||
|         log::info!("Initialising window surface..."); | ||||
|         let surface = unsafe { instance.create_surface(&window) }.unwrap(); | ||||
| 
 | ||||
|         log::info!("Requesting GPU adapter..."); | ||||
|         let adapter = instance | ||||
|             .request_adapter(&wgpu::RequestAdapterOptions { | ||||
|                 power_preference: wgpu::PowerPreference::HighPerformance, | ||||
|                 force_fallback_adapter: false, | ||||
|                 compatible_surface: Some(&surface), | ||||
|             }) | ||||
|             .await | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         log::info!("Checking GPU adapter meets requirements"); | ||||
|         log::info!("Requesting GPU device..."); | ||||
|         let (device, queue) = adapter | ||||
|             .request_device( | ||||
|                 &wgpu::DeviceDescriptor { | ||||
|                     label: None, | ||||
|                     features: wgpu::Features::empty(), | ||||
|                     limits, | ||||
|                 }, | ||||
|                 None, | ||||
|             ) | ||||
|             .await | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         log::info!("Configuring window surface..."); | ||||
|         let size = window.inner_size(); | ||||
|         let surface_config = surface | ||||
|             .get_default_config(&adapter, size.width, size.height) | ||||
|             .unwrap(); | ||||
|         surface.configure(&device, &surface_config); | ||||
| 
 | ||||
|         Self { | ||||
|             window, | ||||
|             instance, | ||||
|             size, | ||||
|             surface, | ||||
|             surface_config, | ||||
|             adapter, | ||||
|             device, | ||||
|             queue, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn resize(&mut self, new_size: PhysicalSize<u32>) { | ||||
|         if new_size.width > 0 && new_size.height > 0 { | ||||
|             self.size = new_size; | ||||
|             self.surface_config.width = new_size.width; | ||||
|             self.surface_config.height = new_size.height; | ||||
|             self.surface.configure(&self.device, &self.surface_config); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +0,0 @@ | |||
| use std::time::Duration; | ||||
| 
 | ||||
| pub trait Renderer { | ||||
|     fn update(&mut self, dt: &Duration, context: &super::Context); | ||||
|     fn render(&self, context: &super::Context); | ||||
| } | ||||
|  | @ -1,198 +0,0 @@ | |||
| // TODO: Support mip-mapping and multi-sampling
 | ||||
| 
 | ||||
| use super::{BindGroupBuilder, BindGroupLayoutBuilder, Context}; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct TextureAttributes { | ||||
|     pub size: wgpu::Extent3d, | ||||
|     pub dimension: wgpu::TextureDimension, | ||||
|     pub format: wgpu::TextureFormat, | ||||
|     pub usage: wgpu::TextureUsages, | ||||
|     pub address_mode_u: wgpu::AddressMode, | ||||
|     pub address_mode_v: wgpu::AddressMode, | ||||
|     pub address_mode_w: wgpu::AddressMode, | ||||
|     pub mag_filter: wgpu::FilterMode, | ||||
|     pub min_filter: wgpu::FilterMode, | ||||
|     pub mipmap_filter: wgpu::FilterMode, | ||||
|     pub shader_visibility: wgpu::ShaderStages, | ||||
| } | ||||
| 
 | ||||
| impl Default for TextureAttributes { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             size: Default::default(), | ||||
|             dimension: wgpu::TextureDimension::D2, | ||||
|             format: wgpu::TextureFormat::Rgba8UnormSrgb, | ||||
|             usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, | ||||
|             address_mode_u: wgpu::AddressMode::default(), | ||||
|             address_mode_v: wgpu::AddressMode::default(), | ||||
|             address_mode_w: wgpu::AddressMode::default(), | ||||
|             mag_filter: wgpu::FilterMode::default(), | ||||
|             min_filter: wgpu::FilterMode::default(), | ||||
|             mipmap_filter: wgpu::FilterMode::default(), | ||||
|             shader_visibility: wgpu::ShaderStages::FRAGMENT, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct TextureBuilder { | ||||
|     pub attributes: TextureAttributes, | ||||
| } | ||||
| 
 | ||||
| impl TextureBuilder { | ||||
|     pub fn new() -> Self { | ||||
|         Self { | ||||
|             attributes: Default::default(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_size(mut self, width: u32, height: u32, depth: u32) -> Self { | ||||
|         self.attributes.size = wgpu::Extent3d { | ||||
|             width, | ||||
|             height, | ||||
|             depth_or_array_layers: depth, | ||||
|         }; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_dimension(mut self, dimension: wgpu::TextureDimension) -> Self { | ||||
|         self.attributes.dimension = dimension; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_format(mut self, format: wgpu::TextureFormat) -> Self { | ||||
|         self.attributes.format = format; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_usage(mut self, usage: wgpu::TextureUsages) -> Self { | ||||
|         self.attributes.usage = usage; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_address_mode(mut self, address_mode: wgpu::AddressMode) -> Self { | ||||
|         self.attributes.address_mode_u = address_mode; | ||||
|         self.attributes.address_mode_v = address_mode; | ||||
|         self.attributes.address_mode_w = address_mode; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_filter_mode(mut self, filter_mode: wgpu::FilterMode) -> Self { | ||||
|         self.attributes.mag_filter = filter_mode; | ||||
|         self.attributes.min_filter = filter_mode; | ||||
|         self.attributes.mipmap_filter = filter_mode; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn with_shader_visibility(mut self, visibility: wgpu::ShaderStages) -> Self { | ||||
|         self.attributes.shader_visibility = visibility; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     #[inline] | ||||
|     pub fn build(self, context: &Context) -> Texture { | ||||
|         Texture::new(context, self.attributes) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Texture { | ||||
|     pub attributes: TextureAttributes, | ||||
|     pub texture: wgpu::Texture, | ||||
|     pub view: wgpu::TextureView, | ||||
|     pub sampler: wgpu::Sampler, | ||||
|     pub bind_group_layout: wgpu::BindGroupLayout, | ||||
|     pub bind_group: wgpu::BindGroup, | ||||
| } | ||||
| 
 | ||||
| impl Texture { | ||||
|     pub fn new(context: &Context, attributes: TextureAttributes) -> Self { | ||||
|         let texture = context.device.create_texture(&wgpu::TextureDescriptor { | ||||
|             label: None, | ||||
|             size: attributes.size, | ||||
|             mip_level_count: 1, | ||||
|             sample_count: 1, | ||||
|             dimension: attributes.dimension, | ||||
|             format: attributes.format, | ||||
|             usage: attributes.usage, | ||||
|             view_formats: &[], | ||||
|         }); | ||||
| 
 | ||||
|         let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); | ||||
|         let sampler = context.device.create_sampler(&wgpu::SamplerDescriptor { | ||||
|             address_mode_u: attributes.address_mode_u, | ||||
|             address_mode_v: attributes.address_mode_v, | ||||
|             address_mode_w: attributes.address_mode_w, | ||||
|             mag_filter: attributes.mag_filter, | ||||
|             min_filter: attributes.min_filter, | ||||
|             mipmap_filter: attributes.mipmap_filter, | ||||
|             ..Default::default() | ||||
|         }); | ||||
| 
 | ||||
|         let view_dimension = match attributes.dimension { | ||||
|             wgpu::TextureDimension::D1 => wgpu::TextureViewDimension::D1, | ||||
|             wgpu::TextureDimension::D2 => wgpu::TextureViewDimension::D2, | ||||
|             wgpu::TextureDimension::D3 => wgpu::TextureViewDimension::D3, | ||||
|         }; | ||||
| 
 | ||||
|         let bind_group_layout = BindGroupLayoutBuilder::new() | ||||
|             .with_entry( | ||||
|                 attributes.shader_visibility, | ||||
|                 wgpu::BindingType::Texture { | ||||
|                     sample_type: wgpu::TextureSampleType::Float { filterable: true }, | ||||
|                     view_dimension, | ||||
|                     multisampled: false, | ||||
|                 }, | ||||
|                 None, | ||||
|             ) | ||||
|             .with_entry( | ||||
|                 attributes.shader_visibility, | ||||
|                 wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), | ||||
|                 None, | ||||
|             ) | ||||
|             .build(context); | ||||
|         let bind_group = BindGroupBuilder::new() | ||||
|             .with_layout(&bind_group_layout) | ||||
|             .with_entry(wgpu::BindingResource::TextureView(&view)) | ||||
|             .with_entry(wgpu::BindingResource::Sampler(&sampler)) | ||||
|             .build(context); | ||||
| 
 | ||||
|         Self { | ||||
|             attributes, | ||||
|             texture, | ||||
|             view, | ||||
|             sampler, | ||||
|             bind_group_layout, | ||||
|             bind_group, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn update(&self, context: &Context, data: &[u8]) { | ||||
|         log::info!("Updating texture contents..."); | ||||
|         let copy_texture = wgpu::ImageCopyTexture { | ||||
|             texture: &self.texture, | ||||
|             mip_level: 0, | ||||
|             origin: wgpu::Origin3d::ZERO, | ||||
|             aspect: wgpu::TextureAspect::All, | ||||
|         }; | ||||
| 
 | ||||
|         let size = self.attributes.size; | ||||
|         let image_layout = wgpu::ImageDataLayout { | ||||
|             offset: 0, | ||||
|             bytes_per_row: Some(4 * size.width), | ||||
|             rows_per_image: Some(size.height), | ||||
|         }; | ||||
| 
 | ||||
|         context | ||||
|             .queue | ||||
|             .write_texture(copy_texture, data, image_layout, size); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										138
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										138
									
								
								src/main.rs
								
								
								
								
							|  | @ -1,139 +1,5 @@ | |||
| mod gfx; | ||||
| 
 | ||||
| use winit::{ | ||||
|     dpi::PhysicalSize, | ||||
|     event::*, | ||||
|     event_loop::{ControlFlow, EventLoop}, | ||||
|     window::WindowBuilder, | ||||
| }; | ||||
| 
 | ||||
| pub async fn run() { | ||||
|     let event_loop = EventLoop::new(); | ||||
|     let window = WindowBuilder::new() | ||||
|         .with_title("Haranae") | ||||
|         .with_inner_size(PhysicalSize::new(1280, 720)) | ||||
|         .build(&event_loop) | ||||
|         .unwrap(); | ||||
| 
 | ||||
|     let mut render_ctx = gfx::Context::new(window, wgpu::Limits::default()).await; | ||||
| 
 | ||||
|     let shader = render_ctx | ||||
|         .device | ||||
|         .create_shader_module(wgpu::include_wgsl!("../res/shaders/main.wgsl")); | ||||
|     let render_pipeline_layout = | ||||
|         render_ctx | ||||
|             .device | ||||
|             .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { | ||||
|                 label: Some("RP Layout"), | ||||
|                 bind_group_layouts: &[], | ||||
|                 push_constant_ranges: &[], | ||||
|             }); | ||||
|     let render_pipeline = | ||||
|         render_ctx | ||||
|             .device | ||||
|             .create_render_pipeline(&wgpu::RenderPipelineDescriptor { | ||||
|                 label: Some("Render Pipeline"), | ||||
|                 layout: Some(&render_pipeline_layout), | ||||
|                 vertex: wgpu::VertexState { | ||||
|                     module: &shader, | ||||
|                     entry_point: "vs_main", | ||||
|                     buffers: &[], | ||||
|                 }, | ||||
|                 fragment: Some(wgpu::FragmentState { | ||||
|                     module: &shader, | ||||
|                     entry_point: "fs_main", | ||||
|                     targets: &[Some(wgpu::ColorTargetState { | ||||
|                         format: render_ctx.surface_config.format, | ||||
|                         blend: Some(wgpu::BlendState::REPLACE), | ||||
|                         write_mask: wgpu::ColorWrites::ALL, | ||||
|                     })], | ||||
|                 }), | ||||
|                 primitive: wgpu::PrimitiveState { | ||||
|                     topology: wgpu::PrimitiveTopology::TriangleList, | ||||
|                     strip_index_format: None, | ||||
|                     front_face: wgpu::FrontFace::Ccw, | ||||
|                     cull_mode: Some(wgpu::Face::Back), | ||||
|                     unclipped_depth: false, | ||||
|                     polygon_mode: wgpu::PolygonMode::Fill, | ||||
|                     conservative: false, | ||||
|                 }, | ||||
|                 depth_stencil: None, | ||||
|                 multisample: wgpu::MultisampleState { | ||||
|                     count: 1, | ||||
|                     mask: !0, | ||||
|                     alpha_to_coverage_enabled: false, | ||||
|                 }, | ||||
|                 multiview: None, | ||||
|             }); | ||||
| 
 | ||||
|     event_loop.run(move |event, _, control_flow| match event { | ||||
|         Event::WindowEvent { | ||||
|             ref event, | ||||
|             window_id, | ||||
|         } if window_id == render_ctx.window.id() => match event { | ||||
|             WindowEvent::CloseRequested | ||||
|             | WindowEvent::KeyboardInput { | ||||
|                 input: | ||||
|                     KeyboardInput { | ||||
|                         state: ElementState::Pressed, | ||||
|                         virtual_keycode: Some(VirtualKeyCode::Escape), | ||||
|                         .. | ||||
|                     }, | ||||
|                 .. | ||||
|             } => *control_flow = ControlFlow::Exit, | ||||
|             WindowEvent::Resized(physical_size) => { | ||||
|                 render_ctx.resize(*physical_size); | ||||
|             } | ||||
|             WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { | ||||
|                 render_ctx.resize(**new_inner_size); | ||||
|             } | ||||
|             _ => {} | ||||
|         }, | ||||
|         Event::RedrawRequested(window_id) if window_id == render_ctx.window.id() => { | ||||
|             let output = match render_ctx.surface.get_current_texture() { | ||||
|                 Ok(it) => it, | ||||
|                 Err(err) => return log::error!("{err}"), | ||||
|             }; | ||||
| 
 | ||||
|             let view = output | ||||
|                 .texture | ||||
|                 .create_view(&wgpu::TextureViewDescriptor::default()); | ||||
| 
 | ||||
|             let mut encoder = | ||||
|                 render_ctx | ||||
|                     .device | ||||
|                     .create_command_encoder(&wgpu::CommandEncoderDescriptor { | ||||
|                         label: Some("Render encoder"), | ||||
|                     }); | ||||
| 
 | ||||
|             let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | ||||
|                 label: Some("Render Pass"), | ||||
|                 color_attachments: &[Some(wgpu::RenderPassColorAttachment { | ||||
|                     view: &view, | ||||
|                     resolve_target: None, | ||||
|                     ops: wgpu::Operations { | ||||
|                         load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), | ||||
|                         store: true, | ||||
|                     }, | ||||
|                 })], | ||||
|                 depth_stencil_attachment: None, | ||||
|             }); | ||||
|             render_pass.set_pipeline(&render_pipeline); | ||||
|             render_pass.draw(0..3, 0..1); | ||||
| 
 | ||||
|             drop(render_pass); | ||||
| 
 | ||||
|             render_ctx.queue.submit(std::iter::once(encoder.finish())); | ||||
|             output.present(); | ||||
|         } | ||||
|         Event::MainEventsCleared => { | ||||
|             render_ctx.window.request_redraw(); | ||||
|         } | ||||
|         _ => {} | ||||
|     }); | ||||
| } | ||||
| use bevy::prelude::*; | ||||
| 
 | ||||
| fn main() { | ||||
|     env_logger::init(); | ||||
|     pollster::block_on(run()); | ||||
|     App::new().add_plugins(DefaultPlugins).run(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue