[video output=day476 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Providing Convenient Camera Controls" vod_platform=youtube id=05fgxEYTR5M annotator=Miblo]
[0:00][Recap and set the stage for the day continuing the renderer :API cleanup][:speech]
[1:25][Determine to switch platform_renderer to use a table of function pointers, to enable loading of renderers from DLLs][:api :library :speech]
[3:41][Switch platform_renderer to use function pointers][:api]
[9:57][Demo C++ virtual function calls][:language :speech]
[13:18][Enable RenderLoop() to use the functions pointed to in platform_renderer, introducing Win32LoadOpenGLRenderer()][:api]
[17:24][:Run the Renderer Test to see everything working fine][:api]
[17:38][Switch [~hero Handmade Hero] to use our function pointers in platform_renderer][:api]
[18:11][:Run the game][:api]
[18:54][Export Win32LoadRenderer() – renamed from Win32LoadOpenGLRenderer() – to a DLL][:language :library]
[25:43][C++ name mangling][:language :speech]
[26:52][Try to enable the compiler to export Win32LoadRenderer() by applying extern "C"][:language :library]
[28:15][Investigate why the compiler could not find Win32LoadRenderer(), using dumpbin][:admin :language :library]
[29:58][Stop marking Win32LoadRenderer() as internal (static), to enable the compiler to find it][:language :library]
[31:52][Link all the necessary libraries to our DLL][:language :library]
[33:35][Check our newly generated win32_handmade_opengl.dll in dumpbin and depends, to see Win32LoadRenderer in there][:admin :language :library]
[35:30][Enable RenderLoop() to load in our renderer DLL, introducing Win32LoadRendererDLL()[ref
    site=MSDN
    page="LoadLibrary function"
    url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx]][:language :library]
[44:46][Remove opengl32.lib from our CommonLinkerFlags][:language :library]
[45:14][Step through RenderLoop() and into the Renderer Test running in our external .dll][:language :library :run]
[46:17][Enable RenderLoop() to pop up a dialog box if we failed to find a renderer[ref
    site=MSDN
    page="MessageBox function"
    url=https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-messagebox]][:"error handling" :library]
[48:46][Delete win32_handmade_opengl.dll and :run the Renderer Test to see our dialog box][:"error handling" :library]
[49:28][Introduce Win32InitDefaultRenderer() to wrap up the renderer DLL loading][:api :library]
[51:54][Switch [~hero Handmade Hero] over to use our external renderer DLL][:library]
[53:19][:Run the game using the external DLL, with a few words on the potential to create other renderers][:library]
[54:16][Determine to clean up the :camera and sprite pushing :API, and general code organisation][:speech]
[55:08][Dive into cleaning up the :camera :API]
[1:02:25][Introduce Translation() for our :camera setup code to initialise the matrix][:mathematics]
[1:03:54][:Run the Renderer Test with the :camera working just as before]
[1:04:26][Fold the CameraOffset into the :camera matrix initialisation]
[1:06:57][:Run the Renderer Test using our single :camera matrix operation]
[1:07:25][Simplify the :camera setup code out into BuildCameraObjectMatrix() and GetStandardCameraParams()][:api]
[1:14:05][:Run the Renderer Test to see the exact same result][:api :camera]
[1:14:29][Continue to simplify the :camera code out into ViewFromCamera()][:api]
[1:16:44][:Run the Renderer Test, noting the simplicity of our :camera :API while retaining all the power]
[1:17:40][Make SetCameraTransform() take fog_params and alpha_clip_params][:api :camera]
[1:27:43][:Run the Renderer Test to verify that we work with the fog and alpha defaults][:api :camera]
[1:27:57][Try setting some fog_params in ViewFromCamera()][:api :camera]
[1:30:37][:Run the Renderer Test to see our fog, and play with the params, encountering some bugs with the sprite outlines][:api :camera :programming]
[1:34:38][Augment the camera struct with FogStart and FogEnd][:api :camera]
[1:38:47][:Run our fogged Renderer Test][:api :camera]
[1:39:04][Augment the camera struct with ClipAlphaStart and ClipAlphaEnd for ViewFromCamera() to use][:api :camera]
[1:42:07][:Run the Renderer Test to see our alpha clipping][:api :camera]
[1:42:51][Reflect on our newly simplified :camera :API, and consider getting rid of the render_group][:speech]
[1:46:23][@nxsy][Q: 1\:30pm]
[1:47:10][Consider the reason for render_group][:api :speech]
[1:49:16][Switch [~hero Handmade Hero] over to our new :camera :API]
[1:49:57][:Run the game, noting that we've lost our fog and alpha clip][:api :camera]
[1:50:51][Make UpdateAndRenderWorld() set the fog and alpha clip][:api :camera]
[1:52:48][:Run the game with our fog and alpha clip working][:api :camera]
[1:52:59][Document our window setup]
[1:54:59][:Run the Renderer Test preserving the 16\:9 aspect ratio][:rendering]
[1:55:09][Try setting the draw region to fill the entire window][:rendering]
[1:55:24][:Run the Renderer Test to see that we correctly draw to the entire window][:rendering]
[1:55:53][Document the :camera testing and texture downloading][:"asset loading"]
[2:00:17][Q&A][:speech]
[2:01:12][@naysayer88][Q: How can I program a really good Windows Update system like Windows has that makes sure you update all the time especially if you are not home or are watching a movie right now?]
[2:04:31][@vateferfout][Q: (Off-topic) You mentioned in the pre-stream fetching the cache misses. Do you mind explaining how it's done?][:profiling]
[2:04:50][@cynokron][Q: Why do you want to remove the render group? What is the alternative? My following is a bit spotty so I am sorry if this is obvious from watching previous streams]
[2:05:31][@tkscootlive][Q: What is your opinion on the Vulkan :API? Is it overkill to use it for a little indie game or is it worth the thousands of setup code lines?][:rant]
[2:09:09][@vateferfout][Q: I mean memory cache misses][:profiling]
[2:09:38][@uhee][Q: What steps are you going to do to optimize the renderer?][:optimisation]
[2:10:21][@accidentalrebel][Q: I'm making DOS games for fun. Have you had experience making games during the DOS era?]
[2:11:11][@vateferfout][Q: Sorry, I'll rephrase it. Is there a function that lets you know how many L1, L2, etc. cache misses happened since, for example, the last time you called the function?][:profiling :run]
[2:14:53][@mattiamanzati][Q: After ending up with the renderer part, which do you thing is the next macro-step on [~hero Handmade Hero]?]
[2:15:11][@cynokron][Q: Do you ever see Linux as a consumer machine? I'd personally rather use Linux to play games than Windows or Mac, but in your Vulkan rant Linux was not mentioned at all]
[2:15:58][@mmozeiko][Q: On Linux you can do that with "perf" utility. It does not require anything extra, kernel already provides this information]
[2:17:03][Wrap it up[ref
    site="Handmade Hero"
    url=https://handmadehero.org/][ref
        site="Molly Rocket's Site Nexus"
        url=https://mollyrocket.com/nexus]][:speech]
[/video]
