<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jor-Dani-Elder</title>
    <link>https://jordanielder.com/</link>
    <description>Recent content on Jor-Dani-Elder</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 18 Sep 2023 15:11:46 -0500</lastBuildDate><atom:link href="https://jordanielder.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How To Start Website Development</title>
      <link>https://jordanielder.com/posts/how-to-start-website-development/</link>
      <pubDate>Mon, 18 Sep 2023 15:11:46 -0500</pubDate>
      
      <guid>https://jordanielder.com/posts/how-to-start-website-development/</guid>
      <description>The first time you look at computer code you might stare until you go cross-eyed, but with a little guidance that same mangled text can quickly become a sharp tool for creativity. This introductory guide is something I wish I had when starting out. I hope it can help those with zero experience get started or at least walk away with an understanding of a few concepts found in website development.</description>
      <content>&lt;p&gt;The first time you look at computer code you might stare until you go cross-eyed, but with a little guidance that same mangled text can quickly become a sharp tool for creativity. This introductory guide is something I wish I had when starting out. I hope it can help those with zero experience get started or at least walk away with an understanding of a few concepts found in website development.&lt;/p&gt;
&lt;h3 id=&#34;object&#34;&gt;Object&lt;/h3&gt;
&lt;p&gt;an &lt;a href=&#34;https://www.w3schools.com/js/js_objects.asp&#34;&gt;object&lt;/a&gt; in programming is a collection of data&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sentence&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;const&lt;/strong&gt; - stands for &lt;code&gt;constant variable&lt;/code&gt; a variable can typically change its value, but a constant variable will not change.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h3 id=&#34;html&#34;&gt;HTML&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.w3.org/wiki/Html/Training/What_is_HTML&#34;&gt;HTML&lt;/a&gt; stands for &lt;em&gt;Hypertext Markup Language&lt;/em&gt; which is in a class of languages called &lt;a href=&#34;https://en.wikipedia.org/wiki/Markup_language&#34;&gt;Markup Languages&lt;/a&gt; and it tells Web Browsers what to do with your important website information.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;webpage&amp;#34;&lt;/span&gt;&amp;gt;Hello world&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;div&lt;/strong&gt; - stands for &lt;code&gt;division&lt;/code&gt;, but not like in math, a &lt;code&gt;div&lt;/code&gt; tag seperates elements in a page.&lt;/li&gt;
&lt;li&gt;This div has an &lt;code&gt;id&lt;/code&gt; attribute we assign the name of &amp;ldquo;webpage&amp;rdquo; for use in our upcoming script.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt; - every &lt;em&gt;tag&lt;/em&gt; in HTML has a &lt;code&gt;closing tag&lt;/code&gt; represented with the name of the Element with a &lt;code&gt;/&lt;/code&gt; in front, in our case &lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;javascript&#34;&gt;Javascript&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/JavaScript&#34;&gt;Javascript&lt;/a&gt; is what&amp;rsquo;s called a &lt;a href=&#34;https://en.wikipedia.org/wiki/Scripting_language&#34;&gt;scripting language&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This example is actually a &lt;a href=&#34;https://en.wikipedia.org/wiki/Subset&#34;&gt;subset&lt;/a&gt; of Javascript, called a &lt;a href=&#34;https://en.wikipedia.org/wiki/Comparison_of_JavaScript-based_web_frameworks&#34;&gt;framework&lt;/a&gt;, named &lt;a href=&#34;https://en.wikipedia.org/wiki/JQuery&#34;&gt;jQuery&lt;/a&gt;. I find it both more efficient and easier to learn Javascript through playing with jQuery, but there are reasons, you&amp;rsquo;ll discover on your own, for pure Javascript and &lt;a href=&#34;https://en.wikipedia.org/wiki/Subset&#34;&gt;supersets&lt;/a&gt; of Javascript like &lt;a href=&#34;https://en.wikipedia.org/wiki/TypeScript&#34;&gt;Typescript&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;$&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#webpage&amp;#34;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;text&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;message&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sentence&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;$()&lt;/code&gt; is a &lt;code&gt;jQuery selector&lt;/code&gt; it&amp;rsquo;s a shorthand &lt;em&gt;selector&lt;/em&gt; for &lt;strong&gt;HTML DOM Elements&lt;/strong&gt;, &lt;strong&gt;Classes&lt;/strong&gt;, and in our case &lt;strong&gt;IDs&lt;/strong&gt;, denoted by the preceeding &lt;code&gt;#&lt;/code&gt; and our &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&amp;rsquo;s given name &lt;code&gt;webpage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;.&lt;/code&gt; following the &lt;code&gt;$()&lt;/code&gt; is a &lt;em&gt;&lt;a href=&#34;https://www.w3schools.com/jquery/jquery_chaining.asp&#34;&gt;chain operator&lt;/a&gt;&lt;/em&gt;, which &lt;em&gt;promises&lt;/em&gt; to execute each following &lt;em&gt;function&lt;/em&gt; attached, in our case it&amp;rsquo;s &lt;code&gt;text()&lt;/code&gt; with our &lt;strong&gt;Object&lt;/strong&gt; called.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Object&lt;/strong&gt; is in a format called &lt;em&gt;Javascript Object Notation&lt;/em&gt; typically shortened to &lt;em&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/JSON&#34;&gt;JSON&lt;/a&gt;&lt;/em&gt; which also uses a &lt;code&gt;.&lt;/code&gt; operator to denote the hierarchical structure we defined before&lt;/li&gt;
&lt;li&gt;Our &lt;code&gt;message&lt;/code&gt; variable contains the &lt;code&gt;sentence&lt;/code&gt; key which returns the &lt;code&gt;Hello world!&lt;/code&gt; value to the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with the ID (&lt;code&gt;#&lt;/code&gt;) of &lt;code&gt;webpage&lt;/code&gt; as &lt;code&gt;text()&lt;/code&gt;. This is the essence of &lt;a href=&#34;https://en.wikipedia.org/wiki/Data_structure&#34;&gt;data structures&lt;/a&gt; in a format called &lt;a href=&#34;https://en.wikipedia.org/wiki/Key%E2%80%93value_database&#34;&gt;Key-Value Store&lt;/a&gt; which will be your bread and butter for all things data going forward.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;filename&amp;gt;.html from a web browser&lt;/code&gt;&lt;br&gt;
&lt;img src=&#34;images/helloworld.png&#34; alt=&#34;Open Your File In A Web Browser&#34;&gt;&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;&lt;code&gt;Putting It All Together!&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;lang&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;meta&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;charset&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;meta&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;viewport&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;content&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;title&lt;/span&gt;&amp;gt;Key-Value Store Example&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;title&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://code.jquery.com/jquery-3.7.1.min.js&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;integrity&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;crossorigin&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;background:pink&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;webpage&amp;#34;&lt;/span&gt;&amp;gt;Hello world&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// Object
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sentence&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// Javascript
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;$&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#webpage&amp;#34;&lt;/span&gt;).&lt;span style=&#34;color:#a6e22e&#34;&gt;text&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;message&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;sentence&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;WOW THAT&amp;rsquo;S A LOT MORE STUFF!&lt;/li&gt;
&lt;li&gt;Now that you understand the basics and the few things that really mattered in this web page, there&amp;rsquo;s nothing left but to see a real world example such as this.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s a lot here, but one thing to play with is the &lt;code&gt;style&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag, start by changing that value and have fun learning!&lt;/li&gt;
&lt;li&gt;you can copy/paste this code into a file called &lt;code&gt;hello.html&lt;/code&gt; and open it in your web browser to view. To edit again right click and select &lt;code&gt;open with&lt;/code&gt; and choose a text editor. I recommend downloading &lt;a href=&#34;https://code.visualstudio.com/download&#34;&gt;Microsoft VS Code&lt;/a&gt; if you don&amp;rsquo;t have anything but notepad.&lt;/li&gt;
&lt;li&gt;I also recommend typing all of this block out by hand so you can get a feel for it, but also understand that there is tooling out there such as &lt;a href=&#34;https://code.visualstudio.com/docs/editor/emmet&#34;&gt;Emmet&lt;/a&gt; that are meant to generate stuff for you later on in your journey~&lt;/li&gt;
&lt;li&gt;From here check out the &lt;a href=&#34;https://blog.apilayer.com/lamp-stack-what-is-it-advantages-alternatives-in-2023/&#34;&gt;LAMP Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and be sure you have visited &lt;a href=&#34;https://www.w3schools.com/&#34;&gt;W3C Schools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Happy Hacking!&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>Helm Quick Start With Next Cloud</title>
      <link>https://jordanielder.com/posts/helm-quick-start-with-next-cloud/</link>
      <pubDate>Sat, 21 Jan 2023 04:57:50 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/helm-quick-start-with-next-cloud/</guid>
      <description>Getting started with Kubernetes can be a daunting task, especially for newcomers. This is where Helm comes to smooth out the experience. Referred to as the package manager for Kubernetes, Helm aims to simplify the deployment of k8s applications, making it easier for users to harness the full potential of Kubernetes. In this guide I&amp;rsquo;ll jump through the steps I took in gettin acquainted with Helm through the Next Cloud Chart.</description>
      <content>&lt;p&gt;Getting started with Kubernetes can be a daunting task, especially for newcomers. This is where Helm comes to smooth out the experience. Referred to as &lt;em&gt;the package manager for Kubernetes&lt;/em&gt;, Helm aims to simplify the deployment of k8s applications, making it easier for users to harness the full potential of Kubernetes. In this guide I&amp;rsquo;ll jump through the steps I took in gettin acquainted with Helm through the Next Cloud Chart.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This guide assumes you already have a &lt;a href=&#34;https://k21academy.com/docker-kubernetes/kubernetes-installation-options/&#34;&gt;Kubernetes&lt;/a&gt; cluster and &lt;a href=&#34;https://helm.sh/docs/helm/helm_install/&#34;&gt;Helm&lt;/a&gt; installed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://artifacthub.io/&#34;&gt;Search for the App on &lt;strong&gt;ArtifactHub.io&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image.png&#34; alt=&#34;ArtifactHub Home&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://artifacthub.io/packages/helm/nextcloud/nextcloud&#34;&gt;I&amp;rsquo;ll be using the official &lt;strong&gt;nextcloud&lt;/strong&gt; chart&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-1.png&#34; alt=&#34;ArtifactHub NextCloud&#34;&gt;&lt;/p&gt;
&lt;p&gt;Click the button labeled &lt;strong&gt;Default Values&lt;/strong&gt; on the right side of the screen&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-2.png&#34; alt=&#34;ArtifactHub Default Values&#34;&gt;&lt;/p&gt;
&lt;p&gt;and either copy/paste or save the file into a location of your choice. I will be using &lt;code&gt;~/helm/nexctloud/values.yml&lt;/code&gt; as my destination&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;values.yml&lt;/code&gt; file is the full list of every possible change to be made to this application. This is the piece of the puzzle that everyone breezes over. You can edit any line of this file as-stated in the &lt;a href=&#34;https://artifacthub.io/packages/helm/nextcloud/nextcloud#configuration&#34;&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-7.png&#34; alt=&#34;Alt text&#34;&gt;&lt;/p&gt;
&lt;p&gt;in that file you&amp;rsquo;ll see plenty of things you&amp;rsquo;ll wanna edit such values as host, username, password, etc&amp;hellip; give this file a good once-over, read some of the comments and understand that what we&amp;rsquo;re about to do is ephemeral, meaning there is not an underlying storage mechanism in this install of NextCloud. &lt;em&gt;This post is about Helm after all&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-3.png&#34; alt=&#34;NextCloud Yaml Example&#34;&gt;&lt;/p&gt;
&lt;p&gt;and in my case I needed to add my access domain to the &lt;code&gt;config:&lt;/code&gt; line &lt;em&gt;which was stated in browser the first time I loaded without that line&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;configs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;proxy.config.php&lt;/span&gt;: |-&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;lt;?php
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    $CONFIG = array (
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      &amp;#39;trusted_domains&amp;#39; =&amp;gt; array(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        0 =&amp;gt; &amp;#39;nc.10.1.1.254.nip.io&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;      ),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    );&lt;/span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and after all that you can save the &lt;code&gt;values.yml&lt;/code&gt; file and go on to &lt;strong&gt;install&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;helm repo add nextcloud https://nextcloud.github.io/helm/  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;helm install my-release nextcloud/nextcloud --values helm/nexctloud/values.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;note that &lt;code&gt;--values helm/nextcloud/values.yml&lt;/code&gt; is the location of my edited &lt;code&gt;values.yml&lt;/code&gt; file&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;now as for &lt;em&gt;Ingress Controller&lt;/em&gt; that&amp;rsquo;s beyond the scope of this quickstart, but this Ingress Resource will work for Traefik and Nginx. I&amp;rsquo;m just sending it to the subdomain of &lt;code&gt;nc&lt;/code&gt; and &lt;code&gt;10.1.1.254&lt;/code&gt; is the address of my cluster, yours will more likely be another IP or localhost, and &lt;code&gt;nip.io&lt;/code&gt; just let&amp;rsquo;s you attach subdomains onto an IP address:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Ingress&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my-release-nextcloud&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;rules&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;host&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;nc.10.1.1.254.nip.io&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;http&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          - &lt;span style=&#34;color:#f92672&#34;&gt;path&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;pathType&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;backend&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;service&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my-release-nextcloud&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;port&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#f92672&#34;&gt;number&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and now when I visit &lt;code&gt;nc.10.1.1.254.nip.io&lt;/code&gt; in my browser I see Next Cloud! You should be able to type the subdomain you provided attached to your cluster&amp;rsquo;s IP and run it against &lt;a href=&#34;https://nip.io/&#34;&gt;nip.io&lt;/a&gt; as well for the same result: &lt;code&gt;nc.your-cluster-ip.nip.io&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-5.png&#34; alt=&#34;NextCloud Login&#34;&gt;&lt;/p&gt;
&lt;p&gt;and I can log in with my user with &lt;code&gt;admin&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; which you should have changed if you&amp;rsquo;re on the public internet!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/image-8.png&#34; alt=&#34;NextCloud Dashboard&#34;&gt;&lt;/p&gt;
&lt;p&gt;when you wanna make any changes just edit the yaml file again and run&lt;br&gt;
&lt;code&gt;helm upgrade my-release nextcloud/nextcloud --values helm/nextcloud/values.yml&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;REMINDER: we didn&amp;rsquo;t attach storage to NextCloud this is for testing purposes only! Your data will not persist across upgrades. Do not stop here if you intend to deploy Next Cloud for real world use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Happy Helming!&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>LosslessCut: My Most Used Video Editor</title>
      <link>https://jordanielder.com/posts/losslesscut-my-most-used-video-editor/</link>
      <pubDate>Sat, 21 Jan 2023 04:57:50 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/losslesscut-my-most-used-video-editor/</guid>
      <description>Throughout my experience with Linux and Open-Source I&amp;rsquo;ve enjoyed many great free video-editing tools. Software like FFmpeg and ImageMagick have done so much of my heavy lifting over the years, and Editors like OpenShot, Kdenlive, and Lightworks all have their places in my different environments; but one video editor that has made its way into my upper-eschalon of tools over the last few years is a little-known tool called LosslessCut.</description>
      <content>&lt;p&gt;Throughout my experience with Linux and Open-Source I&amp;rsquo;ve enjoyed many great free video-editing tools. Software like &lt;a href=&#34;https://ffmpeg.org/&#34;&gt;FFmpeg&lt;/a&gt; and &lt;a href=&#34;https://imagemagick.org/index.php&#34;&gt;ImageMagick&lt;/a&gt; have done so much of my heavy lifting over the years, and Editors like &lt;a href=&#34;https://www.openshot.org/&#34;&gt;OpenShot&lt;/a&gt;, &lt;a href=&#34;https://kdenlive.org/en/&#34;&gt;Kdenlive&lt;/a&gt;, and &lt;a href=&#34;https://lwks.com/&#34;&gt;Lightworks&lt;/a&gt; all have their places in my different environments; but one video editor that has made its way into my upper-eschalon of tools over the last few years is a little-known tool called &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://ffmpeg.org/&#34;&gt;FFmpeg&lt;/a&gt; is a command-line tool that is widely used for video encoding, decoding, and conversion, it can be used for a wide range of tasks including trimming, cutting, and merging videos, but it is not a full-fledged video editor like &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt;. It can be challenging for users who are not familiar with command-line interface to use.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://imagemagick.org/index.php&#34;&gt;ImageMagick&lt;/a&gt; is a powerful and versatile tool for working with images, but it requires a good understanding of command-line interface and the software capabilities to take full advantage of its potential.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.openshot.org/&#34;&gt;OpenShot&lt;/a&gt; and &lt;a href=&#34;https://kdenlive.org/en/&#34;&gt;Kdenlive&lt;/a&gt; are both open-source video editors that offer a more traditional timeline-based editing experience. They provide a wide range of features such as advanced color correction, motion graphics, 3D animation, and more. However, they may not be as efficient or as fast as &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; when it comes to trimming and cutting videos without re-encoding.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://lwks.com/&#34;&gt;Lightworks&lt;/a&gt; is a professional video editing software that is widely used in the film and television industry. It offers a wide range of advanced editing features and a professional-grade workflow. However, it is &lt;strong&gt;not free&lt;/strong&gt;, and it may be too complex for users who only need to perform basic editing tasks.&lt;/p&gt;
&lt;h1 id=&#34;losslesscuthttpsmifinolosslesscut&#34;&gt;&lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Though I often turn to &lt;a href=&#34;https://www.openshot.org/&#34;&gt;OpenShot&lt;/a&gt; for my overall video projects, I often start with FFmpeg and&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; is a simple, efficient, and free video editing tool that is well-suited for quickly trimming and cutting videos without re-encoding. It may not be as feature-rich as other editors like &lt;a href=&#34;https://www.openshot.org/&#34;&gt;OpenShot&lt;/a&gt;, &lt;a href=&#34;https://kdenlive.org/en/&#34;&gt;Kdenlive&lt;/a&gt;, or &lt;a href=&#34;https://lwks.com/&#34;&gt;Lightworks&lt;/a&gt;, but it is a good choice for users who need a fast and easy-to-use tool for basic video editing tasks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/LosslessCut-Blank.png&#34; alt=&#34;LosslessCut-Blank.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;is a simple and efficient tool that allows users to quickly trim and cut videos without re-encoding, as well mix and merge multiple sources. You&amp;rsquo;ll want to add this free and open-source tool to your workstation no matter what platform you&amp;rsquo;re on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/start.png&#34; alt=&#34;start.png&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;options&#34;&gt;Options&lt;/h1&gt;
&lt;p&gt;Often I will just extract all tracks for a common workflow for the band, and that&amp;rsquo;s possible as soon as the file is open from the &lt;code&gt;Edit-&amp;gt;Tracks&lt;/code&gt; dropdown&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/header.png&#34; alt=&#34;header.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll go into just a little detail here about some of the different settings available in the &lt;code&gt;File-&amp;gt;Settings&lt;/code&gt; or with the keyboard shortcut &lt;code&gt;Ctrl+Comma&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/options.png&#34; alt=&#34;options.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;The list of settings and preferences offers a rich set of options to customize their experience when using the program, this is just a few options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;App language&lt;/strong&gt;: Allows users to select the language that the program will be displayed in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keyboard &amp;amp; mouse shortcuts&lt;/strong&gt;: Allows users to customize the keyboard and mouse shortcuts used in the program.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Working directory&lt;/strong&gt;: Allows users to specify the location where working files and exported files will be stored.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto save project file&lt;/strong&gt;: Allows users to enable or disable automatic saving of the project file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom FFmpeg directory (experimental)&lt;/strong&gt;: Allows users to specify custom FFmpeg and FFprobe binaries to use.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keyframe cut mode&lt;/strong&gt;: Allows users to select the cutting mode to be used when exporting videos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extract unprocessable tracks&lt;/strong&gt;: Allows users to specify what to do with tracks that cannot be processed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experimental ffmpeg features flag&lt;/strong&gt;: Allows users to enable experimental features in ffmpeg.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snapshot capture format&lt;/strong&gt;: Allows users to select the format in which snapshots will be captured.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In timecode show&lt;/strong&gt;: Allows users to specify whether timecode is displayed in the timeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timeline trackpad/wheel sensitivity&lt;/strong&gt;: Allows users to specify the sensitivity of the trackpad and wheel when navigating the timeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto load timecode from file&lt;/strong&gt;: Allows users to enable or disable the automatic loading of timecode from a file as an offset in the timeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto convert to supported format&lt;/strong&gt;: Allows users to enable or disable automatic conversion of unsupported files to a supported format when they are opened.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hide informational notifications&lt;/strong&gt;: Allows users to enable or disable the display of informational notifications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ask about what to do when opening a new file&lt;/strong&gt;: Allows users to specify whether the program should ask what to do when a new file is opened while another file is already open.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;multiple-sources&#34;&gt;Multiple Sources&lt;/h1&gt;
&lt;p&gt;As soon you pull a video file into the program, simply dragging and dropping on most systems, you&amp;rsquo;re able to export the tracks or start trimming up segments&lt;/p&gt;
&lt;p&gt;Setting the Working Directory is where the files your exported files will be saved&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/workingdir.png&#34; alt=&#34;workingdir.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;If you open multiple tracks in you&amp;rsquo;ll see the menu on the left to show your different video layers. You&amp;rsquo;ll notice one of my tracks is has &lt;em&gt;cut-merged&lt;/em&gt; in the name, that is how your files will be appended in &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/merge.png&#34; alt=&#34;merge.png&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;multiple-tracks&#34;&gt;Multiple Tracks&lt;/h1&gt;
&lt;p&gt;since &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; doesn&amp;rsquo;t re-encode the video, it is very fast and since it also retains video quality. You&amp;rsquo;re able to mix, merge, and concat audio and video tracks from within the batch file list.
&lt;img src=&#34;images/merge-concat-full.png&#34; alt=&#34;merge-concat-full.png&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;lossless-export&#34;&gt;Lossless Export&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; is designed to handle multiple tracks. It lets you trim video tracks and export them down into tiny segment quickly. You&amp;rsquo;re are able to add multiple audio tracks and switch between them, which is useful for creating a final video with multiple audio tracks (e.g. for different languages, or to add a commentary). You can trim, cut, and adjust the video tracks independently of each other and place them in different layers allowing multiple videos to be combined into a single video.
&lt;img src=&#34;images/export.png&#34; alt=&#34;export.png&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;screenshots&#34;&gt;Screenshots&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; is also a great way to grab screenshots from the video as you&amp;rsquo;re working on it, so you don&amp;rsquo;t have to go to external tools for that.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/screenshot.png&#34; alt=&#34;screenshot.png&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;ffmpeg-is-still-quicker-for-some-things&#34;&gt;FFmpeg is still quicker for some things&lt;/h1&gt;
&lt;p&gt;Allthough &lt;a href=&#34;https://ffmpeg.org/&#34;&gt;FFmpeg&lt;/a&gt; &lt;em&gt;can&lt;/em&gt; do anything that a video editor can do; &lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt; doesn&amp;rsquo;t replace FFmpeg entirely for me, there are still some tasks that I leave up to my favorite command-line tool:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Video Information:&lt;br&gt;
&lt;code&gt;ffmpeg -i video.mp4 -hide_banner -f null -&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and ripping audio is usually also something I&amp;rsquo;ll do with FFmpeg unless it&amp;rsquo;s a byproduct of a larger video project&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Basic MP4 to MP3:&lt;br&gt;
&lt;code&gt;ffmpeg -i video.mp4 audio.mp3&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content>
    </item>
    
    <item>
      <title>Thunderbird in 2023</title>
      <link>https://jordanielder.com/posts/thunderbird-in-2023/</link>
      <pubDate>Mon, 16 Jan 2023 21:34:04 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/thunderbird-in-2023/</guid>
      <description>More Than A Mail Client Thunderbird is a powerful, free and open-source email, news, and chat client developed by the Mozilla Foundation. It is available for Windows, Mac, and Linux operating systems and offers a wide range of features and functionalities to help users access your emails, schedule appointments and events, and customize the look and feel of the application.
One of the key features of Thunderbird is its interoperability with a wide range of email service providers.</description>
      <content>&lt;h1 id=&#34;more-than-a-mail-client&#34;&gt;More Than A Mail Client&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://www.thunderbird.net/&#34;&gt;Thunderbird&lt;/a&gt; is a powerful, free and open-source email, news, and chat client developed by the &lt;a href=&#34;https://foundation.mozilla.org/&#34;&gt;Mozilla Foundation&lt;/a&gt;. It is available for Windows, Mac, and Linux operating systems and offers a wide range of features and functionalities to help users access your emails, schedule appointments and events, and customize the look and feel of the application.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/mail.png&#34; alt=&#34;mail&#34;&gt;&lt;/p&gt;
&lt;p&gt;One of the key features of Thunderbird is its interoperability with a wide range of email service providers. The application supports popular email protocols which allows it to work seamlessly with most email services, including &lt;strong&gt;Gmail&lt;/strong&gt;, &lt;strong&gt;Yahoo&lt;/strong&gt;, and &lt;strong&gt;Outlook&lt;/strong&gt;, among others. Thunderbird also allows you to set up multiple email accounts &lt;em&gt;within&lt;/em&gt; the same application, giving you access to all of your email accounts from one central location. Contrary to popular belief, &lt;em&gt;mail&lt;/em&gt; isn&amp;rsquo;t all it&amp;rsquo;s capable of&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/calendar.png&#34; alt=&#34;calendar&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;the-calendar-and-reminders&#34;&gt;The Calendar and Reminders&lt;/h1&gt;
&lt;p&gt;Additionally, you can use the built-in calendar and task manager to schedule appointments and events, set reminders, and manage your to-do list across your accounts. Thunderbird&amp;rsquo;s Calendar is compatible with other calendar services, such as &lt;strong&gt;Google Calendar&lt;/strong&gt;, &lt;strong&gt;Exchange&lt;/strong&gt;, and &lt;strong&gt;iCloud&lt;/strong&gt;, allowing you to synchronize your events and tasks across multiple devices, this is especially useful if you use multiple devices for work or personal use.&lt;/p&gt;
&lt;p&gt;You can quickly check all of your calendars to see what you have planned for the day, week, or month, and make adjustments as needed and allows you to manage your tasks and to-do list. The task manager is quite rich in Thunderbird. Have a look here!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/tasks.png&#34; alt=&#34;tasks&#34;&gt;&lt;/p&gt;
&lt;p&gt;Thunderbird&amp;rsquo;s built-in task manager allows users to efficiently manage your tasks and to-do list, by setting due dates, priorities and marking them as complete, making it a useful tool for staying organized and on top of your schedule.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/contacts.png&#34; alt=&#34;contacts&#34;&gt;&lt;/p&gt;
&lt;p&gt;The built-in contact system allows you to store and organize information about your contacts, such as your name, email address, phone number, and other details; and allows you to create multiple address books, which can be used to organize your contacts into different groups or categories. For example, you can create separate address books for personal contacts, business contacts, or contacts from a specific project or organization.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/rss.png&#34; alt=&#34;rss&#34;&gt;&lt;/p&gt;
&lt;p&gt;Thunderbird includes support for newsgroups and RSS feeds, and now also includes Matrix chat support through an extension, allowing you to read and post to newsgroups, subscribe to RSS feeds, and join and chat on Matrix servers, all within the same application. &lt;em&gt;Newsgroups&lt;/em&gt; in Thunderbird refers to online discussion forums organized by topic. They are similar to forums or message boards, where users can post messages, read messages posted by others, and respond to them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/matrix.png&#34; alt=&#34;matrix&#34;&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an extension for Matrix Chat, which allows you to join and chat on Matrix servers from within Thunderbird. &lt;a href=&#34;https://matrix.org/&#34;&gt;Matrix&lt;/a&gt; is a secure, decentralized communication platform that enables real-time communication, including instant messaging, voice, and video calls, and allows for integration with other platforms and services. By using the Matrix Chat extension with Thunderbird, you can join any Matrix room, chat with your contacts, access to your room&amp;rsquo;s history, and more.&lt;/p&gt;
&lt;p&gt;All this combined means that you can use Thunderbird as a central hub for all your communication needs, including email, newsgroups, RSS feeds, and Matrix chat, all within the same application; and can be very useful for people who need to keep in touch with multiple groups of people or who need to stay informed on different topics.&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Building a Hugo Blog Website with Digital Ocean and GitHub</title>
      <link>https://jordanielder.com/posts/building-a-hugo-blog-website-with-digital-ocean-and-github/</link>
      <pubDate>Mon, 16 Jan 2023 12:58:41 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/building-a-hugo-blog-website-with-digital-ocean-and-github/</guid>
      <description>What is a Hugo? Firstly welcome to the world of static sites! If you&amp;rsquo;re new to the concept, a static site is a website that is built using plain HTML, CSS, and JavaScript files, as opposed to a dynamic site that is generated on the fly using a server-side language like PHP or Ruby.
One of the most popular tools for building static sites is Hugo. Hugo is a static site generator written in Go, and it&amp;rsquo;s known for its speed and ease of use.</description>
      <content>&lt;h1 id=&#34;what-is-a-hugo&#34;&gt;What is a &lt;em&gt;Hugo&lt;/em&gt;?&lt;/h1&gt;
&lt;p&gt;Firstly welcome to the world of static sites! If you&amp;rsquo;re new to the concept, a static site is a website that is built using plain HTML, CSS, and JavaScript files, as opposed to a dynamic site that is generated on the fly using a server-side language like PHP or Ruby.&lt;/p&gt;
&lt;p&gt;One of the most popular tools for building static sites is &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. Hugo is a static site generator written in &lt;a href=&#34;https://go.dev/&#34;&gt;Go&lt;/a&gt;, and it&amp;rsquo;s known for its speed and ease of use. With Hugo, you can create a website in minutes, without having to worry about setting up a server or a database!&lt;/p&gt;
&lt;p&gt;One of the key benefits of using Hugo is that it&amp;rsquo;s incredibly fast. Since your website is just a bunch of static files, it can be served to your visitors quickly and efficiently. This means that your website will load faster, which is great for both your visitors and your search engine rankings.&lt;/p&gt;
&lt;p&gt;Another benefit of using Hugo is that it&amp;rsquo;s extremely easy to use. You can create a new website by simply running a single command, and then you can add pages and content to your site by creating new markdown files. You can also use Hugo to create a custom theme for your website, which means you can make it look exactly the way you want it to.&lt;/p&gt;
&lt;p&gt;Overall, Hugo is a great choice for building your next static website. It&amp;rsquo;s fast, easy to use, and highly customizable. So if you&amp;rsquo;re looking for a simple and powerful way to create a website, let&amp;rsquo;s go ahead and get moving!&lt;/p&gt;
&lt;h1 id=&#34;download-a-few-things-to-get-started&#34;&gt;Download a Few Things to Get Started&lt;/h1&gt;
&lt;p&gt;NOTE: I will be using &lt;a href=&#34;https://cloud.digitalocean.com/&#34;&gt;Digital Ocean&lt;/a&gt;  and &lt;a href=&#34;https://github.com/&#34;&gt;GitHub&lt;/a&gt; (not sponsored) like the article title implies, but you can also use &lt;a href=&#34;https://www.jupiterbroadcasting.com/sponsors/&#34;&gt;Linode&lt;/a&gt; and &lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab&#34;&gt;GitLab&lt;/a&gt; or other tools for these concepts.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t currently have a Digital Ocean account &lt;a href=&#34;https://tuxdigital.com/sponsors/&#34;&gt;use this link&lt;/a&gt; to get extra credits, it doesn&amp;rsquo;t support me, but it does support Destination Linux, which is a podcast I like.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://git-scm.com/&#34;&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;on Fedora Linux you can run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo dnf install git hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and same with apt on the Debian derivatives, you know the drill.&lt;/p&gt;
&lt;h1 id=&#34;create-your-site&#34;&gt;Create Your Site&lt;/h1&gt;
&lt;p&gt;Now that the installation is taken care of, navigate to your desired directory, mine is &lt;code&gt;~/hugo&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir ~/hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd ~/hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new site mydomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd mydomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git init
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;don&amp;rsquo;t close this window just yet, we&amp;rsquo;ll be right back here&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;on Windows use these commands instead:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd &lt;span style=&#34;color:#66d9ef&#34;&gt;%&lt;/span&gt;userprofile%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new site mydomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd mydomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git init
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;don&amp;rsquo;t close this window just yet, we&amp;rsquo;ll be right back here&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;replace &lt;code&gt;mydomain.com&lt;/code&gt; with your own domain name, and if you do not already own a Domain I recommend &lt;a href=&#34;https://dashboard.godaddy.com/venture&#34;&gt;GoDaddy&lt;/a&gt;, not sponsored. The reason I recommend them is due to the ease of use in their dashboard. We&amp;rsquo;ll get to the steps of getting a Domain if you don&amp;rsquo;t already have one, but first we need to build our site locally and make it our own!&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll have noticed this particular bit of output when you ran the &lt;code&gt;hugo new site&lt;/code&gt; command:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/hugo-new-site.png&#34; alt=&#34;hugo new site&#34;&gt;&lt;/p&gt;
&lt;p&gt;we&amp;rsquo;ll be adding a theme next but firstly let&amp;rsquo;s just see what we have going so far by running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;images/hugo-server.png&#34; alt=&#34;hugo server&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;this is my actual local development server for this site which is why my numbers are not set lower to &lt;code&gt;0&lt;/code&gt; like a new site would be&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;the-local-server-is-now-running&#34;&gt;The Local Server Is Now Running&lt;/h1&gt;
&lt;p&gt;don&amp;rsquo;t exit this window, but do note that near the end of the output, there is a line that reads:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Web Server is available at http://localhost:1313/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;on Linux you can &lt;code&gt;Ctrl+LeftClick&lt;/code&gt; to open the link in your web browser, and on Windows CMD you have to highlight the text and &lt;code&gt;Right Click&lt;/code&gt; to copy the text, then paste that link into your web browser URL.&lt;/p&gt;
&lt;p&gt;If all goes accordingly you should now be staring at a blank white screen&amp;hellip; That&amp;rsquo;s not what we want our site to look like, but we&amp;rsquo;re about to change it. And before we go changing things we want to start adding things to our local git Repo to be later pushed to github.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve already initialized our website directory as a git repo when we ran the above command &lt;code&gt;git init&lt;/code&gt; so now we can add &lt;code&gt;git submodules&lt;/code&gt; to our repo. To do this firstly we need to figure out which theme we want to add. Go to this site to browse the official themes list:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;https://themes.gohugo.io/&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;this-site-is-built-with-hugo-and-digital-ocean&#34;&gt;&lt;em&gt;This&lt;/em&gt; Site is Built with Hugo and Digital Ocean&lt;/h1&gt;
&lt;p&gt;Just like this article goes on to explain how to do, but before we can go on to host the site, we have to have it looking like we want it. The first step in any Hugo site was just done, creating the site, but next we need to &lt;em&gt;serve&lt;/em&gt; the site locally so we can see our changes as we make them, and most importantly before anyone else can. I&amp;rsquo;ve landed on &lt;a href=&#34;https://themes.gohugo.io/themes/hugo-theme-terminal/&#34;&gt;Terminal&lt;/a&gt; for my theme on this website, but want to use a Resume theme for one and a blog theme for another. To use any theme from &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;https://themes.gohugo.io/&lt;/a&gt; select the &lt;strong&gt;Download&lt;/strong&gt; button and you&amp;rsquo;ll be taken to a GitHub page.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/terminal-thumb.png&#34; alt=&#34;Terminal&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;a-few-theme-options&#34;&gt;A Few Theme Options&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;m going to show a few different variations of websites, but by this point you should be following your own theme&amp;rsquo;s instructions. If you want to follow any of these themes, then we&amp;rsquo;ll continue. Otherwise meet me back here once your theme is installed and we&amp;rsquo;ll go through the &lt;code&gt;GitHub&lt;/code&gt; and &lt;code&gt;Digital Ocean&lt;/code&gt; steps down below&lt;/p&gt;
&lt;p&gt;Now go back to your terminal window and use &lt;code&gt;Ctrl+C&lt;/code&gt; to end the server instance so we can add our theme. Once the server stopped and you can type again follow the instructions on your theme&amp;rsquo;s GitHub page. If you&amp;rsquo;re following with this theme the following steps are from its GitHub:&lt;/p&gt;
&lt;h1 id=&#34;option-1-resume-site&#34;&gt;Option #1: Resume Site&lt;/h1&gt;
&lt;p&gt;For this part I&amp;rsquo;ll be using the &lt;a href=&#34;https://themes.gohugo.io/themes/simple-cv/&#34;&gt;Simple CV Theme&lt;/a&gt;. Once you&amp;rsquo;ve made your way to your selected theme&amp;rsquo;s &lt;a href=&#34;https://github.com/hootan09/simple-cv&#34;&gt;GitHub page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/CV.png&#34; alt=&#34;CV&#34;&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git submodule add https://github.com/hootan09/simple-cv.git themes/simple-cv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and copy in the example site information from the theme&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -a themes/simple-cv/exampleSite/. .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;when going back to &lt;code&gt;http://localhost:1313/&lt;/code&gt; you should see the Author&amp;rsquo;s CV is what&amp;rsquo;s here by default, but now you can go on to edit everything that was copied from the theme, which are the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── content.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── fa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│       └── content.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── static
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── img
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        └── avatar.jpg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Edit these files to your liking and skip the blog section for the next set of instructions!&lt;/p&gt;
&lt;h1 id=&#34;option-2-blog-site&#34;&gt;Option #2: Blog Site&lt;/h1&gt;
&lt;p&gt;So I also want to go through the steps of getting a blog website up too&lt;/p&gt;
&lt;p&gt;For this I&amp;rsquo;ll be using the &lt;a href=&#34;https://themes.gohugo.io/themes/hugo-paper/&#34;&gt;hugo-paper theme&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/nanxiaobei/hugo-paper&#34;&gt;https://github.com/nanxiaobei/hugo-paper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/Hugo-Blog-1.png&#34; alt=&#34;Hugo-Blog-1&#34;&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git submodule add https://github.com/nanxiaobei/hugo-paper themes/paper
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and copy this into your &lt;code&gt;config.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;baseURL&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://example.org/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;languageCode&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;en-us&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;title&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;My New Hugo Site&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;disqusShortname&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_DISQUS_SHORTNAME&amp;#39;&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# use disqus comments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;params&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# color style&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;color&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;linen&amp;#39;&lt;/span&gt;                           &lt;span style=&#34;color:#75715e&#34;&gt;# linen, wheat, gray, light&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# header social icons&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;twitter&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_TWITTER_ID&amp;#39;&lt;/span&gt;               &lt;span style=&#34;color:#75715e&#34;&gt;# twitter.com/YOUR_TWITTER_ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;github&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_GITHUB_ID&amp;#39;&lt;/span&gt;                 &lt;span style=&#34;color:#75715e&#34;&gt;# github.com/YOUR_GITHUB_ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;instagram&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_INSTAGRAM_ID&amp;#39;&lt;/span&gt;           &lt;span style=&#34;color:#75715e&#34;&gt;# instagram.com/YOUR_INSTAGRAM_ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mastodon&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_MASTODON_LINK&amp;#39;&lt;/span&gt;           &lt;span style=&#34;color:#75715e&#34;&gt;# e.g. &amp;#39;https://mastodon.instance/@xxx&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;rss&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;                                &lt;span style=&#34;color:#75715e&#34;&gt;# show rss icon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# home page profile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;avatar&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;GRAVATAR_EMAIL&amp;#39;&lt;/span&gt;                 &lt;span style=&#34;color:#75715e&#34;&gt;# gravatar email or image url&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_NAME&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;bio&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;YOUR_BIO&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# misc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;disableHLJS&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;                        &lt;span style=&#34;color:#75715e&#34;&gt;# disable highlight.js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;monoDarkIcon&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;                       &lt;span style=&#34;color:#75715e&#34;&gt;# show monochrome dark mode icon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;gravatarCdn&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;GRAVATAR_CDN_LINK&amp;#39;&lt;/span&gt;         &lt;span style=&#34;color:#75715e&#34;&gt;# e.g. &amp;#39;https://cdn.v2ex.com/gravatar/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;graphCommentId&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;YOUR_GRAPH_COMMENT_ID&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# use graph comment (disqus alternative)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and replace the the personal information with your info.&lt;/p&gt;
&lt;p&gt;and also I always make sure to go into &lt;code&gt;archetypes/default.md&lt;/code&gt; and replace &lt;code&gt;draft: true&lt;/code&gt; to &lt;code&gt;draft: false&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title: &amp;#34;{{ replace .Name &amp;#34;-&amp;#34; &amp;#34; &amp;#34; | title }}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;date: {{ .Date }}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;draft: false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;so that the next command will populate the page as soon as its created, and when I want to create a draft I&amp;rsquo;ll switch it back off on a page-by-page basis.&lt;/p&gt;
&lt;p&gt;now one last thing, we do need to add a post, and the way I like to do this is the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new posts/my-first-post/index.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;this creates a new &lt;em&gt;index.md&lt;/em&gt; file at &lt;code&gt;content/posts/my-first-post/index.md&lt;/code&gt; and anything you create in this folder can be accessed by that index.md file, so I went ahead and created an images folder here too:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mkdir content/posts/my-first-post/images
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and I copied my old discord avatar in as a &lt;code&gt;test.png&lt;/code&gt; there.&lt;/p&gt;
&lt;p&gt;As for the &lt;code&gt;index.md&lt;/code&gt; that was created, in this example all I added was:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title: &amp;#34;My First Post&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;date: 2023-01-16T15:55:59-06:00
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;draft: false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# This is the header
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;![&lt;span style=&#34;color:#f92672&#34;&gt;Here&amp;#39;s an Image&lt;/span&gt;](&lt;span style=&#34;color:#a6e22e&#34;&gt;images/test.png&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;make sure your server is running by this point:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and you&amp;rsquo;ll see something like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/Hugo-Blog-2.png&#34; alt=&#34;Hugo-Blog-2&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;other-options&#34;&gt;Other Options&lt;/h1&gt;
&lt;p&gt;There are many styles of Hugo Sites and they all have a slightly different setup process, but they all follow a general set of instructions. As you dig deeper the file hierarchy will make more sense!&lt;/p&gt;
&lt;h1 id=&#34;hosting-your-site&#34;&gt;Hosting Your Site&lt;/h1&gt;
&lt;p&gt;If this is your first time purchasing a domain take note that we will not need to purchase anything extra from GoDaddy besides the domain name. All of our storage and name resolution will take place on Digital Ocean&amp;rsquo;s servers. Your price should not be more than your advertised domain cost for this type of website.&lt;/p&gt;
&lt;p&gt;on GoDaddy now that you have your domain and you&amp;rsquo;re logged into your account, you&amp;rsquo;ll have a lot of options, but the only one you need to worry about for the lifetime of this site is going to the &lt;a href=&#34;https://account.godaddy.com/products&#34;&gt;GoDaddy Dashboard&lt;/a&gt; and beside your domain name click &lt;strong&gt;DNS&lt;/strong&gt; and scroll down to the &lt;strong&gt;Nameservers&lt;/strong&gt; section.&lt;/p&gt;
&lt;p&gt;Select the &lt;strong&gt;Change&lt;/strong&gt; button and replace each of the nameservers with:&lt;/p&gt;
&lt;h2 id=&#34;godaddy-1imagesgdns-1png&#34;&gt;&lt;img src=&#34;images/gdns-1.png&#34; alt=&#34;GoDaddy 1&#34;&gt;&lt;/h2&gt;
&lt;p&gt;Select the tiny font at the bottom:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Enter my own nameservers (Advanced)&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;godaddy-2imagesgdns-2png&#34;&gt;&lt;img src=&#34;images/gdns-2.png&#34; alt=&#34;GoDaddy 2&#34;&gt;&lt;/h2&gt;
&lt;p&gt;Place the following Nameserver Domains into the fields like the picture shows:&lt;br&gt;
&lt;code&gt;ns1.digitalocean.com&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ns2.digitalocean.com&lt;/code&gt;&lt;br&gt;
&lt;code&gt;ns3.digitalocean.com&lt;/code&gt;&lt;br&gt;
&lt;img src=&#34;images/gdns-3.png&#34; alt=&#34;GoDaddy 3&#34;&gt;&lt;/p&gt;
&lt;p&gt;One of the major hurdles in &lt;a href=&#34;https://docs.github.com/en/get-started&#34;&gt;Getting Started with GitHub&lt;/a&gt; is setting up your &lt;a href=&#34;https://github.com/settings/keys&#34;&gt;SSH key&lt;/a&gt;, and if you&amp;rsquo;ve never done that before &lt;a href=&#34;https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent&#34;&gt;the official documentation&lt;/a&gt; is the best place to go for information, however I will attempt to recap the steps required here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/ssh-keygen.png&#34; alt=&#34;ssh-keygen&#34;&gt;&lt;/p&gt;
&lt;p&gt;on all platforms you should have access to the &lt;code&gt;ssh-keygen&lt;/code&gt; command, but in case you&amp;rsquo;re having issues running the commands maybe try &lt;a href=&#34;https://www.ssh.com/academy/ssh/windows&#34;&gt;an application from this list&lt;/a&gt;, I recommend &lt;a href=&#34;https://www.putty.org/&#34;&gt;PuTTY&lt;/a&gt; which comes with an application called &lt;code&gt;PuTTYgen&lt;/code&gt; but the usage of that tool is beyond the scope of this article.&lt;/p&gt;
&lt;p&gt;open a &lt;code&gt;terminal&lt;/code&gt; or &lt;code&gt;command prompt&lt;/code&gt; on windows and use the following commands to get your desired key pair:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-keygen -t ed25519 -C &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;your_email@example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;use the email address you used to sign up with &lt;em&gt;GitHub&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;usually the defaults are okay, press enter a few times, and make sure that you enter a password for your safety.&lt;/p&gt;
&lt;p&gt;and add it to the keyring:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-add ~/.ssh/id_ed25519
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;on Windows the path is typically &lt;code&gt;C:\Users\USERNAME\.ssh\&lt;/code&gt; so you&amp;rsquo;d run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-add C:\Users\USERNAME\.ssh\id_ed25519
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;replace &lt;code&gt;USERNAME&lt;/code&gt; with your profile name on Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;now open your &lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; file in a text editor and copy the contents into the &lt;a href=&#34;https://github.com/settings/keys&#34;&gt;GitHub Textbox&lt;/a&gt; and assign it a name of your choice&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/GitHub-SSH.png&#34; alt=&#34;GitHub-SSH&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;after-your-site-is-up-and-running-and-your-github-key-is-linked&#34;&gt;After Your Site is Up and Running and Your GitHub Key is Linked&lt;/h1&gt;
&lt;p&gt;and you&amp;rsquo;ve edited the personal information to your liking&lt;/p&gt;
&lt;p&gt;While you&amp;rsquo;re still on GitHub go ahead and create the repo, without initializing it, we&amp;rsquo;ve already done that locally. We just need to have get a link to this repo.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/GitHub-Repo-1.png&#34; alt=&#34;GitHub-Repo-1&#34;&gt;&lt;/p&gt;
&lt;p&gt;Follow the steps you&amp;rsquo;re presented with:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/GitHub-Repo-2.png&#34; alt=&#34;GitHub-Repo-2&#34;&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry about copying the link from the top of the final page, but remember your &lt;code&gt;username&lt;/code&gt; and your &lt;code&gt;repository name&lt;/code&gt; for the next step:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/GitHub-Repo-3.png&#34; alt=&#34;GitHub-Repo-3&#34;&gt;&lt;/p&gt;
&lt;p&gt;and you can issue the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git remote add origin git@github.com:USERNAME/REPOSITORY.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;initial commit&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git push origin master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;USERNAME&lt;/code&gt; and &lt;code&gt;REPOSITORY&lt;/code&gt; with your GitHub username and the repo you want to publish&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and when you&amp;rsquo;re finished you&amp;rsquo;ll be able to go back to that final page and see that it&amp;rsquo;s been updated with something similar to:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/GitHub-Repo-4.png&#34; alt=&#34;GitHub-Repo-4&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now that our site is set to use Digital Ocean&amp;rsquo;s Nameservers let&amp;rsquo;s go over to our &lt;a href=&#34;https://cloud.digitalocean.com/apps&#34;&gt;Digital Ocean Dashboard&lt;/a&gt; and get our &lt;code&gt;App&lt;/code&gt; set up!&lt;/p&gt;
&lt;p&gt;be sure that if you don&amp;rsquo;t have an account you take advantage of &lt;a href=&#34;https://tuxdigital.com/sponsors/&#34;&gt;some free credit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;once we&amp;rsquo;re on the &lt;a href=&#34;https://cloud.digitalocean.com/apps&#34;&gt;dashboard&lt;/a&gt; select the &lt;code&gt;Create App&lt;/code&gt; button&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/DigitalOcean-App.png&#34; alt=&#34;DigitalOcean-App&#34;&gt;&lt;/p&gt;
&lt;p&gt;Link your Digital Ocean account from here with your GitHub, and it will present the repo to your site in the dropdown. If you don&amp;rsquo;t see it for some reason, unlink and re-link your account. I actually had to do that the first time.&lt;/p&gt;
&lt;p&gt;Select your branch either &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt; and leave the source directory &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;autodeploy&lt;/code&gt; checked&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re welcome to rename your deployment, but everything else can be left as default and you should be able to run on a starter plan for Apps as of this point in time which will only cost $1.00/mo&lt;/p&gt;
&lt;p&gt;After everything looks good hit Create Resources and you should be able to go back to your &lt;a href=&#34;https://cloud.digitalocean.com/apps&#34;&gt;Digital Ocean Dashboard&lt;/a&gt; and the domain management should prompt you near the top of the dashboard to enter your domain, and Digital Ocean will handle the DNS routes for you.&lt;/p&gt;
&lt;p&gt;By the end of the process you should have a deployment linked to your GitHub posts&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/hugo-app.png&#34; alt=&#34;hugo-app&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;to-add-more-posts&#34;&gt;To Add More Posts&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new posts/name-of-your-new-post/index.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir posts/name-of-your-new-post/images
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;to remove any posts just delete the folder&lt;/li&gt;
&lt;li&gt;to rename a post just rename the folder&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;if-youre-new-to-markdown&#34;&gt;If You&amp;rsquo;re New to Markdown&lt;/h1&gt;
&lt;p&gt;check out the &lt;a href=&#34;https://www.markdownguide.org/getting-started/&#34;&gt;Markdown Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and also check out the &lt;a href=&#34;https://github.com/Jmac217/hugotest/tree/main/content/posts&#34;&gt;source files for this website&lt;/a&gt;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Building a Triangle with Vulkan and C&#43;&#43; in Fedora 37</title>
      <link>https://jordanielder.com/posts/building-a-triangle-with-vulkan-and-cmake-in-fedora/</link>
      <pubDate>Sat, 14 Jan 2023 18:23:21 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/building-a-triangle-with-vulkan-and-cmake-in-fedora/</guid>
      <description>Navigation Beginning the Journey Pre-requisites The Material Downloading The Boilerplate VulkanSDK DNF CMake Testing Vulkan Starting Line Window Notes Initial Directory Structure Vulkan Window FirstApp Class JdeWindow Class Main Function Launching the Window The Hard Part Full Directory Structure Shader Chain Shader Compilation Starting The Triangle Revamped first_app.hpp Revamped first_app.cpp Graphics Pipeline Configuration jde_pipeline.hpp Graphics Pipeline Configuration jde_pipeline.cpp Revamped jde_window.hpp Revamped jde_window.cpp Build The Triangle Launch The Triangle! Beginning the Journey I&amp;rsquo;ve been looking at Vulkan from afar for 6 months while I honed my C++ skills and worked through SFML, GLFW, and OpenGL, along with a few windowing frameworks like ImGui and GTK3, but all of that work just barely prepared me for this most arduous of tasks&amp;hellip; The legendary Vulkan Triangle!</description>
      <content>&lt;h1 id=&#34;navigation&#34;&gt;Navigation&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#Beginning&#34;&gt;Beginning the Journey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#PreRequisites&#34;&gt;Pre-requisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Material&#34;&gt;The Material&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Download&#34;&gt;Downloading The Boilerplate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#VulkanSDK&#34;&gt;VulkanSDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#DNF&#34;&gt;DNF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#CMake&#34;&gt;CMake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Test&#34;&gt;Testing Vulkan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#StartingLine&#34;&gt;Starting Line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Moves&#34;&gt;Window Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Notes&#34;&gt;Initial Directory Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Window&#34;&gt;Vulkan Window&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#FirstApp&#34;&gt;FirstApp Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#JdeWindow&#34;&gt;JdeWindow Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#main&#34;&gt;Main Function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Open&#34;&gt;Launching the Window&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#HardPart&#34;&gt;The Hard Part&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#TriDir&#34;&gt;Full Directory Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ShaderChain&#34;&gt;Shader Chain&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#ShaderCompile&#34;&gt;Shader Compilation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Triangle&#34;&gt;Starting The Triangle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#FirstTriangleHpp&#34;&gt;Revamped first_app.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#FirstTriangleCpp&#34;&gt;Revamped first_app.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#PipelineHpp&#34;&gt;Graphics Pipeline Configuration jde_pipeline.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#PipelineCpp&#34;&gt;Graphics Pipeline Configuration jde_pipeline.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#WindowHpp&#34;&gt;Revamped jde_window.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#WindowCpp&#34;&gt;Revamped jde_window.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#BuildTriangle&#34;&gt;Build The Triangle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Launch&#34;&gt;Launch The Triangle!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;Beginning&#34;&gt;Beginning the Journey&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;ve been looking at Vulkan from afar for 6 months while I honed my C++ skills and worked through SFML, GLFW, and OpenGL, along with a few windowing frameworks like ImGui and GTK3, but all of that work just barely prepared me for this most arduous of tasks&amp;hellip; The legendary Vulkan Triangle! Settle in, this is going to take some time to even read through, let alone work through!&lt;/p&gt;
&lt;p&gt;I sat down about &lt;del&gt;8 hours ago&lt;/del&gt; yesterday, now at the time of finishing the post, thinking this might not be so bad, and in some ways it&amp;rsquo;s not &lt;em&gt;that bad&lt;/em&gt;, but comparing it to everything I&amp;rsquo;ve done till now, it is the &lt;em&gt;hardest thing&lt;/em&gt; I&amp;rsquo;ve had to comprehend in programming. What makes a Triangle less than simple in Vulkan is that by simply starting a Vulkan project you&amp;rsquo;re signing up for plenty of up-front thinking through the architecture of what you&amp;rsquo;re building as well as filling in the fields that Vulkan expects of Graphical Applications both small and massive. The tried and true OpenGL was pretty dang quick to get up and running and gave you a sense of &lt;em&gt;&amp;ldquo;I can do this!&amp;rdquo;&lt;/em&gt;, but then at every turn there was something to add to your API, and if you didn&amp;rsquo;t know it was coming it could derail your project to the point of no return. Having gone through a few of the stumbling points with OpenGL I had &lt;em&gt;some&lt;/em&gt; idea of what I was getting into with Vulkan, but not nearly enough to think twice about sitting down with it tonight. &lt;strong&gt;TL;DR: Vulkan forces you to double check your vision before stepping into the pitfalls you&amp;rsquo;ll surely encounter with OpenGL.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;All of the content from this post summarizes the first 6 videos of &lt;a href=&#34;https://www.youtube.com/watch?v=Y9U9IE0gVHA&amp;amp;list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;Brendan Galea&amp;rsquo;s&lt;/a&gt; Vulkan Game Engine YouTube Series.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;PreRequisites&#34;&gt;Pre-requisites&lt;/h1&gt;
&lt;p&gt;This must be the longest list of pre-requisites I&amp;rsquo;ve seen in a post, let-alone a post I wrote, but it&amp;rsquo;s all of the things you need to get going on Fedora Linux &lt;em&gt;version 37 at the time of writing this&lt;/em&gt;.&lt;/p&gt;
&lt;h1 id=&#34;Material&#34;&gt;The Material&lt;/h1&gt;
&lt;p&gt;I didn&amp;rsquo;t set out to follow a tutorial, but I absolutely had to, and everyone recommended &lt;a href=&#34;https://www.youtube.com/watch?v=Y9U9IE0gVHA&amp;amp;list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;Brendan Galea&amp;rsquo;s Vulkan Game Engine Tutorial&lt;/a&gt; over the last few months of casually looking into this. I decided that it was going to be the quickest way to get up and running in a manner that would allow me to continue learning and would align with my overall plans for Vulkan, which is to incorporate it into an game engine for myself to learn with.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to use &lt;a href=&#34;https://www.youtube.com/watch?v=Y9U9IE0gVHA&amp;amp;list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;Brendan&amp;rsquo;s tutorial&lt;/a&gt; as reference for some of the points I talk about, but mostly I&amp;rsquo;m going to make his process more specific to Linux and even more specifically Fedora. Fedora makes for a great workstation, so that&amp;rsquo;s where I&amp;rsquo;ve been spending my last few months.&lt;/p&gt;
&lt;h1 id=&#34;Download&#34;&gt;Download These And Make Edits Accordingly&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=Y9U9IE0gVHA&amp;amp;list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;Brendan&lt;/a&gt; has 4 files hosted that you&amp;rsquo;ll need to download and follow his short instructions on what to change in those files, these links will take you to the timestamp in the videos, as well as to the download location within the description of the videos.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=LYKlEIzGmW4&amp;amp;t=94s&#34;&gt;lve_device.cpp &amp;amp; lve_device.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=IUYH74MqxOA&amp;amp;t=194s&#34;&gt;lve_swap_chain.cpp &amp;amp; lve_swap_chain.hpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;VulkanSDK&#34;&gt;VulkanSDK&lt;/h1&gt;
&lt;p&gt;The biggest thing to get going up front is to &lt;a href=&#34;https://vulkan.lunarg.com/sdk/home#linux&#34;&gt;Download the VulkanSDK&lt;/a&gt; and get it properly set up in your environment for use with &lt;code&gt;glslc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When you get the &lt;code&gt;SDK - SDK Installer&lt;/code&gt; &lt;code&gt;vulkansdk-linux-x86_64-1.3.236.0.tar.gz&lt;/code&gt; (at the time of writing this) file downloaded, follow the next few commands to get the ball rolling on this setup process. NOTE: There&amp;rsquo;s a script in the tar archive that is supposed to make it easy to install, but it didn&amp;rsquo;t work for me, so I created a new directory at &lt;code&gt;~/VulkanSDK&lt;/code&gt; and moved our tar into it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir ~/VulkanSDK
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd ~/VulkanSDK
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar -xzvf vulkansdk-linux-x86_64-1.3.236.0.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd 1.3.236.0/x86_64
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pwd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;pwd&lt;/code&gt; will output the &lt;code&gt;path&lt;/code&gt; you&amp;rsquo;ll need for the &lt;code&gt;$VULKAN_SDK&lt;/code&gt; environment variable&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/home/USERNAME/VulkanSDK/1.3.236.0/x86_64
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From there you can copy that &lt;code&gt;path&lt;/code&gt; and use it for the following instructions.&lt;br&gt;
since most people are using &lt;code&gt;BASH&lt;/code&gt; I&amp;rsquo;ll post the instructions for that first,&lt;br&gt;
but I&amp;rsquo;ll go into detail about the &lt;code&gt;fish&lt;/code&gt; solution as well!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export VULKAN_SDK&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/home/USERNAME/VulkanSDK/1.3.236.0/x86_64/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$VULKAN_SDK&lt;span style=&#34;color:#e6db74&#34;&gt;/bin:&lt;/span&gt;$PATH&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run those in your terminal to add them temporarily, or add them to your &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt; or somewhere else you can think of.&lt;/p&gt;
&lt;p&gt;Next up the solution that &lt;a href=&#34;https://fishshell.com/&#34;&gt;Fish Shell&lt;/a&gt; users have to live with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -gx VULKAN_SDK &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/home/USERNAME/VulkanSDK/1.3.236.0/x86_64/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fish_add_path $VULKAN_SDK/bin/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;those are now added permenantly to your path, you can overwrite them them with the same command if you make a typo, or clear them entirely with another &lt;code&gt;set&lt;/code&gt; command.&lt;/p&gt;
&lt;h1 id=&#34;you-should-now-be-able-to-run-glslc&#34;&gt;You should now be able to run &lt;code&gt;glslc&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;test this by issuing a simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;glslc --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and you should see:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;shaderc v2022.4 v2022.4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spirv-tools v2022.5-dev v2022.4-28-gd9446130
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;glslang 11.1.0-605-g728c6895
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Target: SPIR-V 1.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;DNF&#34;&gt;DNF&lt;/h1&gt;
&lt;p&gt;Now that the manual setup is out of the way is out of the way it&amp;rsquo;s time to get our development environment up and going!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;dnf&lt;/code&gt; all the things!&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo dnf install &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    @&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Development Tools&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    vulkan-headers &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    vulkan-loader-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    vulkan-tools &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    vulkan-validation-layers &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    vulkan-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libcxx-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libcxx &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    glm-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    cmake &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libpng-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    wayland-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libpciaccess-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libX11-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libXpresent &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libxcb &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    xcb-util &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libxcb-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libXrandr-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    xcb-util-keysyms-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    xcb-util-wm-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    python3 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    git &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    lz4-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libzstd-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    python3-distutils-extra &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    qt &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    gcc-g++ &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    wayland-protocols-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    ninja-build &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    python3-jsonschema &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    qt5-qtbase-devel &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    qt &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    xinput &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    libXinerama
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;CMake&#34;&gt;CMake&lt;/h2&gt;
&lt;p&gt;My preferred build generator is CMake even with its blemishes. I&amp;rsquo;ve used a few dirty tricks to get this going quickly.&lt;/p&gt;
&lt;h2 id=&#34;cmakeliststxt&#34;&gt;&lt;code&gt;CmakeLists.txt&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cmake&#34; data-lang=&#34;cmake&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# CMakeLists.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;cmake_minimum_required(&lt;span style=&#34;color:#e6db74&#34;&gt;VERSION&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;3.25&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;project(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Set C++ standard to a proper standard
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;set(&lt;span style=&#34;color:#e6db74&#34;&gt;CMAKE_CXX_STANDARD&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;20&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Add the GLFW and Vulkan libraries
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;find_package(&lt;span style=&#34;color:#e6db74&#34;&gt;glfw3&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;REQUIRED&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;find_package(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;REQUIRED&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;find_package(&lt;span style=&#34;color:#e6db74&#34;&gt;glm&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;REQUIRED&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Copy contents of src/shaders to the binary location
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;add_custom_target(&lt;span style=&#34;color:#e6db74&#34;&gt;copy_assets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;COMMAND&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;${&lt;/span&gt;CMAKE_COMMAND&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;-E&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;copy_directory&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;${&lt;/span&gt;CMAKE_CURRENT_LIST_DIR&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/src/shaders&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;${&lt;/span&gt;CMAKE_CURRENT_BINARY_DIR&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;/src/shaders&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Dirty way to add all source files in the ./src directory
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;file(&lt;span style=&#34;color:#e6db74&#34;&gt;GLOB_RECURSE&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;SRC_FILES&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;src/*.cpp&amp;#34;&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Create the executable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;add_executable(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;${&lt;/span&gt;SRC_FILES&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Link our executable against the libraries
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;target_link_libraries(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;glfw&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;target_link_libraries(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan::Vulkan&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;target_link_libraries(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;glm::glm&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;add_dependencies(&lt;span style=&#34;color:#e6db74&#34;&gt;Vulkan-Starter&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;copy_assets&lt;/span&gt;)&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;A &lt;code&gt;CMakeLists.txt&lt;/code&gt; file is used to configure C and C++ projects with CMake, ours is called &amp;ldquo;Vulkan-Starter&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This config sets the C++ standard to version 20, which is the latest version of C++ for now! &lt;em&gt;I&amp;rsquo;m impatiently waiting for C++23 this year!&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We&amp;rsquo;ll use the &lt;code&gt;find_package&lt;/code&gt; command to locate and include the &lt;code&gt;GLFW&lt;/code&gt;, &lt;code&gt;Vulkan&lt;/code&gt; and &lt;code&gt;GLM&lt;/code&gt; libraries, which are required for the &lt;code&gt;project&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a custom target that I&amp;rsquo;ve named &lt;code&gt;copy_assets&lt;/code&gt; which copies the contents of the &lt;code&gt;src/shaders&lt;/code&gt; directory to the binary directory, the directory where the executable gets built.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I opted to use &lt;code&gt;file(GLOB_RECURSE SRC_FILES &amp;quot;src/*.cpp&amp;quot;)&lt;/code&gt; to add all source files in the &lt;code&gt;src/&lt;/code&gt; directory to the &lt;code&gt;SRC_FILES&lt;/code&gt; variable&amp;hellip; This is not a recommended option for modern CMake, but it does work, and &lt;em&gt;before release&lt;/em&gt; you&amp;rsquo;d want to do a full revamp on the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally we create an executable called &lt;code&gt;Vulkan-Starter&lt;/code&gt; using the &lt;code&gt;add_executable&lt;/code&gt; command and links it against the &lt;code&gt;GLFW&lt;/code&gt;, &lt;code&gt;Vulkan&lt;/code&gt;, and &lt;code&gt;GLM&lt;/code&gt; libraries using the &lt;code&gt;target_link_libraries&lt;/code&gt; command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The way that assets are handled is with a dependency between the &lt;code&gt;executable&lt;/code&gt; and the custom target &lt;code&gt;copy_assets&lt;/code&gt; using the &lt;code&gt;add_dependencies&lt;/code&gt; command so that the &lt;em&gt;assets&lt;/em&gt; are &lt;em&gt;copied before&lt;/em&gt; the executable is built.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;Test&#34;&gt;Testing Vulkan&lt;/h2&gt;
&lt;p&gt;This file can be copied to use as a test for your environment. If you don&amp;rsquo;t have any errors then you&amp;rsquo;re ready to move on!&lt;/p&gt;
&lt;h1 id=&#34;maincpp&#34;&gt;&lt;code&gt;main.cpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// main.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define GLFW_INCLUDE_VULKAN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;GLFW/glfw3.h&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define GLM_FORCE_RADIANS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define GLM_FORCE_DEPTH_ZERO_TO_ONE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;glm/mat4x4.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;glm/vec4.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwInit();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    GLFWwindow&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; window &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; glfwCreateWindow(&lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;600&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Vulkan Window&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; extensionCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vkEnumerateInstanceExtensionProperties(&lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;extensionCount, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;cout &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; extensionCount &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34; extensions supported&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glm&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;mat4 matrix;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glm&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vec4 vec;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; test &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; matrix &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; vec;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;glfwWindowShouldClose(window))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwPollEvents();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwDestroyWindow(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is just a simple introduction to the world of Vulkan graphics programming! Ultimately this file should open a GLFW window.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Our entrypoint starts by initializing the &lt;code&gt;GLFW&lt;/code&gt; library, which we use to create a window that will serve as the canvas for our Vulkan graphics. We then specify that we want to use the &lt;em&gt;Vulkan client API&lt;/em&gt;, and create a window with a width of 800 pixels, a height of 600 pixels, and the title &amp;ldquo;Vulkan Window&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, we use the &lt;code&gt;vkEnumerateInstanceExtensionProperties&lt;/code&gt; function to determine the number of extensions supported by the current system. This information is then output to the console. My number was 20, but yours could be anything depending on your machine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We also utilize the &lt;code&gt;GLM&lt;/code&gt; library for some matrix and vector operations, specifically creating a &lt;em&gt;4x4 matrix&lt;/em&gt; and a &lt;em&gt;4-element vector&lt;/em&gt;, and then performing a &lt;em&gt;matrix-vector multiplication&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, we enter a loop that repeatedly polls for events and continues running as long as the window remains open. Once the window is closed, we clean up by destroying the window and shutting down &lt;code&gt;GLFW&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Overall, this program serves as a basic introduction to some key concepts and libraries in the world of Vulkan programming, and is a great starting point for our upcoming triangle.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;StartingLine&#34;&gt;The Starting Line&lt;/h1&gt;
&lt;p&gt;&lt;img src=&#34;images/starting-line.png&#34; alt=&#34;Starting-Line&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.khronos.org/spir/&#34;&gt;SPIR-V&lt;/a&gt; is the format that Vulkan expects for our shaders which is why we had to download VulkanSDK and get &lt;code&gt;glslc&lt;/code&gt; added to the path
The &lt;code&gt;CMakeLists.txt&lt;/code&gt; sets up everything our project will need&lt;br&gt;
and the &lt;code&gt;main.cpp&lt;/code&gt; file utilizes GLFW to create a Window and logs the number of extensions supported by &lt;code&gt;vkEnumerateInstanceExtensionProperties&lt;/code&gt;&lt;br&gt;
which in my case is &lt;code&gt;20 extensions supported&lt;/code&gt; and is the only use for this file.&lt;br&gt;
Since the purpose of this &lt;code&gt;main.cpp&lt;/code&gt; was to simply test our installation you may now remove all of the code from it and follow along with &lt;a href=&#34;https://www.youtube.com/watch?v=Y9U9IE0gVHA&amp;amp;list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;Brendan Galea&amp;rsquo;s Vulkan Game Engine Tutorial series on YouTube&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;Moves&#34;&gt;Let&amp;rsquo;s Make Some Moves!&lt;/h1&gt;
&lt;p&gt;Getting a &lt;em&gt;window&lt;/em&gt; up and running with &lt;code&gt;Vulkan&lt;/code&gt; is exactly the same as it would be with &lt;code&gt;OpenGL&lt;/code&gt; and &lt;code&gt;GLFW&lt;/code&gt;. I am very glad to have had a chance to play with GLFW when I did to smooth out this process!&lt;/p&gt;
&lt;p&gt;I always prefer to start from the last file written and work my way backwards to the first. It usually layers properly in my brain that way, so we&amp;rsquo;ll be starting with &lt;code&gt;first_app.cpp&lt;/code&gt; and work our way backwards ending with &lt;code&gt;main.cpp&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;Notes&#34;&gt;Code Notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;anything you see that has &lt;code&gt;jde&lt;/code&gt; or &lt;code&gt;Jde&lt;/code&gt; is something that I changed, and is something that &lt;em&gt;YOU&lt;/em&gt; can also change! In the &lt;a href=&#34;&#34;&gt;videos&lt;/a&gt; you&amp;rsquo;ll notice these are originally &lt;code&gt;lve&lt;/code&gt; and &lt;code&gt;Lve&lt;/code&gt; but you should change these to something for yourself as it helps with the learning process.&lt;/li&gt;
&lt;li&gt;every translation unit is namespaced with &lt;code&gt;jde&lt;/code&gt; which was also originally &lt;code&gt;lve&lt;/code&gt; in the tutorial&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;we&amp;rsquo;re starting with a small directory structure that will just create a GLFW window:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── CMakeLists.txt                      BUILDS PROJECT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── src
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── first_app.cpp                   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── first_app.hpp                   CLASS &amp;#34;FirstApp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_window.cpp                  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_window.hpp                  CLASS &amp;#34;JdeWindow&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── main.cpp                        ENTRY POINT
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;remember&lt;/strong&gt; it&amp;rsquo;s totally encouraged to change anything named &lt;code&gt;jde&lt;/code&gt; or &lt;code&gt;Jde&lt;/code&gt; to your liking, but the two &lt;strong&gt;are&lt;/strong&gt; case sensitve!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;Window&#34;&gt;Starting The Vulkan Window&lt;/h1&gt;
&lt;h1 id=&#34;FirstApp&#34;&gt;The &lt;code&gt;FirstApp&lt;/code&gt; Class&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;calls &lt;code&gt;FirstApp::run()&lt;/code&gt; in the &lt;code&gt;jde&lt;/code&gt; namespace which contains a &lt;code&gt;while&lt;/code&gt; loop that repeatedly calls &lt;code&gt;glfwPollEvents()&lt;/code&gt; until the &lt;code&gt;jdeWindow&lt;/code&gt; member variable of the &lt;code&gt;FirstApp&lt;/code&gt; class returns &lt;code&gt;true&lt;/code&gt; for the &lt;code&gt;shouldClose()&lt;/code&gt; method. This is our &lt;code&gt;Game Loop&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;first_appcpp&#34;&gt;&lt;code&gt;first_app.cpp&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// first_app.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;first_app.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;run()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;jdeWindow.shouldClose())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            glfwPollEvents();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;first_apphpp&#34;&gt;&lt;code&gt;first_app.hpp&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// first_app.hpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_window.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FirstApp&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;constexpr&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; WIDTH &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;constexpr&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; HEIGHT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;600&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow jdeWindow{WIDTH, HEIGHT, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello Vulkan!&amp;#34;&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;note that we are including &lt;code&gt;jde_window.hpp&lt;/code&gt; in the header in this file; the header for our &lt;code&gt;FirstApp&lt;/code&gt; class in the &lt;code&gt;jde&lt;/code&gt; namespace. This is where we define the &lt;code&gt;WIDTH&lt;/code&gt; and &lt;code&gt;HEIGHT&lt;/code&gt; of the application as &lt;code&gt;static constexpr int&lt;/code&gt;, and at a resolution of &lt;code&gt;800x600&lt;/code&gt;. Finally the &lt;code&gt;private method&lt;/code&gt; &lt;code&gt;jdeWindow&lt;/code&gt; is initialized with our height and width when &lt;code&gt;run()&lt;/code&gt; is called and our game loop begins;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;JdeWindow&#34;&gt;The &lt;code&gt;JdeWindow&lt;/code&gt; Class&lt;/h3&gt;
&lt;h1 id=&#34;jde_windowhpp&#34;&gt;&lt;code&gt;jde_window.hpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define GLFW_INCLUDE_VULKAN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JdeWindow&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; w, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; h, std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string name);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;JdeWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;operator&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;shouldClose&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; glfwWindowShouldClose(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; initWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; width;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; height;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string windowName;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        GLFWwindow &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;window;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;this is our window class &lt;code&gt;JdeWindow&lt;/code&gt;, its constructor takes a &lt;code&gt;w&lt;/code&gt;, &lt;code&gt;h&lt;/code&gt;, and a &lt;code&gt;name&lt;/code&gt; which are used to initialize the &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and &lt;code&gt;name&lt;/code&gt; of the window. We properly handle the available constructors, and the destructor destroys the window and terminates GLFW. The class has &lt;em&gt;deleted &lt;code&gt;copy constructor&lt;/code&gt; and copy &lt;code&gt;assignment operator&lt;/code&gt;&lt;/em&gt;, which means that instances of this class cannot be copied. This is where our &lt;code&gt;game loop&lt;/code&gt; is requested to terminate. &lt;code&gt;JdeWindow&lt;/code&gt; has a public method called &lt;code&gt;shouldClose()&lt;/code&gt;, which returns a bool indicating whether the window has been closed or not. Finally there is also one private method &lt;code&gt;initWindow()&lt;/code&gt; that actually initializes the window. The private variables store width, height, and the name of the GLFW window.&lt;/p&gt;
&lt;h1 id=&#34;jde_windowcpp&#34;&gt;&lt;code&gt;jde_window.cpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// jde_window.cpp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_window.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; w, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; h, std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string name)&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        width{w}, height{h}, windowName{name}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        initWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::~&lt;/span&gt;JdeWindow()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwDestroyWindow(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;initWindow()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwInit();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        window &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; glfwCreateWindow(width, height, windowName.c_str(), &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jde_window.cpp&lt;/code&gt; code starts by including the &lt;code&gt;jde_window.hpp&lt;/code&gt; header file, which contains declarations for the &lt;code&gt;JdeWindow&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;our namespace &lt;code&gt;jde&lt;/code&gt; is defined.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;JdeWindow&lt;/code&gt; class is defined, which has a constructor that takes in three parameters: &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and a &lt;em&gt;string&lt;/em&gt; &lt;code&gt;name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;constructor&lt;/code&gt;, the input parameters are assigned to the &lt;em&gt;member variables&lt;/em&gt; of the class. Then the function &lt;code&gt;initWindow()&lt;/code&gt; is called.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;destructor&lt;/code&gt; is defined, which is called when the &lt;code&gt;JdeWindow&lt;/code&gt; object is destroyed. It destroys the window and terminates &lt;code&gt;GLFW&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;initWindow()&lt;/code&gt; function is defined, which initializes &lt;code&gt;GLFW&lt;/code&gt; and sets some &lt;em&gt;window hints&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;GLFW&lt;/code&gt; library is initialized.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;GLFW_CLIENT_API&lt;/code&gt; hint is set to &lt;code&gt;GLFW_NO_API&lt;/code&gt; to indicate that no graphics API is used&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;GLFW_RESIZABLE&lt;/code&gt; hint is set to &lt;code&gt;GLFW_FALSE&lt;/code&gt; to indicate that the window is &lt;em&gt;not resizable&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;window&lt;/em&gt; is created with the specified &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;window pointer&lt;/em&gt; is assigned to the window member variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;main&#34;&gt;Making Entry in &lt;code&gt;main.cpp&lt;/code&gt;!&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;We now get to hit the &lt;code&gt;run()&lt;/code&gt; command we saw very first! This is the &lt;code&gt;main()&lt;/code&gt; function of the application, which is the entry point of our window!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;first_app.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;cstdlib&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdexcept&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    jde&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;FirstApp app{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        app.run();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    } &lt;span style=&#34;color:#66d9ef&#34;&gt;catch&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;exception &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;cerr &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; e.what() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; EXIT_FAILURE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; EXIT_SUCCESS;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our entrypoint creates an instance of our &lt;code&gt;FirstApp&lt;/code&gt; class, which was defined in &lt;code&gt;first_app.hpp&lt;/code&gt;, and calls &lt;code&gt;run()&lt;/code&gt;; which is responsible for executing our main loop aka game loop, which just keeps running as long as the window is open. This loop keeps running as long as the window is open, by &lt;code&gt;polling&lt;/code&gt; the &lt;code&gt;events&lt;/code&gt; from the &lt;code&gt;window&lt;/code&gt;. I like to use the powerful C++ standard when I can and haven&amp;rsquo;t had the opportunity to use &lt;em&gt;try-catch blocks&lt;/em&gt; in a real-world application yet, so this tutorial has me happy for that. The main function also includes a try-catch block that catches any &lt;em&gt;exceptions&lt;/em&gt; that are thrown by the &lt;code&gt;run()&lt;/code&gt; method. If an &lt;code&gt;exception&lt;/code&gt; is caught, the &lt;em&gt;error message&lt;/em&gt; is printed to the &lt;em&gt;standard error output&lt;/em&gt; and the program exits with the failure status code: &lt;code&gt;EXIT_FAILURE&lt;/code&gt;; otherwise, if the program exits without an &lt;code&gt;exception&lt;/code&gt;, it will return the &lt;code&gt;EXIT_SUCCESS&lt;/code&gt; status code.&lt;/p&gt;
&lt;h1 id=&#34;Open&#34;&gt;Opening the Window to the World of Vulkan!&lt;/h1&gt;
&lt;p&gt;Run the following &lt;code&gt;CMake&lt;/code&gt; command &lt;em&gt;if you&amp;rsquo;re not using something like Emacs or VS Code&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cmake -B ./build -S .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and you should see around the same output as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- The C compiler identification is GNU 12.2.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- The CXX compiler identification is GNU 12.2.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compiler ABI info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compiler ABI info - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Check for working C compiler: /usr/bin/cc - skipped
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compile features
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compile features - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compiler ABI info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compiler ABI info - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Check for working CXX compiler: /usr/bin/c++ - skipped
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compile features
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compile features - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Found Vulkan: /lib64/libvulkan.so (found version &amp;#34;1.3.216&amp;#34;) found components: glslc glslangValidator 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Configuring done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Generating done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Build files have been written to: /home/mac/Documents/Projects/C++/Vulkan/build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;changing into the &lt;em&gt;build directory&lt;/em&gt; and issuing a &lt;code&gt;make&lt;/code&gt; command is next:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or I found that you can run &lt;code&gt;make&lt;/code&gt; from anywhere using the &lt;code&gt;-C&lt;/code&gt; flag &lt;code&gt;make -C build&lt;/code&gt;&lt;br&gt;
in any case you should see something similar to the following output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[  0%] Built target copy_assets
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 14%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/first_app.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 28%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_device.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 42%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_pipeline.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 57%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_swap_chain.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 71%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_window.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 85%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/main.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[100%] Linking CXX executable Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[100%] Built target Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the last line says &lt;code&gt;Built target Vulkan-Starter&lt;/code&gt; is what matters, that&amp;rsquo;s our binary!&lt;/p&gt;
&lt;p&gt;now we can change into the build directory, if you&amp;rsquo;re not already there &lt;code&gt;cd build&lt;/code&gt;, and launch our &lt;del&gt;GLFW&lt;/del&gt; Vulkan Window!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;images/blank-window.png&#34; alt=&#34;blank-window&#34;&gt;&lt;/p&gt;
&lt;p&gt;and with any luck you&amp;rsquo;ll have a fully functional GLFW window that doesn&amp;rsquo;t immediately exit, but also doesn&amp;rsquo;t do anything!&lt;/p&gt;
&lt;h1 id=&#34;HardPart&#34;&gt;Unfortunately That Was the Easy Part&lt;/h1&gt;
&lt;p&gt;Next we have to build out the entire Vulkan graphics pipeline and an API to interface with the Graphics Card.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/Brendan-Galea-Graphics-Pipeline-Overview-Vulkan-Game-Engine-Tutorial-02.png&#34; alt=&#34;Brendan-Galea-Graphics-Pipeline-Overview-Vulkan-Game-Engine-Tutorial-02&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;image credit to Brendan Galea - Vulkan Game Engine Tutorial 2&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;TriDir&#34;&gt;Directory Structure for the Vulkan Triangle&lt;/h1&gt;
&lt;p&gt;You&amp;rsquo;ll need to download these 4 files if you haven&amp;rsquo;t grabbed them yet!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=LYKlEIzGmW4&amp;amp;t=94s&#34;&gt;lve_device.cpp &amp;amp; lve_device.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=IUYH74MqxOA&amp;amp;t=194s&#34;&gt;lve_swap_chain.cpp &amp;amp; lve_swap_chain.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;if you watch the section of the video he talks about the edits you will need to make to those files! Basically it comes down to the namespace and the first few letters of the class name, and each method of the class.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and create 5 more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;glslc.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jde_pipeline.cpp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jde_pipeline.hpp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shaders/simple_shader.frag&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shaders/simple_shader.vert&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;my project directory tree AFTER &lt;a href=&#34;https://youtu.be/_VOR6q3edig?list=PL8327DO66nu9qYVKLDmdLW_84-yE4auCR&#34;&gt;video #7&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;.spv&lt;/code&gt; are the compiled output from &lt;code&gt;glslc&lt;/code&gt; which we&amp;rsquo;re getting to soon&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── CMakeLists.txt                      BUILDS PROJECT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── src
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── first_app.cpp                   
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── first_app.hpp                   CLASS &amp;#34;FirstApp&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── glslc.sh                        COMPILES SHADERS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_device.cpp                  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_device.hpp                  CLASS &amp;#34;JdeDevice&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_pipeline.cpp                
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_pipeline.hpp                CLASS &amp;#34;JdePipeline&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_swap_chain.cpp              
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_swap_chain.hpp              CLASS &amp;#34;JdeSwapChain&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_window.cpp                  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── jde_window.hpp                  CLASS &amp;#34;JdeWindow&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── main.cpp                        ENTRY POINT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── shaders
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ├── simple_shader.frag          SPIR-V FRAGMENT SHADER
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ├── simple_shader.frag.spv      COMPILED SPIR-V FROM GLSLC
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ├── simple_shader.vert          SPIR-V VERTEX SHADER
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        └── simple_shader.vert.spv      COMPILED SPIR-V FROM GLSLC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h1 id=&#34;ShaderChain&#34;&gt;One Nice Thing About the Shader Chain&lt;/h1&gt;
&lt;p&gt;we can really only program two stages of the shader chain in Vulkan, the &lt;code&gt;Vertex Shader&lt;/code&gt; and the &lt;code&gt;Fragment Shader&lt;/code&gt;, which are right here:&lt;/p&gt;
&lt;h1 id=&#34;srcshaderssimple_shaderfrag&#34;&gt;&lt;code&gt;src/shaders/simple_shader.frag&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;is our fragment shader, responsible for determining the color of each pixel on the screen.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-HLSL&#34; data-lang=&#34;HLSL&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#version 450&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;layout (location &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;out&lt;/span&gt; vec4 outColor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; main()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    outColor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; vec4(&lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It defines a single output variable &amp;ldquo;outColor&amp;rdquo;, which is a 4-component vector representing the red, green, blue, and alpha (transparency) values of the pixel. In the main function, the outColor variable is set to a fixed value of (1.0, 1.0, 0.1, 1.0), which corresponds to a bright yellow color with full opacity.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;srcshaderssimple_shadervert&#34;&gt;&lt;code&gt;src/shaders/simple_shader.vert&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;is our vertex shader, which is responsible for determining the position of each vertex in the 3D space.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-HLSL&#34; data-lang=&#34;HLSL&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#version 450&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vec2 positions[&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; vec2[](
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vec2(&lt;span style=&#34;color:#ae81ff&#34;&gt;0.0&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vec2(&lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vec2(&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; main() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gl_Position &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; vec4(positions[gl_VertexIndex], &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It defines an array &amp;ldquo;positions&amp;rdquo; of 2D vectors, which represent the coordinates of three vertices. This shader will be used to draw the triangle on the screen using the provided vertex positions.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;ShaderCompile&#34;&gt;Shaders Are Done, Now Let&amp;rsquo;s Compile!&lt;/h1&gt;
&lt;p&gt;and that&amp;rsquo;s the last time we&amp;rsquo;ll have to touch those before we get a Triangle on-screen, but that&amp;rsquo;s a ways off still. First we now need to utilize our VulkanSDK to run &lt;code&gt;glslc&lt;/code&gt;. In the video he uses this script which works just fine in &lt;code&gt;bash&lt;/code&gt;, so from &lt;code&gt;fish&lt;/code&gt; I&amp;rsquo;ve just been launching a &lt;code&gt;bash&lt;/code&gt; shell to run this &lt;code&gt;src/glslc.sh&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$VULKAN_SDK/bin/glslc shaders/simple_shader.vert -o shaders/simple_shader.vert.spv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$VULKAN_SDK/bin/glslc shaders/simple_shader.frag -o shaders/simple_shader.frag.spv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make sure that you change the mode of our file for executuion with  &lt;code&gt;chmod&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod +x src/glslc.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and finally&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./src/glslc.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;should run do the thing&lt;/p&gt;
&lt;p&gt;It won&amp;rsquo;t tell you if you got it right, but &lt;code&gt;glslc&lt;/code&gt; complain nicely if something didn&amp;rsquo;t go right.&lt;/p&gt;
&lt;p&gt;if you&amp;rsquo;re using &lt;code&gt;fish&lt;/code&gt; you may as well just go to &lt;code&gt;BASH&lt;/code&gt; like I did:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bash ./src/glslc.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./src/glslc.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to get a full shell environment up. If your environment variables aren&amp;rsquo;t working, make sure you&amp;rsquo;ve logged out of your user session since adding anything to your &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt;. If it really isn&amp;rsquo;t working just use the commands from the script as a guide to work through the process manually.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t go as far as incorporating the shader compilation step into the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;copy_assets&lt;/code&gt; function just yet, but that&amp;rsquo;s still something I will go on and do. I&amp;rsquo;ll update this post if/when it happens.&lt;/p&gt;
&lt;h1 id=&#34;Triangle&#34;&gt;Toward The TRIANGLE!&lt;/h1&gt;
&lt;p&gt;The GLFW window we wrote is about to get Vulkanized, and this page is going to start looking like &lt;a href=&#34;https://github.com/Jmac217/Vulkan-Starter-Engine&#34;&gt;GitHub&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;As Brendan Stated in the &lt;a href=&#34;https://youtu.be/LYKlEIzGmW4?t=94&#34;&gt;tutorial&lt;/a&gt;, there&amp;rsquo;s a lot of extra boilerplate that gets in the way and does not need to be thought about at this stage. By following the tutorial beyond the point of this triangle example&lt;/p&gt;
&lt;p&gt;There are 4 files to download from the tutorial and at very least the namespace will need to be changed to &lt;code&gt;jde&lt;/code&gt; in those downloads. It&amp;rsquo;s not proper etiquate to link directly to those files, and you should watch those parts of the videos anyway to really see what to change in the files.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=LYKlEIzGmW4&amp;amp;t=94s&#34;&gt;lve_device.cpp &amp;amp; lve_device.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=IUYH74MqxOA&amp;amp;t=194s&#34;&gt;lve_swap_chain.cpp &amp;amp; lve_swap_chain.hpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;re jumping right to the Tringle BTW, these next couple of files are the only things we still need!&lt;/p&gt;
&lt;h1 id=&#34;FirstTriangleHpp&#34;&gt;The expanded &lt;code&gt;first_app.hpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_window.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_pipeline.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_device.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_swap_chain.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FirstApp&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;constexpr&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; WIDTH &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;constexpr&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; HEIGHT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;600&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        FirstApp();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;FirstApp();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        FirstApp(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; FirstApp &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        FirstApp &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;operator&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; FirstApp &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; createPipelineLayout();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;createPipeline&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;createCommandBuffers&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;drawFrame&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow jdeWindow{WIDTH, HEIGHT, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello Vulkan!&amp;#34;&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeDevice jdeDevice{jdeWindow};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeSwapChain jdeSwapChain{jdeDevice, jdeWindow.getExtent()};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;unique_ptr&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; jdePipeline;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineLayout pipelineLayout;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;VkCommandBuffer&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; commandBuffers;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our &lt;code&gt;FirstApp&lt;/code&gt; class has a &lt;em&gt;default&lt;/em&gt; &lt;code&gt;constructor&lt;/code&gt; and &lt;code&gt;destructor&lt;/code&gt; and a still similar &lt;code&gt;run()&lt;/code&gt; method.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;constructor&lt;/code&gt; now creates a &lt;em&gt;pipeline layout&lt;/em&gt;, pipeline, and &lt;em&gt;command buffers&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;destructor&lt;/code&gt; now destroys the &lt;em&gt;pipeline layout&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;run()&lt;/code&gt; method is still our main loop in the application, it polls events and now calls the &lt;code&gt;drawFrame&lt;/code&gt; method.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;createPipelineLayout&lt;/code&gt; method creates a &lt;em&gt;pipeline layout&lt;/em&gt; for the pipeline. It sets the layout count and push constant range count to 0 and creates the &lt;em&gt;pipeline layout&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;createPipeline&lt;/code&gt; method creates a pipeline and assigns the &lt;em&gt;render pass&lt;/em&gt; and &lt;em&gt;pipeline layout&lt;/em&gt; to it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;createCommandBuffers&lt;/code&gt; method resizes the &lt;em&gt;command buffers&lt;/em&gt; vector to the size of the &lt;em&gt;swap chain&lt;/em&gt; images. It allocates &lt;em&gt;command buffers&lt;/em&gt; and begins recording them. It sets up a &lt;em&gt;render pass&lt;/em&gt;, clears the color and depth values, and binds the pipeline and draws a triangle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;drawFrame&lt;/code&gt; method acquires an image from the &lt;em&gt;swap chain&lt;/em&gt;, and begins and ends the command buffer while submitting to the mailbox queue.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and the accompanying translation unit is rather large:&lt;/p&gt;
&lt;h1 id=&#34;FirstTriangleCpp&#34;&gt;&lt;code&gt;first_app.cpp&lt;/code&gt; Just Got A Lot Bigger!&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;first_app.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdexcept&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;array&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;FirstApp()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createPipelineLayout();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createPipeline();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createCommandBuffers();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::~&lt;/span&gt;FirstApp()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vkDestroyPipelineLayout(jdeDevice.device(), pipelineLayout, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;run()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;jdeWindow.shouldClose())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            glfwPollEvents();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            drawFrame();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createPipelineLayout()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineLayoutInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineLayoutInfo.setLayoutCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineLayoutInfo.pSetLayouts &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineLayoutInfo.pushConstantRangeCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineLayoutInfo.pPushConstantRanges &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vkCreatePipelineLayout(jdeDevice.device(), &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pipelineLayoutInfo, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pipelineLayout) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to create pipeline layout!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createPipeline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; pipelineConfig &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;defaultPipelineConfigInfo(jdeSwapChain.width(), jdeSwapChain.height());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineConfig.renderPass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.getRenderPass();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineConfig.pipelineLayout &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pipelineLayout;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        jdePipeline &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;make_unique&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            jdeDevice, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;src/shaders/simple_shader.vert.spv&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;src/shaders/simple_shader.frag.spv&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            pipelineConfig);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createCommandBuffers()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        commandBuffers.resize(jdeSwapChain.imageCount());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkCommandBufferAllocateInfo allocInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allocInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allocInfo.level &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_COMMAND_BUFFER_LEVEL_PRIMARY;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allocInfo.commandPool &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeDevice.getCommandPool();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        allocInfo.commandBufferCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(commandBuffers.size());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(vkAllocateCommandBuffers(jdeDevice.device(), &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;allocInfo, commandBuffers.data())&lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to allocate command buffers!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; commandBuffers.size(); i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            VkCommandBufferBeginInfo beginInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            beginInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vkBeginCommandBuffer(commandBuffers[i], &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;beginInfo) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to begin recording command buffers!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            VkRenderPassBeginInfo renderPassInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.renderPass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.getRenderPass();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.framebuffer &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.getFrameBuffer(i);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.renderArea.offset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.renderArea.extent &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.getSwapChainExtent();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;array&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;VkClearValue, &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; clearValues{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            clearValues[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ae81ff&#34;&gt;0.2f&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.5f&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.9f&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            clearValues[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].depthStencil &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.clearValueCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(clearValues.size());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            renderPassInfo.pClearValues &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; clearValues.data();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            vkCmdBeginRenderPass(commandBuffers[i], &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            jdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;bind(commandBuffers[i]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            vkCmdDraw(commandBuffers[i], &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            vkCmdEndRenderPass(commandBuffers[i]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vkEndCommandBuffer(commandBuffers[i]) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to record command buffer&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; FirstApp&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;drawFrame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; imageIndex;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.acquireNextImage(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;imageIndex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (result &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; result &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUBOPTIMAL_KHR)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;imageIndex failed to acquire swap chain image!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; jdeSwapChain.submitCommandBuffers(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;commandBuffers[imageIndex], &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;imageIndex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (result &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;result failed to acquire swap chain image!&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;FirstApp &lt;code&gt;constructor&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creates a &lt;em&gt;pipeline layout&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;creates a pipeline&lt;/li&gt;
&lt;li&gt;creates &lt;em&gt;command buffers&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;FirstApp &lt;code&gt;destructor&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;destroys the &lt;em&gt;pipeline layout&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;FirstApp::run()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;enters a loop that polls events and calls the &lt;code&gt;drawFrame&lt;/code&gt; method as long as the window is not closed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;FirstApp::createPipelineLayout()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creates a &lt;em&gt;pipeline layout&lt;/em&gt; with no set layouts or push constant ranges&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;FirstApp::createPipeline()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;creates a pipeline with the render pass and &lt;em&gt;pipeline layout&lt;/em&gt; from the &lt;code&gt;JdeSwapChain&lt;/code&gt; and &lt;code&gt;JdePipeline&lt;/code&gt; classes, and assigns it to the &lt;code&gt;jdePipeline&lt;/code&gt; &lt;em&gt;member variable&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;FirstApp::createCommandBuffers()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;resizes the &lt;em&gt;command buffers&lt;/em&gt; vector to the number of images in the &lt;em&gt;swap chain&lt;/em&gt;
allocates &lt;em&gt;command buffers&lt;/em&gt; and begins recording them&lt;/li&gt;
&lt;li&gt;sets up a render pass, clears the color and depth values, and binds the pipeline and draws a triangle&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;FirstApp::drawFrame()&lt;/code&gt;:
acquires an image from the &lt;em&gt;swap chain&lt;/em&gt;
begins and ends the &lt;em&gt;command buffer&lt;/em&gt; and submits it to the mailbox queue&lt;/p&gt;
&lt;h1 id=&#34;PipelineHpp&#34;&gt;Vulkan Graphics Pipeline Configuration&lt;/h1&gt;
&lt;h1 id=&#34;jde_pipelinehpp&#34;&gt;&lt;code&gt;jde_pipeline.hpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_device.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;PipelineConfigInfo&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkViewport viewport;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkRect2D scissor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineViewportStateCreateInfo viewportInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineRasterizationStateCreateInfo rasterizationInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineMultisampleStateCreateInfo multisampleInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineColorBlendAttachmentState colorBlendAttachment;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineColorBlendStateCreateInfo colorBlendInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineLayout pipelineLayout &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkRenderPass renderPass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; subpass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JdePipeline&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdePipeline(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            JdeDevice &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;device, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; vertFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; fragFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; PipelineConfigInfo&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; configInfo);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;JdePipeline();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdePipeline(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;operator&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;bind&lt;/span&gt;(VkCommandBuffer commandBuffer);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; PipelineConfigInfo &lt;span style=&#34;color:#a6e22e&#34;&gt;defaultPipelineConfigInfo&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; width, &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; height);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; readFile(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; filepath);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;createGraphicsPipeline&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; vertFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; fragFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; PipelineConfigInfo&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; configInfo);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;createShaderModule&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt; code, VkShaderModule&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; shaderModule);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// implicitly will outlive any class that depends on it. &amp;#34;aggregation&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        JdeDevice&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; jdeDevice;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipeline graphicsPipeline;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkShaderModule vertShaderModule;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkShaderModule fragShaderModule;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code is defining a class called &lt;code&gt;JdePipeline&lt;/code&gt; in the &lt;code&gt;jde&lt;/code&gt; namespace. The class has a &lt;code&gt;constructor&lt;/code&gt;, &lt;code&gt;destructor&lt;/code&gt;, and a function called &lt;code&gt;bind()&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;constructor&lt;/code&gt; takes in a &lt;code&gt;JdeDevice&lt;/code&gt; object, the file paths for a &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shader&lt;/code&gt;, and a &lt;code&gt;PipelineConfigInfo&lt;/code&gt; struct.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;destructor&lt;/code&gt; will clean up the &lt;em&gt;pipeline&lt;/em&gt; and &lt;em&gt;shader modules&lt;/em&gt;. The &lt;code&gt;bind()&lt;/code&gt; function is used to &lt;em&gt;bind&lt;/em&gt; the &lt;em&gt;pipeline&lt;/em&gt; to a &lt;em&gt;command buffer&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;JdePipeline&lt;/code&gt; class also has a static function called &lt;code&gt;defaultPipelineConfigInfo()&lt;/code&gt; that returns a &lt;code&gt;PipelineConfigInfo&lt;/code&gt; struct with default values for its member variables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The class has a &lt;em&gt;private function&lt;/em&gt; called &lt;code&gt;createGraphicsPipeline()&lt;/code&gt; that creates the &lt;em&gt;pipeline&lt;/em&gt; using the provided configuration and &lt;em&gt;shaders&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It also has a private function called &lt;code&gt;createShaderModule()&lt;/code&gt; that creates a shader module from the provided code.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The class has a member variable &lt;code&gt;graphicsPipeline&lt;/code&gt; of type &lt;code&gt;VkPipeline&lt;/code&gt;, which will store the &lt;em&gt;pipeline&lt;/em&gt; object.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It also has two &lt;em&gt;member variables&lt;/em&gt; of type &lt;code&gt;VkShaderModule&lt;/code&gt;, which will store the &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shader&lt;/code&gt; modules.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The class also has a reference to the &lt;code&gt;JdeDevice&lt;/code&gt; object, which is passed in through the &lt;code&gt;constructor&lt;/code&gt; and is used to interact with the device throughout the lifetime of the &lt;em&gt;pipeline&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and the massive list of groupings of definitions lie ahead:&lt;/p&gt;
&lt;h1 id=&#34;PipelineCpp&#34;&gt;&lt;code&gt;jde_pipeline.cpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_pipeline.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;fstream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdexcept&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;cassert&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;JdePipeline(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            JdeDevice &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;device, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; vertFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; fragFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; PipelineConfigInfo&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; configInfo)&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            jdeDevice{device}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createGraphicsPipeline(vertFilepath, fragFilepath, configInfo);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::~&lt;/span&gt;JdePipeline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vkDestroyShaderModule(jdeDevice.device(), vertShaderModule, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vkDestroyShaderModule(jdeDevice.device(), fragShaderModule, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vkDestroyPipeline(jdeDevice.device(), graphicsPipeline, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;readFile(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; filepath)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;ifstream file{filepath, std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;ios&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;ate &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;ios&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;binary};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;file.is_open())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to open file: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; filepath);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        size_t fileSize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;size_t&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(file.tellg());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; buffer(fileSize);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        file.seekg(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        file.read(buffer.data(), fileSize);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        file.close();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; buffer;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createGraphicsPipeline(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; vertFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; fragFilepath, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; PipelineConfigInfo&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; configInfo)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assert(configInfo.pipelineLayout &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_NULL_HANDLE &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot create graphics pipeline:: no pipelineLayout provided in configInfo&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assert(configInfo.renderPass &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_NULL_HANDLE &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Cannot create graphics pipeline:: no pipelineLayout provided in configInfo&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; vertCode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; readFile(vertFilepath);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt; fragCode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; readFile(fragFilepath);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createShaderModule(vertCode, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;vertShaderModule);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createShaderModule(fragCode, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;fragShaderModule);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineShaderStageCreateInfo shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].stage &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_SHADER_STAGE_VERTEX_BIT;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].module &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; vertShaderModule;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].pName &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].flags &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].pNext &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;].pSpecializationInfo &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].stage &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_SHADER_STAGE_FRAGMENT_BIT;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].module &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; fragShaderModule;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].pName &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].flags &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].pNext &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shaderStages[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;].pSpecializationInfo &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vertexInputInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vertexInputInfo.vertexAttributeDescriptionCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vertexInputInfo.vertexBindingDescriptionCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vertexInputInfo.pVertexAttributeDescriptions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vertexInputInfo.pVertexBindingDescriptions &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkPipelineViewportStateCreateInfo viewportInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        viewportInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        viewportInfo.viewportCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        viewportInfo.pViewports &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.viewport;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        viewportInfo.scissorCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        viewportInfo.pScissors &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.scissor;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkGraphicsPipelineCreateInfo pipelineInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.stageCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pStages &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; shaderStages;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pVertexInputState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;vertexInputInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pInputAssemblyState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.inputAssemblyInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pViewportState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;viewportInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pRasterizationState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.rasterizationInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pMultisampleState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.multisampleInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pColorBlendState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.colorBlendInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pDepthStencilState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.depthStencilInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.pDynamicState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.layout &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; configInfo.pipelineLayout;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.renderPass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; configInfo.renderPass;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.subpass &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; configInfo.subpass;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.basePipelineIndex &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipelineInfo.basePipelineHandle &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_NULL_HANDLE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vkCreateGraphicsPipelines(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            jdeDevice.device(), 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            VK_NULL_HANDLE, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;pipelineInfo, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;graphicsPipeline) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to create graphics pipeline&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createShaderModule(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;vector&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt; code, VkShaderModule&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; shaderModule)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkShaderModuleCreateInfo createInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createInfo.codeSize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; code.size();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        createInfo.pCode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;reinterpret_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&amp;gt;&lt;/span&gt;(code.data());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vkCreateShaderModule(jdeDevice.device(), &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;createInfo, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, shaderModule) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to create shader module&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;bind(VkCommandBuffer commandBuffer)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    PipelineConfigInfo JdePipeline&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;defaultPipelineConfigInfo(&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; width, &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; height)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        PipelineConfigInfo configInfo{};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.inputAssemblyInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.inputAssemblyInfo.topology &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.inputAssemblyInfo.primitiveRestartEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.width &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;float&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(width);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.height &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;float&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(height);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.minDepth &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.viewport.maxDepth &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.scissor.offset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.scissor.extent &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {width, height};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.depthClampEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.rasterizerDiscardEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.polygonMode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_POLYGON_MODE_FILL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.lineWidth &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.cullMode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_CULL_MODE_NONE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.frontFace &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FRONT_FACE_CLOCKWISE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.depthBiasEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.rasterizationInfo.depthBiasConstantFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.rasterizationInfo.depthBiasClamp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;           &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.rasterizationInfo.depthBiasSlopeFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;     &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.multisampleInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.multisampleInfo.sampleShadingEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.multisampleInfo.rasterizationSamples &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_SAMPLE_COUNT_1_BIT;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.multisampleInfo.minSampleShading &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;;           &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.multisampleInfo.pSampleMask &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;;             &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.multisampleInfo.alphaToCoverageEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.multisampleInfo.alphaToOneEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;       &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendAttachment.colorWriteMask &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            VK_COLOR_COMPONENT_R_BIT &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; VK_COLOR_COMPONENT_G_BIT &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; VK_COLOR_COMPONENT_B_BIT &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            VK_COLOR_COMPONENT_A_BIT;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendAttachment.blendEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendAttachment.srcColorBlendFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_FACTOR_ONE;   &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendAttachment.dstColorBlendFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_FACTOR_ZERO;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendAttachment.colorBlendOp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_OP_ADD;              &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendAttachment.srcAlphaBlendFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_FACTOR_ONE;   &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendAttachment.dstAlphaBlendFactor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_FACTOR_ZERO;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendAttachment.alphaBlendOp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_BLEND_OP_ADD;              &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendInfo.logicOpEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendInfo.logicOp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_LOGIC_OP_COPY;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendInfo.attachmentCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendInfo.pAttachments &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;configInfo.colorBlendAttachment;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.colorBlendInfo.blendConstants[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendInfo.blendConstants[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendInfo.blendConstants[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.colorBlendInfo.blendConstants[&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.sType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.depthTestEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_TRUE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.depthWriteEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_TRUE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.depthCompareOp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_COMPARE_OP_LESS;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.depthBoundsTestEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.minDepthBounds &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.depthStencilInfo.maxDepthBounds &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0f&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.depthStencilInfo.stencilTestEnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VK_FALSE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        configInfo.depthStencilInfo.front &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {};  &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        configInfo.depthStencilInfo.back &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {};   &lt;span style=&#34;color:#75715e&#34;&gt;// Optional
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; configInfo;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;JdePipeline&lt;/code&gt; class provides an implementation for creating a &lt;em&gt;graphics pipeline&lt;/em&gt; in a Vulkan application.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The constructor takes in a &lt;code&gt;JdeDevice&lt;/code&gt; and file paths for &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shader&lt;/code&gt;, as well as a &lt;code&gt;PipelineConfigInfo&lt;/code&gt; struct containing information about the pipeline layout and render pass.&lt;/li&gt;
&lt;li&gt;The class uses the provided file paths to create and load a vertex and fragment shader module.&lt;/li&gt;
&lt;li&gt;It then uses the provided &lt;code&gt;PipelineConfigInfo&lt;/code&gt; and the loaded shaders to create the &lt;em&gt;graphics pipeline&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;destructor&lt;/code&gt; destroys the shader modules and the &lt;em&gt;pipeline&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;readFile&lt;/code&gt; method reads a file and returns the contents as a vector of chars.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;createShaderModule&lt;/code&gt; method creates a shader module from a vector of chars.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;createGraphicsPipeline&lt;/code&gt; method sets up the &lt;em&gt;pipeline&lt;/em&gt;, including specifying the &lt;em&gt;shaders&lt;/em&gt;, &lt;em&gt;vertex input&lt;/em&gt;, and &lt;em&gt;viewport information&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;defaultPipelineConfigInfo&lt;/code&gt; is a helper method that returns a &lt;code&gt;PipelineConfigInfo&lt;/code&gt; struct with default values for its fields. The method takes in the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; of the &lt;code&gt;viewport&lt;/code&gt;, and sets the &lt;code&gt;viewport&lt;/code&gt; and &lt;code&gt;scissor&lt;/code&gt; fields accordingly. It also sets default values for the &lt;code&gt;viewportInfo&lt;/code&gt;, &lt;code&gt;inputAssemblyInfo&lt;/code&gt;, &lt;code&gt;rasterizationInfo&lt;/code&gt;, &lt;code&gt;multisampleInfo&lt;/code&gt;, &lt;code&gt;colorBlendAttachment&lt;/code&gt;, &lt;code&gt;colorBlendInfo&lt;/code&gt;, and &lt;code&gt;depthStencilInfo&lt;/code&gt; fields.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;pipeline layout&lt;/em&gt; and &lt;em&gt;render pass&lt;/em&gt; fields are initialized to &lt;code&gt;nullptr&lt;/code&gt;, and the &lt;code&gt;subpass&lt;/code&gt; field is initialized to &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;createGraphicsPipeline&lt;/code&gt; is the method responsible for creating the &lt;em&gt;graphics pipeline&lt;/em&gt;. It takes in the filepaths for the &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shaders&lt;/code&gt;, and a &lt;code&gt;PipelineConfigInfo&lt;/code&gt; struct that contains the configuration for the &lt;em&gt;pipeline&lt;/em&gt;. The method starts by reading the &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shaders&lt;/code&gt; from the filepaths, and creating shader modules from the code.&lt;/li&gt;
&lt;li&gt;It then sets up the &lt;code&gt;shaderStages&lt;/code&gt; array with the &lt;code&gt;vertex shader&lt;/code&gt; and &lt;code&gt;fragment shader&lt;/code&gt; modules, and sets up the &lt;code&gt;vertexInputInfo&lt;/code&gt;, &lt;code&gt;viewportInfo&lt;/code&gt;, and &lt;code&gt;rasterizationInfo&lt;/code&gt; structs with the appropriate values. The &lt;code&gt;multisampleInfo&lt;/code&gt;, &lt;code&gt;colorBlendAttachment&lt;/code&gt;, &lt;code&gt;colorBlendInfo&lt;/code&gt;, and &lt;code&gt;depthStencilInfo&lt;/code&gt; structs are also set up with default values.&lt;/li&gt;
&lt;li&gt;It then creates the &lt;em&gt;graphics pipeline&lt;/em&gt; by calling &lt;code&gt;vkCreateGraphicsPipelines&lt;/code&gt; with the appropriate parameters. It also &lt;em&gt;binds&lt;/em&gt; the &lt;em&gt;pipeline layout&lt;/em&gt; and &lt;em&gt;render pass&lt;/em&gt; to the &lt;em&gt;pipeline&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1 id=&#34;WindowHpp&#34;&gt;A New And Improved &lt;code&gt;jde_window.hpp&lt;/code&gt; Window Class&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#pragma once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define GLFW_INCLUDE_VULKAN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;GLFW/glfw3.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;JdeWindow&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; w, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; h, std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string name);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;JdeWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;operator&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; JdeWindow &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;delete&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;shouldClose&lt;/span&gt;() { &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; glfwWindowShouldClose(window); }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        VkExtent2D &lt;span style=&#34;color:#a6e22e&#34;&gt;getExtent&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(width), 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;static_cast&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;(height)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;createWindowSurface&lt;/span&gt;(VkInstance instance, VkSurfaceKHR &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;surface);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; initWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; width;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; height;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string windowName;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        GLFWwindow &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;window;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;We define a class called &lt;code&gt;JdeWindow&lt;/code&gt; within the &lt;code&gt;jde&lt;/code&gt; namespace.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;JdeWindow&lt;/code&gt; class has a constructor that takes in an &lt;em&gt;integer width&lt;/em&gt;, an &lt;em&gt;integer height&lt;/em&gt; and a &lt;em&gt;string name&lt;/em&gt;, it creates a &lt;em&gt;window&lt;/em&gt; using &lt;code&gt;GLFW&lt;/code&gt; library with the provided &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;destructor&lt;/code&gt; destroys the &lt;em&gt;window&lt;/em&gt;, and a &lt;em&gt;copy constructor&lt;/em&gt; and &lt;em&gt;assignment operator&lt;/em&gt; that have been &lt;code&gt;deleted&lt;/code&gt; to prevent &lt;em&gt;object copying&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;shouldClose()&lt;/code&gt; public method returns a boolean indicating whether the window has been marked as closed by the user or not, it uses &lt;code&gt;GLFW&lt;/code&gt; library to check the status of the &lt;em&gt;window&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getExtent&lt;/code&gt; public method returns the size of the &lt;em&gt;window&lt;/em&gt; as a &lt;code&gt;VkExtent2D&lt;/code&gt; struct, which is a struct that contains the width and height of an area.&lt;/li&gt;
&lt;li&gt;There is also a method called &lt;code&gt;createWindowSurface&lt;/code&gt; that creates a &lt;em&gt;window surface&lt;/em&gt; and assigns it to the provided pointer, it takes in a &lt;code&gt;VkInstance&lt;/code&gt; and a pointer to a &lt;code&gt;VkSurfaceKHR&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The class also has a private method called &lt;code&gt;initWindow()&lt;/code&gt; which initializes the window using &lt;code&gt;GLFW&lt;/code&gt; library.
It has several &lt;em&gt;private member variables&lt;/em&gt; including &lt;em&gt;width&lt;/em&gt;, &lt;em&gt;height&lt;/em&gt;, &lt;em&gt;windowName&lt;/em&gt; and &lt;em&gt;window&lt;/em&gt; which are used to store information about the &lt;em&gt;window&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and the final piece to our triangular puzzle..!&lt;/p&gt;
&lt;h1 id=&#34;WindowCpp&#34;&gt;&lt;code&gt;jde_window.cpp&lt;/code&gt;&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;#34;jde_window.hpp&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdexcept&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;namespace&lt;/span&gt; jde {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;JdeWindow(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; w, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; h, std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;string name)&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        width{w}, height{h}, windowName{name}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        initWindow();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::~&lt;/span&gt;JdeWindow()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwDestroyWindow(window);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwTerminate();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;initWindow()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwInit();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        window &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; glfwCreateWindow(width, height, windowName.c_str(), &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; JdeWindow&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;createWindowSurface(VkInstance instance, VkSurfaceKHR &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;surface)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (glfwCreateWindowSurface(instance, window, &lt;span style=&#34;color:#66d9ef&#34;&gt;nullptr&lt;/span&gt;, surface) &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; VK_SUCCESS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;throw&lt;/span&gt; std&lt;span style=&#34;color:#f92672&#34;&gt;::&lt;/span&gt;runtime_error(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;failed to create window surface&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;JdeWindow&lt;/code&gt; class creates a &lt;code&gt;GLFW&lt;/code&gt; window with a specified &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and &lt;code&gt;name&lt;/code&gt;. The &lt;code&gt;initWindow()&lt;/code&gt; method is called in the &lt;code&gt;constructor&lt;/code&gt; to initialize the &lt;code&gt;GLFW&lt;/code&gt; library and create the window with the given &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and &lt;code&gt;name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It has a &lt;code&gt;destructor&lt;/code&gt; that destroys the window and terminates &lt;code&gt;GLFW&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;shouldClose()&lt;/code&gt; method returns a boolean indicating whether the window should be closed or not.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getExtent()&lt;/code&gt; method returns a &lt;code&gt;VkExtent2D&lt;/code&gt; struct with the width and height of the window.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;createWindowSurface&lt;/code&gt; method creates a &lt;code&gt;VkSurfaceKHR&lt;/code&gt; for the window by calling &lt;code&gt;glfwCreateWindowSurface&lt;/code&gt;, passing in the &lt;code&gt;VkInstance&lt;/code&gt;, the &lt;code&gt;GLFWwindow&lt;/code&gt;, and a &lt;code&gt;nullptr&lt;/code&gt; for the allocation callbacks. If the return value is not &lt;code&gt;VK_SUCCESS&lt;/code&gt;, it throws a runtime error &lt;em&gt;&amp;ldquo;failed to create window surface.&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;BuildTriangle&#34;&gt;And Finally Repeat The Build Steps From Before&lt;/h1&gt;
&lt;p&gt;Run the following &lt;code&gt;CMake&lt;/code&gt; command &lt;em&gt;if you&amp;rsquo;re not using something like Emacs or VS Code&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cmake -B ./build -S .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and you should see around the same output as:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- The C compiler identification is GNU 12.2.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- The CXX compiler identification is GNU 12.2.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compiler ABI info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compiler ABI info - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Check for working C compiler: /usr/bin/cc - skipped
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compile features
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting C compile features - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compiler ABI info
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compiler ABI info - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Check for working CXX compiler: /usr/bin/c++ - skipped
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compile features
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Detecting CXX compile features - done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Found Vulkan: /lib64/libvulkan.so (found version &amp;#34;1.3.216&amp;#34;) found components: glslc glslangValidator 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Configuring done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Generating done
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-- Build files have been written to: /home/mac/Documents/Projects/C++/Vulkan/build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;change into the &lt;em&gt;build directory&lt;/em&gt; and issue a &lt;code&gt;make&lt;/code&gt; command:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or I found that you can run &lt;code&gt;make&lt;/code&gt; from anywhere using the &lt;code&gt;-C&lt;/code&gt; flag &lt;code&gt;make -C build&lt;/code&gt;&lt;br&gt;
in any case you should see something similar to the following output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[  0%] Built target copy_assets
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 14%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/first_app.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 28%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_device.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 42%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_pipeline.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 57%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_swap_chain.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 71%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/jde_window.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[ 85%] Building CXX object CMakeFiles/Vulkan-Starter.dir/src/main.cpp.o
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[100%] Linking CXX executable Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[100%] Built target Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;the last line says &lt;code&gt;Built target Vulkan-Starter&lt;/code&gt; is what matters, that&amp;rsquo;s our binary!&lt;/p&gt;
&lt;h1 id=&#34;Launch&#34;&gt;LAUNCH THAT TRIANGLE!&lt;/h1&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./build/Vulkan-Starter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;images/triangle-window.png&#34; alt=&#34;Hello-Vulkan-Triangle&#34;&gt;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Using GraphQL and Express.js to Query Users from a MySQL Database</title>
      <link>https://jordanielder.com/posts/using-graphql-and-express-js-to-query-users-from-mysql-database/</link>
      <pubDate>Mon, 09 Jan 2023 20:54:30 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/using-graphql-and-express-js-to-query-users-from-mysql-database/</guid>
      <description>Starting with the Why? We&amp;rsquo;ll get into what exactly these technologies are, but first I want to explain the reasoning behind my steps in this demonstration. I&amp;rsquo;m setting out to build a rich GraphQL API and I&amp;rsquo;ve never done that before. I&amp;rsquo;ve watched some videos, read some docs, and I worked through the following steps. Before it&amp;rsquo;s lost to sleep I&amp;rsquo;m writing it all down to come back to! I hope this piques your interest!</description>
      <content>&lt;h1 id=&#34;starting-with-the-why&#34;&gt;Starting with the &lt;em&gt;Why?&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;We&amp;rsquo;ll get into what exactly these technologies are, but first I want to explain the reasoning behind my steps in this demonstration. I&amp;rsquo;m setting out to build a rich GraphQL API and I&amp;rsquo;ve never done that before. I&amp;rsquo;ve watched some videos, read some docs, and I worked through the following steps. Before it&amp;rsquo;s lost to sleep I&amp;rsquo;m writing it all down to come back to! I hope this piques your interest!&lt;/p&gt;
&lt;h1 id=&#34;so-then-lets-start-by-defining-what-each-of-the-technologies-are-that-well-be-using&#34;&gt;So then let&amp;rsquo;s start by defining what each of the technologies are that we&amp;rsquo;ll be using?&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://graphql.org/&#34;&gt;GraphQL&lt;/a&gt;&lt;/strong&gt; is &amp;ldquo;a query language for your API&amp;rdquo; which is a way to ask for specific information from a server. You can use it to get just the data that you need. Think of GraphQL like like asking a librarian for a specific book, it provides a common interface between the client and the server for data fetching and manipulations. In this demo we use it to get two users named John and Jane.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://nodejs.org/en/&#34;&gt;Node.js&lt;/a&gt;&lt;/strong&gt; is a programming language that lets you run JavaScript on your computer instead of just in a web browser.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.npmjs.com/&#34;&gt;NPM&lt;/a&gt;&lt;/strong&gt; stands for &amp;ldquo;Node Package Manager&amp;rdquo;. It&amp;rsquo;s a Package Manager for Javascript that helps developers share and reuse code. It also helps easily install, update, and use these packages. It is used in conjunction with Node.js, which is a runtime environment that allows developers to run JavaScript on the server-side (as opposed to the client-side, which is what happens in a web browser).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://expressjs.com/&#34;&gt;Express.js&lt;/a&gt;&lt;/strong&gt; is a popular web framework for building web applications in Node.js. It provides a set of features and functionality to make it easier to build and deploy web applications using Node.js. It allows developers to set up routes, handle HTTP requests and responses, and connect to databases, among other things. It is often used in conjunction with other tools and libraries, such as GraphQL, to build powerful and scalable web applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.gatsbyjs.com/docs/how-to/querying-data/running-queries-with-graphiql/&#34;&gt;Graph&lt;em&gt;i&lt;/em&gt;QL&lt;/a&gt;&lt;/strong&gt; is an in-browser tool for testing and developing GraphQL APIs. It allows developers to send GraphQL queries and mutations to the server and see the results in real-time, as well as see documentation for available fields and their arguments. This makes it a useful tool for exploring and debugging GraphQL APIs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://mariadb.org/&#34;&gt;MariaDB&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&#34;https://www.mysql.com/&#34;&gt;MySQL&lt;/a&gt;&lt;/strong&gt; are popular open-source database management systems. They allow you to store, organize, and retrieve data in a structured way. MariaDB is a fork of MySQL and is compatible with it, meaning that it can use the same data and run the same applications as MySQL. Both MariaDB and MySQL use the SQL language to interact with the database, which is a standard language for accessing and manipulating databases. They are often used in web development to store and retrieve data for web applications.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt;&lt;/strong&gt; is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package. By doing so, Docker aims to eliminate the &amp;ldquo;works on my machine&amp;rdquo; problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt;&lt;/strong&gt; is a tool used to run and manage containers, which should work in every way that Docker does to my knowlege. It allows developers to easily package and deploy applications in lightweight containers, making it easier to manage and deploy applications in different environments. Podman is a standalone tool, meaning it does not require a daemon to run, making it more secure and efficient than Docker.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;now-lets-just-dive-in-shall-we&#34;&gt;Now let&amp;rsquo;s just dive in, shall we?&lt;/h1&gt;
&lt;p&gt;Once you have &lt;a href=&#34;https://nodejs.org/en/&#34;&gt;node.js&lt;/a&gt; installed and either &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; or &lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt; up and running you&amp;rsquo;re ready to insall the NPM dependencies:
&lt;code&gt;npm install --save express express-graphql graphql mysql --force&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;--save&lt;/code&gt; flag tells npm to save these packages as dependencies in your project&amp;rsquo;s &lt;code&gt;package.json&lt;/code&gt; file. This is useful because it allows other people to easily install all of the required dependencies for your project by running npm install, and in this case it is what we are using to install the proper packages to the container image.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;--force&lt;/code&gt; flag tells npm to install the packages even if there are conflicts with already-installed packages. This can be useful if you want to overwrite an existing installation of a package. I had package conflicts and this is the dirty way to deal with them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&#34;the-real-first-step-is-planning&#34;&gt;The &lt;em&gt;real&lt;/em&gt; first step is planning&amp;hellip;&lt;/h1&gt;
&lt;p&gt;Let&amp;rsquo;s stop and think. We are going to set up a GraphQL server using Express.js and connect it to a MariaDB database using the mysql library. There&amp;rsquo;s a few things to note about that setup going in: First we&amp;rsquo;re using podman to create two containers, one for our GraphQL app and the other for the MariaDB database; and next the containers will be deployed with &lt;code&gt;podman-compose&lt;/code&gt;. There is one caveat that will be brushed over later. I&amp;rsquo;m manually inserting information into the MariaDB database for this post. It is possible to go on and add something like &lt;a href=&#34;https://www.phpmyadmin.net/&#34;&gt;PhpMyAdmin&lt;/a&gt; to manage the database operations.&lt;/p&gt;
&lt;p&gt;Copy the following &lt;code&gt;Dockerfile&lt;/code&gt; to build out the image that will then be linked in the &lt;code&gt;docker-compose&lt;/code&gt; step.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; node:12-slim&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install MariaDB client&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;RUN&lt;/span&gt; apt-get update &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y mariadb-client&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Create app directory&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WORKDIR&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; /usr/src/app&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install app dependencies&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; package*.json ./&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;RUN&lt;/span&gt; npm install&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Copy app source code&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;COPY&lt;/span&gt; . .&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Expose port 4000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;EXPOSE&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; 4000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Run the app&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CMD&lt;/span&gt; [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;npm&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;start&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and run it with the following podman or docker command:&lt;br&gt;
&lt;code&gt;podman build -t my-app -f Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;now-that-weve-successfully-built-the-image-lets-talk-about-what-just-happened&#34;&gt;Now that we&amp;rsquo;ve successfully built the image let&amp;rsquo;s talk about what just happened.&lt;/h1&gt;
&lt;p&gt;This Dockerfile is used to create a Docker image for a Node.js application that uses MariaDB as a database.&lt;/p&gt;
&lt;p&gt;The first line &lt;code&gt;FROM&lt;/code&gt; specifies the base image, which is a slim version of Node.js v12.&lt;/p&gt;
&lt;p&gt;The next line &lt;code&gt;RUN&lt;/code&gt; installs &lt;code&gt;mariadb-client&lt;/code&gt; from &lt;code&gt;apt-get&lt;/code&gt;, which is a command-line tool used to connect to and interact with MariaDB servers. You probably can just shorten that to &lt;code&gt;apt&lt;/code&gt; but I didn&amp;rsquo;t for some reason.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;WORKDIR&lt;/code&gt; directive sets the &lt;a href=&#34;https://en.wikipedia.org/wiki/Working_directory&#34;&gt;working directory&lt;/a&gt; for the subsequent instructions in our &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;COPY&lt;/code&gt; instructions copy the &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files from the current directory to the &lt;em&gt;working directory&lt;/em&gt; in our image. The &lt;code&gt;RUN&lt;/code&gt; instruction then installs the dependencies specified in these files using NPM.&lt;/p&gt;
&lt;p&gt;The second &lt;code&gt;COPY&lt;/code&gt; instruction copies all files from the &lt;a href=&#34;https://stackoverflow.com/a/66860904&#34;&gt;current directory&lt;/a&gt; to the working directory in our image.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;EXPOSE&lt;/code&gt; directive specifies that the application listens on port &lt;code&gt;4000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;code&gt;CMD&lt;/code&gt; instruction specifies the command to run when the image is run as a container. In this case, it runs &lt;code&gt;npm start&lt;/code&gt;, which starts our Node.js application.&lt;/p&gt;
&lt;h1 id=&#34;next-its-time-to-set-up-the-graphql-schema-and-server-files&#34;&gt;Next it&amp;rsquo;s time to set up the GraphQL schema and server files!&lt;/h1&gt;
&lt;p&gt;We&amp;rsquo;re going to need just two Javascript files for this project: a &lt;code&gt;server.js&lt;/code&gt; and a &lt;code&gt;schema.js&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;server.js&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;express&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;         &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;express&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;graphqlHTTP&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;express-graphql&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mysql&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;           &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mysql&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;          &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;./schema.js&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;pool&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mysql&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;createPool&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;host&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DATABASE_HOST&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;user&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DATABASE_USER&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;password&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DATABASE_PASSWORD&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;database&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;process&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;env&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DATABASE_NAME&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;root&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;users&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Promise((&lt;span style=&#34;color:#a6e22e&#34;&gt;resolve&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;reject&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;pool&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;query&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;SELECT * FROM users&amp;#39;&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;results&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#a6e22e&#34;&gt;reject&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#a6e22e&#34;&gt;resolve&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;results&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            });
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        });
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;express&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;use&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/graphql&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;graphqlHTTP&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;rootValue&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;root&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;graphiql&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;app&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;listen&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;4000&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Listening for GraphQL requests on http://localhost:4000/graphql&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;server.js&lt;/code&gt; we pull in the required modules for our app, &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;express-graphql&lt;/code&gt;, &lt;code&gt;mysql&lt;/code&gt;, and our &lt;code&gt;./schema.js&lt;/code&gt; file, and go on to create a promise for the &lt;code&gt;pool.query&lt;/code&gt; to pass in the &lt;code&gt;mysql&lt;/code&gt;: &lt;code&gt;SELECT * FROM users&lt;/code&gt; when GraphQL is asked for &lt;code&gt;Users&lt;/code&gt;. Then we set the &lt;a href=&#34;https://en.wikipedia.org/wiki/Environment_variable&#34;&gt;Environment Variables&lt;/a&gt; into the container image The root object contains the resolver functions for the GraphQL API. In this case, there is only one resolver function: &lt;code&gt;users&lt;/code&gt;. The &lt;code&gt;users&lt;/code&gt; resolver function accepts an args object as an argument, which contains the arguments passed to the user field in the &lt;code&gt;GraphQL&lt;/code&gt; query. In this case, the args object contains an &lt;code&gt;id&lt;/code&gt; field, which is used to specify the user to retrieve from our database. Then we set &lt;code&gt;app = express()&lt;/code&gt; to initialize our express app, and set our endpoint to &lt;code&gt;/graphql&lt;/code&gt; and to listen on port &lt;code&gt;4000&lt;/code&gt;. One thing to note is that setting &lt;code&gt;graphiql: true&lt;/code&gt; ensures that we can run GraphiQL in the the web browser.&lt;/p&gt;
&lt;p&gt;and next up is our &lt;a href=&#34;https://graphql.org/graphql-js/running-an-express-graphql-server/&#34;&gt;Express-GraphQL Schema&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;schema.js&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;buildSchema&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;graphql&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;buildSchema&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  type User {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    id: ID!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    name: String!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    email: String!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  type Query {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    users: [User]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;module&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;exports&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;schema&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For &lt;code&gt;schema.js&lt;/code&gt; it pulls in the required &lt;code&gt;graphql&lt;/code&gt; module and sets the schema for which GraphQL will be able to query. For our example we have will provide a database that holds a &lt;code&gt;users&lt;/code&gt; table with an auto-incrementing &lt;code&gt;id&lt;/code&gt; field along with &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt; varchar fields, which looks like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;+----+------------+------------------+
| id | name       | email            |
+----+------------+------------------+
|  1 | John Doe   | john@example.com |
|  2 | Jane Smith | jane@example.com |
+----+------------+------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which we haven&amp;rsquo;t set-up just yet, but we&amp;rsquo;ll have it up very soon!&lt;/p&gt;
&lt;h1 id=&#34;next-up-is-the-mariadb-connection&#34;&gt;Next up is the MariaDB connection&lt;/h1&gt;
&lt;p&gt;and to do that we&amp;rsquo;ll set up the final file in our project, the &lt;code&gt;docker-compose.yml&lt;/code&gt; file, and here it is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;version&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;db&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;mariadb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;MYSQL_DATABASE&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my_database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;app&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my-app:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;depends_on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;DATABASE_HOST&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;DATABASE_USER&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;DATABASE_PASSWORD&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;DATABASE_NAME&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;my_database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;4000&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;4000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This &lt;code&gt;docker-compose.yml&lt;/code&gt; file specifically sets up two services, our &lt;code&gt;db&lt;/code&gt; and our &lt;code&gt;app&lt;/code&gt;. &lt;code&gt;db&lt;/code&gt; pulls down the &lt;code&gt;mariadb&lt;/code&gt; image from &lt;a href=&#34;https://hub.docker.com/_/mariadb&#34;&gt;DockerHub&lt;/a&gt; and sets that containers Environment Variables for the Database Password and Database. This is just a demo so I&amp;rsquo;m fine with this password setup. Continuing, &lt;code&gt;app&lt;/code&gt; will try to pull an image named &lt;code&gt;my-app&lt;/code&gt; if you skipped running the build command prior to this step, again that command is &lt;code&gt;podman build -t my-app -f Dockerfile&lt;/code&gt; (and yes I&amp;rsquo;m tacking the &lt;code&gt;-f&lt;/code&gt; on to be explicit, everyone shows the &lt;code&gt;-d&lt;/code&gt; command). The &lt;code&gt;depends_on&lt;/code&gt; line is the reason we&amp;rsquo;re using the compose method, it makes it easy to link the containers together. Finally we add four environment variables to app, and set the port on the &lt;code&gt;host:image&lt;/code&gt; to &lt;code&gt;4000:4000&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;youre-finally-ready-to-run&#34;&gt;You&amp;rsquo;re FINALLY ready to run&amp;hellip;&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;podman-compose up -d&lt;/code&gt;&lt;br&gt;
Success!&lt;/p&gt;
&lt;p&gt;Now that both of our containers are up and running we can run a:&lt;br&gt;
&lt;code&gt;podman ps&lt;/code&gt; to prove it, or if you didn&amp;rsquo;t have a successful run you may want to check out:&lt;br&gt;
&lt;code&gt;podman ps -a&lt;/code&gt; to see if anything has errored. If you have to modify any of the files you can issue a removal of the image with:
&lt;code&gt;podman rm -f &amp;lt;hash-of-the-image&amp;gt;&lt;/code&gt;&lt;br&gt;
and rebuild the app image using the &lt;code&gt;Dockerfile&lt;/code&gt; with:&lt;br&gt;
&lt;code&gt;podman build -t my-app -f Dockerfile&lt;/code&gt;&lt;br&gt;
and re-running:&lt;br&gt;
&lt;code&gt;podman-compose up -d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/podman-ps.png&#34; alt=&#34;Podman PS&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;but-were-not-done-yet&#34;&gt;But we&amp;rsquo;re not done yet!&lt;/h1&gt;
&lt;p&gt;Now that our containers are up we can check &lt;code&gt;localhost:4000/graphql&lt;/code&gt; in a web browser to see that our GraphiQL instance is up and running, but we need to first insert our user information into the database to be retrieved by a GraphQL query. To do that I opted for a raw MySQL method. To follow me through these steps first run:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;podman ps&lt;/code&gt;&lt;br&gt;
to find your containers name, for me it&amp;rsquo;s the column at the furthest right, under the header called &lt;code&gt;NAMES&lt;/code&gt; like in the above image.&lt;/p&gt;
&lt;p&gt;using that name run the following command to start a MySQL connection from within the container:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;podman exec -it graphql_db_1 mysql -u root -ppassword&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/mariadb.png&#34; alt=&#34;MySQL Podman Exec&#34;&gt;&lt;/p&gt;
&lt;p&gt;Note that using &lt;code&gt;podman run&lt;/code&gt; runs a new container whereas &lt;code&gt;podman exec&lt;/code&gt; launches the currently running image!&lt;/p&gt;
&lt;p&gt;Now that we&amp;rsquo;re successfully on the &lt;a href=&#34;https://dev.mysql.com/doc/refman/8.0/en/mysql.html&#34;&gt;MySQL CLI&lt;/a&gt; let&amp;rsquo;s throw our user data in by issuing the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;USE my_database;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create the &lt;code&gt;users&lt;/code&gt; table&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; users (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id INT AUTO_INCREMENT &lt;span style=&#34;color:#66d9ef&#34;&gt;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  email VARCHAR(&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and insert our users into the table&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INTO&lt;/span&gt; users (name, email) &lt;span style=&#34;color:#66d9ef&#34;&gt;VALUES&lt;/span&gt; (&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;John Doe&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;john@example.com&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INTO&lt;/span&gt; users (name, email) &lt;span style=&#34;color:#66d9ef&#34;&gt;VALUES&lt;/span&gt; (&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Jane Smith&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;jane@example.com&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;before we go we can quickly check that we are successfully able to query our table information:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; users;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;at which point you should see the following output:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;+----+------------+------------------+
| id | name       | email            |
+----+------------+------------------+
|  1 | John Doe   | john@example.com |
|  2 | Jane Smith | jane@example.com |
+----+------------+------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&#34;images/mariadb-data.png&#34; alt=&#34;MySQL Data Entry&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;the-final-stretch&#34;&gt;The Final Stretch!&lt;/h1&gt;
&lt;p&gt;Now that all of the pieces are in place, and the database is fueled up, let&amp;rsquo;s run a GraphQL Query!!!&lt;/p&gt;
&lt;p&gt;Oh this part is so exciting. I worked for a long time getting it right, but now we should be able to go to &lt;code&gt;localhost:4000/graphql&lt;/code&gt; in our browser and punch in the following query:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;query&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;users&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;email&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and if everything goes right for you, you&amp;rsquo;ll see..!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;users&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;email&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;john@example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Jane Smith&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;email&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jane@example.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;images/graphiql.png&#34; alt=&#34;GraphiQL Successful Query&#34;&gt;&lt;/p&gt;
&lt;p&gt;This project was quite the journey! Firstly used &lt;code&gt;NPM&lt;/code&gt;, the default package manager for &lt;code&gt;Node.js&lt;/code&gt;, to install the required dependencies for our &lt;code&gt;app&lt;/code&gt; This included the &lt;code&gt;mysql&lt;/code&gt; library, which we used to connect to the MariaDB database, and the &lt;code&gt;express-graphql&lt;/code&gt; library, which allows us to use &lt;code&gt;GraphQL&lt;/code&gt; with &lt;code&gt;Express.js&lt;/code&gt;. We really started things off by setting up a &lt;code&gt;Dockerfile&lt;/code&gt; to initialize the &lt;code&gt;Node.js&lt;/code&gt; container named &lt;code&gt;my-app&lt;/code&gt;. Then we created two files &lt;code&gt;server.js&lt;/code&gt;, and &lt;code&gt;schema.js&lt;/code&gt; to run our &lt;code&gt;Express server&lt;/code&gt; which hosts the &lt;code&gt;GraphQL API&lt;/code&gt; that we defined that GraphQL &lt;code&gt;schema.js&lt;/code&gt; file and finally built and linked in the &lt;code&gt;MariaDB&lt;/code&gt; database through a &lt;code&gt;docker-compose.yml&lt;/code&gt; configuration. Fueled up our &lt;code&gt;MariaDB&lt;/code&gt; with some mock-up &lt;code&gt;users&lt;/code&gt;, John and Jane, and used a &lt;code&gt;GraphQL query&lt;/code&gt; to pull their info from the database!&lt;/p&gt;
&lt;p&gt;Overall, working with &lt;code&gt;Podman&lt;/code&gt; and setting up a &lt;code&gt;docker-compose&lt;/code&gt; file was a great way to manage the different components of our project and make sure everything was running correctly. And using &lt;code&gt;NPM&lt;/code&gt; to install the necessary packages for our server made it easy to get everything set up and running. It was definitely a learning experience, but in the end, we were able to get everything working and have a fully functional &lt;code&gt;GraphQL API&lt;/code&gt;!&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Building Games With Godot 4 and Other Free Software</title>
      <link>https://jordanielder.com/posts/building-games-with-godot-4-and-other-free-software/</link>
      <pubDate>Sun, 08 Jan 2023 05:40:47 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/building-games-with-godot-4-and-other-free-software/</guid>
      <description>Godot 4 Beta 10 Godot is an open source game engine that allows you to create 2D and 3D games. It has a user-friendly interface and a visual scripting system that makes it easy for beginners to get started.
Blender Blender is a powerful open source software for 3D modeling, animation, and rendering. It has a wide range of features and a comprehensive set of tools for creating detailed 3D models and realistic animations.</description>
      <content>&lt;h2 id=&#34;godot-4-beta-10httpsgodotengineorgenarticledev-snapshot-godot-4-0-beta-10&#34;&gt;&lt;a href=&#34;https://godotengine.org/en/article/dev-snapshot-godot-4-0-beta-10&#34;&gt;Godot 4 Beta 10&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Godot is an open source game engine that allows you to create 2D and 3D games. It has a user-friendly interface and a visual scripting system that makes it easy for beginners to get started.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;blenderhttpswwwblenderorg&#34;&gt;&lt;a href=&#34;https://www.blender.org/&#34;&gt;Blender&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Blender is a powerful open source software for 3D modeling, animation, and rendering. It has a wide range of features and a comprehensive set of tools for creating detailed 3D models and realistic animations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;kritahttpskritaorg&#34;&gt;&lt;a href=&#34;https://krita.org/&#34;&gt;Krita&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Krita is an open source digital painting and illustration software. It is well-suited for creating concept art, comics, and other 2D art. It has a wide range of brush options and a user-friendly interface.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;laigterhttpsazagayaitchiolaigter&#34;&gt;&lt;a href=&#34;https://azagaya.itch.io/laigter&#34;&gt;Laigter&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Laigter is a free and open source 3D rendering tool that is designed to be easy to use and provide high-quality results. It is a good choice for beginners looking to create 3D models and animations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;obshttpsobsprojectcom&#34;&gt;&lt;a href=&#34;https://obsproject.com/&#34;&gt;OBS&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;OBS, or Open Broadcaster Software, is a free and open source software for recording and live streaming video. It is popular for its versatility and wide range of features, making it a good choice for beginners looking to stream their gameplay or other content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;losslesscuthttpsmifinolosslesscut&#34;&gt;&lt;a href=&#34;https://mifi.no/losslesscut/&#34;&gt;LosslessCut&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Lossless-Cut is a free and open source video editor that is designed to be simple to use and provide high-quality results. It is a good choice for beginners looking to edit and trim their video footage.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;openshothttpswwwopenshotorg&#34;&gt;&lt;a href=&#34;https://www.openshot.org/&#34;&gt;Openshot&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Openshot is a free, open source video editor that is easy to use and packed with features. Whether you are a beginner or an experienced video editor, Openshot has something to offer. With a clean and intuitive interface, it is easy to get started with Openshot. You can import your video and audio files, trim and cut your clips, add transitions and effects, and much more. Plus, with its support for a wide range of file formats, you can work with just about any type of media. Give Openshot a try and see how it can help you bring your video projects to life.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;gimphttpswwwgimporg&#34;&gt;&lt;a href=&#34;https://www.gimp.org/&#34;&gt;GIMP&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;GIMP (GNU Image Manipulation Program) is a powerful, open source image editor that is perfect for both beginners and professionals. With a wide range of tools and features, GIMP is well-equipped for tasks such as photo retouching, image composition, and image authoring. Its user-friendly interface makes it easy to get started, and its support for a wide range of file formats means you can work with just about any type of image. Whether you are looking to touch up your photos or create original artwork, GIMP has something to offer. Give it a try and see how it can help you bring your creative vision to life.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;*&lt;em&gt;The description headers are hyperlinks to each project&amp;rsquo;s website&lt;/em&gt;
*&lt;em&gt;Descriptions provided by ChatGPT&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=QqRck5c8eRs&#34;&gt;Here&amp;rsquo;s the quick video I shot for this post&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve used all of these softwares to varying degrees. Some as long as 15 years (GIMP) others I came across today (Laigter). In this article I will attempt to recap what I believe are the most important parts of &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&#34;&gt;DevLogLogan&lt;/a&gt;&amp;rsquo;s tutorial video putting all of the pieces I&amp;rsquo;ve known together in one package. Though his video is 25 minutes, I paused and followed closely along the way, and by the end of the project I spent just under 3 hours creating and designing and putting all the pieces together for myself; an invaluable experience.&lt;/p&gt;
&lt;h3 id=&#34;krita&#34;&gt;Krita&lt;/h3&gt;
&lt;p&gt;I had never used Krita for much other than simplistic pixel art until today, and also I didn&amp;rsquo;t think I&amp;rsquo;d sign up for &lt;a href=&#34;https://www.textures.com/library&#34;&gt;texutres.com&lt;/a&gt;, but as &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=19s&#34;&gt;DevLogLogan&lt;/a&gt; mentions, it&amp;rsquo;s free for 15 downloads every day, and I only used 2 textures. I did however realize that, after using these textures and understanding the methods used within Krita, it&amp;rsquo;s quite possible I will be attempting my own seamless textures from my personal photo gallery next time which will feel even more unique. In Krita I imported the downloaded textures one at a time to work on them. Some good shortcuts to remember are:&lt;/p&gt;
&lt;h4 id=&#34;krita-shortcuts-i-learned-in-this-project&#34;&gt;Krita Shortcuts I learned in this project&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;Shift + w&lt;/code&gt; - Tiles the image in all directions&lt;br&gt;
&lt;code&gt;Ctrl + Alt + c&lt;/code&gt; - Resize Canvas&lt;br&gt;
&lt;code&gt;Ctrl + Alt + i&lt;/code&gt; - Scale to New Size&lt;/p&gt;
&lt;p&gt;By using the Clone Brush Preset it&amp;rsquo;s possible to touch up seam or texture region. select a clone region with &lt;code&gt;Ctrl + Left Mouse Button&lt;/code&gt;, resize the regions by &lt;code&gt;Shift + Left Mouse Button + *Moving the mouse around*&lt;/code&gt;, and watching the clone region while dragging the seam or texture region.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/krita.png&#34; alt=&#34;Krita&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;laigter&#34;&gt;Laigter&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=435s&#34;&gt;DevLogLogan&lt;/a&gt; goes into more detail than I can about Laigter, as I have only discovered it today through his video, however I will describe its usefulness in detail. &lt;a href=&#34;https://azagaya.itch.io/laigter&#34;&gt;Laigter&lt;/a&gt; is all about generating texture maps. I fed it the exported brick and floor images one at a time. It lets you add a normal map of the image as it would appear in a texture atlas, and I assume it does all kinds of other equally impressive operations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/laigter.png&#34; alt=&#34;Laigter&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;back-to-krita-but-next-time-ill-use-gimp-for-this-part&#34;&gt;Back to Krita, but next time I&amp;rsquo;ll use GIMP for this part&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=551s&#34;&gt;tutorial&lt;/a&gt; at this point uses Krita to create a &lt;a href=&#34;https://en.wikipedia.org/wiki/Texture_atlas&#34;&gt;Texture Atlas&lt;/a&gt; to be used in Blender. I found Krita to be combersome for this task, and a more general purpose editor like GIMP would suit me better.&lt;/p&gt;
&lt;h3 id=&#34;blender&#34;&gt;Blender&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve used Blender for many projects throughout 2022. Before that I made around a dozen projects in Blender all together. Even with that experience I still found it to be tricky, but I was glad to have the keyboard shortcuts down. I don&amp;rsquo;t think there was a shortcut I learned from the video which I&amp;rsquo;ve impressed myself with. I didn&amp;rsquo;t realize I was getting anywhere until noticing that. I started with a blank scene, added a plane, ensured it was 1m, and from there used edge mode to extrude in 1m increments. I haven&amp;rsquo;t had much experience with UV editing, but two textures is the perfect thing to get familiarized with the process. All together I made 4 dungeon structures: floor, wall, corner-in, and corner-out and fit the texture properly to the geometry like how it&amp;rsquo;s shown in the &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=656s&#34;&gt;video&lt;/a&gt;. Although building the structure in Blender required actually building some kind of &lt;em&gt;structure&lt;/em&gt;, it&amp;rsquo;s required to space each individual geometry out into a lineup to be properly exported. A solid tip is to name each layer &amp;ldquo;wall-&lt;strong&gt;col&lt;/strong&gt;&amp;rdquo;, &amp;ldquo;corner-&lt;strong&gt;col&lt;/strong&gt;&amp;rdquo;, etc, &amp;hellip; for use with Godot (it automatically provides a Trimesh Static Body) .&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A &amp;ldquo;trimesh static body&amp;rdquo; is a type of object that you can use in a video game or other interactive application. It is made up of a bunch of little flat shapes called &amp;ldquo;triangles&amp;rdquo; that are connected together to form a 3D object. This object is called a &amp;ldquo;trimesh&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A &amp;ldquo;static body&amp;rdquo; is an object that doesn&amp;rsquo;t move around or change. It just stays in one place. So a &amp;ldquo;trimesh static body&amp;rdquo; is an object that is made up of triangles and stays in one place. It might be used to represent things like buildings, trees, or other objects that don&amp;rsquo;t move in the game.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There&amp;rsquo;s a ton of stuff I could go on about with this section, but what&amp;rsquo;s important is that once all the geometry is lined up it needs to be exported as &lt;code&gt;*.glb&lt;/code&gt; file extension from Blender to be used with Godot, as seen in the &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=1204s&#34;&gt;video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Static body definitions provided by ChatGPT&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/blender.png&#34; alt=&#34;Blender&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/lineup.png&#34; alt=&#34;Blender GLD Lineup&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;godot&#34;&gt;Godot&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve done some work in Godot, but never before 2022. I really like the engine, although I have my complaints that don&amp;rsquo;t belong in this article. This section of &lt;a href=&#34;&#34;&gt;DevLogLogan&lt;/a&gt;&amp;rsquo;s tutorial starts with a World scene with just a plane, and a Player scene (which I made &lt;a href=&#34;https://www.youtube.com/watch?v=VjuyfBaryu8&amp;amp;t=1307s&#34;&gt;following another one of DevLogLogan&amp;rsquo;s videos&lt;/a&gt;). Adding the &lt;code&gt;glb&lt;/code&gt; file was as easy as dragging it into the scenes list in Godot, I followed the prompts to create the resource, and added it to the Grid node to be painted onto the map after configuring the grid size to match with the geometry. &lt;strong&gt;This part was fun!&lt;/strong&gt; Once you get to this point you&amp;rsquo;re making a game! I spent probably an hour here to be honest. Adding the animations came pretty easily to me for I&amp;rsquo;ve used the &lt;a href=&#34;https://docs.godotengine.org/en/stable/classes/class_animationplayer.html&#34;&gt;Animation Player&lt;/a&gt; for every project in Godot this far. I made my weapon look more like a sword than the video did. One of the more important pieces of setup in Godot is in &lt;code&gt;Project&amp;gt;Project settings&lt;/code&gt;. Changing the keymap to WASD and also setting up the video display correctly to stretch from 320x240 up to 720p like it is to give it that retro look.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/godot.png&#34; alt=&#34;Godot&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/editor.png&#34; alt=&#34;Godot Editor&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/player.png&#34; alt=&#34;Godot Player&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/dungeon.png&#34; alt=&#34;Godot Dungeon&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/map.png&#34; alt=&#34;Godot Dungeon Map&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;obs&#34;&gt;OBS&lt;/h3&gt;
&lt;p&gt;I always take a few minutes of video to wind down a project, and OBS makes it easy to screen record just about anything. I set it and just ran around the map jumping and slashing.&lt;/p&gt;
&lt;h3 id=&#34;losslesscut&#34;&gt;LosslessCut&lt;/h3&gt;
&lt;p&gt;I accidentally recorded trash audio from my room fan in the OBS recording, and LosslesCut makes it easy to add or remove tracks or media segments and concat a new muxed video of the original file. I chopped the OBS views from the video&amp;rsquo;s beginning and ending, and removed the audio. I was also able to easily grab an image from a keyframe of the video from this tool.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/losslesscut.png&#34; alt=&#34;LosslessCut&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/losslesscut-audio.png&#34; alt=&#34;LosslessCut Audio&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/thumbnail.png&#34; alt=&#34;GIMP Thumbnail&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;openshot&#34;&gt;Openshot&lt;/h3&gt;
&lt;p&gt;I did almost nothing to the file in Openshot, I would usually have added quite a bit more, but this time I ony cropped out the desktop around the video. I recommend Openshot if you don&amp;rsquo;t already have a video editor. It&amp;rsquo;s far from the best, but it works for almost everything if you put the time into it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/openshot.png&#34; alt=&#34;Openshot&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;gimp&#34;&gt;GIMP&lt;/h3&gt;
&lt;p&gt;And finally I used GIMP to open the image captured by LosslessCut, crop down the area of the thumbnail and add the 4 logos. I already have a bunch of fonts that make this kind of work come together quickly. My go to technique is to layer everything out, add the similar ones to a group, duplicate that group and flatten it, then go on to use the &lt;em&gt;select by color&lt;/em&gt; tool to select the alpha channel of the flat layer. Inverting this selection will yield a nice border to the elements on the canvas. &lt;code&gt;select&amp;gt;selection to path&lt;/code&gt; will save this border for future layers. I use this path for two layers, the outline for text, or icons; and as well as a fill layer for the shadow backdrop which I typically offset down and right by holding &lt;code&gt;ctrl&lt;/code&gt; with the move tool.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/gimp.png&#34; alt=&#34;GIMP&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/thumb.png&#34; alt=&#34;GIMP Thumb&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;extra-for-godot&#34;&gt;Extra for Godot&lt;/h3&gt;
&lt;h4 id=&#34;the-playergd-script-in-its-entirty-is-as-follows&#34;&gt;The &lt;code&gt;Player.gd&lt;/code&gt; script in its entirty is as follows:&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;extends CharacterBody3D

const SPEED = 5.0
const JUMP_VELOCITY = 4.5

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting(&amp;#34;physics/3d/default_gravity&amp;#34;)

@onready var camera = $Camera3D
@onready var anim_player = $AnimationPlayer
@onready var hitbox = $Camera3D/weaponPivot/weaponMesh/hitbox

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		rotate_y(-event.relative.x * .005)
		camera.rotate_x(-event.relative.y * .005)
		camera.rotation.x = clamp(camera.rotation.x, -(PI/4), PI/4)

func _process(delta):
	if Input.is_action_just_pressed(&amp;#34;quit&amp;#34;):
		get_tree().quit()
	if Input.is_action_just_pressed(&amp;#34;attack&amp;#34;):
		anim_player.play(&amp;#34;attack&amp;#34;)
		hitbox.monitoring = true

func _physics_process(delta):
	# Add the gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Handle Jump.
	if Input.is_action_just_pressed(&amp;#34;ui_accept&amp;#34;) and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions. Mapped in Project Settings
	var input_dir = Input.get_vector(&amp;#34;left&amp;#34;, &amp;#34;right&amp;#34;, &amp;#34;forward&amp;#34;, &amp;#34;back&amp;#34;)
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()


func _on_animation_player_animation_finished(anim_name):
	if anim_name == &amp;#34;attack&amp;#34;:
		anim_player.play(&amp;#34;idle&amp;#34;)
		hitbox.monitoring = false


func _on_hitbox_area_entered(area):
	if area.is_in_group(&amp;#34;enemy&amp;#34;):
		area.queue_free()
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;that-was-a-very-fun-project-i-encourage-anyone-who-wants-to-make-games-to-just-go-for-it-i-thought-about-it-for-years-before-i-found-i-could-do-it-in-a-few-months-time&#34;&gt;That was a very fun project! I encourage anyone who wants to make games to just go for it. I thought about it for years before I found I could do it in a few months time!&lt;/h3&gt;
</content>
    </item>
    
    <item>
      <title>Angular CLI Up And Running with Docker and Podman</title>
      <link>https://jordanielder.com/posts/angular-2-podman-first-steps/</link>
      <pubDate>Wed, 04 Jan 2023 23:04:46 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/angular-2-podman-first-steps/</guid>
      <description>Podman &amp;amp; Docker Podman is a tool for managing and running containerized applications on Linux and uses a command-line interface to create and manage containers directly, without the need for a daemon process. It can access various container registries, including Docker Hub, to store and distribute images used to create containers.
Docker is a similar tool with its own registry, but it requires a daemon to run in order to work, but also runs on windows.</description>
      <content>&lt;h5 id=&#34;podman--docker&#34;&gt;Podman &amp;amp; Docker&lt;/h5&gt;
&lt;p&gt;&lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt; is a tool for managing and running &lt;a href=&#34;https://www.ibm.com/topics/containerization&#34;&gt;containerized applications&lt;/a&gt; on &lt;a href=&#34;https://en.wikipedia.org/wiki/Linux&#34;&gt;Linux&lt;/a&gt; and uses a command-line interface to create and manage containers directly, without the need for a &lt;a href=&#34;https://en.wikipedia.org/wiki/Daemon_(computing)&#34;&gt;daemon process&lt;/a&gt;. It can access various container registries, including &lt;a href=&#34;https://hub.docker.com/&#34;&gt;Docker Hub&lt;/a&gt;, to store and distribute images used to create containers.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; is a similar tool with its own registry, but it requires a &lt;a href=&#34;https://docs.docker.com/engine/reference/commandline/dockerd/&#34;&gt;daemon&lt;/a&gt; to run in order to work, but also runs on &lt;a href=&#34;https://docs.docker.com/desktop/install/windows-install/&#34;&gt;windows&lt;/a&gt;. &lt;a href=&#34;https://www.docker.com/products/docker-desktop/&#34;&gt;Docker Desktop&lt;/a&gt; is a desktop application that provides an easy-to-use development environment for building, testing, and deploying Docker applications. It includes tools such as the Docker Engine, Docker Compose, and Docker Machine, as well as a Kubernetes server and support for other orchestration platforms. Docker Desktop makes it easy for developers to get started with Docker and streamlines the development workflow by providing a single, integrated environment for building, testing, and deploying applications. In this quick demo we we wil not get into the depths of Docker, but &lt;strong&gt;Dockerfiles are fully compatible with Podman&lt;/strong&gt;, so you can use a Dockerfile to build an image with Podman just as you would with Docker.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&#34;https://docs.docker.com/engine/reference/builder/&#34;&gt;Dockerfile&lt;/a&gt; specifies the base image to use for the build, as well as any additional dependencies and instructions needed to build the image. With a few commands it&amp;rsquo;s possible to get anything up and running, but for this demo we&amp;rsquo;ll stick to a simple &lt;a href=&#34;https://angular.io/cli&#34;&gt;Angular CLI&lt;/a&gt; example.&lt;/p&gt;
&lt;h5 id=&#34;pre-requisites&#34;&gt;Pre-requisites&lt;/h5&gt;
&lt;blockquote&gt;
&lt;p&gt;Install &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; or &lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;VS Code&lt;/a&gt; has a few &lt;a href=&#34;https://marketplace.visualstudio.com/search?term=docker&amp;amp;target=VSCode&amp;amp;category=All%20categories&amp;amp;sortBy=Relevance&#34;&gt;Docker extensions&lt;/a&gt; that may help but is not required, just make sure to have a text editor available&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id=&#34;create-a-new-text-file-name-dockerfile-without-a-file-extension-and-paste-the-following-snippet-in&#34;&gt;Create a new text file name &lt;code&gt;Dockerfile&lt;/code&gt; without a file extension, and paste the following snippet in:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Dockerfile
FROM node:latest

# Install Angular CLI
RUN npm install -g @angular/cli

# Set the working directory
WORKDIR /app

# Set the entrypoint to a shell
ENTRYPOINT [&amp;#34;/bin/bash&amp;#34;]
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;: Specifies the base image to use for the build. In this case, the base image is &lt;code&gt;node:latest&lt;/code&gt;, which is the latest version of the Node.js image from the Docker Hub registry&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RUN&lt;/code&gt;: Runs a command during the image build process. &lt;code&gt;npm install -g @angular/cli&lt;/code&gt; installs the Angular CLI tool globally&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORKDIR&lt;/code&gt;: Sets the working directory for the subsequent instructions in the &lt;code&gt;Dockerfile&lt;/code&gt;. The working directory is set to &lt;code&gt;/app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt;: Specifies the command that will be run when a container is started from the image. The entrypoint is set to &lt;code&gt;/bin/bash&lt;/code&gt;, which means that the container will run a &lt;a href=&#34;https://www.gnu.org/software/bash/&#34;&gt;bash shell&lt;/a&gt; when it is started&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;build-the-dockerfile-use-one-of-the-following-commands&#34;&gt;Build the &lt;code&gt;Dockerfile&lt;/code&gt; use one of the following commands:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;podman build -t angular-dev .

or

docker build -t angular-dev .
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;podman&lt;/code&gt;: and &lt;code&gt;docker&lt;/code&gt; are interchangeable&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build&lt;/code&gt;: is the command to build the &lt;code&gt;Dockerfile&lt;/code&gt; into a &lt;code&gt;Docker Image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt;: used to specify the name and optionally a tag to the name of the image in the name:tag format&lt;/li&gt;
&lt;li&gt;&lt;code&gt;angular-dev&lt;/code&gt;: the name of our &lt;code&gt;image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt;: the location of our &lt;code&gt;Dockerfile&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;finally-to-run-the-image-in-a-container-use-one-of-these-commands&#34;&gt;Finally to run the image in a container use one of these commands:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;podman run -it --name angular-env --network host angular-dev

or

docker run -it --name angular-env --network host angular-dev
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt;: stands for &amp;ldquo;interactive&amp;rdquo; and keeps STDIN open even if not attached. This allows you to run the container interactively, so you can input commands and see the output in the terminal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt;: stands for &amp;ldquo;tty&amp;rdquo; and allocates a pseudo-tty. This allows you to interact with the container as if it were a terminal, even if you are not running it interactively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--name&lt;/code&gt;: specifies a name for the container. In this case, the name is &amp;ldquo;angular-env&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--network host&lt;/code&gt;: tells Podman to use the host&amp;rsquo;s network stack for the container. This means that the container will have the same network connectivity as the host and will be able to access the host&amp;rsquo;s network resources.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;angular-dev&lt;/code&gt;: This is the name of the image to use to create the container. In this case, the image is called &amp;ldquo;angular-dev&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;podman run&lt;/code&gt; output&amp;hellip;&lt;/em&gt;
&lt;img src=&#34;images/podman-run.png&#34; alt=&#34;Podman Run Command Output&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id=&#34;a-successful-launch-will-look-something-like-this-in-your-terminal&#34;&gt;A successful launch will look something like this in your terminal:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@hostname:/app#
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;finally-once-the-image-has-been-built-and-the-container-has-been-launched-you-can-input-the-following-commands-into-the-prompt&#34;&gt;Finally once the Image has been built, and the container has been launched, you can input the following commands into the prompt:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# create a new Angular workspace
ng new my-workspace

# change into the workspace directory
cd my-workspace

# generate a new Angular application
ng generate application my-project

# change into the project directory
cd projects/my-project/

# build the sample application
ng build

# and serve to localhost:4200 by default
ng serve
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There&amp;rsquo;s a lot more you can do once you get to this point, such as going on to link a Database and building out a portable Angular dev environment, but the main point of this article was to introduce Podman as a Development tool. I plan on continuing on with podman to build environments for other programming languages in the future.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/angular2-podman.png&#34; alt=&#34;Angular-2-Podman&#34;&gt;&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Alma Linux and Cockpit: A Perfect Match</title>
      <link>https://jordanielder.com/posts/alma-linux-and-cockpit/</link>
      <pubDate>Wed, 04 Jan 2023 20:59:12 -0600</pubDate>
      
      <guid>https://jordanielder.com/posts/alma-linux-and-cockpit/</guid>
      <description>AlmaLinux A Community-driven, free enterprise-grade distribution of Red Hat Enterprise Linux, or RHEL for short. Cockpit A free, open-source web-based server manager that allows you to easily manage your server through a web browser. Installing AlmaLinux You can download and install AlmaLinux using a VM like VirtualBox or QEMU, but I recommend an old Intel machine or a server unit. For USB I&amp;rsquo;d recommend a Windows tool called YUMI/Ventoy(ExFat) My go-to for Linux is old school DD (do be careful with that one if you&amp;rsquo;re unfamiliar with DD maybe avoid it) Installing Cockpit on AlmaLinux To Install Cockpit on AlmaLinux requires the Extra Packages for Enterprise Linux (EPEL) repository to be enabled.</description>
      <content>&lt;h3 id=&#34;almalinuxhttpsalmalinuxorg&#34;&gt;&lt;a href=&#34;https://almalinux.org/&#34;&gt;AlmaLinux&lt;/a&gt;&lt;/h3&gt;
&lt;h5 id=&#34;a-community-driven-free-enterprise-grade-distribution-of-red-hat-enterprise-linux-or-rhel-for-short&#34;&gt;A Community-driven, free enterprise-grade distribution of Red Hat Enterprise Linux, or RHEL for short.&lt;/h5&gt;
&lt;h3 id=&#34;cockpithttpscockpit-projectorg&#34;&gt;&lt;a href=&#34;https://cockpit-project.org/&#34;&gt;Cockpit&lt;/a&gt;&lt;/h3&gt;
&lt;h5 id=&#34;a-free-open-source-web-based-server-manager-that-allows-you-to-easily-manage-your-server-through-a-web-browser&#34;&gt;A free, open-source web-based server manager that allows you to easily manage your server through a web browser.&lt;/h5&gt;
&lt;h3 id=&#34;installing-almalinux&#34;&gt;Installing AlmaLinux&lt;/h3&gt;
&lt;h5 id=&#34;you-can-downloadhttpsmirrorsalmalinuxorgisoshtml-and-install-almalinux-using-a-vm-like-virtualboxhttpswwwvirtualboxorg-or-qemuhttpswwwqemuorg-but-i-recommend-an-old-intel-machine-or-a-server-unit&#34;&gt;You can &lt;a href=&#34;https://mirrors.almalinux.org/isos.html&#34;&gt;download&lt;/a&gt; and install AlmaLinux using a VM like &lt;a href=&#34;https://www.virtualbox.org/&#34;&gt;VirtualBox&lt;/a&gt; or &lt;a href=&#34;https://www.qemu.org/&#34;&gt;QEMU&lt;/a&gt;, but I recommend an old Intel machine or a server unit.&lt;/h5&gt;
&lt;h5 id=&#34;for-usb-id-recommend-a-windows-tool-called-yumiventoyexfathttpswwwpendrivelinuxcomyumi-multiboot-usb-creatoryumi-exfat&#34;&gt;For USB I&amp;rsquo;d recommend a Windows tool called &lt;a href=&#34;https://www.pendrivelinux.com/yumi-multiboot-usb-creator/#YUMI-exFAT&#34;&gt;YUMI/Ventoy(ExFat)&lt;/a&gt;&lt;/h5&gt;
&lt;h5 id=&#34;my-go-to-for-linux-is-old-school-ddhttpswwwgeeksforgeeksorgdd-command-linux-do-be-careful-with-that-one-if-youre-unfamiliar-with-dd-maybe-avoid-it&#34;&gt;My go-to for Linux is old school &lt;a href=&#34;https://www.geeksforgeeks.org/dd-command-linux/&#34;&gt;DD&lt;/a&gt; (do be careful with that one if you&amp;rsquo;re unfamiliar with DD maybe avoid it)&lt;/h5&gt;
&lt;h3 id=&#34;installing-cockpit-on-almalinux&#34;&gt;Installing Cockpit on AlmaLinux&lt;/h3&gt;
&lt;h5 id=&#34;to-install-cockpit-on-almalinux-requires-the-extra-packages-for-enterprise-linux-epel-repositoryhttpsdocsfedoraprojectorgen-usepel-to-be-enabled-to-do-so-run-the-following-commands&#34;&gt;To Install Cockpit on AlmaLinux requires the &lt;a href=&#34;https://docs.fedoraproject.org/en-US/epel/&#34;&gt;Extra Packages for Enterprise Linux (EPEL) repository&lt;/a&gt; to be enabled. To do so, run the following commands:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo dnf update
sudo dnf install epel-release
sudo dnf update
sudo dnf install cockpit
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;to-start-the-cockpit-service-simply-run-the-following-systemctl-command&#34;&gt;To start the cockpit service simply run the following &lt;code&gt;systemctl&lt;/code&gt; command:&lt;/h5&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo systemctl enable --now cockpit.socket
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;from-cockpit-you-can-now-easily-manage-everything-from-your-firewall-ruleshttpsfirewalldorg-to-your-podmanhttpspodmanio-containers-and-more&#34;&gt;From Cockpit you can now easily manage everything from your &lt;a href=&#34;https://firewalld.org/&#34;&gt;firewall rules&lt;/a&gt; to your &lt;a href=&#34;https://podman.io/&#34;&gt;podman&lt;/a&gt; containers and more!&lt;/h5&gt;
</content>
    </item>
    
    <item>
      <title>Contact Jordan Elder for Design Services</title>
      <link>https://jordanielder.com/posts/gallery/</link>
      <pubDate>Thu, 01 Dec 2022 12:00:00 -0100</pubDate>
      
      <guid>https://jordanielder.com/posts/gallery/</guid>
      <description>Jordan Elder has been in Graphic Design for 15 years Whether you need an ad, thumbnail, business card, web banner, emote or logo I can help you bring your ideas to life.
Email Mastodon YouTube Matrix: @jmac217:matrix.org imgur On All Sides (Band) Here are a few highlights of my design work using Gimp, Blender, and other design tools: Donkey Kong Gif Made with TV Panels and a CRT filter Cinemagraph YouTube Thumbnail Games Library Collage Penguin lake edit Game Concept Eidolon In-Game Photography Sandbag art Dino art Gif Transformations Reddit Edit Before On All Sides there was a Wildcat Demo Blender projects from 2013 Cowboy Bebop edits Space Dandy Edit memes Photoshop battles from 2014 Zelda OOT in-game screenshot wallpaper Kentucky Route Zero In-Game Screenshots/Wallpapers Halloween Logo for On All Sides Product accomodations made for internal use at a previous company - 2021</description>
      <content>&lt;h1 id=&#34;jordan-elder-has-been-in-graphic-design-for-15-years&#34;&gt;Jordan Elder has been in Graphic Design for 15 years&lt;/h1&gt;
&lt;p&gt;Whether you need an &lt;strong&gt;ad&lt;/strong&gt;, &lt;strong&gt;thumbnail&lt;/strong&gt;, &lt;strong&gt;business card&lt;/strong&gt;, &lt;strong&gt;web banner&lt;/strong&gt;, &lt;strong&gt;emote&lt;/strong&gt; or &lt;strong&gt;logo&lt;/strong&gt; I can help you bring your ideas to life.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;mailto:jordanelder10@gmail.com&#34;&gt;Email&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fosstodon.org/@Jordanielder&#34;&gt;Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@jmac217x&#34;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://matrix.org/&#34;&gt;Matrix&lt;/a&gt;: &lt;code&gt;@jmac217:matrix.org&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://imgur.com/user/Jmac217&#34;&gt;imgur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@onallsides8083&#34;&gt;On All Sides (Band)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;here-are-a-few-highlights-of-my-design-work-using-gimp-blender-and-other-design-tools&#34;&gt;Here are a few highlights of my design work using Gimp, Blender, and other design tools:&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Donkey Kong Gif Made with TV Panels and a CRT filter
&lt;img src=&#34;images/DKPanel.gif&#34; alt=&#34;DKPanel&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Cinemagraph
&lt;img src=&#34;images/TakoStand.gif&#34; alt=&#34;TakoStand&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;YouTube Thumbnail
&lt;img src=&#34;images/DKC2Thumb.png&#34; alt=&#34;DKC2Thumb&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Games Library Collage
&lt;img src=&#34;images/games-collage-1.jpg&#34; alt=&#34;games-collage-1&#34;&gt;
&lt;img src=&#34;images/games-collage-2.jpg&#34; alt=&#34;games-collage-2&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Penguin lake edit
&lt;img src=&#34;images/PenguinLake.png&#34; alt=&#34;PenguinLake&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Game Concept
&lt;img src=&#34;images/RobotEnteringCavern.png&#34; alt=&#34;RobotEnteringCavern&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Eidolon In-Game Photography
&lt;img src=&#34;images/eidolon-1.jpg&#34; alt=&#34;eidolon-1&#34;&gt;
&lt;img src=&#34;images/eidolon-2.jpg&#34; alt=&#34;eidolon-2&#34;&gt;
&lt;img src=&#34;images/eidolon-3.jpg&#34; alt=&#34;eidolon-3&#34;&gt;
&lt;img src=&#34;images/eidolon-4.jpg&#34; alt=&#34;eidolon-4&#34;&gt;
&lt;img src=&#34;images/eidolon-5.jpg&#34; alt=&#34;eidolon-5&#34;&gt;
&lt;img src=&#34;images/eidolon-6.jpg&#34; alt=&#34;eidolon-6&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Sandbag art
&lt;img src=&#34;images/sandbag.png&#34; alt=&#34;sandbag&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Dino art
&lt;img src=&#34;images/dino.png&#34; alt=&#34;dino&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Gif Transformations
&lt;img src=&#34;images/stoked.gif&#34; alt=&#34;stoked&#34;&gt;
&lt;img src=&#34;images/WaffleStruckDuck.gif&#34; alt=&#34;WaffleStruckDuck&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Reddit Edit
&lt;img src=&#34;images/TheFaceoff.jpg&#34; alt=&#34;TheFaceoff&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Before On All Sides there was a Wildcat Demo
&lt;img src=&#34;images/Wildcat.png&#34; alt=&#34;Wildcat&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Blender projects from 2013
&lt;img src=&#34;images/cup.png&#34; alt=&#34;cup&#34;&gt;
&lt;img src=&#34;images/soccerball.png&#34; alt=&#34;soccerball&#34;&gt;
&lt;img src=&#34;images/poolballs.png&#34; alt=&#34;poolballs&#34;&gt;
&lt;img src=&#34;images/planet.png&#34; alt=&#34;planet&#34;&gt;
&lt;img src=&#34;images/mug.png&#34; alt=&#34;mug&#34;&gt;
&lt;img src=&#34;images/bowl.png&#34; alt=&#34;bowl&#34;&gt;
&lt;img src=&#34;images/clock.png&#34; alt=&#34;clock&#34;&gt;
&lt;img src=&#34;images/chain.png&#34; alt=&#34;chain&#34;&gt;
&lt;img src=&#34;images/bear.png&#34; alt=&#34;bear&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Cowboy Bebop edits
&lt;img src=&#34;images/spike-1.jpg&#34; alt=&#34;spike-1&#34;&gt;
&lt;img src=&#34;images/spike-2.jpg&#34; alt=&#34;spike-2&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Space Dandy Edit
&lt;img src=&#34;images/dandy.jpg&#34; alt=&#34;dandy&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;memes
&lt;img src=&#34;images/shwag.jpg&#34; alt=&#34;shwag&#34;&gt;
&lt;img src=&#34;images/cloud.png&#34; alt=&#34;cloud&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Photoshop battles from 2014
&lt;img src=&#34;images/psbattle-1.jpg&#34; alt=&#34;psbattle-1&#34;&gt;
&lt;img src=&#34;images/psbattle-2.jpg&#34; alt=&#34;psbattle-2&#34;&gt;
&lt;img src=&#34;images/psbattle-3.jpg&#34; alt=&#34;psbattle-3&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Zelda OOT in-game screenshot wallpaper
&lt;img src=&#34;images/dungeon.png&#34; alt=&#34;dungeon&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Kentucky Route Zero In-Game Screenshots/Wallpapers
&lt;img src=&#34;images/KRZ-1.png&#34; alt=&#34;KRZ-1&#34;&gt;
&lt;img src=&#34;images/KRZ-2.jpg&#34; alt=&#34;KRZ-2&#34;&gt;
&lt;img src=&#34;images/KRZ-3.jpg&#34; alt=&#34;KRZ-3&#34;&gt;
&lt;img src=&#34;images/KRZ-4.jpg&#34; alt=&#34;KRZ-4&#34;&gt;
&lt;img src=&#34;images/KRZ-5.png&#34; alt=&#34;KRZ-5&#34;&gt;
&lt;img src=&#34;images/KRZ-6.jpg&#34; alt=&#34;KRZ-6&#34;&gt;
&lt;img src=&#34;images/KRZ-7.jpg&#34; alt=&#34;KRZ-7&#34;&gt;
&lt;img src=&#34;images/KRZ-8.jpg&#34; alt=&#34;KRZ-8&#34;&gt;
&lt;img src=&#34;images/KRZ-9.jpg&#34; alt=&#34;KRZ-9&#34;&gt;
&lt;img src=&#34;images/KRZ-10.jpg&#34; alt=&#34;KRZ-10&#34;&gt;
&lt;img src=&#34;images/KRZ-11.png&#34; alt=&#34;KRZ-11&#34;&gt;
&lt;img src=&#34;images/KRZ-12.jpg&#34; alt=&#34;KRZ-12&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Halloween Logo for On All Sides
&lt;img src=&#34;images/pumpkin.gif&#34; alt=&#34;pumpkin&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Product accomodations made for internal use at a previous company - 2021&lt;br&gt;
&lt;img src=&#34;images/product.png&#34; alt=&#34;product&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Profile Icon made for Discord&lt;br&gt;
&lt;img src=&#34;images/icon1.png&#34; alt=&#34;icon1&#34;&gt;
&lt;img src=&#34;images/icon2.png&#34; alt=&#34;icon2&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Side-Bars/Panels for OBS Streaming&lt;br&gt;
&lt;img src=&#34;images/panels.png&#34; alt=&#34;panels&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Restraunt Menu for my favorite restraunt which is no longer around, The Whistle Stop - 2012&lt;br&gt;
&lt;img src=&#34;images/menu1.png&#34; alt=&#34;menu1&#34;&gt;
&lt;img src=&#34;images/menu2.png&#34; alt=&#34;menu2&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Album Art for On All Sides - Ghosted&lt;br&gt;
&lt;img src=&#34;images/album.png&#34; alt=&#34;album&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Web Banner for Midwestern Japanese Learners - 2020&lt;br&gt;
&lt;img src=&#34;images/japanese.png&#34; alt=&#34;japanese&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Discord emote for my emote server&lt;br&gt;
&lt;img src=&#34;images/discord.png&#34; alt=&#34;discord&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Wallpaper for On All Sides - One Night One Moment&lt;br&gt;
&lt;img src=&#34;images/wallpaper.png&#34; alt=&#34;wallpaper&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Photo Editing for On All Sides - Promotion&lt;br&gt;
&lt;img src=&#34;images/realism.png&#34; alt=&#34;realism&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Poster for On All Sides - Red Flag Show&lt;br&gt;
&lt;img src=&#34;images/announcement.png&#34; alt=&#34;announcement&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Sticker for On All Sides - Merch&lt;br&gt;
&lt;img src=&#34;images/sticker.png&#34; alt=&#34;sticker&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Album Mockup for On All Sides&lt;br&gt;
&lt;img src=&#34;images/emblem.png&#34; alt=&#34;emblem&#34;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Be sure to come back from time to time, I will keep this section up to date with goodies in the future!&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Contact Jordan Elder for Tech Services</title>
      <link>https://jordanielder.com/posts/contact/</link>
      <pubDate>Thu, 01 Dec 2022 12:00:00 -0100</pubDate>
      
      <guid>https://jordanielder.com/posts/contact/</guid>
      <description>Contact Jordan Elder for Tech Services I&amp;rsquo;m available for freelance operations, development, and design work or just to invite to a gig!
If you&amp;rsquo;re interested in my design work, check out the Gallery.
Email Mastodon YouTube Matrix: @jmac217:matrix.org imgur On All Sides (Band) Be sure to come back from time to time, and check out the band, I will keep posting here as long as there&amp;rsquo;s still words to write!</description>
      <content>&lt;h1 id=&#34;contact-jordan-elder-for-tech-services&#34;&gt;Contact Jordan Elder for Tech Services&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;m available for freelance operations, development, and design work or just to invite to a gig!&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in my design work, check out the &lt;a href=&#34;https://jordanielder.com/posts/gallery/&#34;&gt;Gallery&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;mailto:jordanelder10@gmail.com&#34;&gt;Email&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fosstodon.org/@Jordanielder&#34;&gt;Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@jmac217x&#34;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://matrix.org/&#34;&gt;Matrix&lt;/a&gt;: &lt;code&gt;@jmac217:matrix.org&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://imgur.com/user/Jmac217&#34;&gt;imgur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@onallsides8083&#34;&gt;On All Sides (Band)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Be sure to come back from time to time, and check out the &lt;a href=&#34;https://www.youtube.com/@onallsides8083&#34;&gt;band&lt;/a&gt;, I will keep posting here as long as there&amp;rsquo;s still words to write!&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>OLF 2022 Recap</title>
      <link>https://jordanielder.com/posts/ohio-linux-fest-2022/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://jordanielder.com/posts/ohio-linux-fest-2022/</guid>
      <description>Thanks OLF Organization Special thanks to President of the OLF Organization Beth Eicher, Vice President Warner Moore, Chairman Vance Kochenderfer and the rest of the volunteer organizers for making the event warm and welcoming, and keynote speakers Amber Graner, and John &amp;lsquo;Mad Dog&amp;rsquo; Hall spoke to being inclusive of all humans in our technology communities
Jupiter Broadcasting Faces and Handles 15 or probably more like 10 people from the JB audience met at North Market, a food Court containing &amp;ldquo;Ohio’s best independent merchants, farmers, and makers&amp;rdquo;.</description>
      <content>&lt;h1 id=&#34;thanks-olf-organization&#34;&gt;Thanks OLF Organization&lt;/h1&gt;
&lt;p&gt;Special thanks to President of the OLF Organization &lt;a href=&#34;https://olfconference.org/about/staff/&#34;&gt;Beth Eicher&lt;/a&gt;, Vice President &lt;a href=&#34;https://olfconference.org/about/staff/&#34;&gt;Warner Moore&lt;/a&gt;, Chairman &lt;a href=&#34;https://olfconference.org/about/staff/&#34;&gt;Vance Kochenderfer&lt;/a&gt; and the rest of the &lt;a href=&#34;https://olfconference.org/about/staff/&#34;&gt;volunteer organizers&lt;/a&gt; for making the event warm and welcoming, and keynote speakers &lt;a href=&#34;https://olfconference.org/speakers/&#34;&gt;Amber Graner&lt;/a&gt;, and &lt;a href=&#34;https://olfconference.org/speakers/&#34;&gt;John &amp;lsquo;Mad Dog&amp;rsquo; Hall&lt;/a&gt; spoke to being inclusive of all humans in our technology communities&lt;/p&gt;
&lt;h1 id=&#34;jupiter-broadcasting-faces-and-handles&#34;&gt;Jupiter Broadcasting Faces and Handles&lt;/h1&gt;
&lt;p&gt;15 or probably more like 10 people from the JB audience met at &lt;a href=&#34;https://northmarket.org/&#34;&gt;North Market&lt;/a&gt;, a food Court containing &amp;ldquo;Ohio’s best independent merchants, farmers, and makers&amp;rdquo;. which had everything from Vegan to Ramen to Pizza to BBQ
Joined by&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nev&lt;/li&gt;
&lt;li&gt;the beav&lt;/li&gt;
&lt;li&gt;retromat&lt;/li&gt;
&lt;li&gt;losten&lt;/li&gt;
&lt;li&gt;ScorchedMuffin&lt;/li&gt;
&lt;li&gt;Jonathon_Bowman&lt;br&gt;
all from the Matrix chat&lt;/li&gt;
&lt;li&gt;and Carl George from RedHat/CentOS
&amp;hellip; Somehow I forgot to mention Carl George on the show. Anyways he&amp;rsquo;s from RedHat how could I forget. All the RedHatters were inspiring. It was fun talking to Joshua Preston during the conference as well!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;images/JB-Community-OLF-2022.jpg&#34; alt=&#34;Jupiter Broadcasting Community Meetup&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;speakers&#34;&gt;Speakers&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Listener Jonathon Bowman started off the fest with a great talk about automating tasks with Python&lt;/li&gt;
&lt;li&gt;Joshua Preston from Red Hat taught me a lot about &lt;del&gt;Kubernetes&lt;/del&gt; I mean Ansibel Idk why I said Kubernetes&lt;/li&gt;
&lt;li&gt;Tim Quinlan from F5s NGINX talked about setting up reverse proxies&lt;/li&gt;
&lt;li&gt;We had a few &lt;a href=&#34;https://olfconference.org/book-signing-at-olf/&#34;&gt;Linux Authors&lt;/a&gt; in the house: Ben Cotton from Fedora and David Both who has written many books over his 25 years in Linux&lt;/li&gt;
&lt;li&gt;Amber Graner gave the first keynote about how EVERY user is someone&amp;rsquo;s technical guru and how to be more inclusive of all types of technical people into our communities&lt;/li&gt;
&lt;li&gt;John Maddog Hall gave a talk titled United We Stand that hit me in the feels&lt;/li&gt;
&lt;li&gt;Check &lt;a href=&#34;https://olfconference.org/2022-schedule/&#34;&gt;the schedule&lt;/a&gt; to review the talks from the conference&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Schedule.jpg&#34; alt=&#34;OLF Schedule&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Speakers-Carl-George.jpg&#34; alt=&#34;OLF Speaker Carl George&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;raffle&#34;&gt;Raffle&lt;/h1&gt;
&lt;p&gt;Raffled off many goodies including &lt;a href=&#34;https://olfconference.org/raffle-open-for-2022/&#34;&gt;2 Pi 400s and 16 Pi Picos&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Raffle.jpg&#34; alt=&#34;OLF Speaker Carl George&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;freedom-and-beer-thanks-sponsorshttpsolfconferenceorgsponsors&#34;&gt;&lt;a href=&#34;https://olfconference.org/sponsors/&#34;&gt;Freedom and Beer! Thanks Sponsors!&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Free Coffee, Local Beers and Tacos sponsored by CIQ Open Logic and The Linux Foundation
plus I got a picture with a life-size R2D2 from a neighboring &amp;ldquo;galaxy fest&amp;rdquo; going on at the same time&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/Jmac217-R2D2.jpg&#34; alt=&#34;Jmac217 and R2-D2&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;mixed-excitement-for-value-for-value&#34;&gt;Mixed Excitement for Value-for-Value&lt;/h1&gt;
&lt;p&gt;There was mixed excitement for value-for-value but most of the hesitation seemed to be conflating Bitcoin with the other Crypto-currencies.&lt;/p&gt;
&lt;h1 id=&#34;community&#34;&gt;Community&lt;/h1&gt;
&lt;p&gt;There&amp;rsquo;s a grand sense of community between all of the large and small businesses and all individuals who attended the event.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=rkbL-24gXY0&amp;amp;t=4792s&#34;&gt;Check out my Coverage on Jupiter Broadcasting&amp;rsquo;s Linux Unplugged #487&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://i3.ytimg.com/vi/rkbL-24gXY0/maxresdefault.jpg&#34; alt=&#34;Jupiter Broadcasting&amp;amp;rsquo;s Linux Unplugged #487&#34; title=&#34;Jupiter Broadcasting&#39;s Linux Unplugged #487&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Red-Hat.jpg&#34; alt=&#34;My New Red Hat&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Open-Source.jpg&#34; alt=&#34;Open Source T-Shirt from Open Logic&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;hallway-track&#34;&gt;Hallway Track&lt;/h1&gt;
&lt;p&gt;Bumping elbows with everyone in the hallway track alone is well worth the all-night drive back to St Louis for anyone who&amp;rsquo;s on the fense next year.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/jinx-nginx.jpg&#34; alt=&#34;the hotel was beautiful, and jinx the scuba cat loves it&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Night.jpg&#34; alt=&#34;One of One Photos of Downtown Columbus from My Hotel Room&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;images/OLF-Day.jpg&#34; alt=&#34;Two of Two Photos of Downtown Columbus from My Hotel Room&#34;&gt;&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
