[video 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]