[video output=day380 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Attempting (and Failing) to Fix the Clock" vod_platform=youtube id=fxNhmGJ1OLQ annotator=Miblo]
[0:02][Recap and set the stage for the day]
[2:44][Run the game, consult the profiler and note that the game only updates itself as if it's running at 60FPS]
[9:51][Determine to enable the game to play properly at various frame rates]
[12:33][win32_handmade.cpp: Temporarily set TargetSecondsPerFrame to twice the expected rate, and run the game to see that it feels like the 60FPS version]
[16:54][win32_handmade.cpp: Initialise TargetSecondsPerFrame in the game loop]
[21:22][Blackboard: Computing the TargetSecondsPerFrame based on observed seconds elapsed]
[24:57][win32_handmade.cpp: Compute MeasuredSecondsPerFrame and ExactTargetSecondsPerFrame]
[26:06][Blackboard: Rounding seconds, accounting for jittering]
[26:58][Run the game to show the jittering frame rate]
[28:50][win32_handmade.cpp: Round the ExactTargetSecondsPerFrame and run the game to show that]
[30:14][win32_handmade.cpp: Make the debug system display the ExpectedFramesPerUpdate]
[31:40][Run the game and consult the profiler to see the ExpectedFramesPerUpdate oscillating]
[34:34][win32_handmade.cpp: Consult the documentation on wglSwapInterval[ref
    site="Khronos"
    page="EXT_swap_control"
    url=https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt]]
[37:40][win32_handmade.cpp: Pass 2 to wglSwapInterval(), run the game and investigate what wglSwapInterval is doing[ref
    site="Khronos"
    page="EXT_swap_control"
    url=https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt]]
[40:51][Temporarily disable HANDMADE_STREAMING and run the game to see that the wglSwapInterval works more correctly]
[44:04][Determine the refresh rate of the monitor]
[48:00][win32_handmade.cpp: Set the TargetSecondsPerFrame to the MeasuredSecondsPerFrame of the previous frame]
[49:33][Run the game and note all the jitter]
[51:16][Try (unsuccessfully) to set a Swap Interval Override in the video driver]
[56:59][Run the game and note that the movement speed is correct at lower frame rates]
[1:00:23][Determine to get back to working on the camera, fading out floors above the hero]
[1:01:36]["ATI peed on our cake"][quote 572]
[1:02:04][Run the game and consider how to fade out upper floors]
[1:03:02][handmade_world_mode.cpp: Increase the NearClipPlane and run the game to see that upper floors have been clipped out, and peel away gradually while moving between floors]
[1:06:08][handmade_opengl.cpp: Enable the shader to modulate the fragments' alpha amounts by their distance from the camera]
[1:08:15][Run the game to see how that looks]
[1:11:53][Blackboard: The original idea for clipping out upper levels]
[1:13:33][Blackboard: Depth peel]
[1:16:40][Blackboard: Depth peel vs multi-sampling with alpha to coverage]
[1:21:30][handmade_opengl.cpp: Enable OpenGLRenderCommands() to handle GL_TEXTURE_2D slots[ref
    site=docs.GL
    page="glTexImage2D"
    url=http://docs.gl/gl3/glTexImage2D][ref
        site=OpenGL
        page=glTexImage2D
        url=https://www.khronos.org/opengl/wiki/GLAPI/glTexImage2D]]
[1:28:19][Run the game without multisampling on]
[1:29:35][Blackboard: Comparing two depth buffers]
[1:31:13][handmade_opengl.cpp: Introduce a DepthSampler]
[1:33:27][Consult the documentation on gl_FragCoord[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"][ref
        site=Khronos
        page=gl_FragCoord
        url=https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_FragCoord.xhtml]]
[1:36:45][handmade_opengl.cpp: Enable the DepthPeel code to discard fragments nearer the camera than the ClipDepth]
[1:39:47][handmade_opengl.h: Introduce opengl_program struct and CompileZBiasProgram()]
[1:44:32][handmade_opengl.cpp: Introduce UseProgramBegin() and UseProgramEnd()]
[1:48:22][handmade_opengl.cpp: Make the shader call CompileZBiasProgram() for NoDepthPeel and DepthPeel, and fix compile errors]
[1:53:35][Run the game to see that we can run the DepthPeel and regular versions]
[1:54:13][Q&A][:speech]
[1:55:53][@garryjohanson][While we wait for other questions, have you had a good experience with gdb?]
[1:59:50][@uplinkcoder][How to stabilize the volume outlines?]
[2:00:33][handmade_render_group.cpp: Make PushLineSegment() give the debug line segments some ZBias]
[2:01:14][Run the game to see that the Z-fighting has gone]
[2:01:59][@acoto87][To follow the rule of writing the usage code first, don't believe that the project is at a point where it is better to advance in the game now, and when the game needs more engine features, then go and implement them?]
[2:06:32][@uplinkcoder][Clarification: what to do when the angles are too close together?]
[2:07:02][@jessermeyer][The debug text is drawing behind tree sprites, by the way]
[2:07:31][handmade_render_group.h: Add a depth_clear render_group_entry_type and introduce PushDepthClear() for DEBUGStart() to call]
[2:09:57][Run the game to see the debug text always drawn on top]
[2:10:37][@kilo_pasztetowej][Do you have any idea when the engine layer will be finished, and you move to just gameplay programming?]
[2:11:41][@jezzi23][I'm not sure if the profiler shows some insightful information about CPU cache hit / miss rates. How might you implement something like that?]
[2:14:28][@chrysos42][Can the depth buffer contain infinity as a floating point value?]
[2:16:24][@kilo_pasztetowej][Off-topic: What part of game programming do you enjoy the most? Engine, gameplay, etc?]
[2:16:42][Close things down][:speech]
[/video]
