void AddMacrosForRenderingPass(MyRenderPassType pass, ref List <ShaderMacro> macros)
 {
     if (pass == MyRenderPassType.GBuffer)
     {
         macros.AddRange(new ShaderMacro[]
         {
             new ShaderMacro("RENDERING_PASS", 0),
             new ShaderMacro("USE_SIMPLE_INSTANCING", null),
             new ShaderMacro("USE_SIMPLE_INSTANCING_COLORING", null),
         });
     }
     else if (pass == MyRenderPassType.Depth)
     {
         macros.AddRange(new ShaderMacro[]
         {
             new ShaderMacro("RENDERING_PASS", 1),
             new ShaderMacro("USE_SIMPLE_INSTANCING", null),
         });
     }
     else if (pass == MyRenderPassType.Highlight)
     {
         macros.AddRange(new ShaderMacro[]
         {
             new ShaderMacro("RENDERING_PASS", 3),
         });
     }
     else
     {
         MyRenderProxy.Error("Unknown render pass type");
     }
 }
        MyVertexInputComponent[] GetVertexInputComponents(MyRenderPassType pass)
        {
            if (pass == MyRenderPassType.GBuffer)
            {
                List <MyVertexInputComponent> listGBuffer = new List <MyVertexInputComponent>();
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.POSITION_PACKED));
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.NORMAL, 1));
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.TANGENT_SIGN_OF_BITANGENT, 1));
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.TEXCOORD0_H, 1));
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.SIMPLE_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                listGBuffer.Add(new MyVertexInputComponent(MyVertexInputComponentType.SIMPLE_INSTANCE_COLORING, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                return(listGBuffer.ToArray());
            }
            else if (pass == MyRenderPassType.Depth)
            {
                List <MyVertexInputComponent> listDepth = new List <MyVertexInputComponent>();
                listDepth.Add(new MyVertexInputComponent(MyVertexInputComponentType.POSITION_PACKED));
                listDepth.Add(new MyVertexInputComponent(MyVertexInputComponentType.SIMPLE_INSTANCE, 2, MyVertexInputComponentFreq.PER_INSTANCE));
                return(listDepth.ToArray());
            }
            else if (pass == MyRenderPassType.Highlight)
            {
                List <MyVertexInputComponent> listHighlight = new List <MyVertexInputComponent>();
                listHighlight.Add(new MyVertexInputComponent(MyVertexInputComponentType.POSITION_PACKED));
                listHighlight.Add(new MyVertexInputComponent(MyVertexInputComponentType.NORMAL, 1));
                listHighlight.Add(new MyVertexInputComponent(MyVertexInputComponentType.TANGENT_SIGN_OF_BITANGENT, 1));
                listHighlight.Add(new MyVertexInputComponent(MyVertexInputComponentType.TEXCOORD0_H, 1));
                return(listHighlight.ToArray());
            }

            MyRenderProxy.Error("Unknown pass");
            return(null);
        }
        string GetPsDebugName(MyRenderPassType pass, MyMeshDrawTechnique technique, List <ShaderMacro> macros)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("GeoPsNew_");
            AddDebugNameSuffix(ref builder, pass, technique, macros);
            return(builder.ToString());
        }
        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);
        }
 void AddDebugNameSuffix(ref StringBuilder builder, MyRenderPassType pass, MyMeshDrawTechnique technique, List <ShaderMacro> macros)
 {
     builder.Append(pass);
     builder.Append("_");
     builder.Append(technique);
     builder.Append("_");
     foreach (var macro in macros)
     {
         if (string.IsNullOrEmpty(macro.Definition))
         {
             builder.Append(macro.Name);
         }
         else
         {
             builder.Append(macro.Name);
             builder.Append("=");
             builder.Append(macro.Definition);
         }
         builder.Append(";");
     }
 }