示例#1
0
        private void GL_pushState()
        {
            // Begin the effect, flagging to restore previous state on end
            FNA3D.FNA3D_BeginPassRestore(
                currentDevice.GLDevice,
                shaderProgram.glEffect,
                stateChangesPtr
                );

            // Prep our samplers
            for (int i = 0; i < 3; i += 1)
            {
                oldTextures[i]                 = currentDevice.Textures[i];
                oldSamplers[i]                 = currentDevice.SamplerStates[i];
                currentDevice.Textures[i]      = yuvTextures[i];
                currentDevice.SamplerStates[i] = SamplerState.LinearClamp;
            }

            // Prep buffers
            oldBuffers = currentDevice.GetVertexBuffers();
            currentDevice.SetVertexBuffers(vertBuffer);

            // Prep target bindings
            oldTargets = currentDevice.GetRenderTargets();

            unsafe
            {
                fixed(FNA3D.FNA3D_RenderTargetBinding *rt = &nativeVideoTexture[0])
                {
                    GraphicsDevice.PrepareRenderTargetBindings(
                        rt,
                        videoTexture
                        );
                    FNA3D.FNA3D_SetRenderTargets(
                        currentDevice.GLDevice,
                        rt,
                        videoTexture.Length,
                        IntPtr.Zero,
                        DepthFormat.None,
                        0
                        );
                }
            }

            // Prep render state
            prevBlend                       = currentDevice.BlendState;
            prevDepthStencil                = currentDevice.DepthStencilState;
            prevRasterizer                  = currentDevice.RasterizerState;
            currentDevice.BlendState        = BlendState.Opaque;
            currentDevice.DepthStencilState = DepthStencilState.None;
            currentDevice.RasterizerState   = RasterizerState.CullNone;

            // Prep viewport
            prevViewport = currentDevice.Viewport;
            FNA3D.FNA3D_SetViewport(
                currentDevice.GLDevice,
                ref viewport.viewport
                );
        }
示例#2
0
        private void GL_popState()
        {
            // End the effect, restoring the previous shader state
            FNA3D.FNA3D_EndPassRestore(
                currentDevice.GLDevice,
                shaderProgram.glEffect
                );

            // Restore GL state
            currentDevice.BlendState        = prevBlend;
            currentDevice.DepthStencilState = prevDepthStencil;
            currentDevice.RasterizerState   = prevRasterizer;
            prevBlend        = null;
            prevDepthStencil = null;
            prevRasterizer   = null;

            /* Restore targets using GLDevice directly.
             * This prevents accidental clearing of previously bound targets.
             */
            if (oldTargets == null || oldTargets.Length == 0)
            {
                FNA3D.FNA3D_SetRenderTargets(
                    currentDevice.GLDevice,
                    IntPtr.Zero,
                    0,
                    IntPtr.Zero,
                    DepthFormat.None,
                    0
                    );
            }
            else
            {
                IRenderTarget oldTarget = oldTargets[0].RenderTarget as IRenderTarget;

                unsafe
                {
                    fixed(FNA3D.FNA3D_RenderTargetBinding *rt = &nativeOldTargets[0])
                    {
                        GraphicsDevice.PrepareRenderTargetBindings(
                            rt,
                            oldTargets
                            );
                        FNA3D.FNA3D_SetRenderTargets(
                            currentDevice.GLDevice,
                            rt,
                            oldTargets.Length,
                            oldTarget.DepthStencilBuffer,
                            oldTarget.DepthStencilFormat,
                            (byte)(oldTarget.RenderTargetUsage != RenderTargetUsage.DiscardContents ? 1 : 0)                              /* lol c# */
                            );
                    }
                }
            }
            oldTargets = null;

            // Set viewport AFTER setting targets!
            FNA3D.FNA3D_SetViewport(
                currentDevice.GLDevice,
                ref prevViewport.viewport
                );

            // Restore buffers
            currentDevice.SetVertexBuffers(oldBuffers);
            oldBuffers = null;

            // Restore samplers
            for (int i = 0; i < 3; i += 1)
            {
                /* The application may have set a texture ages
                 * ago, only to not unset after disposing. We
                 * have to avoid an ObjectDisposedException!
                 */
                if (oldTextures[i] == null || !oldTextures[i].IsDisposed)
                {
                    currentDevice.Textures[i] = oldTextures[i];
                }
                currentDevice.SamplerStates[i] = oldSamplers[i];
                oldTextures[i] = null;
                oldSamplers[i] = null;
            }
        }