[video output=day384 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Dynamically Responding to Render Settings" vod_platform=youtube id=0QNmoZYaTkM annotator=Miblo]
[0:08][Recap and set the stage for the day]
[1:11][Run the game with the determination to enable dynamic responding to render settings]
[4:08][A few words on our good fortune with GPU programming]
[5:12][handmade_opengl.h: Introduce hardware_rendering_switches]
[8:09][handmade_opengl.cpp: Remove the render_entry_blend_render_target case from OpenGLRenderCommands(), and PushBlendRenderTarget()]
[9:40][handmade_platform.h: typedef b32x and u32x with a description of these types]
[11:37][handmade_platform.h: Introduce game_render_setings]
[14:03][handmade_opengl.cpp: Break OpenGLRenderCommands() out into OpenGLPrepareForSettings() which conditionally enables features based on the game_render_settings]
[30:43][handmade_opengl.h: Add necessary data to the open_gl struct and begin to clean up compile errors]
[33:14][handmade_platform.h: Introduce AreEqual()]
[35:22][Rant on the approach of C++ to automating specific instances of programming routines, rather than providing flexible general tools]
[41:28][handmade_opengl.cpp: Fix up compile errors in OpenGLRenderCommands()]
[44:20][handmade_platform.h: Change the RenderCommandStruct() macro to DefaultRenderCommands()]
[51:11][handmade_opengl.cpp: Enable OpenGLBindFramebuffer() to work without the GlobalFramebuffer variables]
[55:42][Run the game and crash in CreateFramebuffer()]
[56:01][handmade_opengl.cpp: Force multisampling to off, run the game, crash in CreateFramebuffer() and investigate why]
[1:00:04][handmade_opengl.cpp: Make OpenGLRenderCommands() pass the new settings to OpenGLPrepareForSettings(), renamed to OpenGLChangeToSettings()]
[1:00:43][Run the game and see a grey screen]
[1:01:06][Re-emphasise that, if on more recent hardware, we would switch to a graphics debugger]
[1:04:00][handmade_opengl.cpp: Hard set values in the OpenGL pipeline in order to diagnose the bug]
[1:13:48][handmade_opengl.cpp: Enable OpenGLRenderCommands() to target our framebuffers]
[1:14:43][Run the game to see that we're getting closer]
[1:14:54][handmade_opengl.cpp: Change how OpenGLRenderCommands() renders to our depth peels]
[1:18:36][Run the game to see that something else is messed up]
[1:19:03][win32_handmade.cpp: Make DefaultRenderCommands() reset the RenderCommands]
[1:20:24][Run the game to see that we're not quite depth peeling]
[1:20:54][handmade_opengl.cpp: Make OpenGLRenderCommands() bind the framebuffer at the end of the depth peels]
[1:24:53][Run the game to see that it looks correct]
[1:25:10][handmade.cpp: Add some render settings to the debug system]
[1:26:21][Run the game, try changing these render settings and determine to enable multisampling and clean-up]
[1:27:33][Check the time][:admin]
[1:27:46][@insobot][87 minutes into the main stream. 33 until Q&A. (based on NOTE)]
[1:28:02][handmade_opengl.cpp: Introduce FreeFramebuffer() and FreeProgram() for OpenGLChangeToSettings() to call[ref
    site=docs.GL
    page="glDeleteShader"
    url=http://docs.gl/gl3/glDeleteShader][ref
    site=docs.GL
    page="glDeleteFramebuffers"
    url=http://docs.gl/gl3/glDeleteFramebuffers]]
[1:36:35][Advertise the Web]
[1:37:16][win32_handmade.cpp: Pull in glDeleteProgram(), glDeleteShader() and glDeleteFrameBuffers() from glcorearb.h[ref
    site="Khronos"
    page="glcorearb.h"
    url="https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h"]]
[1:39:44][Run the game and note that there isn't a good way to test our resource freeing code without GPU debugging tools]
[1:41:22][handmade_opengl.cpp: Add a TODO in OpenGLChangeToSettings() to use a tool to test our freeing code]
[1:42:31][handmade_opengl.cpp: Make OpenGLChangeToSettings() correctly free the depth peel buffer]
[1:43:02][Run the game and try to gauge if we are correctly freeing]
[1:44:18][Consult the documentation on glGet()[ref
    site="docs.GL"
    page="glGet"
    url="http://docs.gl/gl3/glGet"]]
[1:45:27][handmade_opengl.cpp: Add a TODO in OpenGLChangeToSettings() to fix the enabling of multisampling]
[1:48:06][Q&A][:speech]
[1:49:04][@garryjohanson][So one of my left-field questions: Do you think there is a case to be made for a GL implementation to be written in OpenCL, OpenCL having the capacity to natively run on the CPU and is compatible with visual studio, so you could CPU debug your OpenGL code in visual studio. Would that capacity solve the OpenGL debug problem, or is the problem typically somewhere else, like actual problems with opaque GPU functionality, if that all made sense?]
[1:49:37][Rant on GPU programming]
[1:58:49][@nyeecola][Casey, I've started to program more like the way you teach and I'm liking it so far, but there's one thing that makes me feel strange: When using structs to set up some data that will be used by a function later, how can I make sure that I won't forget to set some member of that struct before calling that function? Is there a way to make sure I always initialize every member of the structure to a value (other than zero)?]
[2:00:31][@jessermeyer][Why do you typedef some structs in the render layer, but not all of them?]
[2:01:34][@nyeecola][Casey, do you remove asserts when shipping a game?]
[2:01:46][@desuused][In a sense, Vulkan provides you an ISA with strict specification, but the initialization code is quite fat]
[2:04:01][@jezzi23][I didn't quite understand how OpenGL and multithreading can cooperate. I believe you once said in an episode that an OpenGL context is specific to the thread that created it. So if I create the context on a main thread, can I not have other worker threads call into OpenGL without somehow setting the context for each thread?]
[2:08:31][We're done][:speech]
[2:10:14][Plug Lysa[ref
    site="Handmade Network"
    page="Lysa"
    url="https://lysa.handmade.network/"]][:research]
[/video]
