Handmade Hero»Episode Guide
Solving for Debug Camera Parameters
?
?

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
🗩
0:00Recap and set the stage for the day
🗩
0:00Recap and set the stage for the day
🗩
2:34Demo our world level / elevation fogging, and our need for a rigorous Z-bias solution
🏃
2:34Demo our world level / elevation fogging, and our need for a rigorous Z-bias solution
🏃
2:34Demo our world level / elevation fogging, and our need for a rigorous Z-bias solution
🏃
5:52Z Occlusion
🖌
5:52Z Occlusion
🖌
5:52Z Occlusion
🖌
10:07Keeping Z, sliding forward in Y and tilting backwards
🖌
10:07Keeping Z, sliding forward in Y and tilting backwards
🖌
10:07Keeping Z, sliding forward in Y and tilting backwards
🖌
13:06Set up to get our debug camera in good shape to develop our Z occlusion solution
🖌
13:06Set up to get our debug camera in good shape to develop our Z occlusion solution
🖌
13:06Set up to get our debug camera in good shape to develop our Z occlusion solution
🖌
14:44Demo the garbage debug camera
🏃
14:44Demo the garbage debug camera
🏃
14:44Demo the garbage debug camera
🏃
15:57Show off the title screen
🏃
15:57Show off the title screen
🏃
15:57Show off the title screen
🏃
16:29Reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
16:29Reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
16:29Reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
19:17Set up UpdateAndRenderWorld() to handle debug camera panning, and more clearly set the Debug and Regular clip planes
19:17Set up UpdateAndRenderWorld() to handle debug camera panning, and more clearly set the Debug and Regular clip planes
19:17Set up UpdateAndRenderWorld() to handle debug camera panning, and more clearly set the Debug and Regular clip planes
21:24Continue to reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
21:24Continue to reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
21:24Continue to reacquaint ourselves with the debug camera code in UpdateAndRenderWorld()
📖
23:47Temporarily make PlayWorld() set the DebugCameraDolly
23:47Temporarily make PlayWorld() set the DebugCameraDolly
23:47Temporarily make PlayWorld() set the DebugCameraDolly
24:47Find that the debug camera is now restored
🏃
24:47Find that the debug camera is now restored
🏃
24:47Find that the debug camera is now restored
🏃
25:03Set up UpdateAndRenderWorld() to position the debug camera to match the regular camera
25:03Set up UpdateAndRenderWorld() to position the debug camera to match the regular camera
25:03Set up UpdateAndRenderWorld() to position the debug camera to match the regular camera
29:52Reconstructing a camera's dolly, orbit and pitch from a point1
🖌
29:52Reconstructing a camera's dolly, orbit and pitch from a point1
🖌
29:52Reconstructing a camera's dolly, orbit and pitch from a point1
🖌
37:14Make UpdateAndRenderWorld() reconstruct the debug camera's dolly from the regular camera's position
37:14Make UpdateAndRenderWorld() reconstruct the debug camera's dolly from the regular camera's position
37:14Make UpdateAndRenderWorld() reconstruct the debug camera's dolly from the regular camera's position
41:33Using the inner product to isolate the position of a point on only one axis
🖌
41:33Using the inner product to isolate the position of a point on only one axis
🖌
41:33Using the inner product to isolate the position of a point on only one axis
🖌
42:49Add CameraPan to game_mode_world for UpdateAndRenderWorld() to compute
42:49Add CameraPan to game_mode_world for UpdateAndRenderWorld() to compute
42:49Add CameraPan to game_mode_world for UpdateAndRenderWorld() to compute
45:16Make UpdateAndRenderWorld() reconstruct the debug camera's orbit and pitch using ATan2()
45:16Make UpdateAndRenderWorld() reconstruct the debug camera's orbit and pitch using ATan2()
45:16Make UpdateAndRenderWorld() reconstruct the debug camera's orbit and pitch using ATan2()
47:20atan2 assumes that our starting vector points along x
🖌
47:20atan2 assumes that our starting vector points along x
🖌
47:20atan2 assumes that our starting vector points along x
🖌
49:57Change UpdateAndRenderWorld() to feed an x-pointing vector to atan2
49:57Change UpdateAndRenderWorld() to feed an x-pointing vector to atan2
49:57Change UpdateAndRenderWorld() to feed an x-pointing vector to atan2
52:37Crash in FindAlign() with an "Access violation" error
🏃
52:37Crash in FindAlign() with an "Access violation" error
🏃
52:37Crash in FindAlign() with an "Access violation" error
🏃
53:44Find that the debug camera is wrong
🏃
53:44Find that the debug camera is wrong
🏃
53:44Find that the debug camera is wrong
🏃
54:03Scrutinise our debug camera construction in UpdateAndRenderWorld()
📖
54:03Scrutinise our debug camera construction in UpdateAndRenderWorld()
📖
54:03Scrutinise our debug camera construction in UpdateAndRenderWorld()
📖
57:15Make UpdateAndRenderWorld() compute separate debug camera values to aid debugging
57:15Make UpdateAndRenderWorld() compute separate debug camera values to aid debugging
57:15Make UpdateAndRenderWorld() compute separate debug camera values to aid debugging
59:11Step in to UpdateAndRenderWorld() and inspect our debug camera values
🏃
59:11Step in to UpdateAndRenderWorld() and inspect our debug camera values
🏃
59:11Step in to UpdateAndRenderWorld() and inspect our debug camera values
🏃
1:05:46Fix the winding of the DebugCameraPitch computation in UpdateAndRenderWorld()
1:05:46Fix the winding of the DebugCameraPitch computation in UpdateAndRenderWorld()
1:05:46Fix the winding of the DebugCameraPitch computation in UpdateAndRenderWorld()
1:09:40Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:09:40Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:09:40Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:10:20Fix the DebugCamera0 computation to use an XRotation(), and negate the PlanarArm length in the DebugCameraPitch computation
1:10:20Fix the DebugCamera0 computation to use an XRotation(), and negate the PlanarArm length in the DebugCameraPitch computation
1:10:20Fix the DebugCamera0 computation to use an XRotation(), and negate the PlanarArm length in the DebugCameraPitch computation
1:11:08Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:11:08Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:11:08Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:12:11Refrain from negating the PlanarArm length in the DebugCameraPitch computation
1:12:11Refrain from negating the PlanarArm length in the DebugCameraPitch computation
1:12:11Refrain from negating the PlanarArm length in the DebugCameraPitch computation
1:12:23Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:12:23Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:12:23Step back in to UpdateAndRenderWorld() and inspect our DebugCameraPitch
🏃
1:12:58Find that our orbit is −90° off
🏃
1:12:58Find that our orbit is −90° off
🏃
1:12:58Find that our orbit is −90° off
🏃
1:13:14Fix the DebugCameraOrbit computation
1:13:14Fix the DebugCameraOrbit computation
1:13:14Fix the DebugCameraOrbit computation
1:14:32Find that our debug camera is now correct
🏃
1:14:32Find that our debug camera is now correct
🏃
1:14:32Find that our debug camera is now correct
🏃
1:15:28Invert the mouse's X-axis in UpdateAndRenderWorld()
1:15:28Invert the mouse's X-axis in UpdateAndRenderWorld()
1:15:28Invert the mouse's X-axis in UpdateAndRenderWorld()
1:15:47Try out our perfect debug camera
🏃
1:15:47Try out our perfect debug camera
🏃
1:15:47Try out our perfect debug camera
🏃
1:16:28Naively make UpdateAndRenderWorld() to handle debug camera panning
1:16:28Naively make UpdateAndRenderWorld() to handle debug camera panning
1:16:28Naively make UpdateAndRenderWorld() to handle debug camera panning
1:17:26Try our newly panning debug camera
🏃
1:17:26Try our newly panning debug camera
🏃
1:17:26Try our newly panning debug camera
🏃
1:17:46Invert the panning axes in UpdateAndRenderWorld()
1:17:46Invert the panning axes in UpdateAndRenderWorld()
1:17:46Invert the panning axes in UpdateAndRenderWorld()
1:17:59Try our newly panning debug camera, noting that it breaks when the orbits of our debug and regular cameras are not aligned
🏃
1:17:59Try our newly panning debug camera, noting that it breaks when the orbits of our debug and regular cameras are not aligned
🏃
1:17:59Try our newly panning debug camera, noting that it breaks when the orbits of our debug and regular cameras are not aligned
🏃
1:18:46Enable UpdateAndRenderWorld() to pan the camera in camera-space
1:18:46Enable UpdateAndRenderWorld() to pan the camera in camera-space
1:18:46Enable UpdateAndRenderWorld() to pan the camera in camera-space
1:20:45Show our camera panning in camera-space
🏃
1:20:45Show our camera panning in camera-space
🏃
1:20:45Show our camera panning in camera-space
🏃
1:21:13Find that we are inverting the mouse's Y axis
📖
1:21:13Find that we are inverting the mouse's Y axis
📖
1:21:13Find that we are inverting the mouse's Y axis
📖
1:22:17Note the correctness of our panning
🏃
1:22:17Note the correctness of our panning
🏃
1:22:17Note the correctness of our panning
🏃
1:22:45Make UpdateAndRenderWorld() invert our panning and scale its speed by the camera's distance from the subject
1:22:45Make UpdateAndRenderWorld() invert our panning and scale its speed by the camera's distance from the subject
1:22:45Make UpdateAndRenderWorld() invert our panning and scale its speed by the camera's distance from the subject
1:23:40Try out our distance-proportional panning camera
🏃
1:23:40Try out our distance-proportional panning camera
🏃
1:23:40Try out our distance-proportional panning camera
🏃
1:25:28Take a close look at our sprites in preparation to try our Z occlusion solution
🏃
1:25:28Take a close look at our sprites in preparation to try our Z occlusion solution
🏃
1:25:28Take a close look at our sprites in preparation to try our Z occlusion solution
🏃
1:27:59Reacquaint ourselves with SpriteValuesForUpright()
📖
1:27:59Reacquaint ourselves with SpriteValuesForUpright()
📖
1:27:59Reacquaint ourselves with SpriteValuesForUpright()
📖
1:30:21Remove ZBias from SpriteValuesForUpright()
1:30:21Remove ZBias from SpriteValuesForUpright()
1:30:21Remove ZBias from SpriteValuesForUpright()
1:30:32Find that we draw just fine without the ZBias
🏃
1:30:32Find that we draw just fine without the ZBias
🏃
1:30:32Find that we draw just fine without the ZBias
🏃
1:30:44Temporarily make SpriteValuesForUpright() displace the sprites in Y
1:30:44Temporarily make SpriteValuesForUpright() displace the sprites in Y
1:30:44Temporarily make SpriteValuesForUpright() displace the sprites in Y
1:32:33Check out our displaced entities and adjust the alignment points to find that we are displacing in the wrong direction
🏃
1:32:33Check out our displaced entities and adjust the alignment points to find that we are displacing in the wrong direction
🏃
1:32:33Check out our displaced entities and adjust the alignment points to find that we are displacing in the wrong direction
🏃
1:33:17Change SpriteValuesForUpright() to use the (not inverted) WorldDim.y in the sprite displacement
1:33:17Change SpriteValuesForUpright() to use the (not inverted) WorldDim.y in the sprite displacement
1:33:17Change SpriteValuesForUpright() to use the (not inverted) WorldDim.y in the sprite displacement
1:33:44Align the hero's body and head, and find that we now sort beautifully (i.e. no penetration with walls), except during hopping which we are erroneously performing in Y
🏃
1:33:44Align the hero's body and head, and find that we now sort beautifully (i.e. no penetration with walls), except during hopping which we are erroneously performing in Y
🏃
1:33:44Align the hero's body and head, and find that we now sort beautifully (i.e. no penetration with walls), except during hopping which we are erroneously performing in Y
🏃
1:37:25Make UpdateAndRenderEntities() hop the entities in Z
1:37:25Make UpdateAndRenderEntities() hop the entities in Z
1:37:25Make UpdateAndRenderEntities() hop the entities in Z
1:39:07Check out our Z-hopping entities, to find that our hero never penetrates walls
🏃
1:39:07Check out our Z-hopping entities, to find that our hero never penetrates walls
🏃
1:39:07Check out our Z-hopping entities, to find that our hero never penetrates walls
🏃
1:40:26Q&A
🗩
1:40:26Q&A
🗩
1:40:26Q&A
🗩
1:41:35Brian Q: You uploaded the last episode as episode 520, instead of 519
🗪
1:41:35Brian Q: You uploaded the last episode as episode 520, instead of 519
🗪
1:41:35Brian Q: You uploaded the last episode as episode 520, instead of 519
🗪
1:42:17recyrillic Q: Are we gonna switch to remedybg for Handmade Hero soon?
🗪
1:42:17recyrillic Q: Are we gonna switch to remedybg for Handmade Hero soon?
🗪
1:42:17recyrillic Q: Are we gonna switch to remedybg for Handmade Hero soon?
🗪
1:43:41garryjohanson Q: So one of the reasons I became briefly enthusiastic about WinDBG Preview is the ability to record a trace of a running program and then send that trace to someone else and they can look at the exact debug session you were looking at, rather than having to reproduce a bug spending possibly a long period of time. To me that sounds like a silver bullet way to reproduce a bug. Can you think of any reason why I would be wrong to conclude that the feature is a silver bullet for reproducing bugs?
🗪
1:43:41garryjohanson Q: So one of the reasons I became briefly enthusiastic about WinDBG Preview is the ability to record a trace of a running program and then send that trace to someone else and they can look at the exact debug session you were looking at, rather than having to reproduce a bug spending possibly a long period of time. To me that sounds like a silver bullet way to reproduce a bug. Can you think of any reason why I would be wrong to conclude that the feature is a silver bullet for reproducing bugs?
🗪
1:43:41garryjohanson Q: So one of the reasons I became briefly enthusiastic about WinDBG Preview is the ability to record a trace of a running program and then send that trace to someone else and they can look at the exact debug session you were looking at, rather than having to reproduce a bug spending possibly a long period of time. To me that sounds like a silver bullet way to reproduce a bug. Can you think of any reason why I would be wrong to conclude that the feature is a silver bullet for reproducing bugs?
🗪
1:46:27ingenero Q: So far it seems all the animation is done programatically, moving static sprites. Is there any plan to include pre-set or artist-created animations?
🗪
1:46:27ingenero Q: So far it seems all the animation is done programatically, moving static sprites. Is there any plan to include pre-set or artist-created animations?
🗪
1:46:27ingenero Q: So far it seems all the animation is done programatically, moving static sprites. Is there any plan to include pre-set or artist-created animations?
🗪
1:47:30pythno Q: I studied the rendering code for a bit and it seems that the vertices and indices for the cubes (and quads) are generated each frame on the CPU and put into a big VBO which is set to stream_draw. Is this correct and, if yes, what was the decision to do it that way and not even using VAOs? For big models with a lot of polygons would you go a different route?
🗪
1:47:30pythno Q: I studied the rendering code for a bit and it seems that the vertices and indices for the cubes (and quads) are generated each frame on the CPU and put into a big VBO which is set to stream_draw. Is this correct and, if yes, what was the decision to do it that way and not even using VAOs? For big models with a lot of polygons would you go a different route?
🗪
1:47:30pythno Q: I studied the rendering code for a bit and it seems that the vertices and indices for the cubes (and quads) are generated each frame on the CPU and put into a big VBO which is set to stream_draw. Is this correct and, if yes, what was the decision to do it that way and not even using VAOs? For big models with a lot of polygons would you go a different route?
🗪
1:49:31vapenir Q: What's your take on profilers vs. DIY in-game profiling? What are some decent profilers that you know of or have used?
🗪
1:49:31vapenir Q: What's your take on profilers vs. DIY in-game profiling? What are some decent profilers that you know of or have used?
🗪
1:49:31vapenir Q: What's your take on profilers vs. DIY in-game profiling? What are some decent profilers that you know of or have used?
🗪
1:51:05pkey1 Q: What you think about python?
🗪
1:51:05pkey1 Q: What you think about python?
🗪
1:51:05pkey1 Q: What you think about python?
🗪
1:52:16lucid_frost Q: Do you think there is any value in keeping the concept of registers in the higher level language?
🗪
1:52:16lucid_frost Q: Do you think there is any value in keeping the concept of registers in the higher level language?
🗪
1:52:16lucid_frost Q: Do you think there is any value in keeping the concept of registers in the higher level language?
🗪
1:52:39friedhit Q: How do you feel about dynamically-typed languages?
🗪
1:52:39friedhit Q: How do you feel about dynamically-typed languages?
🗪
1:52:39friedhit Q: How do you feel about dynamically-typed languages?
🗪
1:53:08useless_pony Q: I may have asked this before, but have you looked at ponylang? If so, what are your thoughts on it?
🗪
1:53:08useless_pony Q: I may have asked this before, but have you looked at ponylang? If so, what are your thoughts on it?
🗪
1:53:08useless_pony Q: I may have asked this before, but have you looked at ponylang? If so, what are your thoughts on it?
🗪
1:53:46vapenir Q: Does the game load levels from files, and do you plan to include a level editor with the final game?
🗪
1:53:46vapenir Q: Does the game load levels from files, and do you plan to include a level editor with the final game?
🗪
1:53:46vapenir Q: Does the game load levels from files, and do you plan to include a level editor with the final game?
🗪
1:55:20Deep thoughts on modern languages like PLISK, StopLang and ZnO, and their cutting edge provision for memory composting
🗩
1:55:20Deep thoughts on modern languages like PLISK, StopLang and ZnO, and their cutting edge provision for memory composting
🗩
1:55:20Deep thoughts on modern languages like PLISK, StopLang and ZnO, and their cutting edge provision for memory composting
🗩
2:01:34Wrap it up for the day
🗩
2:01:34Wrap it up for the day
🗩
2:01:34Wrap it up for the day
🗩