Beispiel #1
0
        /// <summary>
        /// Function to build up the render targets.
        /// </summary>
        /// <param name="width">The width of the render targets.</param>
        /// <param name="height">The height of the render targets.</param>
        /// <param name="format">The format of the buffer.</param>
        private void BuildRenderTargets(int width, int height, BufferFormat format)
        {
            // For the lighting effect, we use a deferred rendering technique where we have 3 render targets for diffuse, specularity, and normal mapping.
            // These targets are sub resources of the same texture resource (array indices).

            // Diffuse.
            _rtvInfo.Width      = width;
            _rtvInfo.Height     = height;
            _rtvInfo.Format     = format;
            _rtvInfo.ArrayCount = 2;

            _gbufferTargets[0] = Graphics.TemporaryTargets.Rent(_rtvInfo, "Gorgon 2D GBuffer - Diffuse/Specular", false);
            _gbufferTargets[0].Clear(GorgonColor.Black);
            // Specular.
            _gbufferTargets[1] = _gbufferTargets[0].Texture.GetRenderTargetView(arrayIndex: 1, arrayCount: 1);

            _rtvInfo.Format     = BufferFormat.R8G8B8A8_UNorm;
            _rtvInfo.ArrayCount = 1;

            // Normals.
            // We'll clear it before the pass, the default color is insufficient.
            _gbufferTargets[2] = Graphics.TemporaryTargets.Rent(_rtvInfo, "Gorgon 2D Buffer - Normals", false);
            GorgonTexture2DView normalSrv = _gbufferTargets[2].GetShaderResourceView();

            if ((_pixelLitShaderState.ShaderResources[1] != normalSrv) ||
                (_diffuseFilter != DiffuseFiltering) ||
                (_normalFilter != NormalFiltering) ||
                (_specularFilter != SpecularFiltering))
            {
                _diffuseFilter  = DiffuseFiltering ?? GorgonSamplerState.Default;
                _normalFilter   = NormalFiltering ?? GorgonSamplerState.PointFiltering;
                _specularFilter = SpecularFiltering ?? GorgonSamplerState.Default;

                _pixelDeferShaderState = PixelShaderBuilder.ResetTo(_pixelDeferShaderState)
                                         .SamplerState(_diffuseFilter, 0)
                                         .SamplerState(_normalFilter, 1)
                                         .SamplerState(_specularFilter, 2)
                                         .Build();

                _pixelLitShaderState = PixelShaderBuilder
                                       .ResetTo(_pixelLitShaderState)
                                       .ShaderResource(normalSrv, 1)
                                       .SamplerState(_diffuseFilter, 0)
                                       .SamplerState(_normalFilter, 1)
                                       .SamplerState(_specularFilter, 2)
                                       .Build();

                _lightingState = BatchStateBuilder
                                 .ResetTo(_lightingState)
                                 .PixelShaderState(_pixelLitShaderState)
                                 .Build();
            }


            _gbufferTexture = _gbufferTargets[0].Texture.GetShaderResourceView();
        }
Beispiel #2
0
        /// <summary>
        /// Function to assign a sampler to a shader on the pipeline.
        /// </summary>
        /// <param name="sampler">The sampler to assign.</param>
        /// <param name="index">[Optional] The index of the sampler.</param>
        /// <returns>The fluent interface for this builder.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if the <paramref name="index"/> parameter is less than 0, or greater than/equal to <see cref="GorgonSamplerStates.MaximumSamplerStateCount"/>.</exception>
        public Gorgon2DShaderStateBuilder <T> SamplerState(GorgonSamplerState sampler, int index = 0)
        {
            if ((index < 0) || (index >= GorgonSamplerStates.MaximumSamplerStateCount))
            {
                throw new ArgumentOutOfRangeException(nameof(index), string.Format(Resources.GOR2D_ERR_INVALID_SAMPLER_INDEX, GorgonSamplerStates.MaximumSamplerStateCount));
            }

            _workingShader.RwSamplers[index] = sampler;
            return(this);
        }
 /// <summary>Handles the PropertyChanged event of the WrappingEditor control.</summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
 private void WrappingEditor_PropertyChanged(object sender, PropertyChangedEventArgs e)
 {
     switch (e.PropertyName)
     {
     case nameof(ISpriteWrappingEditor.BorderColor):
     case nameof(ISpriteWrappingEditor.HorizontalWrapping):
     case nameof(ISpriteWrappingEditor.VerticalWrapping):
         _current = SpriteContent.WrappingEditor.GetSampler(SpriteContent.SamplerState.Filter);
         break;
     }
 }
        /// <summary>Function called when the sprite has a property change.</summary>
        /// <param name="e">The event parameters.</param>
        protected override void OnSpriteChanged(PropertyChangedEventArgs e)
        {
            base.OnSpriteChanged(e);

            switch (e.PropertyName)
            {
            case nameof(ISpriteContent.SamplerState):
                _current = SpriteContent.WrappingEditor.GetSampler(SpriteContent.SamplerState.Filter);
                SpriteContent.WrappingEditor.HorizontalWrapping  = _current.WrapU;
                SpriteContent.WrappingEditor.VerticalWrapping    = _current.WrapV;
                SpriteContent.WrappingEditor.OriginalBorderColor =
                    SpriteContent.WrappingEditor.BorderColor     = _current.BorderColor;
                break;
            }
        }
        /// <summary>Function called to perform custom loading of resources.</summary>
        protected override void OnLoad()
        {
            base.OnLoad();

            if (_builder == null)
            {
                _builder = new GorgonSamplerStateBuilder(Graphics);
            }

            _current = SpriteContent.SamplerState;

            SpriteContent.WrappingEditor.HorizontalWrapping  = _current.WrapU;
            SpriteContent.WrappingEditor.VerticalWrapping    = _current.WrapV;
            SpriteContent.WrappingEditor.OriginalBorderColor =
                SpriteContent.WrappingEditor.BorderColor     = _current.BorderColor;
            SpriteContent.WrappingEditor.PropertyChanged    += WrappingEditor_PropertyChanged;

            BuildSpriteRtv();
        }
Beispiel #6
0
        /// <summary>
        /// Function to render a texture to the current render target using the current effect.
        /// </summary>
        /// <param name="texture">The texture to render.</param>
        /// <param name="outputSize">The size of the output render target that the blit will render into.</param>
        /// <param name="destinationRegion">[Optional] The region that the texture will be drawn into.</param>
        /// <param name="textureCoordinates">[Optional] The texture coordinates to use with the texture.</param>
        /// <param name="samplerStateOverride">[Optional] An override for the current texture sampler.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="texture"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// <para>
        /// This method is a convenience method that will render a texture to the current set render target in slot 0.
        /// </para>
        /// <para>
        /// If the <paramref name="destinationRegion"/> parameter is omitted, then the texture will be rendered to the full size of the current render target.  If it is provided, then texture will be rendered to the
        /// location specified, and with the width and height specified.
        /// </para>
        /// <para>
        /// If the <paramref name="textureCoordinates"/> parameter is omitted, then the full size of the texture is rendered.
        /// </para>
        /// <para>
        /// If the <paramref name="samplerStateOverride"/> parameter is omitted, then the <see cref="GorgonSamplerState.Default"/> is used.  When provided, this will alter how the pixel shader samples our
        /// texture in slot 0.
        /// </para>
        /// <para>
        /// <note type="important">
        /// <para>
        /// For performance reasons, any exceptions thrown by this method will only be thrown when Gorgon is compiled as DEBUG.
        /// </para>
        /// </note>
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonBlendState"/>
        /// <seealso cref="GorgonDepthStencilState"/>
        /// <seealso cref="GorgonRasterState"/>
        /// <seealso cref="Gorgon2DOrthoCamera"/>
        /// <seealso cref="Gorgon2DPerspectiveCamera"/>
        protected void BlitTexture(GorgonTexture2DView texture,
                                   DX.Size2 outputSize,
                                   DX.RectangleF?destinationRegion         = null,
                                   DX.RectangleF?textureCoordinates        = null,
                                   GorgonSamplerState samplerStateOverride = null)
        {
            texture.ValidateObject(nameof(texture));

            if (destinationRegion == null)
            {
                destinationRegion = new DX.RectangleF(0, 0, outputSize.Width, outputSize.Height);
            }

            if (textureCoordinates == null)
            {
                textureCoordinates = new DX.RectangleF(0, 0, 1, 1);
            }

            Renderer.DrawFilledRectangle(destinationRegion.Value, GorgonColor.White, texture, textureCoordinates, textureSampler: samplerStateOverride);
        }
Beispiel #7
0
 /// <summary>
 /// Function to blit the specified texture into the current output target.
 /// </summary>
 /// <param name="texture">The texture to blit.</param>
 /// <param name="textureCoordinates">[Optional] The texture coordinates to use on the source texture.</param>
 /// <param name="samplerState">[Optional] The sampler state to apply.</param>
 protected void Blit(GorgonTexture2DView texture, DX.RectangleF?textureCoordinates = null, GorgonSamplerState samplerState = null) =>
 Renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, OutputSize.Width, OutputSize.Height),
                              GorgonColor.White,
                              texture,
                              textureCoordinates ?? new DX.RectangleF(0, 0, 1, 1),
                              textureSampler: samplerState ?? GorgonSamplerState.Default,
                              depth: 0.1f);
Beispiel #8
0
        /// <summary>
        /// Function to blit the texture to the specified render target.
        /// </summary>
        /// <param name="texture">The texture that will be blitted to the render target.</param>
        /// <param name="destRect">The layout area to blit the texture into.</param>
        /// <param name="sourceOffset">The offset within the source texture to start blitting from.</param>
        /// <param name="color">The color used to tint the diffuse value of the texture.</param>
        /// <param name="clip"><b>true</b> to clip the contents of the texture if the destination is larger/small than the size of the texture.</param>
        /// <param name="blendState">The blending state to apply.</param>
        /// <param name="samplerState">The sampler state to apply.</param>
        /// <param name="pixelShader">The pixel shader used to override the default pixel shader.</param>
        /// <param name="pixelShaderConstants">The pixel shader constant buffers to use.</param>
        public void Blit(GorgonTexture2DView texture,
                         DX.Rectangle destRect,
                         DX.Point sourceOffset,
                         GorgonColor color,
                         bool clip,
                         GorgonBlendState blendState,
                         GorgonSamplerState samplerState,
                         GorgonPixelShader pixelShader,
                         GorgonConstantBuffers pixelShaderConstants)
        {
            if ((_graphics.RenderTargets[0] == null) ||
                (color.Alpha.EqualsEpsilon(0)))
            {
                return;
            }

            if (texture == null)
            {
                texture = _defaultTexture;
            }

            GorgonRenderTargetView currentView = _graphics.RenderTargets[0];

            // We need to update the projection/view if the size of the target changes.
            if ((_targetBounds == null) ||
                (currentView.Width != _targetBounds.Value.Width) ||
                (currentView.Height != _targetBounds.Value.Height))
            {
                _needsWvpUpdate = true;
            }

            UpdateProjection();

            // Set to default states if not provided.
            if (blendState == null)
            {
                blendState = GorgonBlendState.NoBlending;
            }

            if (pixelShader == null)
            {
                pixelShader = _pixelShader;
            }

            if (samplerState == null)
            {
                samplerState = GorgonSamplerState.Default;
            }

            if (pixelShaderConstants == null)
            {
                pixelShaderConstants = _emptyPsConstants;
            }

            GetDrawCall(texture, blendState, samplerState, pixelShader, pixelShaderConstants);

            // Calculate position on the texture.
            DX.Vector2 topLeft     = texture.Texture.ToTexel(sourceOffset);
            DX.Vector2 bottomRight = texture.Texture.ToTexel(clip ? new DX.Vector2(destRect.Width, destRect.Height) : new DX.Point(texture.Width, texture.Height));

            if (clip)
            {
                DX.Vector2.Add(ref bottomRight, ref topLeft, out bottomRight);
            }

            // Update the vertices.
            _vertices[0] = new BltVertex
            {
                Position = new DX.Vector4(destRect.X, destRect.Y, 0, 1.0f),
                Uv       = topLeft,
                Color    = color
            };
            _vertices[1] = new BltVertex
            {
                Position = new DX.Vector4(destRect.Right, destRect.Y, 0, 1.0f),
                Uv       = new DX.Vector2(bottomRight.X, topLeft.Y),
                Color    = color
            };
            _vertices[2] = new BltVertex
            {
                Position = new DX.Vector4(destRect.X, destRect.Bottom, 0, 1.0f),
                Uv       = new DX.Vector2(topLeft.X, bottomRight.Y),
                Color    = color
            };
            _vertices[3] = new BltVertex
            {
                Position = new DX.Vector4(destRect.Right, destRect.Bottom, 0, 1.0f),
                Uv       = new DX.Vector2(bottomRight.X, bottomRight.Y),
                Color    = color
            };

            // Copy to the vertex buffer.
            _vertexBufferBindings[0].VertexBuffer.SetData(_vertices);
            _graphics.Submit(_drawCall);
        }
Beispiel #9
0
        /// <summary>
        /// Function to return the appropriate draw call based on the states provided.
        /// </summary>
        /// <param name="texture">The texture to display.</param>
        /// <param name="blendState">The blending state for the texture.</param>
        /// <param name="samplerState">The sampler state for the texture.</param>
        /// <param name="shader">The pixel shader to use.</param>
        /// <param name="constantBuffers">Constant buffers for the pixel shader, if required.</param>
        private void GetDrawCall(GorgonTexture2DView texture, GorgonBlendState blendState, GorgonSamplerState samplerState, GorgonPixelShader shader, GorgonConstantBuffers constantBuffers)
        {
            if ((_drawCall != null) &&
                (shader == _pixelShader) &&
                (_drawCall.PixelShader.Samplers[0] == samplerState) &&
                (_pipelineState.BlendStates[0] == blendState) &&
                (_drawCall.PixelShader.ShaderResources[0] == texture) &&
                (_drawCall.PixelShader.ConstantBuffers.DirtyEquals(constantBuffers)))
            {
                // This draw call hasn't changed, so return the previous one.
                return;
            }

            if (_pipelineState.BlendStates[0] != blendState)
            {
                _pipelineState = _pipeStateBuilder
                                 .BlendState(blendState)
                                 .Build();

                _drawCallBuilder.PipelineState(_pipelineState);
            }

            _drawCall = _drawCallBuilder.ConstantBuffers(ShaderType.Pixel, constantBuffers)
                        .SamplerState(ShaderType.Pixel, samplerState)
                        .ShaderResource(ShaderType.Pixel, texture)
                        .Build(_drawAllocator);
        }
 /// <summary>
 /// Function to assign a texture sampler to the polygon sprite.
 /// </summary>
 /// <param name="sampler">The sampler to assign to the sprite.</param>
 /// <returns>The fluent interface for this builder.</returns>
 public GorgonPolySpriteBuilder TextureSampler(GorgonSamplerState sampler)
 {
     _workingSprite.TextureSampler = sampler;
     return(this);
 }