Esempio n. 1
0
    public StartScreenComponent(Microsoft.Xna.Framework.Game game, IServiceLocator services)
      : base(game)
    {
      _services = services;
      _inputService = services.GetInstance<IInputService>();
      _graphicsService = services.GetInstance<IGraphicsService>();
      _uiService = _services.GetInstance<IUIService>();

      // Add a GraphicsScreen to draw some text. In a real game we would draw
      // a spectacular start screen image instead.
      _graphicsScreen = new SampleGraphicsScreen(services);
      _graphicsScreen.ClearBackground = true;
      _graphicsService.Screens.Insert(0, _graphicsScreen);

      // Load stuff in a parallel task.
      _loadStuffTask = Parallel.Start(LoadStuff);
    }
Esempio n. 2
0
        public void Render(IList<SceneNode> occluders, LightNode lightNode, SceneNodeRenderer renderer, RenderContext context)
        {
            if (context == null)
            throw new ArgumentNullException("context");

              context.ThrowIfCameraMissing();

              // ----- Sort occluders by type: IOcclusionProxy vs. SceneNode
              SortOccluders(occluders, renderer, context);
              Statistics.Occluders = _occlusionProxies.Count + _sceneNodes.Count;

              // ----- Update all IOcclusionProxy in background.
              if (_occlusionProxies.Count > 0)
              {
            if (EnableMultithreading)
              _updateTask = Parallel.Start(_updateOcclusionProxies);
            else
              UpdateOcclusionProxies();
              }

              // ----- Backup render state.
              var originalRenderTarget = context.RenderTarget;
              var originalViewport = context.Viewport;

              var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              var originalRenderState = new RenderStateSnapshot(graphicsDevice);

              // ----- Camera properties
              var cameraNode = context.CameraNode;
              Matrix cameraView = (Matrix)cameraNode.View;
              var cameraProjection = cameraNode.Camera.Projection;
              Matrix cameraViewProjection = cameraView * cameraProjection;

              if (lightNode == null)
              {
            _lightHzbAvailable = false;
              }
              else
              {
            // ----- Render light HZB.
            _lightHzbAvailable = true;

            var shadow = lightNode.Shadow as CascadedShadow;
            if (shadow == null)
              throw new ArgumentException("LightNode expected to have a CascadedShadow.", "lightNode");

            // Set up orthographic camera similar to CascadedShadowMapRenderer.
            context.CameraNode = _orthographicCameraNode;

            // Part of camera frustum covered by shadow map.
            var maxShadowDistance = shadow.Distances[shadow.NumberOfCascades - 1];
            _splitVolume.SetFieldOfView(cameraProjection.FieldOfViewY, cameraProjection.AspectRatio, cameraProjection.Near, Math.Min(cameraProjection.Far, maxShadowDistance));

            // Find the bounding sphere of the camera frustum.
            Vector3F center;
            float radius;
            GetBoundingSphere(_splitVolume, out center, out radius);

            Matrix33F orientation = lightNode.PoseWorld.Orientation;
            Vector3F lightBackward = orientation.GetColumn(2);
            var orthographicProjection = (OrthographicProjection)_orthographicCameraNode.Camera.Projection;

            // Create a tight orthographic frustum around the cascade's bounding sphere.
            orthographicProjection.SetOffCenter(-radius, radius, -radius, radius, 0, 2 * radius);
            center = cameraNode.PoseWorld.ToWorldPosition(center);
            Vector3F cameraPosition = center + radius * lightBackward;
            Pose frustumPose = new Pose(cameraPosition, orientation);

            // For rendering the shadow map, move near plane back by MinLightDistance
            // to catch occluders in front of the cascade.
            orthographicProjection.Near = -shadow.MinLightDistance;
            _orthographicCameraNode.PoseWorld = frustumPose;

            Pose lightView = frustumPose.Inverse;
            Matrix lightViewProjection = (Matrix)lightView * orthographicProjection;

            _parameterCameraViewProj.SetValue(lightViewProjection);
            _parameterCameraNear.SetValue(orthographicProjection.Near);
            _parameterCameraFar.SetValue(orthographicProjection.Far);

            RenderOccluders(renderer, context);
            CreateDepthHierarchy(_lightHzb, context);

            // Set effect parameters for use in Query().
            _lightAabb = _orthographicCameraNode.Aabb;
            _parameterLightViewProj.SetValue(lightViewProjection);
            _parameterLightToCamera.SetValue(Matrix.Invert(lightViewProjection) * cameraViewProjection);

            context.CameraNode = cameraNode;
              }

              // ----- Render camera HZB.
              // Set camera parameters. (These effect parameters are also needed in Query()!)
              _cameraAabb = cameraNode.Aabb;
              _parameterCameraViewProj.SetValue(cameraViewProjection);
              _parameterCameraNear.SetValue(cameraProjection.Near);
              _parameterCameraFar.SetValue(cameraProjection.Far);

              var lodCameraNode = context.LodCameraNode;
              if (lodCameraNode != null)
              {
            // Enable distance culling.
            _parameterCameraPosition.SetValue((Vector3)lodCameraNode.PoseWorld.Position);
            float yScale = Math.Abs(lodCameraNode.Camera.Projection.ToMatrix44F().M11);
            _parameterNormalizationFactor.SetValue(1.0f / yScale * cameraNode.LodBias * context.LodBias);
              }
              else
              {
            // Disable distance culling.
            _parameterCameraPosition.SetValue(new Vector3());
            _parameterNormalizationFactor.SetValue(0);
              }

              RenderOccluders(renderer, context);
              CreateDepthHierarchy(_cameraHzb, context);

              _sceneNodes.Clear();
              _occlusionProxies.Clear();

              // Restore render state.
              graphicsDevice.SetRenderTarget(null);
              originalRenderState.Restore();

              context.RenderTarget = originalRenderTarget;
              context.Viewport = originalViewport;
        }
Esempio n. 3
0
    // Updates the different sub-systems (input, physics, game logic, ...).
    protected override void Update(GameTime gameTime)
    {
      _deltaTime = gameTime.ElapsedGameTime;

      // Tell the profiler that a new frame has begun.
      _profiler.NewFrame();
      _profiler.Start("Update");

      // Update input manager. The input manager gets the device states and performs other work.
      // (Note: XNA requires that the input service is run on the main thread!)
      _profiler.Start("InputManager.Update             ");
      _inputManager.Update(_deltaTime);
      _profiler.Stop();

      if (EnableParallelGameLoop)
      {
        // In a parallel game loop animation, physics and particles are started at
        // the end of the Update method. The services are now running in parallel. 
        // --> Wait for services to finish.
        _updateAnimationTask.Wait();
        _updatePhysicsTask.Wait();
        _updateParticlesTask.Wait();

        // Now, nothing is running in parallel anymore and we can apply the animations.
        // (This means the animation values are written to the objects and properties
        // that are being animated.)
        _animationManager.ApplyAnimations();
      }
      else
      {
        // Update animation, physics, particles sequentially.

        // For debugging we can pause the physics and particle simulations with <P>,
        // and execute single simulation steps with <T>.
        if (_inputManager.IsPressed(Keys.P, true))
          _isSimulationPaused = !_isSimulationPaused;

        if (!_isSimulationPaused || _inputManager.IsPressed(Keys.T, true))
        {
          // Update physics simulation.
          _profiler.Start("Simulation.Update               ");
          _simulation.Update(_deltaTime);
          _profiler.Stop();

          // Update particles.
          _profiler.Start("ParticleSystemManager.Update    ");
          _particleSystemManager.Update(_deltaTime);
          _profiler.Stop();
        }

        // Update animations.
        // (The animation results are stored internally but not yet applied).
        _profiler.Start("AnimationManger.Update          ");
        _animationManager.Update(_deltaTime);
        _profiler.Stop();

        // Apply animations.
        // (The animation results are written to the objects and properties that 
        // are being animated. ApplyAnimations() must be called at a point where 
        // it is thread-safe to change the animated objects and properties.)
        _profiler.Start("AnimationManager.ApplyAnimations");
        _animationManager.ApplyAnimations();
        _profiler.Stop();
      }

      // Run any task completion callbacks that have been scheduled.
      _profiler.Start("Parallel.RunCallbacks           ");
      Parallel.RunCallbacks();
      _profiler.Stop();

      // When the menu is visible, update SampleFramework before the game logic.
      if (_sampleFramework.IsMenuVisible)
        _sampleFramework.Update();

      // Update XNA GameComponents.
      _profiler.Start("base.Update                     ");
      base.Update(gameTime);
      _profiler.Stop();

      // Update UI manager. The UI manager updates all registered UIScreens.
      _profiler.Start("UIManager.Update                ");
      _uiManager.Update(_deltaTime);
      _profiler.Stop();

      // Update DigitalRune GameObjects.
      _profiler.Start("GameObjectManager.Update        ");
      _gameObjectManager.Update(_deltaTime);
      _profiler.Stop();

      // When the menu is hidden, update SampleFramework after the game logic.
      if (!_sampleFramework.IsMenuVisible)
        _sampleFramework.Update();

      if (EnableParallelGameLoop)
      {
        // Start animation, physics and particle simulation. They will be executed 
        // parallel to the graphics rendering in Draw().
        _updateAnimationTask = Parallel.Start(_updateAnimation);
        _updatePhysicsTask = Parallel.Start(_updatePhysics);
        _updateParticlesTask = Parallel.Start(_updateParticles);
      }

      _profiler.Stop();
    }