Making a Simple Scene with the Separated Renderer
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:00Recap and set the stage for the day cleaning up the renderer's API
🗩
0:00Recap and set the stage for the day cleaning up the renderer's API
🗩
0:00Recap and set the stage for the day cleaning up the renderer's API
🗩
0:50Texture handling
🗩
0:50Texture handling
🗩
0:50Texture handling
🗩
3:38Texture atlases and mipmapping
🗩
3:38Texture atlases and mipmapping
🗩
3:38Texture atlases and mipmapping
🗩
6:30Our potential to lean on the streaming system for texture handling
🗩
6:30Our potential to lean on the streaming system for texture handling
🗩
6:30Our potential to lean on the streaming system for texture handling
🗩
9:03Keep Reminder.txt open
🗹
9:03Keep Reminder.txt open
🗹
9:03Keep Reminder.txt open
🗹
9:45Run the Renderer Test with the determination to render textured cubes and sprites
🏃
9:45Run the Renderer Test with the determination to render textured cubes and sprites
🏃
9:45Run the Renderer Test with the determination to render textured cubes and sprites
🏃
10:41Consult a screenshot of Hartacon Tactics1
📖
10:41Consult a screenshot of Hartacon Tactics1
📖
10:41Consult a screenshot of Hartacon Tactics1
📖
15:16Introduce PushSimpleScene()
15:16Introduce PushSimpleScene()
15:16Introduce PushSimpleScene()
20:14Run the Renderer Test to see our world of cubes
🏃
20:14Run the Renderer Test to see our world of cubes
🏃
20:14Run the Renderer Test to see our world of cubes
🏃
20:21Make PushSimpleScene() push blue cubes
20:21Make PushSimpleScene() push blue cubes
20:21Make PushSimpleScene() push blue cubes
20:57Run it to see our blue world
🏃
20:57Run it to see our blue world
🏃
20:57Run it to see our blue world
🏃
21:20Make our camera orbit the world
21:20Make our camera orbit the world
21:20Make our camera orbit the world
22:09Run it to see our orbiting perspective of the world
🏃
22:09Run it to see our orbiting perspective of the world
🏃
22:09Run it to see our orbiting perspective of the world
🏃
22:32Apply a texture to our cubes
22:32Apply a texture to our cubes
22:32Apply a texture to our cubes
28:43Enable OpenGLManageTextures() in handmade_renderer_opengl.cpp to fully manage the textures, introducing DequeuePending() and EnqueueFree() in handmade_renderer.h
28:43Enable OpenGLManageTextures() in handmade_renderer_opengl.cpp to fully manage the textures, introducing DequeuePending() and EnqueueFree() in handmade_renderer.h
28:43Enable OpenGLManageTextures() in handmade_renderer_opengl.cpp to fully manage the textures, introducing DequeuePending() and EnqueueFree() in handmade_renderer.h
35:05Wait-free vs ticketed mutex
🗩
35:05Wait-free vs ticketed mutex
🗩
35:05Wait-free vs ticketed mutex
🗩
35:57Finish implementing EnqueueFree() and OpenGLManageTextures()
35:57Finish implementing EnqueueFree() and OpenGLManageTextures()
35:57Finish implementing EnqueueFree() and OpenGLManageTextures()
41:21Run the game to see that we're not running okay
🏃
41:21Run the game to see that we're not running okay
🏃
41:21Run the game to see that we're not running okay
🏃
41:40Introduce InitTextureQueue() in handmade_renderer.h
41:40Introduce InitTextureQueue() in handmade_renderer.h
41:40Introduce InitTextureQueue() in handmade_renderer.h
45:36Run the game okay, with scepticism on this texture initialisation code
🏃
45:36Run the game okay, with scepticism on this texture initialisation code
🏃
45:36Run the game okay, with scepticism on this texture initialisation code
🏃
47:13Call OpenGLManageTextures() in win32_renderer_test.cpp
47:13Call OpenGLManageTextures() in win32_renderer_test.cpp
47:13Call OpenGLManageTextures() in win32_renderer_test.cpp
47:42Run the Renderer Test to see our textured cubes
🏃
47:42Run the Renderer Test to see our textured cubes
🏃
47:42Run the Renderer Test to see our textured cubes
🏃
48:36Select a tree and forest asset
🎨
48:36Select a tree and forest asset
🎨
48:36Select a tree and forest asset
🎨
52:41Change LoadBMP() to take a renderer_texture and load our forest tile into the test
52:41Change LoadBMP() to take a renderer_texture and load our forest tile into the test
52:41Change LoadBMP() to take a renderer_texture and load our forest tile into the test
55:15Run the test to see our textured ground
🏃
55:15Run the test to see our textured ground
🏃
55:15Run the test to see our textured ground
🏃
55:56Load our tree sprite into the test and enable PushSimpleScene() to sprinkle them around the scene
55:56Load our tree sprite into the test and enable PushSimpleScene() to sprinkle them around the scene
55:56Load our tree sprite into the test and enable PushSimpleScene() to sprinkle them around the scene
57:41Consider making PushBitmap() part of the renderer proper
🗩
57:41Consider making PushBitmap() part of the renderer proper
🗩
57:41Consider making PushBitmap() part of the renderer proper
🗩
59:10Introduce PushBitmap() in handmade_renderer.cpp
59:10Introduce PushBitmap() in handmade_renderer.cpp
59:10Introduce PushBitmap() in handmade_renderer.cpp
59:41Consider relieving PushBitmap() of the need to shrink bitmap borders in favour of making the software renderer upload textures into a bordered region
🗩
59:41Consider relieving PushBitmap() of the need to shrink bitmap borders in favour of making the software renderer upload textures into a bordered region
🗩
59:41Consider relieving PushBitmap() of the need to shrink bitmap borders in favour of making the software renderer upload textures into a bordered region
🗩
1:03:21Rename PushBitmap() to PushSprite() and clean it up
1:03:21Rename PushBitmap() to PushSprite() and clean it up
1:03:21Rename PushBitmap() to PushSprite() and clean it up
1:10:12Try making PushSimpleScene() call PushSprite() for our trees
1:10:12Try making PushSimpleScene() call PushSprite() for our trees
1:10:12Try making PushSimpleScene() call PushSprite() for our trees
1:11:34Run the Renderer Test, see no trees and step into PushSprite() to see what it's computing
🏃
1:11:34Run the Renderer Test, see no trees and step into PushSprite() to see what it's computing
🏃
1:11:34Run the Renderer Test, see no trees and step into PushSprite() to see what it's computing
🏃
1:12:53Prevent PushSimpleScene() from pushing cubes
1:12:53Prevent PushSimpleScene() from pushing cubes
1:12:53Prevent PushSimpleScene() from pushing cubes
1:13:06Run it to see our trees
🏃
1:13:06Run it to see our trees
🏃
1:13:06Run it to see our trees
🏃
1:13:12Enable PushSimpleScene() to elevate sprites above the cubes
1:13:12Enable PushSimpleScene() to elevate sprites above the cubes
1:13:12Enable PushSimpleScene() to elevate sprites above the cubes
1:14:08Run it to see our trees above the ground cubes
🏃
1:14:08Run it to see our trees above the ground cubes
🏃
1:14:08Run it to see our trees above the ground cubes
🏃
1:14:37Make PushSprite() centre the sprites on the cubes
1:14:37Make PushSprite() centre the sprites on the cubes
1:14:37Make PushSprite() centre the sprites on the cubes
1:15:44Run it to see our centred trees
🏃
1:15:44Run it to see our centred trees
🏃
1:15:44Run it to see our centred trees
🏃
1:15:55Grow the trees in PushSimpleScene() and scatter them randomly
1:15:55Grow the trees in PushSimpleScene() and scatter them randomly
1:15:55Grow the trees in PushSimpleScene() and scatter them randomly
1:16:23Run it to see our scattered trees
🏃
1:16:23Run it to see our scattered trees
🏃
1:16:23Run it to see our scattered trees
🏃
1:16:50Make the camera pan rather than orbit
1:16:50Make the camera pan rather than orbit
1:16:50Make the camera pan rather than orbit
1:21:43Run it to see our panning camera
🏃
1:21:43Run it to see our panning camera
🏃
1:21:43Run it to see our panning camera
🏃
1:22:31Widen the scene and shrink the trees in PushSimpleScene()
1:22:31Widen the scene and shrink the trees in PushSimpleScene()
1:22:31Widen the scene and shrink the trees in PushSimpleScene()
1:22:51Run it to see our scene, feeling like the trees aren't quite pegged to the centre
🏃
1:22:51Run it to see our scene, feeling like the trees aren't quite pegged to the centre
🏃
1:22:51Run it to see our scene, feeling like the trees aren't quite pegged to the centre
🏃
1:24:02Enable PushCube() to map our texture to the faces of the cube
1:24:02Enable PushCube() to map our texture to the faces of the cube
1:24:02Enable PushCube() to map our texture to the faces of the cube
1:28:51Run it to see our textured cubes, and reconsider the sprite centring
🏃
1:28:51Run it to see our textured cubes, and reconsider the sprite centring
🏃
1:28:51Run it to see our textured cubes, and reconsider the sprite centring
🏃
1:30:41Enable PushSimpleScene() to push Krampus' head and walls
1:30:41Enable PushSimpleScene() to push Krampus' head and walls
1:30:41Enable PushSimpleScene() to push Krampus' head and walls
1:34:15Check out our scene
1:34:15Check out our scene
1:34:15Check out our scene
1:34:33Make PushSimpleScene() position Krampus unit forwards and apply the correct texture to the walls
1:34:33Make PushSimpleScene() position Krampus unit forwards and apply the correct texture to the walls
1:34:33Make PushSimpleScene() position Krampus unit forwards and apply the correct texture to the walls
1:35:14Run it to see Z-fighting
🏃
1:35:14Run it to see Z-fighting
🏃
1:35:14Run it to see Z-fighting
🏃
1:35:30Make PushSimpleScene() elevate the walls above the ground by their radius
1:35:30Make PushSimpleScene() elevate the walls above the ground by their radius
1:35:30Make PushSimpleScene() elevate the walls above the ground by their radius
1:35:59Run it to see trees intersecting wall geometry
🏃
1:35:59Run it to see trees intersecting wall geometry
🏃
1:35:59Run it to see trees intersecting wall geometry
🏃
1:37:44Make PushSprite() bias the Z of upright sprites by their entire vertical size
1:37:44Make PushSprite() bias the Z of upright sprites by their entire vertical size
1:37:44Make PushSprite() bias the Z of upright sprites by their entire vertical size
1:37:56Run it to see how that looks
🏃
1:37:56Run it to see how that looks
🏃
1:37:56Run it to see how that looks
🏃
1:38:15Reduce the WallRadius in PushSimpleScene()
1:38:15Reduce the WallRadius in PushSimpleScene()
1:38:15Reduce the WallRadius in PushSimpleScene()
1:38:52Run it to see the trees more correctly occluding the walls
🏃
1:38:52Run it to see the trees more correctly occluding the walls
🏃
1:38:52Run it to see the trees more correctly occluding the walls
🏃
1:40:06Make PushSprite() render the sprites without modifying their axes
1:40:06Make PushSprite() render the sprites without modifying their axes
1:40:06Make PushSprite() render the sprites without modifying their axes
1:41:07Run it to see the trees standing perfectly upright, but looking like cardboard cutouts
🏃
1:41:07Run it to see the trees standing perfectly upright, but looking like cardboard cutouts
🏃
1:41:07Run it to see the trees standing perfectly upright, but looking like cardboard cutouts
🏃
1:41:47Enable PushSprite() to lerp between modified axes
1:41:47Enable PushSprite() to lerp between modified axes
1:41:47Enable PushSprite() to lerp between modified axes
1:42:11Run it to see that it looks quite nice from this perspective
🏃
1:42:11Run it to see that it looks quite nice from this perspective
🏃
1:42:11Run it to see that it looks quite nice from this perspective
🏃
1:43:40Increase the camera pitch and bias the lerp towards the correct axes
1:43:40Increase the camera pitch and bias the lerp towards the correct axes
1:43:40Increase the camera pitch and bias the lerp towards the correct axes
1:45:48Check out how that looks
🏃
1:45:48Check out how that looks
🏃
1:45:48Check out how that looks
🏃
1:47:47Play with the camera focal length, pitch and position
1:47:47Play with the camera focal length, pitch and position
1:47:47Play with the camera focal length, pitch and position
1:52:13Run it to see everything stacking nicely
🏃
1:52:13Run it to see everything stacking nicely
🏃
1:52:13Run it to see everything stacking nicely
🏃
1:53:20Create win32_renderer_test.h and introduce test_scene struct, InitTestScene() and PlaceRandom()
1:53:20Create win32_renderer_test.h and introduce test_scene struct, InitTestScene() and PlaceRandom()
1:53:20Create win32_renderer_test.h and introduce test_scene struct, InitTestScene() and PlaceRandom()
2:04:20Run it to see our well-spaced scene
🏃
2:04:20Run it to see our well-spaced scene
🏃
2:04:20Run it to see our well-spaced scene
🏃
2:05:08Fix PlaceRandom() to space elements out more
2:05:08Fix PlaceRandom() to space elements out more
2:05:08Fix PlaceRandom() to space elements out more
2:05:23Run it to see our even better-spaced scene
🏃
2:05:23Run it to see our even better-spaced scene
🏃
2:05:23Run it to see our even better-spaced scene
🏃
2:06:42Q&A
🗩
2:06:42Q&A
🗩
2:06:42Q&A
🗩
2:06:52quote_corn_if_brother Q: Are we going to do anything special on Day 500?
🗪
2:06:52quote_corn_if_brother Q: Are we going to do anything special on Day 500?
🗪
2:06:52quote_corn_if_brother Q: Are we going to do anything special on Day 500?
🗪
2:07:40vateferfout Q: The right side of the walls seems to be flipped vertically, I guess it's because of the UV ordering
🗪
2:07:40vateferfout Q: The right side of the walls seems to be flipped vertically, I guess it's because of the UV ordering
🗪
2:07:40vateferfout Q: The right side of the walls seems to be flipped vertically, I guess it's because of the UV ordering
🗪
2:07:53somebody_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)
🗪
2:07:53somebody_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)
🗪
2:07:53somebody_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)
🗪
2:08:10Fix EnqueueFree() to set the Queue->FirstFree
2:08:10Fix EnqueueFree() to set the Queue->FirstFree
2:08:10Fix EnqueueFree() to set the Queue->FirstFree
2:09:39Fix PushCube() to map our texture to the correct faces of the cube
2:09:39Fix PushCube() to map our texture to the correct faces of the cube
2:09:39Fix PushCube() to map our texture to the correct faces of the cube
2:12:48Run it to see that our wall textures look good
🏃
2:12:48Run it to see that our wall textures look good
🏃
2:12:48Run it to see that our wall textures look good
🏃
2:14:05vaualbus Q: So I missed the stream today. What have we done with the texture generation today?
🗪
2:14:05vaualbus Q: So I missed the stream today. What have we done with the texture generation today?
🗪
2:14:05vaualbus Q: So I missed the stream today. What have we done with the texture generation today?
🗪
2:14:59filiadelski Q: Are we done with the renderer or will we maintain both versions?
🗪
2:14:59filiadelski Q: Are we done with the renderer or will we maintain both versions?
🗪
2:14:59filiadelski Q: Are we done with the renderer or will we maintain both versions?
🗪
2:15:43jim0_o Q: Handmade Hero will be using this decoupled renderer, right?
🗪
2:15:43jim0_o Q: Handmade Hero will be using this decoupled renderer, right?
🗪
2:15:43jim0_o Q: Handmade Hero will be using this decoupled renderer, right?
🗪
2:16:11cirdanvalen 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?
🗪
2:16:11cirdanvalen 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?
🗪
2:16:11cirdanvalen 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?
🗪
2:17:20filiadelski Q: I assumed we weren't going to use the decoupled version, but that makes sense
🗪
2:17:20filiadelski Q: I assumed we weren't going to use the decoupled version, but that makes sense
🗪
2:17:20filiadelski Q: I assumed we weren't going to use the decoupled version, but that makes sense
🗪
2:18:47Build the game in -O2
2:18:47Build the game in -O2
2:18:47Build the game in -O2
2:19:04Run the renderer test
🏃
2:19:04Run the renderer test
🏃
2:19:04Run the renderer test
🏃
2:19:24jim0_o Q: Would it be too much to attach the profiling stuff to just see the FPS etc?
🗪
2:19:24jim0_o Q: Would it be too much to attach the profiling stuff to just see the FPS etc?
🗪
2:19:24jim0_o Q: Would it be too much to attach the profiling stuff to just see the FPS etc?
🗪
2:19:36Enable win32_renderer_test.cpp to print the milliseconds per frame
2:19:36Enable win32_renderer_test.cpp to print the milliseconds per frame
2:19:36Enable win32_renderer_test.cpp to print the milliseconds per frame
2:24:20Run it to see our milliseconds per frame
🏃
2:24:20Run it to see our milliseconds per frame
🏃
2:24:20Run it to see our milliseconds per frame
🏃
2:24:55Reduce the TEST_SCENE_DIM_Y
2:24:55Reduce the TEST_SCENE_DIM_Y
2:24:55Reduce the TEST_SCENE_DIM_Y
2:25:27Run it to see our still-variable frame rate
🏃
2:25:27Run it to see our still-variable frame rate
🏃
2:25:27Run it to see our still-variable frame rate
🏃
2:26:02Increase the TEST_SCENE_DIM_Y
2:26:02Increase the TEST_SCENE_DIM_Y
2:26:02Increase the TEST_SCENE_DIM_Y
2:26:16Run it to see our just-as-variable frame rate
🏃
2:26:16Run it to see our just-as-variable frame rate
🏃
2:26:16Run it to see our just-as-variable frame rate
🏃
2:26:48neitchzehrer Q: Did you update 4coder yesterday (if necessary)?
🗪
2:26:48neitchzehrer Q: Did you update 4coder yesterday (if necessary)?
🗪
2:26:48neitchzehrer Q: Did you update 4coder yesterday (if necessary)?
🗪
2:26:52Check our rendering performance
🏃
2:26:52Check our rendering performance
🏃
2:26:52Check our rendering performance
🏃
2:28:13filiadelski Q: Why do the frames drop so badly when moving the window? Does Windows spam the process with messages or something?
🗪
2:28:13filiadelski Q: Why do the frames drop so badly when moving the window? Does Windows spam the process with messages or something?
🗪
2:28:13filiadelski Q: Why do the frames drop so badly when moving the window? Does Windows spam the process with messages or something?
🗪
2:30:04Enable win32_renderer_test.cpp to create a thread for the rendering separate from Windows' message processing
2:30:04Enable win32_renderer_test.cpp to create a thread for the rendering separate from Windows' message processing
2:30:04Enable win32_renderer_test.cpp to create a thread for the rendering separate from Windows' message processing
2:34:25Run it and reconsider our rendering performance
🏃
2:34:25Run it and reconsider our rendering performance
🏃
2:34:25Run it and reconsider our rendering performance
🏃
2:36:31nickito97 Q: What is volatile?
🗪
2:36:31nickito97 Q: What is volatile?
🗪
2:36:31nickito97 Q: What is volatile?
🗪
2:39:21mmozeiko Q: Now the main thread should use GetMessage(), not PeekMessage(), to save on CPU
🗪
2:39:21mmozeiko Q: Now the main thread should use GetMessage(), not PeekMessage(), to save on CPU
🗪
2:39:21mmozeiko Q: Now the main thread should use GetMessage(), not PeekMessage(), to save on CPU
🗪
2:39:41Change win32_renderer_test.cpp to use GetMessage()2
2:39:41Change win32_renderer_test.cpp to use GetMessage()2
2:39:41Change win32_renderer_test.cpp to use GetMessage()2
2:42:54pythno 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
🗪
2:42:54pythno 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
🗪
2:42:54pythno 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
🗪
2:44:14mmozeiko Q: GetMessage should be GetMessageA
🗪
2:44:14mmozeiko Q: GetMessage should be GetMessageA
🗪
2:44:14mmozeiko Q: GetMessage should be GetMessageA
🗪
2:44:40Remove all the "A" function-name suffixes
2:44:40Remove all the "A" function-name suffixes
2:44:40Remove all the "A" function-name suffixes
2:46:47mmozeiko 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 Handmade Hero code in Visual Studio projects
🗪
2:46:47mmozeiko 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 Handmade Hero code in Visual Studio projects
🗪
2:46:47mmozeiko 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 Handmade Hero code in Visual Studio projects
🗪
2:47:16Embark on Windows Unicode string handling
2:47:16Embark on Windows Unicode string handling
2:47:16Embark on Windows Unicode string handling
2:51:26mmozeiko Q: Try to #define UNICODE at top of file, to see if the compiler is happy
🗪
2:51:26mmozeiko Q: Try to #define UNICODE at top of file, to see if the compiler is happy
🗪
2:51:26mmozeiko Q: Try to #define UNICODE at top of file, to see if the compiler is happy
🗪
2:51:32Try to #define UNICODE and continue down the Windows Unicode rat-hole3,4
2:51:32Try to #define UNICODE and continue down the Windows Unicode rat-hole3,4
2:51:32Try to #define UNICODE and continue down the Windows Unicode rat-hole3,4
3:00:25“So, great, good, fantastic, nice work. Great job, Microsoft, as always crushing it”α
💢
🗩
3:00:25“So, great, good, fantastic, nice work. Great job, Microsoft, as always crushing it”α
💢
🗩
3:00:25“So, great, good, fantastic, nice work. Great job, Microsoft, as always crushing it”α
💢
🗩
3:00:45Run it successfully
🏃
3:00:45Run it successfully
🏃
3:00:45Run it successfully
🏃
3:01:10mmozeiko Q: I think you need to also #define _UNICODE 1
🗪
3:01:10mmozeiko Q: I think you need to also #define _UNICODE 1
🗪
3:01:10mmozeiko Q: I think you need to also #define _UNICODE 1
🗪
3:01:59Reflect on the progress of our standalone renderer
🗩
3:01:59Reflect on the progress of our standalone renderer
🗩
3:01:59Reflect on the progress of our standalone renderer
🗩
3:03:13Make our camera orbit the world
3:03:13Make our camera orbit the world
3:03:13Make our camera orbit the world
3:04:39Run it to see our 2D sprites rotating erroneously
🏃
3:04:39Run it to see our 2D sprites rotating erroneously
🏃
3:04:39Run it to see our 2D sprites rotating erroneously
🏃
3:06:34Wind it down
🗩
3:06:34Wind it down
🗩
3:06:34Wind it down
🗩