[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Changing to Single Dispatch Per Pass (Part 2)" vod_platform=youtube id=0d0_NitChCY annotator=Miblo]
[0:00][Recap our switch to texture vertex indices][:hardware :rendering :speech]
[1:36][Augment game_render_commands with an IndexArray, with a few words on the GPU's ability to cache vertex shader transforms][:hardware :rendering]
[7:29][Remove renderer_texture_group and renderer_memory_layout, and pass our new IndexArray down the pipe, also augmenting open_gl with IndexArray and MaxIndexCount][:hardware :rendering]
[14:00][:Run the Renderer Test successfully][:hardware :rendering]
[14:12][Reduce the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene(), with a few words on breaking the problem into steps][:hardware :rendering]
[16:30][:Run the Renderer Test with our single vertex buffer working][:hardware :rendering]
[16:51][Augment render_entry_textured_quads with IndexArrayOffset for OpenGLEndFrame() to use the index buffer passed in][:hardware :rendering]
[20:19][Change OpenGLEndFrame() to call glBufferData() once, instead of while processing every render command][:hardware :rendering]
[22:17][:Run it to see problems with the depth peeling][:hardware :rendering]
[22:44][Make OpenGLInit() generate a separate CompositeVertexBuffer and ScreenFillVertexBuffer[ref
[28:52][:Run it with the depth peel working correctly][:hardware :rendering]
[29:03][Revert the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene() to their original high values][:hardware :rendering]
[29:55][:Run it to see that it is much zippier][:hardware :performance :rendering]
[30:34][Temporarily disable the :lighting][:rendering]
[31:15][:Run it to see that it didn't affect it much][:lighting :performance :rendering]
[31:51][Make RenderLoop() disable the :lighting][:rendering]
[33:17][:Run it and gauge the :performance with the :lighting disabled][:rendering]
[35:40][Turn off all the grass and augment open_gl with an IndexBuffer for OpenGLEndFrame() to use, rather than initialising Indices itself[ref
[1:04:41][:Run it to see that it looks good][:hardware :rendering]
[1:05:29][Let OpenGLEndFrame() texture our quads with the grass bitmap][:hardware :rendering]
[1:06:06][:Run it to see that we now don't have any :performance spikes][:hardware :rendering]
[1:08:30][Begin to switch the renderer over to use texture arrays, first enabling the vertex shader to understand the notion of a vertex index][:hardware :rendering]
[1:18:44][:Run it successfully][:hardware :rendering]
[1:18:51][Switch OpenGLAllocateTexture() to specify a feed-forward texture array, calling glTexSubImage3D()[ref
[2:02:05][:Run it and hit an OpenGL error: "Invalid texture format"][:hardware :rendering]
[2:03:38][Prevent OpenGLInit() from allocating the WhiteBitmap, and make it specify a texture level of 1 when calling glTexStorage2D()][:hardware :rendering]
[2:04:29][:Run it to see it all working with the correct textures, just that they are not always correctly sized[ref
[2:07:26][:Run [~hero Handmade Hero] to see that it has issues][:"asset loading" :hardware :rendering]
[2:08:09][Remove the WhiteBitmap from the renderer in favour of allowing the game itself to specify it if needed][:"asset loading"]
[2:11:56][Enable AllocateGameAssets() in [~hero Handmade Hero] to create its needed WhiteBitmap][:"asset loading"]
[2:15:24][Augment the renderer_texture with Width and Height for PushQuad() to use and so fix the texture sizing, renaming TextureHandle() to ReferToTexture()][:"asset loading"]
[2:27:13][Make PushQuad() scale the texture UVs based on their sizes][:rendering]
[2:29:14][:Run the Renderer Test and [~hero Handmade Hero] to see that the textures are correctly sized][:rendering]
[2:31:46][@lkalinovcic][Q: Are there any benefits to using PBOs for async texture transfers these days? I've heard that drivers copy texture data into their internal :memory anyway, so the call returns immediately and behaves as if it were asynchronous][:hardware :rendering]
[2:34:27][@mmozeiko][Q: In GL Core Profile you need to generate all "names" (textures, buffers, FBO, ...). Only in Compatibility Profile you are allowed to provide your own "name" values][:hardware :rendering]
[2:34:49][@lkalinovcic][Q: Unrelated: What's the recommended way to deal with Windows doing an infinite WindowProc loop while moving or resizing a window? My current approach is to jump in and out of the event processing loop with fibers. Is there something less hacky?][:"platform layer"]
[2:36:14][@mmozeiko][Q: You probably would want to replace glTexStorage3D() call with glTexImage3D(). TexStorage is from OpenGL 4.2 version (or ARB_texture_storage extension). TexStorage differs from TexImage in a way that its texture properties (size / format) are immutable – it cannot be changed once texture is created. It may help :performance but often it does not change][:hardware :rendering]
[2:36:58][Replace glTexStorage3D() with glTexImage3D()[ref
[2:40:04][@vateferfout][Q: Do you still multiply the offset in the glDrawElementsBaseVertex() call? Because I never do it and never had any problem, so I don't understand what's going on[ref
[2:44:19][@mmozeiko][Q: Please show glTexSubImage3D() call that fails][:hardware :rendering :run]
[2:47:38][@mmozeiko][Q: It needs to be GL_RGBA or whatever (value does not matter, because it is for last argument pixel data, which is NULL, so no data specified)][:hardware :rendering]
[2:48:28][@mmozeiko][Q: "does not matter", as long as it is valid, nonzero][:hardware :rendering]
[2:49:49][@cemuzunlar][Q: I think glTexImage3D() is the failing call. Can you please check the call stack again at crash time?][:hardware :rendering]
[2:51:45][Wrap it up with the determination to find out why we can't use glTexImage3D() here in OpenGLInit(), and a plug of [~cmuratori Casey] and [~checker Chris Hecker]'s upcoming talks at Busan Indie Connect Festival 2018[ref