Пример #1
0
        internal static void OnDeviceReset()
        {
            MyHwBuffers.OnDeviceReset();
            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();
            MyPipelineStates.OnDeviceReset();
            MyTextures.OnDeviceReset();
            MyRwTextures.OnDeviceEnd();
            MyShadows.OnDeviceReset();
            MyBillboardRenderer.OnDeviceRestart();

            MyMeshMaterials1.InvalidateMaterials();
            MyVoxelMaterials1.InvalidateMaterials();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
        }
Пример #2
0
        private static void OnDeviceReset()
        {
            MyManagers.OnDeviceReset();

            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();

            MyTransparentRendering.OnDeviceReset();

            ResetShadows(MyShadowCascades.Settings.NewData.CascadesCount, Settings.User.ShadowQuality.ShadowCascadeResolution());

            MyBillboardRenderer.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();

            MyMeshMaterials1.OnDeviceReset();
            MyVoxelMaterials1.OnDeviceReset();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();
        }
Пример #3
0
        internal void BuildProxy(out MyRenderableProxy_2 proxy, out UInt64 key)
        {
            var material = MyMeshMaterials1.GetProxyId(MyMeshMaterials1.MaterialRkIndex.Get(m_rootMaterialRK, MyMeshMaterialId.NULL));

            proxy = new MyRenderableProxy_2
            {
                MaterialType = MyMaterialType.OPAQUE,

                ObjectConstants = new MyConstantsPack {
                },

                ObjectSrvs = new MySrvTable {
                    StartSlot = MyCommon.INSTANCE_INDIRECTION, Srvs = m_mergeGroup.m_srvs, BindFlag = MyBindFlag.BIND_VS, Version = this.GetHashCode()
                },

                DepthShaders     = GetMergeInstancing(X.TEXT_(MyMaterialShaders.DEPTH_PASS), MyShaderUnifiedFlags.DEPTH_ONLY),
                HighlightShaders = GetMergeInstancing(X.TEXT_(MyMaterialShaders.HIGHLIGHT_PASS)),
                Shaders          = GetMergeInstancing(X.TEXT_(MyMaterialShaders.GBUFFER_PASS)),
                ForwardShaders   = GetMergeInstancing(X.TEXT_(MyMaterialShaders.FORWARD_PASS), MyShaderUnifiedFlags.USE_SHADOW_CASCADES),

                RenderFlags = MyRenderableProxyFlags.DepthSkipTextures,

                Submeshes = new MyDrawSubmesh_2[] { new MyDrawSubmesh_2 {
                                                        DrawCommand = MyDrawCommandEnum.Draw, Count = m_mergeGroup.VerticesNum, MaterialId = material
                                                    } },
                SubmeshesDepthOnly = new MyDrawSubmesh_2[] { new MyDrawSubmesh_2 {
                                                                 DrawCommand = MyDrawCommandEnum.Draw, Count = m_mergeGroup.VerticesNum, MaterialId = material
                                                             } },

                InstanceCount = 0,
                StartInstance = 0,
            };

            key = 0;
        }
Пример #4
0
        internal static void UnloadData()
        {
            MyActorFactory.RemoveAll();
            // many-to-one relation, can live withput owners, deallocated separately
            // MyComponentFactory<MyInstancingComponent>.RemoveAll();

            //MyVoxelMesh.RemoveAll();
            //MyDynamicMesh.RemoveAll();


            MyRender11.Log.WriteLine("Unloading session data");

            MyScene.RenderablesDBVH.Clear();
            MyScene.GroupsDBVH.Clear();
            MyClipmapFactory.RemoveAll();

            MyInstancing.OnSessionEnd();
            MyMeshes.OnSessionEnd();
            MyLights.OnSessionEnd();

            MyMaterials1.OnSessionEnd();
            MyVoxelMaterials1.OnSessionEnd();
            MyMeshMaterials1.OnSessionEnd();

            MyTextures.OnSessionEnd();
            MyBigMeshTable.Table.OnSessionEnd();

            //MyAssetsLoader.ClearMeshes();
        }
Пример #5
0
        internal void TurnIntoSeparateRenderables()
        {
            foreach (var child in m_children)
            {
                var r = child.GetRenderable();

                var model    = r.GetModel();
                var material = MyMeshes.GetMeshPart(model, 0, 0).Info.Material;

                bool fracture = model.Info.RuntimeGenerated || model.Info.Dynamic;

                if (MyMeshMaterials1.IsMergable(material) && MyBigMeshTable.Table.IsMergable(model) && !fracture)
                {
                    if (child.GetGroupLeaf().m_mergeGroup != null)
                    {
                        var materialRk            = MyMeshMaterials1.Table[material.Index].RepresentationKey;
                        var mergeGroupForMaterial = m_materialGroups.Get(materialRk);
                        if (mergeGroupForMaterial == null)
                        {
                            continue;
                        }

                        r.SetStandaloneRendering(true);
                        child.GetGroupLeaf().m_mergeGroup = null;

                        mergeGroupForMaterial.RemoveEntity(child);
                    }
                }
            }

            m_isMerged = false;
        }
Пример #6
0
        internal void Merge(MyActor child)
        {
            var r = child.GetRenderable();

            var model    = r.GetModel();
            var material = MyMeshes.GetMeshPart(model, 0, 0).Info.Material;

            bool fracture = model.Info.RuntimeGenerated || model.Info.Dynamic;

            if (MyMeshMaterials1.IsMergable(material) && MyBigMeshTable.Table.IsMergable(model) && !fracture)
            {
                var materialRk            = MyMeshMaterials1.Table[material.Index].RepresentationKey;
                var mergeGroupForMaterial = m_materialGroups.Get(materialRk);
                if (mergeGroupForMaterial == null)
                {
                    var proxyIndex = m_materialGroups.Count;
                    mergeGroupForMaterial = new MyMaterialMergeGroup(MyBigMeshTable.Table, material, proxyIndex);
                    m_materialGroups[MyMeshMaterials1.Table[material.Index].RepresentationKey] = mergeGroupForMaterial;

                    m_dirtyProxy = true;
                }

                r.SetStandaloneRendering(false);
                child.GetGroupLeaf().m_mergeGroup = mergeGroupForMaterial;

                mergeGroupForMaterial.AddEntity(child, model);
                mergeGroupForMaterial.UpdateEntity(child);
            }
        }
Пример #7
0
        internal static void OnDeviceReset()
        {
            MyHwBuffers.OnDeviceReset();
            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();
            MyPipelineStates.OnDeviceReset();
            MyTextures.OnDeviceReset();
            MyRwTextures.OnDeviceReset();
            MyTransparentRendering.OnDeviceReset();

            ResetShadows(Settings.ShadowCascadeCount, RenderSettings.ShadowQuality.ShadowCascadeResolution());

            MyBillboardRenderer.OnDeviceRestart();
            MyScreenDecals.OnDeviceReset();

            MyMeshMaterials1.InvalidateMaterials();
            MyVoxelMaterials1.InvalidateMaterials();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();
        }
Пример #8
0
        internal static void UpdateRenderSettings(MyRenderSettings1 settings)
        {
            MyRender11.Log.WriteLine("UpdateRenderSettings");
            MyRender11.Log.IncreaseIndent();

            var prevSettings = m_renderSettings;

            m_renderSettings = settings;

            LogUpdateRenderSettings(ref settings);

            MyRenderProxy.Settings.EnableCameraInterpolation = settings.InterpolationEnabled;
            MyRenderProxy.Settings.EnableObjectInterpolation = settings.InterpolationEnabled;

            MyRenderProxy.Settings.GrassDensityFactor = settings.GrassDensityFactor;

            //       if(settings.GrassDensityFactor != prevSettings.GrassDensityFactor)
            //           MyRenderProxy.ReloadGrass();

            if (settings.ShadowQuality != prevSettings.ShadowQuality)
            {
                MyShadows.ResizeCascades();
            }

            if (settings.AntialiasingMode != prevSettings.AntialiasingMode)
            {
                GlobalShaderHeader = MyShaderHelpers.FormatMacros(MyRender11.ShaderMultisamplingDefine(), MyRender11.FxaaEnabled ? "FXAA_ENABLED" : null);
                MyShaders.Recompile();
                MyMaterialShaders.Recompile();
                MyRenderableComponent.MarkAllDirty();

                if (settings.AntialiasingMode.SamplesCount() != prevSettings.AntialiasingMode.SamplesCount())
                {
                    CreateScreenResources();
                }
            }

            if (settings.AnisotropicFiltering != prevSettings.AnisotropicFiltering)
            {
                UpdateTextureSampler(m_textureSamplerState, TextureAddressMode.Wrap);
                UpdateTextureSampler(m_alphamaskarraySamplerState, TextureAddressMode.Clamp);
            }

            if (settings.TextureQuality != prevSettings.TextureQuality)
            {
                //MyTextureManager.UnloadTextures();

                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyTextures.ReloadQualityDependantTextures();

                //MyVoxelMaterials.ReloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();
            }

            m_settingsChangedListeners();

            MyRender11.Log.DecreaseIndent();
        }
        internal static void UpdateRenderSettings(MyRenderSettings1 settings)
        {
            Log.WriteLine("UpdateRenderSettings");
            Log.IncreaseIndent();

            var prevSettings = m_renderSettings;

            m_renderSettings = settings;

            LogUpdateRenderSettings(ref settings);

            MyRenderConstants.SwitchRenderQuality(settings.Dx9Quality); //because of lod ranges

            // THIS IS SHIT! MOVE TO USE JUST ONE STRUCT FOR RENDER SETTINGS!!!!!
            MyRender11.Settings.EnableCameraInterpolation = settings.InterpolationEnabled;
            MyRender11.Settings.EnableObjectInterpolation = settings.InterpolationEnabled;

            MyRender11.Settings.GrassDensityFactor = settings.GrassDensityFactor;
            if (settings.GrassDensityFactor == 0.0f)
            {
                m_renderSettings.FoliageDetails = MyFoliageDetails.DISABLED;
            }
            MyRender11.Settings.ModelQuality = settings.ModelQuality;
            MyRender11.Settings.VoxelQuality = settings.VoxelQuality;

            //       if(settings.GrassDensityFactor != prevSettings.GrassDensityFactor)
            //           MyRenderProxy.ReloadGrass();

            if (settings.ShadowQuality != prevSettings.ShadowQuality)
            {
                ResetShadows(MyShadowCascades.Settings.NewData.CascadesCount, settings.ShadowQuality.ShadowCascadeResolution());
            }

            if (settings.AntialiasingMode != prevSettings.AntialiasingMode)
            {
                UpdateAntialiasingMode(settings.AntialiasingMode, prevSettings.AntialiasingMode);
            }

            if (settings.AnisotropicFiltering != prevSettings.AnisotropicFiltering)
            {
                MySamplerStateManager.UpdateFiltering();
            }

            if (settings.TextureQuality != prevSettings.TextureQuality)
            {
                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyManagers.FileTextures.DisposeTex(MyFileTextureManager.MyFileTextureHelper.IsQualityDependantFilter);
                MyManagers.DynamicFileArrayTextures.ReloadAll();

                //MyVoxelMaterials.ReloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();
            }

            m_settingsChangedListeners();

            Log.DecreaseIndent();
        }
Пример #10
0
        internal static void UpdateRenderSettings(MyRenderSettings1 settings)
        {
            Log.WriteLine("UpdateRenderSettings");
            Log.IncreaseIndent();

            var prevSettings = m_renderSettings;

            m_renderSettings = settings;

            LogUpdateRenderSettings(ref settings);

            MyRenderConstants.SwitchRenderQuality(settings.Dx9Quality); //because of lod ranges

            MyRenderProxy.Settings.EnableCameraInterpolation = settings.InterpolationEnabled;
            MyRenderProxy.Settings.EnableObjectInterpolation = settings.InterpolationEnabled;

            MyRenderProxy.Settings.GrassDensityFactor = settings.GrassDensityFactor;
            if (settings.GrassDensityFactor == 0.0f)
            {
                m_renderSettings.FoliageDetails = MyFoliageDetails.DISABLED;
            }
            MyRenderProxy.Settings.VoxelQuality = settings.VoxelQuality;

            //       if(settings.GrassDensityFactor != prevSettings.GrassDensityFactor)
            //           MyRenderProxy.ReloadGrass();

            if (settings.ShadowQuality != prevSettings.ShadowQuality)
            {
                ResetShadows(MyRenderProxy.Settings.ShadowCascadeCount, settings.ShadowQuality.ShadowCascadeResolution());
            }

            if (settings.AntialiasingMode != prevSettings.AntialiasingMode)
            {
                UpdateAntialiasingMode(settings.AntialiasingMode, prevSettings.AntialiasingMode);
            }

            if (settings.AnisotropicFiltering != prevSettings.AnisotropicFiltering)
            {
                SamplerStates.UpdateFiltering();
            }

            if (settings.TextureQuality != prevSettings.TextureQuality)
            {
                //MyTextureManager.UnloadTextures();

                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyTextures.ReloadQualityDependantTextures();

                //MyVoxelMaterials.ReloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();
            }

            m_settingsChangedListeners();

            Log.DecreaseIndent();
        }
Пример #11
0
        internal static unsafe void InitSubsystems()
        {
            InitializeBlendStates();
            InitializeRasterizerStates();
            InitilizeSamplerStates();

            MyCommon.Init();
            MyPipelineStates.Init();
            MyTextures.Init();
            MyVertexLayouts.Init();
            MyShaders.Init();
            MyRwTextures.Init();
            MyHwBuffers.Init();
            MyMeshes.Init();
            MyMeshTableSRV.Init();
            MyMergeInstancing.Init();
            MyGeometryRenderer.Init();
            MyLightRendering.Init();
            MyShadows.Init();
            MyLinesRenderer.Init();
            MySpritesRenderer.Init();
            MyPrimitivesRenderer.Init();
            MyFoliageRenderer.Init();
            MyOutline.Init();

            MyComponents.Init();

            MyBillboardRenderer.Init(); // hardcoded limits
            MyDebugRenderer.Init();
            MyGPUFoliageGenerating.Init();

            MyScreenDecals.Init();
            MyEnvProbeProcessing.Init();
            MyShadowsResolve.Init();
            MyAtmosphereRenderer.Init();
            MyAAEdgeMarking.Init();
            MyScreenPass.Init();
            MyCopyToRT.Init();
            MyBlendTargets.Init();
            MyFXAA.Init();
            MyDepthResolve.Init();
            MyBloom.Init();
            MyLuminanceAverage.Init();
            MyToneMapping.Init();
            MySSAO.Init();
            MyHdrDebugTools.Init();

            MySceneMaterials.Init();
            MyMaterials1.Init();
            MyVoxelMaterials1.Init();
            MyMeshMaterials1.Init();

            //MyShaderFactory.RunCompilation(); // rebuild
        }
Пример #12
0
        internal static unsafe void InitSubsystems()
        {
            MyRwTextures.Init();
            MyHwBuffers.Init();
            MyPipelineStates.Init();
            ResetShadows(MyRenderProxy.Settings.ShadowCascadeCount, RenderSettings.ShadowQuality.ShadowCascadeResolution());
            MyRender11.Init();
            MyCommon.Init();
            SamplerStates.Init();
            MyDepthStencilState.Init();
            MyTextures.Init();
            MyVertexLayouts.Init();
            MyShaders.Init();
            MyMeshes.Init();
            MyMeshTableSRV.Init();
            MyLightRendering.Init();
            MyLinesRenderer.Init();
            MySpritesRenderer.Init();
            MyPrimitivesRenderer.Init();
            MyOutline.Init();
            MyBlur.Init();
            MyTransparentRendering.Init();

            MyFoliageComponents.Init();

            MyBillboardRenderer.Init(); // hardcoded limits
            MyDebugRenderer.Init();

            MyScreenDecals.Init();
            MyEnvProbeProcessing.Init();
            MyAtmosphereRenderer.Init();
            MyCloudRenderer.Init();
            MyAAEdgeMarking.Init();
            MyScreenPass.Init();
            MyCopyToRT.Init();
            MyBlendTargets.Init();
            MyFXAA.Init();
            MyDepthResolve.Init();
            MyBloom.Init();
            MyLuminanceAverage.Init();
            MyToneMapping.Init();
            MySSAO.Init();
            MyPlanetBlur.Init();
            MyHdrDebugTools.Init();

            MySceneMaterials.Init();
            MyMaterials1.Init();
            MyVoxelMaterials1.Init();
            MyMeshMaterials1.Init();
        }
Пример #13
0
        internal static void UpdateRenderSettings(MyRenderSettings settings)
        {
            Log.WriteLine("UpdateRenderSettings");
            Log.IncreaseIndent();

            var prevSettings = Settings;

            Settings = settings;

            LogUpdateRenderSettings();

            if (settings.User.GrassDensityFactor != prevSettings.User.GrassDensityFactor)
            {
                DisposeGrass();
            }

            MyRenderConstants.SwitchRenderQuality(settings.User.Dx9Quality); //because of lod ranges

            if (settings.User.ShadowQuality != prevSettings.User.ShadowQuality)
            {
                ResetShadows(MyShadowCascades.Settings.NewData.CascadesCount, settings.User.ShadowQuality.ShadowCascadeResolution());
            }

            if (settings.User.AntialiasingMode != prevSettings.User.AntialiasingMode)
            {
                UpdateAntialiasingMode(settings.User.AntialiasingMode, prevSettings.User.AntialiasingMode);
            }

            if (settings.User.AnisotropicFiltering != prevSettings.User.AnisotropicFiltering)
            {
                MySamplerStateManager.UpdateFiltering();
            }

            if (settings.User.TextureQuality != prevSettings.User.TextureQuality)
            {
                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyManagers.FileTextures.DisposeTex(MyFileTextureManager.MyFileTextureHelper.IsQualityDependantFilter);
                MyManagers.DynamicFileArrayTextures.ReloadAll();

                //MyVoxelMaterials.ReloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();
            }

            m_settingsChangedListeners();

            Log.DecreaseIndent();
        }
Пример #14
0
        internal static void Init()
        {
            m_vs = MyShaders.CreateVs("Decals/Decals.hlsl");
            var transparentMacro = new ShaderMacro("RENDER_TO_TRANSPARENT", null);

            m_psColorMapTransparent = MyShaders.CreatePs("Decals/Decals.hlsl", new ShaderMacro[] { transparentMacro });
            m_psColorMap            = MyShaders.CreatePs("Decals/Decals.hlsl", MyMeshMaterials1.GetMaterialTextureMacros(MyFileTextureEnum.COLOR_METAL));
            m_psNormalMap           = MyShaders.CreatePs("Decals/Decals.hlsl", MyMeshMaterials1.GetMaterialTextureMacros(MyFileTextureEnum.NORMALMAP_GLOSS));
            m_psNormalColorMap      = MyShaders.CreatePs("Decals/Decals.hlsl",
                                                         MyMeshMaterials1.GetMaterialTextureMacros(MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS));
            m_psNormalColorExtMap = MyShaders.CreatePs("Decals/Decals.hlsl",
                                                       MyMeshMaterials1.GetMaterialTextureMacros(
                                                           MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS | MyFileTextureEnum.EXTENSIONS));

            InitIB();
        }
Пример #15
0
        internal static void UnloadData()
        {
            MyManagers.OnUnloadData();

            MyActorFactory.RemoveAll();
            // many-to-one relation, can live withput owners, deallocated separately
            // MyComponentFactory<MyInstancingComponent>.RemoveAll();

            //MyVoxelMesh.RemoveAll();
            //MyDynamicMesh.RemoveAll();


            MyRender11.Log.WriteLine("Unloading session data");

            // Remove leftover persistent debug draw messages
            m_debugDrawMessages.Clear();

            MyScene.DynamicRenderablesDBVH.Clear();
            if (MyScene.SeparateGeometry)
            {
                MyScene.StaticRenderablesDBVH.Clear();
            }
            MyScene.GroupsDBVH.Clear();
            MyScene.FoliageDBVH.Clear();
            MyClipmapFactory.RemoveAll();
            MyClipmap.UnloadCache();

            MyInstancing.OnSessionEnd();
            MyFoliageComponents.OnSessionEnd();
            MyMeshes.OnSessionEnd();
            MyLights.OnSessionEnd();

            MyMaterials1.OnSessionEnd();
            MyVoxelMaterials1.OnSessionEnd();
            MyMeshMaterials1.OnSessionEnd();
            MyScreenDecals.OnSessionEnd();

            MyBigMeshTable.Table.OnSessionEnd();

            MyPrimitivesRenderer.Unload();

            MyTransparentRendering.OnSessionEnd();

            //MyAssetsLoader.ClearMeshes();
        }
Пример #16
0
        public static void RegisterMaterials(Dictionary <string, List <MyDecalMaterialDesc> > descriptions)
        {
            m_materials.Clear();
            foreach (var pair in descriptions)
            {
                List <MyDecalTextures> list = new List <MyDecalTextures>();
                foreach (var desc in pair.Value)
                {
                    list.Add(new MyDecalTextures()
                    {
                        DecalType         = MyMeshMaterials1.GetMaterialTextureTypes(desc.NormalmapTexture, desc.ColorMetalTexture, desc.ExtensionsTexture, null),
                        NormalmapTexture  = desc.NormalmapTexture,
                        ColorMetalTexture = desc.ColorMetalTexture,
                        ExtensionsTexture = desc.ExtensionsTexture,
                        AlphamaskTexture  = desc.AlphamaskTexture,
                    });
                }

                m_materials[X.TEXT_(pair.Key)] = list;
            }
        }
Пример #17
0
        public static void RegisterMaterials(Dictionary <string, List <MyDecalMaterialDesc> > descriptions)
        {
            MyFileTextureManager texManager = MyManagers.FileTextures;

            m_materials.Clear();
            foreach (var pair in descriptions)
            {
                List <MyDecalTextures> list = new List <MyDecalTextures>();
                foreach (var desc in pair.Value)
                {
                    list.Add(new MyDecalTextures()
                    {
                        DecalType         = MyMeshMaterials1.GetMaterialTextureTypes(desc.ColorMetalTexture, desc.NormalmapTexture, desc.ExtensionsTexture, null),
                        ColorMetalTexture = texManager.GetTexture(desc.ColorMetalTexture, MyFileTextureEnum.COLOR_METAL),
                        NormalmapTexture  = texManager.GetTexture(desc.NormalmapTexture, MyFileTextureEnum.NORMALMAP_GLOSS),
                        ExtensionsTexture = texManager.GetTexture(desc.ExtensionsTexture, MyFileTextureEnum.EXTENSIONS),
                        AlphamaskTexture  = texManager.GetTexture(desc.AlphamaskTexture, MyFileTextureEnum.ALPHAMASK),
                    });
                }

                m_materials[X.TEXT_(pair.Key)] = list;
            }
        }
Пример #18
0
        internal void Add(MyActor child)
        {
            child.AddComponent(MyComponentFactory <MyGroupLeafComponent> .Create());

            child.GetGroupLeaf().m_parent = m_owner;

            m_children.Add(child);

            if (child.m_relativeTransform == null)
            {
                child.m_relativeTransform = (Matrix)(child.WorldMatrix * MatrixD.Invert(m_owner.WorldMatrix));
            }

            if (!m_owner.m_localAabb.HasValue)
            {
                m_owner.m_localAabb = child.m_localAabb;
            }
            else
            {
                var localAabb = child.m_localAabb.Value;
                m_owner.m_localAabb = m_owner.m_localAabb.Value.Include(ref localAabb);
            }

            PropagateMatrixChange(child);

            if (child.GetRenderable() == null)
            {
                return;
            }

            //var mesh = child.GetRenderable().GetMesh();
            var model    = child.GetRenderable().GetModel();
            var material = MyMeshes.GetMeshPart(model, 0, 0).Info.Material;

            bool fracture = model.Info.RuntimeGenerated || model.Info.Dynamic;

            if (MyMeshMaterials1.IsMergable(material) && MyBigMeshTable.Table.IsMergable(model) && !fracture)
            {
                child.GetGroupLeaf().m_mergable = true;

                MyBigMeshTable.Table.AddMesh(model);
                m_mergablesCounter++;

                if (!m_isMerged && m_mergablesCounter >= MERGE_THRESHOLD)
                {
                    TurnIntoMergeInstancing();
                }
                else if (m_isMerged)
                {
                    Merge(child);
                }

                //var materialRk = MyMeshMaterials1.Table[material.Index].RepresentationKey;
                //var mergeGroupForMaterial = m_materialGroups.Get(materialRk);
                //if (mergeGroupForMaterial == null)
                //{
                //    var proxyIndex = m_materialGroups.Count;
                //    mergeGroupForMaterial = new MyMaterialMergeGroup(MyBigMeshTable.Table, material, proxyIndex);
                //    m_materialGroups[MyMeshMaterials1.Table[material.Index].RepresentationKey] = mergeGroupForMaterial;

                //    m_dirtyProxy = true;
                //}

                //child.GetRenderable().SetStandaloneRendering(false);
                //child.GetGroupLeaf().m_mergeGroup = mergeGroupForMaterial;


                //mergeGroupForMaterial.AddEntity(child, model);
                //mergeGroupForMaterial.UpdateEntity(child);
            }
            else
            {
                //Debug.WriteLine(String.Format("Mesh {0}, material {1} is not mergable", mesh.Name, material));
            }

            m_dirtyTree = true;
        }
 internal static void AddMaterialShaderFlagMacrosTo(List <ShaderMacro> list, MyShaderUnifiedFlags flags, MyFileTextureEnum textureTypes = MyFileTextureEnum.UNSPECIFIED)
 {
     if ((flags & MyShaderUnifiedFlags.DEPTH_ONLY) > 0)
     {
         list.Add(new ShaderMacro("DEPTH_ONLY", null));
     }
     if ((flags & MyShaderUnifiedFlags.ALPHA_MASKED) > 0)
     {
         list.Add(new ShaderMacro("ALPHA_MASKED", null));
     }
     if ((flags & MyShaderUnifiedFlags.ALPHA_MASK_ARRAY) > 0)
     {
         list.Add(new ShaderMacro("ALPHA_MASK_ARRAY", null));
     }
     if ((flags & MyShaderUnifiedFlags.TRANSPARENT) > 0)
     {
         list.Add(new ShaderMacro("TRANSPARENT", null));
     }
     if ((flags & MyShaderUnifiedFlags.DITHERED) > 0)
     {
         list.Add(new ShaderMacro("DITHERED", null));
     }
     if ((flags & MyShaderUnifiedFlags.DITHERED_LOD) > 0)
     {
         list.Add(new ShaderMacro("DITHERED_LOD", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_SKINNING) > 0)
     {
         list.Add(new ShaderMacro("USE_SKINNING", null));
     }
     if ((flags & MyShaderUnifiedFlags.STATIC_DECAL) > 0)
     {
         Debug.Assert(textureTypes != MyFileTextureEnum.UNSPECIFIED);
         list.Add(new ShaderMacro("STATIC_DECAL", null));
         list.AddRange(MyMeshMaterials1.GetMaterialTextureMacros(textureTypes));
     }
     if ((flags & MyShaderUnifiedFlags.STATIC_DECAL_CUTOUT) > 0)
     {
         list.Add(new ShaderMacro("STATIC_DECAL_CUTOUT", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_CUBE_INSTANCING) > 0)
     {
         list.Add(new ShaderMacro("USE_CUBE_INSTANCING", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_DEFORMED_CUBE_INSTANCING) > 0)
     {
         list.Add(new ShaderMacro("USE_DEFORMED_CUBE_INSTANCING", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_GENERIC_INSTANCING) > 0)
     {
         list.Add(new ShaderMacro("USE_GENERIC_INSTANCING", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_MERGE_INSTANCING) > 0)
     {
         list.Add(new ShaderMacro("USE_MERGE_INSTANCING", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_SINGLE_INSTANCE) > 0)
     {
         Debug.Assert((flags & MyShaderUnifiedFlags.USE_MERGE_INSTANCING) > 0);
         list.Add(new ShaderMacro("USE_SINGLE_INSTANCE", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_VOXEL_MORPHING) == MyShaderUnifiedFlags.USE_VOXEL_MORPHING)
     {
         list.Add(new ShaderMacro("USE_VOXEL_MORPHING", null));
     }
     if ((flags & MyShaderUnifiedFlags.USE_VOXEL_DATA) == MyShaderUnifiedFlags.USE_VOXEL_DATA)
     {
         list.Add(new ShaderMacro("USE_VOXEL_DATA", null));
     }
 }
Пример #20
0
        internal void BuildProxy(out MyRenderableProxy_2 proxy, out UInt64 key)
        {
            proxy = new MyRenderableProxy_2
            {
                MaterialType = MyMaterialType.OPAQUE,

                ObjectConstants = new MyConstantsPack {
                },

                ObjectSRVs = new MySrvTable {
                    StartSlot = MyCommon.INSTANCE_INDIRECTION, SRVs = m_mergeGroup.m_SRVs, BindFlag = MyBindFlag.BIND_VS, Version = this.GetHashCode()
                },
                VertexData = new MyVertexDataProxy_2 {
                },

                DepthShaders   = MyMaterialShaders.Get(X.TEXT("standard"), X.TEXT(MyGeometryRenderer.DEFAULT_DEPTH_PASS), MyVertexLayouts.Empty, MyShaderUnifiedFlags.USE_MERGE_INSTANCING | MyShaderUnifiedFlags.DEPTH_ONLY),
                Shaders        = MyMaterialShaders.Get(X.TEXT("standard"), X.TEXT(MyGeometryRenderer.DEFAULT_OPAQUE_PASS), MyVertexLayouts.Empty, MyShaderUnifiedFlags.USE_MERGE_INSTANCING),
                ForwardShaders = MyMaterialShaders.Get(X.TEXT("standard"), X.TEXT(MyGeometryRenderer.DEFAULT_FORWARD_PASS), MyVertexLayouts.Empty, MyShaderUnifiedFlags.USE_MERGE_INSTANCING | MyShaderUnifiedFlags.USE_SHADOW_CASCADES),

                RenderFlags = MyRenderableProxyFlags.DepthSkipTextures,

                Submeshes = new MyDrawSubmesh_2[] { new MyDrawSubmesh_2 {
                                                        DrawCommand = MyDrawCommandEnum.Draw, Count = m_mergeGroup.VerticesNum, MaterialId = MyMeshMaterials1.GetProxyId(MyMeshMaterials1.MaterialRkIndex.Get(m_rootMaterialRK, MyMeshMaterialId.NULL))
                                                    } },
                SubmeshesDepthOnly = new MyDrawSubmesh_2[] { new MyDrawSubmesh_2 {
                                                                 DrawCommand = MyDrawCommandEnum.Draw, Count = m_mergeGroup.VerticesNum, MaterialId = MyMeshMaterials1.GetProxyId(MyMeshMaterials1.MaterialRkIndex.Get(m_rootMaterialRK, MyMeshMaterialId.NULL))
                                                             } },

                InstanceCount = 0,
                StartInstance = 0,
            };

            key = 0;
        }
Пример #21
0
        MyRenderMeshInfo LoadMesh(string assetName, out MyLODDescriptor[] LodDescriptors)
        {
            //Debug.Assert(assetName.EndsWith(".mwm"));
            #region Temporary for mwm endings
            if (!assetName.EndsWith(".mwm"))
            {
                assetName += ".mwm";
            }
            #endregion

            var meshVertexInput = MyVertexInputLayout.Empty;
            LodDescriptors = null;
            MyRenderMeshInfo result = new MyRenderMeshInfo();

            var importer = new MyModelImporter();
            var fsPath   = Path.IsPathRooted(assetName) ? assetName : Path.Combine(MyFileSystem.ContentPath, assetName);

            if (!MyFileSystem.FileExists(fsPath))
            {
                System.Diagnostics.Debug.Fail("Model " + assetName + " does not exists!");

                return(MyAssetsLoader.GetDebugMesh().LODs[0].m_meshInfo);
            }


            string contentPath = null;
            if (Path.IsPathRooted(assetName) && assetName.ToLower().Contains("models"))
            {
                contentPath = assetName.Substring(0, assetName.ToLower().IndexOf("models"));
            }

            try
            {
                importer.ImportData(fsPath, new string[]
                {
                    MyImporterConstants.TAG_VERTICES,
                    MyImporterConstants.TAG_BLENDINDICES,
                    MyImporterConstants.TAG_BLENDWEIGHTS,
                    MyImporterConstants.TAG_NORMALS,
                    MyImporterConstants.TAG_TEXCOORDS0,
                    MyImporterConstants.TAG_TANGENTS,
                    MyImporterConstants.TAG_BINORMALS,
                    MyImporterConstants.TAG_BONES,
                    MyImporterConstants.TAG_MESH_PARTS,
                    MyImporterConstants.TAG_BOUNDING_BOX,
                    MyImporterConstants.TAG_BOUNDING_SPHERE,
                    MyImporterConstants.TAG_LODS,
                });
                Dictionary <string, object> tagData = importer.GetTagData();

                // extract data
                var positions = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES];
                System.Diagnostics.Debug.Assert(positions.Length > 0);
                var verticesNum     = positions.Length;
                var boneIndices     = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES];
                var boneWeights     = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS];
                var normals         = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS];
                var texcoords       = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                var tangents        = (Byte4[])tagData[MyImporterConstants.TAG_TANGENTS];
                var bintangents     = (Byte4[])tagData[MyImporterConstants.TAG_BINORMALS];
                var tangentBitanSgn = new Byte4[verticesNum];
                for (int i = 0; i < verticesNum; i++)
                {
                    var N = VF_Packer.UnpackNormal(normals[i].PackedValue);
                    var T = VF_Packer.UnpackNormal(tangents[i].PackedValue);
                    var B = VF_Packer.UnpackNormal(bintangents[i].PackedValue);

                    var tanW = new Vector4(T.X, T.Y, T.Z, 0);

                    tanW.W             = T.Cross(N).Dot(B) < 0 ? -1 : 1;
                    tangentBitanSgn[i] = VF_Packer.PackTangentSignB4(ref tanW);
                }
                bool hasBonesInfo = false;
                if (boneIndices.Length > 0 && boneWeights.Length > 0)
                {
                    hasBonesInfo = true;
                }
                var bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

                //
                var           vertexBuffers = new List <VertexBufferId>();
                IndexBufferId indexBuffer   = IndexBufferId.NULL;
                var           submeshes     = new Dictionary <string, List <MyDrawSubmesh> >();
                var           submeshes2    = new Dictionary <string, List <MySubmeshInfo> >();
                var           submeshesMeta = new List <MySubmeshInfo>();

                int  indicesNum      = 0;
                bool missingMaterial = false;
                if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS))
                {
                    var  indices  = new List <uint>(positions.Length);
                    uint maxIndex = 0;

                    var meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List <MyMeshPartInfo>;
                    foreach (MyMeshPartInfo meshPart in meshParts)
                    {
                        # region Bones indirection
                        int[] bonesRemapping = null;
                        if (boneIndices.Length > 0 && bones.Length > MyRender11Constants.SHADER_MAX_BONES)
                        {
                            Dictionary <int, int> vertexChanged = new Dictionary <int, int>();

                            Dictionary <int, int> bonesUsed = new Dictionary <int, int>();

                            int trianglesNum = meshPart.m_indices.Count / 3;
                            for (int i = 0; i < trianglesNum; i++)
                            {
                                for (int j = 0; j < 3; j++)
                                {
                                    int index = meshPart.m_indices[i * 3 + j];
                                    if (boneWeights[index].X > 0)
                                    {
                                        bonesUsed[boneIndices[index].X] = 1;
                                    }
                                    if (boneWeights[index].Y > 0)
                                    {
                                        bonesUsed[boneIndices[index].Y] = 1;
                                    }
                                    if (boneWeights[index].Z > 0)
                                    {
                                        bonesUsed[boneIndices[index].Z] = 1;
                                    }
                                    if (boneWeights[index].W > 0)
                                    {
                                        bonesUsed[boneIndices[index].W] = 1;
                                    }
                                }
                            }

                            if (bonesUsed.Count > MyRender11Constants.SHADER_MAX_BONES)
                            {
                                Debug.Assert(bonesUsed.Count <= MyRender11Constants.SHADER_MAX_BONES, "Model \"" + assetName + "\"'s part uses more than 60 bones, please split model on more parts");
                            }

                            var partBones = new List <int>(bonesUsed.Keys);
                            partBones.Sort();
                            if (partBones.Count > 0 && partBones[partBones.Count - 1] >= MyRender11Constants.SHADER_MAX_BONES)
                            {
                                for (int i = 0; i < partBones.Count; i++)
                                {
                                    bonesUsed[partBones[i]] = i;
                                }

                                Dictionary <int, int> vertexTouched = new Dictionary <int, int>();

                                for (int i = 0; i < trianglesNum; i++)
                                {
                                    for (int j = 0; j < 3; j++)
                                    {
                                        int index = meshPart.m_indices[i * 3 + j];
                                        if (!vertexTouched.ContainsKey(index))
                                        {
                                            if (boneWeights[index].X > 0)
                                            {
                                                boneIndices[index].X = bonesUsed[boneIndices[index].X];
                                            }
                                            if (boneWeights[index].Y > 0)
                                            {
                                                boneIndices[index].Y = bonesUsed[boneIndices[index].Y];
                                            }
                                            if (boneWeights[index].Z > 0)
                                            {
                                                boneIndices[index].Z = bonesUsed[boneIndices[index].Z];
                                            }
                                            if (boneWeights[index].W > 0)
                                            {
                                                boneIndices[index].W = bonesUsed[boneIndices[index].W];
                                            }

                                            vertexTouched[index] = 1;

                                            int changes = 0;
                                            vertexChanged.TryGetValue(index, out changes);
                                            vertexChanged[index] = changes + 1;
                                        }
                                    }
                                }

                                bonesRemapping = partBones.ToArray();
                            }

                            if (vertexChanged.Values.Count > 0)
                            {
                                Debug.Assert(vertexChanged.Values.Max() < 2, "Vertex shared between model parts, will likely result in wrong skinning");
                            }
                        }

                        #endregion

                        int startIndex = indices.Count;
                        int indexCount = meshPart.m_indices.Count;

                        uint minIndex = (uint)meshPart.m_indices[0];
                        foreach (var i in meshPart.m_indices)
                        {
                            indices.Add((uint)i);
                            minIndex = Math.Min(minIndex, (uint)i);
                        }

                        uint baseVertex = minIndex;

                        for (int i = startIndex; i < startIndex + indexCount; i++)
                        {
                            indices[i] -= minIndex;
                            maxIndex    = Math.Max(maxIndex, indices[i]);
                        }

                        #region Material
                        var materialDesc = meshPart.m_MaterialDesc;

                        var matId        = MyMeshMaterials1.GetMaterialId(materialDesc, contentPath);
                        var partKey      = MyMeshMaterials1.Table[matId.Index].Technique;
                        var materialName = MyMeshMaterials1.Table[matId.Index].Name;

                        var list = submeshes.SetDefault(partKey, new List <MyDrawSubmesh>());
                        list.Add(new MyDrawSubmesh(indexCount, startIndex, (int)baseVertex, MyMeshMaterials1.GetProxyId(matId), bonesRemapping));

                        submeshesMeta.Add(new MySubmeshInfo
                        {
                            IndexCount   = indexCount,
                            StartIndex   = startIndex,
                            BaseVertex   = (int)baseVertex,
                            BonesMapping = bonesRemapping,
                            Material     = materialName.ToString(),
                            Technique    = partKey
                        });

                        var list2 = submeshes2.SetDefault(partKey, new List <MySubmeshInfo>());
                        list2.Add(submeshesMeta[submeshesMeta.Count - 1]);

                        #endregion
                    }
                    indicesNum = indices.Count;

                    #region Fill gpu buffes
                    unsafe
                    {
                        if (maxIndex <= ushort.MaxValue)
                        {
                            // create 16 bit indices
                            var indices16 = new ushort[indices.Count];
                            for (int i = 0; i < indices.Count; i++)
                            {
                                indices16[i] = (ushort)indices[i];
                            }

                            result.Indices = indices16;

                            fixed(ushort *I = indices16)
                            {
                                indexBuffer = MyHwBuffers.CreateIndexBuffer(indices16.Length, Format.R16_UInt, BindFlags.IndexBuffer, ResourceUsage.Immutable, new IntPtr(I), assetName + " index buffer");
                            }
                        }
                        else
                        {
                            var indicesArray = indices.ToArray();
                            fixed(uint *I = indicesArray)
                            {
                                indexBuffer = MyHwBuffers.CreateIndexBuffer(indices.Count, Format.R32_UInt, BindFlags.IndexBuffer, ResourceUsage.Immutable, new IntPtr(I), assetName + " index buffer");
                            }
                        }
                    }
                    unsafe
                    {
                        if (!hasBonesInfo)
                        {
                            var vertices = new MyVertexFormatPositionH4[verticesNum];

                            for (int i = 0; i < verticesNum; i++)
                            {
                                vertices[i] = new MyVertexFormatPositionH4(positions[i]);
                            }
                            meshVertexInput = meshVertexInput.Append(MyVertexInputComponentType.POSITION_PACKED);

                            result.VertexPositions = vertices;

                            fixed(MyVertexFormatPositionH4 *V = vertices)
                            {
                                vertexBuffers.Add(MyHwBuffers.CreateVertexBuffer(verticesNum, sizeof(MyVertexFormatPositionH4), BindFlags.VertexBuffer, ResourceUsage.Immutable, new IntPtr(V), assetName + " vertex buffer " + vertexBuffers.Count));
                            }
                        }
                        else
                        {
                            var vertices = new MyVertexFormatPositionSkinning[verticesNum];
                            for (int i = 0; i < verticesNum; i++)
                            {
                                vertices[i] = new MyVertexFormatPositionSkinning(
                                    positions[i],
                                    new Byte4(boneIndices[i].X, boneIndices[i].Y, boneIndices[i].Z, boneIndices[i].W),
                                    boneWeights[i]);
                            }
                            meshVertexInput = meshVertexInput.Append(MyVertexInputComponentType.POSITION_PACKED)
                                              .Append(MyVertexInputComponentType.BLEND_WEIGHTS).Append(MyVertexInputComponentType.BLEND_INDICES);

                            fixed(MyVertexFormatPositionSkinning *V = vertices)
                            {
                                vertexBuffers.Add(MyHwBuffers.CreateVertexBuffer(verticesNum, sizeof(MyVertexFormatPositionSkinning), BindFlags.VertexBuffer, ResourceUsage.Immutable, new IntPtr(V), assetName + " vertex buffer " + vertexBuffers.Count));
                            }
                        }
                        // add second stream
                        {
                            var vertices = new MyVertexFormatTexcoordNormalTangent[verticesNum];
                            for (int i = 0; i < verticesNum; i++)
                            {
                                vertices[i] = new MyVertexFormatTexcoordNormalTangent(texcoords[i], normals[i], tangentBitanSgn[i]);
                            }

                            fixed(MyVertexFormatTexcoordNormalTangent *V = vertices)
                            {
                                vertexBuffers.Add(MyHwBuffers.CreateVertexBuffer(verticesNum, sizeof(MyVertexFormatTexcoordNormalTangent), BindFlags.VertexBuffer, ResourceUsage.Immutable, new IntPtr(V), assetName + " vertex buffer " + vertexBuffers.Count));
                            }

                            result.VertexExtendedData = vertices;

                            meshVertexInput = meshVertexInput
                                              .Append(MyVertexInputComponentType.NORMAL, 1)
                                              .Append(MyVertexInputComponentType.TANGENT_SIGN_OF_BITANGENT, 1)
                                              .Append(MyVertexInputComponentType.TEXCOORD0_H, 1);
                        }
                    }
                    #endregion
                }
                #region Extract lods
                if (tagData.ContainsKey(MyImporterConstants.TAG_LODS))
                {
                    var tagLODs = tagData[MyImporterConstants.TAG_LODS];
                    if (((MyLODDescriptor[])tagLODs).Length > 0)
                    {
                    }
                    LodDescriptors = (MyLODDescriptor[])((MyLODDescriptor[])tagLODs).Clone();
                }
                #endregion

                if (missingMaterial)
                {
                    Debug.WriteLine(String.Format("Mesh {0} has missing material", assetName));
                }

                //indexBuffer.SetDebugName(assetName + " index buffer");
                int c = 0;
                //vertexBuffers.ForEach(x => x.SetDebugName(assetName + " vertex buffer " + c++));

                //
                result.BoundingBox    = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                result.BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                result.VerticesNum    = verticesNum;
                result.IndicesNum     = indicesNum;
                result.VertexLayout   = meshVertexInput;
                result.IB             = indexBuffer;
                result.VB             = vertexBuffers.ToArray();
                result.IsAnimated     = hasBonesInfo;
                result.Parts          = submeshes.ToDictionary(x => x.Key, x => x.Value.ToArray());
                result.PartsMetadata  = submeshes2.ToDictionary(x => x.Key, x => x.Value.ToArray());
                result.m_submeshes    = submeshesMeta;

                IsAnimated |= result.IsAnimated;

                importer.Clear();
                return(result);
            }
Пример #22
0
 internal static void GatherTextures()
 {
     MyMeshMaterials1.OnResourcesGathering();
     MyVoxelMaterials1.OnResourcesGather();
 }
Пример #23
0
 internal static void QueryTexturesFromEntities()
 {
     MyMeshMaterials1.OnResourcesRequesting();
     MyVoxelMaterials1.OnResourcesRequesting();
 }
Пример #24
0
        internal static unsafe void InitSubsystems()
        {
            MyManagers.OnDeviceInit();
            //MyRwTextures.Init();
            MyHwBuffers.Init();
            ResetShadows(MyShadowCascades.Settings.NewData.CascadesCount, RenderSettings.ShadowQuality.ShadowCascadeResolution());
            MyRender11.Init();
            MyCommon.Init();
            MyVertexLayouts.Init();
            MyShaders.Init();
            MyMeshes.Init();
            MyMeshTableSrv.Init();
            MyLightRendering.Init();
            MyLinesRenderer.Init();
            MySpritesRenderer.Init();
            MyPrimitivesRenderer.Init();
            MyOutline.Init();
            MyBlur.Init();
            MyTransparentRendering.Init();

            MyFoliageComponents.Init();

            MyBillboardRenderer.Init(); // hardcoded limits
            MyDebugRenderer.Init();

            MyScreenDecals.Init();
            MyEnvProbeProcessing.Init();
            MyAtmosphereRenderer.Init();
            MyCloudRenderer.Init();
            MyAAEdgeMarking.Init();
            MyScreenPass.Init();
            MyCopyToRT.Init();
            MyBlendTargets.Init();
            MyFXAA.Init();
            MyDepthResolve.Init();
            MyBloom.Init();
            MyLuminanceAverage.Init();
            MyToneMapping.Init();
            MySSAO.Init();
            MyHdrDebugTools.Init();

            MySceneMaterials.Init();
            MyMaterials1.Init();
            MyVoxelMaterials1.Init();
            MyMeshMaterials1.Init();

            MyHBAO.Init();

            try
            {
                if (m_settings.UseStereoRendering)
                {
                    var openVR = new MyOpenVR();
                    MyStereoStencilMask.InitUsingOpenVR();
                }
            }
            catch (System.Exception e)
            {
                if (!VRage.MyCompilationSymbols.DX11ForceStereo)
                {
                    throw;
                }
                MyStereoStencilMask.InitUsingUndefinedMask();
            }
        }
        private static void ProcessMessageInternal(IMyRenderMessage message)
        {
            switch (message.MessageType)
            {
            case MyRenderMessageEnum.SetCameraViewMatrix:
            {
                var rMessage = (MyRenderMessageSetCameraViewMatrix)message;

                SetupCameraMatrices(rMessage);

                break;
            }

            case MyRenderMessageEnum.DrawScene:
            {
                var rMessage = (IMyRenderMessage)message;

                m_drawQueue.Enqueue(rMessage);

                m_messageTracker.Clear();

                break;
            }

            case MyRenderMessageEnum.RebuildCullingStructure:
            {
                break;
            }

                #region Profiler

            case MyRenderMessageEnum.RenderProfiler:
            {
                var profMessage = (MyRenderMessageRenderProfiler)message;

                MyRenderProfiler.HandleInput(profMessage.Command, profMessage.Index);

                break;
            }

                #endregion

                #region Characters

            case MyRenderMessageEnum.CreateRenderCharacter:
            {
                var rMessage = (MyRenderMessageCreateRenderCharacter)message;

                var    actor        = MyActorFactory.CreateCharacter();
                Matrix worldMatrixF = rMessage.WorldMatrix;
                //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(rMessage.Model));
                actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model)));
                actor.SetMatrix(ref worldMatrixF);

                if (rMessage.ColorMaskHSV.HasValue)
                {
                    var color = ColorFromMask(rMessage.ColorMaskHSV.Value);
                    actor.GetRenderable().SetKeyColor(new Vector4(color, 1));
                }

                actor.SetID(rMessage.ID);

                //var entity = MyComponents.CreateEntity(rMessage.ID);
                //MyComponents.CreateRenderable(
                //    entity,
                //    MyMeshes.GetMeshId(X.TEXT(rMessage.Model)),
                //    rMessage.ColorMaskHSV.HasValue ? rMessage.ColorMaskHSV.Value : Vector3.One);
                //MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix);

                break;
            }

            case MyRenderMessageEnum.SetCharacterSkeleton:
            {
                var rMessage = (MyRenderMessageSetCharacterSkeleton)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID);

                if (actor != null)
                {
                    actor.GetSkinning().SetSkeleton(rMessage.SkeletonBones, rMessage.SkeletonIndices);
                }

                //var entity = MyComponents.GetEntity(rMessage.CharacterID);
                //MyComponents.SetSkeleton(entity, rMessage.SkeletonBones, rMessage.SkeletonIndices);

                break;
            };

            case MyRenderMessageEnum.SetCharacterTransforms:
            {
                var rMessage = (MyRenderMessageSetCharacterTransforms)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID);

                if (actor != null)
                {
                    actor.GetSkinning().SetAnimationBones(rMessage.RelativeBoneTransforms);
                }
                //var entity = MyComponents.GetEntity(rMessage.CharacterID);
                //MyComponents.SetAnimation(entity, rMessage.RelativeBoneTransforms);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderEntity:
            {
                var rMessage = (MyRenderMessageUpdateRenderEntity)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null && actor.GetRenderable() != null)
                {
                    if (rMessage.ColorMaskHSV.HasValue)
                    {
                        actor.GetRenderable().SetKeyColor(new Vector4(ColorFromMask(rMessage.ColorMaskHSV.Value), 1));
                    }
                    actor.GetRenderable().SetDithering(rMessage.Dithering);

                    if (rMessage.Dithering < 0)
                    {
                    }
                }

                break;
            }

            case MyRenderMessageEnum.ChangeModelMaterial:
            {
                var rMessage = (MyRenderMessageChangeModelMaterial)message;



                //var matId = MyMeshMaterialId.NULL;
                //if (rMessage.Material.ToLower().Contains("debug"))
                //{
                //    matId = MyMeshMaterials1.DebugMaterialId;
                //}
                //else
                //{
                //    matId = MyMeshMaterials1.GetMaterialId(rMessage.Material);
                //}

                //MyAssetsLoader.GetModel(rMessage.Model).SetMaterial_SLOW(MyMeshMaterials1.GetProxyId(matId));

                break;
            }

                #endregion

                #region Render objects

            case MyRenderMessageEnum.CreateRenderEntity:
            {
                var rMessage = (MyRenderMessageCreateRenderEntity)message;

                Matrix m = (Matrix)rMessage.WorldMatrix;

                var actor = MyActorFactory.CreateSceneObject();
                if (rMessage.Model != null)
                {
                    var model = MyAssetsLoader.ModelRemap.Get(rMessage.Model, rMessage.Model);

                    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //if (MyDestructionMesh.ModelsDictionary.ContainsKey(model))
                    //{
                    //    //actor.GetRenderable().SetModel(MyDestructionMesh.ModelsDictionary.Get(model));
                    //    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //}
                    //else
                    //{
                    //    //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(model));
                    //    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //}
                }

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref m);

                break;
            }

            case MyRenderMessageEnum.CreateRenderVoxelDebris:
            {
                var rMessage = (MyRenderMessageCreateRenderVoxelDebris)message;

                Matrix m = (Matrix)rMessage.WorldMatrix;

                var actor = MyActorFactory.CreateSceneObject();
                if (rMessage.Model != null)
                {
                    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model)));
                }

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref m);

                MyRenderableComponent.DebrisEntityVoxelMaterial[rMessage.ID] = rMessage.VoxelMaterialIndex;

                break;
            }

            case MyRenderMessageEnum.UpdateRenderObject:
            {
                var rMessage = (MyRenderMessageUpdateRenderObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    Matrix m = (Matrix)rMessage.WorldMatrix;
                    actor.SetMatrix(ref m);
                    if (rMessage.AABB.HasValue)
                    {
                        actor.SetAabb((BoundingBox)rMessage.AABB.Value);
                    }
                }

                var entity = MyComponents.GetEntity(rMessage.ID);
                if (entity != EntityId.NULL)
                {
                    MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix);
                    if (rMessage.AABB.HasValue)
                    {
                        var aabb = rMessage.AABB.Value;
                        MyComponents.SetAabb(entity, ref aabb);
                    }
                }

                break;
            }

            case MyRenderMessageEnum.RemoveRenderObject:
            {
                var rMessage = (MyRenderMessageRemoveRenderObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    if (actor.GetRenderable() != null && actor.GetRenderable().GetModel().Info.Dynamic)
                    {
                        MyMeshes.RemoveMesh(actor.GetRenderable().GetModel());
                    }

                    actor.Destruct();
                }

                var instancing = MyInstancing.Get(rMessage.ID);
                if (instancing != InstancingId.NULL)
                {
                    MyInstancing.Remove(rMessage.ID, instancing);
                }

                var light = MyLights.Get(rMessage.ID);
                if (light != LightId.NULL)
                {
                    MyLights.Remove(rMessage.ID, light);
                }

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ID);
                if (clipmap != null)
                {
                    clipmap.RemoveFromUpdate();
                }

                break;
            }

            case MyRenderMessageEnum.UpdateRenderObjectVisibility:
            {
                var rMessage = (MyRenderMessageUpdateRenderObjectVisibility)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    actor.SetVisibility(rMessage.Visible);
                }

                break;
            }


            case MyRenderMessageEnum.CreateRenderInstanceBuffer:
            {
                var rMessage = (MyRenderMessageCreateRenderInstanceBuffer)message;

                //var instancing = MyComponentFactory<MyInstancingComponent>.Create();
                //instancing.SetID(rMessage.ID);
                //instancing.Init(rMessage.Type);
                //instancing.SetDebugName(rMessage.DebugName);

                MyInstancing.Create(rMessage.ID, rMessage.Type, rMessage.DebugName);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderInstanceBuffer:
            {
                var rMessage = (MyRenderMessageUpdateRenderInstanceBuffer)message;

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID);
                //if(instancing != null)
                //{
                //    instancing.UpdateGeneric(rMessage.InstanceData, rMessage.Capacity);
                //}

                MyInstancing.UpdateGeneric(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity);

                rMessage.InstanceData.Clear();

                break;
            }

            case MyRenderMessageEnum.UpdateRenderCubeInstanceBuffer:
            {
                var rMessage = (MyRenderMessageUpdateRenderCubeInstanceBuffer)message;

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID);
                //if (instancing != null)
                //{
                //    instancing.UpdateCube(rMessage.InstanceData, rMessage.Capacity);
                //}
                MyInstancing.UpdateCube(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity);

                rMessage.InstanceData.Clear();

                break;
            }

            case MyRenderMessageEnum.SetInstanceBuffer:
            {
                var rMessage = (MyRenderMessageSetInstanceBuffer)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.InstanceBufferId);

                if (actor != null)
                {
                    //if (actor.GetComponent(MyActorComponentEnum.Instancing) != instancing)
                    //{
                    //    actor.AddComponent(instancing);
                    //}
                    //actor.SetLocalAabb(rMessage.LocalAabb);
                    //actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart);

                    actor.GetRenderable().SetInstancing(MyInstancing.Get(rMessage.InstanceBufferId));
                    actor.SetLocalAabb(rMessage.LocalAabb);
                    actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart);
                }

                break;
            }

            case MyRenderMessageEnum.CreateManualCullObject:
            {
                var rMessage = (MyRenderMessageCreateManualCullObject)message;

                var actor = MyActorFactory.CreateGroup();
                actor.SetID(rMessage.ID);
                Matrix m = (Matrix)rMessage.WorldMatrix;
                actor.SetMatrix(ref m);

                break;
            }

            case MyRenderMessageEnum.SetParentCullObject:
            {
                var rMessage = (MyRenderMessageSetParentCullObject)message;

                var child = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                var parent = MyIDTracker <MyActor> .FindByID(rMessage.CullObjectID);

                if (child != null && parent != null && parent.GetGroupRoot() != null && child.GetGroupLeaf() == null)
                {
                    child.SetRelativeTransform(rMessage.ChildToParent);
                    parent.GetGroupRoot().Add(child);
                }

                break;
            }

            case MyRenderMessageEnum.CreateLineBasedObject:
            {
                var rMessage = (MyRenderMessageCreateLineBasedObject)message;

                var actor = MyActorFactory.CreateSceneObject();
                //actor.GetRenderable().SetModel(new MyDynamicMesh());

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref Matrix.Identity);

                MyMeshMaterials1.GetMaterialId("__ROPE_MATERIAL", null, "Textures/rope_cm.dds", "Textures/rope_ng.dds", "Textures/rope_add.dds", MyMesh.DEFAULT_MESH_TECHNIQUE);
                actor.GetRenderable().SetModel(MyMeshes.CreateRuntimeMesh(X.TEXT("LINE" + rMessage.ID), 1, true));

                break;
            }

            case MyRenderMessageEnum.UpdateLineBasedObject:
            {
                var rMessage = (MyRenderMessageUpdateLineBasedObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    //var mesh = actor.GetRenderable().GetMesh() as MyDynamicMesh;

                    MyVertexFormatPositionH4 []            stream0;
                    MyVertexFormatTexcoordNormalTangent [] stream1;

                    MyLineHelpers.GenerateVertexData(ref rMessage.WorldPointA, ref rMessage.WorldPointB,
                                                     out stream0, out stream1);

                    var indices  = MyLineHelpers.GenerateIndices(stream0.Length);
                    var sections = new MySectionInfo[]
                    {
                        new MySectionInfo {
                            TriCount = indices.Length / 3, IndexStart = 0, MaterialName = "__ROPE_MATERIAL"
                        }
                    };

                    MyMeshes.UpdateRuntimeMesh(MyMeshes.GetMeshId(X.TEXT("LINE" + rMessage.ID)),
                                               indices,
                                               stream0,
                                               stream1,
                                               sections,
                                               (BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB));

                    //actor.SetAabb((BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB));
                    actor.MarkRenderDirty();

                    var matrix = Matrix.CreateTranslation((Vector3)(rMessage.WorldPointA + rMessage.WorldPointB) * 0.5f);
                    actor.SetMatrix(ref matrix);
                }

                break;
            }

            case MyRenderMessageEnum.SetRenderEntityData:
            {
                var rMessage = (MyRenderMessageSetRenderEntityData)message;

                Debug.Assert(false, "MyRenderMessageSetRenderEntityData is deprecated!");

                break;
            }

            case MyRenderMessageEnum.AddRuntimeModel:
            {
                var rMessage = (MyRenderMessageAddRuntimeModel)message;

                //MyDestructionMesh mesh = MyDestructionMesh.ModelsDictionary.Get(rMessage.Name);
                //if (mesh == null)
                //{
                //mesh = new MyDestructionMesh(rMessage.Name);

                //ProfilerShort.Begin("LoadBuffers");
                //mesh.Fill(rMessage.ModelData.Indices, rMessage.ModelData.Positions, rMessage.ModelData.Normals, rMessage.ModelData.Tangents, rMessage.ModelData.TexCoords, rMessage.ModelData.Sections, rMessage.ModelData.AABB);
                //ProfilerShort.End();

                if (!MyMeshes.Exists(rMessage.Name))
                {
                    {
                        ushort[] indices = new ushort[rMessage.ModelData.Indices.Count];
                        for (int i = 0; i < rMessage.ModelData.Indices.Count; i++)
                        {
                            indices[i] = (ushort)rMessage.ModelData.Indices[i];
                        }
                        var verticesNum = rMessage.ModelData.Positions.Count;
                        MyVertexFormatPositionH4[]            stream0 = new MyVertexFormatPositionH4[verticesNum];
                        MyVertexFormatTexcoordNormalTangent[] stream1 = new MyVertexFormatTexcoordNormalTangent[verticesNum];
                        for (int i = 0; i < verticesNum; i++)
                        {
                            stream0[i] = new MyVertexFormatPositionH4(rMessage.ModelData.Positions[i]);
                            stream1[i] = new MyVertexFormatTexcoordNormalTangent(
                                rMessage.ModelData.TexCoords[i], rMessage.ModelData.Normals[i], rMessage.ModelData.Tangents[i]);
                        }
                        var id = MyMeshes.CreateRuntimeMesh(X.TEXT(rMessage.Name), rMessage.ModelData.Sections.Count, false);
                        MyMeshes.UpdateRuntimeMesh(id, indices, stream0, stream1, rMessage.ModelData.Sections.ToArray(), rMessage.ModelData.AABB);
                    }

                    if (rMessage.ReplacedModel != null)
                    {
                        //MyAssetsLoader.ModelRemap[rMessage.ReplacedModel] = rMessage.Name;
                        MyAssetsLoader.ModelRemap[rMessage.Name] = rMessage.ReplacedModel;
                    }

                    //if (MyAssetsLoader.LOG_MESH_STATISTICS)
                    //{
                    //    mesh.DebugWriteInfo();
                    //}
                }

                break;
            }

            case MyRenderMessageEnum.UpdateModelProperties:
            {
                var rMessage = (MyRenderMessageUpdateModelProperties)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    var key = new MyEntityMaterialKey {
                        LOD = rMessage.LOD, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (rMessage.Enabled.HasValue)
                    {
                        if (!MyScene.EntityDisabledMaterials.ContainsKey(rMessage.ID))
                        {
                            MyScene.EntityDisabledMaterials.Add(rMessage.ID, new HashSet <MyEntityMaterialKey>());
                        }

                        if (!rMessage.Enabled.Value)
                        {
                            MyScene.EntityDisabledMaterials[rMessage.ID].Add(key);
                        }
                        else
                        {
                            MyScene.EntityDisabledMaterials[rMessage.ID].Remove(key);
                        }
                    }

                    var r = actor.GetRenderable();

                    if ((rMessage.Emissivity.HasValue || rMessage.DiffuseColor.HasValue) && !r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }

                    if (rMessage.Emissivity.HasValue)
                    {
                        r.ModelProperties[key].Emissivity = rMessage.Emissivity.Value;
                    }

                    if (rMessage.DiffuseColor.HasValue)
                    {
                        r.ModelProperties[key].ColorMul = rMessage.DiffuseColor.Value;
                    }

                    actor.MarkRenderDirty();
                }

                break;
            }

            case MyRenderMessageEnum.PreloadModel:
            {
                var rMessage = (MyRenderMessagePreloadModel)message;

                //MyAssetsLoader.GetModel(rMessage.Name);
                MyMeshes.GetMeshId(X.TEXT(rMessage.Name));

                break;
            }

            case MyRenderMessageEnum.ChangeMaterialTexture:
            {
                var rMessage = (MyRenderMessageChangeMaterialTexture)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID);

                if (actor != null)
                {
                    var r   = actor.GetRenderable();
                    var key = new MyEntityMaterialKey {
                        LOD = 0, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (!r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }
                    r.ModelProperties[key].TextureSwap = new MyMaterialTextureSwap {
                        TextureName = X.TEXT(rMessage.TextureName)
                    };

                    r.FreeCustomRenderTextures(key);

                    actor.MarkRenderDirty();
                }

                break;
            }

            case MyRenderMessageEnum.DrawTextToMaterial:
            {
                var rMessage = (MyRenderMessageDrawTextToMaterial)message;

                //rMessage.EntityId
                //rMessage.FontColor
                //rMessage.MaterialName
                //rMessage.Text;
                //rMessage.TextScale;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID);

                if (actor != null)
                {
                    var r   = actor.GetRenderable();
                    var key = new MyEntityMaterialKey {
                        LOD = 0, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (!r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }
                    else
                    {
                        r.ModelProperties[key].TextureSwap = null;
                    }

                    RwTexId handle = r.ModelProperties[key].CustomRenderedTexture;
                    if (handle == RwTexId.NULL && MyModelProperties.CustomTextures < MyModelProperties.MaxCustomTextures)
                    {
                        handle = MyRwTextures.CreateRenderTarget(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, true);
                        r.ModelProperties[key].CustomRenderedTexture = handle;
                        ++MyModelProperties.CustomTextures;
                    }

                    if (handle != RwTexId.NULL)
                    {
                        var clearColor = new SharpDX.Color4(rMessage.BackgroundColor.PackedValue);
                        clearColor.Alpha = 0;
                        MyRender11.ImmediateContext.ClearRenderTargetView(handle.Rtv, clearColor);

                        // my sprites renderer -> push state
                        MySpritesRenderer.PushState(new Vector2(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution));


                        MySpritesRenderer.DrawText(Vector2.Zero, new StringBuilder(rMessage.Text), rMessage.FontColor, rMessage.TextScale);
                        // render text with fonts to rt
                        // update texture of proxy
                        MySpritesRenderer.Draw(handle.Rtv, new MyViewport(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution));

                        // render to rt
                        // my sprites renderer -> pop state
                        MySpritesRenderer.PopState();


                        MyRender11.ImmediateContext.GenerateMips(handle.ShaderView);

                        actor.MarkRenderDirty();
                    }
                    else
                    {
                        MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId);
                    }
                }
                else
                {
                    MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId);
                }

                break;
            }

            case MyRenderMessageEnum.PreloadMaterials:
            {
                var rMessage = (MyRenderMessagePreloadMaterials)message;

                //MyAssetsLoader.GetMaterials(rMessage.Name);
                MyMeshes.GetMeshId(X.TEXT(rMessage.Name));

                break;
            }

                #endregion

                #region Voxels

            case MyRenderMessageEnum.CreateClipmap:
            {
                var rMessage = (MyRenderMessageCreateClipmap)message;

                var clipmap = new MyClipmapHandler(rMessage.ClipmapId, rMessage.ScaleGroup, rMessage.WorldMatrix, rMessage.SizeLod0);
                MyClipmapFactory.ClipmapByID[rMessage.ClipmapId] = clipmap;
                clipmap.Base.LoadContent();


                break;
            }

            case MyRenderMessageEnum.UpdateClipmapCell:
            {
                var rMessage = (MyRenderMessageUpdateClipmapCell)message;

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId);
                if (clipmap != null)
                {
                    clipmap.Base.UpdateCell(rMessage);
                }

                rMessage.Batches.Clear();
                break;
            }

            case MyRenderMessageEnum.InvalidateClipmapRange:
            {
                var rMessage = (MyRenderMessageInvalidateClipmapRange)message;

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId);
                if (clipmap != null)
                {
                    clipmap.Base.InvalidateRange(rMessage.MinCellLod0, rMessage.MaxCellLod0);
                }

                break;
            }

            case MyRenderMessageEnum.CreateRenderVoxelMaterials:
            {
                var rMessage = (MyRenderMessageCreateRenderVoxelMaterials)message;

                Debug.Assert(MyVoxelMaterials1.CheckIndices(rMessage.Materials));
                MyVoxelMaterials1.Set(rMessage.Materials);

                rMessage.Materials = null;

                break;
            }


                #endregion

                #region Lights

            case MyRenderMessageEnum.CreateRenderLight:
            {
                var rMessage = (MyRenderMessageCreateRenderLight)message;

                //MyLight.Create(rMessage.ID);

                MyLights.Create(rMessage.ID);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderLight:
            {
                var rMessage = (MyRenderMessageUpdateRenderLight)message;


                var light = MyLights.Get(rMessage.ID);

                if (light != LightId.NULL)
                {
                    var lightInfo = new MyLightInfo
                    {
                        Position           = rMessage.Position,
                        PositionWithOffset = rMessage.Position + rMessage.Offset * rMessage.Range * rMessage.ReflectorDirection,
                        CastsShadows       = rMessage.CastShadows,
                        ShadowsDistance    = rMessage.ShadowDistance,
                        ParentGID          = rMessage.ParentID,
                        UsedInForward      = rMessage.UseInForwardRender
                    };

                    MyLights.UpdateEntity(light, ref lightInfo);

                    if ((rMessage.Type & LightTypeEnum.PointLight) > 0)
                    {
                        MyLights.UpdatePointlight(light, rMessage.LightOn, rMessage.Range, new Vector3(rMessage.Color.R, rMessage.Color.G, rMessage.Color.B) / 255.0f * rMessage.Intensity, rMessage.Falloff);
                    }
                    if ((rMessage.Type & LightTypeEnum.Hemisphere) > 0)
                    {
                        //rMessage.Color;
                        //rMessage.Falloff;
                        //rMessage.Intensity;
                        //rMessage.LightOn;
                        //rMessage.ReflectorDirection;
                        //rMessage.ReflectorUp;
                    }
                    if ((rMessage.Type & LightTypeEnum.Spotlight) > 0)
                    {
                        // because it's so in dx9...
                        float coneMaxAngleCos = 1 - rMessage.ReflectorConeMaxAngleCos;
                        coneMaxAngleCos = (float)Math.Min(Math.Max(coneMaxAngleCos, 0.01), 0.99f);
                        MyLights.UpdateSpotlight(light, rMessage.ReflectorOn,
                                                 rMessage.ReflectorDirection, rMessage.ReflectorRange, coneMaxAngleCos, rMessage.ReflectorUp,
                                                 new Vector3(rMessage.ReflectorColor.R, rMessage.ReflectorColor.G, rMessage.ReflectorColor.B) / 255.0f * rMessage.Intensity, rMessage.ReflectorFalloff,
                                                 MyTextures.GetTexture(rMessage.ReflectorTexture, MyTextureEnum.CUSTOM));
                    }

                    if (rMessage.GlareOn)
                    {
                        MyLights.UpdateGlare(light, new MyGlareDesc
                            {
                                Enabled     = rMessage.GlareOn,
                                Material    = X.TEXT(rMessage.GlareMaterial),
                                Intensity   = rMessage.GlareIntensity,
                                QuerySize   = rMessage.GlareQuerySize,
                                Type        = rMessage.GlareType,
                                Size        = rMessage.GlareSize,
                                MaxDistance = rMessage.GlareMaxDistance,
                                Color       = rMessage.Color,
                                Direction   = rMessage.ReflectorDirection,
                                Range       = rMessage.Range
                            });
                    }
                }

                break;
            }

            case MyRenderMessageEnum.SetLightShadowIgnore:
            {
                var rMessage = (MyRenderMessageSetLightShadowIgnore)message;

                var light = MyLights.Get(rMessage.ID);
                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID2);

                if (light != LightId.NULL && actor != null)
                {
                    if (!MyLights.IgnoredEntitites.ContainsKey(light))
                    {
                        MyLights.IgnoredEntitites[light] = new HashSet <uint>();
                    }
                    MyLights.IgnoredEntitites[light].Add(rMessage.ID2);
                }

                break;
            }


            case MyRenderMessageEnum.ClearLightShadowIgnore:
            {
                var rMessage = (MyRenderMessageClearLightShadowIgnore)message;

                var light = MyLights.Get(rMessage.ID);
                if (light != LightId.NULL)
                {
                    MyLights.IgnoredEntitites.Remove(light);
                }

                break;
            }

            case MyRenderMessageEnum.UpdateFogSettings:
            {
                var rMessage = (MyRenderMessageUpdateFogSettings)message;

                MyEnvironment.FogSettings = rMessage.Settings;

                break;
            }

            case MyRenderMessageEnum.UpdateRenderEnvironment:
            {
                var rMessage = (MyRenderMessageUpdateRenderEnvironment)message;

                MyEnvironment.DirectionalLightDir       = VRageMath.Vector3.Normalize(rMessage.SunDirection);
                MyEnvironment.DirectionalLightIntensity = rMessage.SunIntensity * rMessage.SunColor.ToVector3();
                MyEnvironment.DirectionalLightEnabled   = rMessage.SunLightOn;
                MyEnvironment.DayTime           = (float)(rMessage.DayTime - Math.Truncate(rMessage.DayTime));
                MyEnvironment.SunDistance       = rMessage.DistanceToSun;
                MyEnvironment.SunColor          = rMessage.SunColor;
                MyEnvironment.SunMaterial       = rMessage.SunMaterial;
                MyEnvironment.SunSizeMultiplier = rMessage.SunSizeMultiplier;

                var skybox = rMessage.BackgroundTexture;

                m_resetEyeAdaptation = m_resetEyeAdaptation || rMessage.ResetEyeAdaptation;

                break;
            }

            case MyRenderMessageEnum.UpdateEnvironmentMap:
            {
                break;
            }

            case MyRenderMessageEnum.UpdatePostprocessSettings:
            {
                var rMessage = (MyRenderMessageUpdatePostprocessSettings)message;

                m_postprocessSettings = rMessage.Settings;

                break;
            }

            case MyRenderMessageEnum.UpdateSSAOSettings:
            {
                var rMessage = (MyRenderMessageUpdateSSAOSettings)message;


                MySSAO.Params.MinRadius  = rMessage.MinRadius;
                MySSAO.Params.MaxRadius  = rMessage.MaxRadius;
                MySSAO.Params.RadiusGrow = rMessage.RadiusGrowZScale;

                MySSAO.Params.RadiusBias    = rMessage.Bias;
                MySSAO.Params.Falloff       = rMessage.Falloff;
                MySSAO.Params.Normalization = rMessage.NormValue;
                MySSAO.Params.Contrast      = rMessage.Contrast;

                break;
            }

                #endregion

                #region Sprites
            case MyRenderMessageEnum.DrawSprite:
            case MyRenderMessageEnum.DrawSpriteNormalized:
            case MyRenderMessageEnum.DrawSpriteAtlas:
            case MyRenderMessageEnum.SpriteScissorPush:
            case MyRenderMessageEnum.SpriteScissorPop:
            {
                m_drawQueue.Enqueue(message);
                break;
            }

                #endregion

                #region Fonts and text

            case MyRenderMessageEnum.CreateFont:
            {
                var createFontMessage = message as MyRenderMessageCreateFont;
                Debug.Assert(createFontMessage != null);

                var renderFont = new MyRenderFont(createFontMessage.FontPath);
                renderFont.LoadContent();
                AddFont(createFontMessage.FontId, renderFont, createFontMessage.IsDebugFont);

                break;
            }

            case MyRenderMessageEnum.DrawString:
            {
                m_drawQueue.Enqueue(message);
                break;
            }

                #endregion

                #region Textures

            case MyRenderMessageEnum.PreloadTextures:
            {
                var preloadMsg = message as MyRenderMessagePreloadTextures;

                //MyTextureManager.PreloadTextures(preloadMsg.InDirectory, preloadMsg.Recursive);
                //MyTextures.UnloadTexture(texMessage.Texture);

                break;
            }

            case MyRenderMessageEnum.UnloadTexture:
            {
                var texMessage = (MyRenderMessageUnloadTexture)message;

                //MyTextureManager.UnloadTexture(texMessage.Texture);
                MyTextures.UnloadTexture(texMessage.Texture);

                break;
            }

            case MyRenderMessageEnum.ReloadTextures:
            {
                var reloadMsg = (MyRenderMessageReloadTextures)message;

                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyTextures.ReloadAssetTextures();

                //MyTextureManager.UnloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();

                break;
            }

            case MyRenderMessageEnum.ReloadModels:
            {
                var reloadMsg = (MyRenderMessageReloadModels)message;

                //MyMaterials.Clear();
                MyAssetsLoader.ReloadMeshes();
                MyRenderableComponent.MarkAllDirty();

                break;
            }

                #endregion

            case MyRenderMessageEnum.TakeScreenshot:
            {
                var rMessage = (MyRenderMessageTakeScreenshot)message;

                m_screenshot = new MyScreenshot(rMessage.PathToSave, rMessage.SizeMultiplier, rMessage.IgnoreSprites);

                break;
            }

            case MyRenderMessageEnum.ReloadEffects:
            {
                m_reloadShaders = true;

                //MyShaderBundleFactory.ClearCache();
                //MyShaderMaterial.ClearCache();
                //MyShaderPass.ClearCache();

                MyShaders.Recompile();
                MyMaterialShaders.Recompile();

                MyRenderableComponent.MarkAllDirty();

                foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
                {
                    f.Dispose();
                }

                break;
            }

            case MyRenderMessageEnum.PlayVideo:
            {
                var rMessage = (MyRenderMessagePlayVideo)message;

                MyVideoFactory.Create(rMessage.ID, rMessage.VideoFile);
                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Volume = rMessage.Volume;
                }

                break;
            }

            case MyRenderMessageEnum.CloseVideo:
            {
                var rMessage = (MyRenderMessageCloseVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Stop();
                    video.Dispose();
                    MyVideoFactory.Videos.Remove(rMessage.ID);
                }

                break;
            }

            case MyRenderMessageEnum.DrawVideo:
            {
                var rMessage = (MyRenderMessageDrawVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Draw(rMessage.Rectangle, rMessage.Color, rMessage.FitMode);
                }

                break;
            }

            case MyRenderMessageEnum.UpdateVideo:
            {
                var rMessage = (MyRenderMessageUpdateVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Update();
                }

                break;
            }

            case MyRenderMessageEnum.SetVideoVolume:
            {
                var rMessage = (MyRenderMessageSetVideoVolume)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Volume = rMessage.Volume;
                }

                break;
            }

            case MyRenderMessageEnum.VideoAdaptersRequest:
            {
                MyRenderProxy.SendVideoAdapters(GetAdaptersList());
                break;
            }

            case MyRenderMessageEnum.SwitchDeviceSettings:
            {
                MyRenderProxy.RenderThread.SwitchSettings((message as MyRenderMessageSwitchDeviceSettings).Settings);
                break;
            }

            case MyRenderMessageEnum.SwitchRenderSettings:
                break;         // Can be ignored as we're handling newer version of the message.

            case MyRenderMessageEnum.SwitchRenderSettings1:
            {
                UpdateRenderSettings((message as MyRenderMessageSwitchRenderSettings1).Settings);
                break;
            }

            case MyRenderMessageEnum.UnloadData:
            {
                MyRender11.UnloadData();
                break;
            }

            case MyRenderMessageEnum.CollectGarbage:
            {
                GC.Collect();
                break;
            }

                #region Debug draw

            case MyRenderMessageEnum.DebugDrawPoint:
            case MyRenderMessageEnum.DebugDrawLine3D:
            case MyRenderMessageEnum.DebugDrawLine2D:
            case MyRenderMessageEnum.DebugDrawSphere:
            case MyRenderMessageEnum.DebugDrawAABB:
            case MyRenderMessageEnum.DebugDrawAxis:
            case MyRenderMessageEnum.DebugDrawOBB:
            case MyRenderMessageEnum.DebugDrawCone:
            case MyRenderMessageEnum.DebugDrawTriangle:
            case MyRenderMessageEnum.DebugDrawCapsule:
            case MyRenderMessageEnum.DebugDrawText2D:
            case MyRenderMessageEnum.DebugDrawText3D:
            case MyRenderMessageEnum.DebugDrawModel:
            case MyRenderMessageEnum.DebugDrawTriangles:
            case MyRenderMessageEnum.DebugDrawPlane:
            case MyRenderMessageEnum.DebugDrawCylinder:
            {
                m_debugDrawMessages.Enqueue(message);
            }
            break;

            case MyRenderMessageEnum.DebugCrashRenderThread:
            {
                throw new InvalidOperationException("Forced exception");
            }
                #endregion
            }
        }
Пример #26
0
        internal static void UpdateRenderSettings(MyRenderSettings1 settings)
        {
            Log.WriteLine("UpdateRenderSettings");
            Log.IncreaseIndent();

            var prevSettings = m_renderSettings;

            m_renderSettings = settings;

            LogUpdateRenderSettings(ref settings);

            MyRenderConstants.SwitchRenderQuality(settings.Dx9Quality); //because of lod ranges

            MyRenderProxy.Settings.EnableCameraInterpolation = settings.InterpolationEnabled;
            MyRenderProxy.Settings.EnableObjectInterpolation = settings.InterpolationEnabled;

            MyRenderProxy.Settings.GrassDensityFactor = settings.GrassDensityFactor;
            if (settings.GrassDensityFactor == 0.0f)
            {
                m_renderSettings.FoliageDetails = MyFoliageDetails.DISABLED;
            }
            MyRenderProxy.Settings.VoxelQuality = settings.VoxelQuality;

            //       if(settings.GrassDensityFactor != prevSettings.GrassDensityFactor)
            //           MyRenderProxy.ReloadGrass();

            if (settings.ShadowQuality != prevSettings.ShadowQuality)
            {
                ResetShadows(MyRenderProxy.Settings.ShadowCascadeCount, settings.ShadowQuality.ShadowCascadeResolution());
            }

            if (settings.AntialiasingMode != prevSettings.AntialiasingMode)
            {
                var defineList = new List <ShaderMacro>();
                if (RenderSettings.AntialiasingMode != MyAntialiasingMode.NONE)
                {
                    defineList.Add(ShaderMultisamplingDefine());
                }
                if (DebugMode)
                {
                    defineList.Add(MyShadersDefines.DebugMacro);
                }

                GlobalShaderMacro = defineList.ToArray();

                MyShaders.Recompile();
                MyMaterialShaders.Recompile();
                MyRenderableComponent.MarkAllDirty();

                if (settings.AntialiasingMode.SamplesCount() != prevSettings.AntialiasingMode.SamplesCount())
                {
                    CreateScreenResources();
                }
            }

            if (settings.AnisotropicFiltering != prevSettings.AnisotropicFiltering)
            {
                SamplerStates.UpdateFiltering();
            }

            if (settings.TextureQuality != prevSettings.TextureQuality)
            {
                //MyTextureManager.UnloadTextures();

                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyTextures.ReloadQualityDependantTextures();

                //MyVoxelMaterials.ReloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();
            }

            m_settingsChangedListeners();

            Log.DecreaseIndent();
        }
Пример #27
0
        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;
            }
        }
Пример #28
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;
            }
        }