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;
            }
        }
Esempio n. 2
0
        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;
            }
        }