From 6a3c5e658a9d4071b6e672d7d1adc992df7efa30 Mon Sep 17 00:00:00 2001 From: Colin Edwards Date: Sun, 15 Oct 2023 13:42:38 -0500 Subject: [PATCH] More render reorg --- Cargo.lock | 7 + cappy3ds/src/capture/katsukitty/mod.rs | 20 +- cappy3ds/src/capture/katsukitty/parse.rs | 25 ++ cappy3ds/src/capture/loopy_ds/mod.rs | 22 ++ cappy3ds/src/lib.rs | 7 +- cappy3ds_render/Cargo.toml | 1 + cappy3ds_render/resources/test/lower_wow.png | Bin 0 -> 124259 bytes cappy3ds_render/src/dsscreen.rs | 263 ++++++++++++++ cappy3ds_render/src/lib.rs | 29 +- cappy3ds_render/src/main.rs | 85 +++++ cappy3ds_render/src/primitive.rs | 28 ++ cappy3ds_render/src/render.rs | 357 ++----------------- 12 files changed, 481 insertions(+), 363 deletions(-) create mode 100644 cappy3ds/src/capture/loopy_ds/mod.rs create mode 100644 cappy3ds_render/resources/test/lower_wow.png create mode 100644 cappy3ds_render/src/dsscreen.rs create mode 100644 cappy3ds_render/src/main.rs create mode 100644 cappy3ds_render/src/primitive.rs diff --git a/Cargo.lock b/Cargo.lock index 294e354..4885102 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,6 +321,7 @@ dependencies = [ "cpal", "env_logger", "futures", + "glam", "image", "log", "raw-window-handle", @@ -862,6 +863,12 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "glam" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" + [[package]] name = "glob" version = "0.3.1" diff --git a/cappy3ds/src/capture/katsukitty/mod.rs b/cappy3ds/src/capture/katsukitty/mod.rs index 0f06651..92e514e 100644 --- a/cappy3ds/src/capture/katsukitty/mod.rs +++ b/cappy3ds/src/capture/katsukitty/mod.rs @@ -102,14 +102,14 @@ fn open_device( pub fn do_capture(handle: &mut DeviceHandle, data_callback: F) where - F: Fn(&[i16], BytesMut, BytesMut), + F: FnMut(&[i16], BytesMut, BytesMut), { bulk_read(handle, data_callback); } extern "system" fn transfer_finished(transfer_ptr: *mut usbffi::libusb_transfer) where - F: Fn(&[i16], BytesMut, BytesMut), + F: FnMut(&[i16], BytesMut, BytesMut), { let transfer: &mut usbffi::libusb_transfer = unsafe { &mut *transfer_ptr }; @@ -162,8 +162,8 @@ where let (_, short, _) = unsafe { sound_buffer.align_to::() }; (handler.data_callback)( short, - parse::rgb565_to_rgb(&upper_buffer), - parse::rgb565_to_rgb(&lower_buffer), + parse::rgb565_to_rgba(&upper_buffer), + parse::rgb565_to_rgba(&lower_buffer), ); handler.current_buffer += 1; @@ -209,7 +209,7 @@ const TRANSFER_SIZE: usize = 0x4000; impl CaptureHandler where - F: Fn(&[i16], BytesMut, BytesMut), + F: FnMut(&[i16], BytesMut, BytesMut), { fn new(data_callback: F) -> Self { let mut buffers = Vec::::with_capacity(NUM_BUFFERS); @@ -230,7 +230,7 @@ where fn bulk_read(handle: &mut DeviceHandle, data_callback: F) where - F: Fn(&[i16], BytesMut, BytesMut), + F: FnMut(&[i16], BytesMut, BytesMut), { println!("Starting Bulk Read"); @@ -289,10 +289,10 @@ where } loop { - let current_buffer = capture_handler.lock().unwrap().current_buffer; - if current_buffer >= NUM_BUFFERS - 10 { - //break; - } + //let current_buffer = capture_handler.lock().unwrap().current_buffer; + //if current_buffer >= NUM_BUFFERS - 10 { + //break; + //} //let ten_millis = time::Duration::from_millis(1); //thread::sleep(ten_millis); } diff --git a/cappy3ds/src/capture/katsukitty/parse.rs b/cappy3ds/src/capture/katsukitty/parse.rs index 0a02068..7267661 100644 --- a/cappy3ds/src/capture/katsukitty/parse.rs +++ b/cappy3ds/src/capture/katsukitty/parse.rs @@ -63,3 +63,28 @@ pub fn rgb565_to_rgb(data: &BytesMut) -> BytesMut { image_buffer } + +pub fn rgb565_to_rgba(data: &BytesMut) -> BytesMut { + let mut image_buffer = BytesMut::with_capacity(data.len() / 2 * 4); + image_buffer.resize(data.len() / 2 * 4, 0); + + let mut j = 0; + for i in (0..data.len()).step_by(2) { + let high = (data[i + 1] as u16) << 8; + let c: u16 = data[i] as u16 + high; + let r = (((c & 0xF800) >> 11) << 3) as u8; + let g = (((c & 0x7E0) >> 5) << 2) as u8; + let b = ((c & 0x1F) << 3) as u8; + + image_buffer[j] = r; + j += 1; + image_buffer[j] = g; + j += 1; + image_buffer[j] = b; + j += 1; + image_buffer[j] = 0; + j += 1; + } + + image_buffer +} diff --git a/cappy3ds/src/capture/loopy_ds/mod.rs b/cappy3ds/src/capture/loopy_ds/mod.rs new file mode 100644 index 0000000..36a21a4 --- /dev/null +++ b/cappy3ds/src/capture/loopy_ds/mod.rs @@ -0,0 +1,22 @@ +USBDS_VID = 0x16D0, +USBDS_PID = 0x0647, + + //device vendor requests: + CMDIN_STATUS = 0x31, + // Returns device status: + // struct { + // u32 framecount, //free running frame counter + // u8 lcd_on, + // u8 capture_in_progress, + // } + CMDIN_FRAMEINFO = 0x30, + // Returns record of last captured frame: + // struct { + // u8 bitmap[48], //bitmap of lines sent (1 bit per half-line) + // u32 frame, //frame number + // u8 valid, //0 if capture timed out (LCD is inactive) + // } + CMDOUT_CAPTURE_START = 0x30, + // capture new frame + CMDOUT_CAPTURE_STOP = 0x31, + // stop capture in progress and reset frame counter to 0 \ No newline at end of file diff --git a/cappy3ds/src/lib.rs b/cappy3ds/src/lib.rs index 9cdbbee..b7e4d94 100644 --- a/cappy3ds/src/lib.rs +++ b/cappy3ds/src/lib.rs @@ -11,12 +11,9 @@ pub struct Cappy3ds { impl Cappy3ds where - F: Fn(&[i16], BytesMut, BytesMut), + F: FnMut(&[i16], BytesMut, BytesMut), { - pub fn new(data_callback: F) -> Self - where - F: Fn(&[i16], BytesMut, BytesMut), - { + pub fn new(data_callback: F) -> Self { Self { data_callback, usb_context: None, diff --git a/cappy3ds_render/Cargo.toml b/cappy3ds_render/Cargo.toml index c9cefd7..44ac191 100644 --- a/cappy3ds_render/Cargo.toml +++ b/cappy3ds_render/Cargo.toml @@ -18,6 +18,7 @@ cappy3ds = { path = "../cappy3ds" } ringbuf = "0.3.3" simple-error = "0.3.0" bytes = "1.5.0" +glam = "0.24.2" [lib] name = "cappy3ds_render" diff --git a/cappy3ds_render/resources/test/lower_wow.png b/cappy3ds_render/resources/test/lower_wow.png new file mode 100644 index 0000000000000000000000000000000000000000..8387864465232d1ef2c3b8a1a57d0c21ac02a8fc GIT binary patch literal 124259 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 STCUPe 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 Self { + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + }); + + let num_vertices = VERTICES.len() as u32; + + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(INDICES), + usage: wgpu::BufferUsages::INDEX, + }); + + let num_indices = INDICES.len() as u32; + + let texture_size = wgpu::Extent3d { + width: 240, + height: 400, + depth_or_array_layers: 1, + }; + let diffuse_texture = device.create_texture(&wgpu::TextureDescriptor { + // All textures are stored as 3D, we represent our 2D texture + // by setting depth to 1. + size: texture_size, + mip_level_count: 1, // We'll talk about this a little later + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + // Most images are stored using sRGB so we need to reflect that here. + format: wgpu::TextureFormat::Rgba8UnormSrgb, + // TEXTURE_BINDING tells wgpu that we want to use this texture in shaders + // COPY_DST means that we want to copy data to this texture + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + label: Some("diffuse_texture"), + // This is the same as with the SurfaceConfig. It + // specifies what texture formats can be used to + // create TextureViews for this texture. The base + // texture format (Rgba8UnormSrgb in this case) is + // always supported. Note that using a different + // texture format is not supported on the WebGL2 + // backend. + view_formats: &[], + }); + + let diffuse_bytes = include_bytes!("../resources/test/upper_5.png"); + let diffuse_image = image::load_from_memory(diffuse_bytes).unwrap(); + let diffuse_rgba = diffuse_image.to_rgba8(); + + // use image::GenericImageView; + // let dimensions = diffuse_image.dimensions(); + + // We don't need to configure the texture view much, so let's + // let wgpu define it. + let diffuse_texture_view = + diffuse_texture.create_view(&wgpu::TextureViewDescriptor::default()); + let diffuse_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + + let texture_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + // This should match the filterable field of the + // corresponding Texture entry above. + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, + ], + label: Some("texture_bind_group_layout"), + }); + + let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &texture_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&diffuse_texture_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&diffuse_sampler), + }, + ], + label: Some("diffuse_bind_group"), + }); + + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("Shader"), + source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()), + }); + + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Render Pipeline Layout"), + bind_group_layouts: &[&texture_bind_group_layout], + push_constant_ranges: &[], + }); + + let render_pipeline = 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: &[Vertex::desc()], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format: texture_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), + polygon_mode: wgpu::PolygonMode::Fill, + unclipped_depth: false, + conservative: false, + }, + + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + + // todo: hardcoded lol + let mut buffer = BytesMut::with_capacity(384000); + buffer.extend_from_slice(&diffuse_rgba); + + DSScreen { + vertex_buffer, + index_buffer, + num_indices, + render_pipeline, + diffuse_bind_group, + diffuse_texture, + texture_update: true, + texture_size, + buffer, + } + } + + pub fn write_texture(&mut self, buffer: &BytesMut) { + self.buffer.clear(); + self.buffer.extend_from_slice(buffer); + self.texture_update = true; + } + + pub fn update_textures(&self, queue: &wgpu::Queue) { + if self.texture_update { + queue.write_texture( + // Tells wgpu where to copy the pixel data + wgpu::ImageCopyTexture { + texture: &self.diffuse_texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + // The actual pixel data + &self.buffer, + // The layout of the texture + wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4 * 240), + rows_per_image: Some(400), + }, + self.texture_size, + ); + } + } + + pub fn render(&self, encoder: &mut wgpu::CommandEncoder, render_target: &wgpu::TextureView) { + { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("ds screen"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: render_target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + + render_pass.draw_indexed(0..self.num_indices, 0, 0..1); + } + } +} diff --git a/cappy3ds_render/src/lib.rs b/cappy3ds_render/src/lib.rs index b66880a..67b04e8 100644 --- a/cappy3ds_render/src/lib.rs +++ b/cappy3ds_render/src/lib.rs @@ -6,6 +6,8 @@ use raw_window_handle::{ }; use std::ffi; +mod dsscreen; +mod primitive; mod render; use std::thread; @@ -19,7 +21,7 @@ pub extern "C" fn send_window(app_kit_nsview: *mut ffi::c_void) { }; let res = State::new(&window); - let mut v = executor::block_on(res); + let v = executor::block_on(res); v.render(); } @@ -32,7 +34,7 @@ pub fn send_raw_window< //capture::do_capture(); let res = State::new(&window); - let mut v = executor::block_on(res); + let v = executor::block_on(res); let mut heheh = Box::new(v); @@ -46,34 +48,11 @@ pub fn send_raw_window< fn trash_code(v: &mut State) { let mut cappy3ds = cappy3ds::Cappy3ds::new( |audio: &[i16], upper_buffer: BytesMut, lower_buffer: BytesMut| { - //print!("{:?}\n", upper_buffer.len()); - if upper_buffer.len() >= 288000 { v.write_texture(&upper_buffer); v.render(); - /*let found_frames = "wow"; - - // print lower image - let result = - ImageBuffer::, _>::from_raw(240, 320, lower_buffer); - if let Some(image) = result { - image.save(format!("./img_out/lower_{}.png", found_frames)); - } - - // print upper image - let result: Option, BytesMut>> = - ImageBuffer::, _>::from_raw(240, 400, upper_buffer); - if let Some(image) = result { - image.save(format!("./img_out/upper_{}.png", found_frames)); - } - - panic!("LOL");*/ } - - /*for sample in data { - //producer.push(0.0).unwrap(); - }*/ }, ); diff --git a/cappy3ds_render/src/main.rs b/cappy3ds_render/src/main.rs new file mode 100644 index 0000000..4759d9b --- /dev/null +++ b/cappy3ds_render/src/main.rs @@ -0,0 +1,85 @@ +use bytes::BytesMut; +use cappy3ds; +use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; +use image::{ImageBuffer, Rgb}; +use ringbuf::HeapRb; + +fn main() { + let host = cpal::default_host(); + let output_device = host.default_output_device().unwrap(); + + let config: cpal::StreamConfig = output_device.default_output_config().unwrap().into(); + + //config.sample_rate.0 = 32728; + let latency_frames = (150.0 / 1_000.0) * config.sample_rate.0 as f32; + let latency_samples = latency_frames as usize * config.channels as usize; + + let ring = HeapRb::::new(latency_samples * 2); + let (mut producer, mut consumer) = ring.split(); + + for _ in 0..latency_samples { + // The ring buffer has twice as much space as necessary to add latency here, + // so this should never fail + producer.push(0.0).unwrap(); + } + + let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { + let mut input_fell_behind = false; + for sample in data { + *sample = match consumer.pop() { + Some(s) => s, + None => { + input_fell_behind = true; + 0.0 + } + }; + } + if input_fell_behind { + //eprintln!("input stream fell behind: try increasing latency"); + } + }; + + let output_stream = output_device + .build_output_stream(&config, output_data_fn, err_fn, None) + .unwrap(); + println!("Successfully built streams."); + + let mut cappy3ds = cappy3ds::Cappy3ds::new( + |audio: &[i16], upper_buffer: BytesMut, lower_buffer: BytesMut| { + print!("{:?}\n", upper_buffer.len()); + + if upper_buffer.len() >= 288000 { + let found_frames = "wow"; + + // print lower image + let result = ImageBuffer::, _>::from_raw(240, 320, lower_buffer); + if let Some(image) = result { + image.save(format!("./img_out/lower_{}.png", found_frames)); + } + + // print upper image + let result: Option, BytesMut>> = + ImageBuffer::, _>::from_raw(240, 400, upper_buffer); + if let Some(image) = result { + image.save(format!("./img_out/upper_{}.png", found_frames)); + } + + panic!("LOL"); + } + + /*for sample in data { + //producer.push(0.0).unwrap(); + }*/ + }, + ); + + cappy3ds.connect(); + + //output_stream.play(); + + cappy3ds.do_capture(); +} + +fn err_fn(err: cpal::StreamError) { + //eprintln!("an error occurred on stream: {}", err); +} diff --git a/cappy3ds_render/src/primitive.rs b/cappy3ds_render/src/primitive.rs new file mode 100644 index 0000000..465ddbd --- /dev/null +++ b/cappy3ds_render/src/primitive.rs @@ -0,0 +1,28 @@ +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +pub struct Vertex { + pub position: [f32; 3], + pub tex_coords: [f32; 2], // NEW! +} + +impl Vertex { + pub fn desc() -> wgpu::VertexBufferLayout<'static> { + use std::mem; + wgpu::VertexBufferLayout { + array_stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float32x2, + }, + ], + } + } +} diff --git a/cappy3ds_render/src/render.rs b/cappy3ds_render/src/render.rs index cc85f66..4001a5c 100644 --- a/cappy3ds_render/src/render.rs +++ b/cappy3ds_render/src/render.rs @@ -1,28 +1,10 @@ use bytes::BytesMut; -use cappy3ds; -use image::{DynamicImage, ImageBuffer, Rgb, Rgba}; use wgpu::util::DeviceExt; -const VERTICES: &[Vertex] = &[ - Vertex { - position: [-1.0, -1.0, 0.0], - tex_coords: [0.0, 0.0], - }, - Vertex { - position: [1.0, -1.0, 0.0], - tex_coords: [0.0, 1.0], - }, - Vertex { - position: [-1.0, 1.0, 0.0], - tex_coords: [1.0, 0.0], - }, - Vertex { - position: [1.0, 1.0, 0.0], - tex_coords: [1.0, 1.0], - }, -]; +use crate::dsscreen::DSScreen; -const INDICES: &[u16] = &[0, 1, 2, 2, 1, 3]; +const SCENE_WIDTH: u32 = 1270; +const SCENE_HEIGHT: u32 = 720; pub struct State { surface: wgpu::Surface, @@ -34,43 +16,7 @@ pub struct State { // it gets dropped after it as the surface contains // unsafe references to the window's resources. //window: Window, - vertex_buffer: wgpu::Buffer, - num_vertices: u32, - index_buffer: wgpu::Buffer, - num_indices: u32, - render_pipeline: wgpu::RenderPipeline, - diffuse_bind_group: wgpu::BindGroup, - - diffuse_texture: wgpu::Texture, -} - -#[repr(C)] -#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] -struct Vertex { - position: [f32; 3], - tex_coords: [f32; 2], // NEW! -} - -impl Vertex { - fn desc() -> wgpu::VertexBufferLayout<'static> { - use std::mem; - wgpu::VertexBufferLayout { - array_stride: mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &[ - wgpu::VertexAttribute { - offset: 0, - shader_location: 0, - format: wgpu::VertexFormat::Float32x3, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, - shader_location: 1, - format: wgpu::VertexFormat::Float32x2, - }, - ], - } - } + ds_screen: DSScreen, } impl State { @@ -82,9 +28,6 @@ impl State { ) -> Self { // let size = window.inner_size(); - let width = 1280; - let height = 720; - // The instance is a handle to our GPU // Backends::all => Vulkan + Metal + DX12 + Browser WebGPU let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { @@ -129,256 +72,29 @@ impl State { .copied() .find(|f| f.is_srgb()) .unwrap_or(surface_caps.formats[0]); + let config = wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT, format: surface_format, - width: width, - height: height, + width: SCENE_WIDTH, + height: SCENE_HEIGHT, present_mode: surface_caps.present_modes[0], alpha_mode: surface_caps.alpha_modes[0], view_formats: vec![], }; surface.configure(&device, &config); - let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Vertex Buffer"), - contents: bytemuck::cast_slice(VERTICES), - usage: wgpu::BufferUsages::VERTEX, - }); - - let num_vertices = VERTICES.len() as u32; - - let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Index Buffer"), - contents: bytemuck::cast_slice(INDICES), - usage: wgpu::BufferUsages::INDEX, - }); - - let num_indices = INDICES.len() as u32; - - let diffuse_bytes = include_bytes!("../resources/test/upper_5.png"); - let diffuse_image = image::load_from_memory(diffuse_bytes).unwrap(); - let diffuse_rgba = diffuse_image.to_rgba8(); - - use image::GenericImageView; - let dimensions = diffuse_image.dimensions(); - - let texture_size = wgpu::Extent3d { - width: dimensions.0, - height: dimensions.1, - depth_or_array_layers: 1, - }; - let diffuse_texture = device.create_texture(&wgpu::TextureDescriptor { - // All textures are stored as 3D, we represent our 2D texture - // by setting depth to 1. - size: texture_size, - mip_level_count: 1, // We'll talk about this a little later - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - // Most images are stored using sRGB so we need to reflect that here. - format: wgpu::TextureFormat::Rgba8UnormSrgb, - // TEXTURE_BINDING tells wgpu that we want to use this texture in shaders - // COPY_DST means that we want to copy data to this texture - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - label: Some("diffuse_texture"), - // This is the same as with the SurfaceConfig. It - // specifies what texture formats can be used to - // create TextureViews for this texture. The base - // texture format (Rgba8UnormSrgb in this case) is - // always supported. Note that using a different - // texture format is not supported on the WebGL2 - // backend. - view_formats: &[], - }); - - queue.write_texture( - // Tells wgpu where to copy the pixel data - wgpu::ImageCopyTexture { - texture: &diffuse_texture, - mip_level: 0, - origin: wgpu::Origin3d::ZERO, - aspect: wgpu::TextureAspect::All, - }, - // The actual pixel data - &diffuse_rgba, - // The layout of the texture - wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(4 * dimensions.0), - rows_per_image: Some(dimensions.1), - }, - texture_size, - ); - - // We don't need to configure the texture view much, so let's - // let wgpu define it. - let diffuse_texture_view = - diffuse_texture.create_view(&wgpu::TextureViewDescriptor::default()); - let diffuse_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Nearest, - mipmap_filter: wgpu::FilterMode::Nearest, - ..Default::default() - }); - - let texture_bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - entries: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - multisampled: false, - view_dimension: wgpu::TextureViewDimension::D2, - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - }, - count: None, - }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStages::FRAGMENT, - // This should match the filterable field of the - // corresponding Texture entry above. - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), - count: None, - }, - ], - label: Some("texture_bind_group_layout"), - }); - - let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &texture_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&diffuse_texture_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&diffuse_sampler), - }, - ], - label: Some("diffuse_bind_group"), - }); - - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some("Shader"), - source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()), - }); - - let render_pipeline_layout = - device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout], - push_constant_ranges: &[], - }); - - let render_pipeline = 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: &[Vertex::desc()], - }, - fragment: Some(wgpu::FragmentState { - // 3. - module: &shader, - entry_point: "fs_main", - targets: &[Some(wgpu::ColorTargetState { - // 4. - format: config.format, - blend: Some(wgpu::BlendState::REPLACE), - write_mask: wgpu::ColorWrites::ALL, - })], - }), - - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, // 1. - strip_index_format: None, - front_face: wgpu::FrontFace::Ccw, // 2. - cull_mode: Some(wgpu::Face::Back), - // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE - polygon_mode: wgpu::PolygonMode::Fill, - // Requires Features::DEPTH_CLIP_CONTROL - unclipped_depth: false, - // Requires Features::CONSERVATIVE_RASTERIZATION - conservative: false, - }, - - depth_stencil: None, // 1. - multisample: wgpu::MultisampleState { - count: 1, // 2. - mask: !0, // 3. - alpha_to_coverage_enabled: false, // 4. - }, - multiview: None, // 5. - }); + let ds_screen = DSScreen::new(&device, surface_format); + ds_screen.update_textures(&queue); Self { - //window, surface, device, queue, - // config, - // size, - render_pipeline, - vertex_buffer, - num_vertices, - index_buffer, - num_indices, - diffuse_bind_group, - diffuse_texture, + ds_screen, } } - /*pub fn window(&self) -> &Window { - &self.window - }*/ - - fn update(&mut self) { - todo!() - } - - pub fn write_texture(&self, buffer: &BytesMut) { - let output_data = buffer - .chunks_exact(3) - .flat_map(|s| [s[0], s[1], s[2], 11]) - .collect(); - - let result = ImageBuffer::, _>::from_raw(240, 400, output_data); - - let diffuse_rgba = DynamicImage::ImageRgba8(result.unwrap()).to_rgba8(); - - let texture_size = wgpu::Extent3d { - width: 240, - height: 400, - depth_or_array_layers: 1, - }; - - self.queue.write_texture( - // Tells wgpu where to copy the pixel data - wgpu::ImageCopyTexture { - texture: &self.diffuse_texture, - mip_level: 0, - origin: wgpu::Origin3d::ZERO, - aspect: wgpu::TextureAspect::All, - }, - // The actual pixel data - &diffuse_rgba, - // The layout of the texture - wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(4 * 240), - rows_per_image: Some(400), - }, - texture_size, - ); - } - pub fn render(&self) -> Result<(), wgpu::SurfaceError> { let output = self.surface.get_current_texture()?; @@ -393,45 +109,40 @@ impl State { }); { - // 1. let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), - color_attachments: &[ - // This is what @location(0) in the fragment shader targets - Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color { - r: 0.1, - g: 0.2, - b: 0.3, - a: 1.0, - }), - store: true, - }, - }), - ], + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: 0.1, + g: 0.2, + b: 0.3, + a: 1.0, + }), + store: true, + }, + })], depth_stencil_attachment: None, }); - - /*render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - render_pass.draw_indexed(0..self.num_indices, 0, 0..1);*/ - - render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); - render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - - render_pass.draw_indexed(0..self.num_indices, 0, 0..1); } + self.ds_screen.render(&mut encoder, &view); + // submit will accept anything that implements IntoIter self.queue.submit(std::iter::once(encoder.finish())); output.present(); Ok(()) } + + pub fn write_texture(&mut self, buffer: &BytesMut) { + self.ds_screen.write_texture(buffer); + self.ds_screen.update_textures(&self.queue); + } +} + +fn generate_projection_matrix() { + glam::Mat4::orthographic_rh(0.0, SCENE_WIDTH as f32, SCENE_HEIGHT as f32, 0.0, -2.0, 2.0); }