示例#1
0
    public OcclusionCullingScreen(IServiceLocator services)
      : base(services)
    {
      _sceneNodes = new List<SceneNode>();

      // Create new occlusion buffer with default settings.
      OcclusionBuffer = new OcclusionBuffer(GraphicsService);
      OcclusionBuffer.ProgressiveShadowCasterCulling = true;

      EnableCulling = true;

      // Create a second camera for rendering a top-down view of the scene.
      var topDownPerspective = new PerspectiveProjection();
      topDownPerspective.SetFieldOfView(MathHelper.ToRadians(90), 1, 1, 512);
      _topDownCameraNode = new CameraNode(new Camera(topDownPerspective));
      _topDownCameraNode.PoseWorld = new Pose(new Vector3F(-10, 120, -10));
      _topDownCameraNode.LookAt(new Vector3F(-10, 0, -10), Vector3F.UnitZ);

      _sceneQuery = new CustomSceneQuery();
      _debugRenderer = new DebugRenderer(GraphicsService, null);

      // The DigitalRune Profiler is used to measure execution times.
      Profiler.SetFormat("Occlusion.Render", 1e3f, "[ms]");
      Profiler.SetFormat("Occlusion.Query", 1e3f, "[ms]");
    }
示例#2
0
        public MyGraphicsScreen(IGraphicsService graphicsService)
            : base(graphicsService)
        {
            _meshRenderer = new MeshRenderer();

              var contentManager = ServiceLocator.Current.GetInstance<ContentManager>();
              var spriteFont = contentManager.Load<SpriteFont>("SpriteFont1");
              _debugRenderer = new DebugRenderer(graphicsService, spriteFont);

              Scene = new Scene();

              // Add a camera with a perspective projection.
              var projection = new PerspectiveProjection();
              projection.SetFieldOfView(
            ConstantsF.PiOver4,
            graphicsService.GraphicsDevice.Viewport.AspectRatio,
            0.1f,
            100.0f);
              CameraNode = new CameraNode(new Camera(projection))
              {
            Name = "CameraPerspective",
            PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(10, 5, 10), new Vector3F(0, 1, 0), new Vector3F(0, 1, 0)).Inverse),
              };
              Scene.Children.Add(CameraNode);
        }
示例#3
0
        public EditorBase(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            // Get services from the global service container.
            var services = (ServiceContainer)ServiceLocator.Current;
            UIContentManager = services.GetInstance<ContentManager>("UIContent");
            InputService = services.GetInstance<IInputService>();
            AnimationService = services.GetInstance<IAnimationService>();
            GraphicsService = services.GetInstance<IGraphicsService>();
            GameObjectService = services.GetInstance<IGameObjectService>();
            UIService = services.GetInstance<IUIService>();

            // Create a local service container which can be modified in samples:
            // The local service container is a child container, i.e. it inherits the
            // services of the global service container. Samples can add new services
            // or override existing entries without affecting the global services container
            // or other samples.
            Services = services.CreateChildContainer();

            // Load a UI theme, which defines the appearance and default values of UI controls.
            Theme theme = UIContentManager.Load<Theme>("BlendBlue/Theme");

            FigureRenderer = new FigureRenderer(GraphicsService, 2000);
            DebugRenderer = new DebugRenderer(GraphicsService, UIContentManager.Load<SpriteFont>("BlendBlue/Default"));
            UIRenderer = new UIRenderer(GraphicsService.GraphicsDevice, theme);

            UIScreen = new UIScreen("Main Screen", UIRenderer)
            {
                Background = Color.TransparentBlack,
            };

            UIService.Screens.Add(UIScreen);

            Scene = new Scene();
        }
示例#4
0
    public AvatarRagdollSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      // This sample uses for a DebugRenderer for the rendering rigid bodies.
      _debugRenderer = new DebugRenderer(GraphicsService, SpriteFont);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(0, 1, -3), ConstantsF.Pi, 0);
      GameObjectService.Objects.Add(_cameraObject);

      // Add some objects which allow the user to interact with the rigid bodies.
      _grabObject = new GrabObject(Services);
      _ballShooterObject = new BallShooterObject(Services) { Speed = 20 };
      GameObjectService.Objects.Add(_grabObject);
      GameObjectService.Objects.Add(_ballShooterObject);

      // Add some default force effects.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a ground plane in the simulation.
      Simulation.RigidBodies.Add(new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
      {
        MotionType = MotionType.Static
      });

      // Create a random avatar.
      _avatarDescription = AvatarDescription.CreateRandom();
      _avatarRenderer = new AvatarRenderer(_avatarDescription);
    }
示例#5
0
        public FigurePickerObject(IGraphicsService graphicsService, Scene scene, Editor2DCameraObject cameraObject, DebugRenderer debugRenderer)
        {
            _cameraObject = cameraObject;
            _scene = scene;
            _debugRenderer = debugRenderer;

            // Create a collision domain which manages all collision objects used for
            // picking: the picking object and the collision objects for figure nodes.
            _collisionDomain = new CollisionDomain(new CollisionDetection());

            // Create the picking object:
            // The picking object represents the mouse cursor or the reticle. Usually 
            // a ray is used, but in this example we want to use a cylinder/cone. This 
            // allows to check which objects within a certain radius of the reticle. A 
            // picking cylinder/cone is helpful for touch devices where the picking is 
            // done with an imprecise input method like the human finger.

            // We want to pick objects in 10 pixel radius around the reticle. To determine 
            // the world space size of the required cylinder/cone, we can use the projection
            // and the viewport. 
            const float pickingRadius = 0.25f;
            var projection = _cameraObject.CameraNode.Camera.Projection;
            var viewport = graphicsService.GraphicsDevice.Viewport;

            Shape pickingShape;
            if (projection is OrthographicProjection)
            {
                // Use cylinder for orthographic projections:
                // The cylinder is centered at the camera position and reaches from the 
                // camera position to the camera far plane. A TransformedShape is used
                // to rotate and translate the cylinder.
                float radius = projection.Width / viewport.Width * pickingRadius;
                pickingShape = new TransformedShape(
                  new GeometricObject(
                    new CylinderShape(radius, projection.Far),
                    new Pose(new Vector3F(0, 0, -projection.Far / 2), Matrix33F.CreateRotationX(ConstantsF.PiOver2))));
            }
            else
            {
                // Use cone for perspective projections:
                // The cone tip is at the camera position and the cone base is at the 
                // camera far plane. 

                // Compute the radius at the far plane that projects to 10 pixels in screen space.
                float radius = viewport.Unproject(
                  new Vector3(viewport.Width / 2.0f + pickingRadius, viewport.Height / 2.0f, 1),
                  (Matrix)_cameraObject.CameraNode.Camera.Projection.ToMatrix44F(),
                  Matrix.Identity,
                  Matrix.Identity).X;

                // A transformed shape is used to rotate and translate the cone.
                pickingShape = new TransformedShape(
                  new GeometricObject(
                    new ConeShape(radius, projection.Far),
                    new Pose(new Vector3F(0, 0, -projection.Far), Matrix33F.CreateRotationX(ConstantsF.PiOver2))));
            }

            // Create collision object with the picking shape.
            _pickingObject = new CollisionObject(new GeometricObject(pickingShape, _cameraObject.CameraNode.PoseWorld));
        }
示例#6
0
    public ProxyNodeSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      _renderer = new MeshRenderer();

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      _scene = new Scene();
      SceneSample.InitializeDefaultXnaLights(_scene);

      // For advanced users: Set this flag if you want to analyze the imported opaque data of
      // effect bindings.
      EffectBinding.KeepOpaqueData = true;

      // Original model in scene graph.
      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude").Clone();
      modelNode.PoseLocal = new Pose(new Vector3F(-2, 0, 0));
      var meshNode = modelNode.GetSubtree().OfType<MeshNode>().First();
      _scene.Children.Add(modelNode);

      // Clone referenced by proxy node.
      var modelNode2 = modelNode.Clone();
      var meshNode2 = modelNode2.GetSubtree().OfType<MeshNode>().First();
      meshNode2.SkeletonPose = meshNode.SkeletonPose;
      _proxyNode = new ProxyNode(null)
      {
        Name = "Proxy",
        PoseLocal = new Pose(new Vector3F(2, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)),
        ScaleLocal = new Vector3F(0.5f),
      };
      _scene.Children.Add(_proxyNode);
      _proxyNode.Node = modelNode2;

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      var mesh = meshNode.Mesh;
      foreach (var m in mesh.Materials)
      {
        //((ConstParameterBinding<Vector3>)m["Default"].ParameterBindings["SpecularColor"]).Value = new Vector3();
        ((SkinnedEffectBinding)m["Default"]).PreferPerPixelLighting = true;
      }

      var timeline = new TimelineClip(mesh.Animations.Values.First())
      {
        Duration = TimeSpan.MaxValue,
        LoopBehavior = LoopBehavior.Cycle,
      };
      AnimationService.StartAnimation(timeline, (IAnimatableProperty)meshNode.SkeletonPose);
    }
示例#7
0
    public ProjectedShadowSample(Microsoft.Xna.Framework.Game game)
    : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Create a new empty scene.
      _scene = new Scene();
      Services.Register(typeof(IScene), null, _scene);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(-8, 6, 8), -ConstantsF.PiOver4, -0.4f);
      GameObjectService.Objects.Add(_cameraObject);

      // Add a default light setup (ambient light + 3 directional lights).
      var defaultLightsObject = new DefaultLightsObject(Services);
      GameObjectService.Objects.Add(defaultLightsObject);

      // Get the main directional light.
      _mainDirectionalLightNode = ((LightNode)_scene.GetSceneNode("KeyLight"));

      // Add a ground plane model to the scene graph.
      var grid = ContentManager.Load<ModelNode>("Ground/Ground").Clone();
      grid.ScaleLocal = new Vector3F(0.3f);
      _scene.Children.Add(grid);

      // Add a tank model to the scene graph.
      var tank = ContentManager.Load<ModelNode>("Tank/tank").Clone();
      _scene.Children.Add(tank);

      // Remember the mesh nodes of tank node.
      _tankMeshNodes = tank.GetSubtree().Where(n => n is MeshNode).ToArray();

      // Create the renderers.
      _meshRenderer = new MeshRenderer();

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      _projectedShadowRenderer = new ProjectedShadowRenderer(GraphicsService)
      {
        // The plane onto which the shadows are projected. It is positioned a bit above the ground
        // plane to avoid z-fighting.
        ShadowedPlane = new Plane(new Vector3F(0, 1, 0), 0.01f),

        // The shadow color is a transparent black.
        ShadowColor = new Vector4F(0, 0, 0, 0.4f),

        // The light position is set in Update().
        //LightPosition = ...
      };
    }
示例#8
0
    public RectangleObject(IServiceLocator services)
    {
      _inputService = services.GetInstance<IInputService>();
      _gameObjectService = services.GetInstance<IGameObjectService>();
      _debugRenderer = services.GetInstance<DebugRenderer>("DebugRenderer2D");

      _left = RandomHelper.Random.NextInteger(0, 1000);
      _top = RandomHelper.Random.NextInteger(0, 600);
      SetRandomColor();
    }
示例#9
0
        //--------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="BasicGraphicsScreen"/> class.
        /// </summary>
        /// <param name="services">The services.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="services"/> is <see langword="null"/>.
        /// </exception>
        public BasicGraphicsScreen(IServiceLocator services)
            : base(services?.GetInstance<IGraphicsService>())
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            _meshRenderer = new MeshRenderer();
            _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

            var contentManager = services.GetInstance<ContentManager>();
            var spriteFont = contentManager.Load<SpriteFont>("DigitalRune.Editor.Game/Fonts/DejaVuSans");
            DebugRenderer = new DebugRenderer(GraphicsService, spriteFont);

            Scene = new Scene();
        }
示例#10
0
    public FigureSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");

      _figureRenderer = new FigureRenderer(GraphicsService, 2048);
      _spriteRenderer = new SpriteRenderer(GraphicsService, spriteFont);
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = Color.Black,
        DefaultTextPosition = new Vector2F(20, 40)
      };

      _scene = new Scene();

      // To draw figures, they are flattened (= converted to line segments) 
      // internally. Figure.Tolerance defines the allowed error between the 
      // smooth and the flattened curve.
      Figure.Tolerance = 0.0001f;

      // Add some FigureNodes to the scene.
      CreateGrid();
      CreateGridClone();
      CreateRandomPath();
      CreateRectangles();
      CreateEllipses();
      CreateAlphaBlendedFigures();
      CreateChain();
      CreateGizmo(spriteFont);
      CreateFlower();

      // Add a game object which handles the picking:
      GameObjectService.Objects.Add(new FigurePickerObject(GraphicsService, _scene, _cameraObject, _debugRenderer));
    }
示例#11
0
    public DebugRendererSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // Load a sprite font.
      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");

      // Create a new debug renderer.
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = Color.White,
      };

      // A normal XNA model.
      _xnaModel = ContentManager.Load<Model>("Saucer3/saucer");

      // A DigitalRune model.
      _modelNode = ContentManager.Load<ModelNode>("Dude/Dude").Clone();
      _modelNode.PoseLocal = new Pose(new Vector3F(6, 0, -7));

      // Create a geometric object with a height field shape.
      var numberOfSamplesX = 20;
      var numberOfSamplesZ = 20;
      var samples = new float[numberOfSamplesX * numberOfSamplesZ];
      for (int z = 0; z < numberOfSamplesZ; z++)
        for (int x = 0; x < numberOfSamplesX; x++)
          samples[z * numberOfSamplesX + x] = 1.0f + (float)(Math.Cos(z / 2f) * Math.Sin(x / 2f) * 1.0f);
      HeightField heightField = new HeightField(0, 0, 120, 120, samples, numberOfSamplesX, numberOfSamplesZ);
      _geometricObject = new GeometricObject(heightField, new Pose(new Vector3F(5, 0, -5)))
      {
        Scale = new Vector3F(0.01f, 0.05f, 0.02f),
      };
    }
示例#12
0
    public ObliqueFrustumSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var graphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, graphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      TestClippedProjection();
    }
示例#13
0
    public BasicAvatarSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      // This sample uses for a DebugRenderer for the rendering Avatar skeleton.
      _debugRenderer = new DebugRenderer(GraphicsService, SpriteFont)
      {
        DefaultColor = Color.Black,
        DefaultTextPosition = new Vector2F(10),
      };

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(0, 1, -3), ConstantsF.Pi, 0);
      GameObjectService.Objects.Add(_cameraObject);

      // Create a random avatar.
      _avatarDescription = AvatarDescription.CreateRandom();
      _avatarRenderer = new AvatarRenderer(_avatarDescription);
    }
示例#14
0
    public CustomSceneNodeSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // Create a new empty scene.
      _scene = new Scene();

      // Add the camera node to the scene.
      _scene.Children.Add(_cameraObject.CameraNode);

      // Add a few TextNodes. Position them along a circle.
      for (int i = 0; i < 36; i++)
      {
        Vector3F position = Matrix33F.CreateRotationZ(MathHelper.ToRadians((float)i * 10)) * new Vector3F(1, 0, 0);
        var textNode = new TextNode
        {
          PoseLocal = new Pose(position),
          Color = Color.Yellow,
          Text = i.ToString()
        };
        _scene.Children.Add(textNode);
      }

      // Initialize the TextRenderer.
      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _textRenderer = new TextRenderer(GraphicsService, spriteFont);

      // For debugging:
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);
    }
示例#15
0
        //--------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="DebugGraphicsScreen" /> class.
        /// </summary>
        /// <param name="services">The services.</param>
        public DebugGraphicsScreen(IServiceLocator services)
            : base(services?.GetInstance<IGraphicsService>())
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            Coverage = GraphicsScreenCoverage.Partial;
            _spriteBatch = GraphicsService.GetSpriteBatch();
            _whiteTexture = GraphicsService.GetDefaultTexture2DWhite();

            var contentManager = services.GetInstance<ContentManager>();
            var spriteFont = contentManager.Load<SpriteFont>("DigitalRune.Editor.Game/Fonts/DejaVuSans");
            DebugRenderer = new DebugRenderer(GraphicsService, spriteFont);
            _internalDebugRenderer = new DebugRenderer(GraphicsService, spriteFont);

            // To count the update frame rate, we handle the GameLogicUpdating event.
            // (We cannot use GraphicsScreen.OnUpdate because it is only called at the same rate if
            // the graphics screen is registered in the graphics service. If it is not registered,
            // then OnUpdate and OnRender are always called together.)
            var editor = services.GetInstance<IEditorService>();
            _gameExtension = editor.Extensions.OfType<GameExtension>().FirstOrDefault();
            if (_gameExtension != null)
                _gameExtension.GameLogicUpdating += OnGameLogicUpdating;
        }
示例#16
0
        public SampleGraphicsScreen(IServiceLocator services)
            : base(services.GetInstance<IGraphicsService>())
        {
            _sampleFramework = services.GetInstance<SampleFramework>();

              Name = "SampleScreen";
              ClearBackground = false;
              BackgroundColor = new Color(220, 220, 220);
              DrawReticle = false;
              UseFixedWidthFont = false;

              // Use 2D texture for reticle.
              var contentManager = services.GetInstance<ContentManager>();
              _reticle = contentManager.Load<Texture2D>("Reticle");

              // Get the sprite fonts used in the UI theme.
              var uiContentManager = services.GetInstance<ContentManager>("UIContent");
              _defaultFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
              _fixedWidthFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Console");

              // Set up 2D camera such that (0, 0) is upper, left corner of screen and
              // (screenWidth, screenHeight) is lower, right corner of screen.
              var graphicsDevice = GraphicsService.GraphicsDevice;
              int screenWidth = graphicsDevice.PresentationParameters.BackBufferWidth;
              int screenHeight = graphicsDevice.PresentationParameters.BackBufferHeight;
              var projection = new OrthographicProjection
              {
            Near = 0, Far = 2000,
            Left = 0, Right = screenWidth,
            Top = 0, Bottom = screenHeight,
              };
              var camera = new Camera(projection);
              _cameraNode2D = new CameraNode(camera)
              {
            PoseWorld = new Pose(new Vector3F(0, 0, 1000)),
              };

              // Initialize renderers.
              _spriteBatch = new SpriteBatch(graphicsDevice);
              _meshRenderer = new MeshRenderer();
              _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);
              DebugRenderer2D = new DebugRenderer(GraphicsService, _defaultFont)
              {
            SpriteFont = _defaultFont,
            DefaultColor = new Color(0, 0, 0),
            DefaultTextPosition = new Vector2F(10)
              };
              DebugRenderer = new DebugRenderer(GraphicsService, _defaultFont)
              {
            SpriteFont = _defaultFont,
            DefaultColor = new Color(0, 0, 0),
            DefaultTextPosition = new Vector2F(10)
              };

              Scene = new Scene();
        }
示例#17
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    public DeferredGraphicsScreen(IServiceLocator services)
      : base(services.GetInstance<IGraphicsService>())
    {
      _sampleFramework = services.GetInstance<SampleFramework>();
      var contentManager = services.GetInstance<ContentManager>();

      SpriteBatch = GraphicsService.GetSpriteBatch();

      // Let's create the necessary scene node renderers:
#if !XBOX360
      TerrainRenderer = new TerrainRenderer(GraphicsService);
#endif
      MeshRenderer = new MeshRenderer();

      // The _opaqueMeshSceneRenderer combines all renderers for opaque
      // (= not alpha blended) meshes.
      _opaqueMeshSceneRenderer = new SceneRenderer();
#if !XBOX360
      _opaqueMeshSceneRenderer.Renderers.Add(TerrainRenderer);
#endif
      _opaqueMeshSceneRenderer.Renderers.Add(MeshRenderer);

      _decalRenderer = new DecalRenderer(GraphicsService);
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048)
      {
        EnableSoftParticles = true,

        // If you have an extreme amount of particles that cover the entire screen,
        // you can turn on offscreen rendering to improve performance.
        //EnableOffscreenRendering = true,
      };

      // The AlphaBlendSceneRenderer combines all renderers for transparent
      // (= alpha blended) objects.
      AlphaBlendSceneRenderer = new SceneRenderer();
      AlphaBlendSceneRenderer.Renderers.Add(MeshRenderer);
      AlphaBlendSceneRenderer.Renderers.Add(_billboardRenderer);
      AlphaBlendSceneRenderer.Renderers.Add(new WaterRenderer(GraphicsService));
      AlphaBlendSceneRenderer.Renderers.Add(new FogSphereRenderer(GraphicsService));
      AlphaBlendSceneRenderer.Renderers.Add(new VolumetricLightRenderer(GraphicsService));

#if !XBOX360
      // Update terrain clipmaps. (Only necessary if TerrainNodes are used.)
      _terrainClipmapRenderer = new TerrainClipmapRenderer(GraphicsService);
#endif

      // Renderer for cloud maps. (Only necessary if LayeredCloudMaps are used.)
      _cloudMapRenderer = new CloudMapRenderer(GraphicsService);

      // Renderer for SceneCaptureNodes. See also SceneCapture2DSample.
      // In the constructor we specify a method which is called in SceneCaptureRenderer.Render() 
      // when the scene must be rendered for the SceneCaptureNodes.
      SceneCaptureRenderer = new SceneCaptureRenderer(context =>
      {
        // Get scene nodes which are visible by the current camera.
        CustomSceneQuery sceneQuery = Scene.Query<CustomSceneQuery>(context.CameraNode, context);
        // Render scene (with post-processing, with lens flares, no debug rendering, no reticle).
        RenderScene(sceneQuery, context, true, true, false, false);
      });

      // Renderer for PlanarReflectionNodes. See also PlanarReflectionSample.
      // In the constructor we specify a method which is called in PlanarReflectionRenderer.Render() 
      // to create the reflection images.
      _planarReflectionRenderer = new PlanarReflectionRenderer(context =>
      {
        // Get scene nodes which are visible by the current camera.
        CustomSceneQuery sceneQuery = Scene.Query<CustomSceneQuery>(context.CameraNode, context);

        var planarReflectionNode = (PlanarReflectionNode)context.ReferenceNode;

        // Planar reflections are often for WaterNodes. These nodes should not be rendered 
        // into their own reflection map because when the water surface is displaced by waves, 
        // some waves could be visible in the reflection. 
        // --> Remove the water node from the renderable nodes. (In our samples, the water
        // node is the parent of the reflection node.)
        if (planarReflectionNode.Parent is WaterNode)
        {
          var index = sceneQuery.RenderableNodes.IndexOf(planarReflectionNode.Parent);
          if (index >= 0)
            sceneQuery.RenderableNodes[index] = null;
        }

        // Render scene (no post-processing, no lens flares, no debug rendering, no reticle).
        RenderScene(sceneQuery, context, false, false, false, false);
      });

      _waterWavesRenderer = new WaterWavesRenderer(GraphicsService);

      // The shadow map renderer renders a depth image from the viewpoint of the light and
      // stores it in LightNode.Shadow.ShadowMap.
      ShadowMapRenderer = new ShadowMapRenderer(context =>
      {
        var query = context.Scene.Query<ShadowCasterQuery>(context.CameraNode, context);
        if (query.ShadowCasters.Count == 0)
          return false;

        _opaqueMeshSceneRenderer.Render(query.ShadowCasters, context);
        return true;
      });

      // The shadow mask renderer evaluates the shadow maps, does shadow filtering 
      // and stores the resulting shadow factor in a screen space image 
      //(see LightNode.Shadow.ShadowMask/ShadowMaskChannel).
      ShadowMaskRenderer = new ShadowMaskRenderer(GraphicsService, 2);

      // Optionally, we can blur the shadow mask to make the shadows smoother.
      var blur = new Blur(GraphicsService)
      {
        IsAnisotropic = false,
        IsBilateral = true,
        EdgeSoftness = 0.05f,
        Scale = 1f,
        Enabled = false,  // Disable blur by default.
      };
      blur.InitializeGaussianBlur(11, 3, true);
      ShadowMaskRenderer.Filter = blur;

      // Renderers which create the intermediate render targets:
      // Those 2 renderers are implemented in this sample. Those functions could
      // be implemented directly in this class but we have created separate classes
      // to make the code more readable.
      _gBufferRenderer = new GBufferRenderer(GraphicsService, _opaqueMeshSceneRenderer, _decalRenderer);
      LightBufferRenderer = new LightBufferRenderer(GraphicsService);

      // Other specialized renderers:
      _lensFlareRenderer = new LensFlareRenderer(GraphicsService);
      _skyRenderer = new SkyRenderer(GraphicsService);
      _fogRenderer = new FogRenderer(GraphicsService);
      _internalDebugRenderer = new DebugRenderer(GraphicsService, null);
      _rebuildZBufferRenderer = new RebuildZBufferRenderer(GraphicsService);

      Scene = new Scene();

      // This screen needs a HDR filter to map high dynamic range values back to
      // low dynamic range (LDR).
      PostProcessors = new PostProcessorChain(GraphicsService);
      PostProcessors.Add(new HdrFilter(GraphicsService)
      {
        EnableBlueShift = true,
        BlueShiftCenter = 0.0004f,
        BlueShiftRange = 0.5f,
        //BlueShiftColor = new Vector3F(1.05f / 4f, 0.97f / 4f, 1.27f / 4f),  // Default physically-based blue-shift
        BlueShiftColor = new Vector3F(0.25f, 0.25f, 0.7f),  // More dramatic blue-shift
        MinExposure = 0,
        MaxExposure = 10,
        BloomIntensity = 1,
        BloomThreshold = 0.6f,
      });
      _underwaterPostProcessor = new UnderwaterPostProcessor(GraphicsService, contentManager);
      PostProcessors.Add(_underwaterPostProcessor);

      // Use 2D texture for reticle.
      _reticle = contentManager.Load<Texture2D>("Reticle");

      // Use the sprite font of the GUI.
      var uiContentManager = services.GetInstance<ContentManager>("UIContent");
      var spriteFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      DebugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = new Color(0, 0, 0),
        DefaultTextPosition = new Vector2F(10),
      };

      EnableLod = true;
    }
示例#18
0
    public PostProcessingGraphicsScreen(IServiceLocator services)
      : base(services.GetInstance<IGraphicsService>())
    {
      _sampleFramework = services.GetInstance<SampleFramework>();

      _spriteBatch = new SpriteBatch(GraphicsService.GraphicsDevice);
      _clearGBufferRenderer = new ClearGBufferRenderer(GraphicsService);
      _rebuildZBufferRenderer = new RebuildZBufferRenderer(GraphicsService);
      _meshRenderer = new MeshRenderer();
      _skyRenderer = new SkyRenderer(GraphicsService);
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

      Scene = new Scene();
      PostProcessors = new PostProcessorChain(GraphicsService);

      // Use 2D texture for reticle.
      var contentManager = services.GetInstance<ContentManager>();
      _reticle = contentManager.Load<Texture2D>("Reticle");

      // Use the sprite font of the GUI.
      var uiContentManager = services.GetInstance<ContentManager>("UIContent");
      var spriteFont = uiContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      DebugRenderer = new DebugRenderer(GraphicsService, spriteFont)
      {
        DefaultColor = new Color(0, 0, 0),
        DefaultTextPosition = new Vector2F(10),
      };
    }
示例#19
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    public CharacterControllerObject(IServiceLocator services)
    {
      Name = "CharacterController";

      _inputService = services.GetInstance<IInputService>();
      _debugRenderer = services.GetInstance<DebugRenderer>();
      _simulation = services.GetInstance<Simulation>();

      // Create character controller.
#if USE_DYNAMIC_CHARACTER_CONTROLLER
      CharacterController = new DynamicCharacterController(_simulation);
#else
      CharacterController = new KinematicCharacterController(_simulation);
#endif
      CharacterController.Enabled = false;
      CharacterController.Position = new Vector3F(0, 0, 10);
      CharacterController.Gravity = 10;   // Setting gravity to 0 switches to fly mode (instead of walking).

      // Special: No gravity and damping for character controller.
      // The character controller uses a rigid body. The gravity and damping force effects
      // should not influence this body. The character controller handles gravity itself.
      // Gravity and Damping are ForceEffects. Each force effect has an AreaOfEffect which,
      // by default, is a GlobalAreaOfEffect (= affects all bodies in the simulation). We can 
      // set a predicate method that excludes the rigid body of the character controller.
      GlobalAreaOfEffect areaOfEffect = new GlobalAreaOfEffect
      {
        Exclude = body => body == CharacterController.Body,
      };
      _simulation.ForceEffects.OfType<Gravity>().First().AreaOfEffect = areaOfEffect;
      _simulation.ForceEffects.OfType<Damping>().First().AreaOfEffect = areaOfEffect;

      // Special: Collision filtering.
      // We will have some collision objects that should not collide with the character controller.
      // We will use collision group 3 for the character and 4 for objects that should not collide
      // with it.
      CharacterController.CollisionGroup = 3;
      ICollisionFilter filter = (ICollisionFilter)_simulation.CollisionDomain.CollisionDetection.CollisionFilter;
      filter.Set(3, 4, false);  // Disable collisions between group 3 and 4.
    }
示例#20
0
    public IntersectionSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services, 10);
      _cameraObject.ResetPose(new Vector3F(0, 0, -4), ConstantsF.Pi, 0);
      GameObjectService.Objects.Add(_cameraObject);

      // Create a new scene with some lights.
      _scene = new Scene();
      SceneSample.InitializeDefaultXnaLights(_scene);

      _meshRenderer = new MeshRenderer();
      _debugRenderer = new DebugRenderer(GraphicsService, null);

      _intersectionRenderer = new IntersectionRenderer(GraphicsService, ContentManager)
      {
        DownsampleFactor = 1,
      };

      //_submeshA = MeshHelper.CreateSubmesh(GraphicsService.GraphicsDevice, new SphereShape(0.5f).GetMesh(0.001f, 5), MathHelper.ToRadians(70));
      //_submeshB = MeshHelper.CreateSubmesh(GraphicsService.GraphicsDevice, new BoxShape(1, 1, 2).GetMesh(0.001f, 5), MathHelper.ToRadians(70));

      var meshNodeA = CreateMeshNode(new[]
      {
        MeshHelper.CreateTorus(GraphicsService.GraphicsDevice, 1, 0.3f, 30),
        MeshHelper.CreateSubmesh(GraphicsService.GraphicsDevice, new BoxShape(1, 1, 2).GetMesh(0.001f, 5), MathHelper.ToRadians(70)),
      },
      Color.DarkBlue);
      meshNodeA.PoseWorld = new Pose(RandomHelper.Random.NextVector3F(-0.5f, 0.5f),
                                    RandomHelper.Random.NextQuaternionF());
      _scene.Children.Add(meshNodeA);
      _debugRenderer.DrawObject(meshNodeA, Color.Green, true, false);

      var shape = new TransformedShape(
        new GeometricObject(new SphereShape(0.5f), new Pose(new Vector3F(1, 0, 0))));
      var meshNodeB = CreateMeshNode(new[]
      {
        MeshHelper.CreateTorus(GraphicsService.GraphicsDevice, 1, 0.3f, 30),
        MeshHelper.CreateSubmesh(GraphicsService.GraphicsDevice, shape.GetMesh(0.001f, 4), MathHelper.ToRadians(90)),
      },
      Color.Gray);
      meshNodeB.PoseWorld = new Pose(RandomHelper.Random.NextVector3F(-1f, 1f),
                                    RandomHelper.Random.NextQuaternionF());
      _scene.Children.Add(meshNodeB);
      _debugRenderer.DrawObject(meshNodeB, Color.Green, true, false);

      var meshNodeC = CreateMeshNode(new[]
      {
        MeshHelper.CreateBox(GraphicsService.GraphicsDevice),
        MeshHelper.CreateSubmesh(GraphicsService.GraphicsDevice, new BoxShape(1, 1, 2).GetMesh(0.001f, 5), MathHelper.ToRadians(70))
      },
      Color.DarkGreen);
      meshNodeC.PoseWorld = new Pose(RandomHelper.Random.NextVector3F(-1f, 1f),
                                    RandomHelper.Random.NextQuaternionF());
      meshNodeC.ScaleLocal = new Vector3F(0.1f, 1f, 0.5f);
      _scene.Children.Add(meshNodeC);
      _debugRenderer.DrawObject(meshNodeC, Color.Green, true, false);

      _meshNodePairs.Add(new Pair<MeshNode>(meshNodeA, meshNodeB));
      _meshNodePairs.Add(new Pair<MeshNode>(meshNodeA, meshNodeC));
      _meshNodePairs.Add(new Pair<MeshNode>(meshNodeB, meshNodeC));

      CreateGuiControls();
    }
示例#21
0
    protected override void OnLoad()
    {
      var contentManager = _services.GetInstance<ContentManager>();

      _lights.Add(new LightNode(new AmbientLight
      {
        Color = new Vector3F(0.9f, 0.9f, 1f),
        Intensity = 0.05f,
        HemisphericAttenuation = 1,
      })
      {
        Name = "AmbientLight",

        // This ambient light is "infinite", the pose is irrelevant for the lighting. It is only
        // used for the debug rendering below.
        PoseWorld = new Pose(new Vector3F(0, 4, 0)),
      });

      _lights.Add(new LightNode(new DirectionalLight
      {
        Color = new Vector3F(0.6f, 0.8f, 1f),
        DiffuseIntensity = 0.1f,
        SpecularIntensity = 0.1f,
      })
      {
        Name = "DirectionalLightWithShadow",
        Priority = 10,   // This is the most important light.
        PoseWorld = new Pose(new Vector3F(0, 5, 0), Matrix33F.CreateRotationY(-1.4f) * Matrix33F.CreateRotationX(-0.6f)),
        Shadow = new CascadedShadow
        {
          PreferredSize = 1024,
        }
      });

      _lights.Add(new LightNode(new DirectionalLight
      {
        Color = new Vector3F(0.8f, 0.4f, 0.0f),
        DiffuseIntensity = 0.1f,
        SpecularIntensity = 0.0f,
      })
      {
        Name = "DirectionalLight",
        PoseWorld = new Pose(new Vector3F(0, 6, 0), Matrix33F.CreateRotationY(-1.4f) * Matrix33F.CreateRotationX(-0.6f) * Matrix33F.CreateRotationX(ConstantsF.Pi)),
      });

      _lights.Add(new LightNode(new PointLight
      {
        Color = new Vector3F(0, 1, 0),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Range = 3,
        Attenuation = 1f,
      })
      {
        Name = "PointLight",
        PoseWorld = new Pose(new Vector3F(-9, 1, 0))
      });

      _lights.Add(new LightNode(new PointLight
      {
        DiffuseIntensity = 4,
        SpecularIntensity = 4,
        Range = 3,
        Attenuation = 1f,
        Texture = contentManager.Load<TextureCube>("LavaBall/LavaCubeMap"),
      })
      {
        Name = "PointLightWithTexture",
        PoseWorld = new Pose(new Vector3F(-3, 1, 0))
      });

      _lights.Add(new LightNode(new PointLight
      {
        Color = new Vector3F(1, 1, 1),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Range = 3,
        Attenuation = 1f,
      })
      {
        Name = "PointLightWithShadow",
        PoseWorld = new Pose(new Vector3F(3, 1, 0)),
        Shadow = new CubeMapShadow
        {
          PreferredSize = 128,
        }
      });

      _lights.Add(new LightNode(new PointLight
      {
        Color = new Vector3F(1, 1, 1),
        DiffuseIntensity = 4,
        SpecularIntensity = 4,
        Range = 3,
        Attenuation = 1f,
        Texture = contentManager.Load<TextureCube>("MagicSphere/ColorCube"),
      })
      {
        Name = "PointLightWithTextureAndShadow",
        PoseWorld = new Pose(new Vector3F(9, 1, 0)),
        Shadow = new CubeMapShadow
        {
          PreferredSize = 128,
        }
      });

      _lights.Add(new LightNode(new ProjectorLight
      {
        Texture = contentManager.Load<Texture2D>("TVBox/TestCard"),
      })
      {
        Name = "ProjectorLight",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(-1, 1, -7), new Vector3F(-5, 0, -7), new Vector3F(0, 1, 0))).Inverse,
      });

      _lights.Add(new LightNode(new ProjectorLight
      {
        Texture = contentManager.Load<Texture2D>("TVBox/TestCard"),
      })
      {
        Name = "ProjectorLightWithShadow",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(5, 1, -7), new Vector3F(1, 0, -7), new Vector3F(0, 1, 0))).Inverse,
        Shadow = new StandardShadow
        {
          PreferredSize = 128,
        }
      });

      _lights.Add(new LightNode(new Spotlight
      {
        Color = new Vector3F(0, 1, 0),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
      })
      {
        Name = "Spotlight",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(-7, 1, -14), new Vector3F(-10, 0, -14), new Vector3F(0, 1, 0))).Inverse,
      });

      _lights.Add(new LightNode(new Spotlight
      {
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Texture = contentManager.Load<Texture2D>("TVBox/TestCard"),
      })
      {
        Name = "SpotlightWithTexture",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(-1, 1, -14), new Vector3F(-5, 0, -14), new Vector3F(0, 1, 0))).Inverse,
      });

      _lights.Add(new LightNode(new Spotlight
      {
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
      })
      {
        Name = "SpotlightWithShadow",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(5, 1, -14), new Vector3F(1, 0, -14), new Vector3F(0, 1, 0))).Inverse,
        Shadow = new StandardShadow
        {
          PreferredSize = 128,
        }
      });

      _lights.Add(new LightNode(new Spotlight
      {
        Color = new Vector3F(1, 1, 0),
        DiffuseIntensity = 2,
        SpecularIntensity = 2,
        Texture = contentManager.Load<Texture2D>("TVBox/TestCard"),
      })
      {
        Name = "SpotlightWithTextureAndShadow",
        PoseWorld = Pose.FromMatrix(Matrix44F.CreateLookAt(new Vector3F(11, 1, -14), new Vector3F(5, 0, -14), new Vector3F(0, 1, 0))).Inverse,
        Shadow = new StandardShadow
        {
          PreferredSize = 128,
        }
      });

      var scene = _services.GetInstance<IScene>();
      _debugRenderer = _services.GetInstance<DebugRenderer>();

      foreach (var lightNode in _lights)
        scene.Children.Add(lightNode);
    }
示例#22
0
    public AdvancedAvatarRagdollSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      // This sample uses for a DebugRenderer to draw text and rigid bodies.
      _debugRenderer = new DebugRenderer(GraphicsService, SpriteFont)
      {
        DefaultColor = Color.Black,
        DefaultTextPosition = new Vector2F(10),
      };

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      _cameraObject.ResetPose(new Vector3F(0, 1, -3), ConstantsF.Pi, 0);
      GameObjectService.Objects.Add(_cameraObject);

      // Add some objects which allow the user to interact with the rigid bodies.
      _grabObject = new GrabObject(Services);
      _ballShooterObject = new BallShooterObject(Services) { Speed = 20 };
      GameObjectService.Objects.Add(_grabObject);
      GameObjectService.Objects.Add(_ballShooterObject);

      // Add some default force effects.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Create a random avatar.
      _avatarDescription = AvatarDescription.CreateRandom();
      _avatarRenderer = new AvatarRenderer(_avatarDescription);

      // Use the "Wave" animation preset.
      var avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Wave);
      _expressionAnimation = new AnimationClip<AvatarExpression>(new WrappedAvatarExpressionAnimation(avatarAnimation))
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      _skeletonAnimation = new AnimationClip<SkeletonPose>(new WrappedAvatarSkeletonAnimation(avatarAnimation))
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };

      // Add a ground plane in the simulation.
      Simulation.RigidBodies.Add(new RigidBody(new PlaneShape(Vector3F.UnitY, 0)) { MotionType = MotionType.Static });

      // Distribute a few dynamic spheres and boxes across the landscape.
      SphereShape sphereShape = new SphereShape(0.3f);
      for (int i = 0; i < 10; i++)
      {
        Vector3F position = RandomHelper.Random.NextVector3F(-10, 10);
        position.Y = 1;
        Simulation.RigidBodies.Add(new RigidBody(sphereShape) { Pose = new Pose(position) });
      }

      BoxShape boxShape = new BoxShape(0.6f, 0.6f, 0.6f);
      for (int i = 0; i < 10; i++)
      {
        Vector3F position = RandomHelper.Random.NextVector3F(-10, 10);
        position.Y = 1;
        Simulation.RigidBodies.Add(new RigidBody(boxShape) { Pose = new Pose(position) });
      }
    }
示例#23
0
    public SceneSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // Create a new empty scene.
      _scene = new Scene();

      // Add the camera node to the scene.
      _scene.Children.Add(_cameraObject.CameraNode);

      // Load a model. This model uses the DigitalRune Model Processor. Several XML 
      // files (*.drmdl and *.drmat) in the folder of dude.fbx define the materials and other properties. 
      // The DigitalRune Model Processor also imports the animations of the dude model.
      var model = ContentManager.Load<ModelNode>("Dude/Dude");

      // Add two clones of the model to the scene.
      _model0 = model.Clone();
      _model1 = model.Clone();
      _scene.Children.Add(_model0);
      _scene.Children.Add(_model1);

      // The dude model contains a single mesh node.
      var meshNode0 = (MeshNode)_model0.Children[0];
      var meshNode1 = (MeshNode)_model1.Children[0];

      // The imported animation data (skeleton and animations) is stored with the mesh.
      var animations = meshNode0.Mesh.Animations;

      // The MeshNodes of skinned models has a SkeletonPose which can be animated.
      // Let's start the first animation.
      var timeline0 = new TimelineClip(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle, // Loop animation...
        Duration = TimeSpan.MaxValue,      // ...forever.
      };
      _animationController0 = AnimationService.StartAnimation(timeline0, (IAnimatableProperty)meshNode0.SkeletonPose);
      _animationController0.UpdateAndApply();

      var timeline1 = new TimelineClip(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,

        // Start second animation at a different animation time to add some variety.
        Delay = TimeSpan.FromSeconds(-1),
      };
      _animationController1 = AnimationService.StartAnimation(timeline1, (IAnimatableProperty)meshNode1.SkeletonPose);
      _animationController1.UpdateAndApply();

      // Add some lights to the scene which have the same properties as the lights 
      // of BasicEffect.EnableDefaultLighting().
      InitializeDefaultXnaLights(_scene);

      _meshRenderer = new MeshRenderer();

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);
    }
示例#24
0
    public BillboardSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // In this example we need three renderers:
      // The MeshRenderer handles MeshNodes.
      _meshRenderer = new MeshRenderer();

      // The BillboardRenderer handles BillboardNodes and ParticleSystemNodes.
      _billboardRenderer = new BillboardRenderer(GraphicsService, 2048);

      // The DebugRenderer is used to draw text.
      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

      // Create a new empty scene.
      _scene = new Scene();

      // Add the camera node to the scene.
      _scene.Children.Add(_cameraObject.CameraNode);

      // Add a few models to the scene.
      var sandbox = ContentManager.Load<ModelNode>("Sandbox/Sandbox").Clone();
      _scene.Children.Add(sandbox);

      // Add some lights to the scene which have the same properties as the lights 
      // of BasicEffect.EnableDefaultLighting().
      SceneSample.InitializeDefaultXnaLights(_scene);

      var texture = new PackedTexture(ContentManager.Load<Texture2D>("Billboard/BillboardReference"));

      // ----- View plane-aligned billboards with variations.
      // View plane-aligned billboards are rendered parallel to the screen.
      // The up-axis of the BillboardNode determines the up direction of the 
      // billboard.
      var pose0 = new Pose(new Vector3F(-9, 1.0f, 1.5f));
      var pose1 = pose0;
      var billboard = new ImageBillboard(texture);
      var billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying color\nVarying alpha";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(1, 0, 0);
      billboardNode.Alpha = 0.9f;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(0, 1, 0);
      billboardNode.Alpha = 0.7f;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      billboardNode.Color = new Vector3F(0, 0, 1);
      billboardNode.Alpha = 0.3f;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with different blend modes
      // blend mode = 0 ... additive blend
      // blend mode = 1 ... alpha blend
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying blend mode";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.333f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 0.667f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.BlendMode = 1.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with alpha test
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.9f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying reference alpha";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.667f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.333f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboard = new ImageBillboard(texture);
      billboard.AlphaTest = 0.0f;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- View plane-aligned billboards with different scale and rotation
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ViewPlaneAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "View plane-aligned\nVarying scale\nVarying rotation";
      billboardNode.PoseWorld = pose1;
      billboardNode.ScaleLocal = new Vector3F(0.4f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-15)));
      billboardNode.ScaleLocal = new Vector3F(0.6f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-30)));
      billboardNode.ScaleLocal = new Vector3F(0.8f);
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-45)));
      billboardNode.ScaleLocal = new Vector3F(1.0f);
      _scene.Children.Add(billboardNode);

      // ----- Viewpoint-oriented billboards
      // Viewpoint-orientated billboards always face the player. (The face normal 
      // points directly to the camera.)
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ViewpointOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Viewpoint-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Screen-aligned billboards
      // View plane-aligned billboards and screen-aligned billboards are similar. The 
      // billboards are rendered parallel to the screen. The orientation can be changed 
      // by rotating the BillboardNode. The difference is that the orientation of view 
      // plane-aligned billboards is relative to world space and the orientation of 
      // screen-aligned billboards is relative to view space.
      // Screen-aligned billboards are, for example, used for text label.
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.ScreenAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Screen-aligned";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Axial, view plane-aligned billboards
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.AxialViewPlaneAligned;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Axial, view plane-aligned";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = billboardNode.Clone();
      billboardNode.Name = null;
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- Axial, viewpoint-oriented billboards
      pose0.Position.X += 2;
      pose1 = pose0;
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.AxialViewpointOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "Axial, viewpoint-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // ----- World-oriented billboards
      // World-oriented billboards have a fixed orientation in world space. The 
      // orientation is determine by the BillboardNode.
      pose0.Position.X += 2;
      pose1 = pose0;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboard = new ImageBillboard(texture);
      billboard.Orientation = BillboardOrientation.WorldOriented;
      billboardNode = new BillboardNode(billboard);
      billboardNode.Name = "World-oriented";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(15)));
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(30)));
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      pose1.Orientation *= Matrix33F.CreateRotationY(0.2f);
      billboardNode = new BillboardNode(billboard);
      billboardNode.PoseWorld = pose1 * new Pose(Matrix33F.CreateRotationZ(MathHelper.ToRadians(45)));
      _scene.Children.Add(billboardNode);

      // ----- Animated billboards
      // DigitalRune Graphics supports "texture atlases". I.e. textures can be packed 
      // together into a single, larger texture file. A PackedTexture can describe a 
      // single texture packed into a texture atlas or a tile set packed into a 
      // texture atlas. In this example the "beeWingFlap" is a set of three tiles.
      // Tile sets can be used for sprite animations. (The animation is set below in 
      // Update().)
      pose0.Position.X += 2;
      pose1 = pose0;
      texture = new PackedTexture("Bee", ContentManager.Load<Texture2D>("Particles/beeWingFlap"), Vector2F.Zero, Vector2F.One, 3, 1);
      _animatedBillboard = new ImageBillboard(texture);
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.Name = "Animated billboards";
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      pose1.Position.Z -= 1;
      billboardNode = new BillboardNode(_animatedBillboard);
      billboardNode.PoseWorld = pose1;
      _scene.Children.Add(billboardNode);

      // Use DebugRenderer to draw node names above billboard nodes.
      foreach (var node in _scene.GetDescendants().OfType<BillboardNode>())
        _debugRenderer.DrawText(node.Name, node.PoseWorld.Position + new Vector3F(0, 1, 0), new Vector2F(0.5f), Color.Yellow, false);
    }
示例#25
0
    protected override void OnUnload()
    {
      _debugRenderer = null;

      foreach (var lightNode in _lights)
      {
        lightNode.Parent.Children.Remove(lightNode);
        lightNode.Dispose(false);
      }
      _lights.Clear();
    }
示例#26
0
    protected override void OnLoad()
    {
      var contentManager = _services.GetInstance<ContentManager>();
      var scene = _services.GetInstance<IScene>();
      _debugRenderer = _services.GetInstance<DebugRenderer>();

      // Load materials (*.drmat files) which define the used shaders and material 
      // properties (e.g. textures, colors, etc.).
      var bloodMaterial = contentManager.Load<Material>("Decals/Decal");        // Original: "Decals/Blood"
      var crackMaterial = contentManager.Load<Material>("Decals/Decal");        // Original: "Decals/Crack"
      var bulletHoleMaterial = contentManager.Load<Material>("Decals/Decal");   // Original: "Decals/BulletHole"

      // Decal materials (like materials of meshes) usually have several render passes
      // (such as "GBuffer", "Material"). Decal materials without a "Material" pass can
      // be used to render only normal maps without color changes:
      //crackMaterial.Remove("Material");

      // Add some DecalNodes, which define where a material is projected onto the scene.
      var bloodDecal0 = new DecalNode(bloodMaterial);
      bloodDecal0.NormalThreshold = MathHelper.ToRadians(75);
      bloodDecal0.LookAt(new Vector3F(0.7f, 0.6f, 0.7f), new Vector3F(0.7f, 0.6f, 0), new Vector3F(0.1f, 1, 0));
      bloodDecal0.Width = 1.1f;
      bloodDecal0.Height = 1.1f;
      bloodDecal0.Depth = 1;
      bloodDecal0.Options = DecalOptions.ProjectOnStatic;
      scene.Children.Add(bloodDecal0);
      _decals.Add(bloodDecal0);

      var bloodDecal1 = new DecalNode(bloodMaterial);
      bloodDecal1.LookAt(new Vector3F(0.0f, 0.2f, 1.9f), new Vector3F(0.0f, 0, 1.9f), new Vector3F(1.0f, 0, -0.5f));
      bloodDecal1.Width = 1.6f;
      bloodDecal1.Height = 1.6f;
      bloodDecal1.Depth = 0.5f;
      scene.Children.Add(bloodDecal1);
      _decals.Add(bloodDecal1);

      var crackDecal0 = new DecalNode(crackMaterial);
      crackDecal0.NormalThreshold = MathHelper.ToRadians(75);
      crackDecal0.LookAt(new Vector3F(-0.7f, 0.7f, 0.7f), new Vector3F(-0.7f, 0.7f, 0), new Vector3F(0.1f, 1, 0));
      crackDecal0.Width = 1.75f;
      crackDecal0.Height = 1.75f;
      crackDecal0.Depth = 0.6f;
      crackDecal0.Options = DecalOptions.ProjectOnStatic;
      scene.Children.Add(crackDecal0);
      _decals.Add(crackDecal0);

      var crackDecal1 = crackDecal0.Clone();
      var position = new Vector3F(2.0f, 0.2f, 2.0f);
      crackDecal1.LookAt(position, position + new Vector3F(0, -1, 0), new Vector3F(-0.8f, 0, 1.0f));
      crackDecal1.Width = 2.5f;
      crackDecal1.Height = 2.5f;
      crackDecal1.Depth = 0.5f;
      scene.Children.Add(crackDecal1);
      _decals.Add(crackDecal1);

      var bulletHole0 = new DecalNode(bulletHoleMaterial);
      bulletHole0.NormalThreshold = MathHelper.ToRadians(90);
      bulletHole0.LookAt(new Vector3F(0.0f, 0.8f, 0.7f), new Vector3F(0.0f, 0.7f, 0), new Vector3F(0.1f, -1, 0));
      bulletHole0.Width = 0.20f;
      bulletHole0.Height = 0.20f;
      bulletHole0.Depth = 1f;
      bulletHole0.DrawOrder = 10;   // Draw over other decals.
      scene.Children.Add(bulletHole0);
      _decals.Add(bulletHole0);

      var bulletHole1 = bulletHole0.Clone();
      bulletHole1.LookAt(new Vector3F(-0.4f, 0.9f, 0.7f), new Vector3F(-0.4f, 0.9f, 0), new Vector3F(0.1f, 1, 0));
      scene.Children.Add(bulletHole1);
      _decals.Add(bulletHole1);

      var bulletHole2 = bulletHole0.Clone();
      bulletHole2.LookAt(new Vector3F(-0.2f, 0.8f, 0.7f), new Vector3F(-0.2f, 0.0f, 0), new Vector3F(0.1f, -1, 0));
      scene.Children.Add(bulletHole2);
      _decals.Add(bulletHole2);

      var bulletHole3 = bulletHole0.Clone();
      bulletHole3.LookAt(new Vector3F(3.0f, 1.0f, 2.0f), new Vector3F(3.0f, 1.0f, 1), new Vector3F(0.3f, 1, 0));
      scene.Children.Add(bulletHole3);
      _decals.Add(bulletHole3);

      var bulletHole4 = bulletHole0.Clone();
      bulletHole4.LookAt(new Vector3F(2.5f, 0.7f, 2.0f), new Vector3F(3.0f, 0.7f, 1.0f), new Vector3F(-0.1f, -1, 0));
      scene.Children.Add(bulletHole4);
      _decals.Add(bulletHole4);

      var bulletHole5 = bulletHole0.Clone();
      bulletHole5.LookAt(new Vector3F(2.7f, 1.2f, 2.0f), new Vector3F(3.0f, 1.2f, 1.0f), new Vector3F(-0.5f, -1, 0));
      scene.Children.Add(bulletHole5);
      _decals.Add(bulletHole5);

      var bulletHole6 = bulletHole0.Clone();
      bulletHole6.LookAt(new Vector3F(3.2f, 0.4f, 2.0f), new Vector3F(3.0f, 0.4f, 1), new Vector3F(-0.3f, -0.5f, 0));
      scene.Children.Add(bulletHole6);
      _decals.Add(bulletHole6);

      // Get the first dynamic mesh (the rusty cube) and add a decal as a child.
      MeshNode meshNode = ((Scene)scene).GetSubtree().OfType<MeshNode>().First(n => !n.IsStatic);
      var bulletHole7 = bulletHole0.Clone();
      bulletHole7.LookAt(new Vector3F(0, 0, -0.6f), new Vector3F(0, 0, 0), new Vector3F(0, 1, 0));
      bulletHole7.Depth = 0.2f;
      meshNode.Children = new SceneNodeCollection { bulletHole7 };
      _decals.Add(bulletHole7);

      // Add GUI controls to the Options window.
      var sampleFramework = _services.GetInstance<SampleFramework>();
      var optionsPanel = sampleFramework.AddOptions("Game Objects");
      var panel = SampleHelper.AddGroupBox(optionsPanel, "EnvironmentDecalsObject");
      SampleHelper.AddCheckBox(
          panel,
          "Enable decals",
          IsEnabled,
          isChecked => IsEnabled = isChecked);
    }
示例#27
0
    public MeshNodeSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;
      var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService)
      {
        RenderCallback = Render,
      };
      GraphicsService.Screens.Insert(0, delegateGraphicsScreen);

      // Add a custom game object which controls the camera.
      _cameraObject = new CameraObject(Services);
      GameObjectService.Objects.Add(_cameraObject);

      // For advanced users: Set this flag if you want to analyze the imported opaque data of
      // effect bindings.
      //EffectBinding.KeepOpaqueData = true;

      // Load a model. The model is processed using the DigitalRune Model Processor - not 
      // the default XNA model processor!
      // In the folder that contains tank.fbx, there is an XML file tank.drmdl which defines 
      // properties of the model. These XML files are automatically processed by the 
      // DigitalRune Model Processor. 
      // Each model itself is a tree of scene nodes. The grid model contains one mesh 
      // node. The tank model contains several mesh nodes (turret, cannon, hatch, 
      // wheels, ...).
      _model = ContentManager.Load<ModelNode>("Tank/tank");

      // The XNA ContentManager manages a single instance of each model. We clone 
      // the model, to get a copy that we can modify without changing the original 
      // instance. Cloning is fast because it only duplicates the scene nodes - but 
      // not the mesh and material information.
      _model = _model.Clone();

      // _model is the root of a tree of scene nodes. The mesh nodes are the child 
      // nodes. When we scale or move the _model, we automatically scale and move 
      // all child nodes.
      _model.ScaleLocal = new Vector3F(0.8f);
      _model.PoseWorld = new Pose(new Vector3F(0, 0, -2), Matrix33F.CreateRotationY(-0.3f));

      // Let's loop through the mesh nodes of the model:
      foreach (var meshNode in _model.GetSubtree().OfType<MeshNode>())
      {
        // Each MeshNode references a Mesh.
        Mesh mesh = meshNode.Mesh;

        // The mesh consists of several submeshes and several materials - usually 
        // one material per submesh, but several submeshes could reference the same 
        // materials.

        // Let's loop through the materials of this mesh.
        foreach (var material in mesh.Materials)
        {
          // A material is a collection of EffectBindings - one EffectBinding for each
          // render pass. For example, a complex game uses several render passes, like
          // a pre-Z pass, a G-buffer pass, a shadow map pass, a deferred material pass, 
          // etc.In simple games there is only one pass which is called "Default".
          var effectBinding = material["Default"];

          // An EffectBinding references an Effect (the XNA Effect class) and it has
          // "parameter bindings" and "technique bindings". These bindings select the 
          // values for the shader parameters when the mesh node is rendered. 

          // Let's change the binding for the DiffuseColor of the shader to give tank 
          // a red color.
          effectBinding.Set("DiffuseColor", new Vector4(1, 0.7f, 0.7f, 1));

          // The tank uses the default effect binding which is a BasicEffectBinding - this
          // effect binding uses the XNA BasicEffect. 
          // In this sample we do not define any lights, therefore we disable the lighting
          // in the shader.
          ((BasicEffectBinding)effectBinding).LightingEnabled = false;
        }
      }

      _meshRenderer = new MeshRenderer();

      var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default");
      _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);
    }