Пример #1
0
        /// <summary>
        /// Set a new state.
        /// </summary>
        /// <param name="newState">The state to set.</param>
        /// <param name="force">Whether to set it regardless of the previous state.</param>
        public void SetState(RenderState newState, bool force = false)
        {
            FlushRenderStream();
            RenderState currentState = Engine.Renderer.CurrentState;

            // Check which state changes should apply, by checking which were set and which differ from the current.
            PerfProfiler.FrameEventStart("ShaderSet");
            if (newState.Shader != null && (force || newState.Shader != currentState.Shader))
            {
                ShaderProgram.EnsureBound(newState.Shader.Pointer);
                Engine.Renderer.CurrentState.Shader = newState.Shader;
                Engine.Renderer.SyncShader();
            }

            PerfProfiler.FrameEventEnd("ShaderSet");

            PerfProfiler.FrameEventStart("Depth/Stencil/Blend Set");
            if (newState.DepthTest != null && (force || newState.DepthTest != currentState.DepthTest))
            {
                SetDepthTest((bool)newState.DepthTest);
            }
            if (newState.StencilTest != null && (force || newState.StencilTest != currentState.StencilTest))
            {
                SetStencilTest((bool)newState.StencilTest);
            }
            if (newState.SFactorRgb != null && newState.SFactorRgb != currentState.SFactorRgb ||
                newState.DFactorRgb != null && newState.DFactorRgb != currentState.DFactorRgb ||
                newState.SFactorA != null && newState.SFactorA != currentState.SFactorA ||
                newState.DFactorA != null && newState.DFactorA != currentState.DFactorA)
            {
                SetAlphaBlendType(
                    newState.SFactorRgb ?? currentState.SFactorRgb !.Value,
                    newState.DFactorRgb ?? currentState.DFactorRgb !.Value,
                    newState.SFactorA ?? currentState.SFactorA !.Value,
                    newState.DFactorA ?? currentState.DFactorA !.Value);
            }
            if (newState.AlphaBlending != null && (force || newState.AlphaBlending != currentState.AlphaBlending))
            {
                SetAlphaBlend((bool)newState.AlphaBlending);
            }
            PerfProfiler.FrameEventEnd("Depth/Stencil/Blend Set");

            PerfProfiler.FrameEventStart("View/Clip Set");
            if (force || newState.ViewMatrix != null && newState.ViewMatrix != currentState.ViewMatrix)
            {
                SetUseViewMatrix((bool)newState.ViewMatrix);
            }
            if (force || newState.ProjectionBehavior != null && newState.ProjectionBehavior != currentState.ProjectionBehavior)
            {
                SetProjectionBehavior((ProjectionBehavior)newState.ProjectionBehavior);
            }
            if (force || newState.ClipRect != currentState.ClipRect)
            {
                SetClipRect(newState.ClipRect);
            }
            PerfProfiler.FrameEventEnd("Depth/Stencil/Blend Set");
        }
Пример #2
0
 /// <summary>
 /// Invalidates the current batch - flushing it to the current buffer.
 /// This should be done when the state changes in some way because calls afterwards will differ from those before and
 /// cannot be batched.
 /// </summary>
 public void InvalidateStateBatches()
 {
     if (ActiveQuadBatch == null || ActiveQuadBatch.BatchedSprites == 0)
     {
         return;
     }
     PerfProfiler.FrameEventStart($"RenderBatch {ActiveQuadBatch.BatchedSprites} Sprites {ActiveQuadBatch.TextureSlotUtilization} Textures");
     ActiveQuadBatch.Render(this);
     ActiveQuadBatch.Recycle();
     PerfProfiler.FrameEventEnd($"RenderBatch {ActiveQuadBatch.BatchedSprites} Sprites {ActiveQuadBatch.TextureSlotUtilization} Textures");
 }
Пример #3
0
        public void RenderObjects(RenderComposer composer)
        {
            // Check if anything is loaded.
            List <T> objects = QueryObjectsToRender();

            PerfProfiler.FrameEventStart("TileMap: Objects");
            for (var i = 0; i < objects.Count; i++)
            {
                objects[i].Render(composer);
            }

            PerfProfiler.FrameEventEnd("TileMap: Objects");
        }
Пример #4
0
        /// <summary>
        /// Set whether to use depth testing.
        /// </summary>
        /// <param name="depth">Whether to use depth testing.</param>
        public void SetDepthTest(bool depth)
        {
            PerfProfiler.FrameEventStart("StateChange: DepthTest");
            FlushRenderStream();

            if (depth)
            {
                Gl.Enable(EnableCap.DepthTest);
                Gl.DepthFunc(DepthFunction.Lequal);
            }
            else
            {
                Gl.Disable(EnableCap.DepthTest);
            }

            Engine.Renderer.CurrentState.DepthTest = depth;
            PerfProfiler.FrameEventEnd("StateChange: DepthTest");
        }
Пример #5
0
        /// <summary>
        /// Set whether to use alpha blending.
        /// This causes transparent objects to blend their colors when drawn on top of each other.
        /// </summary>
        /// <param name="alphaBlend">Whether to use alpha blending.</param>
        public void SetAlphaBlend(bool alphaBlend)
        {
            PerfProfiler.FrameEventStart("StateChange: AlphaBlend");
            FlushRenderStream();

            if (alphaBlend)
            {
                Gl.Enable(EnableCap.Blend);
                Gl.BlendFuncSeparate(CurrentState.SFactorRgb !.Value, CurrentState.DFactorRgb !.Value, CurrentState.SFactorA !.Value, CurrentState.DFactorA !.Value);
            }
            else
            {
                Gl.Disable(EnableCap.Blend);
            }

            Engine.Renderer.CurrentState.AlphaBlending = alphaBlend;
            PerfProfiler.FrameEventEnd("StateChange: AlphaBlend");
        }
Пример #6
0
        /// <summary>
        /// Whether, and where to clip.
        /// </summary>
        /// <param name="clip">The rectangle to clip outside of.</param>
        public void SetClipRect(Rectangle?clip)
        {
            PerfProfiler.FrameEventStart("StateChange: Clip");
            FlushRenderStream();

            if (clip == null)
            {
                Gl.Disable(EnableCap.ScissorTest);
            }
            else
            {
                Gl.Enable(EnableCap.ScissorTest);
                Rectangle c = clip.Value;
                Gl.Scissor((int)c.X,
                           (int)(Engine.Renderer.CurrentTarget.Viewport.Height - c.Height - c.Y),
                           (int)c.Width,
                           (int)c.Height);
            }

            Engine.Renderer.CurrentState.ClipRect = clip;
            PerfProfiler.FrameEventEnd("StateChange: Clip");
        }
Пример #7
0
        /// <summary>
        /// Enable or disable stencil testing.
        /// When enabling the stencil buffer is cleared.
        /// </summary>
        /// <param name="stencil">Whether to enable or disable stencil testing.</param>
        public void SetStencilTest(bool stencil)
        {
            PerfProfiler.FrameEventStart("StateChange: Stencil");
            FlushRenderStream();

            // Set the stencil test to it's default state - don't write to it.

            if (stencil)
            {
                Gl.Enable(EnableCap.StencilTest);

                // Clear after enabling.
                ClearStencil();
                StencilStateDefault();
            }
            else
            {
                Gl.Disable(EnableCap.StencilTest);
                StencilStateDefault(); // Some drivers don't understand that off means off
            }

            Engine.Renderer.CurrentState.StencilTest = stencil;
            PerfProfiler.FrameEventEnd("StateChange: Stencil");
        }