[video output=day374 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Debugging Z Transform and Bias" vod_platform=youtube id=G4e70hz3pC0 annotator=Miblo]
[0:12][Recap and set the stage for the day]
[4:26][Determine to fix the "glGetString(GL_EXTENSIONS) fails with error GL_INVALID_ENUM issue"[ref
    site="GitHub"
    page="HandmadeHero/cpp Issues"
    url="https://github.com/HandmadeHero/cpp/issues"]]
[6:28][handmade_opengl.cpp: Make OpenGLGetInfo() use glGetIntergerv() and glGetStringi() rather than glGetString()[ref
    site="docs.GL"
    page="glGetString"
    url="http://docs.gl/gl3/glGetString"]]
[13:26][handmade_opengl.cpp: Pull in GL_NUM_EXTENSIONS and glGetStringi() from corearb.h[ref
    site="Khronos"
    page="glcorearb.h"
    url="https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h"]]
[14:54][win32_handmade.cpp: Pull in glGetStringi() from corearb.b[ref
    site="Khronos"
    page="glcorearb.h"
    url="https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h"]]
[17:18][Run the game, step through OpenGLGetInfo() and close that issue]
[18:25][Run the game and consider what we have to do]
[20:16][handmade_world_mode.cpp: Make PlayWorld() always make rooms above and below us]
[22:40][Run the game to see that our zoom isn't working, and investigate why]
[23:16][handmade_world_mode.cpp: Make PlayWorld() only make one room]
[23:58][Run the game, try to switch to the debug camera and hit the assert in RecanonicalizeCoord()]
[26:26][Step through UpdateAndRenderWorld() to see what's going on]
[28:54][handmade_render_group.cpp: Make Unproject() correctly compute the ProbeZ]
[29:58][Blackboard: Camera transform matrix]
[31:31][handmade_render_group.cpp: Make Unproject() grab the Z row out of the camera projection matrix]
[33:26][Run the game and step in to Unproject() to inspect the ProbeZ]
[38:00][Run the game and step through Unproject() more carefully]
[39:45][handmade_render_group.cpp: Make Unproject() compute the ProbeZ using the correct CameraZ]
[40:31][Run the game and step into Unproject() to find that we have a more correct ProbeZ, but a busted ClipZ]
[41:46][Blackboard: Our combined projection matrix]
[42:44][handmade_render_group.cpp: Make Unproject() compute the ProbeZ fully correct]
[43:04][Run the game to see that we get a better ClipZ, just not exactly what we'd expect]
[48:28][Run the game and step through PerspectiveProjection() to see how it is building the matrix]
[50:31][handmade_math.h: Make PerspectiveProjection() perform a full transform in the tests]
[51:31][Run the game and step in to PerspectiveProjection() to inspect the results of the tests]
[53:14][Run the game and step through SetCameraTransform() to see how that is working]
[55:00][handmade_render_group.h: Introduce render_transform struct, and make render_group contain one each for the game and camera]
[56:03][handmade_render_group.cpp: Make the necessary functions take this render_transform]
[1:03:12][handmade_render_group.cpp: Make SetCameraTransform() build the correct transform matrix]
[1:06:26][Run the game to see that the central debug rectangle is stable, and continue to investigate Unproject()]
[1:11:29][handmade_world_mode.cpp: Force UpdateAndRenderWorld() to call Unproject() right at the near clip plane]
[1:13:23][Run the game and step in to Unproject() to inspect the ProbeZ and ClipZ]
[1:15:22][handmade_world_mode.cpp: Force UpdateAndRenderWorld() to call Unproject() right at the far clip plane]
[1:15:42][Run the game and step in to Unproject() to inspect the ProbeZ and ClipZ]
[1:16:01][handmade_world_mode.cpp: Force UpdateAndRenderWorld() to call Unproject() at 0.8]
[1:16:18][Run the game and step in to Unproject() to inspect the ProbeZ and ClipZ]
[1:16:37]["It's the inverse-square law kicking our butts"][quote 563]
[1:16:51][handmade_math.h: Try to make PerspectiveProjection() move the near clip plane out]
[1:17:40][Run the game and step in to Unproject() to inspect the ClipZ]
[1:18:26][todo.txt: Fix Z buffer to be better resolution]
[1:18:44][4coder feature request: TODO list formatting]
[1:21:56][Consider getting our Z story sorted out and return to debugging the problem with multiple stacked screens]
[1:22:45][Run the game to find our camera encased in some degenerate geometry]
[1:23:22][handmade_world_mode.cpp: Make PlayWorld() set DoorDirection to 2]
[1:23:41][Run the game and determine that the problem only occurs when the floors are generated to the camera]
[1:24:32][handmade_render_group.cpp: Make PushBitmap() reduce the ZBias]
[1:24:55][Run the game, zoom out and determine that our bias is being applied incorrectly]
[1:25:31][handmade_opengl.cpp: Investigate how the VertexCode is applying the ZBias]
[1:29:46][handmade_opengl.cpp: Try making OpenGLRenderCommands() pass GL_DEPTH_COMPONENT32F to glTexImage2DMultisample()]
[1:29:54][Run the game to see the same behaviour, and consider it not to be a precision issue]
[1:32:04][handmade_opengl.cpp: Try commenting out the ZVertex.z biasing]
[1:32:23][Run the game to see that all of the stuff seems pretty consistent]
[1:34:56][handmade_world_mode.cpp: Try increasing the far clip plane]
[1:36:43][Run the game and watch the incorrect clipping behaviour]
[1:37:42][handmade_math.h: Tweak the near and far clip plane in PerspectiveProjection()]
[1:38:54][Try to find a source for the standard projection perspective matrix]
[1:43:48][Run the game to see some projection wonkiness]
[1:46:06][handmade_render_group.cpp: Try turning off the ZBias in PushBitmap()]
[1:46:25][Run the game to see that everything is sorting as expected]
[1:48:45][Consider that the ZBias is pre-transformed and appears to be being applied in clip space]
[1:51:45][Moment of realisation: Our ZMaxTransform.z depends on the w value to counter-divide it]
[1:52:58][Blackboard: Computing ClipZ]
[1:55:32][handmade_opengl.cpp: Make VertexCode compute a ModifiedZ for use in the gl_Position computation]
[1:56:25][Run the game to see that that was exactly what we needed, and consider how to handle blocks obscuring other blocks]
[2:01:04][Blackboard: How the sprites are being generated aligned with the camera]
[2:02:02][handmade_render_group.cpp: Enable PushBitmap() to draw the Upright sprites actually standing upright]
[2:03:02][Run the game to see what that looks like]
[2:04:07][handmade_render_group.cpp: Play with how PushBitmap() combines the upright and camera-facing styles]
[2:07:10][Run the game to admire our trees]
[2:09:17][Q&A][:speech]
[2:10:22][@charlemaynemtg][I am a fairly amateur programmer. I have dabbled in Java, flavors of C, Python, and Ruby while I was in university. My question is, how would you suggest with progressing your proficiency in a particular language? Is it best to follow tutorials?]
[2:15:47][@hej1993][What is Z transform?]
[2:17:52][@macielda][How many draw calls with the profiler open?]
[2:18:08][@abarishu][A few streams ago you showed a function that tells OpenGL to call us back with messages. Do you think it can help debug OpenGL issues instead of sticking glGetError after every call?]
[2:19:13][@areriff][When the new assets gonna be ready?]
[2:19:35][@hholst80][Scenario is that Handmade Hero is expanding to three programmers and two need to understand the architecture you have designed. How would you recommend that they get into the code and understand the architecture? What would you need to do to prepare the system for such a scenario?]
[2:25:09][@ronpaulvevo][I know you don't really like OOP design, but can you provide some ways you might take advantage of OOP design in Handmade Hero?]
[2:30:59]["Don't OOP. OOC"][quote 564]
[2:35:06]["What are the chances that there's one way to always write code?"][quote 565]
[2:35:52][@siltnamis][What do you think about "const correctness"? How often do you use const?]
[2:38:35][@mrpapillon1][const is mainly for teams]
[2:40:58][Wrap it up][:speech]
[/video]
