<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Sinf.org</title>
    <link>https://sinf.org/</link>
    <description>Recent content on Sinf.org</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 09 Dec 2025 21:09:06 +0200</lastBuildDate>
    <atom:link href="https://sinf.org/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>OpenGL Terrain Rendering</title>
      <link>https://sinf.org/posts/scsh-2025-12-09-opengl_terrain_rendering/</link>
      <pubDate>Tue, 09 Dec 2025 21:09:06 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-12-09-opengl_terrain_rendering/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/20251209-desert.png&#34; alt=&#34;Desert rendered from height map&#34;&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Desert rendered from height map&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>OpenGL Instancing</title>
      <link>https://sinf.org/posts/scsh-2025-06-03-opengl_instancing/</link>
      <pubDate>Tue, 03 Jun 2025 15:03:43 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-06-03-opengl_instancing/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-06-03-instancing.jpg&#34; alt=&#34;Experimenting with instancing in PlanetSweeper&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>PomodoroLog different views</title>
      <link>https://sinf.org/posts/scsh-2025-05-18-pomodorolog_different_views/</link>
      <pubDate>Sun, 18 May 2025 15:03:51 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-05-18-pomodorolog_different_views/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-05-18-views.png&#34; alt=&#34;Different views and window sizes&#34;&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Preview of PomodoroLog&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>PomodoroLog Themes</title>
      <link>https://sinf.org/posts/scsh-2025-05-14-pomodorolog_themes/</link>
      <pubDate>Wed, 14 May 2025 15:03:09 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-05-14-pomodorolog_themes/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-05-14-themes.png&#34; alt=&#34;Themes&#34;&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Various color themes for PomodoroLog.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Pomodoro mini projects</title>
      <link>https://sinf.org/posts/scsh-2025-05-01-pomodoro_mini_projects/</link>
      <pubDate>Thu, 01 May 2025 15:03:26 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-05-01-pomodoro_mini_projects/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-05-01-pomodoro.png&#34; alt=&#34;PomodoroLog project&#34;&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Small pomodoro timer project&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>PowerUps</title>
      <link>https://sinf.org/posts/scsh-2025-02-08-powerups/</link>
      <pubDate>Sat, 08 Feb 2025 15:03:49 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-02-08-powerups/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-02-08-powerup.png&#34; alt=&#34;Power Up picker for PlanetSweeper&#34;&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Added power ups to PlanetSweeper.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Menu System</title>
      <link>https://sinf.org/posts/scsh-2025-01-21-menu_system/</link>
      <pubDate>Tue, 21 Jan 2025 15:03:07 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2025-01-21-menu_system/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-10-28-menu1.jpg&#34; alt=&#34;PlanetSweeper menu system&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2025-01-21-menu2.png&#34; alt=&#34;PlanetSweeper game selection&#34;&gt;&lt;/p&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Main menu and game selection for PlanetSweeper.&lt;/p&gt;&#xA;&#xA;</description>
    </item>
    <item>
      <title>Tile animation and explosions</title>
      <link>https://sinf.org/posts/scsh-2024-10-13-tile_animation_and_explosions/</link>
      <pubDate>Sun, 13 Oct 2024 02:02:24 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-10-13-tile_animation_and_explosions/</guid>
      <description>&lt;p&gt;&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-10-13-explosion.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-10-13-explosion.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Various tile and explosion effects.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Bloom</title>
      <link>https://sinf.org/posts/scsh-2024-09-30-bloom/</link>
      <pubDate>Mon, 30 Sep 2024 02:02:56 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-09-30-bloom/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-09-30-bloom.png&#34; alt=&#34;Added bloom to the engine&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Graphics progress</title>
      <link>https://sinf.org/posts/scsh-2024-09-23-graphics_progress/</link>
      <pubDate>Mon, 23 Sep 2024 16:04:10 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-09-23-graphics_progress/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-09-23-progress.png&#34; alt=&#34;Progress over the last few months&#34;&gt;&lt;p class=&#34;note&#34;&gt;Progress over the last few months&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Better light and colors</title>
      <link>https://sinf.org/posts/scsh-2024-09-16-better_light_and_colors/</link>
      <pubDate>Mon, 16 Sep 2024 15:03:53 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-09-16-better_light_and_colors/</guid>
      <description>&lt;p&gt;&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-09-16-engine-colors.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-09-16-engine-colors.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&lt;p class=&#34;note&#34;&gt;Same scene from before but with better lighting.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Engine Demo</title>
      <link>https://sinf.org/posts/scsh-2024-09-01-engine_demo/</link>
      <pubDate>Sun, 01 Sep 2024 15:03:54 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-09-01-engine_demo/</guid>
      <description>&lt;p&gt;&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-09-01-engine-demo.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-09-01-engine-demo.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&lt;p class=&#34;note&#34;&gt;A small demo of engine for diffent game type.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Splash Screen</title>
      <link>https://sinf.org/posts/scsh-2024-06-30-splash_screen/</link>
      <pubDate>Sun, 30 Jun 2024 15:03:37 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-06-30-splash_screen/</guid>
      <description>&lt;p&gt;&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-06-30-splash.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-06-30-splash.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&#xA;&lt;p class=&#34;note&#34;&gt;Implemented a splash screen on startup.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Basic Minesweeper Gameplay</title>
      <link>https://sinf.org/posts/scsh-2024-06-19-basic_minesweeper_gameplay/</link>
      <pubDate>Wed, 19 Jun 2024 15:03:56 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-06-19-basic_minesweeper_gameplay/</guid>
      <description>&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-06-19-gameplay.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-06-19-gameplay.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&#xA;</description>
    </item>
    <item>
      <title>Player Headlights</title>
      <link>https://sinf.org/posts/scsh-2024-06-12-player_headlights/</link>
      <pubDate>Wed, 12 Jun 2024 15:03:33 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-06-12-player_headlights/</guid>
      <description>&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-06-12-spotlight.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-06-12-spotlight.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&#xA;</description>
    </item>
    <item>
      <title>Shadow Rendering</title>
      <link>https://sinf.org/posts/scsh-2024-06-05-shadow_rendering/</link>
      <pubDate>Wed, 05 Jun 2024 15:03:56 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-06-05-shadow_rendering/</guid>
      <description>&lt;video class=&#34;video&#34; preload=&#34;none&#34; poster=&#34;/images/2024-06-05-shadows.jpg&#34; controls&gt;&#xA;  &lt;source src=&#34;https://sinf.org/images/2024-06-05-shadows.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&#xA;</description>
    </item>
    <item>
      <title>Better Colors</title>
      <link>https://sinf.org/posts/scsh-2024-05-26-better_colors/</link>
      <pubDate>Sun, 26 May 2024 15:03:04 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-05-26-better_colors/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-05-26-planet.gif&#34; alt=&#34;Made planet look more like a planet&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Planet Models</title>
      <link>https://sinf.org/posts/scsh-2024-05-17-planet_models/</link>
      <pubDate>Fri, 17 May 2024 15:03:13 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-05-17-planet_models/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-05-17-models.gif&#34; alt=&#34;Added objects (trees, building, etc) on planet&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Skeleton Animation</title>
      <link>https://sinf.org/posts/scsh-2024-05-06-skeleton_animation/</link>
      <pubDate>Mon, 06 May 2024 15:03:23 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-05-06-skeleton_animation/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-05-06-animation.gif&#34; alt=&#34;Basic skeleton animation in OpenGL&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Settings Menu Demo</title>
      <link>https://sinf.org/posts/scsh-2024-04-14-settings_menu_demo/</link>
      <pubDate>Sun, 14 Apr 2024 15:03:28 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-04-14-settings_menu_demo/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-04-14-menu.gif&#34; alt=&#34;Example of live graphics settings change.&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>OpenGL Polyhedron</title>
      <link>https://sinf.org/posts/scsh-2024-04-07/</link>
      <pubDate>Sun, 07 Apr 2024 01:31:42 +0200</pubDate>
      <guid>https://sinf.org/posts/scsh-2024-04-07/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/2024-04-07-polyhedron.gif&#34; alt=&#34;Polyhedron generated and rendered in OpenGL&#34;&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>glUniformLocation Benchmark</title>
      <link>https://sinf.org/posts/gluniformlocation/</link>
      <pubDate>Tue, 23 Jan 2024 01:00:38 +0200</pubDate>
      <guid>https://sinf.org/posts/gluniformlocation/</guid>
      <description>&lt;p&gt;I was looking for some information on whether or not calling &lt;code&gt;glUniformLocation&lt;/code&gt; for every frame has any performance impact. Everything I found was either claims without any sources or very old data.&lt;/p&gt;&#xA;&lt;p&gt;Since I couldn&amp;rsquo;t find anything useful, I ended up writing a small benchmark program to test 3 different ways of using uniform locations:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Calling &lt;code&gt;glUniformLocation&lt;/code&gt; every time (Lookup).&lt;/li&gt;&#xA;&lt;li&gt;Getting the location at first call and caching it in a std::map using compile time keys (Cached).&lt;/li&gt;&#xA;&lt;li&gt;Getting the location at load time and storing the location in a variable (Static).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The test uses a shader with 20 vec4 uniforms (10 in vertex, 10 in fragment) and sets each uniform 50 times per render (less than 50 times made it hard to measure the time delta) with 1000 renders per run to come up with an average time.&lt;/p&gt;&#xA;&lt;p&gt;Here are the results of a modern high-end desktop and 5 year old laptop both running Windows 11.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th style=&#34;text-align:left&#34;&gt;Machine / Method&lt;/th&gt;&#xA;&lt;th style=&#34;text-align:right&#34;&gt;First&lt;/th&gt;&#xA;&lt;th style=&#34;text-align:right&#34;&gt;Second&lt;/th&gt;&#xA;&lt;th style=&#34;text-align:right&#34;&gt;Fastest&lt;/th&gt;&#xA;&lt;th style=&#34;text-align:right&#34;&gt;Slowest&lt;/th&gt;&#xA;&lt;th style=&#34;text-align:right&#34;&gt;Average&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;&lt;em&gt;NVIDIA RTX4090&lt;/em&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Lookup&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1423&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1047&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;578&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;2317&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;929&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Cached&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;366&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;147&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;105&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;402&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;134&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Static&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;159&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;21&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;5&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;167&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;10&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;&lt;em&gt;i7-8565U / UHD 620&lt;/em&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;td&gt;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Lookup&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1300&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1115&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;870&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1984&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1043&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Cached&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;676&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;671&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;488&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;1849&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;579&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td style=&#34;text-align:left&#34;&gt;- Static&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;130&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;129&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;73&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;459&lt;/td&gt;&#xA;&lt;td style=&#34;text-align:right&#34;&gt;103&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;em&gt;Numbers are in μs/microseconds based on 5 runs of the benchmark program for each machine/method combination. The first frame value for &amp;ldquo;cached&amp;rdquo; is misleading since it loops all 20 variable 50 times so only needs to call glUniformLocation for 2% of the calls. With 1000 unique uniform values the first frame would likely be similar to &amp;ldquo;lookup&amp;rdquo; results.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;The difference is pretty significations. If running at 60 fps with 1000 uniforms then looking up the location every frame would use up 5.6% of the frame time on average vs only 0.1-0.6% (depending on hardware) when storing the location.&lt;/p&gt;&#xA;&lt;p&gt;The idea of caching locations in a std::map worked better than lookup but still significantly worse than using a custom class with uniform variables hardcoded.&lt;/p&gt;&#xA;&lt;p&gt;Benchmark &lt;a href=&#34;https://git.sinf.org/sinf/opengl-samples/src/branch/main/gl_uniform_benchmark&#34;&gt;source code available here&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ArcRace Update</title>
      <link>https://sinf.org/posts/arcrace-update/</link>
      <pubDate>Fri, 19 Jan 2024 00:56:36 +0200</pubDate>
      <guid>https://sinf.org/posts/arcrace-update/</guid>
      <description>&lt;p&gt;A small update to my 3D game demo to test some shader and model loading code.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://sinf.org/downloads/arcrace-1.1.zip&#34;&gt;Download&lt;/a&gt; (2.4MB, Windows 10/11)&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/arcrace11.jpg&#34; alt=&#34;ArcRace 1.1&#34;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;libraries&#34;&gt;Libraries&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.glfw.org/&#34;&gt;GLFW&lt;/a&gt;: Window, OpenGL context, and keyboard input&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/google/galogen&#34;&gt;Galogen&lt;/a&gt;: OpenGL API headers&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/g-truc/glm&#34;&gt;GLM&lt;/a&gt;: Vector and matrix math&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/nothings/stb/&#34;&gt;std_image&lt;/a&gt;: Texture loading&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://solhsa.com/soloud/&#34;&gt;SoLoud&lt;/a&gt;: Sound playback&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/nlohmann/json&#34;&gt;JSON for Modern C++&lt;/a&gt;: Parsing JSON in GLTF models.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4 id=&#34;music--sound-fx&#34;&gt;Music &amp;amp; Sound FX&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://pixabay.com/music/video-games-chiptune-grooving-142242/&#34;&gt;Chiptune Grooving by K00sin&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://sfxr.me/&#34;&gt;Jsfxr&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>OpenGL Text using stb_truetype</title>
      <link>https://sinf.org/posts/opengl-text-stb/</link>
      <pubDate>Thu, 11 Jan 2024 00:47:58 +0200</pubDate>
      <guid>https://sinf.org/posts/opengl-text-stb/</guid>
      <description>&lt;p&gt;A quick on using stb_truetype.h to render text in OpenGL using an alpha mask texture with the &lt;code&gt;stbtt_PackBegin&lt;/code&gt;/&lt;code&gt;stbtt_PackFontRage&lt;/code&gt; API.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/stbtt.png&#34; alt=&#34;Text rendering&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;First load the font. The important data is the pixel data for the texture and packed character data. The example below packs characters from codepoints 0 to 125. If a different starting point than 0 is used then lookups in charData array must be offset by that number. (With 0-125 uppercase A will be at &lt;code&gt;charData[65]&lt;/code&gt;, with 32-125 then A is at &lt;code&gt;charData[65-32]&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;stbtt_pack_context packContext;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;stbtt_packedchar charData[&lt;span style=&#34;color:#f99b15&#34;&gt;126&lt;/span&gt;];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#fec418&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#fec418&#34;&gt;char&lt;/span&gt; pixels[TEXTURE_WIDTH &lt;span style=&#34;color:#5bc4bf&#34;&gt;*&lt;/span&gt; TEXTURE_HEIGHT];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06b6ef&#34;&gt;tbtt_PackBegin&lt;/span&gt;(&lt;span style=&#34;color:#5bc4bf&#34;&gt;&amp;amp;&lt;/span&gt;packContext, pixels, &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               TEXTURE_WIDTH, TEXTURE_HEIGHT,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;               TEXTURE_WIDTH, &lt;span style=&#34;color:#f99b15&#34;&gt;1&lt;/span&gt;, NULL);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06b6ef&#34;&gt;stbtt_PackFontRange&lt;/span&gt;(&lt;span style=&#34;color:#5bc4bf&#34;&gt;&amp;amp;&lt;/span&gt;packContext, (&lt;span style=&#34;color:#fec418&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#fec418&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#5bc4bf&#34;&gt;*&lt;/span&gt;)ttfData, &lt;span style=&#34;color:#f99b15&#34;&gt;0&lt;/span&gt;, TEXTURE_FONT_SIZE,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f99b15&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#f99b15&#34;&gt;125&lt;/span&gt;, charData);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06b6ef&#34;&gt;stbtt_PackEnd&lt;/span&gt;(&lt;span style=&#34;color:#5bc4bf&#34;&gt;&amp;amp;&lt;/span&gt;packContext);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;p&gt;Then put the pixel data into an OpenGL texture. The data is a single channel monochrome color:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e7e9db;background-color:#2f1e2e;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06b6ef&#34;&gt;glTexImage2D&lt;/span&gt;(GL_TEXTURE_2D, &lt;span style=&#34;color:#f99b15&#34;&gt;0&lt;/span&gt;, GL_R8,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             TEXTURE_WIDTH, TEXTURE_HEIGHT, &lt;span style=&#34;color:#f99b15&#34;&gt;0&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             GL_RED, GL_UNSIGNED_BYTE, pixels);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;&lt;p&gt;To render text, lookup each character in the charData array to get the position in the texture as &lt;code&gt;char.x0, char.x1, char.y0, char.y1&lt;/code&gt;. The actual size of the character can be calculated from the offsets as &lt;code&gt;char.xoff2 - char.xoff&lt;/code&gt; and &lt;code&gt;char.yoff2 - char.yoff&lt;/code&gt;. The xoff values are the start and end offset from the left. Yoff are the start and end offset from the baseline (y values will be negative when above the baseline, positive when below).&#xA;The x distance to the next character is available in &lt;code&gt;char.xadvance&lt;/code&gt;. This can also be used to calculating the full width of a string before rendering for things like scaling to fit or center/right aligning text.&lt;/p&gt;&#xA;&lt;p&gt;MIT licensed &lt;a href=&#34;https://git.sinf.org/sinf/opengl-samples/src/branch/main/stb_truetype_example&#34;&gt;demo code available here&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ArcRace Mini Game</title>
      <link>https://sinf.org/posts/arcrace-mini-game/</link>
      <pubDate>Sun, 31 Dec 2023 15:24:13 +0200</pubDate>
      <guid>https://sinf.org/posts/arcrace-mini-game/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;&amp;#x1f4dd; An updated version 1.1 is &lt;a href=&#34;https://sinf.org/posts/arcrace-update&#34;&gt;now available here&lt;/a&gt;.&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&lt;/table&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;A small game demo made to refresh OpenGL and general 3D programming.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://sinf.org/downloads/arcrace-1.0.zip&#34;&gt;Download&lt;/a&gt; (2.4MB, Windows 10/11)&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://sinf.org/images/arcrace10.jpg&#34; alt=&#34;ArcRace 1.0&#34;&gt;&lt;/p&gt;&#xA;&lt;h5 id=&#34;libraries&#34;&gt;Libraries&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.glfw.org/&#34;&gt;GLFW&lt;/a&gt;: Window, OpenGL context, and keyboard input&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/google/galogen&#34;&gt;Galogen&lt;/a&gt;: OpenGL API headers&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/g-truc/glm&#34;&gt;GLM&lt;/a&gt;: Vector and matrix math&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/nothings/stb/&#34;&gt;std_image&lt;/a&gt;: Texture loading&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://solhsa.com/soloud/&#34;&gt;SoLoud&lt;/a&gt;: Sound playback&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h5 id=&#34;music--sound-fx&#34;&gt;Music &amp;amp; Sound FX&lt;/h5&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://pixabay.com/music/video-games-chiptune-grooving-142242/&#34;&gt;Chiptune Grooving by K00sin&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://sfxr.me/&#34;&gt;Jsfxr&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
  </channel>
</rss>
