Handmade Hero»Episode Guide
OpenGL Projection Matrices Revisited
?
?

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:03Recap and set the stage for the day
0:03Recap and set the stage for the day
0:03Recap and set the stage for the day
4:25A few words on what "stepping through GPU code" entails
4:25A few words on what "stepping through GPU code" entails
4:25A few words on what "stepping through GPU code" entails
8:59Run the game to see our 2D pipeline running, and determine to remove the screen-space transform
8:59Run the game to see our 2D pipeline running, and determine to remove the screen-space transform
8:59Run the game to see our 2D pipeline running, and determine to remove the screen-space transform
10:13handmade_render_group.cpp: Look at how GetRenderEntityBasisP() transforms the world coordinates into screen coordinates
10:13handmade_render_group.cpp: Look at how GetRenderEntityBasisP() transforms the world coordinates into screen coordinates
10:13handmade_render_group.cpp: Look at how GetRenderEntityBasisP() transforms the world coordinates into screen coordinates
12:50handmade_opengl.cpp: Look at how OpenGLSetScreenSpace() works and fits into the pipeline
12:50handmade_opengl.cpp: Look at how OpenGLSetScreenSpace() works and fits into the pipeline
12:50handmade_opengl.cpp: Look at how OpenGLSetScreenSpace() works and fits into the pipeline
13:46"We're going to go over that in very excruciating detail in a moment"1α
13:46"We're going to go over that in very excruciating detail in a moment"1α
13:46"We're going to go over that in very excruciating detail in a moment"1α
16:12Blackboard: Projection Matrix
16:12Blackboard: Projection Matrix
16:12Blackboard: Projection Matrix
19:43On "column major" vs "row major", and defining an array in C or C++
19:43On "column major" vs "row major", and defining an array in C or C++
19:43On "column major" vs "row major", and defining an array in C or C++
22:49Blackboard: What our projection matrix is doing
22:49Blackboard: What our projection matrix is doing
22:49Blackboard: What our projection matrix is doing
24:28Blackboard: Homogeneous matrix
24:28Blackboard: Homogeneous matrix
24:28Blackboard: Homogeneous matrix
25:56Blackboard: Matrix multiply
25:56Blackboard: Matrix multiply
25:56Blackboard: Matrix multiply
30:04Blackboard: |xyz1| == point; |xyz0| == vector
30:04Blackboard: |xyz1| == point; |xyz0| == vector
30:04Blackboard: |xyz1| == point; |xyz0| == vector
34:12Blackboard: More on what our "projection" matrix is doing
34:12Blackboard: More on what our "projection" matrix is doing
34:12Blackboard: More on what our "projection" matrix is doing
37:55Blackboard: Why OpenGL operates in a -1 to 1 space
37:55Blackboard: Why OpenGL operates in a -1 to 1 space
37:55Blackboard: Why OpenGL operates in a -1 to 1 space
39:01Blackboard: Clipping
39:01Blackboard: Clipping
39:01Blackboard: Clipping
42:20Illustrate "texture warping"2
42:20Illustrate "texture warping"2
42:20Illustrate "texture warping"2
43:03Blackboard: On the necessity for correct sub-pixel fill and texture coordinate picking
43:03Blackboard: On the necessity for correct sub-pixel fill and texture coordinate picking
43:03Blackboard: On the necessity for correct sub-pixel fill and texture coordinate picking
46:25Blackboard: How OpenGL handles its coordinates system: bilateral unit cube
46:25Blackboard: How OpenGL handles its coordinates system: bilateral unit cube
46:25Blackboard: How OpenGL handles its coordinates system: bilateral unit cube
48:49"As is the rule on Handmade Hero: I never get to do any preparation"β
48:49"As is the rule on Handmade Hero: I never get to do any preparation"β
48:49"As is the rule on Handmade Hero: I never get to do any preparation"β
50:15Blackboard: Transforming from "clip space" to "window space"3
50:15Blackboard: Transforming from "clip space" to "window space"3
50:15Blackboard: Transforming from "clip space" to "window space"3
53:56Consult the OpenGL 2.0 specification4
53:56Consult the OpenGL 2.0 specification4
53:56Consult the OpenGL 2.0 specification4
55:23Blackboard: Fix up the terminology in accordance with the OpenGL spec
55:23Blackboard: Fix up the terminology in accordance with the OpenGL spec
55:23Blackboard: Fix up the terminology in accordance with the OpenGL spec
58:01Blackboard: Perspective projection
58:01Blackboard: Perspective projection
58:01Blackboard: Perspective projection
1:00:32Blackboard: Projecting to the screen using a relationship of similar triangles
1:00:32Blackboard: Projecting to the screen using a relationship of similar triangles
1:00:32Blackboard: Projecting to the screen using a relationship of similar triangles
1:02:37Blackboard: Matrix multiplication doesn't allow for dividing
1:02:37Blackboard: Matrix multiplication doesn't allow for dividing
1:02:37Blackboard: Matrix multiplication doesn't allow for dividing
1:05:14Blackboard: How OpenGL provides for one divide operation, normalisation of the vector by its w coordinate, in order to compute correct perspective
1:05:14Blackboard: How OpenGL provides for one divide operation, normalisation of the vector by its w coordinate, in order to compute correct perspective
1:05:14Blackboard: How OpenGL provides for one divide operation, normalisation of the vector by its w coordinate, in order to compute correct perspective
1:08:00Blackboard: Implementing our own perspective projection and why we compute z
1:08:00Blackboard: Implementing our own perspective projection and why we compute z
1:08:00Blackboard: Implementing our own perspective projection and why we compute z
1:10:11Double-check the OpenGL spec on coordinate transformations5
1:10:11Double-check the OpenGL spec on coordinate transformations5
1:10:11Double-check the OpenGL spec on coordinate transformations5
1:13:03Blackboard: Performing the near plane clipping before moving into the -1 to 1 space
1:13:03Blackboard: Performing the near plane clipping before moving into the -1 to 1 space
1:13:03Blackboard: Performing the near plane clipping before moving into the -1 to 1 space
1:16:33Blackboard: Recap what our perspective transform must accomplish
1:16:33Blackboard: Recap what our perspective transform must accomplish
1:16:33Blackboard: Recap what our perspective transform must accomplish
1:19:30Blackboard: The Z-buffer and near and far clip planes
1:19:30Blackboard: The Z-buffer and near and far clip planes
1:19:30Blackboard: The Z-buffer and near and far clip planes
1:21:56Further reading: W-buffer; infinite far clip plane; disable far clip plane
1:21:56Further reading: W-buffer; infinite far clip plane; disable far clip plane
1:21:56Further reading: W-buffer; infinite far clip plane; disable far clip plane
1:23:46Blackboard: Camera space, and getting the effects we want out of the projection matrix
1:23:46Blackboard: Camera space, and getting the effects we want out of the projection matrix
1:23:46Blackboard: Camera space, and getting the effects we want out of the projection matrix
1:26:47handmade_render_group.cpp: Consider how our perspective transform is currently happening
1:26:47handmade_render_group.cpp: Consider how our perspective transform is currently happening
1:26:47handmade_render_group.cpp: Consider how our perspective transform is currently happening
1:30:04handmade_opengl.cpp: Temporarily make OpenGLSetScreenSpace() calculate the height dimension based on the width and run the game to see what that does
1:30:04handmade_opengl.cpp: Temporarily make OpenGLSetScreenSpace() calculate the height dimension based on the width and run the game to see what that does
1:30:04handmade_opengl.cpp: Temporarily make OpenGLSetScreenSpace() calculate the height dimension based on the width and run the game to see what that does
1:31:14handmade_render_group.cpp: Prevent GetRenderEntityBasisP() from adding CameraTransform->ScreenCenter to the Perspective computation, and run the game to see what that has done
1:31:14handmade_render_group.cpp: Prevent GetRenderEntityBasisP() from adding CameraTransform->ScreenCenter to the Perspective computation, and run the game to see what that has done
1:31:14handmade_render_group.cpp: Prevent GetRenderEntityBasisP() from adding CameraTransform->ScreenCenter to the Perspective computation, and run the game to see what that has done
1:32:23handmade_opengl.cpp: Shuffle the projection matrix initialised in OpenGLSetScreenspace(), and run the game to see that our transform is correct, but the sorting is not
1:32:23handmade_opengl.cpp: Shuffle the projection matrix initialised in OpenGLSetScreenspace(), and run the game to see that our transform is correct, but the sorting is not
1:32:23handmade_opengl.cpp: Shuffle the projection matrix initialised in OpenGLSetScreenspace(), and run the game to see that our transform is correct, but the sorting is not
1:33:52handmade_render_group.cpp: Consider what the MetersToPixels value is contributing to GetRenderEntityBasisP()
1:33:52handmade_render_group.cpp: Consider what the MetersToPixels value is contributing to GetRenderEntityBasisP()
1:33:52handmade_render_group.cpp: Consider what the MetersToPixels value is contributing to GetRenderEntityBasisP()
1:36:47Blackboard: How MetersToPixels passes through the pipeline
1:36:47Blackboard: How MetersToPixels passes through the pipeline
1:36:47Blackboard: How MetersToPixels passes through the pipeline
1:41:20handmade_render.h: Consider how to simplify MetersToPixels
1:41:20handmade_render.h: Consider how to simplify MetersToPixels
1:41:20handmade_render.h: Consider how to simplify MetersToPixels
1:42:14handmade_opengl.cpp: Make OpenGLSetScreenspace() compute the Width and Height more simply
1:42:14handmade_opengl.cpp: Make OpenGLSetScreenspace() compute the Width and Height more simply
1:42:14handmade_opengl.cpp: Make OpenGLSetScreenspace() compute the Width and Height more simply
1:43:34handmade_render.h: Prevent GetStandardCameraParams() from taking WidthInPixels into account in the MetersToPixels computation, and run the game
1:43:34handmade_render.h: Prevent GetStandardCameraParams() from taking WidthInPixels into account in the MetersToPixels computation, and run the game
1:43:34handmade_render.h: Prevent GetStandardCameraParams() from taking WidthInPixels into account in the MetersToPixels computation, and run the game
1:44:29handmade_render.h: Remove WidthOfMonitor from the camera_params struct and rename MetersToPixels to WorldScale
1:44:29handmade_render.h: Remove WidthOfMonitor from the camera_params struct and rename MetersToPixels to WorldScale
1:44:29handmade_render.h: Remove WidthOfMonitor from the camera_params struct and rename MetersToPixels to WorldScale
1:47:11handmade_render_group.cpp: Consider simplifying the ProjectedXY computation
1:47:11handmade_render_group.cpp: Consider simplifying the ProjectedXY computation
1:47:11handmade_render_group.cpp: Consider simplifying the ProjectedXY computation
1:48:45handmade_render_group.h: Remove the render_entry_coordinate_system struct
1:48:45handmade_render_group.h: Remove the render_entry_coordinate_system struct
1:48:45handmade_render_group.h: Remove the render_entry_coordinate_system struct
1:49:50handmade_render_group.h: Make the entity_basis_p_result struct contain a 3D coordinate, and propagate that change
1:49:50handmade_render_group.h: Make the entity_basis_p_result struct contain a 3D coordinate, and propagate that change
1:49:50handmade_render_group.h: Make the entity_basis_p_result struct contain a 3D coordinate, and propagate that change
1:56:21Run the game with everything being passed down as 3D, and consider how we'll proceed
1:56:21Run the game with everything being passed down as 3D, and consider how we'll proceed
1:56:21Run the game with everything being passed down as 3D, and consider how we'll proceed
1:57:51Q&A
🗩
1:57:51Q&A
🗩
1:57:51Q&A
🗩
1:58:27rivten Concerning the "homogeneous" use. The "homogeneous" word indeed comes from mathematics. Homogeneous is used for mathematical objects that have some scalability property. Here, p0 = (x, y, z, 1) and p1 = (2x, 2y, 2z, 2) represent the same point in space (but p1 = 2 * p0 mathematically speaking). Therefore the usage of homogeneous coordinates and homogeneous matrices here
🗪
1:58:27rivten Concerning the "homogeneous" use. The "homogeneous" word indeed comes from mathematics. Homogeneous is used for mathematical objects that have some scalability property. Here, p0 = (x, y, z, 1) and p1 = (2x, 2y, 2z, 2) represent the same point in space (but p1 = 2 * p0 mathematically speaking). Therefore the usage of homogeneous coordinates and homogeneous matrices here
🗪
1:58:27rivten Concerning the "homogeneous" use. The "homogeneous" word indeed comes from mathematics. Homogeneous is used for mathematical objects that have some scalability property. Here, p0 = (x, y, z, 1) and p1 = (2x, 2y, 2z, 2) represent the same point in space (but p1 = 2 * p0 mathematically speaking). Therefore the usage of homogeneous coordinates and homogeneous matrices here
🗪
2:00:03vaualbus Turn off the sorting so we won't have flashing
🗪
2:00:03vaualbus Turn off the sorting so we won't have flashing
🗪
2:00:03vaualbus Turn off the sorting so we won't have flashing
🗪
2:01:58handmade_render.cpp: Temporarily make SortEntries() set ShouldSort to false and run the game to see how that affects it
2:01:58handmade_render.cpp: Temporarily make SortEntries() set ShouldSort to false and run the game to see how that affects it
2:01:58handmade_render.cpp: Temporarily make SortEntries() set ShouldSort to false and run the game to see how that affects it
2:03:20kim_jorgensen Debug UI is broken?
🗪
2:03:20kim_jorgensen Debug UI is broken?
🗪
2:03:20kim_jorgensen Debug UI is broken?
🗪
2:05:25elxenoaizd I was reading the article from Fabian about his optimizations on the Intel software renderer and I saw him doing the clipping in a very simple manner in screenspace, where he takes the min / max between the pixel and screen dimensions because he was using orient2d and barycentric coordinates to rasterize. The clipping was only four lines of code and easy to understand. Why does OpenGL have to do complicated homogeneous clipping?6
🗪
2:05:25elxenoaizd I was reading the article from Fabian about his optimizations on the Intel software renderer and I saw him doing the clipping in a very simple manner in screenspace, where he takes the min / max between the pixel and screen dimensions because he was using orient2d and barycentric coordinates to rasterize. The clipping was only four lines of code and easy to understand. Why does OpenGL have to do complicated homogeneous clipping?6
🗪
2:05:25elxenoaizd I was reading the article from Fabian about his optimizations on the Intel software renderer and I saw him doing the clipping in a very simple manner in screenspace, where he takes the min / max between the pixel and screen dimensions because he was using orient2d and barycentric coordinates to rasterize. The clipping was only four lines of code and easy to understand. Why does OpenGL have to do complicated homogeneous clipping?6
🗪
2:07:58rivten In practice, does the camera near plane and the camera focal length really differ? I would expect them to be the same
🗪
2:07:58rivten In practice, does the camera near plane and the camera focal length really differ? I would expect them to be the same
🗪
2:07:58rivten In practice, does the camera near plane and the camera focal length really differ? I would expect them to be the same
🗪
2:10:37elxenoaizd Are we going to continue supporting the software renderer in 3D as well?
🗪
2:10:37elxenoaizd Are we going to continue supporting the software renderer in 3D as well?
🗪
2:10:37elxenoaizd Are we going to continue supporting the software renderer in 3D as well?
🗪
2:11:07elxenoaizd If I set the near clip plane to, say, 10, does that mean that entities with a world space Z less than 10 would be clipped? Just trying to make sure that near / far clip planes are defined in terms of world space
🗪
2:11:07elxenoaizd If I set the near clip plane to, say, 10, does that mean that entities with a world space Z less than 10 would be clipped? Just trying to make sure that near / far clip planes are defined in terms of world space
🗪
2:11:07elxenoaizd If I set the near clip plane to, say, 10, does that mean that entities with a world space Z less than 10 would be clipped? Just trying to make sure that near / far clip planes are defined in terms of world space
🗪
2:13:35elxenoaizd Can you use the GPU to bypass the OpenGL or DirectX API / pipeline and just use compute shaders to implement your own pipeline that's also running on the GPU?
🗪
2:13:35elxenoaizd Can you use the GPU to bypass the OpenGL or DirectX API / pipeline and just use compute shaders to implement your own pipeline that's also running on the GPU?
🗪
2:13:35elxenoaizd Can you use the GPU to bypass the OpenGL or DirectX API / pipeline and just use compute shaders to implement your own pipeline that's also running on the GPU?
🗪
2:16:51rivten So, to avoid Z fighting, should we have dynamical near / far planes? I mean that their values should change according to the nearest and the farthest objects we want to render in order for the near / far plane space to be as small as possible?7
🗪
2:16:51rivten So, to avoid Z fighting, should we have dynamical near / far planes? I mean that their values should change according to the nearest and the farthest objects we want to render in order for the near / far plane space to be as small as possible?7
🗪
2:16:51rivten So, to avoid Z fighting, should we have dynamical near / far planes? I mean that their values should change according to the nearest and the farthest objects we want to render in order for the near / far plane space to be as small as possible?7
🗪
2:22:50elxenoaizd Does any of that clip and projection math change if we change the rendering technique that we're using? Say, rasterizing vs raytracing or voxels
🗪
2:22:50elxenoaizd Does any of that clip and projection math change if we change the rendering technique that we're using? Say, rasterizing vs raytracing or voxels
🗪
2:22:50elxenoaizd Does any of that clip and projection math change if we change the rendering technique that we're using? Say, rasterizing vs raytracing or voxels
🗪
2:26:40Close out
🗩
2:26:40Close out
🗩
2:26:40Close out
🗩