[video output=day419 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Debugging Missing Lighting" vod_platform=youtube id=N5050xYdpQc annotator=Miblo]
[0:01][Recap and set the stage for the day, with a few words about :lighting][:rendering :speech]
[3:06][:Run the game with the intention of showing the :lighting][:rendering]
[5:01][Read through the :lighting code][:rendering :research]
[8:45][:Run the game to show that bitmaps aren't lit][:lighting :rendering]
[9:28][Continue to read through the :lighting code][:research :rendering]
[15:37][:Run the game, note that we're not getting any emission and step through the code to determine why][:lighting :rendering]
[20:08][Press F4 and see the light][:lighting :rendering :run]
[22:32][Make PlayWorld() set UpdatingLighting to true on startup][:lighting :rendering]
[23:40][:Run the game and note the long :lighting trails][:rendering]
[24:03][Make ComputeLightPropagation() interpolate the :lighting across 10 frames][:lighting :rendering]
[24:24][:Run the game to see more flickery light, yet with a shorter trail][:lighting :rendering]
[24:58][Consider what could be happening with the snake's light at corners][:run]
[28:39][Remove all PushLight() calls except for those performed by AddSnakeSegment() for the snake's head][:"entity system" :lighting :rendering]
[29:43][:Run the game to see that the bug persists with our single light source][:lighting :rendering]
[30:00][Admire the :UI of Microsoft Visual Studio][:rant]
[30:40][Step through PushCube() to inspect the :lighting values][:rendering :run]
[33:16][Step through ExtractReflectorsFromQuads() to follow the light data down the pipe][:lighting :rendering :run]
[38:53][Step through OutputLightingTextures() to see if we correctly output all the lights][:lighting :rendering :run]
[41:19][Enable CompileZBiasProgram() to colour the light by its assigned index][:"debug visualisation" :hardware :lighting :rendering]
[43:39][:Run the game to see that the light indices and positions are coherent][:"debug visualisation" :lighting]
[45:07][Make CompileZBiasProgram() colour the light <= 1033 green and > 1033 red][:"debug visualisation" :lighting :rendering]
[45:48][:Run the game to see a suspicious pattern][:"debug visualisation" :lighting :rendering]
[47:07][Read through ComputeLightPropagation() looking for any biasing][:lighting :rendering :research]
[50:14][Mention the problem inherent in graphics programming to do with misalignment of disparate arrays][:speech :rendering]
[51:54][Provide a specific break point in ComputeLightPropagation()][:lighting :rendering]
[54:29][:Run the game, successfully break on our point and step through the code from there][:lighting :rendering]
[57:41][Realise that ComputeLightPropagation() is incorrectly setting DestEmit\[EmitIndex\]][:lighting :rendering :run]
[58:29][Make ComputeLightPropagation() correctly set the DestEmit\[EmitIndex\]][:lighting :rendering]
[59:14][:Run the game to see that the :lighting transmission now works][:rendering]
[59:31][Revert everything to semi-normal][:lighting :rendering]
[59:56][:Run the game to see the light looking pretty clean][:lighting :rendering]
[1:04:15][Make PlayWorld() create two rooms][:"procedural generation"]
[1:05:16][:Run the game to see the slowdown caused by :lighting recalculation][:rendering]
[1:06:46][Make PlayWorld() create four rooms][:"procedural generation"]
[1:07:04][:Run the game to see that slowdown][:lighting :rendering]
[1:07:35][Make PlayWorld() create bigger rooms][:"procedural generation"]
[1:07:51][:Run the game to see the slowly recalculating :lighting][:rendering]
[1:11:24][Make PlayWorld() generate rooms in all directions][:"procedural generation"]
[1:12:22][:Run the game and crash][:lighting :rendering]
[1:12:48][Double the LIGHT_DATA_WIDTH][:memory :lighting :rendering]
[1:13:04][:Run the game and consider the frame rate at different zoom levels, at least initially][:lighting :rendering]
[1:17:15][:Run it again and see that PeekMessage starts taking more time later][:"input handling" :"platform layer"]
[1:19:08][Read through Win32ProcessPendingMessages()][:"input handling" :research :"platform layer"]
[1:19:53][:Run the game, check our :memory usage and provide a ton of input to the game to get PeekMessage up to the top of the profiler][:"input handling" :performance :"platform layer"]
[1:23:29][Step into Win32ProcessPendingMessages() to see how often it gets hit, and realise that Alt-Tabbing away removes PeekMessage from the top spot in the profiler][:"input handling" :performance :"platform layer" :run]
[1:26:15][Read through Win32ProcessPendingMessages()][:"input handling" :"platform layer" :research]
[1:26:50][:Run the game and spam PeekMessage with mouse movement][:"input handling" :"platform layer"]
[1:29:56][Put our "PeekMessage" TIMED_BLOCK in Win32ProcessPendingMessages() inside the message loop][:"input handling" :"platform layer"]
[1:30:21][:Run the game and again spam PeekMessage with mouse movement][:"input handling" :"platform layer"]
[1:31:55][Return our "PeekMessage" TIMED_BLOCK to where it was and allow Win32ProcessPendingMessages() to handle all messages[ref
    site=MSDN
    page="PeekMessage function"
    url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms644943]][:"input handling" :"platform layer"]
[1:33:53][:Run the game, try to spam PeekMessage again and find it not rising to the top of the profiler][:"input handling" :performance :"platform layer"]
[1:34:59][Determine to try and narrow down the problem in Win32ProcessPendingMessages()][:"input handling" :"platform layer"]
[1:35:36][:Run the game and successfully produce that bad case][:"input handling" :"platform layer" :rant]
[1:37:17][Prevent Win32ProcessPendingMessages() from skipping WM_PAINT messages][:"platform layer" :rendering]
[1:37:31][:Run the game and again trigger the bad case][:"input handling" :"platform layer"]
[1:37:49][Prevent Win32ProcessPendingMessages() from skipping WM_MOUSEMOVE messages][:"input handling" :"platform layer"]
[1:38:08][:Run the game and fail to produce the bad case, determining that WM_MOUSEMOVE cannot be skipped][:"input handling" :"platform layer"]
[1:38:58][Note our PeekMessage observations][:"input handling" :"platform layer"]
[1:40:04][A few words on the utility of our always-on profiler from the :"debug system"][:profiling :speech]
[1:41:13][Wonder why this is happening][:"input handling" :"platform layer"]
[1:42:04][:Run the game and try to trigger lots of WM_PAINT messages][:"platform layer" :rendering]
[1:44:29][Prevent Win32ProcessPendingMessages() from skipping WM_PAINT messages][:"platform layer" :rendering]
[1:44:54][:Run the game and experience no bad behaviour][:"platform layer" :rendering]
[1:45:16][Try to prevent Win32ProcessPendingMessages() from skipping 0x738 messages][:"platform layer" :rendering]
[1:45:44][:Run the game to see that PeekMessage no longer takes the top spot in the profiler][:performance :"platform layer" :rendering]
[1:46:08][Re-enable Win32ProcessPendingMessages() to skip 0x738 messages][:"platform layer" :rendering]
[1:47:12][Q&A][:speech]
[1:47:16][@chaoscom][[@cmuratori Casey], did you notice that the annotation search doesn't seem to be working anymore?[ref
    site="Handmade Hero"
    page="Annotated Episode Guide"
    url=https://hero.handmade.network/episode/code]][:admin]
[1:49:31][@chaoscom][Why do you call PeekMessage once for each element in the skip list instead of retrieving the message once (if any) and comparing it against the messages you want to skip?][:"platform layer"]
[1:50:27][@finalspace][Q: You got that messages while debugging with the NVidia GPU devy thingy][:hardware]
[1:50:34][Note the situation in which the 0x738 message is problematic][:"platform layer" :rendering]
[1:50:58][Prevent Win32ProcessPendingMessages() from skipping 0x738 messages][:"platform layer" :rendering]
[1:51:36][:Run the game and find that our fonts are gone][:font]
[1:52:24][Try to give us a break point in Win32ProcessPendingMessages()][:"platform layer" :rendering]
[1:53:40][Add an assertion in Win32ProcessPendingMessages()][:"platform layer" :rendering]
[1:54:02][:Run and hit that assertion][:"platform layer" :rendering]
[1:54:19][Re-enable Win32ProcessPendingMessages() to skip 0x738][:"platform layer" :rendering]
[1:54:29][:Run the game to see that we freeze][:"platform layer" :rendering]
[1:54:43][Fix our PeekMessage note][:"platform layer" :rendering]
[1:55:34][@macielda][Q: I heard you have talked about it already, but do you have any comments you would like to make about Meltdown and Spectre on record? I missed the pre-stream][:hardware :security]
[1:58:19][@dragoonx6][Q: What in your opinion is the biggest lie / myth most programmers follow / believe in?]
[2:01:04][@cicero743][Hey [@cmuratori Casey] do you know SFML? If so, what is your opinion about it?]
[2:01:16][@macielda][Q: What do you mean when you mentioned "browser :security" is a concern these days? Should the OS be secure instead of the browser or something like that?][:rant]
[2:06:51][@dragoonx6][Q: Alright. Do you think code reviews and / or writing tests helps with that?][:rant]
[2:14:25][@stuckpanda][Q: I watched the first 50 or so episodes of [~hero Handmade Hero]. Quick question about the current state of things: is the GPU / OpenGL / shaders part of the project now?][:hardware :rendering]
[2:14:40][@frostyninja][Q: When do you plan on showing / adding in the new :art]
[2:14:49][@gg_nate][Q: Opinion of the .net framework platform?]
[2:14:52][@macielda][Q: One argument I get from people that use "advanced C++ features" is that the resulting code is more secure and more robust. Do you agree with that? Why?][:language]
[2:16:16][Close this down][:speech]
[/video]
