[video output=day585 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Centralized Light Atlas Handling" vod_platform=youtube id=0WXRn82zHys annotator=Miblo]
[0:05][Welcome to the stream][:speech]
[0:23][Demo the current specular :lighting][:run]
[2:57][Prepare to use the diffuse light map for bounce :lighting, first treating the light voxel cells as a texture atlas][:speech]
[5:31][Introduce light_atlas][:"data structure" :lighting]
[6:52][Consider leaving the depth map out of it][:lighting :run]
[8:47][Swizzling light atlases for optimal GPU submission][:"data structure" :lighting :speech]
[11:53][Fill in the light_atlas, renaming it to game_light_atlas][:"data structure" :lighting]
[14:41][Consider how to handle specular surfaces][:lighting :speech]
[16:02][Replace the LightVoxel data with a game_light_atlas in game_render_commands, and augment open_gl with game_light_atlas][:"data structure" :lighting]
[17:45][Update ComputeLightPropagationWork() and BeginLightingComputation() to use our new game_light_atlas][:lighting]
[27:26][Introduce v3s overloaded-operator versions of * and /][:language :mathematics]
[28:26][Finish updating BeginLightingComputation() to use our new game_light_atlas][:lighting]
[28:53][Hit a write access violation in ComputeLightPropagationWork()][:lighting :run]
[29:11][Make OpenGLInit() initialise our DiffuseLightAtlas][:hardware :lighting]
[31:20][:Run without crashing to see no obvious differences][:lighting :run]
[31:47][Create handmade_light_atlas.h, and rename game_light_atlas to light_atlas][:language :lighting]
[35:10][Prepare to systematise the light atlas initialisation][:lighting :research]
[37:01][Introduce GetLightAtlasTexelSize(), MakeLightAtlas(), GetLightAtlasSize() and SetLightAtlasTexels() for Win32InitOpenGL() to call, creating handmade_light_atlas.cpp][:lighting :memory]
[49:55][See no :lighting][:run]
[50:09][Remove LightColorData and LightDepthData from open_gl, and update OpenGLEndFrame() to use the new DiffuseLightAtlas, introducing GetLightAtlasTexelCount(), GetLightAtlasTexels(), GetLightAtlasWidth(), GetLightAtlasHeight() and a light_atlas version of IsFloat()][:lighting]
[58:14][Admire our lit world][:lighting :run]
[58:39][Augment open_gl with a SpecularLightAtlas, and replace the old Color and Depth handles with ones for the Diffuse and Specular atlases, propagating these changes to OpenGLInit(), OpenGLChangeToSettings() and OpenGLEndFrame()][:"data structure" :hardware :lighting]
[1:03:46][Hit OpenGL error "Invalid texture format"][:hardware :lighting :run]
[1:04:11][Make Win32InitOpenGL() initialise the SpecularLightAtlas][:lighting]
[1:05:24][Admire our lit world][:lighting :run]
[1:05:52][Prepare to write into our specular atlas directly[ref
    site=Merriam-Webster
    page=trepidatious
    url=https://www.merriam-webster.com/dictionary/trepidatious][ref
    site=Merriam-Webster
    page=trepidation
    url=https://www.merriam-webster.com/dictionary/trepidation]][:lighting :research]
[1:07:26][Remove redundant code related to the :lighting]
[1:13:36][See that it looks the same][:lighting :run]
[1:13:46][Continue to remove redundant code related to the :lighting, augmenting the light_atlas]
[1:24:47][Consider the :performance implications of removing LIGHT_COLOR_LOOKUP_SQUARE_DIM in relation to DirectionFromTxTy()][:lighting :research]
[1:27:30][Augment light_atlas with OxyCoefficient and OctDimCoefficient for MakeLightAtlas() to compute and DirectionFromTxTy() and GetOctahedralOffset() respectively to take][:"data structure" :lighting]
[1:38:43][Replace all mentions of LIGHT_COLOR_LOOKUP_SQUARE_DIM in ComputeLightPropagationWork(), introducing FillLightAtlasBorder() and respecifying VOXEL_OFFSET_C() as LIGHT_ATLAS_OFFSET()][:lighting]
[1:53:11][Replace all mentions of LIGHT_COLOR_LOOKUP_SQUARE_DIM in BuldDiffuseLightMaps()][:lighting]
[1:58:17][:Run unexpectedly successfully][:lighting]
[1:58:46][Determine to sample from the correct maps next stream][:lighting :speech]
[1:59:15][Admire the specular :lighting][:run]
[1:59:46][Q&A][:speech]
[2:00:37][@somedude456][Quick question: Does this game use stuff CRT like VCRUNTIME140.dll?][:library]
[2:02:02][Check the external dependencies of win32_handmade.exe in Depends: GDI32.dll, KERNEL32.dll, USER32.dll and WINMM.dll][:admin :library]
[2:02:23][Check the external dependency of handmade_game_temp.dll in Depends: KERNEL32.dll][:admin :library]
[2:02:50][Check the external dependencies of handmade_renderer_temp.dll in Depends: GDI32.dll, KERNEL32.dll, OPENGL32.dll and USER32.dll][:admin :library]
[2:03:42][@euphius][Q: Do you know why some game require you to restart it if you change the graphics settings? Is it because they can't reload different textures at runtime?][:rendering]
[2:05:41][@tinspin][Q: Why don't all studios use the dynamic .dll loading?! It's the best thing ever, right?][:library]
[2:06:30][@ommos61][Q: Did you forget to upload the previous episode to YouTube?]
[2:06:39][@blind_br][Q: [@cmuratori Casey], great series. Congrats! Any plans to open source the code?]
[2:07:00][@sorrelldev][Q: Apologies in advance if this was already answered previously, but is there a particular reason you use structs and global functions instead of classes?][:language]
[2:11:50][@tinspin][Q: Also, I managed to extract the cl.exe from Visual Studio but I can't redistribute it. Has anyone been sued for redistributing the free cl.exe compiler?]
[2:12:23][@aidsjorb][Q: What is your plan to ensure the orphanage our hero lives in will have sufficient access to paper products, especially toilet paper? How will hand washing work in a world where everything is handmade but the children have no limbs?][:health]
[2:13:25][@graemephi][(Thinks about coronavirus) *touches face*][:health]
[2:13:48][@mattiamanzati][Q: I'm not completely familiar with this environment, that's why I'm enjoying this streaming, but why today did we moved from an array of light voxel cell to a light atlas? Is that because of OpenGL atlases or other?][:"data structure" :lighting]
[2:14:23][@czapa10][Q: Is using _mm_load_ps() and _mm_store_ps() more efficient (or better) then just casting to floats or accessing it through a union?]
[2:16:45][@dithinas][Q: \[Off-topic\] Would you be able to give an intuitive / geometric explanation for what the adjoint matrix computes, and why you need it for doing generalized transforms on surface normal vectors?[ref
    site="Handmade Hero Episode Guide"
    page="The Inverse and the Transpose"
    url=https://guide.handmadehero.org/code/day101/#105]][:geometry :mathematics]
[2:20:19][@d3rzo][Q: Do you think using OpenGL for making games is still fine for the next couple of years? I've heard [@naysayer88 Jon Blow]'s rant about it not being a valid API, but I'm not sure why]
[2:21:55][@d3rzo][Right, but they still support the existing versions (we are up to 4.6, right?). Why aren't the current features enough?]
[2:22:12][@lucid_frost][Q: What do you think about the style of using a bunch of defines to control the generated code of an include for things like libraries (similar to your float define but more extreme)?][:library]
[2:22:27][@eerrman1][Q: Did you take any programming courses at a college? Do you have any recommendations?]
[2:22:33][@taylor_totter][Q: On the Wikipedia page,[ref
    site=Wikipedia
    page="Adjugate matrix"
    url=https://en.wikipedia.org/wiki/Adjugate_matrix]the 2x2 generic example[ref
    site=Wikipedia
    page="Invertible matrix"
    url=https://en.wikipedia.org/wiki/Invertible_matrix]][:geometry :mathematics]
[2:27:11][@tinspin][Q: Do you have a Raspberry 4?]
[2:27:16][@khrob][Q: Why would id support Vulkan instead of just DX?][:api]
[2:27:26][@czapa10][Q: Will you ship the game with debug GUI? [@mike_acton Mike Acton] said at GDC conference that you should be able to debug the release version of your game. How do you do that?][:"debug system"]
[2:28:53][It's been a pleasure][:speech]
[/video]
