{"id":472825,"date":"2025-09-01T09:00:27","date_gmt":"2025-09-01T09:00:27","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=472825"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=472825","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0440\u043e \u0432 2\u043a\u0431 \u043d\u0430 Rust \u0437\u0430 \u0432\u0435\u0447\u0435\u0440<\/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<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435 \u0438\u043d\u0442\u0440\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044f\u0437\u044b\u043a Rust. \u0411\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e Unsafe \u0438 WinAPI \u043a\u043e\u0434\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0445\u043e\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u0441 OpenGL 3.3<\/p>\n<p>\u0412\u043e\u0442 \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435:<strong> <\/strong> <\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e47\/191\/3a3\/e471913a368abd1b7b5160cbd64c43ba.gif\" alt=\"\u0420\u0430\u0437\u043c\u0435\u0440: 1\u00a0661 \u0431\u0430\u0439\u0442\" title=\"\u0420\u0430\u0437\u043c\u0435\u0440: 1\u00a0661 \u0431\u0430\u0439\u0442\" width=\"518\" height=\"518\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e47\/191\/3a3\/e471913a368abd1b7b5160cbd64c43ba.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e47\/191\/3a3\/e471913a368abd1b7b5160cbd64c43ba.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0420\u0430\u0437\u043c\u0435\u0440: 1\u00a0661 \u0431\u0430\u0439\u0442<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/h3>\n<h4>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u041f\u041e:<\/h4>\n<ol>\n<li>\n<p><strong>Nightly-\u0432\u0435\u0440\u0441\u0438\u044f Rust<\/strong>\u00a0(\u0434\u043b\u044f \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 unsafe)<\/p>\n<pre><code>rustup toolchain install nightly<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440<\/strong>\u044b<\/p>\n<pre><code class=\"bash\">rustup target add i686-pc-windows-msvc<\/code><\/pre>\n<\/li>\n<\/ol>\n<ol>\n<li>\n<p><strong>Crinkler<\/strong>\u00a0&#8212; \u043a\u043e\u043c\u043f\u0440\u0435\u0441\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043b\u0438\u043d\u043a\u0435\u0440 \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u0449\u0438\u043a<\/p>\n<ul>\n<li>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0434\u0435\u0441\u044c:\u00a0<a href=\"https:\/\/github.com\/runestubbe\/Crinkler\" rel=\"noopener noreferrer nofollow\">github.com\/runestubbe\/Crinkler<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code class=\"bash\">cargo new --bin 4kb<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443.  <\/p>\n<p>main.rs<\/p>\n<pre><code class=\"rust\">\/\/ \u0421\u0430\u043c\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b #![no_main] \/\/ \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 #![no_std]  \/\/ \u0417\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u0441\u0432\u043e\u0451 #[unsafe(no_mangle)] fn main() -&gt; ! {  }  \/\/ \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u0445  \/*   rust-analyzer \u043c\u043e\u0436\u0435\u0442 \u0440\u0443\u0433\u0430\u0442\u044c\u0441\u044f \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0443:     found duplicate lang item `panic_impl`     the lang item is first defined in crate `std` (which `test` depends on)    \u041d\u043e \u043c\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0430 \u044d\u0442\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 *\/ use core::panic::PanicInfo; #[panic_handler] fn panic(_: &amp;PanicInfo&lt;'_&gt;) -&gt; ! {     loop {} }<\/code><\/pre>\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0441\u0451 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439<\/p>\n<p>build.bat<\/p>\n<pre><code class=\"bash\">del demo.exe del demo.o cargo +nightly rustc -Z build-std=core --target i686-pc-windows-msvc --release -Z build-std-features=panic_immediate_abort --bin 4kb -- --emit obj=\"demo.o\" Crinkler.exe demo.o \/OUT:demo.exe \/SUBSYSTEM:WINDOWS \/ENTRY:main \"\/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22000.0\\um\\x86\" gdi32.lib user32.lib opengl32.lib kernel32.lib winmm.lib demo.exe echo %ErrorLevel%<\/code><\/pre>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443:<\/p>\n<ul>\n<li>\n<p><code>-Z build-std=core<\/code> &#8212; \u0441\u0431\u043e\u0440\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 core \u0432\u0435\u0440\u0441\u0438\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><code>--target i686-pc-window-msvc<\/code> &#8212; \u0441\u0431\u043e\u0440\u043a\u0430 \u043f\u043e\u0434 x86<\/p>\n<\/li>\n<li>\n<p><code>-Z build-std-features=panic_immediate_abort<\/code> &#8212; \u042d\u0442\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u0443\u044e \u043f\u0430\u043d\u0438\u043a\u0443 \u043a\u0430\u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u0437 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e \u043f\u0430\u043d\u0438\u043a\u0435.\u00a0  <\/p>\n<\/li>\n<li>\n<p><code>--emit obj=\"demo.o\"<\/code> &#8212; \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u0441\u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f \u0441 windows lib \u0438 \u043f\u043e\u0442\u043e\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f exe \u0444\u0430\u0439\u043b<\/p>\n<\/li>\n<li>\n<p><code>\/OUT:demo.exe<\/code> &#8212; \u0438\u043c\u044f \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430<\/p>\n<\/li>\n<li>\n<p><code>\/SUBSYSTEM:WINDOWS<\/code> &#8212; \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 Windows \u0438 Console. Windows \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u043e<\/p>\n<\/li>\n<li>\n<p><code>\/ENTRY:main<\/code> &#8212; \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0439 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><code> \"\/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22000.0\\um\\x86\" gdi32.lib user32.lib opengl32.lib kernel32.lib winmm.lib<\/code> &#8212; \u041f\u0443\u0442\u044c \u0434\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 <\/p>\n<\/li>\n<\/ul>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0443 \u043d\u0430\u0441 \u043f\u0443\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442<\/p>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u043c \u043d\u0430\u0448 Cargo.toml, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0443 \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0438 \u0442\u0430\u043a \u0436\u0435 \u0443\u043a\u0430\u0436\u0435\u043c \u0432 release \u0441\u0431\u043e\u0440\u043a\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u0443\u0431\u0440\u0430\u0442\u044c:<\/p>\n<pre><code class=\"yaml\">[dependencies] windows-sys = { version = \"0.52.0\", features = [ \"Win32_Foundation\", \"Win32_System\", \"Win32_System_Threading\", \"Win32_System_Memory\", \"Win32_UI_WindowsAndMessaging\", \"Win32_Graphics_Gdi\", \"Win32_System_LibraryLoader\", \"Win32_Graphics_OpenGL\", \"Win32_Media\", \"Win32_Media_Audio\", \"Win32_Media_Multimedia\",     \"Win32_System_Console\", ]}  [profile.release] # \u0412 \u0441\u043b\u0443\u0447\u0430\u0438 panic \u043f\u0440\u043e\u0441\u0442\u043e \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 panic = \"abort\" # \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c \u0432 release \u0441\u0431\u043e\u0440\u043a\u0435 strip = true # \u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0435\u0434\u0438\u043d\u0438\u0446 codegen \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.  codegen-units = 1 # \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 opt-level = \"z\" <\/code><\/pre>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043e\u043a\u043d\u043e, \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u043e\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434<\/p>\n<p>window.rs<\/p>\n<pre><code class=\"rust\"> use windows_sys::{     Win32::Foundation::*,     Win32::Graphics::{Gdi::*, OpenGL::*},     Win32::System::LibraryLoader::GetModuleHandleA,     Win32::UI::WindowsAndMessaging::*, };  use core::{mem, ptr};  \/\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0442 Windows pub fn handle_message(_window: HWND) -&gt; bool {     let mut msg: mem::MaybeUninit&lt;MSG&gt; = mem::MaybeUninit::uninit();      loop {         unsafe {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0441\u0442\u044c \u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f?             if PeekMessageA(msg.as_mut_ptr(), 0 as HWND, 0, 0, PM_REMOVE) == 0 {                 \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c                 return true;             }              \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c MaybeUninit \u0432 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 MSG             let msg = msg.assume_init();              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434             if msg.message == WM_QUIT {                 \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d \u0441\u0438\u0433\u043d\u0430\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f                 return false;             }              \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u044b (\u0434\u043b\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430)             TranslateMessage(&amp;msg);                          \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u043e\u043a\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438             DispatchMessageA(&amp;msg);         }     } }  \/*   HWND - \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u043a\u043d\u0430   HDC - \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f *\/  #[must_use] pub fn create(width: i32, height: i32) -&gt; (HWND, HDC) {      unsafe {          let instance = GetModuleHandleA(ptr::null());          \/\/ \u0421\u0430\u043c\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043c\u044f \u043e\u043a\u043d\u0443         let window_class = b\"window\\0\";          let wc = WNDCLASSA {             hCursor: LoadCursorW(0, IDC_ARROW),  \/\/ \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 - \u0441\u0442\u0440\u0435\u043b\u043a\u0430             hInstance: instance,                 \/\/ \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b             lpszClassName: window_class.as_ptr(),\/\/ \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430             style: CS_HREDRAW | CS_VREDRAW,      \/\/ \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430             lpfnWndProc: Some(wndproc),          \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439             \/*                 \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0441 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043d\u0438\u0445                 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043a WNDCLASS:                 https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/winuser\/ns-winuser-wndclassa             *\/             cbClsExtra: 0,             cbWndExtra: 0,             hIcon: 0,             hbrBackground: 0,             lpszMenuName: ptr::null(),         };          let _atom = RegisterClassA(&amp;wc);         let title = c\"Pixel\";          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438         let h_wnd = CreateWindowExA(             \/\/ \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 \u043e\u043a\u043d\u0430 (0 - \u0441\u0442\u0438\u043b\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)             0,                          \/\/ \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0438\u043c\u044f \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430             window_class.as_ptr(),                          \/\/ \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u043a\u043d\u0430 (\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 C-\u0441\u0442\u0440\u043e\u043a\u0443)             title.as_ptr() as *const _,              \/\/ \u0421\u0442\u0438\u043b\u0438 \u043e\u043a\u043d\u0430: \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0435\u0441\u044f \u043e\u043a\u043d\u043e + \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u043c\u043e\u0435             WS_OVERLAPPEDWINDOW | WS_VISIBLE,              \/\/ \u041f\u043e\u0437\u0438\u0446\u0438\u044f \u043e\u043a\u043d\u0430: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e             CW_USEDEFAULT,  \/\/ X-\u043f\u043e\u0437\u0438\u0446\u0438\u044f             CW_USEDEFAULT,  \/\/ Y-\u043f\u043e\u0437\u0438\u0446\u0438\u044f              \/\/ \u0420\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u043a\u043d\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445:             width,             height,              \/\/ \u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0435 \u043e\u043a\u043d\u043e (None - \u043d\u0435\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f)             0 as HWND,              \/\/ \u041c\u0435\u043d\u044e (None - \u043d\u0435\u0442 \u043c\u0435\u043d\u044e)             0 as HMENU,              \/\/ \u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f             instance,             \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f (None)             ptr::null(),         );          let h_dc: HDC = GetDC(h_wnd);          let mut pfd: PIXELFORMATDESCRIPTOR = mem::zeroed();         pfd.nSize = mem::size_of::&lt;PIXELFORMATDESCRIPTOR&gt;() as u16;         pfd.nVersion = 1;         \/\/ \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0432 \u044d\u043a\u0440\u0430\u043d, \u043f\u043e\u0434\u0434\u0440\u0435\u0436\u043a\u0430 OpenGL, \u0414\u0432\u043e\u0439\u043d\u0430\u044f \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f         pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;         pfd.iPixelType = PFD_TYPE_RGBA;         \/\/ \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0442 \u043d\u0430 \u0446\u0432\u0435\u0442         pfd.cColorBits = 32;         \/\/ 8 \u0431\u0438\u0442 \u043d\u0430 Alpha \u043a\u0430\u043d\u0430\u043b(\u041f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c)         pfd.cAlphaBits = 8;         \/\/ 24 \u0431\u0438\u0442\u0430 \u043d\u0430 \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0446\u0432\u0435\u0442\u0430         pfd.cDepthBits = 24;          \/\/ \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f         let pfd_id = ChoosePixelFormat(h_dc, &amp;pfd);         \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442         SetPixelFormat(h_dc, pfd_id, &amp;pfd);          \/\/ wglCreateContext \u0438 wglMakeCurrent \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0437 Opengl32.lib         let gl_context: HGLRC = wglCreateContext(h_dc);         \/\/ \u0414\u0435\u043b\u0430\u0435\u043c gl context \u0442\u0435\u043a\u0443\u0449\u0438\u043c         wglMakeCurrent(h_dc, gl_context);          (h_wnd, h_dc)     } }  \/\/ \u0412\u043d\u0435\u0448\u043d\u044f\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435\u043c \u043e \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \"system\" \u0434\u043b\u044f WinAPI extern \"system\" fn wndproc(     window: HWND,          \/\/ \u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u043e\u043a\u043d\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435     message: u32,          \/\/ \u041a\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, WM_PAINT, WM_DESTROY)     wparam: WPARAM,        \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f)     lparam: LPARAM         \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f) ) -&gt; LRESULT {             \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 - \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f          unsafe {  \/\/ \u0411\u043b\u043e\u043a unsafe, \u0442\u0430\u043a \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0441\u044b\u0440\u044b\u043c\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438 WinAPI         match message {  \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439             WM_PAINT =&gt; {  \/\/ \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u043e                 \/\/ \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0447\u0442\u043e \u0432\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u0430                 \/\/ \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438                 ValidateRect(window, ptr::null());                 0  \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c 0, \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435             }                          WM_DESTROY =&gt; {  \/\/ \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438\/\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 \u043e\u043a\u043d\u0430                 \/\/ \u041f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0432\u044b\u0445\u043e\u0434\u0435                 \/\/ \u0441 \u043a\u043e\u0434\u043e\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 0                 PostQuitMessage(0);                 0  \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c 0 \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f             }                          \/\/ \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0435 \u043e\u043a\u043d\u0430             \/\/ \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e             _ =&gt; DefWindowProcA(window, message, wparam, lparam),         }     } }<\/code><\/pre>\n<p>\u043e\u0431\u043d\u043e\u0432\u0438\u043c main.rs<\/p>\n<pre><code class=\"rust\"> #[unsafe(no_mangle)] fn main() -&gt; ! {      let (HWND, HDC) = window::create();      loop {         if !window::handle_message(HWND) {             break;         }     }      unsafe { ExitProcess(0) }; }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0435 \u043e\u043a\u043d\u043e<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/497\/e05\/d41\/497e05d41e7451e0e205cfb2c85c2a77.png\" alt=\"\u041f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f\" title=\"\u041f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f\" width=\"882\" height=\"791\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/497\/e05\/d41\/497e05d41e7451e0e205cfb2c85c2a77.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/497\/e05\/d41\/497e05d41e7451e0e205cfb2c85c2a77.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 OpenGL 3.3, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 opengl32.lib \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u0434\u0443\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 OpenGL 3.3<\/p>\n<pre><code class=\"rust\">#![allow(non_snake_case)] \/\/ \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 #![allow(static_mut_refs)] \/\/ rust-analyer - \u0414\u0430, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c usafe \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 unsafe \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 #![allow(unsafe_op_in_unsafe_fn)]  use core::mem; use windows_sys::Win32::{     Graphics::OpenGL::wglGetProcAddress,     System::LibraryLoader::{GetProcAddress, LoadLibraryA}, };  \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c CVoid \u043a\u0430\u043a ffi::\u0441_void pub struct CVoid;  \/\/ \u0441\u0434\u0435\u0434\u0430\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0442\u0438\u043f\u044b pub type GlBoolean = u8; pub type GlChar = u8; pub type GlFloat = f32; pub type GlEnum = u32; pub type GlInt = i32; pub type GlUint = u32; pub type GlSizeI = i32; pub type GlSizeIPtr = isize;  \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0439\u0434\u0435\u043c \u0432 \u043a\u0430\u043a\u043e\u043c \u043d\u0438\u0431\u0443\u0434\u044c gl.h \u0444\u0430\u0439\u043b\u0435 pub const FALSE: GlBoolean = 0; pub const TRIANGLE_STRIP: GlEnum = 0x0005; pub const FLOAT: GlEnum = 0x1406; pub const COLOR: GlEnum = 0x1800; pub const FRAGMENT_SHADER: GlEnum = 0x8B30; pub const VERTEX_SHADER: GlEnum = 0x8B31; pub const COMPILE_STATUS: GlEnum = 0x8B81; pub const LINK_STATUS: GlEnum = 0x8B82; pub const ARRAY_BUFFER: GlEnum = 0x8892; pub const STATIC_DRAW: GlEnum = 0x88E4;  \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043d\u0430\u0448\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 const GEN_BUFFERS_IDX: u8 = 0; const GEN_VERTEX_ARRAYS_IDX: u8 = 1; const BIND_VERTEX_ARRAY_IDX: u8 = 2; const BIND_BUFFER_IDX: u8 = 3; const BUFFER_DATA_IDX: u8 = 4; const CREATE_PROGRAM_IDX: u8 = 5; const ATTACH_SHADER_IDX: u8 = 6; const LINK_PROGRAM_IDX: u8 = 7; const DETACH_SHADER_IDX: u8 = 8; const CREATE_SHADER_IDX: u8 = 9; const SHADER_SOURCE_IDX: u8 = 10; const COMPILE_SHADER_IDX: u8 = 11; const ENABLE_VERTEX_ATTRIB_ARRAY_IDX: u8 = 12; const VERTEX_ATTRIB_POINTER_IDX: u8 = 13; const CLEAR_BUFFERFV_IDX: u8 = 14; const GET_PROGRAM_IV_IDX: u8 = 15; const GET_SHADER_IV_IDX: u8 = 16; const GET_SHADER_INFO_LOG_IDX: u8 = 17; const WGL_SWAP_INTERVAL_IDX: u8 = 18; const USE_PROGRAM_IDX: u8 = 19; const GET_UNIFORM_LOCATION_IDX: u8 = 20; const UNIFORM_1F_IDX: u8 = 21; const DRAW_ARRAYS_IDX: u8 = 22; const UNIFORM_2F_IDX: u8 = 23;  const N_FUNCTIONS: usize = 24;  static mut GL_API: [usize; N_FUNCTIONS] = [0; N_FUNCTIONS];  \/*   \u0412\u0441\u0435 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443:        1) \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438(\u0447\u0438\u0441\u043b\u0430 usize)            *GL_API.get_unchecked(NAME_IDX as usize),        2) \u0412\u044b\u0437\u043e\u0432 transmute \u0438 \u0438\u043d\u0442\u0435\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044f \u0447\u0438\u0441\u043b\u0430, \u043a\u0430\u043a \u0430\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438        P.S       \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 extern \"system\" \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f \u043e       \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u0430\u043a \u0432 windows os - \u044d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0438\u043d\u0430\u0447\u0435: Segmentation fault        mem::transmute::&lt;_, extern \"system\" fn(params) -&gt; ()&gt;(           *GL_API.get_unchecked(NAME_IDX as usize),       )(params) *\/  pub unsafe fn GenBuffers(n: GlSizeI, buffers: *mut GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlSizeI, *mut GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(GEN_BUFFERS_IDX as usize),     )(n, buffers) }  pub unsafe fn GenVertexArrays(n: GlSizeI, arrays: *mut GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlSizeI, *mut GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(GEN_VERTEX_ARRAYS_IDX as usize),     )(n, arrays) }  pub unsafe fn BindVertexArray(array: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(BIND_VERTEX_ARRAY_IDX as usize),     )(array) }  pub unsafe fn BindBuffer(target: GlEnum, buffer: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlEnum, GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(BIND_BUFFER_IDX as usize),     )(target, buffer) }  pub unsafe fn BufferData(target: GlEnum, size: GlSizeIPtr, data: *const CVoid, usage: GlEnum) {     mem::transmute::&lt;_, extern \"system\" fn(GlEnum, GlSizeIPtr, *const CVoid, GlEnum) -&gt; ()&gt;(         *GL_API.get_unchecked(BUFFER_DATA_IDX as usize),     )(target, size, data, usage) }  pub unsafe fn CreateProgram() -&gt; GlUint {     mem::transmute::&lt;_, extern \"system\" fn() -&gt; GlUint&gt;(         *GL_API.get_unchecked(CREATE_PROGRAM_IDX as usize),     )() }  pub unsafe fn AttachShader(program: GlUint, shader: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(ATTACH_SHADER_IDX as usize),     )(program, shader) }  pub unsafe fn LinkProgram(program: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(LINK_PROGRAM_IDX as usize),     )(program) }  pub unsafe fn DetachShader(program: GlUint, shader: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(DETACH_SHADER_IDX as usize),     )(program, shader) }  #[must_use] pub unsafe fn CreateShader(kind: GlEnum) -&gt; GlUint {     mem::transmute::&lt;_, extern \"system\" fn(GlEnum) -&gt; GlUint&gt;(         *GL_API.get_unchecked(CREATE_SHADER_IDX as usize),     )(kind) }  pub unsafe fn ShaderSource(     shader: GlUint,     count: GlSizeI,     string: *const *const GlChar,     length: *const GlInt, ) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, GlSizeI, *const *const GlChar, *const GlInt) -&gt; ()&gt;(         *GL_API.get_unchecked(SHADER_SOURCE_IDX as usize),     )(shader, count, string, length) }  pub unsafe fn CompileShader(shader: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(COMPILE_SHADER_IDX as usize),     )(shader) }  pub unsafe fn EnableVertexAttribArray(index: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(ENABLE_VERTEX_ATTRIB_ARRAY_IDX as usize),     )(index) }  pub unsafe fn ClearBufferfv(buffer: GlEnum, drawbuffer: GlInt, value: *const GlFloat) {     mem::transmute::&lt;_, extern \"system\" fn(GlEnum, GlInt, *const GlFloat) -&gt; ()&gt;(         *GL_API.get_unchecked(CLEAR_BUFFERFV_IDX as usize),     )(buffer, drawbuffer, value) }  pub unsafe fn VertexAttribPointer(     index: GlUint,     size: GlInt,     type_: GlEnum,     normalized: GlBoolean,     stride: GlSizeI,     pointer: *const CVoid, ) {     mem::transmute::&lt;         _,         extern \"system\" fn(GlUint, GlInt, GlEnum, GlBoolean, GlSizeI, *const CVoid) -&gt; (),     &gt;(*GL_API.get_unchecked(VERTEX_ATTRIB_POINTER_IDX as usize))(         index, size, type_, normalized, stride, pointer,     ) }  pub unsafe fn GetProgramIv(program: GlUint, pname: GlEnum, params: *mut GlInt) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, GlEnum, *mut GlInt) -&gt; ()&gt;(         *GL_API.get_unchecked(GET_PROGRAM_IV_IDX as usize),     )(program, pname, params) }  pub unsafe fn glGetShaderIv(shader: GlUint, sname: GlEnum, params: *mut GlInt) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, GlEnum, *mut GlInt) -&gt; ()&gt;(         *GL_API.get_unchecked(GET_SHADER_IV_IDX as usize),     )(shader, sname, params) }  pub unsafe fn wglSwapIntervalEXT(interval: GlInt) -&gt; GlUint {     mem::transmute::&lt;_, extern \"system\" fn(GlInt) -&gt; GlUint&gt;(         *GL_API.get_unchecked(WGL_SWAP_INTERVAL_IDX as usize),     )(interval) }  pub unsafe fn UseProgram(program: GlUint) {     mem::transmute::&lt;_, extern \"system\" fn(GlUint) -&gt; ()&gt;(         *GL_API.get_unchecked(USE_PROGRAM_IDX as usize),     )(program) }  #[must_use] pub unsafe fn GetUniformLocation(program: GlUint, name: *const GlChar) -&gt; GlInt {     mem::transmute::&lt;_, extern \"system\" fn(GlUint, *const GlChar) -&gt; GlInt&gt;(         *GL_API.get_unchecked(GET_UNIFORM_LOCATION_IDX as usize),     )(program, name) }  pub unsafe fn Uniform1f(location: GlInt, v0: GlFloat) {     mem::transmute::&lt;_, extern \"system\" fn(GlInt, GlFloat)&gt;(         *GL_API.get_unchecked(UNIFORM_1F_IDX as usize),     )(location, v0) }  pub unsafe fn DrawArrays(mode: GlEnum, first: GlInt, count: GlSizeI) {     mem::transmute::&lt;_, extern \"system\" fn(GlEnum, GlInt, GlSizeI)&gt;(         *GL_API.get_unchecked(DRAW_ARRAYS_IDX as usize),     )(mode, first, count) }  pub unsafe fn Uniform2f(location: GlInt, v0: GlFloat, v1: GlFloat) {     mem::transmute::&lt;_, extern \"system\" fn(GlInt, GlFloat, GlFloat)&gt;(         *GL_API.get_unchecked(UNIFORM_1F_IDX as usize),     )(location, v0, v1) }  \/\/\/ \u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f gl \u0444\u0443\u043d\u043a\u0446\u0438\u0439 pub fn init() {     const LOAD_DESCRIPTOR: [(u8, &amp;'static str); N_FUNCTIONS] = [         (GEN_BUFFERS_IDX, \"glGenBuffers\\0\"),         (GEN_VERTEX_ARRAYS_IDX, \"glGenVertexArrays\\0\"),         (BIND_VERTEX_ARRAY_IDX, \"glBindVertexArray\\0\"),         (BIND_BUFFER_IDX, \"glBindBuffer\\0\"),         (BUFFER_DATA_IDX, \"glBufferData\\0\"),         (CREATE_PROGRAM_IDX, \"glCreateProgram\\0\"),         (ATTACH_SHADER_IDX, \"glAttachShader\\0\"),         (LINK_PROGRAM_IDX, \"glLinkProgram\\0\"),         (DETACH_SHADER_IDX, \"glDetachShader\\0\"),         (CREATE_SHADER_IDX, \"glCreateShader\\0\"),         (SHADER_SOURCE_IDX, \"glShaderSource\\0\"),         (COMPILE_SHADER_IDX, \"glCompileShader\\0\"),         (ENABLE_VERTEX_ATTRIB_ARRAY_IDX,\"glEnableVertexAttribArray\\0\",),         (VERTEX_ATTRIB_POINTER_IDX, \"glVertexAttribPointer\\0\"),         (CLEAR_BUFFERFV_IDX, \"glClearBufferfv\\0\"),         (GET_PROGRAM_IV_IDX, \"glGetProgramiv\\0\"),         (GET_SHADER_IV_IDX, \"glGetShaderiv\\0\"),         (GET_SHADER_INFO_LOG_IDX, \"glGetShaderInfoLog\\0\"),         (WGL_SWAP_INTERVAL_IDX, \"wglSwapIntervalEXT\\0\"),         (USE_PROGRAM_IDX, \"glUseProgram\\0\"),         (GET_UNIFORM_LOCATION_IDX, \"glGetUniformLocation\\0\"),         (UNIFORM_1F_IDX, \"glUniform1f\\0\"),         (DRAW_ARRAYS_IDX, \"glDrawArrays\\0\"),         (UNIFORM_2F_IDX, \"glUniform2f\\0\"),     ];      \/\/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c .dll     let handle = unsafe { LoadLibraryA(\"Opengl32.dll\\0\".as_ptr() as *const u8) };      for i in 0..LOAD_DESCRIPTOR.len() {             let (index, name) = LOAD_DESCRIPTOR[i];         unsafe {              \/\/ \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e GetProcAddress OpneGL 1.0+, \u043f\u043e\u0442\u043e\u043c             \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c wglGetProcAddress, \u0435\u0441\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430              let addr = GetProcAddress(handle, name.as_ptr() as *const u8)                 .or_else(|| wglGetProcAddress(name.as_ptr() as *const u8))                 .unwrap() as usize;              \/\/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e             \/\/\/ \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u044d\u0442\u043e unsafe \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f             GL_API[index as usize] = addr;         }     } }  pub fn program_from_shaders(vtx_shader: GlUint, frag_shader: GlUint) -&gt; GlUint {     let program_id;        \/\/\u041c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     \/\/let mut success: GlInt = 1;      unsafe {         program_id = CreateProgram();         AttachShader(program_id, vtx_shader);         AttachShader(program_id, frag_shader);         LinkProgram(program_id);         DetachShader(program_id, vtx_shader);         DetachShader(program_id, frag_shader);         \/\/GetProgramIv(program_id, LINK_STATUS, &amp;mut success);     }      program_id }  pub fn shader_from_source(shader_source: &amp;str, kind: GlEnum) -&gt; GlUint {     let shader_id;      \/\/\u041c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b     \/\/let mut success: GlInt = 1;     unsafe {         shader_id = CreateShader(kind);         ShaderSource(shader_id, 1, &amp;shader_source.as_ptr(), 0 as *const _);         CompileShader(shader_id);         \/\/glGetShaderIv(shader_id, COMPILE_STATUS, &amp;mut success);     }      shader_id } <\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043b\u0438\u0448\u044c \u043d\u0430\u0439\u0442\u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0448\u0435\u0439\u0434\u0435\u0440, \u043e\u0431\u044b\u0447\u043d\u043e \u043a\u0443\u0447\u0443 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0445 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435: <a href=\"https:\/\/www.shadertoy.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/www.shadertoy.com\/<\/a>, \u043d\u043e \u0438\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c\/\u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0434 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 glsl<\/p>\n<p>\u041a\u043e\u0434 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430:<\/p>\n<pre><code class=\"cpp\">#version 330 core  layout(location = 0) in vec3 Pos;  void main() {     gl_Position = vec4(Pos, 1.0); }<\/code><\/pre>\n<p>\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439:<\/p>\n<pre><code class=\"cpp\">#version 330  uniform float iTime;  void main() {      \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430     vec2 iResolution = vec2(720.0, 720.0);     \/\/ \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b     vec2 uv = gl_FragCoord.xy\/iResolution.xy;      \/\/ \u0441\u043c\u0435\u0449\u0430\u0435\u043c, \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u0440\u0438\u043d\u043a\u0430 \u0431\u044b\u043b\u0430 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435     uv -= 0.5;     uv *= 3.0;     uv.x *= (iResolution.x\/iResolution.y);      \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0446\u0432\u0435\u0442     vec3 color = vec3(0.0, 0.0, 0.0);      \/\/ \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c 10 \u0448\u0430\u0440\u0438\u043a\u043e\u0432     for(int i = 0; i &lt; 10; i++) {          \/\/ \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0443\u0433\u043e\u043b \u043c\u0435\u0436\u0434\u0443 \u0448\u0430\u0440\u0438\u043a\u0430\u043c\u0438         float angle = float(i) * 2.0 * 3.14159 \/ 5.0;          \/\/ \u041f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0446\u0435\u043d\u0442\u0440 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f         vec2 center = vec2(             cos((angle + iTime) * 0.5) * 0.5,             sin((angle + iTime) * 0.5) * 0.5         );          \/\/ \u0421\u0447\u0438\u0442\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430         float d = length(uv - center);         \/\/ \u041c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0437\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0441\u0432\u0435\u0442\u0430         d = 0.02 \/ d;          \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u0446\u0432\u0435\u0442\u0430\u043c\u0438         vec3 circleColor = vec3(             0.3 * sin(iTime\/10.0 * float(i)) + 0.1,             0.3 * sin(iTime\/10.0 * float(i)) + 0.2,             0.3 * sin(iTime\/10.0 * float(i)) + 0.3         );          \/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442         color += circleColor * d;     }      gl_FragColor = vec4(color, 1.0); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430\u0448 main.rs<\/p>\n<pre><code class=\"rust\">#![no_main] #![no_std] \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430! \u0411\u0435\u0437 \u043d\u0435\u0435 Crinkler \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u043a\u043d\u043e\u043c #![windows_subsystem = \"windows\"]  use music::play; use windows_sys::Win32::{   Graphics::OpenGL::SwapBuffers,    System::{     Memory::{       GetProcessHeap,        HeapAlloc     },      Threading::ExitProcess   } };  mod gl; mod window;  #[unsafe(no_mangle)] fn main() -&gt; ! {      let (HWND, HDC) = window::create();     gl::init();      unsafe {          \/\/ concat! \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442 \u0434\u0432\u0435 \u0441\u0442\u0440\u043e\u043a\u0438. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \\0         let vertex_shader_src: &amp;'static str = concat!(include_str!(\"..\/shaders\/vs.glsl\"), \"\\0\");         let frag_shader_src: &amp;'static str = concat!(include_str!(\"..\/shaders\/fs.glsl\"), \"\\0\");          \/\/\/ \u0414\u0432\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d,          \/\/  \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438\u0437 \u0437\u0430 TRIANGLE_STRIP         let vertex_coords: [[gl::GlFloat; 3]; 4] =         [             [-1.0, -1.0, 0.0],             [1.0, -1.0, 0.0],             [-1.0, 1.0, 0.0],             [1.0, 1.0, 0.0]         ];          let vertex_shader = gl::shader_from_source(vertex_shader_src, gl::VERTEX_SHADER);         let frag_shader = gl::shader_from_source(frag_shader_src, gl::FRAGMENT_SHADER);         let shader_prog = gl::program_from_shaders(vertex_shader, frag_shader);          \/\/ OpenGL setup         let mut vertex_buffer_id: gl::GlUint = 0;         let mut vertex_array_id: gl::GlUint = 0;          \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c 1 \u0431\u0443\u0444\u0444\u0435\u0440 \u0434\u043b\u044f \u0432\u0435\u0440\u0448\u0438\u043d         gl::GenBuffers(1, &amp;mut vertex_buffer_id);         \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c 1 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0435\u0440\u0448\u0438\u043d         gl::GenVertexArrays(1, &amp;mut vertex_array_id);                  \/\/ \u041f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c Vertex Array Object (VAO) \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432         gl::BindVertexArray(vertex_array_id);                  \/\/ \u041f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c Vertex Buffer Object (VBO) \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c         gl::BindBuffer(gl::ARRAY_BUFFER, vertex_buffer_id);                  \/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0448\u0438\u043d \u0432 \u0432\u0438\u0434\u0435\u043e\u043f\u0430\u043c\u044f\u0442\u044c         gl::BufferData(             gl::ARRAY_BUFFER, \/\/ \u0422\u0438\u043f \u0431\u0443\u0444\u0435\u0440\u0430: \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440             mem::size_of::&lt;gl::GlFloat&gt;() as isize * 12,               \/\/ \u0420\u0430\u0437\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445: 12 float'\u043e\u0432 (4 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u00d7 3 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b)             vtx_coords.as_ptr() as *const gl::CVoid, \/\/ \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0432\u0435\u0440\u0448\u0438\u043d             gl::STATIC_DRAW, \/\/ \u0420\u0435\u0436\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f: \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f         );                  \/\/ \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c 0         gl::EnableVertexAttribArray(0);                  \/\/ \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445         gl::VertexAttribPointer(             0, \/\/layout(location = 0) \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0435)             3, \/\/ \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0443 (x, y, z)             gl::FLOAT, \/\/ \u0422\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430             gl::FALSE, \/\/ \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f             3 * mem::size_of::&lt;gl::GlFloat&gt;() as gl::GlInt,               \/\/ \u0428\u0430\u0433 \u043c\u0435\u0436\u0434\u0443 \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 (12 \u0431\u0430\u0439\u0442 \u0434\u043b\u044f 3\u00d7float)             0 as *const gl::CVoid,                           \/\/ \u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0434\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (0 - \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0444\u0435\u0440\u0430)         );          \/\/ \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438,         \/\/ \u043d\u043e Instant::now() \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 (std), \u0430 \u043d\u0435 \u0432 core.         \/\/ \u0412 \u0447\u0438\u0441\u0442\u043e no_std \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 WinAPI         let mut tick = 0.0;          loop {              if !window::handle_message(HWND) {                 break;             }              \/\/\/ \u0426\u0432\u0435\u0442 \u043e\u0447\u0438\u0441\u0442\u043a\u0438             let rgba = &amp;[0.0, 0.0, 0.0, 0.0];              \/\/\/ \u041e\u0447\u0438\u0449\u0430\u0435\u043c \u044d\u043a\u0440\u0430\u043d             gl::ClearBufferfv(gl::COLOR, 0, rgba.as_ptr());             \/\/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0443\u0436\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443             gl::UseProgram(shader_prog);             \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c Uniform              let tick_loc = gl::GetUniformLocation(shader_prog, \"iTime\\0\".as_ptr());             \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 Uniform             gl::Uniform1f(tick_loc, tick);             \/\/ Bind \u0432\u0435\u0440\u0448\u0438\u043d             gl::BindVertexArray(vertex_array_id);             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c             gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);             \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0431\u0443\u0444\u0444\u0435\u0440 \u043a\u0430\u0434\u0440\u0430             SwapBuffers(HDC);              tick += 0.01;          }          ExitProcess(0);     } }  use core::panic::PanicInfo; #[panic_handler] fn panic(_: &amp;PanicInfo&lt;'_&gt;) -&gt; ! {     loop {} }<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451! \u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u0435, \u0437\u0430\u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Rust \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u0441\u0446\u0435\u043d\u044b \u0438 \u043a\u043e\u043c\u0443 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u044b \u044d\u0442\u0438 \u0438\u043d\u0442\u0440\u043e \u2014 \u044f \u043f\u0440\u043e\u0446\u0438\u0442\u0438\u0440\u0443\u044e \u041a\u0435\u0439\u0432\u0430 \u0414\u0436\u043e\u043d\u0441\u043e\u043d\u0430:<\/p>\n<blockquote>\n<p><em>\u275d\u00a0<\/em><a href=\"https:\/\/citaty.info\/quote\/533173?utm%5C_source=citaty.info&amp;utm%5C_medium=referral&amp;utm%5C_campaign=copy&amp;utm%5C_content=quote-link\" rel=\"noopener noreferrer nofollow\"><em>\u041d\u0430\u0443\u043a\u0430 \u043d\u0435\u00a0\u0442\u0435\u0440\u043f\u0438\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u00ab\u043f\u043e\u0447\u0435\u043c\u0443\u00bb. \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u2014 \u00ab\u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b\u00a0\u0438 \u043d\u0435\u0442\u00bb. \u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0430\u0448\u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u00a0\u043e\u043f\u0430\u0441\u043d\u044b? \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b\u00a0\u043d\u0435 \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0447\u0435\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u043c\u0435\u043d\u0435\u0435 \u043e\u043f\u0430\u0441\u043d\u044b\u043c? \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b\u00a0\u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0441\u0442\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0443\u044e \u0434\u0432\u0435\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u00a0\u0443\u0434\u0430\u0440\u0438\u0442 \u0432\u0430\u0441\u00a0\u043f\u043e\u00a0\u0437\u0430\u0434\u043d\u0438\u0446\u0435 \u043f\u043e\u00a0\u0434\u043e\u0440\u043e\u0433\u0435 \u043e\u0442\u0441\u044e\u0434\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u00a0\u0432\u044b\u00a0\u0443\u0432\u043e\u043b\u0435\u043d\u044b! \u0414\u0430, \u0432\u044b! \u0421\u043e\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0432\u043e\u0438 \u0432\u0435\u0449\u0438. \u041d\u0430\u00a0\u0432\u044b\u0445\u043e\u0434. \u041a\u00a0\u043f\u0430\u0440\u043a\u043e\u0432\u043a\u0435. \u0412\u00a0\u043c\u0430\u0448\u0438\u043d\u0443. \u041f\u0440\u043e\u0449\u0430\u0439\u0442\u0435.<\/em><\/a><em>\u00a0\u275e<\/em><\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/citaty.info\/game\/portal-2?utm%5C_source=citaty.info&amp;utm%5C_medium=referral&amp;utm%5C_campaign=copy&amp;utm%5C_content=source-link\" rel=\"noopener noreferrer nofollow\">\ud83c\udfae Portal 2<\/a>\u00a0<a href=\"https:\/\/citaty.info\/quote\/533173?utm%5C_source=citaty.info&amp;utm%5C_medium=referral&amp;utm%5C_campaign=copy&amp;utm%5C_content=quote-link\" rel=\"noopener noreferrer nofollow\">\ud83d\udd17 <\/a><a href=\"https:\/\/citaty.info\/quote\/533173\" rel=\"noopener noreferrer nofollow\">https:\/\/citaty.info\/quote\/533173<\/a><\/p>\n<p>\u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0443 \u043c\u0435\u043d\u044f \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438: <a href=\"https:\/\/github.com\/olejaaaaaaaa\/4kb\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/olejaaaaaaaa\/4kb<\/a>, \u043d\u043e \u0442\u0430\u043c \u043a\u043e\u0434 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/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\/articles\/942630\/\"> https:\/\/habr.com\/ru\/articles\/942630\/<\/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<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435 \u0438\u043d\u0442\u0440\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044f\u0437\u044b\u043a Rust. \u0411\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e Unsafe \u0438 WinAPI \u043a\u043e\u0434\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0445\u043e\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u0441 OpenGL 3.3<\/p>\n<p>\u0412\u043e\u0442 \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435:<strong> <\/strong> <\/p>\n<figure class=\"\">\n<div><figcaption>\u0420\u0430\u0437\u043c\u0435\u0440: 1\u00a0661 \u0431\u0430\u0439\u0442<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/h3>\n<h4>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u041f\u041e:<\/h4>\n<ol>\n<li>\n<p><strong>Nightly-\u0432\u0435\u0440\u0441\u0438\u044f Rust<\/strong>\u00a0(\u0434\u043b\u044f \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 unsafe)<\/p>\n<pre><code>rustup toolchain install nightly<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440<\/strong>\u044b<\/p>\n<pre><code class=\"bash\">rustup target add i686-pc-windows-msvc<\/code><\/pre>\n<\/li>\n<\/ol>\n<ol>\n<li>\n<p><strong>Crinkler<\/strong>\u00a0&#8212; \u043a\u043e\u043c\u043f\u0440\u0435\u0441\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043b\u0438\u043d\u043a\u0435\u0440 \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u0449\u0438\u043a<\/p>\n<ul>\n<li>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0434\u0435\u0441\u044c:\u00a0<a href=\"https:\/\/github.com\/runestubbe\/Crinkler\" rel=\"noopener noreferrer nofollow\">github.com\/runestubbe\/Crinkler<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code class=\"bash\">cargo new --bin 4kb<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443.  <\/p>\n<p>main.rs<\/p>\n<pre><code class=\"rust\">\/\/ \u0421\u0430\u043c\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b #![no_main] \/\/ \u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 #![no_std]  \/\/ \u0417\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u0441\u0432\u043e\u0451 #[unsafe(no_mangle)] fn main() -&gt; ! {  }  \/\/ \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u0445  \/*   rust-analyzer \u043c\u043e\u0436\u0435\u0442 \u0440\u0443\u0433\u0430\u0442\u044c\u0441\u044f \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0443:     found duplicate lang item `panic_impl`     the lang item is first defined in crate `std` (which `test` depends on)    \u041d\u043e \u043c\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0430 \u044d\u0442\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 *\/ use core::panic::PanicInfo; #[panic_handler] fn panic(_: &amp;PanicInfo&lt;'_&gt;) -&gt; ! {     loop {} }<\/code><\/pre>\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0441\u0451 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439<\/p>\n<p>build.bat<\/p>\n<pre><code class=\"bash\">del demo.exe del demo.o cargo +nightly rustc -Z build-std=core --target i686-pc-windows-msvc --release -Z build-std-features=panic_immediate_abort --bin 4kb -- --emit obj=\"demo.o\" Crinkler.exe demo.o \/OUT:demo.exe \/SUBSYSTEM:WINDOWS \/ENTRY:main \"\/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22000.0\\um\\x86\" gdi32.lib user32.lib opengl32.lib kernel32.lib winmm.lib demo.exe echo %ErrorLevel%<\/code><\/pre>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443:<\/p>\n<ul>\n<li>\n<p><code>-Z build-std=core<\/code> &#8212; \u0441\u0431\u043e\u0440\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 core \u0432\u0435\u0440\u0441\u0438\u0435\u0439<\/p>\n<\/li>\n<li>\n<p><code>--target i686-pc-window-msvc<\/code> &#8212; \u0441\u0431\u043e\u0440\u043a\u0430 \u043f\u043e\u0434 x86<\/p>\n<\/li>\n<li>\n<p><code>-Z build-std-features=panic_immediate_abort<\/code> &#8212; \u042d\u0442\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u0443\u044e \u043f\u0430\u043d\u0438\u043a\u0443 \u043a\u0430\u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u0437 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e \u043f\u0430\u043d\u0438\u043a\u0435.\u00a0  <\/p>\n<\/li>\n<li>\n<p><code>--emit obj=\"demo.o\"<\/code> &#8212; \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u0441\u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f \u0441 windows lib \u0438 \u043f\u043e\u0442\u043e\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0441\u0442\u0441\u044f exe \u0444\u0430\u0439\u043b<\/p>\n<\/li>\n<li>\n<p><code>\/OUT:demo.exe<\/code> &#8212; \u0438\u043c\u044f \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430<\/p>\n<\/li>\n<li>\n<p><code>\/SUBSYSTEM:WINDOWS<\/code> &#8212; \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 Windows \u0438 Console. Windows \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u043e<\/p>\n<\/li>\n<li>\n<p><code>\/ENTRY:main<\/code> &#8212; \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0439 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438<\/p>\n<\/li>\n<li>\n<p><code> \"\/LIBPATH:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22000.0\\um\\x86\" gdi32.lib user32.lib opengl32.lib kernel32.lib winmm.lib<\/code> &#8212; \u041f\u0443\u0442\u044c \u0434\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 <\/p>\n<\/li>\n<\/ul>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0443 \u043d\u0430\u0441 \u043f\u0443\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442<\/p>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u043c \u043d\u0430\u0448 Cargo.toml, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0443 \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0438 \u0442\u0430\u043a \u0436\u0435 \u0443\u043a\u0430\u0436\u0435\u043c \u0432 release \u0441\u0431\u043e\u0440\u043a\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u0443\u0431\u0440\u0430\u0442\u044c:<\/p>\n<pre><code class=\"yaml\">[dependencies] windows-sys = { version = \"0.52.0\", features = [ \"Win32_Foundation\", \"Win32_System\", \"Win32_System_Threading\", \"Win32_System_Memory\", \"Win32_UI_WindowsAndMessaging\", \"Win32_Graphics_Gdi\", \"Win32_System_LibraryLoader\", \"Win32_Graphics_OpenGL\", \"Win32_Media\", \"Win32_Media_Audio\", \"Win32_Media_Multimedia\",     \"Win32_System_Console\", ]}  [profile.release] # \u0412 \u0441\u043b\u0443\u0447\u0430\u0438 panic \u043f\u0440\u043e\u0441\u0442\u043e \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 panic = \"abort\" # \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c \u0432 release \u0441\u0431\u043e\u0440\u043a\u0435 strip = true # \u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0435\u0434\u0438\u043d\u0438\u0446 codegen \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.  codegen-units = 1 # \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 opt-level = \"z\" <\/code><\/pre>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043e\u043a\u043d\u043e, \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u043e\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434<\/p>\n<p>window.rs<\/p>\n<pre><code class=\"rust\"> use windows_sys::{     Win32::Foundation::*,     Win32::Graphics::{Gdi::*, OpenGL::*},     Win32::System::LibraryLoader::GetModuleHandleA,     Win32::UI::WindowsAndMessaging::*, };  use core::{mem, ptr};  \/\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0442 Windows pub fn handle_message(_window: HWND) -&gt; bool {     let mut msg: mem::MaybeUninit&lt;MSG&gt; = mem::MaybeUninit::uninit();      loop {         unsafe {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0441\u0442\u044c \u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f?             if PeekMessageA(msg.as_mut_ptr(), 0 as HWND, 0, 0, PM_REMOVE) == 0 {                 \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c                 return true;             }              \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c MaybeUninit \u0432 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 MSG             let msg = msg.assume_init();              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434             if msg.message == WM_QUIT {                 \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d \u0441\u0438\u0433\u043d\u0430\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f                 return false;             }              \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u044b (\u0434\u043b\u044f \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430)             TranslateMessage(&amp;msg);                          \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u043e\u043a\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438             DispatchMessageA(&amp;msg);         }     } }  \/*   HWND - \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u043a\u043d\u0430   HDC - \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f *\/  #[must_use] pub fn create(width: i32, height: i32) -&gt; (HWND, HDC) {      unsafe {          let instance = GetModuleHandleA(ptr::null());          \/\/ \u0421\u0430\u043c\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043c\u044f \u043e\u043a\u043d\u0443         let window_class = b\"window\\0\";          let wc = WNDCLASSA {             hCursor: LoadCursorW(0, IDC_ARROW),  \/\/ \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 - \u0441\u0442\u0440\u0435\u043b\u043a\u0430             hInstance: instance,                 \/\/ \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b             lpszClassName: window_class.as_ptr(),\/\/ \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430             style: CS_HREDRAW | CS_VREDRAW,      \/\/ \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430             lpfnWndProc: Some(wndproc),          \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439             \/*                 \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0441 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043d\u0438\u0445                 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043a WNDCLASS:                 https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/winuser\/ns-winuser-wndclassa             *\/             cbClsExtra: 0,             cbWndExtra: 0,             hIcon: 0,             hbrBackground: 0,             lpszMenuName: ptr::null(),         };          let _atom = RegisterClassA(&amp;wc);         let title = c\"Pixel\";          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438         let h_wnd = CreateWindowExA(             \/\/ \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 \u043e\u043a\u043d\u0430 (0 - \u0441\u0442\u0438\u043b\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)             0,                          \/\/ \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0438\u043c\u044f \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u043a\u043d\u0430             window_class.as_ptr(),                          \/\/ \u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u043a\u043d\u0430 (\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 C-\u0441\u0442\u0440\u043e\u043a\u0443)             title.as_ptr() as *const _,              \/\/ \u0421\u0442\u0438\u043b\u0438 \u043e\u043a\u043d\u0430: \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0435\u0441\u044f \u043e\u043a\u043d\u043e + \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u043c\u043e\u0435             WS_OVERLAPPEDWINDOW | WS_VISIBLE,              \/\/ \u041f\u043e\u0437\u0438\u0446\u0438\u044f \u043e\u043a\u043d\u0430: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e             CW_USEDEFAULT,  \/\/ X-\u043f\u043e\u0437\u0438\u0446\u0438\u044f             CW_USEDEFAULT,  \/\/ Y-\u043f\u043e\u0437\u0438\u0446\u0438\u044f              \/\/ \u0420\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u043a\u043d\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445:             width,             height,              \/\/ \u0420\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0435 \u043e\u043a\u043d\u043e (None - \u043d\u0435\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f)             0 as HWND,              \/\/ \u041c\u0435\u043d\u044e (None - \u043d\u0435\u0442 \u043c\u0435\u043d\u044e)             0 as HMENU,              \/\/ \u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f             instance,             \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f (None)             ptr::null(),         );          let h_dc: HDC = GetDC(h_wnd);          let mut pfd: PIXELFORMATDESCRIPTOR = mem::zeroed();         pfd.nSize = mem::size_of::&lt;PIXELFORMATDESCRIPTOR&gt;() as u16;         pfd.nVersion = 1;         \/\/ \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0432 \u044d\u043a\u0440\u0430\u043d, \u043f\u043e\u0434\u0434\u0440\u0435\u0436\u043a\u0430 OpenGL, \u0414\u0432\u043e\u0439\u043d\u0430\u044f \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f         pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;         pfd.iPixelType = PFD_TYPE_RGBA;         \/\/ \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0442 \u043d\u0430 \u0446\u0432\u0435\u0442         pfd.cColorBits = 32;         \/\/ 8 \u0431\u0438\u0442 \u043d\u0430 Alpha \u043a\u0430\u043d\u0430\u043b(\u041f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c)         pfd.cAlphaBits = 8;         \/\/ 24 \u0431\u0438\u0442\u0430 \u043d\u0430 \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0446\u0432\u0435\u0442\u0430         pfd.cDepthBits = 24;          \/\/ \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f         let pfd_id = ChoosePixelFormat(h_dc, &amp;pfd);         \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442         SetPixelFormat(h_dc, pfd_id, &amp;pfd);          \/\/ wglCreateContext \u0438 wglMakeCurrent \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0437 Opengl32.lib         let gl_context: HGLRC = wglCreateContext(h_dc);         \/\/ \u0414\u0435\u043b\u0430\u0435\u043c gl context \u0442\u0435\u043a\u0443\u0449\u0438\u043c         wglMakeCurrent(h_dc, gl_context);          (h_wnd, h_dc)     } }  \/\/ \u0412\u043d\u0435\u0448\u043d\u044f\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435\u043c \u043e \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \"system\" \u0434\u043b\u044f WinAPI extern \"system\" fn wndproc(     window: HWND,          \/\/ \u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u043e\u043a\u043d\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435     message: u32,          \/\/ \u041a\u043e\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, WM_PAINT, WM_DESTROY)     wparam: WPARAM,        \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f)     lparam: LPARAM         \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f) ) -&gt; LRESULT {             \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 - \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f          unsafe {  \/\/ \u0411\u043b\u043e\u043a unsafe, \u0442\u0430\u043a \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0441\u044b\u0440\u044b\u043c\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438 WinAPI         match message {  \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439             WM_PAINT =&gt; {  \/\/ \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043e\u043a\u043d\u043e                 \/\/ \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0447\u0442\u043e \u0432\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u0430                 \/\/ \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438                 ValidateRect(window, ptr::null());                 0  \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c 0, \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435             }                          WM_DESTROY =&gt; {  \/\/ \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438\/\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 \u043e\u043a\u043d\u0430                 \/\/ \u041f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0432\u044b\u0445\u043e\u0434\u0435                 \/\/ \u0441 \u043a\u043e\u0434\u043e\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 0                 PostQuitMessage(0);                 0  \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c 0 \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f             }                          \/\/ \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0435 \u043e\u043a\u043d\u0430             \/\/ \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e             _ =&gt; DefWindowProcA(window, message, wparam, lparam),         }     } }<\/code><\/pre>\n<p>\u043e\u0431\u043d\u043e\u0432\u0438\u043c main.rs<\/p>\n<pre><code class=\"rust\"> #[unsafe(no_mangle)] fn main() -&gt; ! {      let (HWND, HDC) = window::create();      loop {         if !window::handle_message(HWND) {             break;         }     }      unsafe { ExitProcess(0) }; }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0435 \u043e\u043a\u043d\u043e<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0443\u0441\u0442\u043e\u0439 \u044d\u043a\u0440\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 OpenGL 3.3, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 opengl32.lib \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u0434\u0443\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 OpenGL 3.3<\/p>\n<pre><code class=\"rust\">#![allow(non_snake_case)] \/\/ \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 #![allow(static_mut_refs)] \/\/<\/code><\/pre>\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-472825","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/472825","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=472825"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/472825\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=472825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=472825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=472825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}