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 6170

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

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

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

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

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

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

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

Warning: Cannot modify header information - headers already sent by (output started at /home/ruwritingagame/public_html/wp-includes/functions.php:6170) in /home/ruwritingagame/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1897
{"id":504,"date":"2021-12-04T02:26:46","date_gmt":"2021-12-04T02:26:46","guid":{"rendered":"https:\/\/writingagame.com\/?p=438"},"modified":"2022-02-09T02:08:54","modified_gmt":"2022-02-09T02:08:54","slug":"chapter-10-simple-shader","status":"publish","type":"post","link":"https:\/\/writingagame.ru\/index.php\/2021\/12\/04\/chapter-10-simple-shader\/","title":{"rendered":"\u0413\u043b\u0430\u0432\u0430 10. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0448\u0435\u0439\u0434\u0435\u0440"},"content":{"rendered":"\n

\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0448\u0435\u0439\u0434\u0435\u0440\u044b<\/strong>! \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043b\u0438\u0432\u043a\u0430 \u0441\u043f\u043b\u043e\u0448\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u043f\u0443\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0432\u0435\u0445\u043d\u043e\u0441\u0442\u0438 (\u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 – \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430).<\/p>\n\n\n\n

\u0428\u0435\u0439\u0434\u0435\u0440\u044b \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043d\u0430 GLSL (OpenGL Shading Language \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043d\u0430 C). GLSL \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0433\u0440\u0430\u0444-\u043a\u0430\u0440\u0442\u0435.<\/p>\n\n\n\n

\u0418\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0430\u044f \u0448\u0435\u0439\u0434\u0435\u0440-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 2-\u0445 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432: Vertex Shader, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0448\u0438\u043d (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b) \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0438\u0445 \u0432 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b. \u0412\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0434\u0443\u0442 \u0432 rasterizer, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 Fragment (Pixel) Shader \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u043e\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f.<\/p>\n\n\n\n

  1. Vertex Shader<\/strong>:<\/li><\/ol>\n\n\n
    \n#version 320 es\nprecision lowp float;\nuniform mat4 uMVP; \/\/ transform matrix (Model-View-Projection)\nin vec3 aPos; \/\/ position attribute (x,y,z)\nvoid main(){\n  gl_Position = uMVP * vec4(aPos, 1.0);\n}\n\n<\/pre><\/div>\n\n\n

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

    \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043a\u0430\u043a txt <\/em>\u0444\u0430\u0439\u043b \u0432<\/p>\n\n\n\n

    C:\\CPP\\engine\\dt\\shaders\\flat_ucolor_v.txt<\/strong><\/em><\/p>\n\n\n\n

    \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0435\u0433\u043e \u043d\u0435 \u043d\u0430\u0434\u043e, \u0432\u0441\u0435 \u0432\u0440\u043e\u0434\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u041d\u0443 \u0438\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a GLSL \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043d\u0430 \u0412\u0435\u0431\u0435.<\/p>\n\n\n\n

    • \u0424\u0430\u0439\u043b test0.txt<\/em> \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0442\u0443\u0434\u0430 \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0435 \u043e\u043d \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f.<\/li><\/ul>\n\n\n\n
      \n\n\n\n

      2. Fragment (Pixel) Shader<\/strong>:<\/p>\n\n\n

      \n#version 320 es\nprecision lowp float;\nuniform vec4 uColor;\nout vec4 FragColor; \/\/output pixel color\nvoid main(){\n  FragColor = uColor;\n}\n\n<\/pre><\/div>\n\n\n

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

      \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 txt <\/em>\u0444\u0430\u0439\u043b\u0430 \u0432<\/p>\n\n\n\n

      C:\\CPP\\engine\\dt\\shaders\\flat_ucolor_f<\/strong>.txt<\/em> <\/p>\n\n\n\n


      \n\n\n\n

      \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0445 \u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c.<\/p>\n\n\n\n

      Windows<\/h2>\n\n\n\n

      3. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c VS. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c C:\\CPP\\a999hello\\p_windows\\p_windows.sln<\/em>.<\/p>\n\n\n\n


      \n\n\n\n

      \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 GL \u043e\u0448\u0438\u0431\u043e\u043a. \u041f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0435\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 utils<\/strong>.<\/p>\n\n\n\n

      4. \u041f\u043e\u0434 xEngine <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c New Item<\/strong><\/p>\n\n\n\n

      • Header File (.h)<\/em><\/li>
      • Name: utils.h<\/em><\/li>
      • Location: C:\\CPP\\engine\\<\/em><\/li><\/ul>\n\n\n\n

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

        \n#pragma once\n#include <string>\n\nint checkGLerrors(std::string ref);\n\n<\/pre><\/div>\n\n\n

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


        \n\n\n\n

        5. \u041f\u043e\u0434 xEngine <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c New Item<\/strong><\/p>\n\n\n\n

        • C++ File (.cpp)<\/em><\/li>
        • Name: utils.cpp<\/em><\/li>
        • Location: C:\\CPP\\engine\\<\/em><\/li><\/ul>\n\n\n\n

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

          \n#include "platform.h"\n#include <string>\n\nint checkGLerrors(std::string ref) {\n    \/\/can be used after any GL call\n    int res = glGetError();\n    if (res == 0)\n        return 0;\n    std::string errCode;\n    switch (res) {\n        \/\/case GL_NO_ERROR: errCode = "GL_NO_ERROR"; break;\n        case GL_INVALID_ENUM: errCode = "GL_INVALID_ENUM"; break;\n        case GL_INVALID_VALUE: errCode = "GL_INVALID_VALUE"; break;\n        case GL_INVALID_OPERATION: errCode = "GL_INVALID_OPERATION"; break;\n        case GL_INVALID_FRAMEBUFFER_OPERATION: errCode = "GL_INVALID_FRAMEBUFFER_OPERATION"; break;\n        case GL_OUT_OF_MEMORY: errCode = "GL_OUT_OF_MEMORY"; break;\n        default: errCode = "??"; break;\n    }\n    mylog("GL ERROR %d-%s in %s\\n", res, errCode.c_str(), ref.c_str());\n    return -1;\n}\n\n<\/pre><\/div>\n\n\n

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


          \n\n\n\n

          Shaders-related \u043a\u043e\u0434 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 Shaders<\/strong>. <\/p>\n\n\n\n

          6. \u041f\u043e\u0434 xEngine <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c New Item<\/strong><\/p>\n\n\n\n

          • Header File (.h)<\/em><\/li>
          • Name: Shader.h<\/em><\/li>
          • Location: C:\\CPP\\engine\\<\/em><\/li><\/ul>\n\n\n\n

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

            \n#pragma once\n#include "platform.h"\n#include <string>\n\nclass Shader\n{\npublic:\n\tstatic int linkShaderProgram(const char* filePathVertexS, const char* filePathFragmentS);\n\tstatic int compileShader(const char* filePath, GLenum shaderType);\n\n\tstatic int shaderErrorCheck(int shaderId, std::string ref);\n\tstatic int programErrorCheck(int programId, std::string ref);\n};\n\n<\/pre><\/div>\n\n\n

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


            \n\n\n\n

            7. \u041f\u043e\u0434 xEngine <\/em>\u0434\u043e\u0431\u0430\u0432\u0438\u043c New Item<\/strong><\/p>\n\n\n\n

            • C++ File (.cpp)<\/em><\/li>
            • Name: Shader.cpp<\/em><\/li>
            • Location: C:\\CPP\\engine\\<\/em><\/li><\/ul>\n\n\n\n

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

              \n#include "Shader.h"\n#include "platform.h"\n#include "utils.h"\n\nGLchar infoLog[1024];\nint logLength;\nint Shader::shaderErrorCheck(int shaderId, std::string ref) {\n    \/\/use after glCompileShader()\n    if (checkGLerrors(ref) > 0)\n        return -1;\n    glGetShaderInfoLog(shaderId, 1024, &logLength, infoLog);\n    if (logLength == 0)\n        return 0;\n    mylog("%s shader infoLog:\\n%s\\n", ref.c_str(), infoLog);\n    return -1;\n}\nint Shader::programErrorCheck(int programId, std::string ref) {\n    \/\/use after glLinkProgram()\n    if (checkGLerrors(ref) > 0)\n        return -1;\n    glGetProgramInfoLog(programId, 1024, &logLength, infoLog);\n    if (logLength == 0)\n        return 0;\n    mylog("%s program infoLog:\\n%s\\n", ref.c_str(), infoLog);\n    return -1;\n}\n\nint Shader::compileShader(const char* filePath, GLenum shaderType) {\n    int shaderId = glCreateShader(shaderType);\n    FILE* pFile;\n    myFopen_s(&pFile, filePath, "rt");\n    if (pFile != NULL)\n    {\n        \/\/ obtain file size:\n        fseek(pFile, 0, SEEK_END);\n        int fSize = ftell(pFile);\n        rewind(pFile);\n        \/\/ size obtained, create buffer\n        char* shaderSource = new char[fSize + 1];\n        fSize = fread(shaderSource, 1, fSize, pFile);\n        shaderSource[fSize] = 0;\n        fclose(pFile);\n        \/\/ source code loaded, compile\n        glShaderSource(shaderId, 1, (const GLchar**)&shaderSource, NULL);\n        \/\/myglErrorCheck("glShaderSource");\n        glCompileShader(shaderId);\n        if (shaderErrorCheck(shaderId, "glCompileShader") < 0)\n            return -1;\n        delete[] shaderSource;\n    }\n    else {\n        mylog("ERROR loading %s\\n", filePath);\n        return -1;\n    }\n    return shaderId;\n}\nint Shader::linkShaderProgram(const char* filePathVertexS, const char* filePathFragmentS) {\n    int vertexShaderId = compileShader(filePathVertexS, GL_VERTEX_SHADER);\n    int fragmentShaderId = compileShader(filePathFragmentS, GL_FRAGMENT_SHADER);\n    int programId = glCreateProgram();\n    glAttachShader(programId, vertexShaderId);\n    glAttachShader(programId, fragmentShaderId);\n    glLinkProgram(programId);\n    if (programErrorCheck(programId, "glLinkProgram") < 0)\n        return -1;\n    \/\/don't need shaders any longer - detach and delete them\n    glDetachShader(programId, vertexShaderId);\n    glDetachShader(programId, fragmentShaderId);\n    glDeleteShader(vertexShaderId);\n    glDeleteShader(fragmentShaderId);\n    return programId;\n}\n\n<\/pre><\/div>\n\n\n

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


              \n\n\n\n

              \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 compileShader(..)<\/em> \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e <\/em>\u0444\u0443\u043d\u043a\u0446\u0438\u044e myFopen_s <\/strong>(\u0441\u0442\u0440\u043e\u043a\u0430 31, \u0442\u043e\u0442 \u0436\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441 \u043a\u0430\u043a fopen_s<\/em>). \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 Windows-\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u0430\u044f fopen <\/em>\u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0439, \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c fopen_s<\/em>, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u043d\u0430 \u0410\u043d\u0434\u0440\u043e\u0438\u0434\u0435 fopen_s <\/em>\u0435\u0449\u0435 \u043d\u0435 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0438 \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c fopen<\/em>. \u0412\u043e\u0431\u0449\u0435\u043c, \u043d\u0443\u0436\u043d\u044b 2 platform-specific<\/strong> \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n\n\n\n

              8. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c platform.h<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\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#include <stdio.h>\n\nvoid mylog(const char* _Format, ...);\nvoid mySwapBuffers();\nvoid myPollEvents();\nint myFopen_s(FILE** pFile, const char* filePath, const char* mode);\n\n<\/pre><\/div>\n\n\n

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


              \n\n\n\n

              9. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c platform.cpp<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c: <\/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}\nint myFopen_s(FILE** pFile, const char* filePath, const char* mode) {\n    return fopen_s(pFile, filePath, mode);\n}\n\n<\/pre><\/div>\n\n\n

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


              \n\n\n\n

              10. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043a\u0440\u043e\u0435\u043c TheGame.cpp<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n

              \n#include "TheGame.h"\n#include "platform.h"\n#include "linmath.h"\n#include "Shader.h"\n\nextern std::string filesRoot;\n\nstatic const struct\n{\n    float x, y, z;\n} vertices[3] =\n{\n    { -0.6f, -0.4f, 0.f },\n    {  0.6f, -0.4f, 0.f },\n    {   0.f,  0.6f, 0.f }\n};\n\nunsigned int vao_buffer, vertex_buffer, shaderProgramId;\nint umvp_location, apos_location, ucol_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    shaderProgramId = Shader::linkShaderProgram((filesRoot + "\/dt\/shaders\/flat_ucolor_v.txt").c_str(), (filesRoot + "\/dt\/shaders\/flat_ucolor_f.txt").c_str());\n\n    umvp_location = glGetUniformLocation(shaderProgramId, "uMVP");\n\n    apos_location = glGetAttribLocation(shaderProgramId, "aPos");\n    glEnableVertexAttribArray(apos_location);\n    glVertexAttribPointer(apos_location, 3, GL_FLOAT, GL_FALSE,\n        sizeof(vertices[0]), (void*)0);\n\n    ucol_location = glGetUniformLocation(shaderProgramId, "uColor");\n\n    glUseProgram(shaderProgramId);\n\n    float uColor[4] = { 1.f, 0.f, 1.f, 1.f }; \/\/R,G,B, alpha\n    glUniform4fv(ucol_location, 1, uColor);\n\n    return 1;\n}\nint TheGame::drawFrame() {\n    myPollEvents();\n\n    mat4x4 m, p, mvp;\n\n    \/\/glClearColor(0.0, 0.0, 0.5, 1.0);\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(shaderProgramId);\n    glUniformMatrix4fv(umvp_location, 1, GL_FALSE, (const GLfloat*)mvp);\n\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

              \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u0447\u0443\u0442\u044c-\u043b\u0438 \u043d\u0435 \u0432\u0434\u0432\u043e\u0435 \u043a\u043e\u0440\u043e\u0447\u0435.<\/p>\n\n\n\n

              \u0412\u0430\u0436\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/p>\n\n\n\n

              • \u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u0434 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432 vertex_shader_text <\/em>\u0438 fragment_shader_text<\/em> \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442.<\/li>
              • \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 vertex_shader <\/em>\u0438 fragment_shader <\/em>\u0442\u043e\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b.<\/li>
              • \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0440\u0443\u0433\u0430\u044f. \u0412\u043c\u0435\u0441\u0442\u043e 2D \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 + \u0446\u0432\u0435\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0441\u0442\u043e 3D \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0431\u0435\u0437 \u0446\u0432\u0435\u0442\u0430.<\/li>
              • \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u0435\u0434\u0438\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u044f.<\/li><\/ul>\n\n\n\n

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


                \n\n\n\n

                11. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a:<\/p>\n\n\n\n

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

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

                \u041e\u0442\u043b\u0438\u0447\u043d\u043e.<\/p>\n\n\n\n


                \n\n\n\n

                \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430<\/p>\n\n\n\n

                \u0410\u043d\u0434\u0440\u043e\u0438\u0434\u0435<\/h2>\n\n\n\n

                12. \u0417\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Visual Studio, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c C:\\CPP\\a999hello\\p_android\\p_android.sln<\/em><\/p>\n\n\n\n


                \n\n\n\n

                13. \u041f\u043e\u0434 xEngine <\/em>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Existing Item<\/strong><\/p>\n\n\n\n

                \u0418\u0434\u0435\u043c \u0432 C:\\CPP\\engine<\/em>, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c<\/p>\n\n\n\n

                • Shader.cpp<\/li>
                • Shader.h<\/li>
                • utils.cpp<\/li>
                • utils.h<\/li><\/ul>\n\n\n\n

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


                  \n\n\n\n

                  \u041d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c myFopen_s(..)<\/em> \u0434\u043b\u044f \u0410\u043d\u0434\u0440\u043e\u0438\u0434\u0430.<\/p>\n\n\n\n

                  14. \u041e\u0442\u043a\u0440\u043e\u0435\u043c platform.h<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n

                  \n#pragma once\n\nvoid mylog(const char* _Format, ...);\nvoid mySwapBuffers();\nvoid myPollEvents();\nint myFopen_s(FILE** pFile, const char* filePath, const char* mode);\n\n<\/pre><\/div>\n\n\n

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


                  \n\n\n\n

                  15. \u041e\u0442\u043a\u0440\u043e\u0435\u043c platform.cpp<\/em> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n

                  \n#include <android\/log.h>\n#include "stdio.h"\n#include "TheGame.h"\n\nextern struct android_app* androidApp;\nextern const ASensor* accelerometerSensor;\nextern ASensorEventQueue* sensorEventQueue;\n\nextern EGLDisplay androidDisplay;\nextern EGLSurface androidSurface;\nextern TheGame theGame;\n\nvoid mylog(const char* _Format, ...) {\n#ifdef _DEBUG\n    char outStr[1024];\n    va_list _ArgList;\n    va_start(_ArgList, _Format);\n    vsprintf(outStr, _Format, _ArgList);\n    __android_log_print(ANDROID_LOG_INFO, "mylog", outStr, NULL);\n    va_end(_ArgList);\n#endif\n};\n\nvoid mySwapBuffers() {\n\teglSwapBuffers(androidDisplay, androidSurface);\n}\nvoid myPollEvents() {\n\t\/\/ Read all pending events.\n\tint ident;\n\tint events;\n\tstruct android_poll_source* source;\n\n\t\/\/ If not animating, we will block forever waiting for events.\n\t\/\/ If animating, we loop until all events are read, then continue\n\t\/\/ to draw the next frame of animation.\n\twhile ((ident = ALooper_pollAll(0, NULL, &events,\n\t\t(void**)&source)) >= 0) {\n\n\t\t\/\/ Process this event.\n\t\tif (source != NULL) {\n\t\t\tsource->process(androidApp, source);\n\t\t}\n\n\t\t\/\/ If a sensor has data, process it now.\n\t\tif (ident == LOOPER_ID_USER) {\n\t\t\tif (accelerometerSensor != NULL) {\n\t\t\t\tASensorEvent event;\n\t\t\t\twhile (ASensorEventQueue_getEvents(sensorEventQueue,\n\t\t\t\t\t&event, 1) > 0) {\n\t\t\t\t\t\/\/LOGI("accelerometer: x=%f y=%f z=%f",\n\t\t\t\t\t\/\/\tevent.acceleration.x, event.acceleration.y,\n\t\t\t\t\t\/\/\tevent.acceleration.z);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t\/\/ Check if we are exiting.\n\t\tif (androidApp->destroyRequested != 0) {\n\t\t\ttheGame.bExitGame = true;\n\t\t\tbreak;\n\t\t}\n\t}\n}\nint myFopen_s(FILE** pFile, const char* filePath, const char* mode) {\n\t*pFile = fopen(filePath, mode);\n\tif (*pFile == NULL) {\n\t\tmylog("ERROR: can't open file %s\\n", filePath);\n\t\treturn -1;\n\t}\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n

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


                  \n\n\n\n

                  16. \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c, \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c, \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c.<\/p>\n\n\n\n

                  \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a.<\/p>\n\n\n\n

                  \u041d\u043e\u0440\u043c.<\/p>\n\n\n\n


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

                  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0448\u0435\u0439\u0434\u0435\u0440\u044b! \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043b\u0438\u0432\u043a\u0430 \u0441\u043f\u043b\u043e\u0448\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u043f\u0443\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0432\u0435\u0445\u043d\u043e\u0441\u0442\u0438 (\u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 – \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430). \u0428\u0435\u0439\u0434\u0435\u0440\u044b \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043d\u0430 GLSL (OpenGL Shading Language \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043d\u0430 C). GLSL \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0433\u0440\u0430\u0444-\u043a\u0430\u0440\u0442\u0435. \u0418\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0430\u044f \u0448\u0435\u0439\u0434\u0435\u0440-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 2-\u0445 \u0448\u0435\u0439\u0434\u0435\u0440\u043e\u0432: Vertex Shader, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0435\u0448\u0438\u043d (\u0432\u043a\u043b\u044e\u0447\u0430\u044f […]<\/p>\n","protected":false},"author":1,"featured_media":1208,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-504","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cross-platform-3d"],"_links":{"self":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/504","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=504"}],"version-history":[{"count":9,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/504\/revisions"}],"predecessor-version":[{"id":1646,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/504\/revisions\/1646"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/media\/1208"}],"wp:attachment":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/media?parent=504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/categories?post=504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/tags?post=504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}