private EffectParameterBinding CreateNoiseMapBinding <T>(Effect effect,
                                                                 EffectParameter parameter, IDictionary <string, object> opaqueData) where T : Texture
        {
            var noiseMap = NoiseHelper.GetNoiseTexture(_graphicsService);

            return(new ConstParameterBinding <T>(effect, parameter, noiseMap as T));
        }
        public TerrainTextureSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);

            var scene = _graphicsScreen.Scene;

            Services.Register(typeof(IScene), null, scene);

            // Add gravity and damping to the physics simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services, 60);

            cameraGameObject.ResetPose(new Vector3F(0, 1.8f, 0), 0, 0);
            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            for (int i = 0; i < 10; i++)
            {
                GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            }

            GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true));

            // Create a simple flat terrain.
            var terrain = new Terrain();

            _terrainTile = new TerrainTile(GraphicsService)
            {
                OriginX  = -100,
                OriginZ  = -100,
                CellSize = 1,
            };
            terrain.Tiles.Add(_terrainTile);

            // Create a flat dummy height texture.
            float[]   heights       = new float[200 * 200];
            Texture2D heightTexture = null;

            TerrainHelper.CreateHeightTexture(
                GraphicsService.GraphicsDevice,
                heights,
                200,
                200,
                false,
                ref heightTexture);
            _terrainTile.HeightTexture = heightTexture;

            var shadowMapEffect = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainShadowMap");
            var gBufferEffect   = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainGBuffer");
            var materialEffect  = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainMaterial");
            var material        = new Material
            {
                { "ShadowMap", new EffectBinding(GraphicsService, shadowMapEffect, null, EffectParameterHint.Material) },
                { "GBuffer", new EffectBinding(GraphicsService, gBufferEffect, null, EffectParameterHint.Material) },
                { "Material", new EffectBinding(GraphicsService, materialEffect, null, EffectParameterHint.Material) }
            };
            var terrainNode = new TerrainNode(terrain, material)
            {
                DetailClipmap =
                {
                    CellsPerLevel  = 1364,
                    NumberOfLevels =    9,
                    EnableMipMap   = true,
                },
            };

            scene.Children.Add(terrainNode);

            // Add 3 detail textures layers: gravel, rock, snow.
            float detailCellSize = terrainNode.DetailClipmap.CellSizes[0];
            var   materialGravel = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture  = ContentManager.Load <Texture2D>("Terrain/Gravel-Diffuse"),
                NormalTexture   = ContentManager.Load <Texture2D>("Terrain/Gravel-Normal"),
                SpecularTexture = ContentManager.Load <Texture2D>("Terrain/Gravel-Specular"),
                TileSize        = detailCellSize * 512,
                BlendRange      = 0.1f,
            };

            _terrainTile.Layers.Add(materialGravel);

            var noiseTexture = NoiseHelper.GetNoiseTexture(GraphicsService, 128, 60);

            var materialRock = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture          = ContentManager.Load <Texture2D>("Terrain/Rock-02-Diffuse"),
                NormalTexture           = ContentManager.Load <Texture2D>("Terrain/Rock-02-Normal"),
                SpecularTexture         = ContentManager.Load <Texture2D>("Terrain/Rock-02-Specular"),
                HeightTexture           = ContentManager.Load <Texture2D>("Terrain/Rock-02-Height"),
                TileSize                = detailCellSize * 1024,
                DiffuseColor            = new Vector3F(1 / 0.702f),
                BlendTexture            = noiseTexture,
                BlendTextureChannel     = 0,
                BlendRange              = 0.1f,
                TerrainHeightBlendRange = 0.1f,
            };

            _terrainTile.Layers.Add(materialRock);

            var materialSnow = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture      = ContentManager.Load <Texture2D>("Terrain/Snow-Diffuse"),
                NormalTexture       = ContentManager.Load <Texture2D>("Terrain/Snow-Normal"),
                SpecularTexture     = ContentManager.Load <Texture2D>("Terrain/Snow-Specular"),
                TileSize            = detailCellSize * 512,
                BlendTexture        = noiseTexture,
                BlendTextureChannel = 1,
                BlendRange          = 0.1f,
            };

            _terrainTile.Layers.Add(materialSnow);

            // Create a flat plane for collision detection.
            var rigidBody = new RigidBody(new PlaneShape(), new MassFrame(), null)
            {
                MotionType = MotionType.Static,
            };

            Simulation.RigidBodies.Add(rigidBody);

            CreateGuiControls();
        }