protected sealed override unsafe void RecordCommandsInternal(MyRenderableProxy proxy) { if ((proxy.Mesh.Buffers.IB == null && proxy.MergedMesh.Buffers.IB == null) || proxy.DrawSubmesh.IndexCount == 0 || proxy.Flags.HasFlags(MyRenderableProxyFlags.SkipInMainView)) { return; } ++Stats.Draws; SetProxyConstants(proxy); BindProxyGeometry(proxy, RC); Debug.Assert(proxy.Shaders.VS != null); MyRenderUtils.BindShaderBundle(RC, proxy.Shaders); if (MyRender11.Settings.Wireframe) { SetDepthStencilView(false); RC.SetBlendState(null); if (proxy.Flags.HasFlags(MyRenderableProxyFlags.DisableFaceCulling)) { RC.SetRasterizerState(MyRasterizerStateManager.NocullWireframeRasterizerState); } else { RC.SetRasterizerState(MyRasterizerStateManager.WireframeRasterizerState); } } else { MyMeshDrawTechnique technique = MyMeshDrawTechnique.MESH; if (proxy.Material != MyMeshMaterialId.NULL) { technique = proxy.Material.Info.Technique; } if (proxy.Flags.HasFlags(MyRenderableProxyFlags.DisableFaceCulling)) { switch (technique) { case MyMeshDrawTechnique.DECAL: SetDepthStencilView(true); MyMeshMaterials1.BindMaterialTextureBlendStates(RC, proxy.Material.Info.TextureTypes, true); RC.SetRasterizerState(MyRasterizerStateManager.NocullDecalRasterizerState); break; case MyMeshDrawTechnique.DECAL_NOPREMULT: SetDepthStencilView(true); MyMeshMaterials1.BindMaterialTextureBlendStates(RC, proxy.Material.Info.TextureTypes, false); RC.SetRasterizerState(MyRasterizerStateManager.NocullDecalRasterizerState); break; case MyMeshDrawTechnique.DECAL_CUTOUT: SetDepthStencilView(true); RC.SetBlendState(null); RC.SetRasterizerState(MyRasterizerStateManager.NocullDecalRasterizerState); break; default: SetDepthStencilView(false); RC.SetBlendState(null); RC.SetRasterizerState(MyRasterizerStateManager.NocullRasterizerState); break; } } else { switch (technique) { case MyMeshDrawTechnique.DECAL: SetDepthStencilView(true); MyMeshMaterials1.BindMaterialTextureBlendStates(RC, proxy.Material.Info.TextureTypes, true); RC.SetRasterizerState(MyRasterizerStateManager.DecalRasterizerState); break; case MyMeshDrawTechnique.DECAL_NOPREMULT: SetDepthStencilView(true); MyMeshMaterials1.BindMaterialTextureBlendStates(RC, proxy.Material.Info.TextureTypes, false); RC.SetRasterizerState(MyRasterizerStateManager.DecalRasterizerState); break; case MyMeshDrawTechnique.DECAL_CUTOUT: SetDepthStencilView(true); RC.SetBlendState(null); RC.SetRasterizerState(MyRasterizerStateManager.DecalRasterizerState); break; default: SetDepthStencilView(false); RC.SetBlendState(null); RC.SetRasterizerState(null); break; } } } ++Stats.Submeshes; var submesh = proxy.DrawSubmesh; if (submesh.MaterialId != Locals.matTexturesID) { ++Stats.MaterialConstantsChanges; Locals.matTexturesID = submesh.MaterialId; var material = MyMaterials1.ProxyPool.Data[submesh.MaterialId.Index]; MyRenderUtils.MoveConstants(RC, ref material.MaterialConstants); MyRenderUtils.SetConstants(RC, ref material.MaterialConstants, MyCommon.MATERIAL_SLOT); MyRenderUtils.SetSrvs(RC, ref material.MaterialSrvs); } if (proxy.InstanceCount == 0) { if (!MyStereoRender.Enable) { RC.DrawIndexed(submesh.IndexCount, submesh.StartIndex, submesh.BaseVertex); } else { MyStereoRender.DrawIndexedGBufferPass(RC, submesh.IndexCount, submesh.StartIndex, submesh.BaseVertex); } ++Stats.Instances; Stats.Triangles += submesh.IndexCount / 3; } else { //MyRender11.AddDebugQueueMessage("GbufferPass DrawIndexedInstanced " + proxy.Material.ToString()); if (!MyStereoRender.Enable) { RC.DrawIndexedInstanced(submesh.IndexCount, proxy.InstanceCount, submesh.StartIndex, submesh.BaseVertex, proxy.StartInstance); } else { MyStereoRender.DrawIndexedInstancedGBufferPass(RC, submesh.IndexCount, proxy.InstanceCount, submesh.StartIndex, submesh.BaseVertex, proxy.StartInstance); } Stats.Instances += proxy.InstanceCount; Stats.Triangles += proxy.InstanceCount * submesh.IndexCount / 3; } }
unsafe static void DrawBatches(MyRenderContext rc, MyStringId material, int matIndex, bool transparent) { if (m_jobs.Count == 0) { return; } var matDesc = m_materials[material][matIndex]; rc.PixelShader.SetSrv(0, MyGBuffer.Main.DepthStencil.SrvDepth); rc.PixelShader.SetSrv(1, MyGlobalResources.Gbuffer1Copy); if (transparent) { rc.PixelShader.Set(m_psColorMapTransparent); } else { rc.SetRtvs(MyGBuffer.Main, MyDepthStencilAccess.ReadOnly); MyFileTextureEnum type = matDesc.DecalType; switch (type) { case MyFileTextureEnum.NORMALMAP_GLOSS: rc.PixelShader.Set(m_psNormalMap); break; case MyFileTextureEnum.COLOR_METAL: rc.PixelShader.Set(m_psColorMap); break; case MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS: rc.PixelShader.Set(m_psNormalColorMap); break; case MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS | MyFileTextureEnum.EXTENSIONS: rc.PixelShader.Set(m_psNormalColorExtMap); break; default: throw new Exception("Unknown decal type"); } MyMeshMaterials1.BindMaterialTextureBlendStates(rc, type); } // factor 1 makes overwriting of gbuffer color & subtracting from ao MyFileTextureManager texManager = MyManagers.FileTextures; rc.PixelShader.SetSrv(3, texManager.GetTexture(matDesc.AlphamaskTexture, MyFileTextureEnum.ALPHAMASK)); rc.PixelShader.SetSrv(4, texManager.GetTexture(matDesc.ColorMetalTexture, MyFileTextureEnum.COLOR_METAL)); rc.PixelShader.SetSrv(5, texManager.GetTexture(matDesc.NormalmapTexture, MyFileTextureEnum.NORMALMAP_GLOSS)); rc.PixelShader.SetSrv(6, texManager.GetTexture(matDesc.ExtensionsTexture, MyFileTextureEnum.EXTENSIONS)); var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * DECAL_BATCH_SIZE); int batchCount = m_jobs.Count / DECAL_BATCH_SIZE + 1; int offset = 0; for (int i1 = 0; i1 < batchCount; i1++) { var mapping = MyMapping.MapDiscard(decalCb); int leftDecals = m_jobs.Count - offset; int decalCount = leftDecals > DECAL_BATCH_SIZE ? DECAL_BATCH_SIZE : leftDecals; for (int i2 = 0; i2 < decalCount; ++i2) { MyDecalConstants constants = new MyDecalConstants(); EncodeJobConstants(i2 + offset, ref constants); mapping.WriteAndPosition(ref constants); } mapping.Unmap(); // Draw a box without buffer: 36 vertices -> 12 triangles. 2 triangles per face -> 6 faces MyImmediateRC.RC.DrawIndexed(36 * decalCount, 0, 0); offset += DECAL_BATCH_SIZE; } }