mirror of
https://github.com/touchHLE/rust-sdl2.git
synced 2026-01-31 01:25:23 +01:00
Update raw-window-handle-with-wgpu example to use wgpu 0.5
* Remove WindowWrapper since wgpu now uses raw-window-handle correctly on OSX which also lets us remove the objc dependency * Add futures dependency to handle parts of the wgpu API that are now asynchronous * Flip y coords in vertex shader to keep triangle oriented the same way since wgpu flipped their y-axis * Fix various other errors resulting from breaking API changes in wgpu
This commit is contained in:
@@ -28,11 +28,9 @@ optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "^0.7"
|
||||
wgpu = "^0.4.0"
|
||||
wgpu = "^0.5.0"
|
||||
glsl-to-spirv = "^0.1.7"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dev-dependencies.objc]
|
||||
version = "^0.2.7"
|
||||
futures = "^0.3"
|
||||
|
||||
[dependencies.raw-window-handle]
|
||||
version = "0.3.3"
|
||||
|
||||
@@ -1,51 +1,15 @@
|
||||
/// Minimal example for getting sdl2 and wgpu working together with raw-window-handle.
|
||||
///
|
||||
/// TODO: update wgpu and this example after https://github.com/gfx-rs/wgpu/pull/462 ships
|
||||
|
||||
extern crate glsl_to_spirv;
|
||||
extern crate libc;
|
||||
#[cfg(target_os = "macos")]
|
||||
extern crate objc;
|
||||
extern crate raw_window_handle;
|
||||
extern crate sdl2;
|
||||
extern crate wgpu;
|
||||
extern crate futures;
|
||||
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
use futures::executor::block_on;
|
||||
|
||||
use sdl2::event::{Event, WindowEvent};
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::video::Window;
|
||||
|
||||
/// sdl2 implements raw-window-handle correctly, but wgpu does not for macOS
|
||||
/// wgpu wrongly expects an NSView to be provided by raw-window-handle, so we have to do a little more work
|
||||
struct WindowWrapper<'a>(pub &'a Window);
|
||||
|
||||
unsafe impl<'a> HasRawWindowHandle for WindowWrapper<'a> {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
/// all non-mac platforms work correctly, so return the handle directly
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
self.0.raw_window_handle()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
/// do some work on macOS to get the root NSView for the NSWindow returned by sdl2
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc::runtime::Object;
|
||||
use raw_window_handle::macos::MacOSHandle;
|
||||
let handle = self.0.raw_window_handle();
|
||||
match handle {
|
||||
RawWindowHandle::MacOS(macos_handle) => {
|
||||
RawWindowHandle::MacOS(MacOSHandle {
|
||||
ns_window: macos_handle.ns_window,
|
||||
ns_view: unsafe { msg_send![macos_handle.ns_window as *mut Object, contentView] },
|
||||
..MacOSHandle::empty()
|
||||
})
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_glsl(code: &str, ty: glsl_to_spirv::ShaderType) -> Result<Vec<u32>, String> {
|
||||
let spirv = glsl_to_spirv::compile(&code, ty)?;
|
||||
@@ -63,22 +27,28 @@ fn main() -> Result<(), String> {
|
||||
.build()
|
||||
.map_err(|e| e.to_string())?;
|
||||
let (width, height) = window.size();
|
||||
let surface = wgpu::Surface::create(&window);
|
||||
|
||||
let adapter_opt = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::Default,
|
||||
backends: wgpu::BackendBit::PRIMARY,
|
||||
});
|
||||
let adapter_opt = block_on(wgpu::Adapter::request(
|
||||
&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::Default,
|
||||
compatible_surface: Some(&surface),
|
||||
},
|
||||
wgpu::BackendBit::PRIMARY,
|
||||
));
|
||||
let adapter = match adapter_opt {
|
||||
Some(a) => a,
|
||||
None => return Err(String::from("No adapter found")),
|
||||
};
|
||||
|
||||
let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
});
|
||||
let (device, queue) = block_on(adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}
|
||||
));
|
||||
|
||||
let vs = include_str!("shader.vert");
|
||||
let vs_spirv = &load_glsl(vs, glsl_to_spirv::ShaderType::Vertex)?;
|
||||
@@ -88,10 +58,14 @@ fn main() -> Result<(), String> {
|
||||
let fs_spirv = &load_glsl(fs, glsl_to_spirv::ShaderType::Fragment)?;
|
||||
let fs_module = device.create_shader_module(fs_spirv);
|
||||
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[] });
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[],
|
||||
label: Some("bind_group_layout"),
|
||||
});
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &bind_group_layout,
|
||||
bindings: &[],
|
||||
label: Some("bind_group"),
|
||||
});
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: &[&bind_group_layout],
|
||||
@@ -121,23 +95,22 @@ fn main() -> Result<(), String> {
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[],
|
||||
},
|
||||
depth_stencil_state: None,
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[],
|
||||
sample_count: 1,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
// use the WindowWrapper to make sure wgpu will work on macOS
|
||||
let surface = wgpu::Surface::create(&WindowWrapper(&window));
|
||||
|
||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
width,
|
||||
height,
|
||||
present_mode: wgpu::PresentMode::Vsync,
|
||||
present_mode: wgpu::PresentMode::Fifo,
|
||||
};
|
||||
|
||||
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||
@@ -165,9 +138,16 @@ fn main() -> Result<(), String> {
|
||||
}
|
||||
}
|
||||
|
||||
let frame = swap_chain.get_next_texture();
|
||||
let frame_res = swap_chain.get_next_texture();
|
||||
let frame = match frame_res {
|
||||
Ok(a) => a,
|
||||
Err(_) => return Err(String::from("Timeout getting next texture")),
|
||||
};
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("command_encoder")
|
||||
});
|
||||
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
|
||||
@@ -5,9 +5,9 @@ out gl_PerVertex {
|
||||
};
|
||||
|
||||
const vec2 positions[3] = vec2[3](
|
||||
vec2(0.0, -0.5),
|
||||
vec2(0.5, 0.5),
|
||||
vec2(-0.5, 0.5)
|
||||
vec2(0.0, 0.5),
|
||||
vec2(0.5, -0.5),
|
||||
vec2(-0.5, -0.5)
|
||||
);
|
||||
|
||||
void main() {
|
||||
|
||||
Reference in New Issue
Block a user