Handmade Hero»Episode Guide
Animating the Back Buffer
?
?

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:30Correction about StretchDIBits()/BitBlt()
0:30Correction about StretchDIBits()/BitBlt()
0:30Correction about StretchDIBits()/BitBlt()
5:20Writing our custom BitmapMemory allocator. (Note about aligned/unaligned byte access)
5:20Writing our custom BitmapMemory allocator. (Note about aligned/unaligned byte access)
5:20Writing our custom BitmapMemory allocator. (Note about aligned/unaligned byte access)
7:13Basic math to determine the bytes needed for BitmapMemorySize. 'Width * Height * BytesPerPixel'
7:13Basic math to determine the bytes needed for BitmapMemorySize. 'Width * Height * BytesPerPixel'
7:13Basic math to determine the bytes needed for BitmapMemorySize. 'Width * Height * BytesPerPixel'
7:57Description and usage of VirtualAlloc(), the WIN32 memory allocation function we will be using
7:57Description and usage of VirtualAlloc(), the WIN32 memory allocation function we will be using
7:57Description and usage of VirtualAlloc(), the WIN32 memory allocation function we will be using
13:15Making sure we free any allocated memory before we resize, using VirtualFree()
13:15Making sure we free any allocated memory before we resize, using VirtualFree()
13:15Making sure we free any allocated memory before we resize, using VirtualFree()
15:20Aside about VirtualProtect(), useful to prevent stale pointers and "use after free" bugs
15:20Aside about VirtualProtect(), useful to prevent stale pointers and "use after free" bugs
15:20Aside about VirtualProtect(), useful to prevent stale pointers and "use after free" bugs
16:49Step through of Win32ResizeDIBSection()
16:49Step through of Win32ResizeDIBSection()
16:49Step through of Win32ResizeDIBSection()
17:45Changing Win32UpdateWindow() to use BitmapMemory
17:45Changing Win32UpdateWindow() to use BitmapMemory
17:45Changing Win32UpdateWindow() to use BitmapMemory
19:30Adding Bitmap dimensions as global variables (temporarily)
19:30Adding Bitmap dimensions as global variables (temporarily)
19:30Adding Bitmap dimensions as global variables (temporarily)
20:00Setting Bitmap Width/Height and using them in Win32ResizeDIBSection()
20:00Setting Bitmap Width/Height and using them in Win32ResizeDIBSection()
20:00Setting Bitmap Width/Height and using them in Win32ResizeDIBSection()
20:20Setting Window Width/Height in Win32UpdateWindow()
20:20Setting Window Width/Height in Win32UpdateWindow()
20:20Setting Window Width/Height in Win32UpdateWindow()
21:57Notes on storing a 2D image inside a 1D "block" of memory. Pitch/Stride.
21:57Notes on storing a 2D image inside a 1D "block" of memory. Pitch/Stride.
21:57Notes on storing a 2D image inside a 1D "block" of memory. Pitch/Stride.
24:30Setting biHeight to a negative number to ensure the window framebuffer uses a top-down coordinate system with its origin in the top left corner
24:30Setting biHeight to a negative number to ensure the window framebuffer uses a top-down coordinate system with its origin in the top left corner
24:30Setting biHeight to a negative number to ensure the window framebuffer uses a top-down coordinate system with its origin in the top left corner
25:59Note on getting MSVC to give full paths to files in the build output log. (Add -FC to build.bat) Allows emacs to jump between build errors
25:59Note on getting MSVC to give full paths to files in the build output log. (Add -FC to build.bat) Allows emacs to jump between build errors
25:59Note on getting MSVC to give full paths to files in the build output log. (Add -FC to build.bat) Allows emacs to jump between build errors
27:00BUGFIX: Win32UpdateWindow() definition change
27:00BUGFIX: Win32UpdateWindow() definition change
27:00BUGFIX: Win32UpdateWindow() definition change
27:45Drawing pixels into the bitmap
27:45Drawing pixels into the bitmap
27:45Drawing pixels into the bitmap
29:05Adding typedefs for specific type sizes
29:05Adding typedefs for specific type sizes
29:05Adding typedefs for specific type sizes
30:39Casting void* to different size types to make pointer arithmetic simpler for bitmap access
30:39Casting void* to different size types to make pointer arithmetic simpler for bitmap access
30:39Casting void* to different size types to make pointer arithmetic simpler for bitmap access
33:36Pixel component layout in memory on Win32. Flipped to read RGB when viewed in the memory registers.
33:36Pixel component layout in memory on Win32. Flipped to read RGB when viewed in the memory registers.
33:36Pixel component layout in memory on Win32. Flipped to read RGB when viewed in the memory registers.
38:10Drawing pixel colors based on the X and Y
38:10Drawing pixel colors based on the X and Y
38:10Drawing pixel colors based on the X and Y
40:10Moving bitmap rendering into RenderWeirdGradient()
40:10Moving bitmap rendering into RenderWeirdGradient()
40:10Moving bitmap rendering into RenderWeirdGradient()
42:40Adding animation and switching GetMessageA() for PeekMessage() so that Windows doesn't block
42:40Adding animation and switching GetMessageA() for PeekMessage() so that Windows doesn't block
42:40Adding animation and switching GetMessageA() for PeekMessage() so that Windows doesn't block
45:23Making sure we handle WM_QUIT inside our PeekMessage() loop
45:23Making sure we handle WM_QUIT inside our PeekMessage() loop
45:23Making sure we handle WM_QUIT inside our PeekMessage() loop
46:23Adding XOffset/YOffset variables to the main loop, ++1 them each time through the loop
46:23Adding XOffset/YOffset variables to the main loop, ++1 them each time through the loop
46:23Adding XOffset/YOffset variables to the main loop, ++1 them each time through the loop
47:40BUGFIX: Adding our window blitting function (Win32UpdateWindow()) to the main loop, so the bitmap will blit each time through the loop
47:40BUGFIX: Adding our window blitting function (Win32UpdateWindow()) to the main loop, so the bitmap will blit each time through the loop
47:40BUGFIX: Adding our window blitting function (Win32UpdateWindow()) to the main loop, so the bitmap will blit each time through the loop
50:25Changing "WindowHandle" to "Window" and "WindowRect" to "ClientRect"
50:25Changing "WindowHandle" to "Window" and "WindowRect" to "ClientRect"
50:25Changing "WindowHandle" to "Window" and "WindowRect" to "ClientRect"
51:56FINALLY ANIMATION!
51:56FINALLY ANIMATION!
51:56FINALLY ANIMATION!
54:25Changing DrawWeirdGradient() to use a 32-bit pointer and write each pixel in one call using bitwise operations
54:25Changing DrawWeirdGradient() to use a 32-bit pointer and write each pixel in one call using bitwise operations
54:25Changing DrawWeirdGradient() to use a 32-bit pointer and write each pixel in one call using bitwise operations
58:38Verification of lack of memory leaks
58:38Verification of lack of memory leaks
58:38Verification of lack of memory leaks
59:44TOTAL SYSTEM MELTDOWN
59:44TOTAL SYSTEM MELTDOWN
59:44TOTAL SYSTEM MELTDOWN
1:02:07Q&A
🗩
1:02:07Q&A
🗩
1:02:07Q&A
🗩
1:02:10Is there a reason you prefer using 0 instead of NULL?
1:02:10Is there a reason you prefer using 0 instead of NULL?
1:02:10Is there a reason you prefer using 0 instead of NULL?
1:03:18Clarification about sized typedefs
1:03:18Clarification about sized typedefs
1:03:18Clarification about sized typedefs
1:04:58What would happen if you called malloc() instead of VirtualAlloc()?
1:04:58What would happen if you called malloc() instead of VirtualAlloc()?
1:04:58What would happen if you called malloc() instead of VirtualAlloc()?
1:05:32What's the difference between malloc and new and HeapAlloc()?
1:05:32What's the difference between malloc and new and HeapAlloc()?
1:05:32What's the difference between malloc and new and HeapAlloc()?
1:06:27Do you think you could go as slow as you did previous days in the future?
1:06:27Do you think you could go as slow as you did previous days in the future?
1:06:27Do you think you could go as slow as you did previous days in the future?
1:07:27Are we going to use Valgrind in the future?
1:07:27Are we going to use Valgrind in the future?
1:07:27Are we going to use Valgrind in the future?
1:07:43Is the project going to take 2 years?
1:07:43Is the project going to take 2 years?
1:07:43Is the project going to take 2 years?
1:08:10Can you explain why we are using the user32.lib and gdi.lib in the build.bat?
1:08:10Can you explain why we are using the user32.lib and gdi.lib in the build.bat?
1:08:10Can you explain why we are using the user32.lib and gdi.lib in the build.bat?
1:08:42Would there be a significant performance increase if we allocated the memory for the bitmap on the stack instead of the heap?
1:08:42Would there be a significant performance increase if we allocated the memory for the bitmap on the stack instead of the heap?
1:08:42Would there be a significant performance increase if we allocated the memory for the bitmap on the stack instead of the heap?
1:10:27Do you know what the PAGE_WRITECOPY Memory Protection flag does?
1:10:27Do you know what the PAGE_WRITECOPY Memory Protection flag does?
1:10:27Do you know what the PAGE_WRITECOPY Memory Protection flag does?
1:15:52About bytes per pixel and bitmap memory layout. Pitch/Stride. Pitch is byte offset between rows.
1:15:52About bytes per pixel and bitmap memory layout. Pitch/Stride. Pitch is byte offset between rows.
1:15:52About bytes per pixel and bitmap memory layout. Pitch/Stride. Pitch is byte offset between rows.
1:19:49You mentioned xxBBGGRR because of little endian, why was the blue channel set in this case instead of the padding?
1:19:49You mentioned xxBBGGRR because of little endian, why was the blue channel set in this case instead of the padding?
1:19:49You mentioned xxBBGGRR because of little endian, why was the blue channel set in this case instead of the padding?
1:21:30Could the padding byte be used as an alpha channel here?
1:21:30Could the padding byte be used as an alpha channel here?
1:21:30Could the padding byte be used as an alpha channel here?
1:22:06Why are we having a wait symbol on the window?
1:22:06Why are we having a wait symbol on the window?
1:22:06Why are we having a wait symbol on the window?
1:22:50Could you explain the offset to X and Y?
1:22:50Could you explain the offset to X and Y?
1:22:50Could you explain the offset to X and Y?
1:24:00About the global_variables and the static keyword
1:24:00About the global_variables and the static keyword
1:24:00About the global_variables and the static keyword
1:28:15Static doesn't give you zero on initialization?
1:28:15Static doesn't give you zero on initialization?
1:28:15Static doesn't give you zero on initialization?
1:29:38Do you consider overflowing numbers to be a good coding practice?
1:29:38Do you consider overflowing numbers to be a good coding practice?
1:29:38Do you consider overflowing numbers to be a good coding practice?
1:30:23Note about statics and extern global variables being initialized to zero
1:30:23Note about statics and extern global variables being initialized to zero
1:30:23Note about statics and extern global variables being initialized to zero