38 ErrorStub |
38 ErrorStub |
39 } |
39 } |
40 } |
40 } |
41 |
41 |
42 impl HwRendererContext { |
42 impl HwRendererContext { |
|
43 fn get_framebuffer_size(window: &Window) -> (u32, u32) { |
|
44 let size = window.get_inner_size().unwrap(); |
|
45 (size.to_physical(window.get_hidpi_factor())).into() |
|
46 } |
|
47 |
|
48 fn create_wpgu_swap_chain(window: &Window, surface: &Surface, device: &Device) -> SwapChain { |
|
49 let (width, height) = Self::get_framebuffer_size(window); |
|
50 device.create_swap_chain( |
|
51 &surface, |
|
52 &SwapChainDescriptor { |
|
53 usage: TextureUsage::OUTPUT_ATTACHMENT, |
|
54 format: TextureFormat::Bgra8Unorm, |
|
55 width, |
|
56 height, |
|
57 present_mode: PresentMode::Fifo, |
|
58 }, |
|
59 ) |
|
60 } |
|
61 |
|
62 fn init_wgpu(event_loop: &EventsLoop, size: dpi::LogicalSize) -> HwWgpuRenderingContext { |
|
63 let builder = WindowBuilder::new() |
|
64 .with_title("hwengine") |
|
65 .with_dimensions(size); |
|
66 let window = builder.build(event_loop).unwrap(); |
|
67 |
|
68 let instance = wgpu::Instance::new(BackendBit::VULKAN); |
|
69 |
|
70 let surface = unsafe { instance.create_surface(&window) }; |
|
71 |
|
72 let adapter = block_on(instance.request_adapter(&RequestAdapterOptions { |
|
73 power_preference: PowerPreference::HighPerformance, |
|
74 compatible_surface: Some(&surface), |
|
75 })) |
|
76 .unwrap(); |
|
77 |
|
78 let (device, queue) = block_on(adapter.request_device(&Default::default(), None)).unwrap(); |
|
79 |
|
80 let swap_chain = Self::create_wpgu_swap_chain(&window, &surface, &device); |
|
81 |
|
82 HwWgpuRenderingContext { |
|
83 window, |
|
84 surface, |
|
85 adapter, |
|
86 device, |
|
87 queue, |
|
88 swap_chain, |
|
89 } |
|
90 } |
|
91 |
|
92 fn init_gl(event_loop: &EventsLoop, size: dpi::LogicalSize) -> HwGlRendererContext { |
|
93 use glutin::ContextBuilder; |
|
94 |
|
95 let builder = WindowBuilder::new() |
|
96 .with_title("hwengine") |
|
97 .with_dimensions(size); |
|
98 |
|
99 let context = ContextBuilder::new() |
|
100 .with_gl(GlRequest::Latest) |
|
101 .with_gl_profile(GlProfile::Core) |
|
102 .build_windowed(builder, &event_loop) |
|
103 .ok() |
|
104 .unwrap(); |
|
105 |
|
106 unsafe { |
|
107 context.make_current().unwrap(); |
|
108 gl::load_with(|ptr| context.get_proc_address(ptr) as *const _); |
|
109 |
|
110 if let Some(sz) = context.get_inner_size() { |
|
111 let (width, height) = Self::get_framebuffer_size(context.window()); |
|
112 gl::Viewport(0, 0, width as i32, height as i32); |
|
113 } |
|
114 } |
|
115 |
|
116 context |
|
117 } |
|
118 |
|
119 fn new(event_loop: &EventsLoop, size: dpi::LogicalSize, use_wgpu: bool) -> Self { |
|
120 if use_wgpu { |
|
121 Self::Wgpu(Self::init_wgpu(event_loop, size)) |
|
122 } else { |
|
123 Self::Gl(Self::init_gl(event_loop, size)) |
|
124 } |
|
125 } |
|
126 |
43 pub fn window(&self) -> &Window { |
127 pub fn window(&self) -> &Window { |
44 match self { |
128 match self { |
45 HwRendererContext::Gl(gl) => &gl.window(), |
129 HwRendererContext::Gl(gl) => &gl.window(), |
46 HwRendererContext::Wgpu(wgpu) => &wgpu.window, |
130 HwRendererContext::Wgpu(wgpu) => &wgpu.window, |
47 } |
131 } |
48 } |
132 } |
49 |
133 |
50 pub fn update(&mut self, size: dpi::LogicalSize) { |
134 pub fn update(&mut self) { |
51 let phys = size.to_physical(self.window().get_hidpi_factor()); |
|
52 match self { |
135 match self { |
53 HwRendererContext::Gl(context) => unsafe { |
136 HwRendererContext::Gl(context) => unsafe { |
54 gl::Viewport(0, 0, phys.width as i32, phys.height as i32); |
137 let (width, height) = Self::get_framebuffer_size(&context.window()); |
|
138 gl::Viewport(0, 0, width as i32, height as i32); |
55 }, |
139 }, |
56 HwRendererContext::Wgpu(context) => { |
140 HwRendererContext::Wgpu(context) => { |
57 context.swap_chain = context.device.create_swap_chain( |
141 context.swap_chain = Self::create_wpgu_swap_chain( |
|
142 &context.window, |
58 &context.surface, |
143 &context.surface, |
59 &SwapChainDescriptor { |
144 &context.device, |
60 usage: TextureUsage::OUTPUT_ATTACHMENT, |
|
61 format: TextureFormat::Bgra8Unorm, |
|
62 width: phys.width as u32, |
|
63 height: phys.height as u32, |
|
64 present_mode: PresentMode::Fifo, |
|
65 }, |
|
66 ); |
145 ); |
67 } |
146 } |
68 } |
147 } |
69 } |
148 } |
70 |
149 |
97 } |
181 } |
98 Ok(()) |
182 Ok(()) |
99 } |
183 } |
100 } |
184 } |
101 |
185 |
102 fn init_wgpu(event_loop: &EventsLoop, size: dpi::LogicalSize) -> HwWgpuRenderingContext { |
|
103 let builder = WindowBuilder::new() |
|
104 .with_title("hwengine") |
|
105 .with_dimensions(size); |
|
106 let window = builder.build(event_loop).unwrap(); |
|
107 |
|
108 let instance = wgpu::Instance::new(BackendBit::PRIMARY); |
|
109 |
|
110 let surface = unsafe { instance.create_surface(&window) }; |
|
111 |
|
112 let adapter = block_on(instance.request_adapter(&RequestAdapterOptions { |
|
113 power_preference: PowerPreference::HighPerformance, |
|
114 compatible_surface: Some(&surface), |
|
115 })) |
|
116 .unwrap(); |
|
117 |
|
118 let (device, queue) = block_on(adapter.request_device(&Default::default(), None)).unwrap(); |
|
119 |
|
120 let size = window.get_inner_size().unwrap(); |
|
121 |
|
122 let phys = size.to_physical(window.get_hidpi_factor()); |
|
123 |
|
124 let mut swap_chain = device.create_swap_chain( |
|
125 &surface, |
|
126 &SwapChainDescriptor { |
|
127 usage: TextureUsage::OUTPUT_ATTACHMENT, |
|
128 format: TextureFormat::Bgra8Unorm, |
|
129 width: phys.width as u32, |
|
130 height: phys.height as u32, |
|
131 present_mode: PresentMode::Fifo, |
|
132 }, |
|
133 ); |
|
134 |
|
135 HwWgpuRenderingContext { |
|
136 window, |
|
137 surface, |
|
138 adapter, |
|
139 device, |
|
140 queue, |
|
141 swap_chain, |
|
142 } |
|
143 } |
|
144 |
|
145 fn init_gl(event_loop: &EventsLoop, size: dpi::LogicalSize) -> HwGlRendererContext { |
|
146 use glutin::ContextBuilder; |
|
147 |
|
148 let builder = WindowBuilder::new() |
|
149 .with_title("hwengine") |
|
150 .with_dimensions(size); |
|
151 |
|
152 let context = ContextBuilder::new() |
|
153 .with_gl(GlRequest::Latest) |
|
154 .with_gl_profile(GlProfile::Core) |
|
155 .build_windowed(builder, &event_loop) |
|
156 .ok() |
|
157 .unwrap(); |
|
158 |
|
159 unsafe { |
|
160 context.make_current().unwrap(); |
|
161 gl::load_with(|ptr| context.get_proc_address(ptr) as *const _); |
|
162 |
|
163 if let Some(sz) = context.get_inner_size() { |
|
164 let phys = sz.to_physical(context.get_hidpi_factor()); |
|
165 |
|
166 gl::Viewport(0, 0, phys.width as i32, phys.height as i32); |
|
167 } |
|
168 } |
|
169 |
|
170 context |
|
171 } |
|
172 |
|
173 fn init(event_loop: &EventsLoop, size: dpi::LogicalSize, use_wgpu: bool) -> HwRendererContext { |
|
174 if use_wgpu { |
|
175 HwRendererContext::Wgpu(init_wgpu(event_loop, size)) |
|
176 } else { |
|
177 HwRendererContext::Gl(init_gl(event_loop, size)) |
|
178 } |
|
179 } |
|
180 |
|
181 fn main() { |
186 fn main() { |
182 let use_wgpu = false; |
187 let use_wgpu = true; |
183 let mut event_loop = EventsLoop::new(); |
188 let mut event_loop = EventsLoop::new(); |
184 let (w, h) = (1024.0, 768.0); |
189 let (w, h) = (1024.0, 768.0); |
185 |
190 |
186 let mut context = init(&event_loop, dpi::LogicalSize::new(w, h), use_wgpu); |
191 let mut context = HwRendererContext::new(&event_loop, dpi::LogicalSize::new(w, h), use_wgpu); |
187 |
192 |
188 let mut engine = EngineInstance::new(); |
193 let mut engine = EngineInstance::new(); |
189 if !use_wgpu { |
194 if !use_wgpu { |
190 engine.world.create_renderer(w as u16, h as u16); |
195 engine.world.create_renderer(w as u16, h as u16); |
191 } |
196 } |
215 event_loop.poll_events(|event| match event { |
220 event_loop.poll_events(|event| match event { |
216 Event::WindowEvent { event, .. } => match event { |
221 Event::WindowEvent { event, .. } => match event { |
217 WindowEvent::CloseRequested => { |
222 WindowEvent::CloseRequested => { |
218 is_running = false; |
223 is_running = false; |
219 } |
224 } |
220 WindowEvent::Resized(size) => context.update(size), |
225 WindowEvent::Resized(_) | WindowEvent::HiDpiFactorChanged(_) => context.update(), |
221 |
226 |
222 WindowEvent::MouseInput { button, state, .. } => { |
227 WindowEvent::MouseInput { button, state, .. } => { |
223 if let MouseButton::Right = button { |
228 if let MouseButton::Right = button { |
224 dragging = state == ElementState::Pressed; |
229 dragging = state == ElementState::Pressed; |
225 } |
230 } |