OpenGL & Vulkan · US Navy · Koenig Original AI-Courseware

Demo Catalogue

Every demo from all 5 days — OpenGL foundations, 3D lighting, Vulkan from scratch, compute shaders, and real-world capstones. Read the short description, open full instructions, try the challenge, or download the project to run on your machine.

20
Course Demos
10
Vulkan Deep-Dives
3
Capstone Projects
33+
Total Demos
📘 5-Day Course · Modules 1–15
Course Demos — D01 to D20

The main demo sequence from the OpenGL & Vulkan training course for the US Navy Department. Each demo introduces one new concept, builds on the previous, and includes a break-to-learn challenge for hands-on reinforcement.

No demos match your filter. Try a different keyword.
Demo 1
Demo 1 · M1
The Rendering Pipeline Walkthrough
OpenGLNo CodeConcept

Interactive animated diagram of the GPU pipeline: vertex shader → rasterisation → fragment shader. Explains where each glEnable() call fits, what the driver does vs what you write, and why vertex position flows from CPU RAM to screen pixel.

🧪 Try This Challenge

Explain what happens between vkCmdDraw() and a pixel lighting up on screen.

Demo 2
Demo 2 · M2
First OpenGL Window
OpenGLGLFWContext

Sets up a GLFW window, creates an OpenGL 3.3 core context, enters the event loop with glfwPollEvents(), clears to navy blue each frame, prints GPU name to terminal. Proves your environment works before writing a single shader.

🧪 Try This Challenge

Change the clear colour each second using glfwGetTime(). Change window title to show FPS.

Demo 3
Demo 3 · M3
VBO — Uploading Vertex Data to GPU
OpenGLVBOGPU Memory

Creates a VkBuffer (OpenGL: glGenBuffers), uploads 3 vertices with glBufferData(), then reads back the data to confirm the upload. Prints byte size, memory address, and confirms round-trip integrity. Foundation for every GPU draw call.

🧪 Try This Challenge

Upload 6 vertices (two triangles) and verify all 6 come back correctly.

Demo 4
Demo 4 · M3
VAO + glVertexAttribPointer Decoded
OpenGLVAOStride/Offset

Shows how a VAO records the connection between a VBO and shader attribute locations. Live diagram printed to terminal: stride=20 bytes, location 0=position (offset 0), location 1=colour (offset 12). Break it by changing stride to see garbage output.

🧪 Try This Challenge

Add a third attribute — UV coordinates — without breaking position or colour.

Demo 5
Demo 5 · M3
First Triangle + Shaders
OpenGLGLSLFragment Shader

Compiles vertex and fragment shaders at runtime, links a program, draws the first triangle using glDrawArrays(). Shader compilation errors are printed to terminal with full GLSL log. The simplest possible full render pipeline.

🧪 Try This Challenge

Write a fragment shader that outputs sin(time)*0.5+0.5 as red channel — watch the triangle pulse red.

Demo 6
Demo 6 · M3
EBO — Rectangle from 4 Vertices
OpenGLEBOIndex Buffer

Uses glDrawElements() + an index buffer to draw a rectangle from only 4 vertices (vs 6 duplicate vertices without EBO). Prints memory saved vs brute-force approach. Introduces TRIANGLE_LIST indexing pattern used in every production renderer.

🧪 Try This Challenge

Draw a hexagon from 6 outer vertices + 1 centre vertex using a 12-index EBO.

Demo 7
Demo 7 · M3 & M4
Uniforms + Animation — Time-Driven Motion
OpenGLUniformsAnimation

Sends a float time uniform each frame via glUniform1f(), drives a translation and colour shift in the vertex shader. Shows glGetUniformLocation() cache pattern and why GPU uniforms are cheaper than per-vertex data for shared values.

🧪 Try This Challenge

Add a glUniform2f() mouse position. Make the triangle follow the cursor using glfwGetCursorPos().

Demo 8
Demo 8 · M4
Full MVP + Fly Camera — WASD + Mouse Look
OpenGLMVPCameraGLM

Builds a full projection pipeline: glm::translate/rotate/scale → model matrix, glm::lookAt → view, glm::perspective → projection. WASD keys move the camera; mouse drag rotates. Demonstrates view frustum and near/far plane clipping live.

🧪 Try This Challenge

Add a pitch angle limit (±89°) to prevent camera gimbal lock. Add Shift to sprint.

Demo 9
Demo 9 · M5
Phong Lighting — Ambient + Diffuse + Specular
OpenGLPhongNormalsGLSL

Implements Blinn-Phong: ambient constant + diffuse dot(N,L) + specular pow(dot(N,H), shininess). UP/DOWN keys change shininess live (2→256). Normal matrix corrects for non-uniform model scale. Orbiting point light demonstrates all three components separately.

🧪 Try This Challenge

Add a second light source of a different colour. See how both contribute to the final fragment colour.

Demo 10
Demo 10 · M6
Textures — UV Coords, stb_image, Textured Lit Cube
OpenGLTexturesUVstb_image

Loads a PNG via stb_image into a GL_TEXTURE_2D object, binds to sampler uniform, applies to a lit 3D cube. UV coordinates are interleaved with positions and normals in a single VBO. Demonstrates mip-mapping, GL_REPEAT wrap mode, and texture × Phong multiplication.

🧪 Try This Challenge

Apply a normal map texture — modify the fragment shader to perturb the normal using the normal map's RGB values.

Demo 11
Demo 11 · M7
Procedural Radar Shader — GLSL Deep Dive
OpenGLGLSLProceduralatan/fract

Writes an entire radar PPI display inside a fragment shader using no textures. atan(x,y) computes bearing, fract() creates range rings, mod() drives the rotating sweep, smoothstep() softens edges. No geometry beyond one quad — the GPU draws everything via math.

🧪 Try This Challenge

Add a contact blip: flash a bright dot at a fixed bearing/range using step() and sin(time).

Demo 12
Demo 12 · M7
Instancing — 1,000 Contacts, One Draw Call
OpenGLInstancinggl_InstanceIDVBO

Renders 1,000 coloured contacts with one glDrawArraysInstanced() call. Instance data (position, colour, size) is in a second VBO with glVertexAttribDivisor(1,1). Toggle instancing off and measure the frame time difference — see CPU overhead vs GPU throughput.

🧪 Try This Challenge

Change divisor to 2 and observe that every pair of contacts shares the same position — explain why.

Demo 13
Demo 13 · M8
FBO Post-Processing — Render Scene to Texture
OpenGLFBOPost-ProcessingFullscreen Quad

Two-pass render: scene → off-screen FBO texture, then fullscreen quad → apply shader filter. Keys 1-4 switch between passthrough, greyscale, invert, and Sobel edge detection without rebuilding any scene geometry. Classic deferred rendering foundation.

🧪 Try This Challenge

Write a vignette pass: darken pixels by 1-smoothstep(0.5, 1.0, length(uv-0.5)*1.5).

Demo 14
Demo 14 · M8
Stencil Outline + Transparent Radar Sweep
OpenGLStencil BufferAlpha BlendingTwo-Pass

Two-pass stencil: first pass writes object pixels to stencil buffer; second pass draws scaled-up outline only where stencil=0 (outside original). Then adds a transparent alpha-blended radar sweep sector on top. Demonstrates blending order and depth–stencil interaction.

🧪 Try This Challenge

Add a third pass that draws a transparent red warning zone circle using additive blending.

Demo 15
Demo 15 · M10
Vulkan Environment — Instance, Layers, Physical Devices
VulkanVkInstanceValidation LayersGPU Enumeration

Creates VkInstance with validation enabled, enumerates all GPUs, scores each by VRAM and device type, creates VkSurfaceKHR via GLFW, destroys everything in correct order. Terminal shows GPU names, VRAM, and queue family availability. No rendering — pure setup.

🧪 Try This Challenge

Add VkPhysicalDeviceProperties output: print maxImageDimension2D and maxUniformBufferRange for each GPU.

Demo 16
Demo 16 · M11
Logical Device + Queues + Command Pool
VulkanVkDeviceVkQueueVkCommandPool

Creates VkDevice requesting graphics + present queues, creates VkCommandPool and allocates a primary command buffer, records a no-op (empty) command buffer and submits it with a fence. Validates the full command recording and submission cycle before adding any rendering.

🧪 Try This Challenge

Record vkCmdSetEvent() and vkCmdWaitEvents() in the command buffer and verify the fence signals after the wait.

Demo 17
Demo 17 · M11
Swapchain + Render Pass — First Real Pixels
VulkanVkSwapchainKHRVkRenderPassVkFramebuffer

Creates VkSwapchainKHR, wraps images in VkImageViews, builds a VkRenderPass with LOAD_OP_CLEAR, creates framebuffers, runs the acquire → record → submit → present frame loop clearing to an animated navy colour via VkClearValue. First time real pixels appear.

🧪 Try This Challenge

Change the clear colour each frame using a sine wave on the red channel. Confirm the framerate matches the display refresh.

Demo 18
Demo 18 · M12
Full Pipeline + vkCmdDraw — First Vulkan Triangle
VulkanVkPipelineSPIR-VvkCmdDraw

Compiles GLSL to SPIR-V with glslc, loads .spv at runtime, creates VkShaderModules, builds VkGraphicsPipelineCreateInfo baking all state. Draws a white triangle on navy. No vertex buffer — positions hardcoded in vertex shader via gl_VertexIndex. Complete frame loop with semaphore+fence sync.

🧪 Try This Challenge

Change VK_POLYGON_MODE_FILL to VK_POLYGON_MODE_LINE in the rasteriser and recompile — draw wireframe without shader changes.

Demo 19
Demo 19 · M13
UBO + Descriptor Sets — Replacing glUniform*()
VulkanUBOVkDescriptorSetRotating Triangle

Builds the full descriptor system: VkDescriptorSetLayout (binding 0 = uniform buffer), VkDescriptorPool, one VkDescriptorSet per swapchain image. Each frame updates MVP matrices via persistent-mapped UBO memory and binds before vkCmdDraw. Orange triangle rotates via shader MVP with Vulkan Y-flip correction.

🧪 Try This Challenge

Change the model matrix to also include a scale driven by abs(sin(time)) — watch the triangle pulse in size while rotating.

Demo 20
Demo 20 · M13
Vulkan Compute Shader — GPU Parallel Image Processing
VulkanComputeSSBOvkCmdDispatch

Creates a compute-only pipeline (no swapchain, no window). 256×256 synthetic image uploaded to storage buffer, compute shader inverts RGB of all 65,536 pixels in parallel (16×16 workgroups). Pipeline barrier ensures GPU writes complete before CPU reads. Prints timing and throughput in pixels/sec.

🧪 Try This Challenge

Change the kernel to greyscale: r_out = g_out = b_out = (r+g+b)/3. Recompile compute shader and verify output changes.

🔷 Standalone Vulkan Series · VK01–VK10
10 Vulkan Learning Demos

A self-contained Vulkan learning series starting from absolute zero. Each project is a standalone CMake build with complete main.cpp, GLSL shaders, and CMakeLists.txt. Shared VulkanBase.h provides common helpers — no duplication, no mystery code.

VK01
VK01
Hello Window — Instance + Device Setup
VulkanVkInstanceVkDeviceGPU Scoring

The definitive Vulkan hello-world. Creates VkInstance with validation, enumerates + scores all GPUs by VRAM and device type, creates VkDevice + queues, builds a VkSwapchainKHR. Every object printed to terminal. No shaders. No rendering. Proves your toolchain is working before anything else.

VK02
VK02
First Triangle — Render Pass, Pipeline, Draw
VulkanVkPipelineVkRenderPassvkCmdDraw

First rendered output in Vulkan. Vertex positions hardcoded in shader.vert via gl_VertexIndex — no vertex buffer. Builds complete VkGraphicsPipelineCreateInfo baking all fixed-function state. Shows acquire → record → vkCmdBeginRenderPass → vkCmdDraw → present loop with semaphore+fence synchronisation.

VK03
VK03
Vertex Buffer — Real Geometry from CPU
VulkanVkBuffervkMapMemoryTRIANGLE_FAN

Uploads a coloured pentagon from CPU memory to a HOST_VISIBLE buffer using vkMapMemory + memcpy. VkVertexInputBindingDescription describes stride; VkVertexInputAttributeDescription describes location, format, and byte offset for position (vec2) and colour (vec3). Topology: TRIANGLE_FAN from centre vertex.

VK04
VK04
Index Buffer — Device-Local via Staging
VulkanEBOStaging BufferDEVICE_LOCAL

Draws a rectangle from 4 vertices + 6 indices with vkCmdDrawIndexed. Introduces the staging pattern: CPU writes to HOST_VISIBLE buffer → one-shot command buffer copies to DEVICE_LOCAL memory → staging buffer destroyed. Device-local is faster GPU memory — the standard pattern for all static geometry.

VK05
VK05
Uniform Buffer — MVP Animation via Descriptor Sets
VulkanUBOVkDescriptorSetMVP

Builds the complete descriptor infrastructure: layout → pool → sets → update. One UBO per swapchain image (prevents CPU overwriting data GPU is reading). Rotating quad driven by MVP matrix. Persistent vkMapMemory + memcpy per frame. proj[1][1]*=-1 corrects Vulkan Y-axis flip.

VK06
VK06
Textures — VkImage, VkSampler, Combined Sampler
VulkanVkImageVkSamplerImage Layout

Uploads a procedural 256×256 checkerboard texture via staging buffer → vkCmdCopyBufferToImage. Two image layout transitions: UNDEFINED→TRANSFER_DST→SHADER_READ_ONLY. Descriptor set with two bindings: UBO (binding 0) + COMBINED_IMAGE_SAMPLER (binding 1). Rotating textured quad.

VK07
VK07
Depth Buffer — 3D Rotating Cube
VulkanDepth BufferVkFormat3D Cube

Adds a depth attachment: VkImage with D32_SFLOAT format, render pass with two attachments, two VkClearValues (colour + depth=1.0). VkPipelineDepthStencilStateCreateInfo enables LESS compare op. 36-vertex cube with unique face colours. Back-face culling ON. Validates face ordering without depth corruption.

VK08
VK08
Multiple Objects — Push Constants
VulkanPush ConstantsvkCmdPushConstantsOrbiting

Draws 5 cubes with one shared vertex buffer but unique transforms via 80-byte push constants (mat4 model + vec4 colour). Push constants are the fastest per-draw update path — no descriptor overhead. Shared VP UBO for camera. Each cube orbits at a different radius and speed.

VK09
VK09
Blinn-Phong Lighting — Normals, Fresnel, UV Sphere
VulkanBlinn-PhongNormal MatrixUV Sphere

Procedurally generated UV sphere (32 stacks × 64 slices). SceneUBO carries model/view/proj + lightPos + viewPos. Normal matrix: transpose(inverse(model)). Blinn-Phong in fragment shader: ambient + diffuse dot(N,L) + specular pow(dot(N,H), shininess). Shininess adjustable with UP/DOWN keys.

VK10
VK10
Compute Filter — Sobel, Blur, Sharpen
VulkanComputeSSBOMandelbrot

Full compute + graphics dual pipeline. Compute shader runs Sobel edge detection / box blur / sharpen on a Mandelbrot fractal (generated in code). Output copied to a VkImage. Graphics renders it as a fullscreen triangle via a combined image sampler. Keys 1/2/3/4 switch filters every frame.

🎯 Real-World Naval Scenarios · CAP01–CAP03
3 Capstone Projects

Three production-quality graphics programs built for real naval training scenarios. Each capstone integrates multiple Vulkan concepts into a single working system — the kind of code you would write on a real defence contract.

CAP01
CAP01
Naval Tactical Radar Display
🎯 Real-World Scenario
Real-WorldAlpha BlendingDynamic VBTwo Pipelines

USS Monterey CIC scenario. Rotating green sweep beam with persistent alpha-blended trail. 4 range rings, north/south/east/west crosshair, 8 simulated surface contacts orbiting at different ranges and speeds. Two pipelines in one render pass: LINE_LIST for rings, TRIANGLE_LIST for sweep sector. Dynamic vertex buffer rebuilt each frame. +/- keys change sweep speed.

CAP02
CAP02
Ocean Surface Renderer (Gerstner Waves)
🎯 Real-World Scenario
Real-WorldVertex AnimationFresnelFly Camera

Royal Australian Navy bridge simulator scenario. 64×64 grid mesh uploaded once — all wave displacement computed in vertex shader via 4 superimposed Gerstner waves (no CPU geometry rebuild per frame). Blinn-Phong sun lighting, Fresnel edge glow, foam on wave crests, depth colour gradient. Fly camera: WASD + mouse drag + +/- wave height.

CAP03
CAP03
GPU Particle System — 100,000 Particles
🎯 Real-World Scenario
Real-WorldCompute PhysicsAdditive BlendvkCmdDispatch

Naval simulation game scenario — missile exhaust fire. 100,000 particles simulated entirely on GPU: compute shader integrates velocity, applies gravity, respawns dead particles. Critical compute→graphics pipeline barrier ensures GPU writes complete before vertex reads. Additive blending creates fire glow. Circular soft-edged point sprites via gl_PointCoord. SPACE adds new emitter.

⚙️ Environment Setup
How to Build & Run Any Demo

All demos use the same toolchain. Set up once, run everything. Windows 10/11 with Visual Studio 2022 recommended.

🛠️
Prerequisites & Installation
Install these once. All demos will build without any further config changes.
01
Vulkan SDK
Download from lunarg.com/vulkan-sdk and run the installer. It installs glslc.exe (shader compiler), VK_LAYER_KHRONOS_validation, and headers.

Verify: open a terminal and type:
glslc --version
You should see the Vulkan SDK version. If not, add %VULKAN_SDK%\Bin to your PATH.
02
GLFW 3 (Window & Input)
Download pre-built Windows binaries from glfw.org/download.
Extract to a folder, e.g. C:\libs\glfw.
Set environment variable:
setx GLFW_DIR "C:\libs\glfw"
All CMakeLists.txt files read $ENV{GLFW_DIR} automatically.
03
GLM (Math Library)
Header-only math library. Download from github.com/g-truc/glm (releases page, zip).
Extract to e.g. C:\libs\glm.
Set environment variable:
setx GLM_DIR "C:\libs\glm"
No compilation needed — it's pure headers.
04
Visual Studio 2022
Install "Desktop development with C++" workload.
Also install CMake via the VS installer (or separately from cmake.org).
Verify CMake is on PATH:
cmake --version
Need v3.20 or higher. The installer adds it to PATH automatically.
Environment Variables Summary
VULKAN_SDK
Set automatically by the Vulkan SDK installer. Points to the SDK root.
GLFW_DIR
You set this manually. Points to the GLFW directory containing include/ and lib-vc2022/.
GLM_DIR
You set this manually. Points to the GLM root containing the glm/ header folder.
Build Any Demo — Universal Steps

Replace VK05_UniformBuffer with any demo folder name. Steps are identical for every project.

REM Step 1 — compile shaders to SPIR-V (Vulkan demos only; skip for OpenGL demos) cd C:\Labs\VK05_UniformBuffer glslc shader.vert -o vert.spv glslc shader.frag -o frag.spv REM Step 2 — configure CMake (Visual Studio 2022, 64-bit) cmake -B build -G "Visual Studio 17 2022" -A x64 REM Step 3 — build the project cmake --build build --config Release REM Step 4 — copy SPIR-V binaries next to .exe (Vulkan only) copy vert.spv build\Release\ REM Step 5 — run build\Release\VK05_UniformBuffer.exe
OpenGL Demos — Extra Dependency

OpenGL demos (D01–D14) also require GLEW. Download the pre-built Windows binary from glew.sourceforge.net, extract it, and add to your CMakeLists manually, or use vcpkg:

vcpkg install glew:x64-windows
Compute Shaders — Extra Compile Step (VK10 + CAP03)
REM Compute shaders use .comp extension glslc filter.comp -o comp.spv # VK10 glslc particle.comp -o comp.spv # CAP03 copy comp.spv build\Release\
Quick Troubleshooting
❌ "Cannot open vert.spv"
You forgot to compile shaders or copy them next to the .exe. Run glslc commands in Step 1 and copy .spv files to build\Release\.
❌ "vulkan-1.dll not found"
Vulkan runtime not installed. Install the Vulkan SDK. If on a system without a GPU, install the Vulkan LunarG CPU emulation layer.
❌ "VK_LAYER_KHRONOS_validation not found"
Vulkan validation layers missing. Re-run the SDK installer and ensure "Debugging Tools" component is checked.
❌ Blank window or black screen
Run from a terminal — check for validation layer errors printed to stdout. Enable VK_LAYER_KHRONOS_validation (already on in all demos) and read the error message.
❌ CMake can't find GLFW or GLM
The environment variables GLFW_DIR and GLM_DIR are not set. Run setx GLFW_DIR "C:\libs\glfw" in a new terminal, then rebuild.
❌ "glslc is not recognised"
Add %VULKAN_SDK%\Bin to your system PATH via System Properties → Environment Variables → Path → Edit → New.