OpenGL Projection Matrices Revisited
⚠ Click here to regain focus ⚠

?

?

t / T Toggle theatre / SUPERtheatre mode

z Toggle filter mode V Revert filter to original state

X, ShiftSpace Toggle category and focus previous

v Invert topics / media as per focus

# Keyboard Navigation

## Global Keys

W, A, P / S, D, N Jump to previous / next markert / T Toggle theatre / SUPERtheatre mode

z Toggle filter mode V Revert filter to original state

## Menu toggling

q Quotes r References f Filter c Credits## Movement

a

w

s

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 nextX, ShiftSpace Toggle category and focus previous

v Invert topics / media as per focus

## Credits Menu

Enter Open URL (in new tab)⏫

Previous: 'Introduction to Depth Buffers'

⏫

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

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 specification

^{4}53:56Consult the OpenGL 2.0 specification

^{4}53:56Consult the OpenGL 2.0 specification

^{4}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: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 transformations

^{5}1:10:11Double-check the OpenGL spec on coordinate transformations

^{5}1:10:11Double-check the OpenGL spec on coordinate transformations

^{5}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: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: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: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: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

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:26:40Close out

2:26:40Close out

2:26:40Close out

⏬

Next: 'Moving the Perspective Divide to OpenGL'

⏬