draw with wgpu
This commit is contained in:
parent
ca80d3d4e2
commit
e168f4e93f
4 changed files with 129 additions and 16 deletions
|
@ -8,7 +8,7 @@ use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn init_render() -> Result<()> {
|
pub fn init_renderer() -> Result<()> {
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
event_loop.set_control_flow(ControlFlow::Poll);
|
event_loop.set_control_flow(ControlFlow::Poll);
|
||||||
let mut app = App::default();
|
let mut app = App::default();
|
||||||
|
|
100
engine/src/core/renderer/ctx.rs
Normal file
100
engine/src/core/renderer/ctx.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use tokio::task::spawn_blocking;
|
||||||
|
use winit::window::Window;
|
||||||
|
|
||||||
|
pub struct WgpuCtx<'window> {
|
||||||
|
device: wgpu::Device,
|
||||||
|
queue: wgpu::Queue,
|
||||||
|
surface: wgpu::Surface<'window>,
|
||||||
|
surface_config: wgpu::SurfaceConfiguration,
|
||||||
|
adapter: wgpu::Adapter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'window> WgpuCtx<'window> {
|
||||||
|
pub async fn new(window: Arc<Window>) -> Result<WgpuCtx<'window>> {
|
||||||
|
let instnace = wgpu::Instance::default();
|
||||||
|
let surface = instnace.create_surface(Arc::clone(&window))?;
|
||||||
|
let adapter = instnace
|
||||||
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
|
power_preference: wgpu::PowerPreference::default(),
|
||||||
|
force_fallback_adapter: false,
|
||||||
|
compatible_surface: Some(&surface),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.expect("Failed to obtain render adapter");
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(
|
||||||
|
&wgpu::DeviceDescriptor {
|
||||||
|
label: None,
|
||||||
|
required_features: wgpu::Features::empty(),
|
||||||
|
required_limits: wgpu::Limits::downlevel_webgl2_defaults()
|
||||||
|
.using_resolution(adapter.limits()),
|
||||||
|
memory_hints: wgpu::MemoryHints::Performance,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Failed to create rendering device");
|
||||||
|
|
||||||
|
let size = window.inner_size();
|
||||||
|
let width = size.width.max(1);
|
||||||
|
let height = size.height.max(1);
|
||||||
|
|
||||||
|
let surface_config = surface.get_default_config(&adapter, width, height).unwrap();
|
||||||
|
surface.configure(&device, &surface_config);
|
||||||
|
|
||||||
|
Ok(WgpuCtx {
|
||||||
|
device: device,
|
||||||
|
queue: queue,
|
||||||
|
surface: surface,
|
||||||
|
surface_config: surface_config,
|
||||||
|
adapter: adapter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn new_blocking(window: Arc<Window>) -> Result<WgpuCtx<'window>> {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async { WgpuCtx::new(window).await })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn resize(&mut self, new_size: (u32, u32)) {
|
||||||
|
let (width, height) = new_size;
|
||||||
|
self.surface_config.width = width.max(1);
|
||||||
|
self.surface_config.height = height.max(1);
|
||||||
|
self.surface.configure(&self.device, &self.surface_config);
|
||||||
|
}
|
||||||
|
pub fn draw(&mut self) {
|
||||||
|
let surface_texture = self
|
||||||
|
.surface
|
||||||
|
.get_current_texture()
|
||||||
|
.expect("Failed to get surface texture");
|
||||||
|
let view = surface_texture.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
|
{
|
||||||
|
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: None,
|
||||||
|
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: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.queue.submit(Some(encoder.finish()));
|
||||||
|
surface_texture.present();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,28 @@
|
||||||
use log2::{debug, error};
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use ctx::WgpuCtx;
|
||||||
|
use log2::{debug, error, trace};
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::event::WindowEvent;
|
use winit::event::WindowEvent;
|
||||||
use winit::event_loop::ActiveEventLoop;
|
use winit::event_loop::ActiveEventLoop;
|
||||||
use winit::window::{Window, WindowId};
|
use winit::window::{self, Window, WindowId};
|
||||||
|
pub mod ctx;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct App {
|
pub struct App<'window> {
|
||||||
window: Option<Window>,
|
window: Option<Arc<Window>>,
|
||||||
|
ctx: Option<WgpuCtx<'window>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApplicationHandler for App {
|
impl ApplicationHandler for App<'_> {
|
||||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||||
if self.window.is_none() {
|
if self.window.is_none() {
|
||||||
let win_attr = Window::default_attributes().with_title("Zenyx");
|
let win_attr = Window::default_attributes().with_title("Zenyx");
|
||||||
let window = event_loop
|
let window = Arc::new(event_loop
|
||||||
.create_window(win_attr)
|
.create_window(win_attr)
|
||||||
.expect("create window err.");
|
.expect("create window err."));
|
||||||
self.window = Some(window);
|
self.window = Some(window.clone());
|
||||||
|
let wgpu_ctx = WgpuCtx::new_blocking(window.clone()).unwrap();
|
||||||
|
self.ctx = Some(wgpu_ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +38,21 @@ impl ApplicationHandler for App {
|
||||||
debug!("Window closed, exiting");
|
debug!("Window closed, exiting");
|
||||||
std::process::exit(0)
|
std::process::exit(0)
|
||||||
}
|
}
|
||||||
|
WindowEvent::RedrawRequested => {
|
||||||
|
if let Some(ctx) = &mut self.ctx {
|
||||||
|
ctx.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
WindowEvent::Resized(size) => {
|
WindowEvent::Resized(size) => {
|
||||||
|
if let (Some(wgpu_ctx),Some(window)) = (&mut self.ctx, &self.window) {
|
||||||
|
wgpu_ctx.resize(size.into());
|
||||||
|
window.request_redraw();
|
||||||
let size_str: String = size.height.to_string() + "x" + &size.width.to_string();
|
let size_str: String = size.height.to_string() + "x" + &size.width.to_string();
|
||||||
//self.window.as_ref().unwrap().set_title(&format!("you reszed the window to {size_str}"));
|
//self.window.as_ref().unwrap().set_title(&format!("you reszed the window to {size_str}"));
|
||||||
debug!("Window resized to {:?}", size_str);
|
debug!("Window resized to {:?}", size_str);
|
||||||
}
|
}
|
||||||
_ => error!("Unhandled window event"),
|
}
|
||||||
|
_ => trace!("Unhandled window event"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log2::info;
|
use log2::info;
|
||||||
|
|
||||||
|
@ -6,17 +5,16 @@ pub mod core;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let _log2 = log2::open("z.log").tee(true).level("trace").start();
|
let _log2 = log2::open("z.log").tee(true).level("debug").start();
|
||||||
info!("Initalizing Engine");
|
info!("Initalizing Engine");
|
||||||
let shell_thread = tokio::task::spawn(async {
|
let shell_thread = tokio::task::spawn(async {
|
||||||
info!("Shell thread started");
|
info!("Shell thread started");
|
||||||
core::repl::handle_repl().await;
|
core::repl::handle_repl().await;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
core::splash::print_splash();
|
core::splash::print_splash();
|
||||||
info!("Engine Initalized");
|
info!("Engine Initalized");
|
||||||
core::init_render()?;
|
core::init_renderer()?;
|
||||||
shell_thread.await?;
|
shell_thread.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue