예제 #1
0
        //--------------------------------------------------------------
        /// <overloads>
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainRoadLayer"/> class.
        /// </summary>
        /// </overloads>
        /// 
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainRoadLayer"/> class with the default
        /// material.
        /// </summary>
        /// <param name="graphicService">The graphic service.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="graphicService"/> is <see langword="null"/>.
        /// </exception>
        public TerrainRoadLayer(IGraphicsService graphicService)
        {
            if (graphicService == null)
            throw new ArgumentNullException("graphicService");

              var effect = graphicService.Content.Load<Effect>("DigitalRune/Terrain/TerrainRoadLayer");
              Material = new Material
              {
            { "Detail", new EffectBinding(graphicService, effect, null, EffectParameterHint.Material) }
              };

              FadeOutStart = int.MaxValue;
              FadeOutEnd = int.MaxValue;
              TileSize = 1;
              DiffuseColor = new Vector3F(1, 1, 1);
              SpecularColor = new Vector3F(1, 1, 1);
              SpecularPower = 10;
              Alpha = 1;
              DiffuseTexture = graphicService.GetDefaultTexture2DWhite();
              SpecularTexture = graphicService.GetDefaultTexture2DBlack();
              NormalTexture = graphicService.GetDefaultNormalTexture();
              HeightTextureScale = 1;
              HeightTexture = graphicService.GetDefaultTexture2DBlack();
              RoadLength = 1;
        }
예제 #2
0
        protected virtual void CloneCore(Material source)
        {
            Name = source.Name;

              // Clone all effect bindings (deep copy).
              foreach (var pass in source)
            _bindingsPerPass.Add(pass.Key, pass.Value.Clone());
        }
예제 #3
0
        private static OutlineItem CreateOutlineItem(Material material)
        {
            var item = new OutlineItem
            {
                Text     = $"Material \"{material.Name}\"",
                Icon     = MultiColorGlyphs.Texture,
                ToolTip  = ToolTipSceneNode,
                UserData = material,
            };

            return(item);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainClearLayer"/> class.
        /// </summary>
        /// <param name="graphicService">The graphic service.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="graphicService"/> is <see langword="null"/>.
        /// </exception>
        public TerrainClearLayer(IGraphicsService graphicService)
        {
            if (graphicService == null)
            throw new ArgumentNullException("graphicService");

              var effect = graphicService.Content.Load<Effect>("DigitalRune/Terrain/TerrainClearLayer");
              var effectBinding = new EffectBinding(graphicService, effect, null, EffectParameterHint.Material);
              Material = new Material
              {
            { "Base", effectBinding },
            { "Detail", effectBinding }
              };
              MaterialInstance = new MaterialInstance(Material);
        }
예제 #5
0
        public static void SetMaterial(this Submesh submesh, Material material)
        {
            if (submesh == null)
            throw new ArgumentNullException("submesh");

              var mesh = submesh.Mesh;
              if (mesh == null)
            throw new InvalidOperationException("Cannot add material to submesh. Submesh needs to be added to Mesh first.");
              if (material == null)
            throw new ArgumentNullException("material");

              var oldMaterial = GetMaterial(submesh);
              if (oldMaterial == material)
            return;

              // Find out if the old or new material is used by other submeshes which belong
              // to the same mesh.
              bool oldMaterialStillInUse = false;
              bool newMaterialAlreadyInUse = false;
              foreach (var otherSubmesh in mesh.Submeshes)
              {
            if (otherSubmesh != submesh)
            {
              Material otherMaterial = GetMaterial(otherSubmesh);
              if (otherMaterial == oldMaterial)
            oldMaterialStillInUse = true;
              else if (otherMaterial == material)
            newMaterialAlreadyInUse = true;
            }
              }

              // Remove old material from parent mesh material collection if it is not used by
              // any submesh.
              int oldIndex = submesh.MaterialIndex;
              if (!oldMaterialStillInUse && oldMaterial != null)
              {
            mesh.Materials.RemoveAt(oldIndex);

            // One material was removed --> Update indices of meshes.
            foreach (var otherSubmesh in mesh.Submeshes)
              if (otherSubmesh.MaterialIndex > oldIndex)
            otherSubmesh.MaterialIndex--;
              }

              // Add new material to parent mesh material collection if this is the first submesh
              // that uses this material.
              if (newMaterialAlreadyInUse)
              {
            // Get index of the new material.
            submesh.MaterialIndex = mesh.Materials.IndexOf(material);
              }
              else
              {
            // Add new material to the mesh at the end of the material collection.
            mesh.Materials.Add(material);
            submesh.MaterialIndex = mesh.Materials.Count - 1;
              }
        }
예제 #6
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();
    }
예제 #7
0
 private static OutlineItem CreateOutlineItem(Material material)
 {
     var item = new OutlineItem
     {
         Text = $"Material \"{material.Name}\"",
         Icon = MultiColorGlyphs.Texture,
         ToolTip = ToolTipSceneNode,
         UserData = material,
     };
     return item;
 }
예제 #8
0
    public static Mesh CreateMesh(IGraphicsService graphicsService, Texture2D texture)
    {
      if (graphicsService == null)
        throw new ArgumentNullException("graphicsService");
      if (texture == null)
        throw new ArgumentNullException("texture");

      List<Vector3> positions = new List<Vector3>();
      List<ushort> indices = new List<ushort>();

      // Create two rings of vertices around the top and bottom of the cylinder.
      for (int i = 0; i < CylinderSegments; i++)
      {
        float angle = ConstantsF.TwoPi * i / CylinderSegments;

        float x = (float)Math.Cos(angle) * CylinderSize;
        float z = (float)Math.Sin(angle) * CylinderSize;

        positions.Add(new Vector3(x, CylinderSize * 5 / 12, z));
        positions.Add(new Vector3(x, -CylinderSize * 5 / 12, z));
      }

      // Create two center vertices, used for closing the top and bottom.
      positions.Add(new Vector3(0, CylinderSize, 0));
      positions.Add(new Vector3(0, -CylinderSize, 0));

      // Create the individual triangles that make up our skydome.
      List<VertexPositionTexture> vertices = new List<VertexPositionTexture>();
      ushort index = 0;
      for (int i = 0; i < CylinderSegments; i++)
      {
        int j = (i + 1) % CylinderSegments;

        // Calculate texture coordinates for this segment of the cylinder.
        float u1 = (float)i / (float)CylinderSegments;
        float u2 = (float)(i + 1) / (float)CylinderSegments;

        // Two triangles form a quad, one side segment of the cylinder.
        vertices.Add(new VertexPositionTexture(positions[i * 2], new Vector2(u1, TexCoordTop)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[j * 2], new Vector2(u2, TexCoordTop)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[i * 2 + 1], new Vector2(u1, TexCoordBottom)));
        indices.Add(index++);

        vertices.Add(new VertexPositionTexture(positions[j * 2], new Vector2(u2, TexCoordTop)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[j * 2 + 1], new Vector2(u2, TexCoordBottom)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[i * 2 + 1], new Vector2(u1, TexCoordBottom)));
        indices.Add(index++);

        // Triangle fanning inward to fill the top above this segment.
        vertices.Add(new VertexPositionTexture(positions[CylinderSegments * 2], new Vector2(u1, 0)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[j * 2], new Vector2(u2, TexCoordTop)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[i * 2], new Vector2(u1, TexCoordTop)));
        indices.Add(index++);

        // Triangle fanning inward to fill the bottom below this segment.
        vertices.Add(new VertexPositionTexture(positions[CylinderSegments * 2 + 1], new Vector2(u1, 1)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[i * 2 + 1], new Vector2(u1, TexCoordBottom)));
        indices.Add(index++);
        vertices.Add(new VertexPositionTexture(positions[j * 2 + 1], new Vector2(u2, TexCoordBottom)));
        indices.Add(index++);
      }

      // Create the vertex buffer.
      VertexBuffer vertexBuffer = new VertexBuffer(
        graphicsService.GraphicsDevice,
        VertexPositionTexture.VertexDeclaration,
        vertices.Count, BufferUsage.
        None);
      vertexBuffer.SetData(vertices.ToArray());

      // Create the index buffer.
      IndexBuffer indexBuffer = new IndexBuffer(
        graphicsService.GraphicsDevice,
        IndexElementSize.SixteenBits,
        indices.Count,
        BufferUsage.None);
      indexBuffer.SetData(indices.ToArray());

      // Create a submesh, which is a set of primitives which can be rendered in 
      // one draw call.
      Submesh submesh = new Submesh
      {
        PrimitiveCount = indices.Count / 3,
        PrimitiveType = PrimitiveType.TriangleList,
        StartIndex = 0,
        StartVertex = 0,
        VertexCount = vertices.Count,
        VertexBuffer = vertexBuffer,
        IndexBuffer = indexBuffer,
      };

      // Create a mesh (which is collection of submeshes and materials).
      Mesh mesh = new Mesh
      {
        Name = "Sky",
        BoundingShape = new CylinderShape(CylinderSize, 2 * CylinderSize),
      };
      mesh.Submeshes.Add(submesh);

      // Create a BasicEffectBinding which wraps the XNA BasicEffect.
      // An EffectBinding connects an effect with effect parameter values ("effect 
      // parameter binding"). Some of these parameter values are defined here. Others, 
      // like World matrices, light parameters, etc. are automatically updated by 
      // the graphics engine in each frame.
      BasicEffectBinding effectBinding = new BasicEffectBinding(graphicsService, null)
      {
        LightingEnabled = false,
        TextureEnabled = true,
        VertexColorEnabled = false
      };
      effectBinding.Set("Texture", texture);
      effectBinding.Set("SpecularColor", new Vector3(0, 0, 0));

      // Create a material, which is a collection of effect bindings - one effect 
      // binding for each "render pass". The sky mesh should be rendered in the 
      // "Sky" render pass. This render pass name is an arbitrary string that is 
      // used in SampleGraphicsScreen.cs.
      Material material = new Material();
      material.Add("Sky", effectBinding);

      // Assign the material to the submesh.
      submesh.SetMaterial(material);

      return mesh;
    }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainDecalLayer"/> class with a custom
        /// material.
        /// </summary>
        /// <param name="material">The material.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="material"/> is <see langword="null"/>.
        /// </exception>
        public TerrainDecalLayer(Material material)
        {
            if (material == null)
            throw new ArgumentNullException("material");

              // Use a down orientation per default.
              Pose = new Pose(Matrix33F.CreateRotationX(-ConstantsF.PiOver2));

              Material = material;
              UpdateAabb();
        }
예제 #10
0
    private MeshNode CreateMeshNode(IEnumerable<Submesh> submeshes, Color color)
    {
      var mesh = new Mesh();
      mesh.Submeshes.AddRange(submeshes);

      var material = new Material();
      BasicEffectBinding defaultEffectBinding = new BasicEffectBinding(GraphicsService, null)
      {
        LightingEnabled = true,
        TextureEnabled = false,
        VertexColorEnabled = false
      };
      defaultEffectBinding.Set("DiffuseColor", color.ToVector4());
      defaultEffectBinding.Set("SpecularColor", new Vector3(1, 1, 1));
      defaultEffectBinding.Set("SpecularPower", 100f);
      material.Add("Default", defaultEffectBinding);

      var triangleMesh = mesh.ToTriangleMesh();
      var shape = new TriangleMeshShape(triangleMesh);
      var aabb = shape.GetAabb();
      mesh.BoundingShape = new TransformedShape(
        new GeometricObject(
          new BoxShape(aabb.Extent),
          new Pose(aabb.Center)));

      mesh.Materials.Add(material);
      foreach (var submesh in mesh.Submeshes)
        submesh.MaterialIndex = 0;

      return new MeshNode(mesh);
    }
예제 #11
0
        //--------------------------------------------------------------
        /// <overloads>
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainDecalLayer"/> class.
        /// </summary>
        /// </overloads>
        /// 
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainDecalLayer"/> class with the default
        /// material.
        /// </summary>
        /// <param name="graphicService">The graphic service.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="graphicService"/> is <see langword="null"/>.
        /// </exception>
        public TerrainDecalLayer(IGraphicsService graphicService)
        {
            if (graphicService == null)
            throw new ArgumentNullException("graphicService");

              // Use a down orientation per default.
              Pose = new Pose(Matrix33F.CreateRotationX(-ConstantsF.PiOver2));

              var effect = graphicService.Content.Load<Effect>("DigitalRune/Terrain/TerrainDecalLayer");
              Material = new Material
              {
            { "Detail", new EffectBinding(graphicService, effect, null, EffectParameterHint.Material) }
              };

              FadeOutStart = int.MaxValue;
              FadeOutEnd = int.MaxValue;
              Width = 1;
              Height = 1;
              DiffuseColor = new Vector3F(1, 1, 1);
              SpecularColor = new Vector3F(1, 1, 1);
              SpecularPower = 10;
              Alpha = 1;
              DiffuseTexture = graphicService.GetDefaultTexture2DWhite();
              SpecularTexture = graphicService.GetDefaultTexture2DBlack();
              NormalTexture = graphicService.GetDefaultNormalTexture();
              HeightTextureScale = 1;
              HeightTexture = graphicService.GetDefaultTexture2DBlack();

              UpdateAabb();
        }
예제 #12
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();
    }
예제 #13
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();
    }
예제 #14
0
    public ParallaxMappingSample(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);
      Services.Register(typeof(IScene), null, _graphicsScreen.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);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      GameObjectService.Objects.Add(new GrabObject(Services));
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
      GameObjectService.Objects.Add(new DynamicSkyObject(Services, false, false, true));
      GameObjectService.Objects.Add(new DynamicObject(Services, 1));
      GameObjectService.Objects.Add(new DynamicObject(Services, 1));
      GameObjectService.Objects.Add(new DynamicObject(Services, 1));
      GameObjectService.Objects.Add(new DynamicObject(Services, 2));
      GameObjectService.Objects.Add(new DynamicObject(Services, 2));
      GameObjectService.Objects.Add(new DynamicObject(Services, 2));

      // Add a few palm trees.
      Random random = new Random(12345);
      for (int i = 0; i < 10; i++)
      {
        Vector3F position = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
        Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
        float scale = random.NextFloat(0.5f, 1.2f);
        GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
      }

      // Load ground model which uses normal mapping.
      var modelNode = ContentManager.Load<ModelNode>("Parallax/Ground");
      _meshNode = modelNode.Children.OfType<MeshNode>().First().Clone();
      _meshNode.ScaleLocal = new Vector3F(0.1f);
      _meshNode.IsStatic = true;

      Debug.Assert(_meshNode.Mesh.Materials.Count == 1, "Mesh should have only one material.");

      // Load materials with normal mapping, parallax mapping and parallax occlusion mapping.
      _normalMaterial = ContentManager.Load<Material>("Parallax/Normal").Clone();
      _parallaxMappingMaterial = ContentManager.Load<Material>("Parallax/PM").Clone();
      _parallaxOcclusionMappingMaterial = ContentManager.Load<Material>("Parallax/POM").Clone();

      // Get default values from materials.
      var parameterBindings = _parallaxOcclusionMappingMaterial["Material"].ParameterBindings;
      _heightScale = ((ConstParameterBinding<float>)parameterBindings["HeightScale"]).Value;
      _heightBias = ((ConstParameterBinding<float>)parameterBindings["HeightBias"]).Value;
      _lodThreshold = ((ConstParameterBinding<int>)parameterBindings["LodThreshold"]).Value;
      _maxSamples = ((ConstParameterBinding<int>)parameterBindings["MaxSamples"]).Value;
      _shadowStrength = ((ConstParameterBinding<float>)parameterBindings["ShadowStrength"]).Value;

      // Start test with POM material.
      _currentMaterialIndex = 2;
      UpdateMesh();

      // Add nodes to scene graph.
      _graphicsScreen.Scene.Children.Add(_meshNode);

      // Create rigid body for ground plane.
      Simulation.RigidBodies.Add(new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
      {
        MotionType = MotionType.Static,
      });
    }
예제 #15
0
        //--------------------------------------------------------------
        /// <summary>
        /// Called when a new <see cref="TerrainTile"/> is created without explicitly specifying a
        /// <see cref="Material"/>.
        /// </summary>
        /// <param name="graphicsService">The graphics service.</param>
        /// <returns>The default material.</returns>
        /// <remarks>
        /// <strong>Notes to Inheritors:</strong>
        /// This method may be executed in the constructor of the <see cref="TerrainTile"/> class.
        /// Therefore, the <see cref="TerrainTile"/> instance may not be fully initialized when this
        /// method is called!
        /// </remarks>
        protected virtual Material OnCreateMaterial(IGraphicsService graphicsService)
        {
            if (graphicsService == null)
            throw new ArgumentNullException("graphicsService");

              object data;
              graphicsService.Data.TryGetValue(DefaultMaterialKey, out data);

              var material = data as Material;
              if (material == null)
              {
            material = new Material
            {
              {
            "Base",
            new EffectBinding(
              graphicsService,
              graphicsService.Content.Load<Effect>("DigitalRune/Terrain/TerrainGeometryLayer"),
              null,
              EffectParameterHint.Material)
              },
              {
            "Detail",
            new EffectBinding(
              graphicsService,
              graphicsService.Content.Load<Effect>("DigitalRune/Terrain/TerrainHoleLayer"),
              null,
              EffectParameterHint.Material)
              }
            };

            graphicsService.Data[DefaultMaterialKey] = material;
              }

              return material;
        }
예제 #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainTile"/> class with the specified
        /// material.
        /// </summary>
        /// <param name="graphicsService">The graphic service.</param>
        /// <param name="material">The material. Can be <see langword="null"/> - see remarks.</param>
        /// <remarks>
        /// The specified material is used to render the terrain geometry (heights, normals, holes) into
        /// the clipmaps. When the <paramref name="material"/> is <see langword="null"/>, no geometry is
        /// rendered into the terrain tile.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="graphicsService"/> is <see langword="null"/>.
        /// </exception>
        public TerrainTile(IGraphicsService graphicsService, Material material)
        {
            if (graphicsService == null)
            throw new ArgumentNullException("graphicsService");

              Material = material;
              Layers = new TerrainLayerCollection(this);

              UpdateAabb();
        }
예제 #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainMaterialLayer"/> class with a custom
        /// material.
        /// </summary>
        /// <param name="material">The material.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="material"/> is <see langword="null"/>.
        /// </exception>
        public TerrainMaterialLayer(Material material)
        {
            if (material == null)
            throw new ArgumentNullException("material");

              Material = material;
        }
예제 #18
0
        //--------------------------------------------------------------
        /// <overloads>
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainMaterialLayer"/> class.
        /// </summary>
        /// </overloads>
        /// 
        /// <summary>
        /// Initializes a new instance of the <see cref="TerrainMaterialLayer"/> class with the default
        /// material.
        /// </summary>
        /// <param name="graphicService">The graphic service.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="graphicService"/> is <see langword="null"/>.
        /// </exception>
        public TerrainMaterialLayer(IGraphicsService graphicService)
        {
            if (graphicService == null)
            throw new ArgumentNullException("graphicService");

              var effect = graphicService.Content.Load<Effect>("DigitalRune/Terrain/TerrainMaterialLayer");
              Material = new Material
              {
            { "Detail", new EffectBinding(graphicService, effect, null, EffectParameterHint.Material) }
              };

              FadeOutStart = int.MaxValue;
              FadeOutEnd = int.MaxValue;
              TileSize = 1;
              DiffuseColor = new Vector3F(1, 1, 1);
              SpecularColor = new Vector3F(1, 1, 1);
              SpecularPower = 10;
              Alpha = 1;
              DiffuseTexture = graphicService.GetDefaultTexture2DWhite();
              SpecularTexture = graphicService.GetDefaultTexture2DBlack();
              NormalTexture = graphicService.GetDefaultNormalTexture();
              HeightTextureScale = 1;
              HeightTextureBias = 0;
              HeightTexture = graphicService.GetDefaultTexture2DBlack();
              TriplanarTightening = -1;
              TintStrength = 1;
              TintTexture = graphicService.GetDefaultTexture2DWhite();
              BlendThreshold = 0.5f;
              BlendRange = 1f;
              BlendHeightInfluence = 0;
              BlendNoiseInfluence = 0;
              BlendTextureChannel = 0;
              BlendTexture = graphicService.GetDefaultTexture2DWhite();
              NoiseTileSize = 1;
              TerrainHeightMin = -1e20f;
              TerrainHeightMax = +1e20f;
              TerrainHeightBlendRange = 1f;
              TerrainSlopeMin = -ConstantsF.Pi;
              TerrainSlopeMax = ConstantsF.Pi;
              TerrainSlopeBlendRange = MathHelper.ToRadians(10);
        }