From 97922d3616c8457f48106076d8c029a0e294f2e1 Mon Sep 17 00:00:00 2001 From: Krishna Ayyalasomayajula Date: Sun, 31 May 2026 20:31:08 -0500 Subject: [PATCH] fix: resolve compile errors in rainbow_triangle.rs --- src/rainbow_traingle.rs | 190 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/rainbow_traingle.rs diff --git a/src/rainbow_traingle.rs b/src/rainbow_traingle.rs new file mode 100644 index 0000000..775fb62 --- /dev/null +++ b/src/rainbow_traingle.rs @@ -0,0 +1,190 @@ +use std::sync::Arc; +use winit::{application::ApplicationHandler, dpi::LogicalSize, window::Window}; + +struct App { + window: Option>, + frame_state: Option, + handle: tokio::runtime::Handle, +} +struct FrameState { + surface: wgpu::Surface<'static>, + device: wgpu::Device, + queue: wgpu::Queue, + config: wgpu::SurfaceConfiguration, + window: Arc, + pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, +} + +impl ApplicationHandler for App { + fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + let window: Arc = Arc::new( + event_loop + .create_window( + Window::default_attributes().with_inner_size(LogicalSize::new(800.0, 800.0)), + ) + .unwrap(), + ); + self.window = Some(window.clone()); + + self.frame_state = Some( + self.handle + .block_on(async { + FrameState::new(window.clone()) + }) + .expect("failed to create wgpu state"), + ); + } +} + +#[repr(C)] +#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] +struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +const VERTICES: &[Vertex] = &[ + Vertex { + position: [-0.5, -0.5, 0.0], + color: [1.0, 0.0, 0.0], + }, // red + Vertex { + position: [0.5, -0.5, 0.0], + color: [0.0, 0.0, 1.0], + }, // blue + Vertex { + position: [0.0, 0.5, 0.0], + color: [0.0, 1.0, 0.0], + }, // green +]; + +impl FrameState { + async fn new(window: Arc) -> Result { + // Step 1: Instance — connection to the graphics driver + let instance = wgpu::Instance::default(); + + // Step 2: Surface — binds our window to the GPU's swapchain + let surface = instance + .create_surface(window) + .map_err(|e| format!("Failed to create surface: {:?}", e))?; + + // Step 3: Adapter — selects the physical GPU + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + force_fallback_adapter: false, + compatible_surface: None, + }) + .await + .ok_or("No GPU adapter found. Ensure Vulkan drivers are installed.")?; + + // Step 4: Device + Queue — resource owner + command submission + let (device, queue) = adapter + .request_device(&wgpu::DeviceDescriptor::default(), None) + .await + .map_err(|e| format!("Failed to request device: {:?}", e))?; + + // Step 5: SurfaceConfiguration — allocates swapchain framebuffers + let size = window.inner_size(); + let surface_caps = surface.get_capabilities(&adapter); + let format = surface_caps + .formats + .iter() + .find(|f| f.is_srgb()) + .copied() + .unwrap_or(surface_caps.formats[0]); + + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + format, + width: size.width.max(1), + height: size.height.max(1), + present_mode: wgpu::PresentMode::Mailbox, + desired_maximum_frame_latency: 2, + alpha_mode: surface_caps.alpha_modes[0], + view_formats: vec![format.add_srgb_suffix()], + }; + surface.configure(&device, &config); + + // Step 6: Compile the shader module + let shader_module = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("Rainbow Triangle Shader"), + source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()), + }); + + // Step 7: Upload vertex data to GPU memory + use wgpu::util::DeviceExt; + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + }); + + // Step 8: Create the render pipeline + let vertex_buffer_layout = wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + format: wgpu::VertexFormat::Float32x3, + shader_location: 0, + }, + wgpu::VertexAttribute { + offset: std::mem::size_of::<[f32; 3]>() as u64, + format: wgpu::VertexFormat::Float32x3, + shader_location: 1, + }, + ], + }; + + let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Triangle Pipeline"), + layout: None, + vertex: wgpu::VertexState { + module: &shader_module, + entry_point: Some("vs_main"), + buffers: &[vertex_buffer_layout], + compilation_options: Default::default(), + }, + 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, + }, + fragment: Some(wgpu::FragmentState { + module: &shader_module, + entry_point: Some("fs_main"), + targets: &[Some(wgpu::ColorTargetState { + format: config.format, + blend: None, + write_mask: wgpu::ColorWrites::ALL, + })], + compilation_options: Default::default(), + }), + multiview_mask: None, + cache: None, + }); + + Ok(Self { + surface, + device, + queue, + config, + window: Arc::clone(&window), + pipeline, + vertex_buffer, + }) + } +}