Пример #1
0
        /// <summary>Initializes a new instance of the <see cref="T:Gorgon.Editor.SpriteEditor.SpriteVertexOffsetRenderer"/> class.</summary>
        /// <param name="sprite">The sprite view model.</param>
        /// <param name="graphics">The graphics interface for the application.</param>
        /// <param name="swapChain">The swap chain for the render area.</param>
        /// <param name="renderer">The 2D renderer for the application.</param>
        /// <param name="vertexEditor">The editor used to modify the sprite vertices.</param>
        /// <param name="initialZoom">The initial zoom scale value.</param>
        public SpriteVertexOffsetRenderer(ISpriteContent sprite, GorgonGraphics graphics, GorgonSwapChain swapChain, Gorgon2D renderer, ISpriteVertexEditService vertexEditor, float initialZoom)
            : base(sprite, graphics, swapChain, renderer, initialZoom)
        {
            InitialTextureAlpha           = 0;
            _vertexEditor                 = vertexEditor;
            _vertexEditor.RectToClient    = r => ToClient(r).Truncate();
            _vertexEditor.PointToClient   = p => ToClient(p).Truncate();
            _vertexEditor.PointFromClient = p => FromClient(p).Truncate();

            _workingSprite = new GorgonSprite
            {
                Texture           = sprite.Texture,
                TextureRegion     = sprite.TextureCoordinates,
                TextureArrayIndex = TextureArrayIndex,
                Size   = sprite.Size,
                Scale  = DX.Vector2.One,
                Anchor = DX.Vector2.Zero,
                Color  = GorgonColor.White,
                Depth  = 0.1f
            };

            UpdateWorkingSprite();

            _vertexEditor.VerticesChanged     += VertexEditor_VerticesChanged;
            _vertexEditor.KeyboardIconClicked += VertexEditor_KeyboardIconClicked;
            _vertexEditor.VertexSelected      += VertexEditor_VertexSelected;

            _camera = new Gorgon2DPerspectiveCamera(renderer, new DX.Size2F(swapChain.Width, swapChain.Height));
        }
 /// <summary>
 /// Function called prior to rendering.
 /// </summary>
 /// <param name="output">The final render target that will receive the rendering from the effect.</param>
 /// <param name="camera">The currently active camera.</param>
 /// <param name="sizeChanged"><b>true</b> if the output size changed since the last render, or <b>false</b> if it's the same.</param>
 /// <remarks>
 /// <para>
 /// Applications can use this to set up common states and other configuration settings prior to executing the render passes. This is an ideal method to initialize and resize your internal render
 /// targets (if applicable).
 /// </para>
 /// </remarks>
 protected override void OnBeforeRender(GorgonRenderTargetView output, IGorgon2DCamera camera, bool sizeChanged)
 {
     if (Graphics.RenderTargets[0] != output)
     {
         Graphics.SetRenderTarget(output, Graphics.DepthStencilView);
     }
 }
Пример #3
0
        /// <summary>
        /// Function to update the camera data on the GPU.
        /// </summary>
        /// <param name="camera">The camera to update.</param>
        public void UpdateCamera(IGorgon2DCamera camera)
        {
            if (camera.AllowUpdateOnResize)
            {
                var viewportSize = new DX.Size2F(Graphics.Viewports[0].Width, Graphics.Viewports[0].Height);

                if (!camera.ViewDimensions.Equals(viewportSize))
                {
                    camera.ViewDimensions = viewportSize;
                }
            }

            bool camChanged = (_current != camera) || (camera.NeedsUpdate);

            if (!camChanged)
            {
                return;
            }

            camera.GetViewMatrix(out DX.Matrix view);
            camera.GetProjectionMatrix(out DX.Matrix projection);

            // Build the view/projection matrix.
            DX.Matrix.Multiply(ref view, ref projection, out _viewProjectionMatrix);

            CameraBuffer.Buffer.SetData(ref _viewProjectionMatrix);

            _current = camera;
        }
Пример #4
0
        /// <summary>
        /// Function called prior to rendering.
        /// </summary>
        /// <param name="output">The final render target that will receive the rendering from the effect.</param>
        /// <param name="camera">The currently active camera.</param>
        /// <param name="sizeChanged"><b>true</b> if the output size changed since the last render, or <b>false</b> if it's the same.</param>
        /// <remarks>
        /// <para>
        /// Applications can use this to set up common states and other configuration settings prior to executing the render passes. This is an ideal method to initialize and resize your internal render
        /// targets (if applicable).
        /// </para>
        /// </remarks>
        protected override void OnBeforeRender(GorgonRenderTargetView output, IGorgon2DCamera camera, bool sizeChanged)
        {
            BuildRenderTargets(output.Width, output.Height, output.Format);

            var globals = new GlobalEffectData
            {
                FlipYNormal    = FlipYNormal ? 1 : 0,
                CameraPosition = Renderer.CurrentCamera == null ? DX.Vector3.Zero : camera.Position
            };

            _globalData.Buffer.SetData(ref globals);
        }
Пример #5
0
        /// <summary>
        /// Function called prior to rendering.
        /// </summary>
        /// <param name="output">The final render target that will receive the rendering from the effect.</param>
        /// <param name="camera">The currently active camera.</param>
        /// <param name="sizeChanged"><b>true</b> if the output size changed since the last render, or <b>false</b> if it's the same.</param>
        /// <remarks>
        /// <para>
        /// Applications can use this to set up common states and other configuration settings prior to executing the render passes. This is an ideal method to initialize and resize your internal render
        /// targets (if applicable).
        /// </para>
        /// </remarks>
        protected override void OnBeforeRender(GorgonRenderTargetView output, IGorgon2DCamera camera, bool sizeChanged)
        {
            BuildRenderTargets(output.Width, output.Height, output.Format);

            var globals = new GlobalEffectData
            {
                FlipYNormal = 0,
                // If no custom camera is in use, we need to pass in our default viewing information which is normally the output width, and height (by half), and an arbitrary Z value so
                // the camera position isn't intersecting with the drawing plane (+ height information). Otherwise, our specular hilight will look really messed up.
                CameraPosition = Renderer.CurrentCamera == null ? new DX.Vector3(output.Width / 2.0f, output.Height / 2.0f, DefaultSpecularZDistance) : camera.Position
            };

            _globalData.Buffer.SetData(ref globals);
        }
Пример #6
0
        /// <summary>Function to perform setup on the renderer.</summary>
        public void Setup()
        {
            _bgTexture = GorgonTexture2DView.CreateTexture(_graphics, new GorgonTexture2DInfo("Texture Atlas BG Texture")
            {
                Binding = TextureBinding.ShaderResource,
                Usage   = ResourceUsage.Immutable,
                Width   = EditorCommonResources.CheckerBoardPatternImage.Width,
                Height  = EditorCommonResources.CheckerBoardPatternImage.Height
            }, EditorCommonResources.CheckerBoardPatternImage);

            _camera = new Gorgon2DOrthoCamera(_renderer, new DX.Size2F(_swapChain.Width, _swapChain.Height))
            {
                Anchor = new DX.Vector2(0.5f, 0.5f)
            };
        }
Пример #7
0
        /// <summary>
        /// Function called to render a single effect pass.
        /// </summary>
        /// <param name="passIndex">The index of the pass being rendered.</param>
        /// <param name="renderMethod">The method used to render a scene for the effect.</param>
        /// <param name="output">The render target that will receive the final render data.</param>
        /// <remarks>
        /// <para>
        /// Applications must implement this in order to see any results from the effect.
        /// </para>
        /// </remarks>
        protected override void OnRenderPass(int passIndex, Action <int, int, DX.Size2> renderMethod, GorgonRenderTargetView output)
        {
            if (passIndex == 0)
            {
                renderMethod(passIndex, PassCount, new DX.Size2(output.Width, output.Height));
                return;
            }

            // We'll do our own drawing so we can ensure we have screen space.
            IGorgon2DCamera currentCamera = Renderer.CurrentCamera;

            Renderer.End();

            var   destRect = new DX.RectangleF(0, 0, output.Width, output.Height);
            float minZ     = 0;

            // Calculate our full screen blit area in camera projection if we're using another camera.
            if (currentCamera != null)
            {
                minZ     = currentCamera.MinimumDepth;
                destRect = currentCamera.ViewableRegion;
            }

            for (int i = 0; i < Lights.Count; ++i)
            {
                Gorgon2DLight light = Lights[i];

                if (light == null)
                {
                    continue;
                }

                UpdateLight(light);

                Renderer.Begin(_lightingState, currentCamera);
                Renderer.DrawFilledRectangle(destRect,
                                             GorgonColor.White,
                                             _gbufferTexture,
                                             new DX.RectangleF(0, 0, 1, 1),
                                             textureSampler: GorgonSamplerState.Default,
                                             depth: minZ);
                Renderer.End();
            }
        }
Пример #8
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);
        }
Пример #9
0
        /// <summary>
        /// Function called prior to rendering a pass.
        /// </summary>
        /// <param name="passIndex">The index of the pass to render.</param>
        /// <param name="output">The final render target that will receive the rendering from the effect.</param>
        /// <param name="camera">The currently active camera.</param>
        /// <returns>A <see cref="PassContinuationState"/> to instruct the effect on how to proceed.</returns>
        /// <remarks>
        /// <para>
        /// Applications can use this to set up per-pass states and other configuration settings prior to executing a single render pass.
        /// </para>
        /// </remarks>
        /// <seealso cref="PassContinuationState"/>

        protected virtual PassContinuationState OnBeforeRenderPass(int passIndex, GorgonRenderTargetView output, IGorgon2DCamera camera) => PassContinuationState.Continue;
Пример #10
0
 /// <summary>
 /// Function called prior to rendering.
 /// </summary>
 /// <param name="output">The final render target that will receive the rendering from the effect.</param>
 /// <param name="camera">The currently active camera.</param>
 /// <param name="sizeChanged"><b>true</b> if the output size changed since the last render, or <b>false</b> if it's the same.</param>
 /// <remarks>
 /// <para>
 /// Applications can use this to set up common states and other configuration settings prior to executing the render passes. This is an ideal method to initialize and resize your internal render
 /// targets (if applicable).
 /// </para>
 /// </remarks>
 protected virtual void OnBeforeRender(GorgonRenderTargetView output, IGorgon2DCamera camera, bool sizeChanged)
 {
 }
Пример #11
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);
        }
Пример #12
0
 /// <summary>
 /// Function to assign a camera for the initial and final scene rendering.
 /// </summary>
 /// <param name="camera">The camera to use.</param>
 /// <returns>The fluent interface for the effects processor.</returns>
 public Gorgon2DCompositor Camera(IGorgon2DCamera camera)
 {
     _camera = camera;
     return(this);
 }
Пример #13
0
        /// <summary>Function called prior to rendering a pass.</summary>
        /// <param name="passIndex">The index of the pass to render.</param>
        /// <param name="output">The final render target that will receive the rendering from the effect.</param>
        /// <param name="camera">The currently active camera.</param>
        /// <returns>A <see cref="PassContinuationState"/> to instruct the effect on how to proceed.</returns>
        /// <remarks>
        ///   <para>
        /// Applications can use this to set up per-pass states and other configuration settings prior to executing a single render pass.
        /// </para>
        /// </remarks>
        /// <seealso cref="PassContinuationState"/>
        protected override PassContinuationState OnBeforeRenderPass(int passIndex, GorgonRenderTargetView output, IGorgon2DCamera camera)
        {
            Debug.Assert(passIndex >= 0, "Illegal pass index.");

            int lightIndex = passIndex - 1;

            if ((Lights.Count == 0) || (lightIndex >= Lights.Count))
            {
                return(PassContinuationState.Stop);
            }

            switch (passIndex)
            {
            case 0:
                // Array 0 is cleared on rental.
                _gbufferTargets[1].Clear(GorgonColor.Black);
                _gbufferTargets[2].Clear(_normalClearColor);
                Graphics.SetRenderTargets(_gbufferTargets, Graphics.DepthStencilView);
                return(PassContinuationState.Continue);

            case 1:
                Graphics.SetRenderTarget(output, Graphics.DepthStencilView);
                return(PassContinuationState.Continue);
            }

            return(PassContinuationState.Stop);
        }
        /// <summary>Function called prior to rendering a pass.</summary>
        /// <param name="passIndex">The index of the pass to render.</param>
        /// <param name="output">The final render target that will receive the rendering from the effect.</param>
        /// <param name="camera">The currently active camera.</param>
        /// <returns>A <see cref="PassContinuationState"/> to instruct the effect on how to proceed.</returns>
        /// <remarks>Applications can use this to set up per-pass states and other configuration settings prior to executing a single render pass.</remarks>
        /// <seealso cref="PassContinuationState" />
        protected override PassContinuationState OnBeforeRenderPass(int passIndex, GorgonRenderTargetView output, IGorgon2DCamera camera)
        {
            DX.Vector2 intensity = FullScreen ? new DX.Vector2((Intensity * 16) * (1.0f / output.Width), (Intensity * 16) * (1.0f / output.Height))
                : new DX.Vector2(Intensity * 0.05f, 0);
            var settings = new DX.Vector4(intensity, output.Width, output.Height);

            _settings.Buffer.SetData(ref settings);

            Graphics.SetRenderTarget(output);

            return(PassContinuationState.Continue);
        }