rust/hwrunner/src/main.rs
changeset 15777 2b3f8af6f647
parent 15776 ec85fdf82942
child 15798 c4d931ce2659
equal deleted inserted replaced
15776:ec85fdf82942 15777:2b3f8af6f647
    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 
    83                 encoder.begin_render_pass(&RenderPassDescriptor {
   162                 encoder.begin_render_pass(&RenderPassDescriptor {
    84                     color_attachments: &[RenderPassColorAttachmentDescriptor {
   163                     color_attachments: &[RenderPassColorAttachmentDescriptor {
    85                         attachment: &frame_view,
   164                         attachment: &frame_view,
    86                         resolve_target: None,
   165                         resolve_target: None,
    87                         ops: Operations {
   166                         ops: Operations {
    88                             load: LoadOp::Clear(Color::BLUE),
   167                             load: LoadOp::Clear(Color {
       
   168                                 r: 0.7,
       
   169                                 g: 0.4,
       
   170                                 b: 0.2,
       
   171                                 a: 1.0,
       
   172                             }),
    89                             store: false,
   173                             store: false,
    90                         },
   174                         },
    91                     }],
   175                     }],
    92                     depth_stencil_attachment: None,
   176                     depth_stencil_attachment: None,
    93                 });
   177                 });
    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                     }
   253         if render_time.elapsed() > Duration::from_millis(16) {
   258         if render_time.elapsed() > Duration::from_millis(16) {
   254             render_time = current_time;
   259             render_time = current_time;
   255             if !use_wgpu {
   260             if !use_wgpu {
   256                 engine.render();
   261                 engine.render();
   257             }
   262             }
   258             context.present();
   263             context.present().ok().unwrap();
   259         }
   264         }
   260     }
   265     }
   261 }
   266 }