[video output=day394 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Basic Multigrid Lighting Upward Iteration" vod_platform=youtube id=h6D85wUYMgg annotator=Miblo] [0:03][Recap and set the stage for the day] [0:54]["You can't win 'em all but you're certainly not gonna win if you never roll"][quote 584] [0:59][Run the game to see where we're at with respect to lighting] [4:13][A few words on multigrid solvers] [6:54][The two halves of our problem: 1) Getting our lighting information down to the renderer] [9:22][2) We will need normals] [9:59][handmade_opengl.h: Rename WriteEmit to WriteEmitFramebuffer in the light_buffer struct, and describe the framebuffers in this struct] [14:33][Blackboard: On the possible need for an additional texture to write into] [20:06][handmade_opengl.cpp: Toggle on the framebuffer visualisation code in OpenGLRenderCommands()] [22:50][Research glReadBuffer[ref site=docs.GL page="glReadBuffer" url=http://docs.gl/gl3/glReadBuffer]] [24:27][handmade_opengl.cpp: Enable the framebuffer visualisation code to pick from a colour buffer] [27:30][Run the game a get a black screen] [27:58][handmade_opengl.cpp: Introduce FakeSeedLighting() and ComputeLightTransport()] [30:17]["I assume it's "hare-brained", like the rabbit. Or is it "hair-brained", like the follicle?"][quote 585] [30:29][handmade_opengl.cpp: Implement FakeSeedLighting() and introduce OpenGLBeginScreenFill() and OpenGLEndScreenFill() to perform some of ResolveMultisample()] [35:06][Run the game to make sure that that still works] [35:23][handmade_opengl.cpp: Finish implementing FakeSeedLighting()] [37:12][handmade_opengl.cpp: Introduce CompileFakeSeedLighting() based on CompileResolveMultisample(), with some structured artwork] [41:12][handmade_opengl.h: Introduce fake_seed_lighting_program struct and add it to open_gl] [42:14][handmade_opengl.cpp: Introduce a version of UseProgramBegin() that only takes a Prog and Setup, and enable OpenGLRenderCommands() to set up the debug lighting framebuffer] [44:30][Run the game to see a green screen, and investigate why we do] [45:45][Consult the Quick Reference Card[ref site="OpenGL Registry" page="The OpenGL Shading Language 1.50 Quick Reference Card" url="https://www.khronos.org/files/opengl-quick-reference-card.pdf"] and the OpenGL Spec[ref site="Khronos" page="The OpenGL Shading Language 1.50" url="https://khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.50.pdf"] to determine how to line up the output fragments with the framebuffer's bound colour attachments] [50:23][handmade_opengl.cpp: Specify the fragments into which CompileFakeSeedLighting() should write our test colours] [51:18][Run the game to see that that worked] [51:21][handmade_platform.h: Add DebugLightBufferIndex and DebugLightBufferTexIndex to game_render_settings] [54:50][Determine to provide debug keys to control the lighting framebuffers] [56:22][handmade_opengl.h: Move the DebugLightBuffer settings into open_gl] [56:50][win32_handmade.cpp: Add debug keys in Win32ProcessPendingMessage() for cycling through the lighting framebuffers] [58:10][Note the "Sign extension bug" issue[ref site="GitHub" page="HandmadeHero/cpp Issues" url="https://github.com/HandmadeHero/cpp/issues"]] [58:45][win32_handmade.cpp: Continue adding these debug keys in Win32ProcessPendingMessage()[ref site="MSDN" page="GetKeyState function" url="https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301"]] [1:00:54][handmade_opengl.cpp: Make OpenGLRenderCommands() keep our framebuffer indices in bounds] [1:02:58][handmade_math.h: Introduce a version of Clamp() that works on s32s] [1:03:32][win32_handmade.cpp: Tweak those bindings in Win32ProcessPendingMessage()] [1:04:20][Run the game to try cycling through the framebuffers, and investigate why nothing happens] [1:05:39][win32_handmade.cpp: Change Win32ProcessPendingMessage() to use 0 and 9] [1:06:47][Run the game to see that 0 and 9 do work] [1:07:12][Investigate which VK_ keys are available to us] [1:10:06][win32_handmade.cpp: Make Win32ProcessPendingMessage() use VK_OEM_PLUS and VK_OEM_MINUS] [1:10:46][Run the game to try out our key bindings, and investigate why we can't cycle between the textures] [1:12:29][handmade_opengl.cpp: Double-check CompileFinalStretch()] [1:13:05][Consult the documentation on Framebuffer[ref site="Khronos" page="Framebuffer" url="https://khronos.org/opengl/wiki/Framebuffer"]] [1:15:00][handmade_opengl.cpp: Make OpenGLChangeToSettings() specify the mapping table and call glDrawBuffers() for both framebuffers[ref site="Khronos" page="glcorearb.h" url=https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h][ref site=docs.GL page="glDrawBuffers" url=http://docs.gl/gl3/glDrawBuffers]] [1:17:52][Run the game and cycle between our texture] [1:18:30][win32_handmade.cpp: Enable Win32ProcessPendingMessage() to print out debug text for the keyboard input] [1:20:26][Run the game and inspect that output] [1:21:05][win32_handmade.cpp: Fix Win32ProcessPendingMessage() to only handle the lighting keys in the IsDown path] [1:22:05][Run the game to see that this is more stable] [1:22:25][handmade_opengl.cpp: Try to make CompileFakeSeedLighting() use vec3 textures] [1:24:15][Run the game to see that that seems to work] [1:25:02][handmade_opengl.cpp: Enable CompileFakeSeedLighting() to light the scene with an emitter that is red on the left and green on the right] [1:36:01][handmade_opengl.cpp: Make CompileFakeSeedLighting() use a v4 for the output gl_FragData] [1:36:23][Run the game, see nothing and investigate why] [1:39:09][handmade_opengl.cpp: Force CompileFakeSeedLighting() to draw a red blob] [1:40:57][Run the game, see a 10 pixel blob in the corner of the screen and investigate why] [1:43:05][Realise that we're rendering at 960*540] [1:43:25][handmade_opengl.cpp: Make CompileFakeSeedLighting() centre the light and slow down its movement] [1:44:43][Run the game and try moving the light] [1:45:16][handmade_opengl.cpp: Implement the upward phase of ComputeLightTransport(), building successively less detailed light buffers] [1:50:39][handmade_opengl.cpp: Introduce OpenGLBindTex() for ComputeLightTransport() to call] [1:53:49][handmade_opengl.cpp: Introduce CompileMultiLightUp() based on CompileFinalStretch()] [2:03:01][handmade_opengl.cpp: Introduce a blank CompileMultiLightDown() and fix compile errors] [2:05:41][Run the game to see that one of our lower detail textures is black, and investigate why] [2:10:03][handmade_opengl.cpp: Try to make ComputeLightTransport() use the FakeSeedLighting() program at every level] [2:10:46][Run the game to determine that there's something wrong with CompileMultiLightUp()] [2:11:42][handmade_opengl.cpp: Manually set all the values in CompileMultiLightUp()] [2:12:16][Run the game to see no pixels being filled] [2:12:34][handmade_opengl.cpp: Make CompileMultiLightUp() correctly set the input position] [2:12:50][Run the game and successfully cycle through the colours] [2:13:01][handmade_opengl.cpp: Remove the debug code from CompileMultiLightUp()] [2:13:10][Run the game and cycle through the detail levels, but see that texture 1 uses red rather than green, and investigate why] [2:17:03][@4bitlightning][Additional semicolon in glGetUniformLocal "SourceBackEmitTex;"] [2:17:21][handmade_opengl.cpp: Remove spurious semicolon from CompileMultiLightUp()] [2:17:28][Run the game and cycle through all the textures and detail levels] [2:17:48][Q&A][:speech] [2:19:14][@fr0styninja][Is this going to be pulled out of the final ship to pull aside as DLC content to charge for?] [2:19:39][@4bitlightning][Ideas for a good IDE-integrated debugger for Linux, like VS and CDB?] [2:21:08][@d7samurai][Could you recap / outline the idea for this lighting scheme?] [2:22:17][@zilarrezko][Will I be able to pay money for an expansion that crashes every so often?] [2:22:53][@hholst80][Is this a single player game or will there be some network / multiplayer features?] [2:24:37][Close it down][:speech] [/video]