예제 #1
0
    //--------------------------------------------------------------
    #region Methods
    //--------------------------------------------------------------

    protected override void OnLoad()
    {
      // Get common services and game objects.
      _graphicsService = _services.GetInstance<IGraphicsService>();
      var content = _services.GetInstance<ContentManager>();
      var scene = _services.GetInstance<IScene>();
      _simulation = _services.GetInstance<Simulation>();
      var gameObjectService = _services.GetInstance<IGameObjectService>();
      _cameraObject = gameObjectService.Objects.OfType<CameraObject>().First();
      _previousCameraFar = _cameraObject.CameraNode.Camera.Projection.Far;

      // Create a new terrain.
      var terrain = new Terrain();
      _terrainTile = new TerrainTile(_graphicsService)
      {
        CellSize = 2,
      };
      terrain.Tiles.Add(_terrainTile);

      var shadowMapEffect = content.Load<Effect>("DigitalRune/Terrain/TerrainShadowMap");
      var gBufferEffect = content.Load<Effect>("DigitalRune/Terrain/TerrainGBuffer");
      var materialEffect = content.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) }
      };
      TerrainNode = new TerrainNode(terrain, material)
      {
        BaseClipmap =
        {
          CellsPerLevel = 128,
          NumberOfLevels = 6,
        },
        DetailClipmap =
        {
          CellsPerLevel = 1364,
          NumberOfLevels = 9,
        },
      };
      scene.Children.Add(TerrainNode);

      // Create a rigid body with a height field for collision detection.
      var heightField = new HeightField
      {
        Depth = 1,
        UseFastCollisionApproximation = false,
      };
      _rigidBody = new RigidBody(heightField, new MassFrame(), null)
      {
        MotionType = MotionType.Static,
        UserData = _terrainTile,
      };
      _simulation.RigidBodies.Add(_rigidBody);

      InitializeHeightsAndNormals();

      InitializeClipmapCellSizes();

      InitializeTerrainLayers(content);

      // Enable mipmaps when using anisotropic filtering on AMD graphics cards:
      //TerrainNode.DetailClipmap.EnableMipMap = true;

      CreateGuiControls();
    }
예제 #2
0
    protected override void OnUnload()
    {
      _cameraObject = null;

      // Remove terrain from scene.
      TerrainNode.Parent.Children.Remove(TerrainNode);

      TerrainNode.Dispose(false);
      TerrainNode = null;

      // We have to dispose the textures which were not loaded via the content manager.
      _terrainTile.HeightTexture.SafeDispose();
      _terrainTile.HeightTexture = null;
      _terrainTile.NormalTexture.SafeDispose();
      _terrainTile.NormalTexture = null;

      _rigidBody.Simulation.RigidBodies.Remove(_rigidBody);

      _terrainTile = null;
      _rigidBody = null;
    }
예제 #3
0
    //--------------------------------------------------------------
    #region Methods
    //--------------------------------------------------------------

    protected override void OnLoad()
    {
      // Get common services and game objects.
      _graphicsService = _services.GetInstance<IGraphicsService>();
      _graphicsScreen = _graphicsService.Screens.OfType<DeferredGraphicsScreen>().First();
      var content = _services.GetInstance<ContentManager>();
      var scene = _services.GetInstance<IScene>();
      _simulation = _services.GetInstance<Simulation>();
      var gameObjectService = _services.GetInstance<IGameObjectService>();
      _cameraObject = gameObjectService.Objects.OfType<CameraObject>().First();
      _previousCameraFar = _cameraObject.CameraNode.Camera.Projection.Far;

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

      // The terrain is made up of terrain tiles which can be loaded independently. 
      // Each terrain tile consists of height and normal textures which define the terrain
      // geometry and terrain layers which define the material (detail textures).
      // In this sample we create 2x2 tiles.
      _tiles = new Tile[2, 2];
      for (int row = 0; row < 2; row++)
      {
        for (int column = 0; column < 2; column++)
        {
          // Create a tile and add it to the terrain.
          // (The tile content is loaded later.)
          var terrainTile = new TerrainTile(_graphicsService)
          {
            CellSize = 1,   // The terrain has a resolution of 1 height sample per world space unit.
          };
          terrain.Tiles.Add(terrainTile);

          // Create a rigid body with a height field for collision detection and add
          // it to the simulation. (The height data is loaded later.)
          var heightField = new HeightField
          {
            Depth = 1,
            UseFastCollisionApproximation = false,
          };
          var rigidBody = new RigidBody(heightField, new MassFrame(), null)
          {
            MotionType = MotionType.Static,
            UserData = terrainTile,
          };
          _simulation.RigidBodies.Add(rigidBody);

          // Store the tile for use later in this sample.
          _tiles[row, column] = new Tile
          {
            TerrainTile = terrainTile,
            RigidBody = rigidBody,
          };
        }
      }

      // Create a terrain node which represents the terrain in the scene graph.
      // The terrain node is rendered by the TerrainRenderer (see DeferredGraphicsScreen).
      // The material used to render the terrain is customizable.  The material must specify 
      // the effects for the different render passes which we use in the DeferredGraphicsScreen 
      // ("ShadowMap", "GBuffer", "Material").
      // The prebuilt DigitalRune content contains standard terrain effects. However, you could
      // change the effects to change how the material is rendered.
      // We can create the material by loading a .drmat file. Or we can create the material in
      // code like this:
      var shadowMapEffect = content.Load<Effect>("DigitalRune/Terrain/TerrainShadowMap");
      var gBufferEffect = content.Load<Effect>("DigitalRune/Terrain/TerrainGBuffer");
      var materialEffect = content.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) }
      };
      TerrainNode = new TerrainNode(terrain, material)
      {
        // The terrain rendering uses clipmaps.
        // The clipmaps are updated by the TerrainClipmapRenderer (see DeferredGraphicsScreen)
        // when the camera moves.
        // The base clipmap contains the basic geometry info (height, normals, hole info).
        // It also determines the terrain mesh resolution.
        BaseClipmap =
        {
          CellsPerLevel = 128,
          NumberOfLevels = 6
        },
        // The detail clipmap contains the splatted detail textures (e.g. grass, rock, ...).
        // (The max texture size in XNA is 4096x4096. That means we can fit 9 clipmap levels
        // into a single texture.)
        DetailClipmap =
        {
          CellsPerLevel = 1365,
          NumberOfLevels = 9,
        },
      };
      scene.Children.Add(TerrainNode);

      // Load the height and normal maps which define the terrain geometry.
      InitializeHeightsAndNormals();

      // Set the clipmap cell sizes.
      InitializeClipmapCellSizes();

      // Create the terrain layers which define the detail textures (e.g. grass, rock, ...)
      InitializeTerrainLayers(content);

      // Special note for AMD GPUs:
      // If we want anisotropic filtering for the terrain, then we need to enable mipmaps for
      // AMD GPUs. NVIDIA and Intel can do anisotropic filtering without mipmaps.
      //TerrainNode.DetailClipmap.EnableMipMap = true;

      CreateGuiControls();
    }
예제 #4
0
        /// <summary>
        /// Invalidates the specified terrain layer in the data cached by the renderer.
        /// </summary>
        /// <param name="tile">The terrain tile owning the terrain layer.</param>
        /// <param name="layer">The terrain layer which should be invalidated.</param>
        /// <inheritdoc cref="Invalidate()"/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="tile"/> or <paramref name="layer"/> is <see langword="null"/>.
        /// </exception>
        public void Invalidate(TerrainTile tile, TerrainLayer layer)
        {
            if (tile == null)
            throw new ArgumentNullException("tile");
              if (layer == null)
            throw new ArgumentNullException("layer");

              UpdateAabb();

              Aabb aabb = layer.Aabb ?? tile.Aabb;

              if (layer.Material.Contains(TerrainClipmapRenderer.RenderPassBase)
              && !RegionsContain(InvalidBaseRegions, aabb))
              {
            InvalidBaseRegions.Add(aabb);

            // If there are 2 or more AABBs, then they need clipping.
            AreInvalidBaseRegionsClipped = (InvalidBaseRegions.Count == 1);
              }

              if (layer.Material.Contains(TerrainClipmapRenderer.RenderPassDetail)
              && !RegionsContain(InvalidDetailRegions, aabb))
              {
            InvalidDetailRegions.Add(aabb);

            // If there are 2 or more AABBs, then they need clipping.
            AreInvalidDetailRegionsClipped = (InvalidDetailRegions.Count == 1);
              }
        }
예제 #5
0
        /// <summary>
        /// Invalidates the specified terrain tile in the data cached by the renderer.
        /// </summary>
        /// <param name="tile">The terrain tile which should be invalidated.</param>
        /// <inheritdoc cref="Invalidate()"/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="tile"/> is <see langword="null"/>.
        /// </exception>
        public void Invalidate(TerrainTile tile)
        {
            if (tile == null)
            throw new ArgumentNullException("tile");

              UpdateAabb();
              Invalidate(tile.Aabb);
        }
예제 #6
0
    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();
    }