[video output=day473 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Removing Screen Coordinates from the Render Group" vod_platform=youtube id=xzOU9RglmIg annotator=Miblo]
[0:08][Recap and set the stage for the day continuing our renderer :API cleanup and addressing texture arrays][:speech]
[3:42][:Run the Renderer Test and consider addressing the :API call for rotation][:rendering]
[5:58][Consider organising our source files into directories][:speech]
[8:57][Move the #include of handmade_memory.h out of handmade_shared.h]
[14:17][Move the #include of handmade_simd.h out of handmade_shared.h]
[16:37][Move the #include of handmade_intrinsics.h and handmade_math.h out of handmade_shared.h]
[18:22][Migrate all our #include directives in win32_renderer_test.h to the top to clearly indicate all the files needed to use our renderer]
[21:55][Further organise and document win32_renderer_test.cpp and win32_renderer.test.h for clarity]
[26:24][Pull out some of PlaceRandom() into CountOccupantsIn3x3(), renaming the former to PlaceRandomInOccupied()]
[29:07][Enable InitTestScene() to place trees in a quantity proportional to the available area][:"procedural generation"]
[30:56][Introduce PlaceRectangularWall() and IsEmpty(), for InitTestScene() to call][:"procedural generation"]
[39:44][:Run it to see our rectangular walls][:"procedural generation"]
[40:15][Make InitTestScene() clamp our rectangular wall to a minimum of 2×2][:"procedural generation"]
[40:31][:Run it and consider throwing more sprites into the scene]
[41:18][Create test_cover_grass.bmp][:drawing]
[43:18][Enable InitTestScene() to load and PushSimpleScene() to push our test_cover_grass.bmp everywhere, one per tile][:"asset loading" :"procedural generation" :rendering]
[46:06][:Run it to see our grass, and shrink it down][:"asset loading" :"procedural generation" :programming :rendering]
[46:52][Enable PushSimpleScene() to randomly displace multiple grass sprites in each tile][:"procedural generation" :rendering]
[49:05][:Run it to see our randomly displaced grass][:"procedural generation" :rendering]
[49:08][Crank up our sprite-count per tile][:"procedural generation" :rendering]
[49:39][:Run it to see our scene looking bad, and begin to investigate why this is permitted][:"procedural generation" :rendering]
[50:55][Assert in PushQuad() that VertexCount <= MaxVertexCount][:rendering]
[52:26][:Run it and do not hit that assertion][:rendering]
[52:36][Add an InvalidCodePath assertion in GetCurrentQuads(), unfortunately in the case that we don't blow out the vertex buffer][:rendering]
[53:37][:Run it and hit that assertion, failing loudly][:rendering]
[54:41][Bump up the MaxVertexCount in RenderLoop()][:rendering]
[54:50][:Run it and unexpectedly hit our new InvalidCodePath in GetCurrentQuads()][:rendering]
[55:59][Step in to GetCurrentQuads() and inspect the Commands][:rendering]
[56:42][Fix the location of our InvalidCodePath in GetCurrentQuads(), in the case that we do blow out the vertex buffer][:rendering]
[57:10][:Run it to see our lower :rendering :performance]
[57:34][Crank up our sprite-count per tile to really slow down our test program][:"procedural generation" :rendering]
[58:19][Set up to test whether the slowdown is in the renderer or our push calls][:"procedural generation" :rendering :speech]
[1:02:30][Make RenderLoop() only call PushSimpleScene() once][:"procedural generation" :rendering]
[1:03:57][:Run it to see that the OpenGL dispatch and :rendering takes at least 89.91ms per frame][:performance]
[1:04:58][Let RenderLoop() call PushSimpleScene() every loop][:"procedural generation" :rendering]
[1:05:15][:Run it to see that our push buffer calls slow us down to 102.56ms per frame, noting that a fair test would omit :camera rotation][:performance :rendering]
[1:06:42][Revert our :performance testing code with the determination to work on the :API]
[1:07:32][Document RenderLoop(), and change the :profiling to only occur if we have a valid frame][:api]
[1:10:22][:Run it to see that our :performance ranges from 20.6 to 36.9ms per frame][:rendering]
[1:11:04][Introduce Win32SetVSync() to support conditionally setting VSync]
[1:12:17][:Run it to see that our :performance still ranges widely][:rendering]
[1:12:50][Consult the NVidia Control Panel for VSync information][:admin]
[1:14:30][Continue to document RenderLoop()][:api :rendering]
[1:22:53][Pull out the :profiling code in RenderLoop() to InitFrameStats() and UpdateFrameStats()][:api]
[1:28:38][:Run it successfully]
[1:29:04][Document the :profiling and :camera in RenderLoop()][:api]
[1:32:21][Enable RenderLoop() to test the scene while orbiting and panning the :camera][:rendering]
[1:33:32][:Run it to see our :camera orbiting and panning][:rendering]
[1:35:01][Make PushSimpleScene() confine sprites to their tile][:"procedural generation" :rendering]
[1:35:28][:Run it to see our grass sprites confined to their tiles][:rendering]
[1:35:38][Document our twofold :camera test in RenderLoop()][:api :rendering]
[1:36:46][Consider how to package up the :camera and render group code from RenderLoop()][:api :rendering :speech]
[1:41:23][Consider relieving the renderer of using pixel coordinates, in favour of specifying clip rects in −1 to 1 screen space coordinates][:api :rendering :speech]
[1:46:31][:Run the game and note the reason why the debug overlay breaks the alpha compositing][:rendering]
[1:47:39][Set up to switch the renderer from pixel coordinates to −1 to 1 screen space coordinates, for the :"debug system" clip rect and the :lighting unproject to work in][:api :rendering :run]
[1:48:17][Switch the renderer from pixel coordinates to −1 to 1 screen space coordinates, introducing S32BinormalLerp() and respecifying GetScreenPoint() as GetClipSpacePoint()][:api :mathematics :rendering]
[1:58:51][:Run it to see that the :lighting works, but the debug overlay does not][:api :"debug system" :rendering]
[1:59:59][Introduce ClipSpaceFromScreenSpace() to re-enable the :"debug system" clicking][:api :"input handling"]
[2:03:57][:Run it with clicking and clipping back online, and reflect on our improved :API][:"debug system" :"input handling" :rendering]
[2:05:41][Q&A][:speech]
[2:06:30][@geordish][Q: Do you think you will ever get back to 60fps in the debug build, or at least a useable frame rate?][:performance]
[2:07:45][@longboolean][Q: Do you want the renderer :API to have a :UI mode, basically a polished version of what the debug display is using now? So no interaction with the :lighting system, perhaps using screen space coordinate system, etc. Or is this something that will always be for debug, and 2D stuff will need to be handled by some other means?][:"debug system" :rendering]
[2:09:09][@longboolean][Q: I mean for the other person who is using your render engine][:api :rendering]
[2:10:08][@Jim0_o][Q: I might have misunderstood but, in the renderer test/demo code I believe you created a function that checked for unoccupied spots but the name said Occupied? PlaceInOccupied I think you called it.]
[2:10:15][Rename PlaceRandomInOccupied() to PlaceRandomInUnoccupied()]
[2:10:59][@halibetlector][Q: On twitter, you said "All user interface design is an adaptive :compression problem." What did you mean by that?][:ui]
[2:12:57][@frostyninja][Q: Going along with getting rid of unnecessary params, do the :camera FOV, aspect ratio and near / far clip need to be passed every frame, or are you going to move them out to a one-time setup call?]
[2:14:04][@wofiel][Q: Minor, but one of your comments had a grammatical error (is → it) around L620?]
[2:14:34][Fix typo in RenderLoop() documentation][:api]
[2:14:47][@nordicplayer][Q: Hey Casey, how can I start with C++?][:language]
[2:15:54][@mallesbixie][Q: On comments: "use later with to figure out" is a few comments above. The "with" is obsolete]
[2:15:59][Fix typo in RenderLoop() documentation][:api]
[2:16:52][@nordicplayer][Q: How you manage your dependencies in a C++ project?][:language :library]
[2:17:25][@jim0_o][Q: Would you consider doing this sort of overhaul on any other parts of the code, like what you've been doing to the renderer?][:api]
[2:18:55][@nordicplayer][Q: Libraries][:library]
[2:24:35][Call it a day[ref
    site="Handmade Hero"
    url=https://handmadehero.org/][ref
        site="Molly Rocket's Site Nexus"
        url=https://mollyrocket.com/nexus]][:speech]
[/video]
