public void RenderRectangle(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Vector3 start, Vector3 end, Color color, bool filled = false)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionColor(start, color),
                new VertexPositionColor(new Vector3(start.X, end.Y, start.Z), color),
                new VertexPositionColor(new Vector3(end.X, start.Y, end.Z), color), new VertexPositionColor(end, color)
            };
            var indicies = new short[] { 0, 1, 2, 3 };

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.LineStrip,
                    vertexes,
                    0,
                    4,
                    indicies,
                    0,
                    3);
            }
        }
        public void RenderPlane(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, TextureAsset texture, Vector2 topLeftUV, Vector2 bottomRightUV)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionNormalTexture(new Vector3(0, 0, 0), new Vector3(0, -1, 0), new Vector2(topLeftUV.X, topLeftUV.Y)),
                new VertexPositionNormalTexture(new Vector3(0, 0, 1), new Vector3(0, -1, 0), new Vector2(topLeftUV.X, bottomRightUV.Y)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector2(bottomRightUV.X, topLeftUV.Y)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 1), new Vector3(0, -1, 0), new Vector2(bottomRightUV.X, bottomRightUV.Y))
            };

            var indicies = new short[]
            {
                0, 2, 1,
                3, 1, 2
            };

            var semantic = effectParameterSet.GetSemantic <ITextureEffectSemantic>();

            if (semantic.Texture != texture.Texture)
            {
                semantic.Texture = texture.Texture;
            }

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleList,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        public void RenderLine(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Vector3 start, Vector3 end, TextureAsset texture, Vector2 startUV, Vector2 endUV)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = _renderCache.GetOrSet(
                "renderlinetex3dvb:" + start + ":" + end + ":" + startUV + ":" + endUV,
                () =>
            {
                var vb = new VertexBuffer(context.GraphicsDevice, VertexPositionTexture.VertexDeclaration, 2,
                                          BufferUsage.WriteOnly);
                vb.SetData(new[] { new VertexPositionTexture(start, startUV), new VertexPositionTexture(end, endUV) });
                return(vb);
            });
            var indicies = _renderCache.GetOrSet(
                "renderline3dib",
                () =>
            {
                var ib = new IndexBuffer(context.GraphicsDevice, IndexElementSize.SixteenBits, 2,
                                         BufferUsage.WriteOnly);
                ib.SetData(new short[] { 0, 1 });
                return(ib);
            });

            context.GraphicsDevice.SetVertexBuffer(vertexes);
            context.GraphicsDevice.Indices = indicies;

            var semantic = effectParameterSet.GetSemantic <ITextureEffectSemantic>();

            if (semantic.Texture != texture.Texture)
            {
                semantic.Texture = texture.Texture;
            }

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, 1);
            }
        }
        public void RenderPlane(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, Color color)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionColor(new Vector3(0, 0, 0), color),
                new VertexPositionColor(new Vector3(0, 0, 1), color),
                new VertexPositionColor(new Vector3(1, 0, 0), color),
                new VertexPositionColor(new Vector3(1, 0, 1), color)
            };

            var indicies = new short[]
            {
                0, 2, 1,
                3, 1, 2
            };

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleList,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        public void RenderLine(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Vector3 start, Vector3 end, Color color)
        {
            if (!context.IsCurrentRenderPass<I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = _renderCache.GetOrSet(
                "renderline3dvb:" + start + ":" + end + ":" + color,
                () =>
                {
                    var vb = new VertexBuffer(context.GraphicsDevice, VertexPositionColor.VertexDeclaration, 2,
                        BufferUsage.WriteOnly);
                    vb.SetData(new[] { new VertexPositionColor(start, color), new VertexPositionColor(end, color) });
                    return vb;
                });
            var indicies = _renderCache.GetOrSet(
                "renderline3dib",
                () =>
                {
                    var ib = new IndexBuffer(context.GraphicsDevice, IndexElementSize.SixteenBits, 2,
                        BufferUsage.WriteOnly);
                    ib.SetData(new short[] { 0, 1 });
                    return ib;
                });

            context.GraphicsDevice.SetVertexBuffer(vertexes);
            context.GraphicsDevice.Indices = indicies;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, 1);
            }
        }
        public void RenderCircle(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, Vector2 center, int radius, Color color, bool filled = false)
        {
            if (!context.IsCurrentRenderPass<I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var points = 8;

            double angle = MathHelper.TwoPi / points;

            var vertexesList = new List<VertexPositionColor>();
            var indicesList = new List<short>();

            vertexesList.Add(new VertexPositionColor(new Vector3(center, 0), color));

            for (int i = 1; i <= points; i++)
            {
                var pos = new Vector2(
                    (float)Math.Round(Math.Sin(angle * i), 4) * radius,
                    (float)Math.Round(Math.Cos(angle * i), 4) * radius);
                
                vertexesList.Add(new VertexPositionColor(new Vector3(center + pos, 0), color));
            }

            if (filled)
            {
                for (int i = 1; i < points; i++)
                {
                    indicesList.Add(0);
                    indicesList.Add((short)(i + 1));
                    indicesList.Add((short) i);
                }
                indicesList.Add(0);
                indicesList.Add(1);
                indicesList.Add((short) points);
            }
            else
            {
                for (int i = 1; i <= points; i++)
                {
                    indicesList.Add((short) i);
                }
                indicesList.Add(1);
            }

            var vertexes = vertexesList.ToArray();
            var indicies = indicesList.ToArray();

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    filled ? PrimitiveType.TriangleList : PrimitiveType.LineStrip,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        public void RenderPlane(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, TextureAsset texture, Vector2 topLeftUV, Vector2 bottomRightUV)
        {
            if (!context.IsCurrentRenderPass<I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionNormalTexture(new Vector3(0, 0, 0), new Vector3(0, -1, 0), new Vector2(topLeftUV.X, topLeftUV.Y)),
                new VertexPositionNormalTexture(new Vector3(0, 0, 1), new Vector3(0, -1, 0), new Vector2(topLeftUV.X, bottomRightUV.Y)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector2(bottomRightUV.X, topLeftUV.Y)),
                new VertexPositionNormalTexture(new Vector3(1, 0, 1), new Vector3(0, -1, 0), new Vector2(bottomRightUV.X, bottomRightUV.Y))
            };

            var indicies = new short[]
            {
                0, 2, 1,
                3, 1, 2
            };

            var semantic = effectParameterSet.GetSemantic<ITextureEffectSemantic>();
            if (semantic.Texture != texture.Texture)
            {
                semantic.Texture = texture.Texture;
            }

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleList,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        public void RenderPlane(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, Color color)
        {
            if (!context.IsCurrentRenderPass<I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionColor(new Vector3(0, 0, 0), color),
                new VertexPositionColor(new Vector3(0, 0, 1), color),
                new VertexPositionColor(new Vector3(1, 0, 0), color),
                new VertexPositionColor(new Vector3(1, 0, 1), color)
            };

            var indicies = new short[]
            {
                0, 2, 1,
                3, 1, 2
            };

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleList,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        private void RenderTexture(
            IRenderContext context,
            IEffect effect, 
            IEffectParameterSet effectParameterSet, 
            Matrix matrix, 
            Texture2D texture, 
            Color? color = null, 
            bool flipHorizontally = false, 
            bool flipVertically = false, 
            Rectangle? sourceArea = null)
        {
            if (color != null)
            {
                throw new NotSupportedException();
            }

            if (flipHorizontally)
            {
                throw new NotSupportedException();
            }

            if (flipVertically)
            {
                throw new NotSupportedException();
            }

            if (sourceArea != null)
            {
                throw new NotSupportedException();
            }

            var semantic = effectParameterSet.GetSemantic<ITextureEffectSemantic>();
            if (semantic.Texture != texture)
            {
                semantic.Texture = texture;
            }

            var vertexes = new[]
            {
                new VertexPositionTexture(Vector3.Transform(new Vector3(0, 0, 0), matrix), new Vector2(0, 1)), 
                new VertexPositionTexture(Vector3.Transform(new Vector3(0, 1, 0), matrix), new Vector2(0, 0)), 
                new VertexPositionTexture(Vector3.Transform(new Vector3(1, 0, 0), matrix), new Vector2(1, 1)), 
                new VertexPositionTexture(Vector3.Transform(new Vector3(1, 1, 0), matrix), new Vector2(1, 0))
            };
            var indicies = new short[] { 1, 3, 0, 2 };

            context.GraphicsDevice.BlendState = BlendState.NonPremultiplied;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleStrip, 
                    vertexes, 
                    0, 
                    vertexes.Length, 
                    indicies, 
                    0, 
                    vertexes.Length - 2);
            }

            context.GraphicsDevice.BlendState = BlendState.Opaque;
        }
        public void RenderRectangle(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Vector3 start, Vector3 end, Color color, bool filled = false)
        {
            if (!context.IsCurrentRenderPass<I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = new[]
            {
                new VertexPositionColor(start, color), 
                new VertexPositionColor(new Vector3(start.X, end.Y, start.Z), color), 
                new VertexPositionColor(new Vector3(end.X, start.Y, end.Z), color), new VertexPositionColor(end, color)
            };
            var indicies = new short[] { 0, 1, 2, 3 };

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.LineStrip, 
                    vertexes, 
                    0, 
                    4, 
                    indicies, 
                    0, 
                    3);
            }
        }
示例#11
0
        private void BlitInternal(
            IRenderContext renderContext,
            Texture2D source,
            RenderTarget2D[] destinations = null,
            IEffect shader = null,
            IEffectParameterSet effectParameterSet = null,
            BlendState blendState = null,
            Vector2?offset        = null,
            Vector2?size          = null)
        {
            float destWidth, destHeight;

            if (destinations != null)
            {
                var destinationsBound = new RenderTargetBinding[destinations.Length];
                for (var i = 0; i < destinations.Length; i++)
                {
                    // Implicit cast.
                    destinationsBound[i] = destinations[i];
                }

                renderContext.PushRenderTarget(destinationsBound);
                destWidth  = destinations[0].Width;
                destHeight = destinations[0].Height;
            }
            else
            {
                // TODO: renderContext.GraphicsDevice.GetRenderTargets();
                destWidth  = renderContext.GraphicsDevice.PresentationParameters.BackBufferWidth;
                destHeight = renderContext.GraphicsDevice.PresentationParameters.BackBufferHeight;
            }

            offset = offset ?? new Vector2(0, 0);
            size   = size ?? new Vector2(1 - offset.Value.X, 1 - offset.Value.Y);

            if (blendState == null)
            {
                blendState = BlendState.Opaque;
            }

            if (shader == null && _blitEffect.IsReady)
            {
                shader = _blitEffect.Asset.Effects["Texture"];
            }

            if (shader == null)
            {
                // Can't perform blit; no shader is available.
                return;
            }

            if (effectParameterSet == null)
            {
                effectParameterSet = shader.CreateParameterSet();
            }

            if (_vertexBuffer == null)
            {
                _vertexBuffer = new VertexBuffer(renderContext.GraphicsDevice, typeof(VertexPositionNormalTexture),
                                                 _vertexes.Length, BufferUsage.WriteOnly);
                _vertexBuffer.SetData(_vertexes);
            }

            if (_indexBuffer == null)
            {
                _indexBuffer = new IndexBuffer(renderContext.GraphicsDevice, typeof(short), _indicies.Length,
                                               BufferUsage.WriteOnly);
                _indexBuffer.SetData(_indicies);
            }

            var oldWorld      = renderContext.World;
            var oldProjection = renderContext.Projection;
            var oldView       = renderContext.View;

            renderContext.GraphicsDevice.BlendState        = blendState;
            renderContext.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            renderContext.GraphicsDevice.SamplerStates[0]  = SamplerState.LinearWrap;
            renderContext.GraphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            renderContext.World      = Matrix.CreateScale(destWidth, destHeight, 1);
            renderContext.Projection =
#if !PLATFORM_WINDOWS
                Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
#endif
                Matrix.CreateOrthographicOffCenter(
                    destWidth * (-offset.Value.X / size.Value.X),
                    destWidth * (-offset.Value.X / size.Value.X) + destWidth / size.Value.X,
                    destHeight * (-offset.Value.Y / size.Value.Y) + destHeight / size.Value.Y,
                    destHeight * (-offset.Value.Y / size.Value.Y),
                    0,
                    1);
            renderContext.View = Matrix.Identity;

            if (source != null && effectParameterSet != null)
            {
                var semantic = effectParameterSet.GetSemantic <ITextureEffectSemantic>();
                if (semantic.Texture != source)
                {
                    semantic.Texture = source;
                }
            }

            renderContext.GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            renderContext.GraphicsDevice.Indices = _indexBuffer;

            shader.LoadParameterSet(renderContext, effectParameterSet);
            foreach (var pass in shader.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                renderContext.GraphicsDevice.DrawIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    0,
                    0,
                    2);
            }

            renderContext.World      = oldWorld;
            renderContext.Projection = oldProjection;
            renderContext.View       = oldView;

            if (destinations != null)
            {
                renderContext.PopRenderTarget();
            }
        }
        public void RenderCircle(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, Vector2 center, int radius, Color color, bool filled = false)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var points = 8;

            double angle = MathHelper.TwoPi / points;

            var vertexesList = new List <VertexPositionColor>();
            var indicesList  = new List <short>();

            vertexesList.Add(new VertexPositionColor(new Vector3(center, 0), color));

            for (int i = 1; i <= points; i++)
            {
                var pos = new Vector2(
                    (float)Math.Round(Math.Sin(angle * i), 4) * radius,
                    (float)Math.Round(Math.Cos(angle * i), 4) * radius);

                vertexesList.Add(new VertexPositionColor(new Vector3(center + pos, 0), color));
            }

            if (filled)
            {
                for (int i = 1; i < points; i++)
                {
                    indicesList.Add(0);
                    indicesList.Add((short)(i + 1));
                    indicesList.Add((short)i);
                }
                indicesList.Add(0);
                indicesList.Add(1);
                indicesList.Add((short)points);
            }
            else
            {
                for (int i = 1; i <= points; i++)
                {
                    indicesList.Add((short)i);
                }
                indicesList.Add(1);
            }

            var vertexes = vertexesList.ToArray();
            var indicies = indicesList.ToArray();

            var world = context.World;

            context.World = transform;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    filled ? PrimitiveType.TriangleList : PrimitiveType.LineStrip,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    indicies.Length / 3);
            }

            context.World = world;
        }
        private void RenderTexture(
            IRenderContext context,
            IEffect effect,
            IEffectParameterSet effectParameterSet,
            Matrix matrix,
            Texture2D texture,
            Color?color           = null,
            bool flipHorizontally = false,
            bool flipVertically   = false,
            Rectangle?sourceArea  = null)
        {
            if (color != null)
            {
                throw new NotSupportedException();
            }

            if (flipHorizontally)
            {
                throw new NotSupportedException();
            }

            if (flipVertically)
            {
                throw new NotSupportedException();
            }

            if (sourceArea != null)
            {
                throw new NotSupportedException();
            }

            var semantic = effectParameterSet.GetSemantic <ITextureEffectSemantic>();

            if (semantic.Texture != texture)
            {
                semantic.Texture = texture;
            }

            var vertexes = new[]
            {
                new VertexPositionTexture(Vector3.Transform(new Vector3(0, 0, 0), matrix), new Vector2(0, 1)),
                new VertexPositionTexture(Vector3.Transform(new Vector3(0, 1, 0), matrix), new Vector2(0, 0)),
                new VertexPositionTexture(Vector3.Transform(new Vector3(1, 0, 0), matrix), new Vector2(1, 1)),
                new VertexPositionTexture(Vector3.Transform(new Vector3(1, 1, 0), matrix), new Vector2(1, 0))
            };
            var indicies = new short[] { 1, 3, 0, 2 };

            context.GraphicsDevice.BlendState = BlendState.NonPremultiplied;

            effect.LoadParameterSet(context, effectParameterSet);
            foreach (var pass in effect.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                context.GraphicsDevice.DrawUserIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    vertexes,
                    0,
                    vertexes.Length,
                    indicies,
                    0,
                    vertexes.Length - 2);
            }

            context.GraphicsDevice.BlendState = BlendState.Opaque;
        }
        private void BlitInternal(
            IRenderContext renderContext,
            Texture2D source,
            RenderTarget2D[] destinations = null, 
            IEffect shader = null,
            IEffectParameterSet effectParameterSet = null,
            BlendState blendState = null,
            Vector2? offset = null,
            Vector2? size = null)
        {
            float destWidth, destHeight;
            if (destinations != null)
            {
                var destinationsBound = new RenderTargetBinding[destinations.Length];
                for (var i = 0; i < destinations.Length; i++)
                {
                    // Implicit cast.
                    destinationsBound[i] = destinations[i];
                }

                renderContext.PushRenderTarget(destinationsBound);
                destWidth = destinations[0].Width;
                destHeight = destinations[0].Height;
            }
            else
            {
                // TODO: renderContext.GraphicsDevice.GetRenderTargets();
                destWidth = renderContext.GraphicsDevice.PresentationParameters.BackBufferWidth;
                destHeight = renderContext.GraphicsDevice.PresentationParameters.BackBufferHeight;
            }

            offset = offset ?? new Vector2(0, 0);
            size = size ?? new Vector2(1 - offset.Value.X, 1 - offset.Value.Y);

            if (blendState == null)
            {
                blendState = BlendState.Opaque;
            }

            if (shader == null)
            {
                shader = _blitEffect;
            }

            if (effectParameterSet == null)
            {
                effectParameterSet = shader.CreateParameterSet();
            }

            if (_vertexBuffer == null)
            {
                _vertexBuffer = new VertexBuffer(renderContext.GraphicsDevice, typeof (VertexPositionNormalTexture),
                    _vertexes.Length, BufferUsage.WriteOnly);
                _vertexBuffer.SetData(_vertexes);
            }

            if (_indexBuffer == null)
            {
                _indexBuffer = new IndexBuffer(renderContext.GraphicsDevice, typeof (short), _indicies.Length,
                    BufferUsage.WriteOnly);
                _indexBuffer.SetData(_indicies);
            }

            var oldWorld = renderContext.World;
            var oldProjection = renderContext.Projection;
            var oldView = renderContext.View;

            renderContext.GraphicsDevice.BlendState = blendState;
            renderContext.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            renderContext.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
            renderContext.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

            renderContext.World = Matrix.CreateScale(destWidth, destHeight, 1);
            renderContext.Projection =
#if !PLATFORM_WINDOWS
                Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
#endif
                Matrix.CreateOrthographicOffCenter(
                    destWidth * (-offset.Value.X / size.Value.X),
                    destWidth * (-offset.Value.X / size.Value.X) + destWidth / size.Value.X, 
                    destHeight * (-offset.Value.Y / size.Value.Y) + destHeight / size.Value.Y,
                    destHeight * (-offset.Value.Y / size.Value.Y),
                    0,
                    1);
            renderContext.View = Matrix.Identity;

            if (source != null && effectParameterSet != null)
            {
                var semantic = effectParameterSet.GetSemantic<ITextureEffectSemantic>();
                if (semantic.Texture != source)
                {
                    semantic.Texture = source;
                }
            }

            renderContext.GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            renderContext.GraphicsDevice.Indices = _indexBuffer;
            
            shader.LoadParameterSet(renderContext, effectParameterSet);
            foreach (var pass in shader.NativeEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                renderContext.GraphicsDevice.DrawIndexedPrimitives(
                    PrimitiveType.TriangleStrip,
                    0,
                    0,
                    2);
            }

            renderContext.World = oldWorld;
            renderContext.Projection = oldProjection;
            renderContext.View = oldView;

            if (destinations != null)
            {
                renderContext.PopRenderTarget();
            }
        }