[video output=day315 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Un-reversing Sort Key Order" vod_platform=youtube id=jr55zspbhGc annotator=Miblo] [0:11][Recap and set the stage for the day] [2:07][Blackboard: Layered Sorting] [4:27][Blackboard: How we currently pull entities out of the simulation for sorting] [7:44][Blackboard: Our choices for doing this layered sorting] [10:50][handmade_render.cpp: Consider how the code is currently working] [12:40][handmade_entity.cpp: Make UpdateAndRenderEntities() sort on the old position of the Entity] [13:46][handmade_entity.h and .cpp: Add ZLayer to the entity struct and make BeginSim() set that Dest->ZLayer] [14:26][handmade_entity.cpp: Make UpdateAndRenderEntities() keep track of and conditionally operate based on the CurrentAbsoluteZLayer] [18:33][handmade_render_group.cpp: Introduce PushSortBarrier()] [20:00][Run the game and hit the assertion in BuildSpriteGraph()] [20:23][handmade_render.cpp: Read through BuildSpriteGraph() and make it break after incrementing the NodeIndexA] [21:40][Debugger: Hit the assertion in BuildSpriteGraph() and investigate what's happening] [23:52][handmade_render.cpp: Change LastIndex to OnePastLastIndex in SortEntries() and operate on it accordingly] [26:37][Debugger: Run the game, hit the assertion in RecursiveFrontToBack() and investigate why] [28:43][handmade_render.cpp: Prevent BuildSpriteGraph() from taking NodeIndexA but rather set it relative, and then simplify SortEntries()] [31:53][Debugger: Run the game and hit the assertion in OpenGLRenderCommands()] [32:21][handmade_render_group.cpp: Make PushSortBarrier() increment the PushBufferElementCount] [33:53][handmade_render.cpp: Make SortEntries() change the total number of things to reflect how many there are without barriers] [36:17]["It's like Doctors Without Barriers, you know what I'm saying?"][quote 509] [36:48][Run the game and see that we are actually running, but that the sorting doesn't appear to be right per se] [37:27][Debugger: Step into UpdateAndRenderEntities() and investigate what's happening with the sorting] [40:02][handmade_render_group.cpp: Make PushSortBarrier() reverse the sense of the sort] [41:38][handmade_platform.h: Consolidate game_render_commands and game_render_prep into something more sane] [43:47][handmade_platform.h: Introduce GetSpriteBounds()] [44:37][handmade_render_group.cpp: Make PushSortBarrier() call GetSpriteBounds() and operate according to what it returns] [46:58][handmade_render_group.cpp: Make PushRenderElement_() similarly operate according to what GetSpriteBounds() returns] [48:15][handmade_render_group.cpp: Make BeginAggregateSortKey() and EndAggregateSortKey() work a little differently] [50:52][handmade_platform.h: Rename GetSpriteBounds() to GetSortEntries() and fix compile errors] [54:27]["Go away, Five minute warning!"][quote 510] [59:28][Run the game and crash and burn] [1:00:28][handmade_render_group.cpp: Introduce push_buffer_result struct and PushBuffer() to do some of the work of PushRenderElement_()] [1:05:28][handmade_render_group.cpp: Make PushClipRect() call PushBuffer()] [1:07:15][handmade_render_group.cpp: Make PushBuffer() correctly set Result.SortEntry] [1:07:31][Run the game and hit the assertion in SafeTruncateToU16()] [1:07:53][Q&A][:speech] [1:09:01][Debugger: Step into PushRenderElement() and GameUpdateAndRender() and inspect the values] [1:10:52][handmade_platform.h: Make RenderCommandStruct() take the correct default values] [1:12:02][@dj_crixl][You mentioned earlier that the compiler would optimize the code making pointer comparison unsafe. When does that happen?] [1:12:24][Blackboard: "Memory Region" / "Allocation", and Pointer Arithmetic] [1:16:59][Assign homework][:speech] [1:17:56][Wrap it up][:speech] [/video]