public MyShaderBundle GetShaderBundle(MyRenderPassType pass, MyMeshDrawTechnique technique, MyInstanceLodState state, bool isCm, bool isNg, bool isExt) { // Modify input: switch (technique) { case MyMeshDrawTechnique.DECAL: case MyMeshDrawTechnique.DECAL_CUTOUT: case MyMeshDrawTechnique.DECAL_NOPREMULT: break; default: isCm = true; isNg = true; isExt = true; break; } MyShaderBundleKey key = new MyShaderBundleKey { Pass = pass, Technique = technique, IsCm = isCm, IsNg = isNg, IsExt = isExt, State = state, }; if (m_cache.ContainsKey(key)) { return(m_cache[key]); } MyVertexInputComponent[] viComps = GetVertexInputComponents(pass); VertexLayoutId vl = MyVertexLayouts.GetLayout(viComps); string vsFilepath = GetShaderDirpath(technique) + "Vertex.hlsl"; string psFilepath = GetShaderDirpath(technique) + "Pixel.hlsl"; List <ShaderMacro> macros = new List <ShaderMacro>(); AddMacrosForRenderingPass(pass, ref macros); AddMacrosForTechnique(technique, isCm, isNg, isExt, ref macros); AddMacrosVertexInputComponents(viComps, ref macros); AddMacrosState(state, ref macros); VertexShaderId vs = MyShaders.CreateVs(vsFilepath, macros.ToArray()); ((VertexShader)vs).DebugName = GetVsDebugName(pass, technique, macros); PixelShaderId ps = MyShaders.CreatePs(psFilepath, macros.ToArray()); ((PixelShader)ps).DebugName = GetPsDebugName(pass, technique, macros);; InputLayoutId il = MyShaders.CreateIL(vs.BytecodeId, vl); MyShaderBundle shaderBundle = new MyShaderBundle(ps, vs, il); m_cache.Add(key, shaderBundle); return(shaderBundle); }
// this is tricky call. The method assumes that Draw() has been called in this frame public void DrawGlass(MyRenderContext RC) { RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); RC.SetViewport(m_viewport.OffsetX, m_viewport.OffsetY, m_viewport.Width, m_viewport.Height); //RC.SetRtvs(m_gbuffer, MyDepthStencilAccess.ReadWrite); <- the rtv is set out of the pass... FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix)); RC.VertexShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.VertexShader.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.PixelShader.SetSrv(MyCommon.DITHER_8X8_SLOT, MyGeneratedTextureManager.Dithering8x8Tex); IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, 255); // <- the lod value does not matter in this case RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); //RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); foreach (var itGroup in m_drawableGroupFactory.GetRawDrawableGroups()) { MyRenderProxy.Assert(itGroup.InstancesCount != 0); MyRenderProxy.Assert(itGroup.InstancesCount == itGroup.InstancesIncrement); if (itGroup.Lod.GlassParts == null) { continue; } foreach (var part in itGroup.Lod.GlassParts) { MyGlassMaterial material = part.GlassMaterial; RC.SetVertexBuffer(0, part.Parent.VB0); RC.SetVertexBuffer(1, part.Parent.VB1); RC.SetVertexBuffer(2, m_vbInstances); RC.SetIndexBuffer(part.Parent.IB); MyShaderBundle shaderBundle = part.GetShaderBundle(itGroup.State); RC.SetInputLayout(shaderBundle.InputLayout); RC.VertexShader.Set(shaderBundle.VertexShader); RC.PixelShader.Set(shaderBundle.PixelShader); RC.PixelShader.SetSrvs(0, material.Srvs); RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, GetGlassCB(RC, material)); int numInstances = itGroup.InstancesCount; int ibOffset = itGroup.OffsetInInstanceBuffer + (part.InstanceMaterialOffsetInLod + 1) * itGroup.InstancesCount; RC.DrawIndexedInstanced(part.IndicesCount, numInstances, part.StartIndex, part.StartVertex, ibOffset); } } }
protected override void Draw(MyRenderContext RC, List <MyInstanceComponent> visibleInstances) { int maxLodId = MyManagers.IDGenerator.DepthLods.GetHighestID(); if (IsProfilingDoable()) { ProfilerShort.Begin("Preparation"); } m_drawableGroupDepthStrategy.Prepare(m_vbInstances); m_drawableGroupFactory.Compute(m_drawableGroupDepthStrategy, visibleInstances, PassId, maxLodId); bool isEmpty = !m_drawableGroupDepthStrategy.Finalize(RC, out m_vbInstances); if (!isEmpty) { FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix)); RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); RC.SetViewport(m_viewport.OffsetX, m_viewport.OffsetY, m_viewport.Width, m_viewport.Height); RC.SetRtv(m_dsv, null); FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix)); RC.VertexShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.VertexShader.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.PixelShader.SetSrv(MyCommon.DITHER_8X8_SLOT, MyGeneratedTextureManager.Dithering8x8Tex); // Just some placeholder: IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, 0); RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); if (IsProfilingDoable()) { ProfilerShort.BeginNextBlock("Recording commands"); } foreach (var itGroup in m_drawableGroupFactory.GetRawDrawableGroups()) { MyRenderProxy.Assert(itGroup.InstancesCount != 0); MyRenderProxy.Assert(itGroup.InstancesCount == itGroup.InstancesIncrement); foreach (var part in itGroup.Lod.Parts) { RC.SetVertexBuffer(0, part.Parent.VB0); RC.SetVertexBuffer(2, m_vbInstances); RC.SetIndexBuffer(part.Parent.IB); RC.SetDepthStencilState(null); RC.SetRasterizerState(GetRasterizerState(m_isCascade)); RC.SetBlendState(null); MyShaderBundle shaderBundle = part.GetShaderBundle(itGroup.State); RC.SetInputLayout(shaderBundle.InputLayout); RC.VertexShader.Set(shaderBundle.VertexShader); RC.PixelShader.Set(shaderBundle.PixelShader); int numInstances = itGroup.InstancesCount; int ibOffset = itGroup.OffsetInInstanceBuffer + (part.InstanceMaterialOffsetInLod + 1) * itGroup.InstancesCount; RC.DrawIndexedInstanced(part.IndicesCount, numInstances, part.StartIndex, part.StartVertex, ibOffset); m_stats.Triangles += (part.IndicesCount / 3) * numInstances; m_stats.Instances += numInstances; m_stats.Draws++; } } } if (IsProfilingDoable()) { ProfilerShort.End(); } }
protected override void Draw(MyRenderContext RC, List <MyInstanceComponent> visibleInstances) { int maxLodId = MyManagers.IDGenerator.GBufferLods.GetHighestID(); ProfilerShort.Begin("Preparation"); m_drawableGroupGBufferStrategy.Prepare(m_vbInstances); m_drawableGroupFactory.Compute(m_drawableGroupGBufferStrategy, visibleInstances, 0, maxLodId); bool isEmpty = !m_drawableGroupGBufferStrategy.Finalize(RC, out m_vbInstances); if (!isEmpty) { RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); RC.SetViewport(m_viewport.OffsetX, m_viewport.OffsetY, m_viewport.Width, m_viewport.Height); RC.SetRtvs(m_gbuffer, MyDepthStencilAccess.ReadWrite); FillConstantBuffer(RC, MyCommon.ProjectionConstants, Matrix.Transpose(m_viewProjMatrix)); RC.VertexShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.VertexShader.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.PixelShader.SetSrv(MyCommon.DITHER_8X8_SLOT, MyGeneratedTextureManager.Dithering8x8Tex); IConstantBuffer cbObjectData = GetPlaceholderObjectCB(RC, 255); // <- the lod value does not matter in this case RC.VertexShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); RC.PixelShader.SetConstantBuffer(MyCommon.OBJECT_SLOT, cbObjectData); ProfilerShort.BeginNextBlock("Recording commands"); foreach (var itGroup in m_drawableGroupFactory.GetRawDrawableGroups()) { MyRenderProxy.Assert(itGroup.InstancesCount != 0); MyRenderProxy.Assert(itGroup.InstancesCount == itGroup.InstancesIncrement); foreach (var part in itGroup.Lod.Parts) { MyStandardMaterial material = part.StandardMaterial; RC.SetVertexBuffer(0, part.Parent.VB0); RC.SetVertexBuffer(1, part.Parent.VB1); RC.SetVertexBuffer(2, m_vbInstances); RC.SetIndexBuffer(part.Parent.IB); if (MyRender11.Settings.Wireframe) { RC.SetDepthStencilState(MyDepthStencilStateManager.DepthTestWrite); RC.SetBlendState(null); RC.SetRasterizerState(MyRasterizerStateManager.NocullWireframeRasterizerState); } else { RC.SetDepthStencilState(part.StandardMaterial.DepthStencilState); RC.SetRasterizerState(material.RasterizerState); RC.SetBlendState(part.StandardMaterial.BlendState); } MyShaderBundle shaderBundle = part.GetShaderBundle(itGroup.State); RC.SetInputLayout(shaderBundle.InputLayout); RC.VertexShader.Set(shaderBundle.VertexShader); RC.PixelShader.Set(shaderBundle.PixelShader); RC.PixelShader.SetSrvs(0, SrvStrategy.GetSrvs(part)); int numInstances = itGroup.InstancesCount; int ibOffset = itGroup.OffsetInInstanceBuffer + (part.InstanceMaterialOffsetInLod + 1) * itGroup.InstancesCount; RC.DrawIndexedInstanced(part.IndicesCount, numInstances, part.StartIndex, part.StartVertex, ibOffset); m_stats.Triangles += (part.IndicesCount / 3) * numInstances; m_stats.Instances += numInstances; m_stats.Draws++; } } } ProfilerShort.End(); }