{"id":486305,"date":"2026-07-06T08:46:52","date_gmt":"2026-07-06T08:46:52","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=486305"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=486305","title":{"rendered":"\u041a\u0430\u043a \u044f \u0434\u0435\u043b\u0430\u043b \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 C++. \u0427\u0430\u0441\u0442\u044c 3"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0441\u0442\u0430\u0442\u0435\u0439 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0439 \u043a\u0440\u043e\u0441\u0441\u2011\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 C++ \u2014 Frenchie. \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u043a \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e <a href=\"https:\/\/github.com\/Alexey-cpu\/Frenchie.git.\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a>. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f.<\/p>\n<p>\u0426\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u2014 \u0434\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u0446\u0438\u043a\u043b \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u043a\u0430\u043a \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u043f\u0443\u0442\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.<\/p>\n<h2>\u0427\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u0432 platform backend-\u0435 ?<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u043a\u0430\u043a \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f, <a href=\"https:\/\/habr.com\/ru\/articles\/1055870\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f, \u043a\u0430\u043a \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u044e\u0442\u0441\u044f<\/a>.<\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0432\u044b\u0448\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u0441\u0435 \u043a\u0440\u043e\u043c\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0432 \u0446\u0438\u043a\u043b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: awake(), frame_start(), frame_update() \u0438.\u0442.\u0434 \u042d\u0442\u043e \u0442\u0435 \u0441\u0430\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u044e \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a GLFW \u0438 SDL3. \u0412 \u0432\u0438\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 awake() \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u0430 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API, \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0435 \u043a OpenGL. \u041f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 API \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u043c\u0443 rendering backend-\u0443. \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<h2>\u0414\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GLFW<\/h2>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 GLFW? GLFW &#8212; \u044d\u0442\u043e \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u0430\u044f open-source \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u043e\u043a\u043e\u043d \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0420\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f awake()<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f awake() \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043d\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API. \u041f\u043e\u043c\u0438\u043c\u043e\u043c \u044d\u0442\u043e\u0433\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f platform backend-\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443 \u043d\u0430\u0441 \u043b\u0435\u0436\u0438\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0435\u0448 \u0435\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0415\u0441\u043b\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 OpenGL, \u0442\u043e \u0434\u043b\u044f Unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e OpenGL, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 GLFW \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438, \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, GLFW \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e-callback, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0443\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u044f (\u043a\u0430\u043a\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u043d\u0430\u0436\u0430\u0442\u0430, \u043e\u0442\u043f\u0443\u0449\u0435\u043d\u0430 \u0438.\u0442.\u0434). \u0412\u043e\u0442 \u044d\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 \u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430 C++, \u0444\u0443\u043d\u043a\u0446\u0438\u044f awake() \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">bool ApplicationPlatformBackend::awake(){    \/\/ \u0435\u0441\u043b\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c    if(m_Api != nullptr &amp;&amp; m_Api-&gt;Window != nullptr)        return true;    \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c GLFW    if(glfwInit() == GLFW_FALSE)        return false;    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 platform backend-\u0430    m_Api = std::make_shared&lt;FrenchieApplicationPlatformApi&gt;();    \/\/ \u0434\u043b\u044f Unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e OpenGL, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c#ifdef FRENCHIE_APPLICATION_PLATFORM_IS_UNIX    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);#endif    \/\/ \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u043c    glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0440\u0430\u043c\u043a\u0443    glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwWindowHint(GLFW_ICONIFIED, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e \u043e\u043a\u043d\u0435    glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0435\u0433\u043e    m_Api-&gt;Window = glfwCreateWindow(512, 256, \"Application\", nullptr, nullptr);    if(m_Api-&gt;Window == nullptr)    {        glfwTerminate();        return false;    }    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c OpenGL API, \u0447\u0442\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    glfwMakeContextCurrent(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 \u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    glfwSetWindowSizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback);    glfwSetFramebufferSizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback);    glfwSetWindowMaximizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_maximized_callback);    glfwSetWindowFocusCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_focused_callback);    glfwSetCursorEnterCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_cursor_enter_callback);    glfwSetCursorPosCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_cursor_moved_callback);    glfwSetMouseButtonCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_mouse_button_callback);    glfwSetScrollCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_mouse_sroll_offset_changed_callback);    glfwSetKeyCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_key_callback);    glfwSetCharCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_character_input_callback);    glfwSetWindowIconifyCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::window_iconify_callback);    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API \u0447\u0435\u0440\u0435\u0437 rendering backend    if(!ApplicationRenderingBackend::awake((void*(*)(const char*))glfwGetProcAddress))    {        glfwTerminate();        return false;    }    \/\/ \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d    glfwMaximizeWindow(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    return true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 GLFW \u0434\u043b\u044f \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c<\/h2>\n<p>\u041a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0440\u0430\u043d\u0435\u0435, GLFW \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u044c\u0437\u0442\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<ol>\n<li>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<li>\n<p> \u0420\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430 \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u043e\u043a\u0443\u0441\u0430 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443<\/p>\n<\/li>\n<li>\n<p>\u0412\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435<\/p>\n<\/li>\n<li>\n<p> \u041d\u0430\u0436\u0430\u0442\u0438\u0435\/\u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u044b\u0448\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u0435\u0441\u0438\u043a\u0430 \u043c\u044b\u0448\u0438<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434<\/p>\n<\/li>\n<li>\n<p>\u0421\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback \u0434\u043b\u044f GLFW \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0430 C++ \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u044b\u0448\u0438 GLFW \u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 FrenchieApplicationPlatformBackendMouseButton::Button FrenchieApplicationGLFWInputHandler::glfw_mouse_button_to_application_mouse_button(int _MouseButton){    switch (_MouseButton)    {    case GLFW_MOUSE_BUTTON_LEFT:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonLeft;    case GLFW_MOUSE_BUTTON_RIGHT:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonRight;    case GLFW_MOUSE_BUTTON_MIDDLE:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonMiddle;    }    return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonEnd;}\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b GLFW \u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 FrenchieApplicationPlatformBackendKey::Key FrenchieApplicationGLFWInputHandler::glfw_key_to_application_key(int _KeyKode, int){    switch (_KeyKode)    {        case GLFW_KEY_TAB: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_Tab;        case GLFW_KEY_LEFT: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_LeftArrow;        case GLFW_KEY_RIGHT: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_RightArrow;        \/\/ \u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041a\u043b\u044e\u0447\u0435\u0439 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e...        default: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_None;    }}\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0431\u0443\u043b\u0435\u0432 TRUE\/FALSE \u043e\u0442 GLFW \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0431\u0443\u043b\u0435\u0432 TRUE\/FALSE C++bool FrenchieApplicationGLFWInputHandler::glfw_boolean_to_application_boolean(int _Boolean){    return _Boolean == GLFW_TRUE;}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430void FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback(GLFWwindow* _Window, int _Width, int _Height){    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    (void)_Window;    int width  = 0;    int height = 0;    glfwGetFramebufferSize(_Window, &amp;width, &amp;height);    ApplicationRenderingBackend::set_viewport(gs_vec2f(0, 0), gs_vec2f(width, height));}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0440\u0430\u0441\u0442\u044f\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0432\u043e \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043dvoid FrenchieApplicationGLFWInputHandler::glfw_on_window_maximized_callback(GLFWwindow* _Window, int _Maximized){    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    (void)_Window;    int width  = 0;    int height = 0;    glfwGetFramebufferSize(_Window, &amp;width, &amp;height);    ApplicationRenderingBackend::set_viewport(gs_vec2f(0, 0), gs_vec2f(width, height));}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0444\u043e\u043a\u0443\u0441\u0430 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443void FrenchieApplicationGLFWInputHandler::glfw_on_window_focused_callback(GLFWwindow* _Window, int _Focused){    ApplicationPlatformBackend::platform_api()-&gt;Input.Window.Focused =        glfw_boolean_to_application_boolean(_Focused);}\/\/  \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430void FrenchieApplicationGLFWInputHandler::glfw_on_cursor_moved_callback(GLFWwindow* _Window, double _X, double _Y){    (void)_Window;    if(ApplicationPlatformBackend::platform_api()-&gt;Input.MouseCursor.Entered)        ApplicationPlatformBackend::platform_api()-&gt;Input.MouseCursor.Position = gs_vec2f(_X, _Y);}\/\/  \u042d\u0442\u043e\u0442 callback \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043a\u0443\u0440\u0441\u043e\u0440 \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430void FrenchieApplicationGLFWInputHandler::glfw_on_cursor_enter_callback(GLFWwindow* _Window, int _Entered){    (void)_Window;    ApplicationPlatformBackend::platform_api()-&gt;Input.MouseCursor.Entered =        glfw_boolean_to_application_boolean(_Entered);}\/\/ \u0412 \u044d\u0442\u043e\u043c callback-\u0435 \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u043c\u044b\u0448\u0438void FrenchieApplicationGLFWInputHandler::glfw_on_mouse_button_callback(GLFWwindow* _Window, int button, int action, int mods){    (void)_Window;    ApplicationPlatformBackend::platform_api()-&gt;Input.MouseButtons[glfw_mouse_button_to_application_mouse_button(button)].Pressed  = action == GLFW_PRESS;    ApplicationPlatformBackend::platform_api()-&gt;Input.MouseButtons[glfw_mouse_button_to_application_mouse_button(button)].Released = action == GLFW_RELEASE;}\/\/ \u0412 \u044d\u0442\u043e\u043c callback-\u0435 \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044bvoid FrenchieApplicationGLFWInputHandler::glfw_on_key_callback(GLFWwindow* _Window, int _Keycode, int _Scancode, int _Action, int _Mods){    (void)_Window;    (void)_Mods;    ApplicationPlatformBackend::platform_api()-&gt;Input.Keys[glfw_key_to_application_key(_Keycode, _Scancode)].Pressed  = _Action == GLFW_PRESS;    ApplicationPlatformBackend::platform_api()-&gt;Input.Keys[glfw_key_to_application_key(_Keycode, _Scancode)].Released = _Action == GLFW_RELEASE;}\/\/ \u0412 \u044d\u0442\u043e\u043c callback-\u0435 \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u0441\u0438\u043c\u0432\u043e\u043bvoid FrenchieApplicationGLFWInputHandler::glfw_on_character_input_callback(GLFWwindow* _Window, unsigned int _Character){    (void)_Window;    ApplicationPlatformBackend::platform_api()-&gt;Input.Character = _Character;}\/\/ \u0412 \u044d\u0442\u043e\u043c callback-\u0435 \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043d\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0435\u0441\u0438\u043a\u0430 \u043c\u044b\u0448\u0438void FrenchieApplicationGLFWInputHandler::glfw_on_mouse_sroll_offset_changed_callback(GLFWwindow* _Window, double _dX, double _dY){    (void)_Window;    ApplicationPlatformBackend::platform_api()-&gt;Input.MouseScrollOffset = gs_vector_normalize(gs_vec2f(_dX, _dY));}\/\/ \u0412 \u044d\u0442\u043e\u043c callback-\u0435 \u043c\u044b \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430void FrenchieApplicationGLFWInputHandler::window_iconify_callback(GLFWwindow* _Window, int _Iconified){    \/\/ \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u043e \u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e    ApplicationPlatformBackend::platform_api()-&gt;Input.Window.Iconified =        glfw_boolean_to_application_boolean(_Iconified);    \/\/ \u0435\u043a\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0435\u043c\u0443 \u0444\u043e\u043a\u0443\u0441 \u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 API, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    if(!glfw_boolean_to_application_boolean(_Iconified))    {        glfwFocusWindow(_Window);        glfwMakeContextCurrent(_Window);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_start()<\/h3>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 frame_start() \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043a \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435, \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 (\u0442.\u0435 \u043f\u0440\u043e\u0441\u0438\u043c GLFW \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448\u0438 callback-\u0438), \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u043a\u0435\u0448 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/articles\/1055870\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>\u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 GLFW \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0441\u043e \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430. \u041a\u043e\u0433\u0434\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0443 \u043d\u0435\u0433\u043e \u0444\u043e\u043a\u0443\u0441 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430, \u0440\u0430\u0432\u043d\u044b\u0439 \u043d\u0443\u043b\u044e. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 GLFW \u043d\u0430 \u043f\u0430\u0443\u0437\u0443, \u043e\u043d\u0430 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u0437\u0430\u0432\u0438\u0441\u043d\u0435\u0442 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0446\u0438\u043a\u043b\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u044e\u0430\u043d\u0441\u043e\u0432, \u0444\u0443\u043d\u043a\u0446\u0438\u044f frame_start() \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_start(){    \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u043e \u043b\u0438 \u043d\u0430\u0448\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e. \u0415\u0441\u043b\u0438 \u043e\u043d\u043e \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u043e, \u043c\u044b \u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430 \u043f\u0430\u0443\u0437\u0443 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 GLFW, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u043b\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434\u0438\u043c    if(ApplicationPlatformBackend::is_window_iconified())    {        glfwWaitEventsTimeout(0.1);        return;    }        \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    int x = 0;    int y = 0;    glfwGetFramebufferSize(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), &amp;x, &amp;y);    m_Api-&gt;Input.FrameBufferSize = gs_vec2f(x, y);    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwGetWindowSize(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), &amp;x, &amp;y);    m_Api-&gt;Input.WindowSize = gs_vec2f(x, y);    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwGetWindowPos(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), &amp;x, &amp;y);    m_Api-&gt;Input.WindowPosition = gs_vec2f(x, y);    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 GLFW, \u0442.\u0435 \u043f\u0440\u043e\u0441\u0438\u043c GLFW \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448\u0438 callback-\u0438    \/\/ \u0438 \u0437\u0430\u043e\u0434\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u043c\u0435\u043d\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0441\u0432\u0435\u0436\u0435\u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e    glfwPollEvents();    glfwSwapInterval(1);    \/\/ \u0437\u0434\u0435\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f rendering backend, \u043c\u044b \u043f\u0440\u043e\u0441\u0438\u043c \u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043a \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044e \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430    ApplicationRenderingBackend::frame_start();    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439    ApplicationPlatformBackend::collect_input();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_update()<\/h3>\n<p>\u042d\u0442\u043e \u0441\u0430\u043c\u0430\u044f \u0438\u0437\u044f\u0449\u043d\u0430\u044f \u0438 \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f platform backend-\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GLFW:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_update(){}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 ? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e GLFW \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\/\u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u0438 \u043d\u0430\u043c \u0441\u0430\u043c\u0438\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_finish()<\/h3>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 frame_finish() \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c rendering backend \u043e\u0442\u0434\u0430\u0442\u044c \u043d\u0430\u043c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430, \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0435\u0448\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_finish(){    \/\/ \u0415\u0441\u043b\u0438 \u043e\u043a\u043d\u043e \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u043e, \u0442\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e    if(ApplicationPlatformBackend::is_window_iconified())        return;    \/\/ \u043f\u0440\u043e\u0441\u0438\u043c rendering backend \u043e\u0442\u0434\u0430\u0442\u044c \u043d\u0430\u043c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430 \u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435    ApplicationRenderingBackend::frame_finish();    \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430, \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    glfwSwapBuffers(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    \/\/ \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u0435\u0448 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    ApplicationPlatformBackend::restore_input();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 quit(), close(), is_closed()<\/h2>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f quit() \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0442.\u043a \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443 \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c\u0441\u044f \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0432\u044b\u043c:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::quit(){    \/\/ \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API    ApplicationRenderingBackend::quit();    \/\/ \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e    glfwDestroyWindow(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    glfwTerminate();    m_Api-&gt;Window = nullptr;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f close() \u0433\u043e\u0432\u043e\u0440\u0438\u0442 GLFW, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f is_closed() \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f:<\/p>\n<pre><code class=\"cpp\">bool ApplicationPlatformBackend::is_closed(){    return glfwWindowShouldClose(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));}void ApplicationPlatformBackend::close(){    glfwSetWindowShouldClose(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), GL_TRUE);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0434\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 platform backend-\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GLFW, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0438\u043c\u0435\u044f \u043f\u043e\u0434 \u0440\u0443\u043a\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 SDL3.<\/p>\n<h2>\u0414\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SDL3<\/h2>\n<p>SDL3 &#8212; \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0443\u0434\u0438\u043e, \u0432\u0432\u043e\u0434\u043e\u043c \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b, \u043c\u044b\u0448\u0438, \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 API \u0442\u0438\u043f\u0430 OpenGL, Vulkan \u0438.\u0442.\u0434. \u0421\u0430\u043c \u0431\u0438\u0431\u0438\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c GLFW \u0438 \u0435\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0448\u0438\u0440\u0435, \u043d\u043e, \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 API.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 SDL3 \u043e\u0442 GLFW \u0432 \u0447\u0430\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 &#8212; \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e callback-\u043e\u0432, SDL3 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u042d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 platform backend-\u0430:<\/p>\n<pre><code class=\"cpp\">\/\/ Application#include &lt;FrenchieApplicationPlatformBackend.hpp&gt;\/\/ SDL3#include \"SDL3\/SDL.h\"namespace Frenchie{    namespace Application    {        \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430-\u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430        struct FrenchieApplicationPlatformSDL3 : public FrenchieApplicationPlatformApi        {            FrenchieApplicationPlatformSDL3(){}            virtual ~FrenchieApplicationPlatformSDL3(){}            \/\/ \u0432 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c            SDL_Event     Event;            \/\/ \u0432 \u044d\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 OpenGL, \u043e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 OpenGL            SDL_GLContext Context;        };    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f awake()<\/h3>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 awake() \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 SDL3 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 OpenGL, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443 \u0438 \u043f\u043e\u0442\u043e\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API:<\/p>\n<pre><code class=\"cpp\">bool ApplicationPlatformBackend::awake(){    \/\/ \u0435\u0441\u043b\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u043c    if(m_Api != nullptr &amp;&amp; m_Api-&gt;Window != nullptr)        return true;    \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c SDL3 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439    if(!SDL_Init(SDL_INIT_VIDEO))        return false;    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 platform backend-\u0430    m_Api = std::make_shared&lt;FrenchieApplicationPlatformSDL3&gt;();    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    \/\/ \u043d\u0430 unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 OpenGL \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0440\u0435\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438.    \/\/ \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 SDL3 \u0432\u0435\u0440\u0441\u0438\u044e OpenGL API \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e#ifdef FRENCHIE_APPLICATION_PLATFORM_IS_UNIX    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);#endif    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e    SDL3-&gt;Window =        SDL_CreateWindow(\"Application\", 512, 256, SDL_WINDOW_OPENGL | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE);    if(m_Api-&gt;Window == nullptr)    {        SDL_Quit();        return false;    }    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c OpenGL \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443    SDL3-&gt;Context = SDL_GL_CreateContext(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));    if(SDL3-&gt;Context == nullptr)    {        SDL_DestroyWindow(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));        SDL_Quit();        return false;    }    if(!SDL_GL_MakeCurrent(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window), SDL3-&gt;Context))    {        SDL_DestroyWindow(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));        SDL_GL_DestroyContext(SDL3-&gt;Context);        SDL_Quit();        return false;    }    \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API    if(!ApplicationRenderingBackend::awake((void*(*)(const char*))SDL_GL_GetProcAddress))    {        SDL_Quit();        return false;    }    return true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_start()<\/h3>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 frame_start() \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043a \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044e, \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c, \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f SDL3, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434 \u0438 \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043a\u043e\u0442\u043d\u0435\u043a\u0442\u0441\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430, \u0435\u0433\u043e frame buffer-\u0430 \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_start(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 == nullptr)        return;    \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 - \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430    int x = 0;    int y = 0;    SDL_GetWindowSizeInPixels(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window), &amp;x, &amp;y);    SDL3-&gt;Input.FrameBufferSize = gs_vec2f(x, y);    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    SDL_GetWindowSize(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window), &amp;x, &amp;y);    SDL3-&gt;Input.WindowSize = gs_vec2f(x, y);    \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    SDL_GetWindowPosition(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window), &amp;x, &amp;y);    SDL3-&gt;Input.WindowPosition = gs_vec2f(x, y);    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430    SDL_StartTextInput(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c, \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f SDL3    SDL_PollEvent(&amp;SDL3-&gt;Event);    SDL_GL_SetSwapInterval(1);    \/\/ \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0443\u0436\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f SDL3, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0443\u044e \u0437\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f    switch (SDL3-&gt;Event.type)    {        case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:        case SDL_EVENT_WINDOW_RESIZED:            ApplicationRenderingBackend::set_viewport(gs_vec2f(0, 0), SDL3-&gt;Input.FrameBufferSize);    }            switch (SDL3-&gt;Event.type)    {        case SDL_EVENT_MOUSE_MOTION:        {            SDL3-&gt;Input.MouseCursor.Position = gs_vec2f((float)SDL3-&gt;Event.motion.x, (float)SDL3-&gt;Event.motion.y);            break;        }        case SDL_EVENT_MOUSE_WHEEL:        {            SDL3-&gt;Input.MouseScrollOffset = gs_vec2f(SDL3-&gt;Event.wheel.x, SDL3-&gt;Event.wheel.y);            break;        }        case SDL_EVENT_MOUSE_BUTTON_DOWN:        case SDL_EVENT_MOUSE_BUTTON_UP:        {            SDL3-&gt;Input.MouseButtons[SDLApplicationInputHandler::glfw_mouse_button_to_application_mouse_button(SDL3-&gt;Event.button.button)].Pressed =                SDL3-&gt;Event.type == SDL_EVENT_MOUSE_BUTTON_DOWN;                        SDL3-&gt;Input.MouseButtons[SDLApplicationInputHandler::glfw_mouse_button_to_application_mouse_button(SDL3-&gt;Event.button.button)].Released =                SDL3-&gt;Event.type == SDL_EVENT_MOUSE_BUTTON_UP;            break;        }        case SDL_EVENT_TEXT_INPUT:        {            std::u32string utf32 = Frenchie::Core::String::convert_utf8_to_utf32(SDL3-&gt;Event.text.text);            if(!utf32.empty())            {                SDL3-&gt;Input.Character = utf32[0];                break;            }        }        case SDL_EVENT_KEY_DOWN:        case SDL_EVENT_KEY_UP:        {            SDL3-&gt;Input.Keys[SDLApplicationInputHandler::glfw_key_to_application_key(SDL3-&gt;Event.key.key, SDL3-&gt;Event.key.scancode)].Pressed =                SDL3-&gt;Event.type == SDL_EVENT_KEY_DOWN;            SDL3-&gt;Input.Keys[SDLApplicationInputHandler::glfw_key_to_application_key(SDL3-&gt;Event.key.key, SDL3-&gt;Event.key.scancode)].Released =                SDL3-&gt;Event.type == SDL_EVENT_KEY_UP;            break;        }        case SDL_EVENT_DISPLAY_ORIENTATION:        case SDL_EVENT_DISPLAY_ADDED:        case SDL_EVENT_DISPLAY_REMOVED:        case SDL_EVENT_DISPLAY_MOVED:        case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:        {            break;        }        case SDL_EVENT_WINDOW_MOUSE_ENTER:        {            SDL3-&gt;Input.MouseCursor.Entered = true;            break;        }        case SDL_EVENT_WINDOW_MOUSE_LEAVE:        {            SDL3-&gt;Input.MouseCursor.Entered = false;            break;        }        case SDL_WINDOW_MINIMIZED:        {            SDL3-&gt;Input.Window.Iconified = SDL3-&gt;Event.type == SDL_WINDOW_MINIMIZED;            break;        }        case SDL_EVENT_WINDOW_FOCUS_GAINED:        case SDL_EVENT_WINDOW_FOCUS_LOST:        {            SDL3-&gt;Input.Window.Focused = SDL3-&gt;Event.type == SDL_EVENT_WINDOW_FOCUS_GAINED;            break;        }        case SDL_EVENT_WINDOW_CLOSE_REQUESTED:        case SDL_EVENT_WINDOW_MOVED:        case SDL_EVENT_WINDOW_RESIZED:        {            if(SDL3-&gt;Event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED)            {            }            else if(SDL3-&gt;Event.type == SDL_EVENT_WINDOW_MOVED)            {            }            else if(SDL3-&gt;Event.type == SDL_EVENT_WINDOW_RESIZED)            {            }            break;        }        case SDL_EVENT_GAMEPAD_ADDED:        case SDL_EVENT_GAMEPAD_REMOVED:            break;        default:            break;    }    \/\/ \u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043a \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u044f rendering_backend()    ApplicationRenderingBackend::frame_start();    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e-\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439    ApplicationPlatformBackend::collect_input();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_update()<\/h3>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 SDL3, \u0444\u0443\u043d\u043a\u0446\u0438\u044f frame_update() \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435, SDL3 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_update(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 == nullptr)        return;    \/\/ \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    if(SDL_TextInputActive(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window)))        SDL_StopTextInput(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_update()<\/h3>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 SDL3, \u0444\u0443\u043d\u043a\u0446\u0438\u044f frame_update() \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435, SDL3 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_update(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 == nullptr)        return;    \/\/ \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    if(SDL_TextInputActive(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window)))        SDL_StopTextInput(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u044f frame_finish()<\/h3>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 frame_finish() \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c rendering backend \u043e\u0442\u0434\u0430\u0442\u044c \u043d\u0430\u043c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0430 \u0432\u0438\u0434\u0435\u043e\u043a\u0430\u0440\u0442\u0430, \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0435\u0448\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::frame_finish(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 == nullptr)        return;    \/\/ execute rendering backend    ApplicationRenderingBackend::frame_finish();    \/\/ swap frame buffers    SDL_GL_SwapWindow(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));    \/\/ restore input    ApplicationPlatformBackend::restore_input();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 quit(), close(), is_closed()<\/h3>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f quit() \u0434\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0442.\u043a \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443 \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c\u0441\u044f \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0432\u044b\u043c:<\/p>\n<pre><code class=\"cpp\">void ApplicationPlatformBackend::quit(){    \/\/ terminate rendering API    ApplicationRenderingBackend::quit();    \/\/ terminate self    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 != nullptr)    {        SDL_GL_DestroyContext(SDL3-&gt;Context);        SDL_DestroyWindow(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));    }    SDL_Quit();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f close() \u0433\u043e\u0432\u043e\u0440\u0438\u0442 SDL3, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f is_closed() \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f:<\/p>\n<pre><code class=\"cpp\">bool ApplicationPlatformBackend::is_closed(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    return SDL3 == nullptr || SDL3-&gt;Event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED;}void ApplicationPlatformBackend::close(){    auto SDL3 = platform_api&lt;FrenchieApplicationPlatformSDL3&gt;();    if(SDL3 == nullptr)        return;    SDL_Event close_event;    SDL_zero(close_event);    close_event.type = SDL_EVENT_WINDOW_CLOSE_REQUESTED;    close_event.window.windowID = SDL_GetWindowID(reinterpret_cast&lt;SDL_Window*&gt;(SDL3-&gt;Window));     SDL_PushEvent(&amp;close_event);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0434\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 platform backend-\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GLFW \u0438 SDL3. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Frenchie &#8212; rendering backend-\u0443. \u0410 \u043d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u043a\u0430-\u0447\u0442\u043e \u0432\u0441\u0435, \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e.<\/p>\n<\/div>\n<p>\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\/1055952\/\">https:\/\/habr.com\/ru\/articles\/1055952\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0441\u0442\u0430\u0442\u0435\u0439 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0439 \u043a\u0440\u043e\u0441\u0441\u2011\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 C++ \u2014 Frenchie. \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u043a \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f.\u0426\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u2014 \u0434\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u0446\u0438\u043a\u043b \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u043a\u0430\u043a \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u043f\u0443\u0442\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.\u0427\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u0432 platform backend-\u0435 ?\u0418\u0442\u0430\u043a, \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u043a\u0430\u043a \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f, \u043a\u0430\u043a \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u044e\u0442\u0441\u044f.\u0412 \u043a\u043e\u0434\u0435 \u0432\u044b\u0448\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u0441\u0435 \u043a\u0440\u043e\u043c\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0432 \u0446\u0438\u043a\u043b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: awake(), frame_start(), frame_update() \u0438.\u0442.\u0434 \u042d\u0442\u043e \u0442\u0435 \u0441\u0430\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u044e \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a GLFW \u0438 SDL3. \u0412 \u0432\u0438\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 awake() \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u0430 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 API, \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0435 \u043a OpenGL. \u041f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 API \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0435, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u043c\u0443 rendering backend-\u0443. \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c.\u0414\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GLFW\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 GLFW? GLFW &#8212; \u044d\u0442\u043e \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u0430\u044f open-source \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u043e\u043a\u043e\u043d \u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0420\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e.\u0424\u0443\u043d\u043a\u0446\u0438\u044f awake()\u0424\u0443\u043d\u043a\u0446\u0438\u044f awake() \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043d\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API. \u041f\u043e\u043c\u0438\u043c\u043e\u043c \u044d\u0442\u043e\u0433\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f platform backend-\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443 \u043d\u0430\u0441 \u043b\u0435\u0436\u0438\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0435\u0448 \u0435\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0415\u0441\u043b\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 OpenGL, \u0442\u043e \u0434\u043b\u044f Unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e OpenGL, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c.\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 GLFW \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438, \u0435\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0438\u0437 \u043d\u0438\u0445 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, GLFW \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e-callback, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0443\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u044f (\u043a\u0430\u043a\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u043d\u0430\u0436\u0430\u0442\u0430, \u043e\u0442\u043f\u0443\u0449\u0435\u043d\u0430 \u0438.\u0442.\u0434). \u0412\u043e\u0442 \u044d\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 \u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430 C++, \u0444\u0443\u043d\u043a\u0446\u0438\u044f awake() \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:bool ApplicationPlatformBackend::awake(){    \/\/ \u0435\u0441\u043b\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c    if(m_Api != nullptr &amp;&amp; m_Api-&gt;Window != nullptr)        return true;    \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c GLFW    if(glfwInit() == GLFW_FALSE)        return false;    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 platform backend-\u0430    m_Api = std::make_shared&lt;FrenchieApplicationPlatformApi&gt;();    \/\/ \u0434\u043b\u044f Unix-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e OpenGL, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c#ifdef FRENCHIE_APPLICATION_PLATFORM_IS_UNIX    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);#endif    \/\/ \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u043c    glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0440\u0430\u043c\u043a\u0443    glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    glfwWindowHint(GLFW_ICONIFIED, GLFW_TRUE);    \/\/ \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e \u043e\u043a\u043d\u0435    glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);    \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043d\u0435\u0433\u043e    m_Api-&gt;Window = glfwCreateWindow(512, 256, &#171;Application&#187;, nullptr, nullptr);    if(m_Api-&gt;Window == nullptr)    {        glfwTerminate();        return false;    }    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c OpenGL API, \u0447\u0442\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    glfwMakeContextCurrent(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 \u043d\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435    glfwSetWindowSizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback);    glfwSetFramebufferSizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback);    glfwSetWindowMaximizeCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_maximized_callback);    glfwSetWindowFocusCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_window_focused_callback);    glfwSetCursorEnterCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_cursor_enter_callback);    glfwSetCursorPosCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_cursor_moved_callback);    glfwSetMouseButtonCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_mouse_button_callback);    glfwSetScrollCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_mouse_sroll_offset_changed_callback);    glfwSetKeyCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_key_callback);    glfwSetCharCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::glfw_on_character_input_callback);    glfwSetWindowIconifyCallback(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window), FrenchieApplicationGLFWInputHandler::window_iconify_callback);    \/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e API \u0447\u0435\u0440\u0435\u0437 rendering backend    if(!ApplicationRenderingBackend::awake((void*(*)(const char*))glfwGetProcAddress))    {        glfwTerminate();        return false;    }    \/\/ \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d    glfwMaximizeWindow(reinterpret_cast&lt;GLFWwindow*&gt;(m_Api-&gt;Window));    return true;}\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438 GLFW \u0434\u043b\u044f \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u043c \u043e\u043a\u043d\u043e\u043c\u041a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0440\u0430\u043d\u0435\u0435, GLFW \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u0434\u0448\u0438\u0445 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u044c\u0437\u0442\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback-\u0438. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f:\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0420\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430 \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u043e\u043a\u0443\u0441\u0430 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443\u0412\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u0443\u0440\u0441\u043e\u0440\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u041d\u0430\u0436\u0430\u0442\u0438\u0435\/\u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u044b\u0448\u0438\u041f\u0440\u043e\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u0435\u0441\u0438\u043a\u0430 \u043c\u044b\u0448\u0438\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434\u0421\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 callback \u0434\u043b\u044f GLFW \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0430 C++ \u0432\u043e\u0442 \u0442\u0430\u043a:\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u044b\u0448\u0438 GLFW \u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 FrenchieApplicationPlatformBackendMouseButton::Button FrenchieApplicationGLFWInputHandler::glfw_mouse_button_to_application_mouse_button(int _MouseButton){    switch (_MouseButton)    {    case GLFW_MOUSE_BUTTON_LEFT:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonLeft;    case GLFW_MOUSE_BUTTON_RIGHT:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonRight;    case GLFW_MOUSE_BUTTON_MIDDLE:        return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonMiddle;    }    return ApplicationPlatformBackendMouseButton::Button::ApplicationPlatformBackendMouseButtonEnd;}\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b GLFW \u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 FrenchieApplicationPlatformBackendKey::Key FrenchieApplicationGLFWInputHandler::glfw_key_to_application_key(int _KeyKode, int){    switch (_KeyKode)    {        case GLFW_KEY_TAB: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_Tab;        case GLFW_KEY_LEFT: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_LeftArrow;        case GLFW_KEY_RIGHT: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_RightArrow;        \/\/ \u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041a\u043b\u044e\u0447\u0435\u0439 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e&#8230;        default: return ApplicationPlatformBackendKey::ApplicationPlatformBackendKey_None;    }}\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0431\u0443\u043b\u0435\u0432 TRUE\/FALSE \u043e\u0442 GLFW \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0431\u0443\u043b\u0435\u0432 TRUE\/FALSE C++bool FrenchieApplicationGLFWInputHandler::glfw_boolean_to_application_boolean(int _Boolean){    return _Boolean == GLFW_TRUE;}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430void FrenchieApplicationGLFWInputHandler::glfw_on_window_resize_callback(GLFWwindow* _Window, int _Width, int _Height){    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    (void)_Window;    int width  = 0;    int height = 0;    glfwGetFramebufferSize(_Window, &amp;width, &amp;height);    ApplicationRenderingBackend::set_viewport(gs_vec2f(0, 0), gs_vec2f(width, height));}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0440\u0430\u0441\u0442\u044f\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u0432\u043e \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043dvoid FrenchieApplicationGLFWInputHandler::glfw_on_window_maximized_callback(GLFWwindow* _Window, int _Maximized){    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 frame buffer-\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430    (void)_Window;    int width  = 0;    int height = 0;    glfwGetFramebufferSize(_Window, &amp;width, &amp;height);    ApplicationRenderingBackend::set_viewport(gs_vec2f(0, 0), gs_vec2f(width, height));}\/\/ \u042d\u0442\u043e\u0442 callback \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0444\u043e\u043a\u0443\u0441\u0430 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043a\u043d\u0443void FrenchieApplicationGLFWInputHandler::glfw_on_window_focused_callback(GLFWwindow* _Window, int _Focused){&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-486305","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/486305","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=486305"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/486305\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=486305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=486305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=486305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}