{"id":338963,"date":"2022-09-28T09:00:34","date_gmt":"2022-09-28T09:00:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=338963"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=338963","title":{"rendered":"<span>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Rust<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f95\/b5a\/5e7\/f95b5a5e79672904287d4f17484061c9.png\" width=\"1278\" height=\"891\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f95\/b5a\/5e7\/f95b5a5e79672904287d4f17484061c9.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0421\u0430\u0448\u0430 \u0438 \u044f backend \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041d\u0435\u0442, \u043d\u0435 \u043d\u0430 rust. \u041d\u043e \u0440\u0430\u0441\u0442 \u043c\u043e\u0439 \u043b\u044e\u0431\u0438\u043c\u044b\u0439 \u044f\u0437\u044b\u043a \u0438 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0437\u0430\u0434\u0430\u043b\u0441\u044f \u0446\u0435\u043b\u044c\u044e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u043e\u043a \u043e\u043d\u043b\u0430\u0439\u043d \u0438\u0433\u0440\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 C++. \u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0441\u044f\u0446 \u0443\u0448\u0435\u043b \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c\u0438 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438, \u0438\u0445 \u0447\u0442\u0435\u043d\u0438\u0435\u043c \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u041d\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c, \u0430 \u043e <em>WGPU<\/em>.<\/p>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 WGPU?<\/h2>\n<p><a href=\"https:\/\/github.com\/gfx-rs\/wgpu\" rel=\"noopener noreferrer nofollow\">WGPU<\/a> \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 <em>WebGPU<\/em> \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 <em>rust<\/em>, \u0446\u0435\u043b\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0432\u0438\u0434\u0435\u043e \u043a\u0430\u0440\u0442\u044b \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 (\u0437\u0430\u043c\u0435\u043d\u0430 <em>webgl<\/em>).\u0412\u043e \u043c\u043d\u043e\u0433\u043e\u043c, API \u043f\u0435\u0440\u0435\u043a\u043b\u0438\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0430\u043a\u043e\u0432\u044b\u043c \u0443 Vulkan API, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c <em>\u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438<\/em> \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 backend-\u044b (<em>DirectX<\/em>, <em>Metal<\/em>, <em>Vulkan, OpenGL<\/em>).<\/p>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u043c\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 3D \u0441\u0446\u0435\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u0443\u0440\u043e\u043a\u043e\u0432 \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0435. \u0412\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e <a href=\"https:\/\/sotrh.github.io\/learn-wgpu\/#what-is-wgpu\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430<\/a> \u043f\u043e <em>wgpu<\/em> + \u043c\u043e\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438.<\/p>\n<h2>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c!<\/h2>\n<p>\u042f \u043f\u043e\u0434\u0435\u043b\u0438\u043b \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u0443\u0440\u043e\u043a\u0438 \u0438 \u043f\u0435\u0440\u0432\u044b\u043c \u0438\u0437 \u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u0443\u0440\u043e\u043a \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043e\u043a\u043d\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043b 3 \u0443\u0440\u043e\u043a\u0430.<\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043b\u044e\u0431\u0430\u044f \u0438\u0433\u0440\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u043a\u043d\u0430, \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u043d\u0435\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u044b.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>cargo<\/em>:<\/p>\n<pre><code>cargo new rust_wgpu_tutorial --bin<\/code><\/pre>\n<p>\u042f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>[dependencies] winit = \"0.26\" env_logger = \"0.9\" log = \"0.4\" wgpu = \"0.13\"<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c \u043a\u043e\u0434:<\/p>\n<pre><code class=\"rust\">use winit::{     event::*,     event_loop::{ControlFlow, EventLoop},     window::WindowBuilder, };  fn main() {     env_logger::init();     let event_loop = EventLoop::new();     let window = WindowBuilder::new().build(&amp;event_loop).unwrap();      event_loop.run(move |event, _, control_flow| match event {         Event::WindowEvent {             ref event,             window_id,         } if window_id == window.id() => match event {             WindowEvent::CloseRequested | WindowEvent::KeyboardInput {                 input:                 KeyboardInput {                     state: ElementState::Pressed,                     virtual_keycode: Some(VirtualKeyCode::Escape),                     ..                 },                 ..             } => *control_flow = ControlFlow::Exit,             _ => {}         },         _ => {}     }); }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0435\u0449\u0435 \u043b\u043e\u0433\u0433\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043e\u0448\u0438\u0431\u043e\u043a <em>wgpu<\/em>, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0443\u0442. \u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u0440\u0430\u0441\u0442\u043e\u043c, \u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u0440\u043e\u043c\u0435 \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 <code>match<\/code>. \u0422\u0430\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 <code>event_loop<\/code>, \u043e\u0442\u0431\u0435\u0440\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043e\u043a\u043d\u0443. \u0415\u0441\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>WindowEvent::CloseRequested<\/code>, \u043b\u0438\u0431\u043e <code>WindowEvent::KeyboardInput<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>KeyboardInput<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 <code>virtual_keycode<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0432\u043d\u043e <code>Some(VirtualKeyCode::Escape)<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>ControlFlow::Exit<\/code> (\u0437\u0430\u043a\u0440\u043e\u0439 \u043e\u043a\u043d\u043e). \u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 pattern-matching \u0432 <em>haskell<\/em>. \u0412\u043e\u0442 \u0437\u0430 \u0447\u0442\u043e \u044f \u043b\u044e\u0431\u043b\u044e <em>rust<\/em>.<\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u043e\u043a\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f! \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0444\u0430\u0439\u043b <code>state.rs<\/code> \u0432 \u043f\u0430\u043f\u043a\u0443 <code>src<\/code>, \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<pre><code class=\"rust\">use winit::window::Window; use winit::{     event::*, };  pub struct State {     surface: wgpu::Surface,     device: wgpu::Device,     queue: wgpu::Queue,     config: wgpu::SurfaceConfiguration,     size: winit::dpi::PhysicalSize&lt;u32>, }  impl State {     pub async fn new(window: &amp;Window) -> Self {         todo!()     }      pub fn resize(&amp;mut self, new_size: winit::dpi::PhysicalSize&lt;u32>) {         todo!()     }      pub fn input(&amp;mut self, event: &amp;WindowEvent) -> bool {         todo!()     }      pub fn update(&amp;mut self) {         todo!()     }      pub fn render(&amp;mut self) -> Result&lt;(), wgpu::SurfaceError> {         todo!()     } }<\/code><\/pre>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441 \u043c\u0435\u0442\u043e\u0434\u0430 <code>new<\/code>:<\/p>\n<pre><code class=\"rust\">async fn new(window: &amp;Window) -> Self {     let size = window.inner_size();      \/\/ instance - \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 wgpu     \/\/ Backends::all => OpenGL + Vulkan + Metal + DX12 + Browser WebGPU     let instance = wgpu::Instance::new(wgpu::Backends::all());     let surface = unsafe { instance.create_surface(window) };     let adapter = instance.request_adapter(         &amp;wgpu::RequestAdapterOptions {             power_preference: wgpu::PowerPreference::LowPower,             compatible_surface: Some(&amp;surface),             force_fallback_adapter: false,         },     ).await.unwrap(); }<\/code><\/pre>\n<h4>Instance \u0438 Adapter<\/h4>\n<p>\u0414\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b\u00a0\u0441\u00a0\u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u043e\u0439\u00a0\u043d\u0430\u043c\u00a0\u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>Adapter<\/code>\u00a0\u0438\u00a0<code>Surface<\/code>,\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u0435\u00a0\u043c\u043e\u0436\u043d\u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0\u043c\u0435\u0442\u043e\u0434\u044b\u00a0<code>instance<\/code>.\u00a0\u041c\u043d\u0435\u00a0\u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f,\u00a0\u0447\u0442\u043e\u00a0\u043f\u0440\u0435\u0436\u0434\u0435\u00a0\u0447\u0435\u043c\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c\u00a0\u0441\u00a0\u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u043e\u0439,\u00a0\u043d\u0443\u0436\u043d\u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0<code>instance<\/code>,\u00a0\u0430\u00a0\u043d\u0435\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c\u00a0\u0441\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u00a0\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c,\u00a0\u043a\u0430\u043a\u00a0\u044d\u0442\u043e\u00a0\u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f\u00a0\u0432\u00a0<em>OpenGL<\/em>,\u00a0\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u041f\u0440\u0438\u00a0\u0432\u044b\u0431\u043e\u0440\u0435\u00a0\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430,\u00a0\u043c\u044b\u00a0\u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443\u0435\u043c\u0441\u044f\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438\u00a0\u043e\u043f\u0446\u0438\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>power_preference<\/code>\u00a0\u0432 \u044d\u0442\u043e\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0432\u044b\u0431\u043e\u0440\u0430\u00a0<em>GPU<\/em>. \u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435\u00a0<code>LowPower<\/code>,\u00a0<em>wgpu<\/em>\u00a0\u0432\u044b\u0431\u0435\u0440\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0443.<\/p>\n<\/li>\n<li>\n<p><code>compatible_surface<\/code>\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code>force_fallback_adapter<\/code>\u00a0\u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432\u00a0<code>true<\/code>,\u00a0<em>wgpu<\/em>\u00a0\u0432\u044b\u0431\u0435\u0440\u0435\u0442 \u0430\u0434\u0430\u043f\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u043e\u043b\u0435\u0439 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0436\u0435\u043b\u0435\u0437\u0435, \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0435<\/p>\n<\/li>\n<\/ul>\n<h4>Surface<\/h4>\n<p><code>Surface<\/code>\u00a0\u044d\u0442\u043e\u00a0\u043e\u0431\u043b\u0430\u0441\u0442\u044c\u00a0\u043e\u043a\u043d\u0430\u00a0(\u043a\u0430\u043a\u00a0<em>canvas<\/em>\u00a0\u0432\u00a0<em>html<\/em>),\u00a0\u043a\u043e\u0442\u043e\u0440\u0430\u044f\u00a0\u0431\u0443\u0434\u0435\u0442\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u00a0\u0434\u043b\u044f\u00a0\u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.\u00a0\u0427\u0442\u043e\u0431\u044b\u00a0\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<code>surface<\/code>,\u00a0\u043e\u043a\u043d\u043e\u00a0\u0434\u043e\u043b\u0436\u043d\u043e\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>HasRawWindowHandle<\/code>\u00a0\u0438\u0437\u00a0\u043f\u0430\u043a\u0435\u0442\u0430\u00a0<a href=\"https:\/\/crates.io\/crates\/raw-window-handle\" rel=\"noopener noreferrer nofollow\">raw-window-handle<\/a>.\u00a0\u0412\u00a0\u043d\u0430\u0448\u0435\u043c\u00a0\u0441\u043b\u0443\u0447\u0430\u0435,\u00a0<code>winit<\/code>\u00a0\u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442\u00a0\u043f\u043e\u0434\u00a0\u044d\u0442\u0438\u00a0\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>Device &amp; Queue<\/h4>\n<p>\u041a\u0430\u043a\u00a0\u0438\u00a0\u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435\u00a0\u0441\u00a0<code>instance<\/code>,\u00a0\u043c\u044b\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c\u00a0\u043d\u0435\u00a0\u0441\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438,\u00a0\u0430\u00a0\u0441\u0430\u043c\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u0435\u043c\u00a0\u043d\u0443\u0436\u043d\u044b\u0435\u00a0\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\u00a0\u0427\u0442\u043e\u0431\u044b\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0<code>device<\/code>\u00a0\u0438\u00a0<code>queue<\/code>,\u00a0\u044f\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u00a0\u043a\u043e\u0434:<\/p>\n<pre><code class=\"rust\">let (device, queue) = adapter.request_device(     &amp;wgpu::DeviceDescriptor {         features: wgpu::Features::empty(),         limits: wgpu::Limits::default(),         label: None,     },     None, \/\/ Trace path ).await.unwrap();<\/code><\/pre>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u00a0<code>features<\/code>. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u043e\u0433\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u00a0<code>limits<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u00a0<code>max_vertex_attributes<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>max_vertex_buffer_array_stride<\/code>. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u043d\u043e\u00a0<a href=\"https:\/\/docs.rs\/wgpu\/latest\/wgpu\/struct.Limits.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0441\u043f\u0435\u043a\u0442\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 GPU.<\/p>\n<h2><\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::new<\/code>, \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<pre><code class=\"rust\">let config = wgpu::SurfaceConfiguration {     usage: wgpu::TextureUsages::RENDER_ATTACHMENT,     format: surface.get_supported_formats(&amp;adapter)[0],     width: size.width,     height: size.height,     present_mode: wgpu::PresentMode::Fifo, }; surface.configure(&amp;device, &amp;config); \/\/ \u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 State Self {     surface,     device,     queue,     config,     size }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043d\u0430 \u043f\u043e\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<ul>\n<li>\n<p><code>usage<\/code>\u00a0\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>format<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b\u00a0<code>SurfaceTextures<\/code>. \u0423 \u0440\u0430\u0437\u043d\u044b\u0445 \u0434\u0438\u0441\u043f\u043b\u0435\u0435\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u0432\u043e\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0444\u043e\u0440\u043c\u0430\u0442.<\/p>\n<\/li>\n<li>\n<p><code>present_mode<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u00a0<code>Surface<\/code>\u00a0\u0441 \u044d\u043a\u0440\u0430\u043d\u043e\u043c.\u00a0<code>wgpu::PresentMode::Fifo<\/code>\u00a0\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u00a0<code>VSYNC<\/code>.<\/p>\n<\/li>\n<\/ul>\n<h2><\/h2>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u00a0<code>State<\/code>\u00a0\u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<code>main<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/368\/5a4\/ca6\/3685a4ca664f77f1e023d388ba7609a6.png\" alt=\"\u0421\u043e\u0437\u0434\u0430\u0435\u043c State\" title=\"\u0421\u043e\u0437\u0434\u0430\u0435\u043c State\" width=\"2350\" height=\"1038\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/368\/5a4\/ca6\/3685a4ca664f77f1e023d388ba7609a6.png\"\/><figcaption>\u0421\u043e\u0437\u0434\u0430\u0435\u043c State<\/figcaption><\/figure>\n<p>\u0422\u043a \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::new<\/code>\u00a0\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0430\u043b\u043e, \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f\u00a0<code>.await<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043d\u0443\u0436\u0435\u043d\u00a0<code>Executor<\/code>. \u042f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c\u00a0<code>tokio<\/code>, \u0443\u043a\u0430\u0437\u0430\u0432 \u0435\u0433\u043e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445:\u00a0<\/p>\n<p><code>tokio = { version = \"1\", features = [\"full\"] }<\/code><\/p>\n<p>\u041c\u0435\u0442\u043e\u0434\u00a0<code>main<\/code>\u00a0\u0442\u043e\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c \u0438 \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439:<\/p>\n<p><code>#[tokio::main]<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n<h3>resize<\/h3>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043d\u0430\u0448\u0443 \u0440\u0430\u0431\u043e\u0442\u0443, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>resize<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u043a\u043d\u0430.<\/p>\n<pre><code class=\"rust\">fn resize(&amp;mut self, new_size: winit::dpi::PhysicalSize&lt;u32>) {     if new_size.width > 0 &amp;&amp; new_size.height > 0 {         self.size = new_size;         self.config.width = new_size.width;         self.config.height = new_size.height;         self.surface.configure(&amp;self.device, &amp;self.config);     } }<\/code><\/pre>\n<p><a href=\"http:\/\/main.rs\" rel=\"noopener noreferrer nofollow\">main.rs<\/a>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/069\/6e5\/934\/0696e5934b07249feadeaae67f6b061e.png\" alt=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Resized &amp; ScaleFactorChanged\" title=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Resized &amp; ScaleFactorChanged\" width=\"2498\" height=\"870\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/069\/6e5\/934\/0696e5934b07249feadeaae67f6b061e.png\"\/><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Resized &amp; ScaleFactorChanged<\/figcaption><\/figure>\n<p>\u0422\u0430\u043a \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435!<br \/>\u041c\u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u043a\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u00a0<code>Moved<\/code>:<\/p>\n<pre><code class=\"rust\">WindowEvent::Moved(_) => {     window.request_redraw(); }<\/code><\/pre>\n<h3>render<\/h3>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u0446\u0432\u0435\u0442\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::render<\/code>.<\/p>\n<pre><code class=\"rust\">let output = self.surface.get_current_texture()?;<\/code><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u00a0<code>SurfaceTexture<\/code>\u00a0(\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u044b\u0448\u0435,\u00a0<em>\u0444\u0440\u0435\u0439\u043c<\/em>), \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0443\u0434\u0430 \u043d\u0430\u0448 \u0444\u043e\u043d.<\/p>\n<pre><code class=\"rust\">let view = output.texture.create_view(&amp;wgpu::TextureViewDescriptor::default());<\/code><\/pre>\n<p><code>create_view<\/code>\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>TextureView<\/code>, \u0442\u043e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c.<\/p>\n<pre><code class=\"rust\">let mut encoder = self.device.create_command_encoder(&amp;wgpu::CommandEncoderDescriptor {     label: Some(\"Render Encoder\"), });<\/code><\/pre>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>CommandEncoder<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u00a0<em>GPU<\/em>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a:<\/p>\n<pre><code class=\"rust\">encoder.begin_render_pass(&amp;wgpu::RenderPassDescriptor {     label: Some(\"Render Pass\"),     color_attachments: &amp;[Some(wgpu::RenderPassColorAttachment {         view: &amp;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: true,         },     })],     depth_stencil_attachment: None, });<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c\u00a0<code>RenderPass<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u044d\u043a\u0440\u0430\u043d\u0430 \u0432 \u0441\u0438\u043d\u0438\u0439 \u0446\u0432\u0435\u0442.<\/p>\n<p>\u041f\u043e\u043b\u0435\u00a0<code>color_attachments.view<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0443\u0434\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f\u00a0<code>view<\/code>).<\/p>\n<p><code>color_attachments.ops.load<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430. <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u044d\u043a\u0440\u0430\u043d \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u0441\u0438\u043d\u0438\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<h2><\/h2>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<code>render<\/code>:<\/p>\n<pre><code class=\"rust\">self.queue.submit(std::iter::once(encoder.finish())); output.present();  Ok(())<\/code><\/pre>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u00a0<code>RenderPass<\/code>\u00a0\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435, \u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/03f\/c50\/670\/03fc506703677ae87947825bf11302d1.png\" alt=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 RedrawRequested \u0438 MainEventsCleared\" title=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 RedrawRequested \u0438 MainEventsCleared\" width=\"2434\" height=\"936\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/03f\/c50\/670\/03fc506703677ae87947825bf11302d1.png\"\/><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 RedrawRequested \u0438 MainEventsCleared<\/figcaption><\/figure>\n<p>\u0412\u043e\u0442, \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f75\/424\/a96\/f75424a965e94b31cc8c30a26b6213a7.png\" alt=\"\u0421\u0438\u043d\u0435\u0435 \u043e\u043a\u043d\u043e\" title=\"\u0421\u0438\u043d\u0435\u0435 \u043e\u043a\u043d\u043e\" width=\"1232\" height=\"874\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f75\/424\/a96\/f75424a965e94b31cc8c30a26b6213a7.png\"\/><figcaption>\u0421\u0438\u043d\u0435\u0435 \u043e\u043a\u043d\u043e<\/figcaption><\/figure>\n<h4>\u0417\u0430\u0434\u0430\u043d\u0438\u0435<\/h4>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>input<\/code>\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u043a\u0438 \u0438 \u043c\u0435\u043d\u044f\u0442\u044c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438. (\u0412\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>WindowEvent::CursorMoved<\/code>)<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/abritov\/rust-wgpu-tutorial\/tree\/master\/lesson1\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434<\/a> \u0443\u0440\u043e\u043a\u0430<\/p>\n<h2>\u0423\u0440\u043e\u043a 2<\/h2>\n<h2>The Pipeline. \u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441\u00a0<em>OpenGL<\/em>, \u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0437\u043d\u0430\u0435\u0442\u0435 \u043f\u0440\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u044b. \u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u044b) \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.<\/p>\n<p>\u0428\u0435\u0439\u0434\u0435\u0440 &#8212; \u044d\u0442\u043e \u043c\u0438\u043d\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0435. \u0412\u044b\u0434\u0435\u043b\u044f\u044e\u0442 \u0442\u0440\u0438 \u0442\u0438\u043f\u0430 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432: \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439, \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439. \u0415\u0441\u0442\u044c \u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u044b, \u043d\u043e \u0438\u0445 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0443\u0440\u043e\u043a\u0435.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4f1\/846\/0ad\/4f18460ad799432d1a33f5e108899b83.png\" width=\"464\" height=\"234\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4f1\/846\/0ad\/4f18460ad799432d1a33f5e108899b83.png\"\/><figcaption><\/figcaption><\/figure>\n<p>Vertex (\u0432\u0435\u0440\u0448\u0438\u043d\u0430) \u2014 \u044d\u0442\u043e \u0442\u043e\u0447\u043a\u0430 \u0432 3D \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 (\u0438\u043b\u0438 2D). \u0412\u0435\u0440\u0448\u0438\u043d\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e 3 \u0438\u043b\u0438 2, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044f \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u0438\u043b\u0438 \u043e\u0442\u0440\u0435\u0437\u043a\u0438. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043b\u044e\u0431\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043a\u0443\u0431\u0430 \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c.<\/p>\n<p>\u0412\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0434\u0432\u0438\u0433 \u0438\u043b\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u043e\u00a0<em>\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b<\/em>. \u041a\u0430\u0436\u0434\u044b\u0439 \u043f\u0438\u043a\u0441\u0435\u043b\u044c \u0432 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0438\u043c\u0435\u0435\u0442\u00a0<em>\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442<\/em>, \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<h3>WGSL<\/h3>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f\u0437\u044b\u043a\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432: GLSL, HLSL, MSL, SPIR-V, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u00a0<em>OpenGL<\/em>,\u00a0<em>DirectX<\/em>,\u00a0<em>Metal<\/em>,\u00a0<em>Vulkan<\/em>. \u041d\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435\u00a0<em>WebGPU<\/em>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a\u00a0<s>\u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043c\u0438 \u0432\u0441\u0435\u043c\u0438<\/s>\u00a0\u0434\u043b\u044f \u0443\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.\u00a0<em>WGSL<\/em>\u00a0\u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e \u0432\u0441\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440!<\/p>\n<pre><code>\/\/ \u0412\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440  struct VertexOutput {     @builtin(position) clip_position: vec4&lt;f32>,            \/\/ 1 };  @vertex                                                     \/\/ 2 fn vs_main(     @builtin(vertex_index) in_vertex_index: u32,            \/\/ 3 ) -> VertexOutput {     var out: VertexOutput;                                  \/\/ 4     let x = f32(1 - i32(in_vertex_index)) * 0.5;            \/\/ 5     let y = f32(i32(in_vertex_index &amp; 1u) * 2 - 1) * 0.5;     out.clip_position = vec4&lt;f32>(x, y, 0.0, 1.0);          \/\/ 6     return out;              }<\/code><\/pre>\n<p>\u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 rust, \u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435?<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u00a0<code>VertexOutput<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u0430. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0435\u00a0<code>clip_position<\/code>, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u043e\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439\u00a0<code>@builtin(position)<\/code>. \u0422\u043a \u0448\u0435\u0439\u0434\u0435\u0440 \u0438\u043c\u0435\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b (\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f), \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u044f\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u043a\u043e\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u0435 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435\u00a0<code>VertexOutput<\/code>\u00a0\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b (position), \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438. \u0412\u00a0<em>OpenGL<\/em>\u00a0\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f\u00a0<code>gl_Position<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432\u00a0<em>WGSL<\/em>\u00a0\u043f\u043e\u043c\u0435\u0447\u0435\u043d\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439\u00a0<code>@vertex<\/code>. \u0412\u00a0<em>WGSL<\/em>\u00a0\u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u043c \u043f\u043b\u044e\u0441\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u00a0<code>in_vertex_index<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438\u00a0<code>pipeline<\/code>. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u00a0<code>@builtin(vertex_index)<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u0445 \u0447\u0430\u0449\u0435 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0445 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u00a0<code>in_vertex_index<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441 \u0442\u0438\u043f\u043e\u043c\u00a0<code>VertexOutput<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u00a0<code>x<\/code>\u00a0\u0438\u00a0<code>y<\/code>\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u00a0<code>f32<\/code>\u00a0&amp;\u00a0<code>i32<\/code>, \u043e\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442 \u0440\u043e\u043b\u044c \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f (cast) \u0442\u0438\u043f\u043e\u0432. \u0422\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u0440\u0430\u0441\u0442\u0435, \u0432\u00a0<em>WGSL<\/em>\u00a0\u0435\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439\u00a0<code>var<\/code>\u00a0\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435\u00a0<code>let<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b, \u0437\u0430\u0434\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00a0<code>out.clip_position<\/code>\u00a0\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u00a0<code>out<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0434\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0431\u0435\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b\u00a0<code>VertexOutput<\/code>:<\/p>\n<pre><code>@vertex fn vs_main(     @builtin(vertex_index) in_vertex_index: u32 ) -> @builtin(position) vec4&lt;f32> {     \/\/ ... }<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u044d\u0442\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0442\u043a \u043f\u043e\u0437\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u0442\u0443\u0434\u0430 \u0435\u0449\u0435 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<h4>\u0424\u0440\u0430\u0433\u043c\u0435\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440<\/h4>\n<pre><code>@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4&lt;f32> {     return vec4&lt;f32>(0.3, 0.2, 0.1, 1.0); }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0435\u0440\u0448\u0438\u043d (\u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432) \u0432 \u043a\u043e\u0440\u0438\u0447\u043d\u0435\u0432\u044b\u0439. \u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441\u00a0<code>VertexOutput<\/code>,\u00a0<code>@location(0)<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430, \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u043b\u0435\u00a0<code>position<\/code>, \u0430 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b. \u041f\u043e\u0437\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.<\/p>\n<h3>\u041d\u043e\u0432\u044b\u0439 State<\/h3>\n<p>\u041d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u00a0<code>State<\/code>!<br \/>\u0414\u043e\u0431\u0430\u0432\u0438\u043c\u00a0<code>pipeline<\/code>:<\/p>\n<pre><code class=\"rust\">pub struct State {     surface: wgpu::Surface,     device: wgpu::Device,     queue: wgpu::Queue,     mouse_x: Option&lt;f64>,     mouse_y: Option&lt;f64>,     config: wgpu::SurfaceConfiguration,     pub(crate) size: winit::dpi::PhysicalSize&lt;u32>,     \/\/ NEW!     render_pipeline: wgpu::RenderPipeline, }<\/code><\/pre>\n<h2><\/h2>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043c\u0435\u0442\u043e\u0434\u0443\u00a0<code>State::new<\/code>:<\/p>\n<pre><code class=\"rust\">let shader = device.create_shader_module(wgpu::include_wgsl!(\"shader.wgsl\"));<\/code><\/pre>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441\u00a0<code>include_wgsl!<\/code>\u00a0\u0447\u0438\u0442\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u0432\u00a0<code>ShaderModuleDescriptor<\/code>.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c\u00a0<code>render_layout<\/code>:<\/p>\n<pre><code class=\"rust\">let render_pipeline_layout =     device.create_pipeline_layout(&amp;wgpu::PipelineLayoutDescriptor {         label: Some(\"Render Pipeline Layout\"),         bind_group_layouts: &amp;[],         push_constant_ranges: &amp;[],     });<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0433\u043e, \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438\u00a0<code>bind_group_layouts<\/code>.<\/p>\n<h2><\/h2>\n<pre><code class=\"rust\">let render_pipeline = device.create_render_pipeline(&amp;wgpu::RenderPipelineDescriptor {     label: Some(\"Render Pipeline\"),     layout: Some(&amp;render_pipeline_layout),     vertex: wgpu::VertexState {                      \/\/ 1         module: &amp;shader,         entry_point: \"vs_main\",                      \/\/ 2.         buffers: &amp;[],                                \/\/ 3.     },     fragment: Some(wgpu::FragmentState {             \/\/ 4.         module: &amp;shader,         entry_point: \"fs_main\",                      \/\/ 5         targets: &amp;[Some(wgpu::ColorTargetState {     \/\/ 6.             format: config.format,             blend: Some(wgpu::BlendState::REPLACE),             write_mask: wgpu::ColorWrites::ALL,         })],     }),     \/\/ ...<\/code><\/pre>\n<p>\u0420\u0430\u043d\u0435\u0435 \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0447\u0442\u043e\u00a0<em>WGSL<\/em>\u00a0\u0443\u043c\u0435\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0418\u043c\u0435\u043d\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0445 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0435\u0449\u0435 \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u0411\u0443\u0444\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440. \u041e\u0431\u044b\u0447\u043d\u043e, \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u044c\u0441\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0435 (<code>x<\/code>\u00a0\u0438\u00a0<code>y<\/code>), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0444\u0435\u0440 \u043f\u0443\u0441\u0442\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p><code>ColorTargetState<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a\u043e\u0439 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0431\u0435\u0440\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u00a0<code>surface<\/code>.\u00a0<code>ColorWrites::ALL<\/code>\u00a0\u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0446\u0432\u0435\u0442\u0430: \u043a\u0440\u0430\u0441\u043d\u044b\u0439, \u0441\u0438\u043d\u0438\u0439, \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0438 \u0430\u043b\u044c\u0444\u0430 \u043a\u0430\u043d\u0430\u043b.\u00a0<code>BlendState::REPLACE<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0441\u043c\u0435\u0448\u0435\u0432\u0430\u043d\u0438\u0438, \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0446\u0432\u0435\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439.<\/p>\n<\/li>\n<\/ol>\n<h2><\/h2>\n<pre><code class=\"rust\">    \/\/ ...     primitive: wgpu::PrimitiveState {         topology: wgpu::PrimitiveTopology::TriangleList, \/\/ 1.         strip_index_format: None,         front_face: wgpu::FrontFace::Ccw,                \/\/ 2.         cull_mode: Some(wgpu::Face::Back),         polygon_mode: wgpu::PolygonMode::Fill,         unclipped_depth: false,         conservative: false,     },     \/\/ ...<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u043a\u0430\u043a \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0438\u0437 \u0432\u0435\u0440\u0448\u0438\u043d \u0432 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438.<\/p>\n<h2><\/h2>\n<pre><code class=\"rust\">    depth_stencil: None,                      \/\/ 1.     multisample: wgpu::MultisampleState {         count: 1,                             \/\/ 2.         mask: !0,                             \/\/ 3.         alpha_to_coverage_enabled: false,     \/\/ 4.     },     multiview: None, \/\/ 5. });<\/code><\/pre>\n<ol>\n<li>\n<p>\u041f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>depth_stencil<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412\u0435\u043b\u0438\u0447\u0438\u043d\u0430 \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u044b. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00a0<code>!0<\/code>\u00a0\u0437\u043d\u0430\u0447\u0438\u0442 &#171;\u0432\u0441\u0435&#187;. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0439\u0442\u0435\u00a0<a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9C%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B2%D1%8B%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D1%81%D0%B3%D0%BB%D0%B0%D0%B6%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a><\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p>\u042d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0442\u0435\u043a\u0441\u0442\u0443\u0440, \u043d\u0435 \u043d\u0430\u0448 \u0441\u043b\u0443\u0447\u0430\u0439<\/p>\n<\/li>\n<\/ol>\n<h2><\/h2>\n<pre><code class=\"rust\">Self {     surface,     device,     queue,     config,     size,     \/\/ NEW!     render_pipeline, }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d!<\/p>\n<h3>Render<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u0439 \u0438 \u0432 \u043d\u0435\u043c \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c!<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::render<\/code>:<\/p>\n<pre><code><\/code><\/pre>\n<ol>\n<li>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430\u00a0<code>begin_render_pass<\/code>\u00a0\u0432\u00a0<code>render_pass<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c\u00a0<code>render_pass<\/code>\u00a0\u0438\u00a0<code>render_pipeline<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u044f \u043e\u0431\u0440\u0430\u043c\u0438\u043b \u043a\u043e\u0434 \u0432 \u0435\u0449\u0435 \u043e\u0434\u043d\u0438 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0432\u0443\u0445 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u0441\u0441\u044b\u043b\u043e\u043a \u0432 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u0411\u0435\u0437 \u043d\u0438\u0445 \u043a\u043e\u0434 \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0414\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a:\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eaf\/47c\/32f\/eaf47c32f73d8ab3e8eb82da247c5d8f.png\" width=\"1008\" height=\"796\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eaf\/47c\/32f\/eaf47c32f73d8ab3e8eb82da247c5d8f.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0446\u0432\u0435\u0442 \u0432\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u043e\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u0435 \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u0435 (<code>VertexOutput<\/code>). \u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430\u043c\u0438 \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 space.<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/abritov\/rust-wgpu-tutorial\/tree\/master\/lesson2\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434<\/a> \u0443\u0440\u043e\u043a\u0430<\/p>\n<h2>\u0423\u0440\u043e\u043a 3<\/h2>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0435\u0440\u0448\u0438\u043d \u0432 GPU<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0443\u0440\u043e\u043a\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u043c \u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u043c \u0431\u0443\u0444\u0435\u0440\u043e\u043c.<\/p>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0431\u0443\u0444\u0435\u0440?<\/h4>\n<p>\u041f\u043e\u0434 \u0431\u0443\u0444\u0435\u0440\u043e\u043c \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0443 \u043b\u044e\u0431\u043e\u0439\u00a0<strong>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439<\/strong>\u00a0\u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0438\u043f\u00a0<em>Vec<\/em>\u00a0\u0432 \u0440\u0430\u0441\u0442\u0435. \u041e\u0431\u044b\u0447\u043d\u043e \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0442\u0430\u043c \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (\u0433\u0440\u0430\u0444, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440), \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043f\u043b\u043e\u0441\u043a\u0443\u044e (\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e) \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0444\u0435\u0440\u044b. \u041d\u0430\u0447\u043d\u0435\u043c \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430.<\/p>\n<h3>\u0412\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440<\/h3>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0443\u0440\u043e\u043a\u0435 \u043c\u044b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u043f\u0440\u044f\u043c\u043e \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u043e\u0448\u043b\u0438\u0441\u044c \u0431\u0435\u0437 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u043b\u0443\u0447\u0448\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0442\u043a \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0435\u0440\u0448\u0438\u043d \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u0448\u0435\u0439\u0434\u0435\u0440.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432 \u0444\u0430\u0439\u043b\u0435\u00a0<code>state<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0448\u0438\u043d\u044b:<\/p>\n<pre><code class=\"rust\">#[repr(C)] #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] struct Vertex {     position: [f32; 3],     color: [f32; 3], }<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0432 \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445, \u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (x, y, z) \u0438 \u0446\u0432\u0435\u0442 (red, green, blue). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e\u00a0<code>#[repr(C)]<\/code>, \u043e\u043d\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437 \u044f\u0437\u044b\u043a\u0430 \u0421. \u0415\u0441\u043b\u0438 \u0435\u0435 \u0443\u0431\u0440\u0430\u0442\u044c, \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u0440\u0443\u0434\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432\u0441\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432\u00a0<em>GPU<\/em>, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b\u00a0<code>#[repr(C)]<\/code>.<\/p>\n<p>\u0415\u0449\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u00a0<code>bytemuck<\/code>\u00a0\u0432\u00a0<code>Cargo.toml<\/code>:<\/p>\n<pre><code>bytemuck = { version = \"1.4\", features = [\"derive\"] }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u044b:<\/p>\n<pre><code class=\"rust\">const VERTICES: &amp;[Vertex] = &amp;[     Vertex { position: [0.0, 0.5, 0.0], color: [1.0, 0.0, 0.0] },     Vertex { position: [-0.5, -0.5, 0.0], color: [0.0, 1.0, 0.0] },     Vertex { position: [0.5, -0.5, 0.0], color: [0.0, 0.0, 1.0] }, ];<\/code><\/pre>\n<p>\u0412\u0435\u0440\u0448\u0438\u043d\u044b \u0437\u0434\u0435\u0441\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043f\u0440\u043e\u0442\u0438\u0432 \u0447\u0430\u0441\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0438: \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0433\u043e\u043b, \u043d\u0438\u0436\u043d\u0438\u0439 \u043b\u0435\u0432\u044b\u0439 \u0438 \u043f\u0440\u0430\u0432\u044b\u0439 \u043b\u0435\u0432\u044b\u0439. \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0443\u0440\u043e\u043a\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438, \u0447\u0442\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0442\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043b\u0430\u043d\u0435.<\/p>\n<h2><\/h2>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0431\u0443\u0444\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435\u00a0<code>State<\/code>:<\/p>\n<pre><code>struct State {     \/\/ ...     render_pipeline: wgpu::RenderPipeline,      \/\/ NEW!     vertex_buffer: wgpu::Buffer,      \/\/ ... }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0443\u0444\u0435\u0440:<\/p>\n<pre><code>let vertex_buffer = device.create_buffer_init(     &amp;wgpu::util::BufferInitDescriptor {         label: Some(\"Vertex Buffer\"),         contents: bytemuck::cast_slice(VERTICES),         usage: wgpu::BufferUsages::VERTEX,     } );<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443 \u0432\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u00a0<code>create_buffer_init<\/code>, \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0442\u00a0<code>use wgpu::util::DeviceExt<\/code>. \u0414\u043b\u044f\u00a0<code>contents<\/code>\u00a0\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0447\u0435\u0440\u0435\u0437\u00a0<code>bytemuck<\/code>, \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e\u00a0<code>Vertex<\/code>\u00a0\u0431\u044b\u043b \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u00a0<code>bytemuck::Pod<\/code>\u00a0&amp;\u00a0<code>bytemuck::Zeroable<\/code>. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u00a0<code>Pod<\/code>\u00a0\u044d\u0442\u043e \u0430\u0431\u0431\u0440\u0435\u0432\u0438\u0430\u0442\u0443\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;Plain Old Data&#187;, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u00a0<code>&amp;[u8]<\/code>.\u00a0<code>Zeroable<\/code>\u00a0\u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>std::mem::zeroed()<\/code>\u00a0\u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435.<\/p>\n<h2><\/h2>\n<p>\u0418 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c:<\/p>\n<pre><code>Self {     surface,     device,     queue,     config,     size,     render_pipeline,     \/\/ NEW!     vertex_buffer, }<\/code><\/pre>\n<h3>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0431\u0443\u0444\u0435\u0440\u0430 \u0432 GPU<\/h3>\n<p>\u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0431\u0443\u0444\u0435\u0440, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u00a0<code>render_pipeline<\/code>. \u0427\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0<em>\u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443<\/em>\u00a0\u0434\u0430\u043d\u043d\u044b\u0445 (<code>VertexBufferLayout<\/code>), \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432\u00a0<em>GPU<\/em>\u00a0\u0432 \u0441\u044b\u0440\u043e\u043c \u0432\u0438\u0434\u0435, \u0431\u0435\u0437 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438. \u0422\u043e-\u0435\u0441\u0442\u044c, \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u0433\u0434\u0435 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f\u00a0<code>position<\/code>, \u0430 \u0433\u0434\u0435\u00a0<code>color<\/code>.<\/p>\n<p><code>VertexBufferLayout<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (layout) \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0444\u0435\u0440\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<pre><code>impl Vertex {     fn description&lt;'a>() -> wgpu::VertexBufferLayout&lt;'a> {         wgpu::VertexBufferLayout {             array_stride: std::mem::size_of::&lt;Vertex>() as wgpu::BufferAddress,      \/\/ 1             step_mode: wgpu::VertexStepMode::Vertex,                                 \/\/ 2             attributes: &amp;[                                                           \/\/ 3                 wgpu::VertexAttribute {                     offset: 0,                                                       \/\/ 4                     shader_location: 0,                                              \/\/ 5                     format: wgpu::VertexFormat::Float32x3,                           \/\/ 6                 },                 wgpu::VertexAttribute {                     offset: std::mem::size_of::&lt;[f32; 3]>() as wgpu::BufferAddress,                     shader_location: 1,                     format: wgpu::VertexFormat::Float32x3,                 }             ]         }     } }<\/code><\/pre>\n<ol>\n<li>\n<p><code>array_stride<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b\u00a0<code>Vertex<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435\u043c. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 24 \u0431\u0430\u0439\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>step_mode<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438. \u041f\u043e\u043c\u043d\u0438\u0442\u0435 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0432 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u0435\u00a0<code>@builtin(vertex_index) in_vertex_index: u32<\/code>? \u041e\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u00a0<code>VertexStepMode<\/code>\u00a0\u0437\u0430\u0432\u0438\u0441\u0438\u0442, \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440.\u00a0<code>Vertex<\/code>\u00a0\u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043a\u0440\u043e\u043c\u0435 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435\u00a0<code>Instance<\/code>, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p><code>attributes<\/code>\u00a0\u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b\u00a0<code>Vertex<\/code>. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0430 \u043f\u043e\u043b\u044f: \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u0446\u0432\u0435\u0442. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432\u00a0<code>atrributes<\/code>\u00a0\u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0432\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0438 \u0446\u0432\u0435\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>offset<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u00a0<code>array_stride<\/code>\u00a0\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435\u00a0<code>Vertex<\/code>. \u041f\u0435\u0440\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u2014\u00a0<code>position<\/code>\u00a0\u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 0 (\u0442\u043a \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442). \u0414\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u043d\u0443\u043b\u044e \u0440\u0430\u0437\u043c\u0435\u0440\u00a0<code>position<\/code>, \u0442\u043e-\u0435\u0441\u0442\u044c\u00a0<code>std::mem::sizeof::&lt;[f32; 3]>()<\/code>\u00a0\u0438\u043b\u0438 4 * 3 = 12 \u0431\u0430\u0439\u0442.<\/p>\n<\/li>\n<li>\n<p><code>shader_location<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0434\u043b\u044f\u00a0<code>location<\/code>, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043f\u043e\u043b\u044e\u00a0<code>position<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u00a0<code>@location(0) position: vec3&lt;f32><\/code>.<\/p>\n<\/li>\n<li>\n<p><code>format<\/code>\u00a0\u0437\u0430\u0434\u0430\u0435\u0442 \u0442\u0438\u043f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 (\u043f\u043e\u043b\u044f) \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435,\u00a0<code>positon<\/code>\u00a0\u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f\u00a0<code>[f32; 3]<\/code>, \u0435\u043c\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0432\u0443\u0435\u0442 \u0442\u0438\u043f\u00a0<code>vec3&lt;f32><\/code>\u00a0\u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0435, \u0430 \u0432 \u043f\u043e\u043b\u0435\u00a0<code>format<\/code>\u00a0\u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u00a0<code>VertexFormat::Float32x3<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 (\u0432\u0437\u044f\u043b \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0438\u0437 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438):\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40f\/95d\/38c\/40f95d38c146a6a3dd9def744e648f28.png\" width=\"1234\" height=\"532\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/40f\/95d\/38c\/40f95d38c146a6a3dd9def744e648f28.png\"\/><figcaption><\/figcaption><\/figure>\n<h2><\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0434\u0430\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0432\u00a0<code>render_pipeline<\/code>:<\/p>\n<pre><code>let render_pipeline = device.create_render_pipeline(&amp;wgpu::RenderPipelineDescriptor {     \/\/ ...     vertex: wgpu::VertexState {         \/\/ ...         buffers: &amp;[             Vertex::description(),         ],     },     \/\/ ... });<\/code><\/pre>\n<p>\u0418 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0431\u0443\u0444\u0435\u0440 \u0432\u00a0<code>render_pass<\/code>:<\/p>\n<pre><code>render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));<\/code><\/pre>\n<p><code>set_vertex_buffer<\/code>\u00a0\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u043f\u0435\u0440\u0432\u044b\u0439 \u2014 \u044d\u0442\u043e \u0441\u043b\u043e\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043f\u0430\u0434\u0435\u0442 \u0431\u0443\u0444\u0435\u0440, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0430\u043c \u0431\u0443\u0444\u0435\u0440. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0440\u0446\u0438\u043e\u043d\u043d\u043e, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e \u0432\u0435\u0441\u044c \u0431\u0443\u0444\u0435\u0440.<\/p>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u0440\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432\u044b\u0437\u044b\u0432\u0430\u044e<\/p>\n<pre><code>render_pass.draw(0..3, 0..1);<\/code><\/pre>\n<p>\u041d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u0438, \u0437\u0434\u0435\u0441\u044c \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430:<\/p>\n<pre><code>render_pass.draw(0..VERTICES.len() as u32, 0..1);<\/code><\/pre>\n<h2><\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0448\u0435\u0439\u0434\u0435\u0440\u044b:<\/p>\n<pre><code>\/\/ \u0412\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440  struct VertexInput {     @location(0) position: vec3&lt;f32>,     @location(1) color: vec3&lt;f32>, };  struct VertexOutput {     @builtin(position) clip_position: vec4&lt;f32>,     @location(0) color: vec3&lt;f32>, };  @vertex fn vs_main(     model: VertexInput, ) -> VertexOutput {     var out: VertexOutput;     out.color = model.color;     out.clip_position = vec4&lt;f32>(model.position, 1.0);     return out; }  \/\/ \u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440  @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4&lt;f32> {     return vec4&lt;f32>(in.color, 1.0); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0433\u043e\u0442\u043e\u0432\u043e:\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6ad\/cf3\/a72\/6adcf3a72fe558cb65b511f5d419feb1.png\" width=\"1102\" height=\"838\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6ad\/cf3\/a72\/6adcf3a72fe558cb65b511f5d419feb1.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0418\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440<\/h3>\n<p>\u0412 \u043d\u0438\u0445 \u043d\u0435\u0442 \u0441\u0442\u0440\u043e\u0433\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043d\u043e \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u043c \u0431\u0443\u0444\u0435\u0440\u043e\u043c \u043f\u0430\u043c\u044f\u0442\u0438 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0430\u043a\u0443\u044e \u0444\u0438\u0433\u0443\u0440\u0443 (\u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0438\u0437 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438):\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2af\/d96\/515\/2afd965150cb5fe55ab491a922b46921.png\" width=\"1184\" height=\"1106\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2af\/d96\/515\/2afd965150cb5fe55ab491a922b46921.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043d\u0435\u0439 5 \u0432\u0435\u0440\u0448\u0438\u043d \u0438 \u0442\u0440\u0438 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430. \u0412\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"rust\">const VERTICES: &amp;[Vertex] = &amp;[     Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },     \/\/ A     Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },    \/\/ B     Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },      \/\/ E      Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },    \/\/ B     Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },   \/\/ C     Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },      \/\/ E      Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },   \/\/ C     Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },     \/\/ D     Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },      \/\/ E ];<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u044b C \u0438 B \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0442\u0441\u044f \u0434\u0432\u0430\u0436\u0434\u044b, \u0430 E \u0442\u0440\u0438\u0436\u0434\u044b. \u0415\u0441\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0432 24 \u0431\u0430\u0439\u0442\u0430, \u0442\u043e \u0438\u0437 216 \u0431\u0430\u0439\u0442, 96 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f. \u0411\u044b\u043b\u043e \u0431\u044b \u0437\u0434\u043e\u0440\u043e\u0432\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0438\u0437 \u0432\u0435\u0440\u0448\u0438\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437?<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440!<\/p>\n<pre><code class=\"rust\">const VERTICES: &amp;[Vertex] = &amp;[     Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },     \/\/ A     Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },    \/\/ B     Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },   \/\/ C     Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },     \/\/ D     Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },      \/\/ E ];  const INDICES: &amp;[u16] = &amp;[     0, 1, 4,    \/\/ \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a A, B, E     1, 2, 4,    \/\/ \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a B, C, E     2, 3, 4,    \/\/ \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a C, D, E ];<\/code><\/pre>\n<p>\u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438\u00a0<code>VERTICES<\/code>\u00a0\u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e 120 \u0431\u0430\u0439\u0442, \u0430\u00a0<code>INDICES<\/code>\u00a018 \u0431\u0430\u0439\u0442 + 2 \u043d\u0430 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435. \u041c\u044b \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u043b\u0438 76 \u0431\u0430\u0439\u0442! \u042d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043c\u0430\u043b\u043e, \u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0444\u0438\u0433\u0443\u0440 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u043e\u043a, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440.<\/p>\n<pre><code>struct State {     surface: wgpu::Surface,     device: wgpu::Device,     queue: wgpu::Queue,     config: wgpu::SurfaceConfiguration,     size: winit::dpi::PhysicalSize&lt;u32>,     render_pipeline: wgpu::RenderPipeline,     vertex_buffer: wgpu::Buffer,     \/\/ NEW!     index_buffer: wgpu::Buffer, \/\/ \u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0441\u044e\u0434\u0430     num_indices: u32, }<\/code><\/pre>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<code>State::new<\/code>:<\/p>\n<pre><code class=\"rust\">let index_buffer = device.create_buffer_init(     &amp;wgpu::util::BufferInitDescriptor {         label: Some(\"Index Buffer\"),         contents: bytemuck::cast_slice(INDICES),         usage: wgpu::BufferUsages::INDEX,     } ); let num_indices = INDICES.len() as u32;<\/code><\/pre>\n<p>\u0415\u0449\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e\u00a0<code>num_indices<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432\u00a0<code>State<\/code>:<\/p>\n<pre><code>Self {     surface,     device,     queue,     config,     size,     render_pipeline,     vertex_buffer,     \/\/ NEW!     index_buffer,     num_indices, }<\/code><\/pre>\n<h2><\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::render<\/code>:<\/p>\n<pre><code class=\"rust\">\/\/ render() render_pass.set_pipeline(&amp;self.render_pipeline); render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); \/\/ 1 render_pass.draw_indexed(0..self.num_indices, 0, 0..1);                               \/\/ 2<\/code><\/pre>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u0415\u0434\u0438\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440, \u043e \u0447\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430\u00a0<code>set_index_buffer<\/code><\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440, \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u00a0<code>draw_indexed<\/code>. \u0422\u0430\u043a\u0436\u0435 \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435, \u0447\u0442\u043e\u00a0<code>self.num_indices<\/code>\u00a0\u0440\u0430\u0432\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435, \u043d\u043e \u043d\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0432\u0435\u0440\u0448\u0438\u043d. \u041e\u0448\u0438\u0431\u043a\u0438 \u0432 \u044d\u0442\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443\u0442 \u043a \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u0438\u043b\u0438 \u044d\u043a\u0441\u0442\u0440\u0435\u043d\u043d\u043e\u043c\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430<\/p>\n<\/li>\n<\/ol>\n<h2><\/h2>\n<p>\u0412\u043e\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:\u00a0<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8d8\/455\/aeb\/8d8455aeb45f6409266eb41316777ba2.png\" width=\"1120\" height=\"874\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8d8\/455\/aeb\/8d8455aeb45f6409266eb41316777ba2.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>\u0426\u0432\u0435\u0442\u043e\u0432\u0430\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0446\u0438\u044f<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u0435 \u0446\u0432\u0435\u0442 \u043f\u0435\u043d\u0442\u0430\u0433\u043e\u043d\u0430, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 #BC00BC. \u0421\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 RGB \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c (188, 0, 188). \u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 255, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0446\u0432\u0435\u0442 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435\u00a0<code>[0, 1]<\/code>, \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (0.737254902, 0, 0.737254902), \u0432\u043c\u0435\u0441\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e (0.5, 0.0, 0.5).<\/p>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0430\u043f\u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0430\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 \u043f\u043e \u0444\u043e\u0440\u043c\u0443\u043b\u0435\u00a0<code>srgb_color = (rgb_color \/ 255) ^ 2.2<\/code>. \u0414\u043b\u044f \u0446\u0432\u0435\u0442\u0430 (188, 0, 188) \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (0.511397819, 0.0, 0.511397819), \u0447\u0442\u043e \u0443\u0436\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043b\u0438\u0436\u0435 \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u0442\u043a \u0432 \u043d\u0438\u0445 \u0446\u0432\u0435\u0442\u0430 \u0443\u0436\u0435 \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435.<\/p>\n<h3>\u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h3>\n<p>\u041d\u0430\u0440\u0438\u0441\u0443\u0439\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0444\u0438\u0433\u0443\u0440\u0443, \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440. \u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0441\u043c\u0435\u043d\u0443 \u0444\u0438\u0433\u0443\u0440 \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435 space.<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/abritov\/rust-wgpu-tutorial\/tree\/master\/lesson3\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434<\/a> \u0443\u0440\u043e\u043a\u0430<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439 \u043d\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430\u043c\u0438, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/690514\/\"> https:\/\/habr.com\/ru\/post\/690514\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0421\u0430\u0448\u0430 \u0438 \u044f backend \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041d\u0435\u0442, \u043d\u0435 \u043d\u0430 rust. \u041d\u043e \u0440\u0430\u0441\u0442 \u043c\u043e\u0439 \u043b\u044e\u0431\u0438\u043c\u044b\u0439 \u044f\u0437\u044b\u043a \u0438 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0437\u0430\u0434\u0430\u043b\u0441\u044f \u0446\u0435\u043b\u044c\u044e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u043e\u043a \u043e\u043d\u043b\u0430\u0439\u043d \u0438\u0433\u0440\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 C++. \u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0441\u044f\u0446 \u0443\u0448\u0435\u043b \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c\u0438 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438, \u0438\u0445 \u0447\u0442\u0435\u043d\u0438\u0435\u043c \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u041d\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c, \u0430 \u043e <em>WGPU<\/em>.<\/p>\n<h2>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 WGPU?<\/h2>\n<p><a href=\"https:\/\/github.com\/gfx-rs\/wgpu\" rel=\"noopener noreferrer nofollow\">WGPU<\/a> \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 <em>WebGPU<\/em> \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 <em>rust<\/em>, \u0446\u0435\u043b\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0432\u0438\u0434\u0435\u043e \u043a\u0430\u0440\u0442\u044b \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 (\u0437\u0430\u043c\u0435\u043d\u0430 <em>webgl<\/em>).\u0412\u043e \u043c\u043d\u043e\u0433\u043e\u043c, API \u043f\u0435\u0440\u0435\u043a\u043b\u0438\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0430\u043a\u043e\u0432\u044b\u043c \u0443 Vulkan API, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c <em>\u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438<\/em> \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 backend-\u044b (<em>DirectX<\/em>, <em>Metal<\/em>, <em>Vulkan, OpenGL<\/em>).<\/p>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u043c\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 3D \u0441\u0446\u0435\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u0443\u0440\u043e\u043a\u043e\u0432 \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0435. \u0412\u043e \u043c\u043d\u043e\u0433\u043e\u043c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e <a href=\"https:\/\/sotrh.github.io\/learn-wgpu\/#what-is-wgpu\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430<\/a> \u043f\u043e <em>wgpu<\/em> + \u043c\u043e\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438.<\/p>\n<h2>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c!<\/h2>\n<p>\u042f \u043f\u043e\u0434\u0435\u043b\u0438\u043b \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u0443\u0440\u043e\u043a\u0438 \u0438 \u043f\u0435\u0440\u0432\u044b\u043c \u0438\u0437 \u043d\u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u0443\u0440\u043e\u043a \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043e\u043a\u043d\u0430. \u0422\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043b 3 \u0443\u0440\u043e\u043a\u0430.<\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043b\u044e\u0431\u0430\u044f \u0438\u0433\u0440\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u043a\u043d\u0430, \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u043d\u0435\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u044b.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>cargo<\/em>:<\/p>\n<pre><code>cargo new rust_wgpu_tutorial --bin<\/code><\/pre>\n<p>\u042f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>[dependencies] winit = \"0.26\" env_logger = \"0.9\" log = \"0.4\" wgpu = \"0.13\"<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c \u043a\u043e\u0434:<\/p>\n<pre><code class=\"rust\">use winit::{     event::*,     event_loop::{ControlFlow, EventLoop},     window::WindowBuilder, };  fn main() {     env_logger::init();     let event_loop = EventLoop::new();     let window = WindowBuilder::new().build(&amp;event_loop).unwrap();      event_loop.run(move |event, _, control_flow| match event {         Event::WindowEvent {             ref event,             window_id,         } if window_id == window.id() => match event {             WindowEvent::CloseRequested | WindowEvent::KeyboardInput {                 input:                 KeyboardInput {                     state: ElementState::Pressed,                     virtual_keycode: Some(VirtualKeyCode::Escape),                     ..                 },                 ..             } => *control_flow = ControlFlow::Exit,             _ => {}         },         _ => {}     }); }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0435\u0449\u0435 \u043b\u043e\u0433\u0433\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043e\u0448\u0438\u0431\u043e\u043a <em>wgpu<\/em>, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0443\u0442. \u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u0440\u0430\u0441\u0442\u043e\u043c, \u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u0440\u043e\u043c\u0435 \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 <code>match<\/code>. \u0422\u0430\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 <code>event_loop<\/code>, \u043e\u0442\u0431\u0435\u0440\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043e\u043a\u043d\u0443. \u0415\u0441\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>WindowEvent::CloseRequested<\/code>, \u043b\u0438\u0431\u043e <code>WindowEvent::KeyboardInput<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>KeyboardInput<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 <code>virtual_keycode<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0432\u043d\u043e <code>Some(VirtualKeyCode::Escape)<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>ControlFlow::Exit<\/code> (\u0437\u0430\u043a\u0440\u043e\u0439 \u043e\u043a\u043d\u043e). \u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 pattern-matching \u0432 <em>haskell<\/em>. \u0412\u043e\u0442 \u0437\u0430 \u0447\u0442\u043e \u044f \u043b\u044e\u0431\u043b\u044e <em>rust<\/em>.<\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u043e\u043a\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f! \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0444\u0430\u0439\u043b <code>state.rs<\/code> \u0432 \u043f\u0430\u043f\u043a\u0443 <code>src<\/code>, \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<pre><code class=\"rust\">use winit::window::Window; use winit::{     event::*, };  pub struct State {     surface: wgpu::Surface,     device: wgpu::Device,     queue: wgpu::Queue,     config: wgpu::SurfaceConfiguration,     size: winit::dpi::PhysicalSize&lt;u32>, }  impl State {     pub async fn new(window: &amp;Window) -> Self {         todo!()     }      pub fn resize(&amp;mut self, new_size: winit::dpi::PhysicalSize&lt;u32>) {         todo!()     }      pub fn input(&amp;mut self, event: &amp;WindowEvent) -> bool {         todo!()     }      pub fn update(&amp;mut self) {         todo!()     }      pub fn render(&amp;mut self) -> Result&lt;(), wgpu::SurfaceError> {         todo!()     } }<\/code><\/pre>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441 \u043c\u0435\u0442\u043e\u0434\u0430 <code>new<\/code>:<\/p>\n<pre><code class=\"rust\">async fn new(window: &amp;Window) -> Self {     let size = window.inner_size();      \/\/ instance - \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 wgpu     \/\/ Backends::all => OpenGL + Vulkan + Metal + DX12 + Browser WebGPU     let instance = wgpu::Instance::new(wgpu::Backends::all());     let surface = unsafe { instance.create_surface(window) };     let adapter = instance.request_adapter(         &amp;wgpu::RequestAdapterOptions {             power_preference: wgpu::PowerPreference::LowPower,             compatible_surface: Some(&amp;surface),             force_fallback_adapter: false,         },     ).await.unwrap(); }<\/code><\/pre>\n<h4>Instance \u0438 Adapter<\/h4>\n<p>\u0414\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b\u00a0\u0441\u00a0\u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u043e\u0439\u00a0\u043d\u0430\u043c\u00a0\u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>Adapter<\/code>\u00a0\u0438\u00a0<code>Surface<\/code>,\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u0435\u00a0\u043c\u043e\u0436\u043d\u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0\u0447\u0435\u0440\u0435\u0437\u00a0\u043c\u0435\u0442\u043e\u0434\u044b\u00a0<code>instance<\/code>.\u00a0\u041c\u043d\u0435\u00a0\u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f,\u00a0\u0447\u0442\u043e\u00a0\u043f\u0440\u0435\u0436\u0434\u0435\u00a0\u0447\u0435\u043c\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c\u00a0\u0441\u00a0\u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u043e\u0439,\u00a0\u043d\u0443\u0436\u043d\u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0<code>instance<\/code>,\u00a0\u0430\u00a0\u043d\u0435\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c\u00a0\u0441\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u00a0\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c,\u00a0\u043a\u0430\u043a\u00a0\u044d\u0442\u043e\u00a0\u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f\u00a0\u0432\u00a0<em>OpenGL<\/em>,\u00a0\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<p>\u041f\u0440\u0438\u00a0\u0432\u044b\u0431\u043e\u0440\u0435\u00a0\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430,\u00a0\u043c\u044b\u00a0\u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443\u0435\u043c\u0441\u044f\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438\u00a0\u043e\u043f\u0446\u0438\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>power_preference<\/code>\u00a0\u0432 \u044d\u0442\u043e\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0432\u044b\u0431\u043e\u0440\u0430\u00a0<em>GPU<\/em>. \u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435\u00a0<code>LowPower<\/code>,\u00a0<em>wgpu<\/em>\u00a0\u0432\u044b\u0431\u0435\u0440\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0443.<\/p>\n<\/li>\n<li>\n<p><code>compatible_surface<\/code>\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code>force_fallback_adapter<\/code>\u00a0\u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u0444\u043b\u0430\u0433 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432\u00a0<code>true<\/code>,\u00a0<em>wgpu<\/em>\u00a0\u0432\u044b\u0431\u0435\u0440\u0435\u0442 \u0430\u0434\u0430\u043f\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u043e\u043b\u0435\u0439 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0436\u0435\u043b\u0435\u0437\u0435, \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0435<\/p>\n<\/li>\n<\/ul>\n<h4>Surface<\/h4>\n<p><code>Surface<\/code>\u00a0\u044d\u0442\u043e\u00a0\u043e\u0431\u043b\u0430\u0441\u0442\u044c\u00a0\u043e\u043a\u043d\u0430\u00a0(\u043a\u0430\u043a\u00a0<em>canvas<\/em>\u00a0\u0432\u00a0<em>html<\/em>),\u00a0\u043a\u043e\u0442\u043e\u0440\u0430\u044f\u00a0\u0431\u0443\u0434\u0435\u0442\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u00a0\u0434\u043b\u044f\u00a0\u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.\u00a0\u0427\u0442\u043e\u0431\u044b\u00a0\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<code>surface<\/code>,\u00a0\u043e\u043a\u043d\u043e\u00a0\u0434\u043e\u043b\u0436\u043d\u043e\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>HasRawWindowHandle<\/code>\u00a0\u0438\u0437\u00a0\u043f\u0430\u043a\u0435\u0442\u0430\u00a0<a href=\"https:\/\/crates.io\/crates\/raw-window-handle\" rel=\"noopener noreferrer nofollow\">raw-window-handle<\/a>.\u00a0\u0412\u00a0\u043d\u0430\u0448\u0435\u043c\u00a0\u0441\u043b\u0443\u0447\u0430\u0435,\u00a0<code>winit<\/code>\u00a0\u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442\u00a0\u043f\u043e\u0434\u00a0\u044d\u0442\u0438\u00a0\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>Device &amp; Queue<\/h4>\n<p>\u041a\u0430\u043a\u00a0\u0438\u00a0\u0432\u00a0\u0441\u043b\u0443\u0447\u0430\u0435\u00a0\u0441\u00a0<code>instance<\/code>,\u00a0\u043c\u044b\u00a0\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c\u00a0\u043d\u0435\u00a0\u0441\u00a0\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438\u00a0\u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438,\u00a0\u0430\u00a0\u0441\u0430\u043c\u0438\u00a0\u0441\u043e\u0437\u0434\u0430\u0435\u043c\u00a0\u043d\u0443\u0436\u043d\u044b\u0435\u00a0\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\u00a0\u0427\u0442\u043e\u0431\u044b\u00a0\u0441\u043e\u0437\u0434\u0430\u0442\u044c\u00a0<code>device<\/code>\u00a0\u0438\u00a0<code>queue<\/code>,\u00a0\u044f\u00a0\u0434\u043e\u0431\u0430\u0432\u0438\u043b\u00a0\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u00a0\u043a\u043e\u0434:<\/p>\n<pre><code class=\"rust\">let (device, queue) = adapter.request_device(     &amp;wgpu::DeviceDescriptor {         features: wgpu::Features::empty(),         limits: wgpu::Limits::default(),         label: None,     },     None, \/\/ Trace path ).await.unwrap();<\/code><\/pre>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435\u00a0<code>features<\/code>. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u043e\u0433\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u00a0<code>limits<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u00a0<code>max_vertex_attributes<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>max_vertex_buffer_array_stride<\/code>. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u043d\u043e\u00a0<a href=\"https:\/\/docs.rs\/wgpu\/latest\/wgpu\/struct.Limits.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0441\u043f\u0435\u043a\u0442\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 GPU.<\/p>\n<h2><\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::new<\/code>, \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<pre><code class=\"rust\">let config = wgpu::SurfaceConfiguration {     usage: wgpu::TextureUsages::RENDER_ATTACHMENT,     format: surface.get_supported_formats(&amp;adapter)[0],     width: size.width,     height: size.height,     present_mode: wgpu::PresentMode::Fifo, }; surface.configure(&amp;device, &amp;config); \/\/ \u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 State Self {     surface,     device,     queue,     config,     size }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043d\u0430 \u043f\u043e\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<ul>\n<li>\n<p><code>usage<\/code>\u00a0\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>format<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b\u00a0<code>SurfaceTextures<\/code>. \u0423 \u0440\u0430\u0437\u043d\u044b\u0445 \u0434\u0438\u0441\u043f\u043b\u0435\u0435\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u0432\u043e\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0444\u043e\u0440\u043c\u0430\u0442.<\/p>\n<\/li>\n<li>\n<p><code>present_mode<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u00a0<code>Surface<\/code>\u00a0\u0441 \u044d\u043a\u0440\u0430\u043d\u043e\u043c.\u00a0<code>wgpu::PresentMode::Fifo<\/code>\u00a0\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u00a0<code>VSYNC<\/code>.<\/p>\n<\/li>\n<\/ul>\n<h2><\/h2>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u00a0<code>State<\/code>\u00a0\u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<code>main<\/code>:<\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u043e\u0437\u0434\u0430\u0435\u043c State<\/figcaption><\/figure>\n<p>\u0422\u043a \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::new<\/code>\u00a0\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0430\u043b\u043e, \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f\u00a0<code>.await<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043d\u0443\u0436\u0435\u043d\u00a0<code>Executor<\/code>. \u042f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c\u00a0<code>tokio<\/code>, \u0443\u043a\u0430\u0437\u0430\u0432 \u0435\u0433\u043e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445:\u00a0<\/p>\n<p><code>tokio = { version = \"1\", features = [\"full\"] }<\/code><\/p>\n<p>\u041c\u0435\u0442\u043e\u0434\u00a0<code>main<\/code>\u00a0\u0442\u043e\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c \u0438 \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439:<\/p>\n<p><code>#[tokio::main]<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n<h3>resize<\/h3>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043d\u0430\u0448\u0443 \u0440\u0430\u0431\u043e\u0442\u0443, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>resize<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043e\u043a\u043d\u0430.<\/p>\n<pre><code class=\"rust\">fn resize(&amp;mut self, new_size: winit::dpi::PhysicalSize&lt;u32>) {     if new_size.width > 0 &amp;&amp; new_size.height > 0 {         self.size = new_size;         self.config.width = new_size.width;         self.config.height = new_size.height;         self.surface.configure(&amp;self.device, &amp;self.config);     } }<\/code><\/pre>\n<p><a href=\"http:\/\/main.rs\" rel=\"noopener noreferrer nofollow\">main.rs<\/a>:<\/p>\n<figure class=\"full-width\"><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f Resized &amp; ScaleFactorChanged<\/figcaption><\/figure>\n<p>\u0422\u0430\u043a \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435!<br \/>\u041c\u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u043a\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u00a0<code>Moved<\/code>:<\/p>\n<pre><code class=\"rust\">WindowEvent::Moved(_) => {     window.request_redraw(); }<\/code><\/pre>\n<h3>render<\/h3>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u0446\u0432\u0435\u0442\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>State::render<\/code>.<\/p>\n<pre><code class=\"rust\">let output = self.surface.get_current_texture()?;<\/code><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u00a0<code>SurfaceTexture<\/code>\u00a0(\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u044b\u0448\u0435,\u00a0<em>\u0444\u0440\u0435\u0439\u043c<\/em>), \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0443\u0434\u0430 \u043d\u0430\u0448 \u0444\u043e\u043d.<\/p>\n<pre><code class=\"rust\">let view = output.texture.create_view(&amp;wgpu::TextureViewDescriptor::default());<\/code><\/pre>\n<p><code>create_view<\/code>\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>TextureView<\/code>, \u0442\u043e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c.<\/p>\n<pre><code class=\"rust\">let mut encoder = self.device.create_command_encoder(&amp;wgpu::CommandEncoderDescriptor {     label: Some(\"Render Encoder\"), });<\/code><\/pre>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>CommandEncoder<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u00a0<em>GPU<\/em>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a:<\/p>\n<pre><code class=\"rust\">encoder.begin_render_pass(&amp;wgpu::RenderPassDescriptor {     label: Some(\"Render Pass\"),     color_attachments: &amp;[Some(wgpu::RenderPassColorAttachment {         view: &amp;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: true,         },     })],     depth_stencil_attachment: None, });<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c\u00a0<code>RenderPass<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u044d\u043a\u0440\u0430\u043d\u0430 \u0432 \u0441\u0438\u043d\u0438\u0439 \u0446\u0432\u0435\u0442.<\/p>\n<p>\u041f\u043e\u043b\u0435\u00a0<code>color_attachments.view<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0443\u0434\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 (\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f\u00a0<code>view<\/code>).<\/p>\n<p><code>color_attachments.ops.load<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430. <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u044d\u043a\u0440\u0430\u043d \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443 \u0441\u0438\u043d\u0438\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<h2><\/h2>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435\u00a0<code>render<\/code>:<\/p>\n<pre><code class=\"rust\">self.queue.submit(std::iter::once(encoder.finish())); output.present();  Ok(())<\/code><\/pre>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u00a0<code>RenderPass<\/code>\u00a0\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435, \u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435:<\/p>\n<figure class=\"full-width\"><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 RedrawRequested \u0438 MainEventsCleared<\/figcaption><\/figure>\n<p>\u0412\u043e\u0442, \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f:<\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u0438\u043d\u0435\u0435 \u043e\u043a\u043d\u043e<\/figcaption><\/figure>\n<h4>\u0417\u0430\u0434\u0430\u043d\u0438\u0435<\/h4>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u00a0<code>input<\/code>\u00a0\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u043a\u0438 \u0438 \u043c\u0435\u043d\u044f\u0442\u044c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438. (\u0412\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f\u00a0<code>WindowEvent::CursorMoved<\/code>)<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/abritov\/rust-wgpu-tutorial\/tree\/master\/lesson1\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434<\/a> \u0443\u0440\u043e\u043a\u0430<\/p>\n<h2>\u0423\u0440\u043e\u043a 2<\/h2>\n<h2>The Pipeline. \u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441\u00a0<em>OpenGL<\/em>, \u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0437\u043d\u0430\u0435\u0442\u0435 \u043f\u0440\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u044b. \u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-338963","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338963","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=338963"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338963\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=338963"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=338963"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=338963"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}