예제 #1
0
        public override void Start()
        {
            switch (colorFormat)
            {
            case ColorFormat.Real:
            {
                videoMemory.SetBackgroundColor(ColorEncoder.Format332FromColor(BackgroundColor));
            } break;

            case ColorFormat.High:
            {
                videoMemory.SetBackgroundColor(ColorEncoder.Format565FromColor(BackgroundColor));
            } break;

            case ColorFormat.True:
            {
                videoMemory.SetBackgroundColor(ColorEncoder.Format888FromColor(BackgroundColor));
            } break;

            default:
                break;
            }

            base.Start();
        }
예제 #2
0
 public override void writeTile(int x, int y, int w, int h, Color[] color, float[] alpha)
 {
     int[] tileData = ColorEncoder.encodeRGBE(color);
     for (int j = 0, index = 0, pixel = x + y * width; j < h; j++, pixel += width - w)
     {
         for (int i = 0; i < w; i++, index++, pixel++)
         {
             data[pixel] = tileData[index];
         }
     }
 }
예제 #3
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;
        }
예제 #4
0
 public override void writeTile(int x, int y, int w, int h, Color[] color, float[] alpha)
 {
     color = ColorEncoder.unlinearize(color);             // gamma correction
     byte[] tileData = ColorEncoder.quantizeRGBA8(color, alpha);
     for (int j = 0, index = 0; j < h; j++)
     {
         int imageIndex = 4 * (x + (height - 1 - (y + j)) * width);
         for (int i = 0; i < w; i++, index += 4, imageIndex += 4)
         {
             // swap bytes around so buffer is in native BGRA order
             data[imageIndex + 0] = tileData[index + 2];
             data[imageIndex + 1] = tileData[index + 1];
             data[imageIndex + 2] = tileData[index + 0];
             data[imageIndex + 3] = tileData[index + 3];
         }
     }
 }
예제 #5
0
        public override void writeTile(int x, int y, int w, int h, Color[] color, float[] alpha)
        {
            color = ColorEncoder.unlinearize(color);             // gamma correction
            byte[] tileData = ColorEncoder.quantizeRGBA8(color, alpha);

            lock (data) {
                for (int j = 0, index = 0; j < h; j++)
                {
                    for (int i = 0; i < w; i++, index += 4)
                    {
                        data.SetPixel(x + i, y + j, System.Drawing.Color.FromArgb(tileData[index + 3],
                                                                                  tileData[index],
                                                                                  tileData[index + 1],
                                                                                  tileData[index + 2]));
                    }
                }
            }
        }
예제 #6
0
        private void UpdateCubeMap(TimeSpan deltaTime)
        {
            if (_cloudMapRenderer == null)
            {
                // This is the first call of UpdateCubeMap. Create the renderers which
                // we need to render the cube map.

                // The CloudMapRenderer creates and animates the LayeredCloudMaps.
                _cloudMapRenderer = new CloudMapRenderer(_graphicsService);

                // The SkyRenderer renders SkyNodes.
                _skyRenderer = new SkyRenderer(_graphicsService);

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

                // The SceneCaptureRenderer handles SceneCaptureNodes. We need to specify
                // a render callback which is called in SceneCaptureNode.Render().
                _sceneCaptureRenderer = new SceneCaptureRenderer(RenderSky);

                // Normally, the render context is managed by the graphics service.
                // When we call renderer outside of a GraphicsScreen, we have to use our
                // own context instance.
                _context = new RenderContext(_graphicsService);
            }

            // Update render context. For off-screen rendering we must at least update
            // the time properties (e.g. for cloud animations).
            _context.DeltaTime = deltaTime;
            _context.Time     += deltaTime;
            _context.Frame++;

            // Create cloud maps.
            _cloudMapRenderer.Render(_skyGroupNode.Children, _context);

            // Capture sky in cube map.
            _sceneCaptureRenderer.Render(_sceneCaptureNode, _context);
        }
        /// <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;
                            }
                        }
                    }
                }
            }
        }
예제 #8
0
        public LdrSkySample(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");

            _debugRenderer = new DebugRenderer(GraphicsService, spriteFont);

            _cieSkyFilter          = new CieSkyFilter(GraphicsService);
            _cieSkyFilter.Exposure = 5;
            _cieSkyFilter.Strength = 0.9f;

            _gradientSky = new GradientSkyNode();
            //_gradientSky.GroundColor = new Vector4F(0, 0, 1, 1);
            //_gradientSky.ZenithColor = new Vector4F(0, 0, 1, 1);
            //_gradientSky.FrontColor = new Vector4F(0, 0, 1, 1);
            //_gradientSky.BackColor = new Vector4F(0, 0, 1, 1);
            //_gradientSky.FrontZenithShift = 0.3f;
            //_gradientSky.FrontGroundShift = 0.1f;
            //_gradientSky.BackGroundShift = 0.1f;
            _gradientSky.CieSkyStrength = 0;

            _gradientTextureSky                = new GradientTextureSkyNode();
            _gradientTextureSky.TimeOfDay      = _time.TimeOfDay;
            _gradientTextureSky.Color          = new Vector4F(1);
            _gradientTextureSky.FrontTexture   = ContentManager.Load <Texture2D>("Sky/GradientSkyFront");
            _gradientTextureSky.BackTexture    = ContentManager.Load <Texture2D>("Sky/GradientSkyBack");
            _gradientTextureSky.CieSkyStrength = 1;

            _scatteringSky = new ScatteringSkyNode();
            _scatteringSky.SunIntensity *= 2;
            _scatteringSky.BetaMie      *= 2;
            _scatteringSky.GMie          = 0.75f;
            _scatteringSky.ScaleHeight   = _scatteringSky.AtmosphereHeight * 0.25f;

            InitializeStarfield();

            _cloudMapRenderer = new CloudMapRenderer(GraphicsService);
            _skyRenderer      = new SkyRenderer(GraphicsService);

            _milkyWay       = ContentManager.Load <TextureCube>("Sky/MilkyWay");
            _milkyWaySkybox = new SkyboxNode(_milkyWay)
            {
                Color = new Vector3F(0.05f)
            };

            _sun = new SkyObjectNode
            {
                GlowColor0    = new Vector3F(1, 1, 1) * 5,
                GlowExponent0 = 4000,

                //GlowColor1 = new Vector3F(0.4f) * 0.1f,
                //GlowExponent1 = 100
            };

            _moon = new SkyObjectNode
            {
                Texture         = new PackedTexture(ContentManager.Load <Texture2D>("Sky/Moon")),
                SunLight        = new Vector3F(1, 1, 1) * 1,
                AmbientLight    = new Vector3F(0.001f) * 1,
                LightWrap       = 0.1f,
                LightSmoothness = 1,
                AngularDiameter = new Vector2F(MathHelper.ToRadians(5)),

                GlowColor0          = new Vector3F(0.005f * 0),
                GlowCutoffThreshold = 0.001f,
                GlowExponent0       = 100
            };

            var cloudMap = new LayeredCloudMap
            {
                Density  = 10,
                Coverage = 0.5f,
                Size     = 1024,
            };
            var scale = CreateScale(0.2f);

            cloudMap.Layers[0] = new CloudMapLayer(null, scale * CreateScale(1), -0.5f, 1, 0.011f * 0);
            cloudMap.Layers[1] = new CloudMapLayer(null, scale * CreateScale(1.7f), -0.5f, 1f / 2f, 0.017f * 0);
            cloudMap.Layers[2] = new CloudMapLayer(null, scale * CreateScale(3.97f), -0.5f, 1f / 4f, 0.033f * 0);
            cloudMap.Layers[3] = new CloudMapLayer(null, scale * CreateScale(8.1f), -0.5f, 1f / 8f, 0.043f * 0);
            cloudMap.Layers[4] = new CloudMapLayer(null, scale * CreateScale(16, 17), -0.5f, 1f / 16f, 0.051f * 0);
            cloudMap.Layers[5] = new CloudMapLayer(null, scale * CreateScale(32, 31), -0.5f, 1f / 32f, 0.059f * 0);
            cloudMap.Layers[6] = new CloudMapLayer(null, scale * CreateScale(64, 67), -0.5f, 1f / 64f, 0.067f * 0);
            cloudMap.Layers[7] = new CloudMapLayer(null, scale * CreateScale(128, 127), -0.5f, 1f / 128f, 0.081f * 0);
            _cloudLayerNode    = new CloudLayerNode(cloudMap)
            {
                ForwardScatterScale  = 2.5f,
                ForwardScatterOffset = 0.3f,
                TextureMatrix        = CreateScale(0.5f),
                SkyCurvature         = 0.9f,
                NumberOfSamples      = 16,
            };

            _ephemeris = new Ephemeris();
            // Approx. location of Ternberg: Latitude = 48, Longitude = 15, Altitude = 300
            _ephemeris.Latitude  = 0;
            _ephemeris.Longitude = 15;
            _ephemeris.Altitude  = 300;
#if XBOX
            //_time = new DateTime(2013, 5, 1, 17, 17, 0, 0);
            _time = DateTime.Now;
#else
            _time = new DateTimeOffset(2013, 5, 1, 12, 0, 0, 0, TimeSpan.Zero);
            //_time = DateTimeOffset.UtcNow;
#endif
            UpdateEphemeris();

            _milkyWaySkybox.DrawOrder     = 0;
            _starfield.DrawOrder          = 1;
            _sun.DrawOrder                = 2;
            _moon.DrawOrder               = 3;
            _scatteringSky.DrawOrder      = 4;
            _gradientSky.DrawOrder        = 4;
            _gradientTextureSky.DrawOrder = 4;
            _cloudLayerNode.DrawOrder     = 5;

            _skyNodes = new SceneNode[]
            {
                _milkyWaySkybox,
                _starfield,
                _sun,
                _moon,
                _scatteringSky,
                //_gradientSky,
                //_gradientTextureSky,
                _cloudLayerNode,
            };

            var graphicsDevice = GraphicsService.GraphicsDevice;
            _skybox = new SkyboxNode(
                new RenderTargetCube(graphicsDevice, 512, false, SurfaceFormat.Color, DepthFormat.None))
            {
                Encoding = ColorEncoding.Rgbm,
            };

            _hdrFilter = new HdrFilter(GraphicsService)
            {
                MinExposure    = 0.5f,
                MaxExposure    = 2,
                BloomIntensity = 1,
                BloomThreshold = 0.6f,
                AdaptionSpeed  = 100,
            };

            _colorEncoder = new ColorEncoder(GraphicsService)
            {
                SourceEncoding = ColorEncoding.Rgb,
                TargetEncoding = _skybox.Encoding,
            };
        }
예제 #9
0
        private void UpdateCubeMap(TimeSpan deltaTime)
        {
            if (_cloudMapRenderer == null)
            {
                // This is the first call of UpdateCubeMap. Create the renderers which
                // we need to render the cube map.

                // The CloudMapRenderer creates and animates the LayeredCloudMaps.
                _cloudMapRenderer = new CloudMapRenderer(_graphicsService);

                // The SkyRenderer renders SkyNodes.
                _skyRenderer = new SkyRenderer(_graphicsService);

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

                // The SceneCaptureRenderer handles SceneCaptureNodes. We need to specify
                // a delegate which is called in SceneCaptureNode.Render().
                _sceneCaptureRenderer = new SceneCaptureRenderer(context =>
                {
                    var graphicsDevice   = _graphicsService.GraphicsDevice;
                    var renderTargetPool = _graphicsService.RenderTargetPool;

                    // We have to render into this render target.
                    var ldrTarget = context.RenderTarget;

                    // Reset render states.
                    graphicsDevice.BlendState        = BlendState.Opaque;
                    graphicsDevice.DepthStencilState = DepthStencilState.Default;
                    graphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

                    // 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;

                    graphicsDevice.Clear(Color.Black);

                    // Render the sky.
                    _skyRenderer.Render(_skyGroupNode.Children, context);

                    // 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;
                });

                // Normally, the render context is managed by the graphics service.
                // When we call renderer outside of a GraphicsScreen, we have to use our
                // own context instance.
                _context = new RenderContext(_graphicsService);
            }

            // Update render context.
            // Frame needs to be updated to tell the renderers that this is a new "frame".
            // (Otherwise, they might abort early to avoid duplicate work in the same frame.)
            _context.Frame++;

            // DeltaTime is relevant for renderers such as the CloudMapRenderer because it
            // might have to animate the clouds.
            _context.DeltaTime = deltaTime;

            // Create cloud maps.
            _cloudMapRenderer.Render(_skyGroupNode.Children, _context);

            // Capture sky in cube map.
            _sceneCaptureRenderer.Render(_sceneCaptureNode, _context);
        }