Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Function called to render the effect.
        /// </summary>
        /// <param name="renderMethod">The method used to render the scene that will be used in the effect.</param>
        /// <param name="output">The render target that will receive the results of rendering the effect.</param>
        /// <param name="blendStateOverride">[Optional] An override for the current blending state.</param>
        /// <param name="depthStencilStateOverride">[Optional] An override for the current depth/stencil state.</param>
        /// <param name="rasterStateOverride">[Optional] An override for the current raster state.</param>
        /// <param name="camera">[Optional] The camera to use when rendering.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="renderMethod"/>, or the <paramref name="output"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// <para>
        /// The <paramref name="renderMethod"/> is a callback to a method with 3 parameters:
        /// <list type="number">
        ///     <item>
        ///         <description>The current pass index.</description>
        ///     </item>
        ///     <item>
        ///         <description>The total number of passes.</description>
        ///     </item>
        ///     <item>
        ///         <description>The size of the current render target.</description>
        ///     </item>
        /// </list>
        /// Users should pass a method that will render the items they want to use with this effect.
        /// </para>
        /// <para>
        /// <para>
        /// If the <paramref name="blendStateOverride"/>, parameter is omitted, then the <see cref="GorgonBlendState.Default"/> is used. When provided, this will override the current blending state.
        /// </para>
        /// <para>
        /// If the <paramref name="depthStencilStateOverride"/> parameter is omitted, then the <see cref="GorgonDepthStencilState.Default"/> is used. When provided, this will override the current
        /// depth/stencil state.
        /// </para>
        /// <para>
        /// If the <paramref name="rasterStateOverride"/> parameter is omitted, then the <see cref="GorgonRasterState.Default"/> is used. When provided, this will override the current raster state.
        /// </para>
        /// <para>
        /// The <paramref name="camera"/> parameter is used to render the texture using a different view, and optionally, a different coordinate set.
        /// </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>
        /// </para>
        /// </remarks>
        public void Render(Action <int, int, DX.Size2> renderMethod,
                           GorgonRenderTargetView output,
                           GorgonBlendState blendStateOverride = null,
                           GorgonDepthStencilState depthStencilStateOverride = null,
                           GorgonRasterState rasterStateOverride             = null,
                           IGorgon2DCamera camera = null)
        {
            renderMethod.ValidateObject(nameof(renderMethod));
            output.ValidateObject(nameof(output));

            bool stateChanged = SetupStates(blendStateOverride, depthStencilStateOverride, rasterStateOverride, output, camera);

            for (int i = 0; i < PassCount; ++i)
            {
                // Batch state should be cached on the implementation side, otherwise the GC could be impacted by a lot of dead objects per frame.
                Gorgon2DBatchState batchState = OnGetBatchState(i, stateChanged);

                switch (OnBeforeRenderPass(i, output, camera))
                {
                case PassContinuationState.Continue:
                    Renderer.Begin(batchState, camera);
                    OnRenderPass(i, renderMethod, output);
                    Renderer.End();

                    OnAfterRenderPass(i, output);
                    break;

                case PassContinuationState.Skip:
                    continue;

                default:
                    OnAfterRender(output);
                    return;
                }
            }

            OnAfterRender(output);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Function to set up state prior to rendering.
        /// </summary>
        /// <param name="blendStateOverride">An override for the current blending state.</param>
        /// <param name="depthStencilStateOverride">An override for the current depth/stencil state.</param>
        /// <param name="rasterStateOverride">An override for the current raster state.</param>
        /// <param name="output">The target used as the output.</param>
        /// <param name="camera">The active camera.</param>
        /// <returns><b>true</b> if state was overridden, <b>false</b> if not or <b>null</b> if rendering is canceled.</returns>
        private bool SetupStates(GorgonBlendState blendStateOverride, GorgonDepthStencilState depthStencilStateOverride, GorgonRasterState rasterStateOverride, GorgonRenderTargetView output, IGorgon2DCamera camera)
        {
            if (!_isInitialized)
            {
                OnInitialize();
                _isInitialized = true;
            }

            bool outputSizeChanged = false;

            if ((_prevOutputSize.Width != output.Width) ||
                (_prevOutputSize.Height != output.Height))
            {
                _prevOutputSize   = new DX.Size2(output.Width, output.Height);
                outputSizeChanged = true;
            }

            OnBeforeRender(output, camera, outputSizeChanged);

            if ((blendStateOverride == BlendStateOverride) &&
                (depthStencilStateOverride == DepthStencilStateOverride) &&
                (rasterStateOverride == RasterStateOverride))
            {
                return(false);
            }

            BatchStateBuilder.BlendState(blendStateOverride ?? GorgonBlendState.Default)
            .DepthStencilState(depthStencilStateOverride ?? GorgonDepthStencilState.Default)
            .RasterState(rasterStateOverride ?? GorgonRasterState.Default);

            BlendStateOverride        = blendStateOverride;
            DepthStencilStateOverride = depthStencilStateOverride;
            RasterStateOverride       = rasterStateOverride;

            return(true);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Function to assign the blend state to the batch state.
 /// </summary>
 /// <param name="blendState">The blend state to assign, or <b>null</b> for a default state.</param>
 /// <returns>The fluent builder interface.</returns>
 public Gorgon2DBatchStateBuilder BlendState(GorgonBlendState blendState)
 {
     _worker.BlendState = blendState;
     return(this);
 }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Function to provide an override for the blending state when rendering the initial scene.
 /// </summary>
 /// <param name="blendState">The blending state to use.</param>
 /// <returns>The fluent interface for the effects processor.</returns>
 public Gorgon2DCompositor FinalBlendState(GorgonBlendState blendState)
 {
     _finalBatchStateBuilder.BlendState(blendState ?? GorgonBlendState.NoBlending);
     _hasFinalBatchStateChanged = true;
     return(this);
 }