Skip to content

Commit

Permalink
refurbish the api, add helo triangle
Browse files Browse the repository at this point in the history
  • Loading branch information
boralg committed May 19, 2024
1 parent 305d0d0 commit 5e1aee2
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,11 @@ crate-type = ["cdylib"]
name = "hello_window"
path = "src/hello_window/main.rs"

[[bin]]
name = "hello_triangle"
path = "src/hello_triangle/main.rs"

[dependencies]
sursface = { path = "../sursface" }
env_logger = "0.11.3"
log = "0.4.21"
sursface = { path = "../sursface" }
10 changes: 10 additions & 0 deletions examples/src/hello_triangle/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use sursface::start;

#[cfg(target_arch = "wasm32")]
use sursface::wasm_bindgen;

#[cfg(target_arch = "wasm32")]
#[wasm_bindgen::prelude::wasm_bindgen]
pub fn start_browser(canvas: sursface::wgpu::web_sys::HtmlCanvasElement) {
start::create_window_browser(canvas);
}
203 changes: 203 additions & 0 deletions examples/src/hello_triangle/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
use std::any::Any;
use std::borrow::Cow;
use std::sync::{Arc, Mutex};
use sursface::app::{App, State};
use sursface::wgpu::{self, Color, CommandEncoder, RenderPipeline, ShaderModule, SurfaceTexture, TextureFormat, TextureView};

// Define the State trait


// Implement State for TriangleState
struct TriangleState {
render_pipeline: RenderPipeline,
shader: ShaderModule,
pipeline_layout: wgpu::PipelineLayout,
format: TextureFormat,
view: Option<TextureView>,
}

impl State for TriangleState {}

impl TriangleState {
fn new(
render_pipeline: RenderPipeline,
shader: ShaderModule,
pipeline_layout: wgpu::PipelineLayout,
format: TextureFormat,
) -> Self {
TriangleState {
render_pipeline,
shader,
pipeline_layout,
format,
view: None,
}
}

fn set_view(&mut self, view: TextureView) {
self.view = Some(view);
}
}

fn init(app: &mut App) -> Box<dyn State> {
let display = app.display.as_ref().unwrap();
let device = &display.device;

let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
});

let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[],
push_constant_ranges: &[],
});

let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
buffers: &[],
compilation_options: Default::default(),
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: "fs_main",
targets: &[Some(display.config.format.into())],
compilation_options: Default::default(),
}),
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
});

Box::new(TriangleState::new(
render_pipeline,
shader,
pipeline_layout,
display.config.format,
))
}

fn render(app: &mut App, mut state: &mut Box<dyn State>) {
let color = Color {
r: 100.0 / 255.0,
g: 149.0 / 255.0,
b: 237.0 / 255.0,
a: 255.0 / 255.0,
};

let output = {
let (output, mut encoder, view) = {
let display = app.display.as_ref().unwrap();

// Clear the screen and get the output, encoder, and view
let (output, mut encoder) = clear_screen(app, color).unwrap();
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());

(output, encoder, view)
};

{
let state = unsafe { core::mem::transmute::<&mut Box<dyn State>, &mut Box<TriangleState>>(state) };
state.set_view(view);

let mut rpass = create_render_pass(state, &mut encoder, state.view.as_ref().unwrap(), color);
draw_triangle(&mut rpass, &state.render_pipeline);
}

// Submit the queue outside of mutable borrow of state
{
let display = app.display.as_ref().unwrap();
display.queue.submit(std::iter::once(encoder.finish()));
}

output
};

// Now perform the present operation after mutable borrows are done
present(output);
}

fn clear_screen(
app: &mut App,
color: Color,
) -> Result<(SurfaceTexture, CommandEncoder), wgpu::SurfaceError> {
let display = app.display.as_ref().unwrap();
let output = display.surface.get_current_texture()?;
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());

let mut encoder = display.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Clear Screen Encoder"),
});

// Clear the screen with the specified color
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Clear Screen Render Pass"),
timestamp_writes: Default::default(),
occlusion_query_set: Default::default(),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(color),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
});
// No further commands needed for clearing
}

Ok((output, encoder))
}

fn create_render_pass<'a>(
state: &'a TriangleState,
encoder: &'a mut CommandEncoder,
view: &'a TextureView,
color: Color,
) -> wgpu::RenderPass<'a> {
let rpass_descriptor = wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(color),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: Default::default(),
occlusion_query_set: Default::default(),
};

encoder.begin_render_pass(&rpass_descriptor)
}

pub fn draw_triangle<'a>(
rpass: &mut wgpu::RenderPass<'a>,
pipeline: &'a RenderPipeline,
) {
rpass.set_pipeline(pipeline);
rpass.draw(0..3, 0..1);
}

fn present(output: SurfaceTexture) {
output.present();
}

#[cfg(not(target_arch = "wasm32"))]
fn main() {
use sursface::winit::dpi::PhysicalSize;
sursface::start::create_window_desktop(PhysicalSize::new(1280, 720), init, render);
}

#[cfg(target_arch = "wasm32")]
fn main() {}
11 changes: 11 additions & 0 deletions examples/src/hello_triangle/shader.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
let x = f32(i32(in_vertex_index) - 1);
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
return vec4<f32>(x, y, 0.0, 1.0);
}

@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
42 changes: 35 additions & 7 deletions examples/src/hello_window/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
use sursface::{app::App, wgpu};
use sursface::{app::{App, State}, wgpu};
use std::any::Any;

#[cfg(not(target_arch = "wasm32"))]
fn main() {
use sursface::winit::dpi::PhysicalSize;
sursface::start::create_window_desktop(PhysicalSize::new(1280, 720), render);
env_logger::init();
log::info!("Starting application");
sursface::start::create_window_desktop(PhysicalSize::new(1280, 720), init, render);
}

fn render<'a>(app: &mut App<'a>) {
let _ = clear_screen(app, sursface::wgpu::Color { r: 100f64 / 255f64, g: 149f64 / 255f64, b: 237f64 / 255f64, a: 255f64 / 255f64 });
#[cfg(target_arch = "wasm32")]
fn main() {}

#[derive(Clone)]
struct EmptyState {}
impl State for EmptyState {}

fn init<'a>(app: &mut App<'a>) -> Box<dyn State> {
log::info!("Initializing state");
Box::new(EmptyState {})
}

fn render<'a>(app: &mut App<'a>, _state: &mut Box<dyn State>) {
log::error!("hhhhom");
let output = clear_screen(app, wgpu::Color {
r: 100.0 / 255.0,
g: 149.0 / 255.0,
b: 237.0 / 255.0,
a: 1.0,
}).unwrap();
let _ = present(app, output);
}

fn clear_screen<'a>(app: &mut App<'a>, color: sursface::wgpu::Color) -> Result<(), wgpu::SurfaceError> {

fn clear_screen<'a>(app: &mut App<'a>, color: sursface::wgpu::Color) -> Result<wgpu::SurfaceTexture, wgpu::SurfaceError> {
log::info!("gaspar");
let display = app.display.as_ref().unwrap();
let output = display.surface.get_current_texture()?;
let view = output
Expand Down Expand Up @@ -39,9 +63,13 @@ fn clear_screen<'a>(app: &mut App<'a>, color: sursface::wgpu::Color) -> Result<(
}

display.queue.submit(std::iter::once(encoder.finish()));
output.present();

Ok(())
Ok(output)
}

fn present<'a>(app: &mut App<'a>, output: sursface::wgpu::SurfaceTexture) -> Result<(), wgpu::SurfaceError> {
output.present();
Ok(())
}

#[cfg(target_arch = "wasm32")]
Expand Down
Loading

0 comments on commit 5e1aee2

Please sign in to comment.