コード例 #1
0
        public void Bind(GalPipelineState New)
        {
            BindConstBuffers(New);

            BindVertexLayout(New);

            if (New.FramebufferSrgb != _old.FramebufferSrgb)
            {
                Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb);

                _renderTarget.FramebufferSrgb = New.FramebufferSrgb;
            }

            if (New.FlipX != _old.FlipX || New.FlipY != _old.FlipY || New.Instance != _old.Instance)
            {
                _shader.SetExtraData(New.FlipX, New.FlipY, New.Instance);
            }

            if (New.FrontFace != _old.FrontFace)
            {
                GL.FrontFace(OglEnumConverter.GetFrontFace(New.FrontFace));
            }

            if (New.CullFaceEnabled != _old.CullFaceEnabled)
            {
                Enable(EnableCap.CullFace, New.CullFaceEnabled);
            }

            if (New.CullFaceEnabled)
            {
                if (New.CullFace != _old.CullFace)
                {
                    GL.CullFace(OglEnumConverter.GetCullFace(New.CullFace));
                }
            }

            if (New.DepthTestEnabled != _old.DepthTestEnabled)
            {
                Enable(EnableCap.DepthTest, New.DepthTestEnabled);
            }

            if (New.DepthWriteEnabled != _old.DepthWriteEnabled)
            {
                GL.DepthMask(New.DepthWriteEnabled);
            }

            if (New.DepthTestEnabled)
            {
                if (New.DepthFunc != _old.DepthFunc)
                {
                    GL.DepthFunc(OglEnumConverter.GetDepthFunc(New.DepthFunc));
                }
            }

            if (New.DepthRangeNear != _old.DepthRangeNear ||
                New.DepthRangeFar != _old.DepthRangeFar)
            {
                GL.DepthRange(New.DepthRangeNear, New.DepthRangeFar);
            }

            if (New.StencilTestEnabled != _old.StencilTestEnabled)
            {
                Enable(EnableCap.StencilTest, New.StencilTestEnabled);
            }

            if (New.StencilTwoSideEnabled != _old.StencilTwoSideEnabled)
            {
                Enable((EnableCap)All.StencilTestTwoSideExt, New.StencilTwoSideEnabled);
            }

            if (New.StencilTestEnabled)
            {
                if (New.StencilBackFuncFunc != _old.StencilBackFuncFunc ||
                    New.StencilBackFuncRef != _old.StencilBackFuncRef ||
                    New.StencilBackFuncMask != _old.StencilBackFuncMask)
                {
                    GL.StencilFuncSeparate(
                        StencilFace.Back,
                        OglEnumConverter.GetStencilFunc(New.StencilBackFuncFunc),
                        New.StencilBackFuncRef,
                        New.StencilBackFuncMask);
                }

                if (New.StencilBackOpFail != _old.StencilBackOpFail ||
                    New.StencilBackOpZFail != _old.StencilBackOpZFail ||
                    New.StencilBackOpZPass != _old.StencilBackOpZPass)
                {
                    GL.StencilOpSeparate(
                        StencilFace.Back,
                        OglEnumConverter.GetStencilOp(New.StencilBackOpFail),
                        OglEnumConverter.GetStencilOp(New.StencilBackOpZFail),
                        OglEnumConverter.GetStencilOp(New.StencilBackOpZPass));
                }

                if (New.StencilBackMask != _old.StencilBackMask)
                {
                    GL.StencilMaskSeparate(StencilFace.Back, New.StencilBackMask);
                }

                if (New.StencilFrontFuncFunc != _old.StencilFrontFuncFunc ||
                    New.StencilFrontFuncRef != _old.StencilFrontFuncRef ||
                    New.StencilFrontFuncMask != _old.StencilFrontFuncMask)
                {
                    GL.StencilFuncSeparate(
                        StencilFace.Front,
                        OglEnumConverter.GetStencilFunc(New.StencilFrontFuncFunc),
                        New.StencilFrontFuncRef,
                        New.StencilFrontFuncMask);
                }

                if (New.StencilFrontOpFail != _old.StencilFrontOpFail ||
                    New.StencilFrontOpZFail != _old.StencilFrontOpZFail ||
                    New.StencilFrontOpZPass != _old.StencilFrontOpZPass)
                {
                    GL.StencilOpSeparate(
                        StencilFace.Front,
                        OglEnumConverter.GetStencilOp(New.StencilFrontOpFail),
                        OglEnumConverter.GetStencilOp(New.StencilFrontOpZFail),
                        OglEnumConverter.GetStencilOp(New.StencilFrontOpZPass));
                }

                if (New.StencilFrontMask != _old.StencilFrontMask)
                {
                    GL.StencilMaskSeparate(StencilFace.Front, New.StencilFrontMask);
                }
            }


            // Scissor Test
            // All scissor test are disabled before drawing final framebuffer to screen so we don't need to handle disabling
            // Skip if there are no scissor tests to enable
            if (New.ScissorTestCount != 0)
            {
                int  scissorsApplied = 0;
                bool applyToAll      = false;

                for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
                {
                    if (New.ScissorTestEnabled[index])
                    {
                        // If viewport arrays are unavailable apply first scissor test to all or
                        // there is only 1 scissor test and it's the first, the scissor test applies to all viewports
                        if (!OglExtension.Required.ViewportArray || (index == 0 && New.ScissorTestCount == 1))
                        {
                            GL.Enable(EnableCap.ScissorTest);
                            applyToAll = true;
                        }
                        else
                        {
                            GL.Enable(IndexedEnableCap.ScissorTest, index);
                        }

                        if (New.ScissorTestEnabled[index] != _old.ScissorTestEnabled[index] ||
                            New.ScissorTestX[index] != _old.ScissorTestX[index] ||
                            New.ScissorTestY[index] != _old.ScissorTestY[index] ||
                            New.ScissorTestWidth[index] != _old.ScissorTestWidth[index] ||
                            New.ScissorTestHeight[index] != _old.ScissorTestHeight[index])
                        {
                            if (applyToAll)
                            {
                                GL.Scissor(New.ScissorTestX[index], New.ScissorTestY[index],
                                           New.ScissorTestWidth[index], New.ScissorTestHeight[index]);
                            }
                            else
                            {
                                GL.ScissorIndexed(index, New.ScissorTestX[index], New.ScissorTestY[index],
                                                  New.ScissorTestWidth[index], New.ScissorTestHeight[index]);
                            }
                        }

                        // If all scissor tests have been applied, or viewport arrays are unavailable we can skip remaining iterations
                        if (!OglExtension.Required.ViewportArray || ++scissorsApplied == New.ScissorTestCount)
                        {
                            break;
                        }
                    }
                }
            }


            if (New.BlendIndependent)
            {
                for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
                {
                    SetBlendState(index, New.Blends[index], _old.Blends[index]);
                }
            }
            else
            {
                if (New.BlendIndependent != _old.BlendIndependent)
                {
                    SetAllBlendState(New.Blends[0]);
                }
                else
                {
                    SetBlendState(New.Blends[0], _old.Blends[0]);
                }
            }

            if (New.ColorMaskCommon)
            {
                if (New.ColorMaskCommon != _old.ColorMaskCommon || !New.ColorMasks[0].Equals(_old.ColorMasks[0]))
                {
                    GL.ColorMask(
                        New.ColorMasks[0].Red,
                        New.ColorMasks[0].Green,
                        New.ColorMasks[0].Blue,
                        New.ColorMasks[0].Alpha);
                }
            }
            else
            {
                for (int index = 0; index < GalPipelineState.RenderTargetsCount; index++)
                {
                    if (!New.ColorMasks[index].Equals(_old.ColorMasks[index]))
                    {
                        GL.ColorMask(
                            index,
                            New.ColorMasks[index].Red,
                            New.ColorMasks[index].Green,
                            New.ColorMasks[index].Blue,
                            New.ColorMasks[index].Alpha);
                    }
                }
            }

            if (New.PrimitiveRestartEnabled != _old.PrimitiveRestartEnabled)
            {
                Enable(EnableCap.PrimitiveRestart, New.PrimitiveRestartEnabled);
            }

            if (New.PrimitiveRestartEnabled)
            {
                if (New.PrimitiveRestartIndex != _old.PrimitiveRestartIndex)
                {
                    GL.PrimitiveRestartIndex(New.PrimitiveRestartIndex);
                }
            }

            _old = New;
        }