Пример #1
0
        protected override void OnUnload()
        {
            // Detach the scene nodes from the scene.
            if (_skyGroupNode.Parent != null)
            {
                _skyGroupNode.Parent.Children.Remove(_skyGroupNode);
            }

            _lightGroupNode.Parent.Children.Remove(_lightGroupNode);

            // Dispose allocated resources.
            _skyGroupNode.Dispose(false);
            _lightGroupNode.Dispose(false);

            if (_enableClouds)
            {
                _cloudLayerNode0.CloudMap.Dispose();
                _cloudLayerNode1.CloudMap.Dispose();
            }

            if (_cacheSky)
            {
                _sceneCaptureNode.RenderToTexture.Texture.Dispose();
                _sceneCaptureNode.Dispose(false);
                _cloudMapRenderer.Dispose();
                _skyRenderer.Dispose();
                _colorEncoder.Dispose();
                _sceneCaptureRenderer.Dispose();
            }

            // Set references to null.
            _cameraObject         = null;
            _skyGroupNode         = null;
            _lightGroupNode       = null;
            _milkyWayNode         = null;
            _starfieldNode        = null;
            _sunNode              = null;
            _moonNode             = null;
            _scatteringSkyNode    = null;
            _ambientLightNode     = null;
            _sunlightNode         = null;
            _moonlightNode        = null;
            _cloudLayerNode0      = null;
            _cloudLayerNode1      = null;
            _sceneCaptureNode     = null;
            SkyboxNode            = null;
            _cloudMapRenderer     = null;
            _skyRenderer          = null;
            _colorEncoder         = null;
            _sceneCaptureRenderer = null;
        }
Пример #2
0
        //--------------------------------------------------------------
        #region Methods
        //--------------------------------------------------------------

        protected override void OnLoad()
        {
            // Get services.
            _inputService    = _services.GetInstance <IInputService>();
            _graphicsService = _services.GetInstance <IGraphicsService>();
            _scene           = _services.GetInstance <IScene>();
            var content           = _services.GetInstance <ContentManager>();
            var gameObjectService = _services.GetInstance <IGameObjectService>();

            // Get camera game object.
            _cameraObject = (CameraObject)gameObjectService.Objects["Camera"];

            // Create SkyNodes.
            InitializeSky(content);

            // Create LightNodes
            InitializeLights();

            // Optionally, the sky is captured into a cube map and the cube map is added
            // to the scene instead of all the sky nodes.
            if (_cacheSky)
            {
                // We use a SceneCaptureNode to create the cube map.
                // The cube map uses RGBM encoding to store HDR values.
                var renderToTexture = new RenderToTexture
                {
                    Texture = new RenderTargetCube(
                        _graphicsService.GraphicsDevice,
#if XBOX
                        512,
#else
                        1024,
#endif
                        true,
                        SurfaceFormat.Color,
                        DepthFormat.None),
                };
                var projection = new PerspectiveProjection();
                projection.SetFieldOfView(ConstantsF.PiOver2, 1, 1, 10);
                _sceneCaptureNode = new SceneCaptureNode(renderToTexture)
                {
                    // Note: The scene is captured at the origin (0, 0, 0).
                    CameraNode = new CameraNode(new Camera(projection)),
                };

                SkyboxNode = new SkyboxNode
                {
                    Encoding = ColorEncoding.Rgbm,
                    Texture  = (TextureCube)renderToTexture.Texture,
                };
                _scene.Children.Add(SkyboxNode);
            }

            // The Ephemeris class computes the positions of the sun and the moon as seen
            // from any place on the earth.
            _ephemeris = new Ephemeris
            {
                // Seattle, Washington
                //Latitude = 47,
                //Longitude = 122,
                //Altitude = 100

                // Vienna
                //Latitude = 48,
                //Longitude = -16,
                //Altitude = 0

                // Equator
                Latitude  = 0,
                Longitude = 0,
                Altitude  = 0
            };

            // Update the positions of sky objects and the lights.
            UpdateSky();

            // Create cube map.
            if (_cacheSky)
            {
                UpdateCubeMap(TimeSpan.Zero);
            }

            // Add GUI controls to the Options window.
            var sampleFramework = _services.GetInstance <SampleFramework>();
            var optionsPanel    = sampleFramework.AddOptions("Game Objects");
            var panel           = SampleHelper.AddGroupBox(optionsPanel, "DynamicSkyObject");

            SampleHelper.AddSlider(
                panel,
                "Time",
                "F2",
                0,
                24,
                (float)Time.TimeOfDay.TotalHours,
                value =>
            {
                var time = Time;
                time     = time.Subtract(time.TimeOfDay).Add(TimeSpan.FromHours(value));
                Time     = time;
            });

            SampleHelper.AddCheckBox(
                panel,
                "Enable ambient light",
                EnableAmbientLight,
                isChecked => EnableAmbientLight = isChecked);

            SampleHelper.AddSlider(
                panel,
                "Fog sample angle",
                "F2",
                0,
                ConstantsF.PiOver2,
                FogSampleAngle,
                value => FogSampleAngle = value);

            SampleHelper.AddSlider(
                panel,
                "Fog saturation",
                "F2",
                0,
                1,
                FogSaturation,
                value => FogSaturation = value);

            //SampleHelper.AddSlider(
            //  panel,
            //  "Fog scattering symmetry R",
            //  "F2",
            //  0,
            //  1,
            //  FogScatteringSymmetry.X,
            //  value => FogScatteringSymmetry = new Vector3F(value, FogScatteringSymmetry.Y, FogScatteringSymmetry.Z));
            //SampleHelper.AddSlider(
            //  panel,
            //  "Fog scattering symmetry G",
            //  "F2",
            //  0,
            //  1,
            //  FogScatteringSymmetry.Y,
            //  value => FogScatteringSymmetry = new Vector3F(FogScatteringSymmetry.X, value, FogScatteringSymmetry.Z));
            //SampleHelper.AddSlider(
            //  panel,
            //  "Fog scattering symmetry B",
            //  "F2",
            //  0,
            //  1,
            //  FogScatteringSymmetry.Z,
            //  value => FogScatteringSymmetry = new Vector3F(FogScatteringSymmetry.X, FogScatteringSymmetry.Y, value));
        }
Пример #3
0
        public SceneCaptureCubeSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            // Create a graphics screen. This screen has to call the SceneCaptureRenderer
            // to handle the SceneCaptureNodes!
            _graphicsScreen = new DeferredGraphicsScreen(Services)
            {
                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;

            // More standard objects.
            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            //GameObjectService.Objects.Add(new StaticSkyObject(Services));
            GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new DudeObject(Services));
            GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            GameObjectService.Objects.Add(new DynamicObject(Services, 2));
            GameObjectService.Objects.Add(new DynamicObject(Services, 5));
            GameObjectService.Objects.Add(new DynamicObject(Services, 6));
            GameObjectService.Objects.Add(new DynamicObject(Services, 7));
            GameObjectService.Objects.Add(new FogObject(Services)
            {
                AttachToCamera = true
            });
            GameObjectService.Objects.Add(new LavaBallsObject(Services));

            // 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 the "Bubble" mesh and place it at a fixed position in the scene.
            var modelNode = ContentManager.Load <ModelNode>("Bubble/Bubble");
            var meshNode  = modelNode.GetDescendants().OfType <MeshNode>().First().Clone();

            meshNode.PoseWorld = new Pose(new Vector3F(0, 1, 0));
            _graphicsScreen.Scene.Children.Add(meshNode);

            // Surface of the mesh should reflect the scene in real-time. Reflections are
            // created using environment mapping: The scene is rendered into a cube map,
            // which is then applied to the mesh.
            // To render the scene into a cube map, we need to define a CameraNode and a
            // SceneCaptureNode: The CameraNode defines the point from where the scene is
            // captured. The SceneCaptureNode defines where and in which format the captured
            // image is needed.

            // Attach a camera to the center of the mesh.
            var projection = new PerspectiveProjection();

            projection.SetFieldOfView(ConstantsF.PiOver2, 1, 0.1f, 20);
            var captureCameraNode = new CameraNode(new Camera(projection));

            meshNode.Children = new SceneNodeCollection {
                captureCameraNode
            };

            // Attach a SceneCaptureNode with a cube map render target to the mesh.
            var renderToTexture = new RenderToTexture
            {
                Texture = new RenderTargetCube(
                    GraphicsService.GraphicsDevice,
                    256,
                    true,
                    SurfaceFormat.Color,
                    DepthFormat.None),
            };
            var sceneCaptureNode = new SceneCaptureNode(renderToTexture)
            {
                Shape      = meshNode.Shape,
                CameraNode = captureCameraNode,
            };

            meshNode.Children.Add(sceneCaptureNode);

            // The bubble model uses a special effect and is rendered in the "AlphaBlend"
            // render pass. Let's modify the effect parameters to use the created cube map
            // as the reflection map of the bubble.
            var effectBinding = meshNode.Mesh.Materials[0]["AlphaBlend"];

            effectBinding.Set("ReflectionStrength", 0.5f);
            effectBinding.Set("RefractionStrength", 0.0f);
            effectBinding.Set("FresnelBias", 1.0f);
            effectBinding.Set("BlendMode", 1.0f);
            effectBinding.Set("Alpha", 1.0f);
            effectBinding.Set("CustomEnvironmentMap", (TextureCube)renderToTexture.Texture);
        }
        /// <summary>
        /// Renders the environment maps for the image-based lights.
        /// </summary>
        /// <remarks>
        /// This method uses the current DeferredGraphicsScreen to render new environment maps at
        /// runtime. The DeferredGraphicsScreen has a SceneCaptureRenderer which we can use to
        /// capture environment maps of the current scene.
        /// To capture new environment maps the flag _updateEnvironmentMaps must be set to true.
        /// When this flag is set, SceneCaptureNodes are added to the scene. When the graphics
        /// screen calls the SceneCaptureRenderer the next time, the new environment maps will be
        /// captured.
        /// The flag _updateEnvironmentMaps remains true until the new environment maps are available.
        /// This method checks the SceneCaptureNode.LastFrame property to check if new environment maps
        /// have been computed. Usually, the environment maps will be available in the next frame.
        /// (However, the XNA Game class can skip graphics rendering if the game is running slowly.
        /// Then we would have to wait more than 1 frame.)
        /// When environment maps are being rendered, the image-based lights are disabled to capture
        /// only the scene with ambient and directional lights. Dynamic objects are also disabled
        /// to capture only the static scene.
        /// </remarks>
        private void UpdateEnvironmentMaps()
        {
            if (!_updateEnvironmentMaps)
            {
                return;
            }

            // One-time initializations:
            if (_sceneCaptureNodes[0] == null)
            {
                // Create cube maps and scene capture nodes.
                // (Note: A cube map size of 256 is enough for surfaces with a specular power
                // in the range [0, 200000].)
                for (int i = 0; i < _sceneCaptureNodes.Length; i++)
                {
                    var renderTargetCube = new RenderTargetCube(
                        GraphicsService.GraphicsDevice,
                        256,
                        true,
                        SurfaceFormat.Color,
                        DepthFormat.None);

                    var renderToTexture = new RenderToTexture {
                        Texture = renderTargetCube
                    };
                    var projection = new PerspectiveProjection();
                    projection.SetFieldOfView(ConstantsF.PiOver2, 1, 1, 100);
                    _sceneCaptureNodes[i] = new SceneCaptureNode(renderToTexture)
                    {
                        CameraNode = new CameraNode(new Camera(projection))
                        {
                            PoseWorld = _lightNodes[i].PoseWorld,
                        },
                    };

                    _imageBasedLights[i].Texture = renderTargetCube;
                }

                // We use a ColorEncoder to encode a HDR image in a normal Color texture.
                _colorEncoder = new ColorEncoder(GraphicsService)
                {
                    SourceEncoding = ColorEncoding.Rgb,
                    TargetEncoding = ColorEncoding.Rgbm,
                };

                // The SceneCaptureRenderer has a render callback which defines what is rendered
                // into the scene capture render targets.
                _graphicsScreen.SceneCaptureRenderer.RenderCallback = context =>
                {
                    var graphicsDevice   = GraphicsService.GraphicsDevice;
                    var renderTargetPool = GraphicsService.RenderTargetPool;

                    // Get scene nodes which are visible by the current camera.
                    CustomSceneQuery sceneQuery = context.Scene.Query <CustomSceneQuery>(context.CameraNode, context);

                    // The final image has to be rendered into this render target.
                    var ldrTarget = context.RenderTarget;

                    // Use an intermediate HDR render target with the same resolution as the final target.
                    var format = new RenderTargetFormat(ldrTarget)
                    {
                        SurfaceFormat      = SurfaceFormat.HdrBlendable,
                        DepthStencilFormat = DepthFormat.Depth24Stencil8
                    };
                    var hdrTarget = renderTargetPool.Obtain2D(format);

                    graphicsDevice.SetRenderTarget(hdrTarget);
                    context.RenderTarget = hdrTarget;

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

                    // Convert the HDR image to RGBM image.
                    context.SourceTexture = hdrTarget;
                    context.RenderTarget  = ldrTarget;
                    _colorEncoder.Process(context);
                    context.SourceTexture = null;

                    // Clean up.
                    renderTargetPool.Recycle(hdrTarget);
                    context.RenderTarget = ldrTarget;
                };
            }

            if (_sceneCaptureNodes[0].Parent == null)
            {
                // Add the scene capture nodes to the scene.
                for (int i = 0; i < _sceneCaptureNodes.Length; i++)
                {
                    _graphicsScreen.Scene.Children.Add(_sceneCaptureNodes[i]);
                }

                // Remember the old time stamp of the nodes.
                _oldEnvironmentMapTimeStamp = _sceneCaptureNodes[0].LastFrame;

                // Disable all lights except ambient and directional lights.
                // We do not capture the image-based lights or any other lights (e.g. point lights)
                // in the cube map.
                foreach (var lightNode in _graphicsScreen.Scene.GetDescendants().OfType <LightNode>())
                {
                    lightNode.IsEnabled = (lightNode.Light is AmbientLight) || (lightNode.Light is DirectionalLight);
                }

                // Disable dynamic objects.
                foreach (var node in _graphicsScreen.Scene.GetDescendants())
                {
                    if (node is MeshNode || node is LodGroupNode)
                    {
                        if (!node.IsStatic)
                        {
                            node.IsEnabled = false;
                        }
                    }
                }
            }
            else
            {
                // The scene capture nodes are part of the scene. Check if they have been
                // updated.
                if (_sceneCaptureNodes[0].LastFrame != _oldEnvironmentMapTimeStamp)
                {
                    // We have new environment maps. Restore the normal scene.
                    for (int i = 0; i < _sceneCaptureNodes.Length; i++)
                    {
                        _graphicsScreen.Scene.Children.Remove(_sceneCaptureNodes[i]);
                    }

                    _updateEnvironmentMaps = false;

                    foreach (var lightNode in _graphicsScreen.Scene.GetDescendants().OfType <LightNode>())
                    {
                        lightNode.IsEnabled = true;
                    }

                    foreach (var node in _graphicsScreen.Scene.GetDescendants())
                    {
                        if (node is MeshNode || node is LodGroupNode)
                        {
                            if (!node.IsStatic)
                            {
                                node.IsEnabled = true;
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
        //--------------------------------------------------------------
        #region Methods
        //--------------------------------------------------------------

        protected override void OnLoad()
        {
            // Get services.
            _inputService    = _services.GetInstance <IInputService>();
            _graphicsService = _services.GetInstance <IGraphicsService>();
            _scene           = _services.GetInstance <IScene>();
            var content           = _services.GetInstance <ContentManager>();
            var gameObjectService = _services.GetInstance <IGameObjectService>();

            // Get camera game object.
            _cameraObject = (CameraObject)gameObjectService.Objects["Camera"];

            // Create SkyNodes.
            InitializeSky(content);

            // Create LightNodes
            InitializeLights();

            // Optionally, the sky is captured into a cube map and the cube map is added
            // to the scene instead of all the sky nodes.
            if (_cacheSky)
            {
                // We use a SceneCaptureNode to create the cube map.
                // The cube map uses RGBM encoding to store HDR values.
                var renderToTexture = new RenderToTexture
                {
                    Texture = new RenderTargetCube(
                        _graphicsService.GraphicsDevice, 1024, false,
                        SurfaceFormat.Color, DepthFormat.None),
                };
                var projection = new PerspectiveProjection();
                projection.SetFieldOfView(ConstantsF.PiOver2, 1, 1, 10);
                _sceneCaptureNode = new SceneCaptureNode(renderToTexture)
                {
                    // Note: The scene is captured at the origin (0, 0, 0).
                    CameraNode = new CameraNode(new Camera(projection)),
                };

                SkyboxNode = new SkyboxNode
                {
                    Encoding = ColorEncoding.Rgbm,
                    Texture  = (TextureCube)renderToTexture.Texture,
                };
                _scene.Children.Add(SkyboxNode);
            }

            // The Ephemeris class computes the positions of the sun and the moon as seen
            // from any place on the earth.
            _ephemeris = new Ephemeris
            {
                // Seattle, Washington
                //Latitude = 47,
                //Longitude = 122,
                //Altitude = 100

                // Vienna
                //Latitude = 48,
                //Longitude = -16,
                //Altitude = 0

                // Equator
                Latitude  = 0,
                Longitude = 90,
                Altitude  = 0
            };

#if XBOX
            _time = DateTime.Now;
#else
            _time = DateTimeOffset.Now;
#endif

            // Update the positions of sky objects and the lights.
            UpdateSky();

            // Create cube map.
            if (_cacheSky)
            {
                UpdateCubeMap(TimeSpan.Zero);
            }
        }