{"id":1839,"date":"2023-05-11T19:25:25","date_gmt":"2023-05-11T19:25:25","guid":{"rendered":"https:\/\/writingagame.com\/?p=1839"},"modified":"2026-04-08T16:59:50","modified_gmt":"2026-04-08T16:59:50","slug":"chapter-3-hello-windows-2","status":"publish","type":"post","link":"https:\/\/writingagame.com\/index.php\/2023\/05\/11\/chapter-3-hello-windows-2\/","title":{"rendered":"Chapter 3. Hello Windows"},"content":{"rendered":"\n<p><strong><strong>Tags:<\/strong> <\/strong><em>Visual Studio, OpenGL ES 3.2 on Desktop, GLFW, GLAD, Win32, C++, Cross-Platform Foundation<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Using OpenGL ES on the PC is less straight forward than on Android. The reason is that GL ES is intended for mobile devices, NOT for desktops. Fortunately, solutions exist. OpenGL producers strongly advise to use a window toolkit (GLFW) and an OpenGL loading libraries (GLAD). Well, let\u2019s download them.<\/p>\n\n\n\n<p>1. Create a placeholder for these libraries.<br>In <strong>Windows File Explorer<\/strong> in our <strong>root<\/strong> C:\\CPP folder create subfolder \u201cp_windows\u201d (&#8220;p&#8221; is for &#8220;platform&#8221;). We\u2019ll keep there all platform-specific stuff that is applicable to ALL our projects.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>2. <strong>Download GLFW<\/strong><\/p>\n\n\n\n<p>Go to <a href=\"https:\/\/www.glfw.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.glfw.org\/<\/a><\/p>\n\n\n\n<p>Proceed to <em>Download <\/em>link on top.<\/p>\n\n\n\n<p>We need <strong>64-bit Windows pre-compiled binaries<\/strong>.<\/p>\n\n\n\n<p>After download finished, in <strong>Windows File Explorer<\/strong> go to your <em>Downloads <\/em>folder, <\/p>\n\n\n\n<p>unzip <strong>glfw-3.3.8.bin.WIN64.zip<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>right-click on file<\/li>\n\n\n\n<li>Extarct All.<\/li>\n\n\n\n<li><strong>IMPORTANT<\/strong>: Change the destination (Copy to) to <em>C:\\CPP\\p_windows\\<\/em><\/li>\n\n\n\n<li>Extract.<\/li>\n<\/ul>\n\n\n\n<p>In  <strong>Windows File Explorer<\/strong> go to  <em>C:\\CPP\\p_windows\\<\/em>  folder and <strong>rename <\/strong><\/p>\n\n\n\n<p>extracted <strong>glfw-3.3.8.bin.WIN64<\/strong> folder to <strong>glfw338win64<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>3. <strong>Download GLAD<\/strong><\/p>\n\n\n\n<p>First &#8211; add subfolder \u201c<strong>glad<\/strong>&#8221; under <em>C:\\CPP\\p_windows\\<\/em>.<\/p>\n\n\n\n<p>Then &#8211; go to <a href=\"https:\/\/glad.dav1d.de\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/glad.dav1d.de\/<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Language: <strong>C\/C++<\/strong>, <\/li>\n\n\n\n<li>Specification: <strong>OpenGL<\/strong><\/li>\n\n\n\n<li>Change Profile to <strong>Core<\/strong><\/li>\n\n\n\n<li>Under gles2 pick <strong>Version 3.2<\/strong><\/li>\n\n\n\n<li>Scroll down<\/li>\n\n\n\n<li>Leave \u201cGenerate a loader\u201d selected<\/li>\n\n\n\n<li>Click <strong>Generate<\/strong><\/li>\n\n\n\n<li>On the next screen click on \u201c<strong>glad.zip<\/strong>\u201d to download<\/li>\n\n\n\n<li>When downloaded, go to <em>Downloads <\/em>folder and unzip <em>glad.zip<\/em> to <strong>C:\\CPP\\p_windows\\glad<\/strong><\/li>\n<\/ul>\n\n\n\n<p>Now our folders structure is:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b04\/c03\/01.jpg\"><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>4. <strong>Create VS projec<\/strong>t.<\/p>\n\n\n\n<p>GLFW website has a nice tutorial\/sample, which we will use here.  This sample was intended for OpenGL ES <strong>2.0<\/strong>. To make it compatible with <strong>3.2<\/strong> I had to modify it a bit. Also, it uses GLFW to create a window,  so we will create not &#8220;window&#8221;, but <strong>Console <\/strong>project.<\/p>\n\n\n\n<p>So, open Visual Studio, <strong>Create a new project<\/strong>, pick <em>Windows <\/em>filter, pick <em>Windows Desktop Wizard<\/em>, then &#8211; <strong>Next<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Project name \u2013 \u201c<strong>pw<\/strong>\u201d (&#8220;p&#8221; for &#8220;platform&#8221;, &#8220;w&#8221; &#8211; for &#8220;windows&#8221;)<\/li>\n\n\n\n<li>Location &#8211; <em>C:\\CPP\\a999hello<\/em><\/li>\n\n\n\n<li>Place solution and project in the same directory &#8211; yes (check)<\/li>\n<\/ul>\n\n\n\n<p>Then \u2013 <strong>Create<\/strong>.<\/p>\n\n\n\n<p>On the next screen pick \u201c<em>Console Application (.exe)<\/em>\u201d and \u201c<em>Empty project<\/em>\u201d:<\/p>\n\n\n\n<p>Then \u2013 <strong>Ok<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>5. <strong>Source code<\/strong>.<\/p>\n\n\n\n<p>Right-click on \u201cpw\u201d <strong>project <\/strong>(not on solution), then <em>Add -&gt; New item<\/em>.<\/p>\n\n\n\n<p>On &lt;Add New Item&gt; screen pick \u201cC++ File (.cpp)\u201d, name \u2013 \u201c<strong>main.cpp<\/strong>\u201d:<\/p>\n\n\n\n<p>Then \u2013 <strong>Add<\/strong>.<\/p>\n\n\n\n<p>Copy-Paste following code to <em>main.cpp<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; highlight: [3,22,35,58,68,69,81,86,87]; title: ; notranslate\" title=\"\">\n#include &lt;glad\/glad.h&gt;\n#define GLFW_INCLUDE_NONE\n#include &lt;GLFW\/glfw3.h&gt;\n#include &quot;linmath.h&quot;\n#include &lt;stdlib.h&gt;\n#include &lt;stdio.h&gt;\nstatic const struct\n{\n    float x, y;\n    float r, g, b;\n} vertices&#91;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};\nstatic const char* vertex_shader_text =\n&quot;#version 320 es\\n&quot;\n&quot;precision lowp float;\\n&quot;\n&quot;uniform mat4 MVP;\\n&quot;\n&quot;in vec3 vCol;\\n&quot;\n&quot;in vec2 vPos;\\n&quot;\n&quot;out vec3 color;\\n&quot;\n&quot;void main()\\n&quot;\n&quot;{\\n&quot;\n&quot;    gl_Position = MVP * vec4(vPos, 0.0, 1.0);\\n&quot;\n&quot;    color = vCol;\\n&quot;\n&quot;}\\n&quot;;\nstatic const char* fragment_shader_text =\n&quot;#version 320 es\\n&quot;\n&quot;precision lowp float;\\n&quot;\n&quot;in vec3 color;\\n&quot;\n&quot;out vec4 FragColor;\\n&quot;\n&quot;void main()\\n&quot;\n&quot;{\\n&quot;\n&quot;    FragColor = vec4(color, 1.0);\\n&quot;\n&quot;}\\n&quot;;\nstatic void error_callback(int error, const char* description)\n{\n    fprintf(stderr, &quot;Error: %s\\n&quot;, description);\n}\nstatic void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)\n{\n    if (key == GLFW_KEY_ESCAPE &amp;&amp; action == GLFW_PRESS)\n        glfwSetWindowShouldClose(window, GLFW_TRUE);\n}\nint main(void)\n{\n    GLFWwindow* window;\n    unsigned int vao_buffer;\n    unsigned int vertex_buffer, vertex_shader, fragment_shader, program;\n    int mvp_location, vpos_location, vcol_location;\n    float angle_z = 0;\n    glfwSetErrorCallback(error_callback);\n    if (!glfwInit())\n        exit(EXIT_FAILURE);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);\n    window = glfwCreateWindow(640, 480, &quot;Hello Windows&quot;, NULL, NULL);\n    if (!window)\n    {\n        glfwTerminate();\n        exit(EXIT_FAILURE);\n    }\n    glfwSetKeyCallback(window, key_callback);\n    glfwMakeContextCurrent(window);\n    gladLoadGLES2Loader((GLADloadproc)glfwGetProcAddress); \/\/gladLoadGL(glfwGetProcAddress);\n    glfwSwapInterval(1);\n    \/\/ NOTE: OpenGL error checks have been omitted for brevity\n    glGenVertexArrays(1, &amp;vao_buffer);\n    glBindVertexArray(vao_buffer);\n    glGenBuffers(1, &amp;vertex_buffer);\n    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);\n    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);\n    vertex_shader = glCreateShader(GL_VERTEX_SHADER);\n    glShaderSource(vertex_shader, 1, &amp;vertex_shader_text, NULL);\n    glCompileShader(vertex_shader);\n    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);\n    glShaderSource(fragment_shader, 1, &amp;fragment_shader_text, NULL);\n    glCompileShader(fragment_shader);\n    program = glCreateProgram();\n    glAttachShader(program, vertex_shader);\n    glAttachShader(program, fragment_shader);\n    glLinkProgram(program);\n    mvp_location = glGetUniformLocation(program, &quot;MVP&quot;);\n    vpos_location = glGetAttribLocation(program, &quot;vPos&quot;);\n    vcol_location = glGetAttribLocation(program, &quot;vCol&quot;);\n    glEnableVertexAttribArray(vpos_location);\n    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,\n        sizeof(vertices&#91;0]), (void*)0);\n    glEnableVertexAttribArray(vcol_location);\n    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,\n        sizeof(vertices&#91;0]), (void*)(sizeof(float) * 2));\n    while (!glfwWindowShouldClose(window))\n    {\n        float ratio;\n        int width, height;\n        mat4x4 m, p, mvp;\n        glfwGetFramebufferSize(window, &amp;width, &amp;height);\n        ratio = width \/ (float)height;\n        glViewport(0, 0, width, height);\n        glClear(GL_COLOR_BUFFER_BIT);\n        mat4x4_identity(m);\n        mat4x4_rotate_Z(m, m, (float)glfwGetTime());\n        mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);\n        mat4x4_mul(mvp, p, m);\n        glUseProgram(program);\n        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*)mvp);\n        glDrawArrays(GL_TRIANGLES, 0, 3);\n        glfwSwapBuffers(window);\n        glfwPollEvents();\n    }\n    glfwDestroyWindow(window);\n    glfwTerminate();\n    exit(EXIT_SUCCESS);\n}\n\n<\/pre><\/div>\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ES <strong>3.2<\/strong>-related changes are highlighted.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>6. Also this sample uses &#8220;<em>linmath.h<\/em>\u201d- a nice little library for linear math by <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/datenwolf\" target=\"_blank\">datenwolf<\/a>.<\/p>\n\n\n\nYou can download it <a href=\"https:\/\/writingagame.com\/img\/b04\/c03\/linmath.h\" download=\"\">here<\/a>.\n\n\n\n<p>Since we will use it in other projects too, let\u2019s place it <strong>outside <\/strong>of <em>a999hello <\/em>folder.<\/p>\n\n\n\n<p>In <strong>Windows File Explorer<\/strong> create a new folder for it: C:\\CPP\\<strong>engine<\/strong>\\<\/p>\n\n\n\n<p>Copy downloaded <em>linmath.h<\/em> file from <em>Downloads <\/em>directory to <\/p>\n\n\n\n<p><em>C:\\CPP\\engine\\<\/em><\/p>\n\n\n\n<p>In <strong>Visual Studio<\/strong> right-click on <strong>pw <\/strong>project -&gt; <em>Add -&gt; New <strong>Filter<\/strong><\/em>.<\/p>\n\n\n\n<p>Name &#8211; <strong>xEngine<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>&#8220;Filter&#8221; &#8211; is kind of virtual sub-folder inside of VS project.<\/li>\n\n\n\n<li>&#8220;x&#8221; before &#8220;Engine&#8221; &#8211; just to keep it after &#8220;Source Files&#8221; (it will be <strong>after <\/strong>when You open VS next time).<\/li>\n<\/ul>\n\n\n\n<p>Now &#8211; right-click on <em>xEngine <\/em>-&gt; <em>Add -&gt; <strong>Existing <\/strong>Item<\/em><\/p>\n\n\n\n<p><em>C:\\CPP\\engine\\<strong>linmath.h<\/strong><\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>7. Also we need to add <em>glad.c<\/em> file (from GLAD download) to the project. <\/p>\n\n\n\n<p>Right-click on \u201c<strong>Source Files<\/strong>\u201d -&gt; <em>Add -&gt; <strong>Existing<\/strong> item<\/em><\/p>\n\n\n\n<p><em>C:\\CPP\\p_windows\\glad\\src\\<strong>glad.c<\/strong><\/em><\/p>\n\n\n\n<p><strong>Add<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>8. Now we need to include references to downloaded libraries.<\/p>\n\n\n\n<p>Right-click on \u201c<strong>pw<\/strong>\u201d project -&gt; <em>Properties<\/em>.<\/p>\n\n\n\n<p><strong>IMPORTANT<\/strong>: Change Configuration from \u201cDebug\u201d to \u201c<strong>All configurations<\/strong>\u201d. Also, make sure that platform is set to <strong>x64<\/strong>.<\/p>\n\n\n\n<p>Now navigate to <em>Configuration properties -&gt; C++ -&gt; General<\/em> and open <em>Additional Include Directories -&gt; Edit<\/em>:<\/p>\n\n\n\n<p>In the Edit window add new line<\/p>\n\n\n\n<p>and <strong>manually <\/strong>add (copy-paste)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em>..\\..\\p_windows\\glad\\include<\/em> <\/code><\/pre>\n\n\n\n<p>(&#8220;..\\..&#8221; means 2 folder levels up), <\/p>\n\n\n\n<p>Then add another new line and add<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> <em>..\\..\\p_windows\\<em>glfw338win64<\/em>\\include<\/em><\/code><\/pre>\n\n\n\n<p>Add another new line and add<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\\..\\<em>engine<\/em><\/code><\/pre>\n\n\n\n<p>Then \u2013 <strong>Ok<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>9. Now navigate to <em>Configuration properties -&gt; Linker -&gt; General<\/em> and open<em> Additional Library Directories -&gt; Edit<\/em>.<\/p>\n\n\n\n<p>Add new line and add<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em>..\\..\\p_windows\\glfw338win64\\lib-vc2022<\/em><\/code><\/pre>\n\n\n\n<p>Then \u2013 <strong>Ok<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>10. Now move to <em>Configuration properties -&gt; Linker -&gt; Input<\/em> and open <em>Additional Dependencies -&gt; Edit<\/em>.<\/p>\n\n\n\n<p>Copy-Paste following libraries:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><em>glfw3.lib; glfw3dll.lib<\/em><\/code><\/pre>\n\n\n\n<p><strong>Ok, Apply, Ok<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>11. One more thing: We don\u2019t want our resulting executable to be called \u201cpw.exe\u201d (as it is defined by project\/solution name). We can change it in project properties. Right-click on <strong>pw <\/strong>project -&gt; <em>Properties -&gt; Configuration Properties -&gt; General<\/em>, pick <em>Target name<\/em>. To change it &#8211; click arrow-down, then <em>Edit<\/em>. Change name to \u201c<em>HelloWindows<\/em>\u201d. Then \u2013 Ok, Apply, Ok.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p>12. Now let\u2019s try to run (green arrow).<\/p>\n\n\n\n<p>Make sure that selected platform (in the top menu) is set to <strong>x64<\/strong>.<br>Works:<\/p>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b04\/c03\/02.jpg\"><\/p>\n\n\n\n<p>Sample is running, but it has TWO windows: Console window AND Application window. The reason is that we didn\u2019t want to create our window the \u201cWindows way\u201d, that\u2019s why we picked \u201cConsole application\u201d and then created our window using GLFW. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">How to rid of Console window:<\/h2>\n\n\n\n<p>13. Actually, having <em>Console window<\/em> is quite beneficial, since It can handle <em>printf<\/em> statements (OpenGL window can\u2019t), which is priceless for development, so we\u2019ll better keep Console window in Debug configuration as is, but will rid of it in Release.<\/p>\n\n\n\n<p>Right-click on \u201cpw\u201d project, open Properties.<\/p>\n\n\n\n<p>Change Configuration to <strong>Release<\/strong>.<\/p>\n\n\n\n<p>Go to <em>Configuration Properties -&gt; Linker -&gt; System<\/em> and change <em>SubSystem<\/em> from Console to <strong>Windows<\/strong><\/p>\n\n\n\n<p>Apply, Ok.<\/p>\n\n\n\n<p>Now, if we will try to compile our program (just don\u2019t forget to switch to Release configuration) we\u2019ll get an error:<\/p>\n\n\n\n<p><em>Error LNK2001 unresolved external symbol WinMain<\/em><\/p>\n\n\n\n<p>This is because now (after switch) linker is looking for a <em>WinMain()<\/em> entry point, not a <em>main()<\/em> one.<\/p>\n\n\n\n<p>If we want to keep our <strong>main()<\/strong> entry point (we do), we need to set the entry point to <em>mainCRTStartup<\/em> under Advanced Linker.<\/p>\n\n\n\n<p>So, again, open project Properties, <strong>Release <\/strong>configuration.<\/p>\n\n\n\n<p>Go to <em>Configuration Properties -&gt; Linker -&gt; Advanced<\/em>. Open <em>Entry Point -&gt; Edit<\/em>. Change to <strong>mainCRTStartup<\/strong><\/p>\n\n\n\n<p>Ok, Apply, Ok.<\/p>\n\n\n\n<p>Now Debug configuration works with Console window, Release \u2013 without.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n\n<p><img decoding=\"async\" src=\"https:\/\/writingagame.com\/img\/b04\/c03\/03.jpg\"><\/p>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Just in case, both Android and Windows solutions are saved on <a rel=\"noreferrer noopener\" href=\"https:\/\/writingagame.com\/index.php\/2023\/05\/11\/github\/\" target=\"_blank\">GitHub<\/a>.<\/p>\n\n\n\n<p>Link: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/bkantemir\/_wg_403\" target=\"_blank\">https:\/\/github.com\/bkantemir\/_wg_403<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>All pathes in both projects are relative, so it is safe to rename unzipped folder at your discretion,<\/li>\n<\/ul>\n\n\n\n<p><strong>WARNING:<\/strong> In the <em>Android<\/em> project, in case of renaming project directory, <em>build.gradle<\/em> can be confused and will give an error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;CXX1409] C:<strong>_wg_403<\/strong>\\a999hello\\pa\\app.cxx\\Debug\\1f254h29\\arm64-v8a\\android_gradle_build.json debug|arm64-v8a : expected buildFiles file 'C:\\<strong>CPP<\/strong>\\a999hello\\pa\\app\\src\\main\\cpp\\CMakeLists.txt' to exist<\/code><\/pre>\n\n\n\n<p>This is because (in my case) original project was build in <em>C:\/<strong>CPP<\/strong>\/a999hello<\/em> directory, and now I am trying to run it from <em>C:\/<strong>_wg_403<\/strong>\/a999hello<\/em>. If you encounter this problem, don&#8217;t worry, it&#8217;s easy to fix:<br>Just follow the link in the error message and fix the problematic references (there are 4 places in the file to fix). Like in this sample, from <em>C:\/<strong>CPP<\/strong>\/a999hello<\/em> to <em>C:\/<strong>_wg_403<\/strong>\/a999hello<\/em>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p class=\"mb-2\">Tags: Visual Studio, OpenGL ES 3.2 on Desktop, GLFW, GLAD, Win32, C++, Cross-Platform Foundation Using OpenGL ES on the PC is less straight forward than on Android. The reason is that GL ES is intended for mobile devices, NOT for desktops. Fortunately, solutions exist. OpenGL producers strongly advise to use a window toolkit (GLFW) and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":214,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1839","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cross-platform-3d"],"_links":{"self":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/1839","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/comments?post=1839"}],"version-history":[{"count":37,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/1839\/revisions"}],"predecessor-version":[{"id":4279,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/posts\/1839\/revisions\/4279"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/media\/214"}],"wp:attachment":[{"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/media?parent=1839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/categories?post=1839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/writingagame.com\/index.php\/wp-json\/wp\/v2\/tags?post=1839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}