Пример #1
0
 public RenderTargetBinding[] GetRenderTargets()
 {
     // Return a correctly sized copy our internal array.
     RenderTargetBinding[] bindings = new RenderTargetBinding[renderTargetCount];
     Array.Copy(renderTargetBindings, bindings, renderTargetCount);
     return(bindings);
 }
        public DeferredRenderer(GraphicsDevice GraphicsDevice, int Width, int Height)
            : base(GraphicsDevice)
        {
            //Create LightMap BlendState
            LightMapBS = new BlendState();
            LightMapBS.ColorSourceBlend = Blend.One;
            LightMapBS.ColorDestinationBlend = Blend.One;
            LightMapBS.ColorBlendFunction = BlendFunction.Add;
            LightMapBS.AlphaSourceBlend = Blend.One;
            LightMapBS.AlphaDestinationBlend = Blend.One;
            LightMapBS.AlphaBlendFunction = BlendFunction.Add;

            //Set GBuffer Texture Size
            GBufferTextureSize = new Vector2(Width, Height);

            //Intialize Each Target of the GBuffer
            GBufferTargets = new RenderTargetBinding[3];
            GBufferTargets[0] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, Width, Height, false, SurfaceFormat.Rgba64, DepthFormat.Depth24Stencil8));
            GBufferTargets[1] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, Width, Height, false, SurfaceFormat.Rgba64, DepthFormat.Depth24Stencil8));
            GBufferTargets[2] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, Width, Height, false, SurfaceFormat.Vector2, DepthFormat.Depth24Stencil8));

            //Initialize LightMap
            LightMap = new RenderTarget2D(GraphicsDevice, Width, Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);

            //Create Fullscreen Quad
            fsq = new FullscreenQuad(GraphicsDevice);
        }
Пример #3
0
        internal void ClearTargets(GraphicsDevice device, RenderTargetBinding[] targets)
        {
            // NOTE: We make the assumption here that the caller has
            // locked the d3dContext for us to use.
            var pixelShaderStage = device._d3dContext.PixelShader;

            // We assume 4 targets to avoid a loop within a loop below.
            var target0 = targets[0].RenderTarget;
            var target1 = targets[1].RenderTarget;
            var target2 = targets[2].RenderTarget;
            var target3 = targets[3].RenderTarget;

            // Make one pass across all the texture slots.
            for (var i = 0; i < _textures.Length; i++)
            {
                if (_textures[i] != target0 &&
                    _textures[i] != target1 &&
                    _textures[i] != target2 &&
                    _textures[i] != target3)
                    continue;

                // Immediately clear the texture from the device.
                _dirty &= ~(1 << i);
                _textures[i] = null;
                pixelShaderStage.SetShaderResource(i, null);
            }
        }
Пример #4
0
 public void ResolveTarget(RenderTargetBinding target)
 {
     ForceToMainThread(() =>
     {
         GLDevice.ResolveTarget(target);
     });             // End ForceToMainThread
 }
Пример #5
0
 public void SetRenderTarget(RenderTarget2D renderTarget)
 {
     if (renderTarget == null)
     {
         SetRenderTargets(null);
     }
     else
     {
         singleTargetCache[0] = new RenderTargetBinding(renderTarget);
         SetRenderTargets(singleTargetCache);
     }
 }
Пример #6
0
 public void SetRenderTarget(RenderTargetCube renderTarget, CubeMapFace cubeMapFace)
 {
     if (renderTarget == null)
     {
         SetRenderTargets(null);
     }
     else
     {
         _tempRenderTargetBinding[0] = new RenderTargetBinding(renderTarget, cubeMapFace);
         SetRenderTargets(_tempRenderTargetBinding);
     }
 }
Пример #7
0
 public void SetRenderTarget(RenderTargetCube renderTarget, CubeMapFace cubeMapFace)
 {
     if (renderTarget == null)
     {
         SetRenderTargets(null);
     }
     else
     {
         singleTargetCache[0] = new RenderTargetBinding(renderTarget, cubeMapFace);
         SetRenderTargets(singleTargetCache);
     }
 }
Пример #8
0
 public void SetRenderTarget(RenderTarget2D renderTarget)
 {
     if (renderTarget == null)
     {
         SetRenderTargets(null);
     }
     else
     {
         _tempRenderTargetBinding[0] = new RenderTargetBinding(renderTarget);
         SetRenderTargets(_tempRenderTargetBinding);
     }
 }
Пример #9
0
        public void SetRenderTargets(int[] indices)
        {
            if (indices.Length == 1)
            {
                SetRenderTarget(indices[0]);
                return;
            }

            var targets = new RenderTargetBinding[indices.Length];

            for (var i = 0; i < indices.Length; ++i)
            {
                targets[i] = new RenderTargetBinding(GetRenderTarget(indices[i]));
            }

            PrevRenderTargetIndex = -1;

            GraphicsDevice.SetRenderTargets(targets);
        }
		/// <summary></summary>
		/// <param name="state"></param>
		protected internal override void Begin(DrawState state)
		{
			if (targets == null)
				throw new ObjectDisposedException("this");

			for (int i = 0; i < targets.Length; i++)
			{
				targets[i].Warm(state);
				if (targets[i].IsDisposed)
					throw new ObjectDisposedException("RenderTexture");
			}

#if XBOX360
			state.nonScreenRenderComplete = true;
#endif

			GraphicsDevice device = state.graphics;

			state.shaderSystem.ResetTextures();

			if (binding == null)
			{
				this.binding = new RenderTargetBinding[targets.Length];
				for (int i = 0; i < targets.Length; i++)
					binding[i] = new RenderTargetBinding(targets[i].GetRenderTarget2D());
			}

			device.SetRenderTargets(binding);
		}
Пример #11
0
        private void ProcessClipmap(TerrainNode node, TerrainClipmap clipmap, RenderContext context)
        {
            var graphicsDevice = context.GraphicsService.GraphicsDevice;
              var lodCameraNode = context.LodCameraNode ?? context.CameraNode;

              bool isBaseClipmap = (node.BaseClipmap == clipmap);

              // Update the clipmap render targets if necessary.
              InitializeClipmapTextures(graphicsDevice, clipmap);

              // Update other clipmap data (origins, offsets, ...). No rendering.
              // (Data is stored in TerrainClipmap class.)
              UpdateClipmapData(node, clipmap, lodCameraNode, isBaseClipmap);

              // Compute which rectangular regions need to be updated.
              // (Data is stored in TerrainClipmap class.)
              ComputeInvalidRegions(node, clipmap, isBaseClipmap);

              // Abort if there are no invalid regions.
              int numberOfInvalidRegions = 0;
              for (int level = 0; level < clipmap.NumberOfLevels; level++)
            numberOfInvalidRegions += clipmap.InvalidRegions[level].Count;

              Debug.Assert(numberOfInvalidRegions > 0 || clipmap.UseIncrementalUpdate,
            "If the clipmap update is not incremental, there must be at least one invalid region.");

              if (numberOfInvalidRegions == 0)
            return;

              // Set render target binding to render into all clipmap textures at once.
              int numberOfTextures = clipmap.Textures.Length;
              if (_renderTargetBindings[numberOfTextures] == null)
            _renderTargetBindings[numberOfTextures] = new RenderTargetBinding[numberOfTextures];

              for (int i = 0; i < numberOfTextures; i++)
            _renderTargetBindings[numberOfTextures][i] = new RenderTargetBinding((RenderTarget2D)clipmap.Textures[i]);

              switch (numberOfTextures)
              {
            case 1: context.Technique = "RenderTargets1"; break;
            case 2: context.Technique = "RenderTargets2"; break;
            case 3: context.Technique = "RenderTargets3"; break;
            case 4: context.Technique = "RenderTargets4"; break;
            default: context.Technique = null; break;
              }

              graphicsDevice.SetRenderTargets(_renderTargetBindings[numberOfTextures]);

              // The viewport covers the whole texture atlas.
              var viewport = graphicsDevice.Viewport;
              context.Viewport = viewport;

              Debug.Assert(_previousMaterialBinding == null);

              // Loop over all layers. Render each layer into all levels (if there is an invalid region).
              Aabb tileAabb = new Aabb(new Vector3F(-Terrain.TerrainLimit), new Vector3F(Terrain.TerrainLimit));
              ProcessLayer(graphicsDevice, context, clipmap, isBaseClipmap, _clearLayer, tileAabb);
              foreach (var tile in node.Terrain.Tiles)
              {
            tileAabb = tile.Aabb;
            context.Object = tile;
            ProcessLayer(graphicsDevice, context, clipmap, isBaseClipmap, tile, tileAabb);

            foreach (var layer in tile.Layers)
              ProcessLayer(graphicsDevice, context, clipmap, isBaseClipmap, layer, tileAabb);

            context.Object = null;
              }

              _previousMaterialBinding = null;

              ClearFlags(_clearLayer, context);
              foreach (var tile in node.Terrain.Tiles)
              {
            ClearFlags(tile, context);
            foreach (var layer in tile.Layers)
              ClearFlags(layer, context);
              }

              // All invalid regions handled.
              for (int i = 0; i < clipmap.NumberOfLevels; i++)
            clipmap.InvalidRegions[i].Clear();

              // The next time we can update incrementally.
              clipmap.UseIncrementalUpdate = true;
        }
Пример #12
0
        public void ResolveTarget(RenderTargetBinding target)
        {
            if ((target.RenderTarget as IRenderTarget).MultiSampleCount > 0)
            {
                // Set up the texture framebuffer
                int width, height;
                if (target.RenderTarget is RenderTarget2D)
                {
                    Texture2D target2D = (target.RenderTarget as Texture2D);
                    width = target2D.Width;
                    height = target2D.Height;
                    glNamedFramebufferTexture(
                        resolveFramebufferDraw,
                        GLenum.GL_COLOR_ATTACHMENT0,
                        (target.RenderTarget.texture as OpenGLTexture).Handle,
                        0
                    );
                }
                else
                {
                    TextureCube targetCube = (target.RenderTarget as TextureCube);
                    width = targetCube.Size;
                    height = targetCube.Size;
                    glNamedFramebufferTextureLayer(
                        resolveFramebufferDraw,
                        GLenum.GL_COLOR_ATTACHMENT0,
                        (target.RenderTarget.texture as OpenGLTexture).Handle,
                        0,
                        (int) target.CubeMapFace
                    );
                }

                // Set up the renderbuffer framebuffer
                glNamedFramebufferRenderbuffer(
                    resolveFramebufferRead,
                    GLenum.GL_COLOR_ATTACHMENT0,
                    GLenum.GL_RENDERBUFFER,
                    ((target.RenderTarget as IRenderTarget).ColorBuffer as OpenGLRenderbuffer).Handle
                );

                // Blit!
                if (scissorTestEnable)
                {
                    glDisable(GLenum.GL_SCISSOR_TEST);
                }
                glBlitNamedFramebuffer(
                    resolveFramebufferRead,
                    resolveFramebufferDraw,
                    0, 0, width, height,
                    0, 0, width, height,
                    GLenum.GL_COLOR_BUFFER_BIT,
                    GLenum.GL_LINEAR
                );
                if (scissorTestEnable)
                {
                    glEnable(GLenum.GL_SCISSOR_TEST);
                }
            }

            // If the target has mipmaps, regenerate them now
            if (target.RenderTarget.LevelCount > 1)
            {
                glGenerateTextureMipmap((target.RenderTarget.texture as OpenGLTexture).Handle);
            }
        }
Пример #13
0
 TextureTarget IRenderTarget.GetFramebufferTarget(RenderTargetBinding renderTargetBinding)
 {
     return(TextureTarget.TextureCubeMapPositiveX + renderTargetBinding.ArraySlice);
 }
Пример #14
0
        private void CreateGBuffer()
        {
            //One of our premises is to do not use the PRESERVE CONTENTS flags, 
            //that is supposed to be more expensive than DISCARD CONTENT.
            //We use a floating point (32bit) buffer for Z values, although our HW use only 24bits.
            //We could use some packing and use a 24bit buffer too, but lets start simpler
            _depthBuffer = new RenderTarget2D(GraphicsDevice, _width, _height, false, SurfaceFormat.Single,
                                              DepthFormat.None, 0, RenderTargetUsage.DiscardContents);

            //the downsampled depth buffer must have the same format as the main one
            _halfDepth = new RenderTarget2D(GraphicsDevice, _width / 2, _height / 2, false,
                                              SurfaceFormat.Single, DepthFormat.None, 0,
                                              RenderTargetUsage.DiscardContents);

            //Our normal buffer stores encoded view-space normal into RG (10bit each) and the specular power in B.
            //Some engines encode the specular power with some log or ln functions. We will output 
            //only the normal texture's alpha channel multiplied by a const value (100),
            //so we have specular power in the range [1..100].
            //Currently, A is not used (2bit).
            _normalBuffer = new RenderTarget2D(GraphicsDevice, _width, _height, false, SurfaceFormat.Rgba1010102,
                                               DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);

            //This buffer stores all the "pure" lighting on the scene, no albedo applied to it. We use an floating
            //point format to allow us "overbright" some areas. Read the blog for more information. We use a depth buffer
            //to optimize light rendering.
            _lightBuffer = new RenderTarget2D(GraphicsDevice, _width, _height, false, SurfaceFormat.HdrBlendable,
                                              DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);

            //we need a separate texture for the specular, since the xbox doesnt allow a RGBA64 buffer
            _lightSpecularBuffer = new RenderTarget2D(GraphicsDevice, _width, _height, false,
                                             SurfaceFormat.HdrBlendable, DepthFormat.None, 0,
                                             RenderTargetUsage.DiscardContents);

            //We need another depth here because we need to render all objects again, to reconstruct their shading 
            //using our light texture.
            _outputTexture = new RenderTarget2D(GraphicsDevice, _width, _height, false, SurfaceFormat.Color,
                                                DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);

            int halfRes = 2;
            _halfBuffer0 = new RenderTarget2D(GraphicsDevice, _width / halfRes, _height / halfRes, false,
                                              SurfaceFormat.Color, DepthFormat.None, 0,
                                              RenderTargetUsage.DiscardContents);
            _halfBuffer1 = new RenderTarget2D(GraphicsDevice, _width / halfRes, _height / halfRes, false,
                                              SurfaceFormat.Color, DepthFormat.None, 0,
                                              RenderTargetUsage.DiscardContents);

            _gBufferBinding[0] = new RenderTargetBinding(_normalBuffer);
            _gBufferBinding[1] = new RenderTargetBinding(_depthBuffer);

            _lightAccumBinding[0] = new RenderTargetBinding(_lightBuffer);
            _lightAccumBinding[1] = new RenderTargetBinding(_lightSpecularBuffer);
        }
Пример #15
0
        // Perform FFTs.
        // 4 complex input images: source0.xy, source0.zw, source1.xy, source1.zw
        // 2 targets: target0 = displacement map, target1 = normal map using Color format.
        public void Process(RenderContext context, bool forward, Texture2D source0, Texture2D source1, RenderTarget2D target0, RenderTarget2D target1, float choppiness)
        {
            if (context == null)
            throw new ArgumentNullException("context");
              if (source0 == null)
            throw new ArgumentNullException("source0");
              if (source1 == null)
            throw new ArgumentNullException("source1");

              if (forward)
              {
            // For forward FFT, uncomment the LastPassScale stuff!
            throw new NotImplementedException("Forward FFT not implemented.");
              }

              var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              var renderTargetPool = graphicsService.RenderTargetPool;

              var savedRenderState = new RenderStateSnapshot(graphicsDevice);

              graphicsDevice.BlendState = BlendState.Opaque;
              graphicsDevice.RasterizerState = RasterizerState.CullNone;
              graphicsDevice.DepthStencilState = DepthStencilState.None;

              int size = source0.Width;
              _parameterSize.SetValue((float)size);

              _parameterChoppiness.SetValue(choppiness);

              int numberOfButterflyPasses = (int)MathHelper.Log2GreaterOrEqual((uint)source0.Width);
              // ReSharper disable once ConditionIsAlwaysTrueOrFalse
              _parameterButterflyTexture.SetValue(GetButterflyTexture(forward, numberOfButterflyPasses));

              var format = new RenderTargetFormat(size, size, false, source0.Format, DepthFormat.None);
              var tempPing0 = renderTargetPool.Obtain2D(format);
              var tempPing1 = renderTargetPool.Obtain2D(format);
              var tempPong0 = renderTargetPool.Obtain2D(format);
              var tempPong1 = renderTargetPool.Obtain2D(format);

              //_parameterIsLastPass.SetValue(false);

              // Perform horizontal and vertical FFT pass.
              for (int i = 0; i < 2; i++)
              {
            //_parameterLastPassScale.SetValue(1);

            // Perform butterfly passes. We ping-pong between two temp targets.
            for (int pass = 0; pass < numberOfButterflyPasses; pass++)
            {
              _parameterButterflyIndex.SetValue(0.5f / numberOfButterflyPasses + (float)pass / numberOfButterflyPasses);

              if (i == 0 && pass == 0)
              {
            // First pass.
            _renderTargetBindings[0] = new RenderTargetBinding(tempPing0);
            _renderTargetBindings[1] = new RenderTargetBinding(tempPing1);
            graphicsDevice.SetRenderTargets(_renderTargetBindings);
            _parameterSourceTexture0.SetValue(source0);
            _parameterSourceTexture1.SetValue(source1);
              }
              else if (i == 1 && pass == numberOfButterflyPasses - 1)
              {
            // Last pass.
            // We have explicit shader passes for the last FFT pass.
            break;

            //_parameterIsLastPass.SetValue(true);
            //if (forward)
            //  _parameterLastPassScale.SetValue(1.0f / size / size);

            //if (_renderTargetBindings[0].RenderTarget == tempPing0)
            //{
            //  _renderTargetBindings[0] = new RenderTargetBinding(target0);
            //  _renderTargetBindings[1] = new RenderTargetBinding(target1);
            //  graphicsDevice.SetRenderTargets(_renderTargetBindings);
            //  _parameterSourceTexture0.SetValue(tempPing0);
            //  _parameterSourceTexture1.SetValue(tempPing1);
            //}
            //else
            //{
            //  _renderTargetBindings[0] = new RenderTargetBinding(target0);
            //  _renderTargetBindings[1] = new RenderTargetBinding(target1);
            //  graphicsDevice.SetRenderTargets(_renderTargetBindings);
            //  _parameterSourceTexture0.SetValue(tempPong0);
            //  _parameterSourceTexture1.SetValue(tempPong1);
            //}
              }
              else
              {
            // Intermediate pass.
            if (_renderTargetBindings[0].RenderTarget == tempPing0)
            {
              _renderTargetBindings[0] = new RenderTargetBinding(tempPong0);
              _renderTargetBindings[1] = new RenderTargetBinding(tempPong1);
              graphicsDevice.SetRenderTargets(_renderTargetBindings);
              _parameterSourceTexture0.SetValue(tempPing0);
              _parameterSourceTexture1.SetValue(tempPing1);
            }
            else
            {
              _renderTargetBindings[0] = new RenderTargetBinding(tempPing0);
              _renderTargetBindings[1] = new RenderTargetBinding(tempPing1);
              graphicsDevice.SetRenderTargets(_renderTargetBindings);
              _parameterSourceTexture0.SetValue(tempPong0);
              _parameterSourceTexture1.SetValue(tempPong1);
            }
              }

              if (i == 0)
            _passFftHorizontal.Apply();
              else
            _passFftVertical.Apply();

              graphicsDevice.DrawFullScreenQuad();
            }
              }

              // Perform final vertical FFT passes. We have to perform them separately
              // because displacement map and normal map usually have different bit depth.
              // Final pass for displacement.
              graphicsDevice.SetRenderTarget(target0);
              if (_renderTargetBindings[1].RenderTarget == tempPing1)
            _parameterSourceTexture0.SetValue(tempPing0);
              else
            _parameterSourceTexture0.SetValue(tempPong0);

              _passFftDisplacement.Apply();
              graphicsDevice.DrawFullScreenQuad();

              // Final pass for normals.
              graphicsDevice.SetRenderTarget(target1);
              if (_renderTargetBindings[1].RenderTarget == tempPing1)
            _parameterSourceTexture0.SetValue(tempPing1);
              else
            _parameterSourceTexture0.SetValue(tempPong1);

              _passFftNormal.Apply();
              graphicsDevice.DrawFullScreenQuad();

              // Clean up.
              _renderTargetBindings[0] = default(RenderTargetBinding);
              _renderTargetBindings[1] = default(RenderTargetBinding);
              _parameterButterflyTexture.SetValue((Texture2D)null);
              _parameterSourceTexture0.SetValue((Texture2D)null);
              _parameterSourceTexture1.SetValue((Texture2D)null);

              renderTargetPool.Recycle(tempPing0);
              renderTargetPool.Recycle(tempPing1);
              renderTargetPool.Recycle(tempPong0);
              renderTargetPool.Recycle(tempPong1);

              savedRenderState.Restore();

              // Reset the texture stages. If a floating point texture is set, we get exceptions
              // when a sampler with bilinear filtering is set.
            #if !MONOGAME
              graphicsDevice.ResetTextures();
            #endif
        }
Пример #16
0
        //--------------------------------------------------------------
        public void Render(IList<SceneNode> lights, RenderContext context)
        {
            var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              var renderTargetPool = graphicsService.RenderTargetPool;

              var target = context.RenderTarget;
              var viewport = context.Viewport;
              var width = viewport.Width;
              var height = viewport.Height;

              RenderTarget2D aoRenderTarget = null;
              if (_ssaoFilter != null)
              {
            // Render ambient occlusion info into a render target.
            aoRenderTarget = renderTargetPool.Obtain2D(new RenderTargetFormat(
              width / _ssaoDownsampleFactor,
              height / _ssaoDownsampleFactor,
              false,
              SurfaceFormat.Color,
              DepthFormat.None));

            // PostProcessors require that context.SourceTexture is set. But since
            // _ssaoFilter.CombineWithSource is set to false, the SourceTexture is not
            // used and we can set it to anything except null.
            context.SourceTexture = aoRenderTarget;
            context.RenderTarget = aoRenderTarget;
            context.Viewport = new Viewport(0, 0, aoRenderTarget.Width, aoRenderTarget.Height);
            _ssaoFilter.Process(context);
            context.SourceTexture = null;
              }

              // The light buffer consists of two full-screen render targets into which we
              // render the accumulated diffuse and specular light intensities.
              var lightBufferFormat = new RenderTargetFormat(width, height, false, SurfaceFormat.HdrBlendable, DepthFormat.Depth24Stencil8);
              context.LightBuffer0 = renderTargetPool.Obtain2D(lightBufferFormat);
              context.LightBuffer1 = renderTargetPool.Obtain2D(lightBufferFormat);

              // Set the device render target to the light buffer.
              _renderTargetBindings[0] = new RenderTargetBinding(context.LightBuffer0); // Diffuse light accumulation
              _renderTargetBindings[1] = new RenderTargetBinding(context.LightBuffer1); // Specular light accumulation
              graphicsDevice.SetRenderTargets(_renderTargetBindings);
              context.RenderTarget = context.LightBuffer0;
              context.Viewport = graphicsDevice.Viewport;

              // Clear the light buffer. (The alpha channel is not used. We can set it to anything.)
              graphicsDevice.Clear(new Color(0, 0, 0, 255));

              // Restore the depth buffer (which XNA destroys in SetRenderTarget).
              // (This is only needed if lights can use a clip geometry (LightNode.Clip).)
              var rebuildZBufferRenderer = (RebuildZBufferRenderer)context.Data[RenderContextKeys.RebuildZBufferRenderer];
              rebuildZBufferRenderer.Render(context, true);

              // Render all lights into the light buffers.
              LightRenderer.Render(lights, context);

              if (aoRenderTarget != null)
              {
            // Render the ambient occlusion texture using multiplicative blending.
            // This will darken the light buffers depending on the ambient occlusion term.
            // Note: Theoretically, this should be done after the ambient light renderer
            // and before the directional light renderer because AO should not affect
            // directional lights. But doing this here has more impact.
            context.SourceTexture = aoRenderTarget;
            graphicsDevice.BlendState = GraphicsHelper.BlendStateMultiply;
            _copyFilter.Process(context);
              }

              // Clean up.
              graphicsService.RenderTargetPool.Recycle(aoRenderTarget);
              context.SourceTexture = null;
              context.RenderTarget = target;
              context.Viewport = viewport;

              _renderTargetBindings[0] = new RenderTargetBinding();
              _renderTargetBindings[1] = new RenderTargetBinding();
        }
Пример #17
0
        /// <inheritdoc/>
        public override void Render(IList<SceneNode> nodes, RenderContext context, RenderOrder order)
        {
            ThrowIfDisposed();

              if (nodes == null)
            throw new ArgumentNullException("nodes");
              if (context == null)
            throw new ArgumentNullException("context");

              int numberOfNodes = nodes.Count;
              if (nodes.Count == 0)
            return;

              context.Validate(_effect);

              var originalRenderTarget = context.RenderTarget;
              var originalViewport = context.Viewport;

              var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              //var renderTargetPool = graphicsService.RenderTargetPool;

              var savedRenderState = new RenderStateSnapshot(graphicsDevice);
              graphicsDevice.BlendState = BlendState.Opaque;
              graphicsDevice.RasterizerState = RasterizerState.CullNone;
              graphicsDevice.DepthStencilState = DepthStencilState.None;

              int frame = context.Frame;

              for (int nodeIndex = 0; nodeIndex < numberOfNodes; nodeIndex++)
              {
            var node = nodes[nodeIndex] as WaterNode;
            if (node == null)
              continue;

            var waves = node.Waves as OceanWaves;
            if (waves == null)
              continue;

            // We update the waves only once per frame.
            if (waves.LastFrame == frame)
              continue;

            waves.LastFrame = frame;

            float time = (float)context.Time.TotalSeconds;

            // Initialize h0 spectrum. Perform CPU FFT.
            waves.Update(graphicsDevice, time);

            int n = waves.TextureSize;

            // Allocate textures in the first frame and when the TextureSize was changed.
            if (waves.DisplacementSpectrum == null || waves.DisplacementSpectrum.Width != n)
            {
              waves.DisplacementSpectrum.SafeDispose();
              waves.NormalSpectrum.SafeDispose();
              waves.DisplacementMap.SafeDispose();
              waves.NormalMap.SafeDispose();

              waves.DisplacementSpectrum = new RenderTarget2D(_graphicsService.GraphicsDevice, n, n, false, SurfaceFormat.Vector4, DepthFormat.None);
              waves.NormalSpectrum = new RenderTarget2D(_graphicsService.GraphicsDevice, n, n, false, SurfaceFormat.Vector4, DepthFormat.None);
              waves.DisplacementMap = new RenderTarget2D(_graphicsService.GraphicsDevice, n, n, false, SurfaceFormat.Vector4, DepthFormat.None);
              waves.NormalMap = new RenderTarget2D(
            _graphicsService.GraphicsDevice,
            n,
            n,
            true,
            SurfaceFormat.Color,
            DepthFormat.None);
            }

            // Create spectrum (h, D, N) for current time from h0.
            _renderTargetBindings[0] = new RenderTargetBinding(waves.DisplacementSpectrum);
            _renderTargetBindings[1] = new RenderTargetBinding(waves.NormalSpectrum);
            graphicsDevice.SetRenderTargets(_renderTargetBindings);
            _parameterSize.SetValue((float)n);
            _parameterSpectrumParameters.SetValue(new Vector4(
              waves.TileSize,
              waves.Gravity,
              time,
              waves.HeightScale));
            _parameterSourceTexture.SetValue(waves.H0Spectrum);
            _passSpectrum.Apply();
            graphicsDevice.DrawFullScreenQuad();

            // Do inverse FFT.
            _fft.Process(
              context,
              false,
              waves.DisplacementSpectrum,
              waves.NormalSpectrum,
              (RenderTarget2D)waves.DisplacementMap,
              (RenderTarget2D)waves.NormalMap,
              waves.Choppiness);

            #region ----- Old Debugging Code -----

            // Create textures from CPU FFT data for debug visualization.
            //n = waves.CpuSize;
            //var s0Data = new Vector4[n * n];
            //var s1Data = new Vector4[n * n];
            //var s0 = new RenderTarget2D(_graphicsService.GraphicsDevice, n, n, false, SurfaceFormat.Vector4, DepthFormat.None);
            //var s1 = new RenderTarget2D(_graphicsService.GraphicsDevice, n, n, false, SurfaceFormat.Vector4, DepthFormat.None);
            //for (int y = 0; y < n; y++)
            //{
            //  for (int x = 0; x < n; x++)
            //  {
            //s0Data[y * n + x] = new Vector4(
            //  -waves._D[x, y].X * waves.Choppiness,
            //  waves._h[x, y].X * 1,
            //  -waves._D[x, y].Y * waves.Choppiness,
            //  1);

            //s1Data[y * n + x] = new Vector4(
            //  waves._N[x, y].X,
            //  waves._N[x, y].Y,
            //  0,
            //  0);
            //  }
            //}
            //s0.SetData(s0Data);
            //s1.SetData(s1Data);
            //WaterSample._t0 = s0;
            //WaterSample._t1 = waves.DisplacementMap;
            #endregion
              }

              savedRenderState.Restore();
              graphicsDevice.SetRenderTarget(null);
              context.RenderTarget = originalRenderTarget;
              context.Viewport = originalViewport;

              _renderTargetBindings[0] = default(RenderTargetBinding);
              _renderTargetBindings[1] = default(RenderTargetBinding);

              // Reset the texture stages. If a floating point texture is set, we get exceptions
              // when a sampler with bilinear filtering is set.
            #if !MONOGAME
              graphicsDevice.ResetTextures();
            #endif
        }
Пример #18
0
 double IRenderTarget.GetFramebufferTarget(RenderTargetBinding renderTargetBinding)
 {
     return(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTargetBinding.ArraySlice);
 }
Пример #19
0
        private void BlitInternal(
            IRenderContext renderContext,
            Texture2D source,
            RenderTarget2D[] destinations = null, 
            IEffect shader = null,
            IEffectParameterSet effectParameterSet = null,
            BlendState blendState = null,
            Vector2? offset = null,
            Vector2? size = null)
        {
            float destWidth, destHeight;
            if (destinations != null)
            {
                var destinationsBound = new RenderTargetBinding[destinations.Length];
                for (var i = 0; i < destinations.Length; i++)
                {
                    // Implicit cast.
                    destinationsBound[i] = destinations[i];
                }

                renderContext.PushRenderTarget(destinationsBound);
                destWidth = destinations[0].Width;
                destHeight = destinations[0].Height;
            }
            else
            {
                // TODO: renderContext.GraphicsDevice.GetRenderTargets();
                destWidth = renderContext.GraphicsDevice.PresentationParameters.BackBufferWidth;
                destHeight = renderContext.GraphicsDevice.PresentationParameters.BackBufferHeight;
            }

            offset = offset ?? new Vector2(0, 0);
            size = size ?? new Vector2(1 - offset.Value.X, 1 - offset.Value.Y);

            if (blendState == null)
            {
                blendState = BlendState.Opaque;
            }

            if (shader == null)
            {
                shader = _blitEffect;
            }

            if (effectParameterSet == null)
            {
                effectParameterSet = shader.CreateParameterSet();
            }

            if (_vertexBuffer == null)
            {
                _vertexBuffer = new VertexBuffer(renderContext.GraphicsDevice, typeof (VertexPositionNormalTexture),
                    _vertexes.Length, BufferUsage.WriteOnly);
                _vertexBuffer.SetData(_vertexes);
            }

            if (_indexBuffer == null)
            {
                _indexBuffer = new IndexBuffer(renderContext.GraphicsDevice, typeof (short), _indicies.Length,
                    BufferUsage.WriteOnly);
                _indexBuffer.SetData(_indicies);
            }

            var oldWorld = renderContext.World;
            var oldProjection = renderContext.Projection;
            var oldView = renderContext.View;

            renderContext.GraphicsDevice.BlendState = blendState;
            renderContext.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            renderContext.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
            renderContext.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

            renderContext.World = Matrix.CreateScale(destWidth, destHeight, 1);
            renderContext.Projection =
#if !PLATFORM_WINDOWS
                Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
#endif
                Matrix.CreateOrthographicOffCenter(
                    destWidth * (-offset.Value.X / size.Value.X),
                    destWidth * (-offset.Value.X / size.Value.X) + destWidth / size.Value.X, 
                    destHeight * (-offset.Value.Y / size.Value.Y) + destHeight / size.Value.Y,
                    destHeight * (-offset.Value.Y / size.Value.Y),
                    0,
                    1);
            renderContext.View = Matrix.Identity;

            if (source != null && effectParameterSet != null)
            {
                var semantic = effectParameterSet.GetSemantic<ITextureEffectSemantic>();
                if (semantic.Texture != source)
                {
                    semantic.Texture = source;
                }
            }

            renderContext.GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            renderContext.GraphicsDevice.Indices = _indexBuffer;
            
            shader.LoadParameterSet(renderContext, effectParameterSet);
            foreach (var pass in shader.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                renderContext.GraphicsDevice.DrawIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    0,
                    0,
                    2);
            }

            renderContext.World = oldWorld;
            renderContext.Projection = oldProjection;
            renderContext.View = oldView;

            if (destinations != null)
            {
                renderContext.PopRenderTarget();
            }
        }
Пример #20
0
        protected override void SetupRenderTargets()
        {
            base.SetupRenderTargets();

            // Create GBuffer Render Target binding
            m_GBuffer = new RenderTargetBinding[4];

            // Rebuild the render targets
            m_ColorTarget = new RenderTarget2D(GraphicsDevice, (int)m_ScreenSize.X, (int)m_ScreenSize.Y, true, SurfaceFormat.Color, DepthFormat.Depth24);
            m_NormalTarget = new RenderTarget2D(GraphicsDevice, (int)m_ScreenSize.X, (int)m_ScreenSize.Y, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
            m_DepthTarget = new RenderTarget2D(GraphicsDevice, (int)m_ScreenSize.X, (int)m_ScreenSize.Y, false, SurfaceFormat.Single, DepthFormat.Depth24Stencil8);
            m_SecondaryDepthTarget = new RenderTarget2D(GraphicsDevice, (int)m_ScreenSize.X, (int)m_ScreenSize.Y, false, SurfaceFormat.HalfVector2, DepthFormat.Depth24Stencil8);
            m_LightTarget = new RenderTarget2D(GraphicsDevice, (int)m_ScreenSize.X, (int)m_ScreenSize.Y, true, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);

            // Add render target bindings
            m_GBuffer[0] = new RenderTargetBinding(m_ColorTarget);
            m_GBuffer[1] = new RenderTargetBinding(m_NormalTarget);
            m_GBuffer[2] = new RenderTargetBinding(m_DepthTarget);
            m_GBuffer[3] = new RenderTargetBinding(m_SecondaryDepthTarget);
        }
Пример #21
0
        public void Render(IList<SceneNode> sceneNodes, IList<SceneNode> decalNodes, RenderContext context)
        {
            var graphicsService = context.GraphicsService;
              var graphicsDevice = graphicsService.GraphicsDevice;
              var renderTargetPool = graphicsService.RenderTargetPool;
              var target = context.RenderTarget;
              var viewport = context.Viewport;

              // The G-buffer consists of two full-screen render targets into which we render
              // depth values, normal vectors and other information.
              var width = context.Viewport.Width;
              var height = context.Viewport.Height;
              context.GBuffer0 = renderTargetPool.Obtain2D(new RenderTargetFormat(
            width,
            height,
            #if !XBOX
            true,        // Note: Only the SaoFilter for SSAO requires mipmaps to boost performance.
            #endif
            SurfaceFormat.Single,
            DepthFormat.Depth24Stencil8));
              context.GBuffer1 = renderTargetPool.Obtain2D(new RenderTargetFormat(width, height, false, SurfaceFormat.Color, DepthFormat.None));

              // Set the device render target to the G-buffer.
              _renderTargetBindings[0] = new RenderTargetBinding(context.GBuffer0);
              _renderTargetBindings[1] = new RenderTargetBinding(context.GBuffer1);
              graphicsDevice.SetRenderTargets(_renderTargetBindings);
              context.RenderTarget = context.GBuffer0;

              graphicsDevice.DepthStencilState = DepthStencilState.None;
              graphicsDevice.RasterizerState = RasterizerState.CullNone;
              graphicsDevice.BlendState = BlendState.Opaque;

              // Clear the z-buffer.
              graphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil, Color.Black, 1, 0);

              // Initialize the G-buffer with default values.
              _clearGBufferRenderer.Render(context);

              // Render the scene nodes using the "GBuffer" material pass.
              context.RenderPass = "******";
              graphicsDevice.DepthStencilState = DepthStencilState.Default;
              graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
              graphicsDevice.BlendState = BlendState.Opaque;
              _sceneNodeRenderer.Render(sceneNodes, context);

              if (_decalRenderer != null && decalNodes.Count > 0)
              {
            // Render decal nodes using the "GBuffer" material pass.
            // Decals are rendered as "deferred decals". The geometry information is
            // read from GBuffer0 and the decal normals are blended with GBuffer1, which
            // has to be set as the first render target. (That means a new GBuffer1 is
            // created. The original GBuffer1 is recycled afterwards.)
            var renderTarget = renderTargetPool.Obtain2D(new RenderTargetFormat(width, height, false, SurfaceFormat.Color, DepthFormat.None));
            graphicsDevice.SetRenderTarget(renderTarget);
            context.RenderTarget = renderTarget;

            // Copy GBuffer1 to current render target and restore the depth buffer.
            var rebuildZBufferRenderer = (RebuildZBufferRenderer)context.Data[RenderContextKeys.RebuildZBufferRenderer];
            rebuildZBufferRenderer.Render(context, context.GBuffer1);

            // Blend decals with the render target.
            _decalRenderer.Render(decalNodes, context);

            // The new render target replaces the GBuffer1.
            renderTargetPool.Recycle(context.GBuffer1);
            context.GBuffer1 = renderTarget;
              }
              context.RenderPass = null;

              // The depth buffer is downsampled into a buffer of half width and half height.
              RenderTarget2D depthBufferHalf = renderTargetPool.Obtain2D(new RenderTargetFormat(width / 2, height / 2, false, context.GBuffer0.Format, DepthFormat.None));
              context.SourceTexture = context.GBuffer0;
              context.RenderTarget = depthBufferHalf;
              context.Viewport = new Viewport(0, 0, depthBufferHalf.Width, depthBufferHalf.Height);
              _downsampleFilter.Process(context);
              context.SourceTexture = null;

              // Store the result in the render context. Depending on the settings, the downsampled
              // depth buffer is used by the SsaoFilter (if SsaoFilter.DownsampleFactor == 2), or
              // by the BillboardRenderer (if EnableOffscreenRendering is set).
              context.Data[RenderContextKeys.DepthBufferHalf] = depthBufferHalf;

              context.RenderTarget = target;
              context.Viewport = viewport;
              _renderTargetBindings[0] = new RenderTargetBinding();
              _renderTargetBindings[1] = new RenderTargetBinding();
        }
Пример #22
0
        public VideoPlayer()
        {
            // Initialize public members.
            IsDisposed = false;
            IsLooped = false;
            IsMuted = false;
            State = MediaState.Stopped;
            Volume = 1.0f;

            // Initialize private members.
            timer = new Stopwatch();

            // The VideoPlayer will use the GraphicsDevice that is set now.
            currentDevice = Game.Instance.GraphicsDevice;

            // Initialize this here to prevent null GetTexture returns.
            videoTexture = new RenderTargetBinding[1];
            videoTexture[0] = new RenderTargetBinding(
                new RenderTarget2D(
                    currentDevice,
                    1280,
                    720,
                    false,
                    SurfaceFormat.Color,
                    DepthFormat.None,
                    0,
                    RenderTargetUsage.PreserveContents
                )
            );

            // Initialize the other GL bits.
            GL_initialize();
        }
 double IRenderTarget.GetFramebufferTarget(RenderTargetBinding renderTargetBinding)
 {
     return(glTarget);
 }
Пример #24
0
		public void ResolveTarget(RenderTargetBinding target)
		{
			if ((target.RenderTarget as IRenderTarget).MultiSampleCount > 0)
			{
				uint prevBuffer = currentDrawFramebuffer;

				// Set up the texture framebuffer
				GLenum textureTarget;
				int width, height;
				if (target.RenderTarget is RenderTarget2D)
				{
					textureTarget = GLenum.GL_TEXTURE_2D;
					Texture2D target2D = (target.RenderTarget as Texture2D);
					width = target2D.Width;
					height = target2D.Height;
				}
				else
				{
					textureTarget = GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) target.CubeMapFace;
					TextureCube targetCube = (target.RenderTarget as TextureCube);
					width = targetCube.Size;
					height = targetCube.Size;
				}
				BindFramebuffer(resolveFramebufferDraw);
				glFramebufferTexture2D(
					GLenum.GL_FRAMEBUFFER,
					GLenum.GL_COLOR_ATTACHMENT0,
					textureTarget,
					(target.RenderTarget.texture as OpenGLTexture).Handle,
					0
				);

				// Set up the renderbuffer framebuffer
				BindFramebuffer(resolveFramebufferRead);
				glFramebufferRenderbuffer(
					GLenum.GL_FRAMEBUFFER,
					GLenum.GL_COLOR_ATTACHMENT0,
					GLenum.GL_RENDERBUFFER,
					((target.RenderTarget as IRenderTarget).ColorBuffer as OpenGLRenderbuffer).Handle
				);

				// Blit!
				if (scissorTestEnable)
				{
					glDisable(GLenum.GL_SCISSOR_TEST);
				}
				BindDrawFramebuffer(resolveFramebufferDraw);
				glBlitFramebuffer(
					0, 0, width, height,
					0, 0, width, height,
					GLenum.GL_COLOR_BUFFER_BIT,
					GLenum.GL_LINEAR
				);
				if (scissorTestEnable)
				{
					glEnable(GLenum.GL_SCISSOR_TEST);
				}

				BindFramebuffer(prevBuffer);
			}

			// If the target has mipmaps, regenerate them now
			if (target.RenderTarget.LevelCount > 1)
			{
				OpenGLTexture prevTex = Textures[0];
				BindTexture(target.RenderTarget.texture);
				glGenerateMipmap((target.RenderTarget.texture as OpenGLTexture).Target);
				BindTexture(prevTex);
			}
		}
        /// <summary>
        /// Helper function for loading deferred render targets.
        /// </summary>
        private void LoadRenderTargets()
        {
            deferredTargets = new RenderTargetBinding[nRenderTargets];

            // Albedo + Emissive
            deferredTargets[0] = new RenderTargetBinding(
                new RenderTarget2D(
                    Device,
                    Device.PresentationParameters.BackBufferWidth,
                    Device.PresentationParameters.BackBufferHeight,
                    false,
                    SurfaceFormat.Rgba1010102,
                    DepthFormat.Depth24));
            // Depth
            deferredTargets[1] = new RenderTargetBinding(
                new RenderTarget2D(
                    Device,
                    Device.PresentationParameters.BackBufferWidth,
                    Device.PresentationParameters.BackBufferHeight,
                    false,
                    SurfaceFormat.Single,
                    DepthFormat.Depth24));
            // Normal
            deferredTargets[2] = new RenderTargetBinding(
                new RenderTarget2D(
                    Device,
                    Device.PresentationParameters.BackBufferWidth,
                    Device.PresentationParameters.BackBufferHeight,
                    false,
                    SurfaceFormat.HalfVector2,
                    DepthFormat.Depth24));

            // Shadow/light map
            lightMap = new RenderTarget2D(Device, 1024, 1024, false, SurfaceFormat.Alpha8, DepthFormat.Depth24);

            // Light accumulation buffer (stage before post-process
            lightAccumulationBuffer = new RenderTarget2D(
                Device,
                Device.PresentationParameters.BackBufferWidth,
                Device.PresentationParameters.BackBufferHeight,
                false,
                SurfaceFormat.Rgba1010102,
                DepthFormat.None,
                0,
                RenderTargetUsage.PreserveContents);

            bloomAccumulationBuffer = new RenderTarget2D(
                Device,
                Device.PresentationParameters.BackBufferWidth / 4,
                Device.PresentationParameters.BackBufferHeight / 4,
                false,
                SurfaceFormat.Rgba1010102,
                DepthFormat.None,
                0,
                RenderTargetUsage.PreserveContents);

            bloomDownSampleBuffers = new RenderTarget2D[3];
            float downSampleAmount = 4;
            for (int i = 0; i < 3; i++)
            {
                bloomDownSampleBuffers[i] = new RenderTarget2D(
                    Device,
                    (int)(Device.PresentationParameters.BackBufferWidth / downSampleAmount),
                    (int)(Device.PresentationParameters.BackBufferHeight / downSampleAmount),
                    false,
                    SurfaceFormat.Rgba1010102,
                    DepthFormat.None,
                    0,
                    RenderTargetUsage.PreserveContents);
                downSampleAmount *= 4;
            }
        }
Пример #26
0
 /// <summary>
 /// it is recommended to use GetRenderTargets() to avoid the extra Array.Copy when using FNA
 /// </summary>
 /// <returns>The render targets.</returns>
 /// <param name="self">Self.</param>
 /// <param name="outTargets">Out targets.</param>
 public static void GetRenderTargets( this GraphicsDevice self, RenderTargetBinding[] outTargets )
 {
     var currentRenderTargets = self.GetRenderTargets();
     System.Diagnostics.Debug.Assert( outTargets.Length == currentRenderTargets.Length, "Invalid outTargets array length!" );
     Array.Copy( currentRenderTargets, outTargets, currentRenderTargets.Length );
 }
Пример #27
0
		public void Play(Video video)
		{
			checkDisposed();

			// We need to assign this regardless of what happens next.
			Video = video;
			video.AttachedToPlayer = true;

			// FIXME: This is a part of the Duration hack!
			Video.Duration = TimeSpan.MaxValue;

			// Check the player state before attempting anything.
			if (State != MediaState.Stopped)
			{
				return;
			}

			// Update the player state now, for the thread we're about to make.
			State = MediaState.Playing;

			// Start the video if it hasn't been yet.
			if (Video.IsDisposed)
			{
				video.Initialize();
			}

			// Grab the first bit of audio. We're trying to start the decoding ASAP.
			if (TheoraPlay.THEORAPLAY_hasAudioStream(Video.theoraDecoder) != 0)
			{
				InitAudioStream();
			}

			// Grab the first bit of video, set up the texture.
			if (TheoraPlay.THEORAPLAY_hasVideoStream(Video.theoraDecoder) != 0)
			{
				currentVideo = TheoraPlay.getVideoFrame(Video.videoStream);
				previousFrame = Video.videoStream;
				do
				{
					// The decoder miiight not be ready yet.
					Video.videoStream = TheoraPlay.THEORAPLAY_getVideo(Video.theoraDecoder);
				} while (Video.videoStream == IntPtr.Zero);
				nextVideo = TheoraPlay.getVideoFrame(Video.videoStream);

				// The VideoPlayer will use the GraphicsDevice that is set now.
				if (currentDevice != Video.GraphicsDevice)
				{
					if (currentDevice != null)
					{
						GL_dispose();
					}
					currentDevice = Video.GraphicsDevice;
					GL_initialize();
				}

				RenderTargetBinding overlap = videoTexture[0];
				videoTexture[0] = new RenderTargetBinding(
					new RenderTarget2D(
						currentDevice,
						(int) currentVideo.width,
						(int) currentVideo.height,
						false,
						SurfaceFormat.Color,
						DepthFormat.None,
						0,
						RenderTargetUsage.PreserveContents
					)
				);
				if (overlap.RenderTarget != null)
				{
					overlap.RenderTarget.Dispose();
				}
				GL_setupTextures(
					(int) currentVideo.width,
					(int) currentVideo.height
				);
			}

			// Initialize the thread!
			FNAPlatform.Log("Starting Theora player...");
			timer.Start();
			if (audioStream != null)
			{
				audioStream.Play();
			}
			FNAPlatform.Log("Started!");
		}
Пример #28
0
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, screenWidth / screenHeight, 1.0f, 100.0f);

            renderTargetBindings = new RenderTargetBinding[3];
            renderTargetBindings[0] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, screenWidth, screenHeight, false, SurfaceFormat.Color, DepthFormat.Depth16));//Color
            renderTargetBindings[1] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, screenWidth, screenHeight, false, SurfaceFormat.Color, DepthFormat.Depth16));//Normal
            renderTargetBindings[2] = new RenderTargetBinding(new RenderTarget2D(GraphicsDevice, screenWidth, screenHeight, false, SurfaceFormat.Single, DepthFormat.Depth16));//Depth

            cubeMesh = Mesh.CreateCubeMesh(0.4f);
            bricks = Content.Load<Texture2D>("brickwork-texture");
            bricksNormal = Content.Load<Texture2D>("brickwork_normal-map");

            clearBufferEffect = Content.Load<Effect>("ClearGBuffer");

            deferredRenderEffect = Content.Load<Effect>("DeferredRenderEffect");
            deferredRenderEffect.Parameters["DiffuseTexture"].SetValue(bricks);
            deferredRenderEffect.Parameters["World"].SetValue(Matrix.Identity);
            deferredRenderEffect.Parameters["Projection"].SetValue(projectionMatrix);

            directionalLightEffect = Content.Load<Effect>("DirectionalLightEffect");
            directionalLightEffect.Parameters["DiffuseMap"].SetValue(renderTargetBindings[0].RenderTarget);
            directionalLightEffect.Parameters["NormalMap"].SetValue(renderTargetBindings[1].RenderTarget);
            directionalLightEffect.Parameters["DepthMap"].SetValue(renderTargetBindings[2].RenderTarget);
            directionalLightEffect.Parameters["lightDirection"].SetValue(-Vector3.UnitY);
            directionalLightEffect.Parameters["Color"].SetValue(Color.BlueViolet.ToVector3());
            directionalLightEffect.Parameters["halfPixel"].SetValue(new Vector2(0.5f / screenWidth, 0.5f / screenHeight));

            quadRenderer = new QuadRenderComponent(this);

            //ship = Content.Load<Model>("Models/ship1");
            //volleyBall = Content.Load<Model>("volleyBall");
            //e = new BasicEffect(GraphicsDevice);
        }
Пример #29
0
		public void SetRenderTargets(
			RenderTargetBinding[] renderTargets,
			IGLRenderbuffer renderbuffer,
			DepthFormat depthFormat
		) {
			// Bind the right framebuffer, if needed
			if (renderTargets == null)
			{
				BindFramebuffer(
					(Backbuffer is OpenGLBackbuffer) ?
						(Backbuffer as OpenGLBackbuffer).Handle :
						0
				);
				flipViewport = 1;
				return;
			}
			else
			{
				BindFramebuffer(targetFramebuffer);
				flipViewport = -1;
			}

			int i;
			uint[] attachments = new uint[renderTargets.Length];
			GLenum[] attachmentTypes = new GLenum[renderTargets.Length];
			for (i = 0; i < renderTargets.Length; i += 1)
			{
				IGLRenderbuffer colorBuffer = (renderTargets[i].RenderTarget as IRenderTarget).ColorBuffer;
				if (colorBuffer != null)
				{
					attachments[i] = (colorBuffer as OpenGLRenderbuffer).Handle;
					attachmentTypes[i] = GLenum.GL_RENDERBUFFER;
				}
				else
				{
					attachments[i] = (renderTargets[i].RenderTarget.texture as OpenGLTexture).Handle;
					if (renderTargets[i].RenderTarget is RenderTarget2D)
					{
						attachmentTypes[i] = GLenum.GL_TEXTURE_2D;
					}
					else
					{
						attachmentTypes[i] = GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) renderTargets[i].CubeMapFace;
					}
				}
			}

			// Update the color attachments, DrawBuffers state
			for (i = 0; i < attachments.Length; i += 1)
			{
				if (attachments[i] != currentAttachments[i])
				{
					if (currentAttachments[i] != 0)
					{
						if (	attachmentTypes[i] != GLenum.GL_RENDERBUFFER &&
							currentAttachmentTypes[i] == GLenum.GL_RENDERBUFFER	)
						{
							glFramebufferRenderbuffer(
								GLenum.GL_FRAMEBUFFER,
								GLenum.GL_COLOR_ATTACHMENT0 + i,
								GLenum.GL_RENDERBUFFER,
								0
							);
						}
						else if (	attachmentTypes[i] == GLenum.GL_RENDERBUFFER &&
								currentAttachmentTypes[i] != GLenum.GL_RENDERBUFFER	)
						{
							glFramebufferTexture2D(
								GLenum.GL_FRAMEBUFFER,
								GLenum.GL_COLOR_ATTACHMENT0 + i,
								currentAttachmentTypes[i],
								0,
								0
							);
						}
					}
					if (attachmentTypes[i] == GLenum.GL_RENDERBUFFER)
					{
						glFramebufferRenderbuffer(
							GLenum.GL_FRAMEBUFFER,
							GLenum.GL_COLOR_ATTACHMENT0 + i,
							GLenum.GL_RENDERBUFFER,
							attachments[i]
						);
					}
					else
					{
						glFramebufferTexture2D(
							GLenum.GL_FRAMEBUFFER,
							GLenum.GL_COLOR_ATTACHMENT0 + i,
							attachmentTypes[i],
							attachments[i],
							0
						);
					}
					currentAttachments[i] = attachments[i];
					currentAttachmentTypes[i] = attachmentTypes[i];
				}
				else if (attachmentTypes[i] != currentAttachmentTypes[i])
				{
					// Texture cube face change!
					glFramebufferTexture2D(
						GLenum.GL_FRAMEBUFFER,
						GLenum.GL_COLOR_ATTACHMENT0 + i,
						attachmentTypes[i],
						attachments[i],
						0
					);
					currentAttachmentTypes[i] = attachmentTypes[i];
				}
			}
			while (i < currentAttachments.Length)
			{
				if (currentAttachments[i] != 0)
				{
					if (currentAttachmentTypes[i] == GLenum.GL_RENDERBUFFER)
					{
						glFramebufferRenderbuffer(
							GLenum.GL_FRAMEBUFFER,
							GLenum.GL_COLOR_ATTACHMENT0 + i,
							GLenum.GL_RENDERBUFFER,
							0
						);
					}
					else
					{
						glFramebufferTexture2D(
							GLenum.GL_FRAMEBUFFER,
							GLenum.GL_COLOR_ATTACHMENT0 + i,
							currentAttachmentTypes[i],
							0,
							0
						);
					}
					currentAttachments[i] = 0;
					currentAttachmentTypes[i] = GLenum.GL_TEXTURE_2D;
				}
				i += 1;
			}
			if (attachments.Length != currentDrawBuffers)
			{
				glDrawBuffers(attachments.Length, drawBuffersArray);
				currentDrawBuffers = attachments.Length;
			}

			// Update the depth/stencil attachment
			/* FIXME: Notice that we do separate attach calls for the stencil.
			 * We _should_ be able to do a single attach for depthstencil, but
			 * some drivers (like Mesa) cannot into GL_DEPTH_STENCIL_ATTACHMENT.
			 * Use XNAToGL.DepthStencilAttachment when this isn't a problem.
			 * -flibit
			 */
			uint handle;
			if (renderbuffer == null)
			{
				handle = 0;
			}
			else
			{
				handle = (renderbuffer as OpenGLRenderbuffer).Handle;
			}
			if (handle != currentRenderbuffer)
			{
				if (currentDepthStencilFormat == DepthFormat.Depth24Stencil8)
				{
					glFramebufferRenderbuffer(
						GLenum.GL_FRAMEBUFFER,
						GLenum.GL_STENCIL_ATTACHMENT,
						GLenum.GL_RENDERBUFFER,
						0
					);
				}
				currentDepthStencilFormat = depthFormat;
				glFramebufferRenderbuffer(
					GLenum.GL_FRAMEBUFFER,
					GLenum.GL_DEPTH_ATTACHMENT,
					GLenum.GL_RENDERBUFFER,
					handle
				);
				if (currentDepthStencilFormat == DepthFormat.Depth24Stencil8)
				{
					glFramebufferRenderbuffer(
						GLenum.GL_FRAMEBUFFER,
						GLenum.GL_STENCIL_ATTACHMENT,
						GLenum.GL_RENDERBUFFER,
						handle
					);
				}
				currentRenderbuffer = handle;
			}
		}
Пример #30
0
 private void ResetRenderTargets(RenderTargetBinding[] oldBindings)
 {
     // Restore the given Graphics Device's Render Target
     Game1.GetInstance().GraphicsDevice.SetRenderTargets(oldBindings);
 }
Пример #31
0
 TextureTarget IRenderTarget.GetFramebufferTarget(RenderTargetBinding renderTargetBinding)
 {
     return(glTarget);
 }
Пример #32
0
 /// <summary>
 /// Sets the render target for scaling.
 /// </summary>
 /// <param name="oldBindings">The old bindings that you need to reapply in the ResetRenderTargets function</param>
 /// <param name="newRenderTarget">The newly created render target on the Graphics Card</param>
 private void SetRenderTargets(out RenderTargetBinding[] oldBindings, out RenderTarget2D newRenderTarget)
 {
     oldBindings = Game1.GetInstance().GraphicsDevice.GetRenderTargets();
     Game1.GetInstance().GraphicsDevice.SetRenderTargets(null);
     // Get the Texture with the screen drawn on it
     // Create the Render Target to draw the scaled Texture to
     newRenderTarget =
         new RenderTarget2D(Game1.GetInstance().GraphicsDevice, (int)this.miniMapTileSize.X, (int)this.miniMapTileSize.Y);
     // Set the given Graphics Device to draw to the new Render Target
     Game1.GetInstance().GraphicsDevice.SetRenderTarget(newRenderTarget);
 }
Пример #33
0
 public void setRenderTargets(RenderTargetCollection collection)
 {
     RenderTargetBinding[] renderTargets = new RenderTargetBinding[collection.Targets.Length]; // collection.Targets.Length
     bool none = true;
     for (int i = 0; i < collection.Targets.Length; ++i)
     {
         if (collection.Targets[i] is RenderTarget2D)
         {
             renderTargets[i] = collection.Targets[i] as RenderTarget2D;
             none = false;
         }
     }
     if (none)
         GraphicsDevice.SetRenderTargets(null);
     else
         GraphicsDevice.SetRenderTargets(renderTargets);
 }
Пример #34
0
 public void bindShader(RenderTargetBinding[] binding)
 {
     mBinding = binding;
 }
Пример #35
0
        /// <summary>
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// </summary>
        /// <param name="loadAllContent">Which type of content to load.</param>
        protected override void LoadContent()
        {
            grid.LoadContent();

            //  EFFECTS
            gridEffect = Content.Load<Effect>("VTFDisplacement");
            WaterCalc = Content.Load<Effect>("WaterCalc");
            debugEffect = Content.Load<Effect>("DebugEffect");

            // CALC TEXTURES
            groundTexture= convertToVec4Texture(Content.Load<Texture2D>("Textures\\height3"));
            waterSourceTexture = convertToVec4Texture(Content.Load<Texture2D>("Textures\\water"));
            waterTexture= convertToVec4Texture(Content.Load<Texture2D>("Textures\\water"));
            fluxTexture = new Texture2D(graphics.GraphicsDevice, 512, 512, false, SurfaceFormat.Vector4);
            sedimentTexture = new Texture2D(graphics.GraphicsDevice, 512, 512, false, SurfaceFormat.Vector4);
            Vector4[] newData = new Vector4[fluxTexture.Width * fluxTexture.Height];
            for (int i = 0; i < fluxTexture.Width * fluxTexture.Height; i++)
                newData[i] = new Vector4(0, 0, 0, 0);
            fluxTexture.SetData<Vector4>(newData);
            sedimentTexture.SetData<Vector4>(newData);
            waterTexture.SetData<Vector4>(newData);

            // VISUAL TEXTURES
            sandTexture = Content.Load<Texture2D>("Textures\\sand");
            grassTexture = Content.Load<Texture2D>("Textures\\grass");
            rockTexture = Content.Load<Texture2D>("Textures\\rock");
            snowTexture = Content.Load<Texture2D>("Textures\\snow");

            debugTexture = Content.Load<Texture2D>("Textures\\sun");

            font = Content.Load<SpriteFont>("MyArial");

            PresentationParameters pp = graphics.GraphicsDevice.PresentationParameters;

            water_rt = new RenderTarget2D[2];
            water_rt[0] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            water_rt[1] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            ground_rt = new RenderTarget2D[2];
            ground_rt[0] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            ground_rt[1] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            water_flux_rt = new RenderTarget2D[2];
            water_flux_rt[0] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            water_flux_rt[1] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            sediment_rt = new RenderTarget2D[2];
            sediment_rt[0] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            sediment_rt[1] = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            added_water_rt = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            velocity_rt = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            debug_rt = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            debug_rt2 = new RenderTarget2D(graphics.GraphicsDevice, 512, 512,
                false, SurfaceFormat.Vector4, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            rtb = new RenderTargetBinding[2][];
            for (int i = 0; i < 2; i++)
            {
                rtb[i] = new RenderTargetBinding[2]
                {
                    new RenderTargetBinding(water_rt[1 - i]),
                    new RenderTargetBinding(velocity_rt),
                };
            }
        }
Пример #36
0
    private void RenderGBuffer(CameraFrustumQuery frustumQuery, RenderContext context)
    {
      // Create render targets for the G-buffer.
      context.GBuffer0 = GraphicsService.RenderTargetPool.Obtain2D(
        new RenderTargetFormat(
          context.Viewport.Width,
          context.Viewport.Height,
          true,        // Note: Only the SaoFilter for SSAO requires mipmaps to boost performance.
          SurfaceFormat.Single,
          DepthFormat.Depth24Stencil8));
      context.GBuffer1 = GraphicsService.RenderTargetPool.Obtain2D(
        new RenderTargetFormat(
          context.Viewport.Width,
          context.Viewport.Height,
          false,
          SurfaceFormat.Color,
          DepthFormat.None));

      var graphicsDevice = GraphicsService.GraphicsDevice;

      _renderTargetBindings[0] = new RenderTargetBinding(context.GBuffer0);
      _renderTargetBindings[1] = new RenderTargetBinding(context.GBuffer1);
      graphicsDevice.SetRenderTargets(_renderTargetBindings);

      // Update the info in the render context. Some renderers or effects might use this info.
      context.RenderTarget = context.GBuffer0;
      context.Viewport = graphicsDevice.Viewport;

      // Clear the depth-stencil buffer.
      graphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil, Color.Black, 1, 0);

      // Reset the G-buffer to default values.
      _clearGBufferRenderer.Render(context);

      // Render the meshes using the "GBuffer" material pass.
      graphicsDevice.DepthStencilState = DepthStencilState.Default;
      graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
      graphicsDevice.BlendState = BlendState.Opaque;
      context.RenderPass = "******";
      _meshRenderer.Render(frustumQuery.SceneNodes, context);
      context.RenderPass = null;
    }
Пример #37
0
    private void RenderWeightedBlendedOIT(WeightedBlendedOITQuery query, RenderContext context)
    {
      var graphicsDevice = GraphicsService.GraphicsDevice;

      var target = context.RenderTarget;
      var viewport = context.Viewport;

      // ----- Transparent pass
      // Set up WBOIT render targets.
      var renderTargetPool = GraphicsService.RenderTargetPool;
      var renderTargetA = renderTargetPool.Obtain2D(
        new RenderTargetFormat(
          context.Viewport.Width,
          context.Viewport.Height,
          false,
          SurfaceFormat.HdrBlendable,
          DepthFormat.Depth24Stencil8));
      var renderTargetB = renderTargetPool.Obtain2D(
        new RenderTargetFormat(
          context.Viewport.Width,
          context.Viewport.Height,
          false,
#if MONOGAME
          SurfaceFormat.HalfSingle,
#else
          SurfaceFormat.HdrBlendable,
#endif
          DepthFormat.None));

      _renderTargetBindings[0] = new RenderTargetBinding(renderTargetA);
      _renderTargetBindings[1] = new RenderTargetBinding(renderTargetB);
      graphicsDevice.SetRenderTargets(_renderTargetBindings);

      context.RenderTarget = renderTargetA;
      context.Viewport = graphicsDevice.Viewport;

      // Clear render targets to (0, 0, 0, 1).
      graphicsDevice.Clear(Color.Black);

      // Make a Z-only pass to render opaque objects in to the depth buffer.
      // (Color output is disabled.)
      graphicsDevice.DepthStencilState = DepthStencilState.Default;
      graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
      graphicsDevice.BlendState = GraphicsHelper.BlendStateNoColorWrite;
      context.RenderPass = "******";
      _meshRenderer.Render(query.SceneNodes, context, RenderOrder.Default);
      context.RenderPass = null;

      // Render transparent objects into the WBOIT render targets.
      graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
      graphicsDevice.RasterizerState = RasterizerState.CullNone;
      graphicsDevice.BlendState = _wboitRenderBlendState;
      context.RenderPass = "******";
      _meshRenderer.Render(query.TransparentNodes, context, RenderOrder.Default);
      context.RenderPass = null;

      _renderTargetBindings[0] = default(RenderTargetBinding);
      _renderTargetBindings[1] = default(RenderTargetBinding);

      // ----- Opaque pass
      // Switch back to original render target.
      graphicsDevice.SetRenderTarget(target);
      context.RenderTarget = target;
      context.Viewport = viewport;

      graphicsDevice.Clear(Color.CornflowerBlue);

      // Render opaque objects.
      graphicsDevice.DepthStencilState = DepthStencilState.Default;
      graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
      graphicsDevice.BlendState = BlendState.Opaque;
      context.RenderPass = "******";
      _meshRenderer.Render(query.SceneNodes, context, RenderOrder.Default);
      context.RenderPass = null;

      // ----- Combine pass
      // Combine the WBOIT render targets with the scene.
      graphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
      graphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
      graphicsDevice.DepthStencilState = DepthStencilState.None;
      graphicsDevice.RasterizerState = RasterizerState.CullNone;
      graphicsDevice.BlendState = _wboitCombineBlendState;
      _parameterViewportSize.SetValue(new Vector2(graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height));
      _parameterTextureA.SetValue(renderTargetA);
      _parameterTextureB.SetValue(renderTargetB);
      _wboitEffect.CurrentTechnique.Passes[0].Apply();
      graphicsDevice.DrawFullScreenQuad();
      _parameterTextureA.SetValue((Texture2D)null);
      _parameterTextureB.SetValue((Texture2D)null);

      renderTargetPool.Recycle(renderTargetA);
      renderTargetPool.Recycle(renderTargetB);
    }
Пример #38
0
        void calculateWater(float dt)
        {
            //Debug.WriteLine(String.Format("{0:0.000}", dt));

            using (SpriteBatch sprite = new SpriteBatch(graphics.GraphicsDevice))
            {
                SamplerState ss = new SamplerState();
                ss.Filter = TextureFilter.Point;
                ss.AddressU = TextureAddressMode.Mirror;
                ss.AddressV = TextureAddressMode.Mirror;

                WaterCalc.Parameters["time"].SetValue(dt);
                graphics.GraphicsDevice.Textures[1] = (waterSourceTexture);
                graphics.GraphicsDevice.Textures[2] = groundTexture;
                graphics.GraphicsDevice.Textures[3] = fluxTexture;

                graphics.GraphicsDevice.SamplerStates[1] = ss;
                graphics.GraphicsDevice.SamplerStates[2] = ss;
                graphics.GraphicsDevice.SamplerStates[3] = ss;
                graphics.GraphicsDevice.SamplerStates[4] = ss;
                graphics.GraphicsDevice.SamplerStates[5] = ss;

                // PASS 1 - WATER ADD
                WaterCalc.CurrentTechnique = WaterCalc.Techniques["WaterAddCalc"];
                graphics.GraphicsDevice.SetRenderTarget(added_water_rt);

                sprite.Begin(0, BlendState.Opaque, ss, null, null, WaterCalc);
                sprite.Draw(waterTexture, new Rectangle(0, 0, added_water_rt.Width, added_water_rt.Height), Color.White);
                sprite.End();

                waterTexture = (Texture2D)added_water_rt;

                // PASS 2 - FLUX

                RenderTargetBinding[] rtb_flux = new RenderTargetBinding[2]
                {
                       new RenderTargetBinding(water_flux_rt[act_water_rt]),
                       new RenderTargetBinding(debug_rt2)
                };

                WaterCalc.CurrentTechnique = WaterCalc.Techniques["FluxCalculation"];
                graphics.GraphicsDevice.SetRenderTargets(rtb_flux);

                sprite.Begin(0, BlendState.Opaque, ss, null, null, WaterCalc);
                sprite.Draw(waterTexture, new Rectangle(0, 0, water_flux_rt[act_water_rt].Width, water_flux_rt[act_water_rt].Height), Color.White);
                sprite.End();

                fluxTexture = (Texture2D)water_flux_rt[act_water_rt];
                graphics.GraphicsDevice.SetRenderTarget(null);
                graphics.GraphicsDevice.Textures[3] = fluxTexture;

                // PASS 3 WATER + VELOCITY
                WaterCalc.CurrentTechnique = WaterCalc.Techniques["WaterCalculation"];

                //graphics.GraphicsDevice.SetRenderTarget(water_rt[1 - act_water_rt]);
                graphics.GraphicsDevice.SetRenderTargets(rtb[act_water_rt]);
                graphics.GraphicsDevice.Clear(new Color(0, 0, 0, 0));
                sprite.Begin(0, BlendState.Opaque, ss, null, null, WaterCalc);
                sprite.Draw(added_water_rt, new Rectangle(0, 0, water_rt[act_water_rt].Width, water_rt[act_water_rt].Height), Color.White);
                sprite.End();

                graphics.GraphicsDevice.SetRenderTarget(null);

                // PASS 4 SEDIMENT DIFFUSE
                WaterCalc.CurrentTechnique = WaterCalc.Techniques["DiffusionCalculation"];
                graphics.GraphicsDevice.Textures[4] = velocity_rt;
                graphics.GraphicsDevice.Textures[5] = sedimentTexture;

                RenderTargetBinding[] rtb_sediment = new RenderTargetBinding[3]
                {
                       new RenderTargetBinding(sediment_rt[act_water_rt]),
                       new RenderTargetBinding(ground_rt[act_water_rt]),
                       new RenderTargetBinding(debug_rt)
                };

                graphics.GraphicsDevice.SetRenderTargets(rtb_sediment);
                graphics.GraphicsDevice.Clear(new Color(0, 0, 0, 0));
                sprite.Begin(0, BlendState.Opaque, ss, null, null, WaterCalc);
                sprite.Draw(water_rt[1 - act_water_rt], new Rectangle(0, 0, water_rt[act_water_rt].Width, water_rt[act_water_rt].Height), Color.White);
                sprite.End();

                graphics.GraphicsDevice.SetRenderTargets(null);

                // PASS 5 WATER EVAP
                WaterCalc.CurrentTechnique = WaterCalc.Techniques["EvaporationCalculation"];

                graphics.GraphicsDevice.SetRenderTarget(water_rt[act_water_rt]);
                sprite.Begin(0, BlendState.Opaque, ss, null, null, WaterCalc);
                sprite.Draw(water_rt[1 - act_water_rt], new Rectangle(0, 0, water_rt[act_water_rt].Width, water_rt[act_water_rt].Height), Color.White);
                sprite.End();

                graphics.GraphicsDevice.SetRenderTarget(null);

                waterTexture = (Texture2D)water_rt[act_water_rt];
                groundTexture = (Texture2D)ground_rt[act_water_rt];
                sedimentTexture = (Texture2D)sediment_rt[act_water_rt];
            }

            act_water_rt = 1 - act_water_rt;
        }