Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the antispam-bee domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/ruwritingagame/public_html/wp-includes/functions.php on line 6131

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6131) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1902
{"id":354,"date":"2021-11-29T22:15:34","date_gmt":"2021-11-29T22:15:34","guid":{"rendered":"https:\/\/writingagame.com\/?p=354"},"modified":"2021-12-02T00:01:16","modified_gmt":"2021-12-02T00:01:16","slug":"chapter-5-cross-platform-windows","status":"publish","type":"post","link":"https:\/\/writingagame.ru\/index.php\/2021\/11\/29\/chapter-5-cross-platform-windows\/","title":{"rendered":"\u0413\u043b\u0430\u0432\u0430 5. Cross-platform, Windows"},"content":{"rendered":"\n

\u0412 \u044d\u0442\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c “\u043f\u0440\u0435\u043f\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c” \u043d\u0430\u0448 GLFW \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u043c. \u041c\u044b \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u201c\u0438\u0433\u0440\u043e\u0432\u043e\u0439\u201d \u043a\u043e\u0434 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u043e\u0442\u043e\u0432\u0438\u0442 \u0438 \u0440\u0438\u0441\u0443\u0435\u0442 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a) \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u043d\u0430 Android-\u0435. \u0427\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u0431\u044b\u043b platform-independent (\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c) \u043c\u044b \u043e\u0442\u0434\u0435\u043b\u0438\u043c \u0435\u0433\u043e \u043e\u0442 platform-specific \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0412\u0435\u0441\u044c environment-related \u043a\u043e\u0434, \u0442\u0438\u043f\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f GL-\u0430, \u0438 \u0442.\u0434., \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0432 main.cpp<\/em> \u043a\u0430\u043a \u0435\u0441\u0442\u044c.<\/p>\n\n\n\n

  1. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Visual Studio, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c C:\\CPP\\a999hello\\p_windows\\p_windows.sln<\/em> solution.<\/li><\/ol>\n\n\n\n
    \n\n\n\n

    2. \u041f\u043e\u0434 p_windows<\/em> \u043f\u0440\u043e\u0435\u043a\u043e\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440.<\/p>\n\n\n\n

    Right-click \u043d\u0430 p_windows<\/em> project -> Add -> New Filter<\/strong><\/em>. Name – xTheGame<\/strong><\/p>\n\n\n\n


    \n\n\n\n

    3. \u041f\u043e\u0434 xTheGame <\/em>\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u201cadd Class\u201d \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0441\u0432\u043e\u0435 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435, \u043d\u0435 \u0442\u0430\u043c \u0433\u0434\u0435 \u043d\u0430\u043c \u043d\u0430\u0434\u043e. \u041b\u0443\u0447\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0433\u043e \u043f\u043e-\u0444\u0430\u0439\u043b\u043e\u0432\u043e.<\/p>\n\n\n\n

    Right-click \u043d\u0430 xTheGame <\/em>-> Add -> New Item<\/strong><\/em>, <\/p>\n\n\n\n

    • Header File (.h)<\/li>
    • Name \u2013 TheGame.h<\/strong><\/li>
    • \u041f\u043e\u043c\u0435\u043d\u044f\u0435\u043c location \u043d\u0430 C:\\CPP\\a999hello<\/em>\\<\/em><\/li><\/ul>\n\n\n\n

      Add<\/strong>.<\/p>\n\n\n\n

      TheGame <\/em>\u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 5-\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 3-\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0432 TheGame.h<\/em>.<\/p>\n\n\n\n

      Copy-paste \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 TheGame.h<\/em>:<\/p>\n\n\n

      \n#pragma once\nclass TheGame\n{\npublic:\n\tint screenSize[2];\n\tfloat screenRatio;\n\tbool bExitGame;\npublic:\n\tint run();\n\tint getReady();\n\tint drawFrame();\n\tint cleanUp();\n\tint onScreenResize(int width, int height);\n};\n\n<\/pre><\/div>\n\n\n

      <\/p>\n\n\n\n


      \n\n\n\n

      4. \u0422\u0435\u043f\u0435\u0440\u044c – \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f:<\/p>\n\n\n\n

      Right-click \u043d\u0430 xTheGame <\/em>-> Add -> New Item<\/strong><\/em>, <\/p>\n\n\n\n

      • C++ File (.cpp)<\/li>
      • Name \u2013 TheGame.cpp<\/strong><\/li>
      • Location – C:\\CPP\\a999hello<\/em>\\<\/em><\/li><\/ul>\n\n\n\n

        Add.<\/p>\n\n\n\n

        \u041a\u043e\u0434:<\/p>\n\n\n

        \n#include "TheGame.h"\n#include "platform.h"\n#include "linmath.h"\n\nstatic const struct\n{\n    float x, y;\n    float r, g, b;\n} vertices[3] =\n{\n    { -0.6f, -0.4f, 1.f, 0.f, 0.f },\n    {  0.6f, -0.4f, 0.f, 1.f, 0.f },\n    {   0.f,  0.6f, 0.f, 0.f, 1.f }\n};\n\nstatic const char* vertex_shader_text =\n"#version 320 es\\n"\n"precision lowp float;\\n"\n"uniform mat4 MVP;\\n"\n"in vec3 vCol;\\n"\n"in vec2 vPos;\\n"\n"out vec3 color;\\n"\n"void main()\\n"\n"{\\n"\n"    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\\n"\n"    color = vCol;\\n"\n"}\\n";\n\nstatic const char* fragment_shader_text =\n"#version 320 es\\n"\n"precision lowp float;\\n"\n"in vec3 color;\\n"\n"out vec4 FragColor;\\n"\n"void main()\\n"\n"{\\n"\n"    FragColor = vec4(color, 1.0);\\n"\n"}\\n";\n\nunsigned int vao_buffer, vertex_buffer, vertex_shader, fragment_shader, program;\nint mvp_location, vpos_location, vcol_location;\nfloat angle_z = 0;\n\nint TheGame::getReady() {\n    bExitGame = false;\n\n    glGenVertexArrays(1, &vao_buffer);\n    glBindVertexArray(vao_buffer);\n\n    glGenBuffers(1, &vertex_buffer);\n    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);\n    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);\n\n    vertex_shader = glCreateShader(GL_VERTEX_SHADER);\n    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);\n    glCompileShader(vertex_shader);\n\n    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);\n    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);\n    glCompileShader(fragment_shader);\n\n    program = glCreateProgram();\n    glAttachShader(program, vertex_shader);\n    glAttachShader(program, fragment_shader);\n    glLinkProgram(program);\n\n    mvp_location = glGetUniformLocation(program, "MVP");\n\n    vpos_location = glGetAttribLocation(program, "vPos");\n    vcol_location = glGetAttribLocation(program, "vCol");\n\n    glEnableVertexAttribArray(vpos_location);\n    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,\n        sizeof(vertices[0]), (void*)0);\n    glEnableVertexAttribArray(vcol_location);\n    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,\n        sizeof(vertices[0]), (void*)(sizeof(float) * 2));\n\n    return 1;\n}\nint TheGame::drawFrame() {\n    myPollEvents();\n\n    mat4x4 m, p, mvp;\n\n    glClear(GL_COLOR_BUFFER_BIT);\n    angle_z += 0.01f;\n    mat4x4_identity(m);\n    mat4x4_rotate_Z(m, m, angle_z);\n    mat4x4_ortho(p, -screenRatio, screenRatio, -1.f, 1.f, 1.f, -1.f);\n    mat4x4_mul(mvp, p, m);\n\n    glUseProgram(program);\n    glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*)mvp);\n    glDrawArrays(GL_TRIANGLES, 0, 3);\n\n    mySwapBuffers();\n    return 1;\n}\nint TheGame::cleanUp() {\n    return 1;\n}\nint TheGame::onScreenResize(int width, int height) {\n    if (screenSize[0] == width && screenSize[1] == height)\n        return 0;\n    screenSize[0] = width;\n    screenSize[1] = height;\n    screenRatio = (float)width \/ (float)height;\n    glViewport(0, 0, width, height);\n    mylog(" screen size %d x %d\\n", width, height);\n    return 1;\n}\nint TheGame::run() {\n    getReady();\n    while (!bExitGame) {\n        drawFrame();\n    }\n    cleanUp();\n    return 1;\n}\n\n<\/pre><\/div>\n\n\n

        <\/p>\n\n\n\n

        • \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 platform-specific \u0441\u0441\u044b\u043b\u043e\u043a (\u043a\u0430\u043a \u043d\u0430 GLAD \u0438\u043b\u0438 GLFW), \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 – \u043d\u0430 Android-\u0435, \u0447\u0442\u043e \u043c\u044b \u043d\u0435\u043f\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435.<\/li><\/ul>\n\n\n\n
          \n\n\n\n

          5. \u0422\u0430\u043a\u0436\u0435 (\u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e) \u043d\u0430\u0434\u043e \u043e\u043f\u043e\u0432\u0435\u0441\u0442\u0438\u0442\u044c p_windows <\/em>\u043f\u0440\u043e\u0435\u043a\u0442, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c TheGame.h<\/em>.<\/p>\n\n\n\n

          Right-click \u043d\u0430 p_windows <\/em> project -> Properties, All Configurations<\/strong>, Win32, Configuration Properties -> C\/C++ -> General<\/em>, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c Additional Include Directories -> Edit<\/em>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. <\/p>\n\n\n\n

          \u0412\u0410\u0416\u041d\u041e<\/strong>: \u041d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 C:\\CPP\\a999hello<\/em> (\u0433\u0434\u0435 TheGame <\/em>\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d), \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/strong> \u0434\u043e\u0431\u0430\u0432\u0438\u043c<\/p>\n\n\n\n

          ..<\/code><\/pre>\n\n\n\n

          <\/p>\n\n\n\n

          \u0414\u0430, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e 2 \u0442\u043e\u0447\u043a\u0438, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 1 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u0432\u0435\u0440\u0445 (\u043e\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 p_windows <\/em>\u043f\u0440\u043e\u0435\u043a\u0442\u0430).<\/p>\n\n\n\n

          Ok, Apply, Ok.<\/p>\n\n\n\n


          \n\n\n\n

          6. \u041a\u0430\u043a \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u043c platform-specific \u043a\u043e\u0434 \u0432\u043d\u0435<\/strong> TheGame <\/em>\u043a\u043b\u0430\u0441\u0441\u0430. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 GLFW \u0438 GLAD, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u0432\u044b\u0437\u043e\u0432 swap screen buffers.<\/p>\n\n\n\n

          \u0418\u0442\u0430\u043a, \u043e\u0442\u043a\u0440\u043e\u0435\u043c platform.h<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c:<\/p>\n\n\n

          \n#pragma once\n#include <glad\/glad.h>\n\nvoid mylog(const char* _Format, ...);\nvoid mySwapBuffers();\nvoid myPollEvents();\n\n<\/pre><\/div>\n\n\n

          <\/p>\n\n\n\n

          • \u0417\u0430\u043e\u0434\u043d\u043e \u0443\u0431\u0440\u0435\u043c mylog(..)<\/em> \u0438\u0437 .h<\/em> \u0432 .cpp<\/em><\/li><\/ul>\n\n\n\n
            \n\n\n\n

            7. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f:<\/p>\n\n\n\n

            Right-click \u043d\u0430 xPlatform <\/em>-> Add -> New Item<\/strong><\/em>, <\/p>\n\n\n\n

            • C++ File (.cpp)<\/li>
            • Name \u2013 platform.cpp<\/strong><\/li>
            • Location – C:\\CPP\\p_windows<\/em>\\<\/em><\/li><\/ul>\n\n\n\n

              Add<\/strong>.<\/p>\n\n\n\n

              \u041a\u043e\u0434:<\/p>\n\n\n

              \n#include <stdarg.h>\n#include <stdio.h>\n#include <GLFW\/glfw3.h>\n#include "platform.h"\n#include "TheGame.h"\n\nextern GLFWwindow* myMainWindow;\nextern TheGame theGame;\n\nvoid mylog(const char* _Format, ...) {\n#ifdef _DEBUG\n    va_list _ArgList;\n    va_start(_ArgList, _Format);\n    vprintf(_Format, _ArgList);\n    va_end(_ArgList);\n#endif\n};\nvoid mySwapBuffers() {\n    glfwSwapBuffers(myMainWindow);\n}\nvoid myPollEvents() {\n    glfwPollEvents();\n    \/\/check if closing the window\n    theGame.bExitGame = glfwWindowShouldClose(myMainWindow);\n    \/\/check screen size\n    int width, height;\n    glfwGetFramebufferSize(myMainWindow, &width, &height);\n    theGame.onScreenResize(width, height);\n}\n\n<\/pre><\/div>\n\n\n

              <\/p>\n\n\n\n


              \n\n\n\n

              8. main.cpp<\/em>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u043e\u0447\u0435:<\/p>\n\n\n

              \n#include <glad\/glad.h>\n#define GLFW_INCLUDE_NONE\n#include <GLFW\/glfw3.h>\n\n#include <stdlib.h>\n\n#include "TheGame.h"\n#include "platform.h"\n\nstatic void error_callback(int error, const char* description)\n{\n    mylog("Error: %s\\n", description);\n}\n\nstatic void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)\n{\n    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)\n        glfwSetWindowShouldClose(window, GLFW_TRUE);\n}\n\nTheGame theGame;\nGLFWwindow* myMainWindow;\n\nint main(void)\n{\n    glfwSetErrorCallback(error_callback);\n\n    if (!glfwInit())\n        exit(EXIT_FAILURE);\n\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);\n\n    myMainWindow = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);\n    if (!myMainWindow)\n    {\n        glfwTerminate();\n        exit(EXIT_FAILURE);\n    }\n\n    glfwSetKeyCallback(myMainWindow, key_callback);\n\n    glfwMakeContextCurrent(myMainWindow);\n    gladLoadGLES2Loader((GLADloadproc)glfwGetProcAddress); \/\/gladLoadGL(glfwGetProcAddress);\n    glfwSwapInterval(1);\n\n    theGame.run();\n\n    glfwDestroyWindow(myMainWindow);\n    glfwTerminate();\n    exit(EXIT_SUCCESS);\n}\n\n<\/pre><\/div>\n\n\n

              <\/p>\n\n\n\n

              \u0417\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u0432 main.cpp<\/em> \u043d\u0430 \u044d\u0442\u043e\u0442.<\/p>\n\n\n\n

              • \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u041d\u0415 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 game-specific \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043d\u0430\u0448\u0438\u0445 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 Windows \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/li><\/ul>\n\n\n\n
                \n\n\n\n

                9. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c (\u0437\u0435\u043b\u0435\u043d\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430). \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n\n\n\n

                • \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0432 Release \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0442\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0431\u0435\u0437 \u043e\u043a\u043d\u0430 \u041a\u043e\u043d\u0441\u043e\u043b\u0438.<\/li><\/ul>\n\n\n\n

                  \u041d\u0430\u0448\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2013 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0430 Android-\u0435.<\/p>\n\n\n\n


                  \n","protected":false},"excerpt":{"rendered":"

                  \u0412 \u044d\u0442\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c “\u043f\u0440\u0435\u043f\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c” \u043d\u0430\u0448 GLFW \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u043c. \u041c\u044b \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u201c\u0438\u0433\u0440\u043e\u0432\u043e\u0439\u201d \u043a\u043e\u0434 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u043e\u0442\u043e\u0432\u0438\u0442 \u0438 \u0440\u0438\u0441\u0443\u0435\u0442 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a) \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u043d\u0430 Android-\u0435. \u0427\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u0431\u044b\u043b platform-independent (\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c) \u043c\u044b \u043e\u0442\u0434\u0435\u043b\u0438\u043c \u0435\u0433\u043e \u043e\u0442 platform-specific \u0432\u044b\u0437\u043e\u0432\u043e\u0432. \u0412\u0435\u0441\u044c environment-related \u043a\u043e\u0434, \u0442\u0438\u043f\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f GL-\u0430, \u0438 \u0442.\u0434., \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0432 main.cpp […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-354","post","type-post","status-publish","format-standard","hentry","category-cross-platform-3d"],"_links":{"self":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/comments?post=354"}],"version-history":[{"count":2,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/354\/revisions"}],"predecessor-version":[{"id":464,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/354\/revisions\/464"}],"wp:attachment":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/media?parent=354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/categories?post=354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/tags?post=354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}