-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
36 lines (36 loc) · 20.7 KB
/
index.html
File metadata and controls
36 lines (36 loc) · 20.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!doctype html><html lang=en itemscope itemtype=http://schema.org/WebPage><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1"><title>Clark Kromenaker</title>
<meta name=author content="Clark Kromenaker"><script type=application/ld+json>{"@context":"http://schema.org","@type":"WebSite","name":"Clark Kromenaker","url":"https:\/\/clarkkromenaker.com\/"}</script><script type=application/ld+json>{"@context":"http://schema.org","@type":"Organization","name":"","url":"https:\/\/clarkkromenaker.com\/"}</script><meta property="og:title" content="Clark Kromenaker"><meta property="og:image" content="https://clarkkromenaker.com/img/avatar-icon.png"><meta property="og:url" content="https://clarkkromenaker.com/"><meta property="og:type" content="website"><meta property="og:site_name" content="Clark Kromenaker"><meta name=twitter:title content="Clark Kromenaker"><meta name=twitter:image content="https://clarkkromenaker.com/img/avatar-icon.png"><meta name=twitter:card content="summary_large_image"><link href=https://clarkkromenaker.com/img/favicon.ico rel=icon type=image/x-icon><meta name=generator content="Hugo 0.133.1"><link rel=alternate href=https://clarkkromenaker.com/index.xml type=application/rss+xml title="Clark Kromenaker"><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css integrity=sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X crossorigin=anonymous><link rel=stylesheet href=https://use.fontawesome.com/releases/v5.5.0/css/all.css integrity=sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU crossorigin=anonymous><link rel=stylesheet href=https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css integrity=sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u crossorigin=anonymous><link rel=stylesheet href=https://clarkkromenaker.com/css/main.css><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic"><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"><link rel=stylesheet href=https://clarkkromenaker.com/css/syntax.css><link rel=stylesheet href=https://clarkkromenaker.com/css/codeblock.css><link rel=stylesheet href=https://clarkkromenaker.com//css/portfolio.css><link rel=stylesheet href=https://clarkkromenaker.com//css/misc.css><link rel=stylesheet href=https://clarkkromenaker.com//css/overrides.css><script src=https://clarkkromenaker.com//js/darkModeToggle.js></script></head><body><nav class="navbar navbar-default navbar-fixed-top navbar-custom"><div class=container-fluid><div class=navbar-header><button type=button class=navbar-toggle data-toggle=collapse data-target=#main-navbar>
<span class=sr-only>Toggle navigation</span>
<span class=icon-bar></span>
<span class=icon-bar></span>
<span class=icon-bar></span>
</button>
<a class=navbar-brand href=https://clarkkromenaker.com/>Clark Kromenaker</a></div><div class="collapse navbar-collapse" id=main-navbar><ul class="nav navbar-nav navbar-right"><li><a title=Blog href=/>Blog</a></li><li><a title=Portfolio href=/portfolio>Portfolio</a></li><li><a title=About href=/about>About</a></li><li><a title=Tags href=/tags>Tags</a></li><li class=navlinks-container id=dark-mode-toggle><a href=javascript:toggleColorScheme();><i id=icon-sun class="fas fa-sun"></i>
<i id=icon-moon class="fas fa-moon"></i></a></li></ul></div><div class=avatar-container><div class=avatar-img-border><a title="Clark Kromenaker" href=https://clarkkromenaker.com/><img class=avatar-img src=https://clarkkromenaker.com/img/avatar-icon.png alt="Clark Kromenaker"></a></div></div></div></nav><div class=pswp tabindex=-1 role=dialog aria-hidden=true><div class=pswp__bg></div><div class=pswp__scroll-wrap><div class=pswp__container><div class=pswp__item></div><div class=pswp__item></div><div class=pswp__item></div></div><div class="pswp__ui pswp__ui--hidden"><div class=pswp__top-bar><div class=pswp__counter></div><button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title=Share></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button><div class=pswp__preloader><div class=pswp__preloader__icn><div class=pswp__preloader__cut><div class=pswp__preloader__donut></div></div></div></div></div><div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class=pswp__share-tooltip></div></div><button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button><div class=pswp__caption><div class=pswp__caption__center></div></div></div></div></div><header class=header-section><div class="intro-header no-img"><div class=container><div class=row><div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"><div class=page-heading><h1>Clark Kromenaker</h1><span class=page-subheading>Software developer based in Honolulu 🌊🌴🤙</span></div></div></div></div></div></header><div role=main class=container><div class=row><div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"><div class=posts-list><article class=post-preview><a href=https://clarkkromenaker.com/post/gfx-texture-loading/><h2 class=post-title>Optimizing Texture Loads in G-Engine</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on October 5, 2025</span></p><div class=post-entry><p>The texture loading code for
<a href=https://github.com/kromenak/gengine target=_blank>G-Engine</a> was written early in development, when I was eager to see some on-screen graphics to demonstrate tangible progress on the project. And then that code stayed relatively untouched for years. However, a
<a href=https://github.com/kromenak/gengine/issues/27 target=_blank>recent GitHub issue</a> highlighted a bottleneck - installing a mod containing very large textures caused scene load times to skyrocket!</p><p>In this post, I’ll explain how this problem was investigated and fixed. It may be a helpful read if you want to learn more about loading image data to be used by a graphics API such as OpenGL, or if you want to see how naive texture loading code can be improved.</p><a href=https://clarkkromenaker.com/post/gfx-texture-loading/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/c++/>C++</a>
<a href=https://clarkkromenaker.com//tags/opengl/>OpenGL</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/library-dynamic-loading-linux/><h2 class=post-title>Loading Shared Libraries on Linux</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on March 30, 2024</span></p><div class=post-entry><p>About three years ago, I wrote
<a href=/post/library-dynamic-loading-mac>a post</a> about wrangling dynamic libraries for Mac applications. I recently faced the same challenge on Linux, so I figured I’d write a follow up.</p><p>If you’re new to dealing with dynamic libraries, I’d recommend reviewing the previous post first - it covers some fundamentals that I won’t rehash here. Linux and Mac handle dynamic libraries in similar ways - but as you might guess, the tools used and some details vary.</p><a href=https://clarkkromenaker.com/post/library-dynamic-loading-linux/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/linux/>Linux</a>
<a href=https://clarkkromenaker.com//tags/build/>Build</a>
<a href=https://clarkkromenaker.com//tags/libraries/>Libraries</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/web-building-and-hosting/><h2 class=post-title>Building a Simple & Affordable Website</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on April 23, 2023</span></p><div class=post-entry><p>Website development is not exactly my forte. Though I’ve dabbled over the years, I spend most of my time in C++, C#, and Java. Despite this, it’s fun and helpful to run a blog and portfolio site (the very one you’re reading), so I need to know a little bit about websites!</p><p>Over the years, I’ve tried a few different approaches to building and hosting this website before landing on what you see before you. This site is simple, easy to maintain, fast to load, secure, and (importantly) inexpensive to host.</p><p>In this post, I’ll explain the approaches I’ve tried in the past and how this site is currently built.</p><a href=https://clarkkromenaker.com/post/web-building-and-hosting/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/web/>Web</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/cpp-eof/><h2 class=post-title>Reading to EOF</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on April 15, 2023</span></p><div class=post-entry><p>Here’s a simple programming task: read everything from a file into memory. To do this, you need to open the file, read the data, and stop reading when you reach the end of the file (abbreviated “EOF”).</p><p>But how do you KNOW you’ve reached the end of a file? That’s a simple question with a slightly complex/misleading answer.</p><a href=https://clarkkromenaker.com/post/cpp-eof/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/c++/>C++</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/cpp-cstrings/><h2 class=post-title>C-Strings in C++</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on May 29, 2022</span></p><div class=post-entry><p>Strings in C are simply arrays of <code>char</code> values - or in other words, a contiguous block of memory containing <code>chars</code>. C++ inherits that representation, but also provides a safer and easier-to-use option called <code>std::string</code>. In C++, the old C-style strings are often called <strong>C-Strings</strong>.</p><p>Most C++ gurus would advise you to avoid C-Strings and just use <code>std::string</code>. And it is true that <code>std::string</code> is safer and easier to use than C-Strings. Whereas <code>std::string</code> manages memory for you and has a ton of built-in functionality, C-Strings are essentially just blocks of <code>char</code> memory that you must manipulate with error-prone and inconsistent functions.</p><p>However, avoiding C-Strings entirely is difficult - sometimes you inherit code that’s using them, sometimes SDKs or libraries require you to use them, sometimes they are the most efficient option.</p><p>C-Strings can be confusing to work with. There are a variety of functions used to manipulate C-Strings, but some are deprecated or insecure, some are only available in certain compilers, and some have intricate ins and outs for using them properly.</p><p>So, my goal with this post is to catalogue some common operations you’d want to perform on C-Strings and identify the best options available, what to avoid, and what pitfalls exist.</p><a href=https://clarkkromenaker.com/post/cpp-cstrings/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/c++/>C++</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/cpp-manager-access/><h2 class=post-title>Accessing Managers in C++</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on October 30, 2021</span></p><div class=post-entry><p>Every game or game engine has at least a few managers under the hood. A manager is a collection of functions and data whose purpose is to “manage” something. You may send HTTP requests through an <code>HttpManager</code>. You may track the player’s inventory with an <code>InventoryManager</code>. You may play audio through an <code>AudioManager</code>. And so on.</p><p>How you access a manager is a seemingly mundane decision that can be surprisingly complex and paralyzing. Do you pass the manager as a function parameter? Use a global variable? Make a bunch of static functions or a namespace? Devise more elaborate mechanisms? Each option has pros and cons, and personal preference comes into play as well. Changing your mind later can incur significant refactoring overhead.</p><p>I’ve been coding games for about a decade now, so I’ve developed some opinions and ideas on this subject. I don’t think there’s a “best” or “right” way to do this, but there are a few ways to consider that might be useful in varying contexts.</p><p>Below, I’ll review several access options along with some pros/cons of each.</p><a href=https://clarkkromenaker.com/post/cpp-manager-access/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/c++/>C++</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/library-dynamic-loading-mac/><h2 class=post-title>Loading Dynamic Libraries on Mac</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on November 7, 2020</span></p><div class=post-entry><p>G-Engine uses various third-party libraries: ffmpeg for video playback, fmod for audio playback, zlib for decompression, etc. In all these cases, the library is included as a “dynamic library” (as opposed to a “static library”).</p><p>On Windows, when an executable needs a dynamic library, it searches for it in a few predefined locations, such as “the same directory as the executable”. On Mac and Linux, however, the situation is different and requires some consideration and explanation.</p><p>I was recently learning how macOS loads dynamic libraries, and it is not as intuitive or well documented as you might hope. This post attempts to lay things out in a clear and easy to digest way.</p><a href=https://clarkkromenaker.com/post/library-dynamic-loading-mac/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/mac/>Mac</a>
<a href=https://clarkkromenaker.com//tags/linux/>Linux</a>
<a href=https://clarkkromenaker.com//tags/build/>Build</a>
<a href=https://clarkkromenaker.com//tags/libraries/>Libraries</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/gengine-09-quaternions/><h2 class=post-title>G-Engine #9: Quaternions</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on October 16, 2020</span></p><div class=post-entry><p>Way back in
<a href=/post/gengine-04-rendering>G-Engine #4</a>, we rendered a triangle, and there was much rejoicing. Since then, the posts in this series have primarily focused on implementing mathematical constructs in code. This point is the final math pre-requisite before we can move on to more interesting things.</p><p>Think of a game engine as its own little universe: at first, there is nothing - the void. Concepts such as time, position, and orientation don’t exist yet. Suddenly, the game loop and delta time introduces the concept of time. With vectors, we can convey positions, directions, and distances. Slowly, our universe takes shape and we can convey important concepts in code.</p><p>But what about rotations? Vectors can store position, direction, and scale data, but they are not effective structures for 3D rotations. We need some other option to convey rotations in code.</p><p>One structure that is very effective for 3D rotations is the <strong>Quaternion</strong>. Much-maligned for their apparent complexity, Quaternions allow us to efficiently store and use 3D rotation data. In this post, we’ll explore why we use quaternions, what they are, how to perform common operations with them, and finally I’ll provide some tips for writing your own <code>Quaternion</code> class.</p><a href=https://clarkkromenaker.com/post/gengine-09-quaternions/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/g-engine/>G-Engine</a>
<a href=https://clarkkromenaker.com//tags/c++/>C++</a>
<a href=https://clarkkromenaker.com//tags/math/>Math</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/gengine-08-matrices/><h2 class=post-title>G-Engine #8: Matrices</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on July 4, 2020</span></p><div class=post-entry><p>Matrices are vital tools for 3D rendering. Graphics libraries expect you to use matrices to represent positions, rotations, and scales of 3D objects. Furthermore, matrices provide a convenient/effective mechanism for representing hierarchies of 3D objects and coordinate systems.</p><p>This post will briefly explain what matrices are, explain commonly used operations for 3D game development, and provide tips for writing matrix classes for your game engine.</p><a href=https://clarkkromenaker.com/post/gengine-08-matrices/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/g-engine/>G-Engine</a>
<a href=https://clarkkromenaker.com//tags/c++/>C++</a>
<a href=https://clarkkromenaker.com//tags/math/>Math</a> </div></article><article class=post-preview><a href=https://clarkkromenaker.com/post/gengine-07-vectors/><h2 class=post-title>G-Engine #7: Vectors</h2></a><p class=post-meta><span class=post-meta><i class=fas></i>Posted on March 14, 2020</span></p><div class=post-entry><p>We have added a basic math library to the 3D engine, but we’re still missing several fundamental mathematical building blocks to move forward and build full-fledged 3D environments. In particular, I want to implement Vectors, Matrices, and Quaternions. This post will cover <strong>Vectors</strong>, which enable the engine to represent important spacial concepts such as “position” and “direction”.</p><a href=https://clarkkromenaker.com/post/gengine-07-vectors/ class=post-read-more>[Read More]</a></div><div class=blog-tags><a href=https://clarkkromenaker.com//tags/g-engine/>G-Engine</a>
<a href=https://clarkkromenaker.com//tags/c++/>C++</a>
<a href=https://clarkkromenaker.com//tags/math/>Math</a> </div></article></div><ul class="pager main-pager"><li class=next><a href=https://clarkkromenaker.com/page/2/>Older Posts →</a></li></ul></div></div></div><div class=page-meta></div><footer><div class=container><div class=row><div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"><ul class="list-inline text-center footer-links"><li><a href=mailto:kromenak@gmail.com title="Email me"><span class="fa-stack fa-lg"><i class="fas fa-circle fa-stack-2x"></i>
<i class="fas fa-envelope fa-stack-1x fa-inverse"></i></span></a></li><li><a href=https://github.com/kromenak title=GitHub><span class="fa-stack fa-lg"><i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-github fa-stack-1x fa-inverse"></i></span></a></li><li><a href=https://linkedin.com/in/clarkkromenaker title=LinkedIn><span class="fa-stack fa-lg"><i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-linkedin fa-stack-1x fa-inverse"></i></span></a></li><li><a href=/index.xml title=RSS><span class="fa-stack fa-lg"><i class="fas fa-circle fa-stack-2x"></i>
<i class="fas fa-rss fa-stack-1x fa-inverse"></i></span></a></li></ul><p class="credits copyright text-muted">Clark Kromenaker
• ©
2025</p><p class="credits theme-by text-muted"><a href=https://gohugo.io>Powered by Hugo v0.133.1</a> • Theme <a href=https://github.com/halogenica/beautifulhugo>Beautiful Hugo</a> adapted from <a href=https://deanattali.com/beautiful-jekyll/>Beautiful Jekyll</a></p></div></div></div></footer><script src=https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js integrity=sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4 crossorigin=anonymous></script><script src=https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js integrity=sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa crossorigin=anonymous></script><script src=https://code.jquery.com/jquery-3.5.1.slim.min.js integrity=sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj crossorigin=anonymous></script><script src=https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js integrity=sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa crossorigin=anonymous></script><script src=https://clarkkromenaker.com/js/main.js></script><script>renderMathInElement(document.body)</script></body></html>