diff --git a/cmuratori/hero/code/code472.hmml b/cmuratori/hero/code/code472.hmml new file mode 100644 index 0000000..49c9638 --- /dev/null +++ b/cmuratori/hero/code/code472.hmml @@ -0,0 +1,124 @@ +[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Making a Simple Scene with the Separated Renderer" vod_platform=youtube id=D3nI8x_pxpU annotator=Miblo] +[0:00][Recap and set the stage for the day cleaning up the renderer's :API][:speech] +[0:50][Texture handling][:api :"asset loading" :rendering :speech] +[3:38][Texture atlases and mipmapping][:api :"asset loading" :rendering :speech] +[6:30][Our potential to lean on the streaming system for texture handling][:api :"asset loading" :rendering :speech] +[9:03][Keep Reminder.txt open][:admin] +[9:45][:Run the Renderer Test with the determination to render textured cubes and sprites] +[10:41][Consult a screenshot of Hartacon Tactics[ref + site="https://media.indiedb.com/images/games/1/26/25317/s.jpg" + url=https://media.indiedb.com/images/games/1/26/25317/s.jpg]][:art :research] +[15:16][Introduce PushSimpleScene()][:rendering] +[20:14][:Run the Renderer Test to see our world of cubes][:rendering] +[20:21][Make PushSimpleScene() push blue cubes][:rendering] +[20:57][:Run it to see our blue world][:rendering] +[21:20][Make our :camera orbit the world] +[22:09][:Run it to see our orbiting perspective of the world][:camera] +[22:32][Apply a texture to our cubes][:"asset loading" :rendering] +[28:43][Enable OpenGLManageTextures() in handmade_renderer_opengl.cpp to fully manage the textures, introducing DequeuePending() and EnqueueFree() in handmade_renderer.h][:rendering :threading] +[35:05][Wait-free vs ticketed mutex][:speech :threading] +[35:57][Finish implementing EnqueueFree() and OpenGLManageTextures()][:rendering :threading] +[41:21][:Run the game to see that we're not running okay][:rendering] +[41:40][Introduce InitTextureQueue() in handmade_renderer.h][:rendering :threading] +[45:36][:Run the game okay, with scepticism on this texture initialisation code][:rendering :threading] +[47:13][Call OpenGLManageTextures() in win32_renderer_test.cpp][:rendering :threading] +[47:42][:Run the Renderer Test to see our textured cubes][:rendering] +[48:36][Select a tree and forest asset][:art :drawing] +[52:41][Change LoadBMP() to take a renderer_texture and load our forest tile into the test][:"asset loading" :rendering] +[55:15][:Run the test to see our textured ground][:"asset loading" :rendering] +[55:56][Load our tree sprite into the test and enable PushSimpleScene() to sprinkle them around the scene][:"asset loading" :rendering] +[57:41][Consider making PushBitmap() part of the renderer proper][:rendering :speech] +[59:10][Introduce PushBitmap() in handmade_renderer.cpp][:"asset loading" :rendering] +[59:41][Consider relieving PushBitmap() of the need to shrink bitmap borders in favour of making the software renderer upload textures into a bordered region][:"asset loading" :rendering :speech] +[1:03:21][Rename PushBitmap() to PushSprite() and clean it up][:"asset loading" :rendering] +[1:10:12][Try making PushSimpleScene() call PushSprite() for our trees][:"asset loading" :rendering] +[1:11:34][:Run the Renderer Test, see no trees and step into PushSprite() to see what it's computing][:"asset loading" :rendering] +[1:12:53][Prevent PushSimpleScene() from pushing cubes][:rendering] +[1:13:06][:Run it to see our trees][:rendering] +[1:13:12][Enable PushSimpleScene() to elevate sprites above the cubes][:rendering] +[1:14:08][:Run it to see our trees above the ground cubes][:rendering] +[1:14:37][Make PushSprite() centre the sprites on the cubes][:rendering] +[1:15:44][:Run it to see our centred trees][:rendering] +[1:15:55][Grow the trees in PushSimpleScene() and scatter them randomly][:rendering] +[1:16:23][:Run it to see our scattered trees][:rendering] +[1:16:50][Make the :camera pan rather than orbit] +[1:21:43][:Run it to see our panning :camera] +[1:22:31][Widen the scene and shrink the trees in PushSimpleScene()][:rendering] +[1:22:51][:Run it to see our scene, feeling like the trees aren't quite pegged to the centre][:rendering] +[1:24:02][Enable PushCube() to map our texture to the faces of the cube][:rendering] +[1:28:51][:Run it to see our textured cubes, and reconsider the sprite centring][:rendering] +[1:30:41][Enable PushSimpleScene() to push Krampus' head and walls][:rendering] +[1:34:15][Check out our scene][:rendering] +[1:34:33][Make PushSimpleScene() position Krampus unit forwards and apply the correct texture to the walls][:rendering] +[1:35:14][:Run it to see Z-fighting][:rendering] +[1:35:30][Make PushSimpleScene() elevate the walls above the ground by their radius][:rendering] +[1:35:59][:Run it to see trees intersecting wall geometry][:rendering] +[1:37:44][Make PushSprite() bias the Z of upright sprites by their entire vertical size][:rendering] +[1:37:56][:Run it to see how that looks][:rendering] +[1:38:15][Reduce the WallRadius in PushSimpleScene()][:rendering] +[1:38:52][:Run it to see the trees more correctly occluding the walls][:rendering] +[1:40:06][Make PushSprite() render the sprites without modifying their axes][:rendering] +[1:41:07][:Run it to see the trees standing perfectly upright, but looking like cardboard cutouts][:rendering] +[1:41:47][Enable PushSprite() to lerp between modified axes][:rendering] +[1:42:11][:Run it to see that it looks quite nice from this perspective][:rendering] +[1:43:40][Increase the :camera pitch and bias the lerp towards the correct axes][:rendering] +[1:45:48][Check out how that looks][:rendering :run] +[1:47:47][Play with the :camera focal length, pitch and position] +[1:52:13][:Run it to see everything stacking nicely][:rendering] +[1:53:20][Create win32_renderer_test.h and introduce test_scene struct, InitTestScene() and PlaceRandom()][:"procedural generation" :rendering] +[2:04:20][:Run it to see our well-spaced scene][:rendering] +[2:05:08][Fix PlaceRandom() to space elements out more][:rendering] +[2:05:23][:Run it to see our even better-spaced scene][:rendering] +[2:06:42][Q&A][:speech] +[2:06:52][@quote_corn_if_brother][Q: Are we going to do anything special on Day 500?] +[2:07:40][@vateferfout][Q: The right side of the walls seems to be flipped vertically, I guess it's because of the UV ordering][:rendering] +[2:07:53][@somebody_took_my_name][Q: Not a question, but I think you changed the meaning of the code in the EnqueueFree() function. The pending list is put back on the queue instead of on the free list (Queue->FirstFree)][:threading] +[2:08:10][Fix EnqueueFree() to set the Queue->FirstFree][:threading] +[2:09:39][Fix PushCube() to map our texture to the correct faces of the cube][:rendering] +[2:12:48][:Run it to see that our wall textures look good][:rendering] +[2:14:05][@vaualbus][Q: So I missed the stream today. What have we done with the texture generation today?] +[2:14:59][@filiadelski][Q: Are we done with the renderer or will we maintain both versions?] +[2:15:43][@jim0_o][Q: [~hero Handmade Hero] will be using this decoupled renderer, right?] +[2:16:11][@cirdanvalen][Q: Would it be helpful in this situation to use the old school billboards that are two or three sprites in a + or X shape?][:rendering] +[2:17:20][@filiadelski][Q: I assumed we weren't going to use the decoupled version, but that makes sense] +[2:18:47][Build the game in -O2] +[2:19:04][:Run the renderer test] +[2:19:24][@jim0_o][Q: Would it be too much to attach the :profiling stuff to just see the FPS etc?] +[2:19:36][Enable win32_renderer_test.cpp to print the milliseconds per frame][:profiling] +[2:24:20][:Run it to see our milliseconds per frame][:performance] +[2:24:55][Reduce the TEST_SCENE_DIM_Y] +[2:25:27][:Run it to see our still-variable frame rate][:performance] +[2:26:02][Increase the TEST_SCENE_DIM_Y] +[2:26:16][:Run it to see our just-as-variable frame rate][:performance] +[2:26:48][@neitchzehrer][Q: Did you update ~4coder yesterday (if necessary)?] +[2:26:52][Check our :rendering :performance][:run] +[2:28:13][@filiadelski][Q: Why do the frames drop so badly when moving the window? Does Windows spam the process with messages or something?][:performance :threading] +[2:30:04][Enable win32_renderer_test.cpp to create a thread for the :rendering separate from Windows' message processing][:threading] +[2:34:25][:Run it and reconsider our :rendering :performance] +[2:36:31][@nickito97][Q: What is volatile?][:language] +[2:39:21][@mmozeiko][Q: Now the main thread should use GetMessage(), not PeekMessage(), to save on CPU] +[2:39:41][Change win32_renderer_test.cpp to use GetMessage()[ref + site=MSDN + page="GetMessage function" + url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx]] +[2:42:54][@pythno][Q: Could you go over the extra render thread thing briefly again, please? I thought the DC is thread-specific and so the OpenGL RC has to reside within the same thread][:threading] +[2:44:14][@mmozeiko][Q: GetMessage should be GetMessageA] +[2:44:40][Remove all the "A" function-name suffixes] +[2:46:47][@mmozeiko][Q: Without A or W you'll depend on "project settings" whether Unicode is set or not, and people had a lot of issues on forums, when they used [~hero Handmade Hero] code in Visual Studio projects] +[2:47:16][Embark on Windows Unicode string handling] +[2:51:26][@mmozeiko][Q: Try to #define UNICODE at top of file, to see if the compiler is happy] +[2:51:32][Try to #define UNICODE and continue down the Windows Unicode rat-hole[ref + site="The Old New Thing" + page="What(‘s) a character!" + url=https://blogs.msdn.microsoft.com/oldnewthing/20070105-00/?p=28503][ref + site=MSDN + page="sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l" + url=https://msdn.microsoft.com/en-us/library/ce3zzk1k.aspx]] +[3:00:25][][:rant :speech][quote 625] +[3:00:45][:Run it successfully] +[3:01:10][@mmozeiko][Q: I think you need to also #define _UNICODE 1] +[3:01:59][Reflect on the progress of our standalone renderer][:speech] +[3:03:13][Make our :camera orbit the world] +[3:04:39][:Run it to see our 2D sprites rotating erroneously][:camera] +[3:06:34][Wind it down][:speech] +[/video]