Esempio n. 1
0
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            BlendStateDescription?       previousBlendState        = null;
            DepthStencilStateDescription?previousDepthStencilState = null;
            EffectInstance previousEffect = null;

            //TODO string comparison ...?
            var isPicking = RenderSystem.RenderStages[renderViewStage.Index].Name == "Picking";

            var hasBegin = false;

            for (var index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);

                var spriteState = (RenderSpriteStudio)renderNode.RenderObject;

                var depthStencilState = DepthStencilStates.DepthRead;

                foreach (var node in spriteState.SortedNodes)
                {
                    if (node.Sprite?.Texture == null || node.Sprite.Region.Width <= 0 || node.Sprite.Region.Height <= 0f || node.Hide != 0)
                    {
                        continue;
                    }

                    // Update the sprite batch

                    BlendStateDescription spriteBlending;
                    switch (node.BaseNode.AlphaBlending)
                    {
                    case SpriteStudioBlending.Mix:
                        spriteBlending = BlendStates.AlphaBlend;
                        break;

                    case SpriteStudioBlending.Multiplication:
                        spriteBlending = MultBlendState;
                        break;

                    case SpriteStudioBlending.Addition:
                        spriteBlending = BlendStates.Additive;
                        break;

                    case SpriteStudioBlending.Subtraction:
                        spriteBlending = SubBlendState;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    // TODO: this should probably be moved to Prepare()
                    // Project the position
                    // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object
                    var worldPosition = new Vector4(spriteState.WorldMatrix.TranslationVector, 1.0f);

                    Vector4 projectedPosition;
                    Vector4.Transform(ref worldPosition, ref renderView.ViewProjection, out projectedPosition);
                    var projectedZ = projectedPosition.Z / projectedPosition.W;

                    var blendState = isPicking ? BlendStates.Default : spriteBlending;
                    // TODO: the current impementation to determine if the sprite is selected does not work. This should be fixed later at some point
                    //var currentEffect = isPicking ? GetOrCreatePickingSpriteEffect() : ShadowObject.IsObjectSelected(spriteState.SpriteStudioComponent) ? GetOrCreateSelectedSpriteEffect() : null;
                    var currentEffect = isPicking ? GetOrCreatePickingSpriteEffect() : null;
                    // TODO remove this code when material are available
                    if (previousEffect != currentEffect || blendState != previousBlendState || depthStencilState != previousDepthStencilState)
                    {
                        if (hasBegin)
                        {
                            sprite3DBatch.End();
                        }
                        sprite3DBatch.Begin(context.GraphicsContext, renderView.ViewProjection, SpriteSortMode.Deferred, blendState, null, depthStencilState, RasterizerStates.CullNone, currentEffect);
                        hasBegin = true;
                    }

                    previousEffect            = currentEffect;
                    previousBlendState        = blendState;
                    previousDepthStencilState = depthStencilState;

                    var sourceRegion = node.Sprite.Region;
                    var texture      = node.Sprite.Texture;

                    // skip the sprite if no texture is set.
                    if (texture == null)
                    {
                        continue;
                    }

                    var color4 = Color4.White;
                    if (isPicking)
                    {
                        // TODO move this code corresponding to picking out of the runtime code.
                        color4 = new Color4(RuntimeIdHelper.ToRuntimeId(spriteState.Source));
                    }
                    else
                    {
                        if (node.BlendFactor > 0.0f)
                        {
                            switch (node.BlendType) //todo this should be done in a shader
                            {
                            case SpriteStudioBlending.Mix:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Multiplication:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Addition:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Subtraction:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else
                        {
                            color4 *= node.FinalTransparency;
                        }
                    }

                    Matrix.Multiply(ref node.ModelTransform, ref spriteState.WorldMatrix, out var worldMatrix);

                    // calculate normalized position of the center of the sprite (takes into account the possible rotation of the image)
                    var normalizedCenter = new Vector2(node.Sprite.Center.X / sourceRegion.Width - 0.5f, 0.5f - node.Sprite.Center.Y / sourceRegion.Height);
                    if (node.Sprite.Orientation == ImageOrientation.Rotated90)
                    {
                        var oldCenterX = normalizedCenter.X;
                        normalizedCenter.X = -normalizedCenter.Y;
                        normalizedCenter.Y = oldCenterX;
                    }
                    // apply the offset due to the center of the sprite
                    var size         = node.Sprite.Size;
                    var centerOffset = Vector2.Modulate(normalizedCenter, size);
                    worldMatrix.M41 -= centerOffset.X * worldMatrix.M11 + centerOffset.Y * worldMatrix.M21;
                    worldMatrix.M42 -= centerOffset.X * worldMatrix.M12 + centerOffset.Y * worldMatrix.M22;

                    // draw the sprite
                    sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref size, ref color4, node.Sprite.Orientation, SwizzleMode.None, projectedZ);
                }
            }

            if (hasBegin)
            {
                sprite3DBatch.End();
            }
        }
Esempio n. 2
0
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            Matrix viewInverse;

            Matrix.Invert(ref renderView.View, out viewInverse);

            BlendStateDescription?       previousBlendState        = null;
            DepthStencilStateDescription?previousDepthStencilState = null;
            EffectInstance previousEffect = null;

            //TODO string comparison ...?
            var isPicking = renderViewStage.RenderStage.Name == "Picking";

            bool hasBegin = false;

            for (var index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);

                var renderSprite = (RenderSprite)renderNode.RenderObject;

                var spriteComp        = renderSprite.SpriteComponent;
                var transfoComp       = renderSprite.TransformComponent;
                var depthStencilState = renderSprite.SpriteComponent.IgnoreDepth ? DepthStencilStates.None : DepthStencilStates.Default;

                var sprite = spriteComp.CurrentSprite;
                if (sprite == null)
                {
                    continue;
                }

                // TODO: this should probably be moved to Prepare()
                // Project the position
                // TODO: This could be done in a SIMD batch, but we need to figure-out how to plugin in with RenderMesh object
                var worldPosition = new Vector4(renderSprite.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

                Vector4 projectedPosition;
                Vector4.Transform(ref worldPosition, ref renderView.ViewProjection, out projectedPosition);
                var projectedZ = projectedPosition.Z / projectedPosition.W;

                // Update the sprite batch
                var blendState    = isPicking ? BlendStates.Default : sprite.IsTransparent ? (spriteComp.PremultipliedAlpha ? BlendStates.AlphaBlend : BlendStates.NonPremultiplied) : BlendStates.Opaque;
                var currentEffect = isPicking ? GetOrCreatePickingSpriteEffect() : null; // TODO remove this code when material are available
                if (previousEffect != currentEffect || blendState != previousBlendState || depthStencilState != previousDepthStencilState)
                {
                    if (hasBegin)
                    {
                        sprite3DBatch.End();
                    }
                    sprite3DBatch.Begin(context.GraphicsContext, renderView.ViewProjection, SpriteSortMode.Deferred, blendState, null, depthStencilState, RasterizerStates.CullNone, currentEffect);
                    hasBegin = true;
                }
                previousEffect            = currentEffect;
                previousBlendState        = blendState;
                previousDepthStencilState = depthStencilState;

                var sourceRegion = sprite.Region;
                var texture      = sprite.Texture;
                var color        = spriteComp.Color;
                if (isPicking) // TODO move this code corresponding to picking out of the runtime code.
                {
                    var compId = RuntimeIdHelper.ToRuntimeId(spriteComp);
                    color = new Color4(compId);
                }

                // skip the sprite if no texture is set.
                if (texture == null)
                {
                    continue;
                }

                // determine the element world matrix depending on the type of sprite
                var worldMatrix = transfoComp.WorldMatrix;
                if (spriteComp.SpriteType == SpriteType.Billboard)
                {
                    worldMatrix = viewInverse;

                    // remove scale of the camera
                    worldMatrix.Row1 /= ((Vector3)viewInverse.Row1).Length();
                    worldMatrix.Row2 /= ((Vector3)viewInverse.Row2).Length();

                    // set the scale of the object
                    worldMatrix.Row1 *= ((Vector3)transfoComp.WorldMatrix.Row1).Length();
                    worldMatrix.Row2 *= ((Vector3)transfoComp.WorldMatrix.Row2).Length();

                    // set the position
                    worldMatrix.TranslationVector = transfoComp.WorldMatrix.TranslationVector;
                }

                // calculate normalized position of the center of the sprite (takes into account the possible rotation of the image)
                var normalizedCenter = new Vector2(sprite.Center.X / sourceRegion.Width - 0.5f, 0.5f - sprite.Center.Y / sourceRegion.Height);
                if (sprite.Orientation == ImageOrientation.Rotated90)
                {
                    var oldCenterX = normalizedCenter.X;
                    normalizedCenter.X = -normalizedCenter.Y;
                    normalizedCenter.Y = oldCenterX;
                }
                // apply the offset due to the center of the sprite
                var centerOffset = Vector2.Modulate(normalizedCenter, sprite.SizeInternal);
                worldMatrix.M41 -= centerOffset.X * worldMatrix.M11 + centerOffset.Y * worldMatrix.M21;
                worldMatrix.M42 -= centerOffset.X * worldMatrix.M12 + centerOffset.Y * worldMatrix.M22;
                worldMatrix.M43 -= centerOffset.X * worldMatrix.M13 + centerOffset.Y * worldMatrix.M23;

                // draw the sprite
                sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref sprite.SizeInternal, ref color, sprite.Orientation, SwizzleMode.None, projectedZ);
            }

            if (hasBegin)
            {
                sprite3DBatch.End();
            }
        }
Esempio n. 3
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var viewParameters = context.Parameters;

            var device         = context.GraphicsDevice;
            var viewProjection = viewParameters.Get(TransformationKeys.ViewProjection);

            BlendState        previousBlendState        = null;
            DepthStencilState previousDepthStencilState = null;
            Effect            previousEffect            = null;

            var isPicking = context.IsPicking();

            bool hasBegin = false;

            for (var i = fromIndex; i <= toIndex; i++)
            {
                var renderItem        = renderItems[i];
                var spriteState       = (SpriteStudioProcessor.Data)renderItem.DrawContext;
                var transfoComp       = spriteState.TransformComponent;
                var depthStencilState = device.DepthStencilStates.None;

                foreach (var node in spriteState.SpriteStudioComponent.SortedNodes)
                {
                    if (node.Sprite?.Texture == null || node.Sprite.Region.Width <= 0 || node.Sprite.Region.Height <= 0f || node.Hide)
                    {
                        continue;
                    }

                    // Update the sprite batch

                    BlendState spriteBlending;
                    switch (node.BaseNode.AlphaBlending)
                    {
                    case SpriteStudioBlending.Mix:
                        spriteBlending = device.BlendStates.AlphaBlend;
                        break;

                    case SpriteStudioBlending.Multiplication:
                        spriteBlending = MultBlendState;
                        break;

                    case SpriteStudioBlending.Addition:
                        spriteBlending = device.BlendStates.Additive;
                        break;

                    case SpriteStudioBlending.Subtraction:
                        spriteBlending = SubBlendState;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    var blendState    = isPicking ? device.BlendStates.Opaque : renderItems.HasTransparency ? spriteBlending : device.BlendStates.Opaque;
                    var currentEffect = isPicking ? GetOrCreatePickingSpriteEffect() : spriteState.SpriteStudioComponent.Tags.Get(IsEntitySelected) ? GetOrCreateSelectedSpriteEffect() : null;
                    // TODO remove this code when material are available
                    if (previousEffect != currentEffect || blendState != previousBlendState || depthStencilState != previousDepthStencilState)
                    {
                        if (hasBegin)
                        {
                            sprite3DBatch.End();
                        }
                        sprite3DBatch.Begin(viewProjection, SpriteSortMode.Deferred, blendState, null, depthStencilState, device.RasterizerStates.CullNone, currentEffect);
                        hasBegin = true;
                    }

                    previousEffect            = currentEffect;
                    previousBlendState        = blendState;
                    previousDepthStencilState = depthStencilState;

                    var sourceRegion = node.Sprite.Region;
                    var texture      = node.Sprite.Texture;

                    // skip the sprite if no texture is set.
                    if (texture == null)
                    {
                        continue;
                    }

                    var color4 = Color4.White;
                    if (isPicking)
                    {
                        // TODO move this code corresponding to picking out of the runtime code.
                        color4 = new Color4(spriteState.SpriteStudioComponent.Id);
                    }
                    else
                    {
                        if (node.BlendFactor > 0.0f)
                        {
                            switch (node.BlendType) //todo this should be done in a shader
                            {
                            case SpriteStudioBlending.Mix:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Multiplication:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Addition:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            case SpriteStudioBlending.Subtraction:
                                color4 = Color4.Lerp(color4, node.BlendColor, node.BlendFactor) * node.FinalTransparency;
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else
                        {
                            color4 *= node.FinalTransparency;
                        }
                    }

                    var worldMatrix = node.ModelTransform * transfoComp.WorldMatrix;

                    // calculate normalized position of the center of the sprite (takes into account the possible rotation of the image)
                    var normalizedCenter = new Vector2(node.Sprite.Center.X / sourceRegion.Width - 0.5f, 0.5f - node.Sprite.Center.Y / sourceRegion.Height);
                    if (node.Sprite.Orientation == ImageOrientation.Rotated90)
                    {
                        var oldCenterX = normalizedCenter.X;
                        normalizedCenter.X = -normalizedCenter.Y;
                        normalizedCenter.Y = oldCenterX;
                    }
                    // apply the offset due to the center of the sprite
                    var size         = node.Sprite.Size;
                    var centerOffset = Vector2.Modulate(normalizedCenter, size);
                    worldMatrix.M41 -= centerOffset.X * worldMatrix.M11 + centerOffset.Y * worldMatrix.M21;
                    worldMatrix.M42 -= centerOffset.X * worldMatrix.M12 + centerOffset.Y * worldMatrix.M22;

                    // draw the sprite
                    sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref size, ref color4, node.Sprite.Orientation, SwizzleMode.None, renderItem.Depth);
                }
            }

            sprite3DBatch.End();
        }
Esempio n. 4
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var viewParameters = context.Parameters;

            var device         = context.GraphicsDevice;
            var viewInverse    = Matrix.Invert(viewParameters.Get(TransformationKeys.View));
            var viewProjection = viewParameters.Get(TransformationKeys.ViewProjection);

            BlendState        previousBlendState        = null;
            DepthStencilState previousDepthStencilState = null;
            Effect            previousEffect            = null;

            var isPicking = context.IsPicking();

            bool hasBegin = false;

            for (var i = fromIndex; i <= toIndex; i++)
            {
                var renderItem        = renderItems[i];
                var spriteState       = (SpriteProcessor.SpriteComponentState)renderItem.DrawContext;
                var spriteComp        = spriteState.SpriteComponent;
                var transfoComp       = spriteState.TransformComponent;
                var depthStencilState = spriteState.SpriteComponent.IgnoreDepth ? device.DepthStencilStates.None : device.DepthStencilStates.Default;

                var sprite = spriteComp.CurrentSprite;
                if (sprite == null)
                {
                    continue;
                }

                // Update the sprite batch
                var blendState    = isPicking ? device.BlendStates.Opaque : renderItems.HasTransparency ? (spriteComp.PremultipliedAlpha ? device.BlendStates.AlphaBlend : device.BlendStates.NonPremultiplied) : device.BlendStates.Opaque;
                var currentEffect = isPicking? GetOrCreatePickingSpriteEffect(): spriteComp.Tags.Get(IsEntitySelected)? GetOrCreateSelectedSpriteEffect(): null; // TODO remove this code when material are available
                if (previousEffect != currentEffect || blendState != previousBlendState || depthStencilState != previousDepthStencilState)
                {
                    if (hasBegin)
                    {
                        sprite3DBatch.End();
                    }
                    sprite3DBatch.Begin(viewProjection, SpriteSortMode.Deferred, blendState, null, depthStencilState, device.RasterizerStates.CullNone, currentEffect);
                    hasBegin = true;
                }
                previousEffect            = currentEffect;
                previousBlendState        = blendState;
                previousDepthStencilState = depthStencilState;

                var sourceRegion = sprite.Region;
                var texture      = sprite.Texture;
                var color        = spriteComp.Color;
                if (isPicking) // TODO move this code corresponding to picking out of the runtime code.
                {
                    color = (Color) new Color4(spriteComp.Id);
                }

                // skip the sprite if no texture is set.
                if (texture == null)
                {
                    continue;
                }

                // determine the element world matrix depending on the type of sprite
                var worldMatrix = transfoComp.WorldMatrix;
                if (spriteComp.SpriteType == SpriteType.Billboard)
                {
                    worldMatrix = viewInverse;

                    // remove scale of the camera
                    worldMatrix.Row1 /= ((Vector3)viewInverse.Row1).Length();
                    worldMatrix.Row2 /= ((Vector3)viewInverse.Row2).Length();

                    // set the scale of the object
                    worldMatrix.Row1 *= ((Vector3)transfoComp.WorldMatrix.Row1).Length();
                    worldMatrix.Row2 *= ((Vector3)transfoComp.WorldMatrix.Row2).Length();

                    // set the position
                    worldMatrix.TranslationVector = transfoComp.WorldMatrix.TranslationVector;
                }

                // apply the offset due to the center of the sprite
                var normalizedCenter = new Vector2(sprite.SizeInternal.X * (sprite.Center.X / sourceRegion.Width - 0.5f), sprite.SizeInternal.Y * (0.5f - sprite.Center.Y / sourceRegion.Height));
                worldMatrix.M41 -= normalizedCenter.X * worldMatrix.M11 + normalizedCenter.Y * worldMatrix.M21;
                worldMatrix.M42 -= normalizedCenter.X * worldMatrix.M12 + normalizedCenter.Y * worldMatrix.M22;
                worldMatrix.M43 -= normalizedCenter.X * worldMatrix.M13 + normalizedCenter.Y * worldMatrix.M23;

                // draw the sprite
                sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref sprite.SizeInternal, ref color, sprite.Orientation, SwizzleMode.None, renderItem.Depth);
            }

            sprite3DBatch.End();
        }
Esempio n. 5
0
        private void DrawScene()
        {
            var cameraSize       = 640f;
            var cameraNear       = 100;
            var projectionMatrix = Matrix.PerspectiveRH(cameraSize, cameraSize, cameraNear, 10000);
            var viewMatrix       = Matrix.LookAtRH(cameraNear * Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);

            GraphicsContext.CommandList.Clear(GraphicsDevice.Presenter.BackBuffer, Color.Black);
            GraphicsContext.CommandList.Clear(GraphicsDevice.Presenter.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
            GraphicsContext.CommandList.SetRenderTargetAndViewport(GraphicsDevice.Presenter.DepthStencilBuffer, GraphicsDevice.Presenter.BackBuffer);

            batch.Begin(GraphicsContext, viewMatrix * projectionMatrix, rasterizerState: rasterizerState);

            var leftTopCorner = new Vector3(-320, -320, 0);
            var pos           = leftTopCorner;
            var noRotation    = rotatedImages["NoRotation"];
            var rotation90    = rotatedImages["Rotation90"];
            var width         = noRotation.Region.Width;
            var height        = noRotation.Region.Height;

            // not rotated image
            pos.X = leftTopCorner.X + width / 2;
            pos.Y = leftTopCorner.Y + height / 2;
            Draw(noRotation, pos);

            // rotated image
            pos.X = leftTopCorner.X + width / 2;
            pos.Y = leftTopCorner.Y + height + height / 2;
            Draw(rotation90, pos);

            // colored image
            pos.X = leftTopCorner.X + 3 * width / 2;
            pos.Y = leftTopCorner.Y + height / 2;
            Draw(noRotation, pos, null, colorParam: Color.Gray);

            // deformed image
            pos.X = leftTopCorner.X + width + height / 2;
            pos.Y = leftTopCorner.Y + 3 * height / 2;
            Draw(noRotation, pos, sizeParam: new Vector2(height, height));

            // image on background
            pos.X = leftTopCorner.X + width;
            pos.Y = leftTopCorner.Y + 3 / 2f * height;
            pos.Z = -20;
            Draw(noRotation, pos);
            pos.Z = 0;

            // rotating image (around Z)
            pos.X = leftTopCorner.X + 3 * width;
            pos.Y = leftTopCorner.Y + width;
            Draw(noRotation, pos, new Vector3(0, 0, timeInSeconds));

            // rotating image (around Y)
            pos.X = leftTopCorner.X + 3 * width;
            pos.Y = leftTopCorner.Y + 3 * width;
            pos.Z = -width / 2;
            Draw(noRotation, pos, new Vector3(timeInSeconds, 0, 0));
            pos.Z = 0;

            // ball
            pos.Y = leftTopCorner.X + 4 * width;
            pos.X = leftTopCorner.Y + 1 * width;

            var time            = timeInSeconds;
            var rotation        = (float)(time * Math.PI * 2.0);
            var sourceRectangle = GetSphereAnimation(time);
            var world           = Matrix.RotationYawPitchRoll(0, 0, rotation) * Matrix.Translation(pos);
            var size            = new Vector2(SphereWidth, SphereHeight);
            var color           = Color4.White;

            batch.Draw(sphere, ref world, ref sourceRectangle, ref size, ref color);

            batch.End();
        }
Esempio n. 6
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            // TODO: Check how to integrate sprites in a Camera renderer instead of this
            var viewParameters = context.Parameters;

            var device         = context.GraphicsDevice;
            var cullMode       = device.RasterizerStates.CullNone;
            var viewInverse    = Matrix.Invert(viewParameters.Get(TransformationKeys.View));
            var viewProjection = viewParameters.Get(TransformationKeys.ViewProjection);

            BlendState previousBlendState = null;
            Effect     previousEffect     = null;

            var isPicking = context.IsPicking();

            bool hasBegin = false;

            for (var i = fromIndex; i <= toIndex; i++)
            {
                var renderItem  = renderItems[i];
                var spriteState = (SpriteProcessor.SpriteComponentState)renderItem.DrawContext;
                var spriteComp  = spriteState.SpriteComponent;
                var transfoComp = spriteState.TransformComponent;

                var sprite = spriteComp.CurrentSprite;
                if (sprite == null)
                {
                    continue;
                }

                // Update the sprite batch
                var blendState    = isPicking ? device.BlendStates.Opaque : renderItems.HasTransparency ? (spriteComp.PremultipliedAlpha ? device.BlendStates.AlphaBlend : device.BlendStates.NonPremultiplied) : device.BlendStates.Opaque;
                var currentEffect = (!isPicking && spriteComp.Tags.Get(IsEntitySelected)) ? GetOrCreateSelectedSpriteEffect(): null; // TODO remove this code when material are available
                if (previousEffect != currentEffect || blendState != previousBlendState)
                {
                    if (hasBegin)
                    {
                        sprite3DBatch.End();
                    }
                    sprite3DBatch.Begin(viewProjection, SpriteSortMode.Deferred, blendState, null, context.GraphicsDevice.DepthStencilStates.None, cullMode, currentEffect);
                    hasBegin = true;
                }
                previousEffect     = currentEffect;
                previousBlendState = blendState;

                var sourceRegion = sprite.Region;
                var texture      = sprite.Texture;
                var color        = spriteComp.Color;
                if (isPicking) // TODO move this code corresponding to picking out of the runtime code.
                {
                    texture = device.GetSharedWhiteTexture();
                    color   = (Color) new Color4(spriteComp.Id);
                }

                // skip the sprite if no texture is set.
                if (texture == null)
                {
                    continue;
                }

                // determine the size of the element depending on the extrusion method.
                var elementSize = Vector2.One;
                if (spriteComp.ExtrusionMethod == SpriteExtrusionMethod.UnitHeightSpriteRatio)
                {
                    elementSize.X = sourceRegion.Width / sourceRegion.Height;
                }
                else if (spriteComp.ExtrusionMethod == SpriteExtrusionMethod.UnitWidthSpriteRatio)
                {
                    elementSize.Y = sourceRegion.Height / sourceRegion.Width;
                }

                // determine the element world matrix depending on the type of sprite
                var worldMatrix = transfoComp.WorldMatrix;
                if (spriteComp.SpriteType == SpriteType.Billboard)
                {
                    worldMatrix = viewInverse;

                    // remove scale of the camera
                    worldMatrix.Row1 /= ((Vector3)viewInverse.Row1).Length();
                    worldMatrix.Row2 /= ((Vector3)viewInverse.Row2).Length();

                    // set the scale of the object
                    worldMatrix.Row1 *= ((Vector3)transfoComp.WorldMatrix.Row1).Length();
                    worldMatrix.Row2 *= ((Vector3)transfoComp.WorldMatrix.Row2).Length();

                    // set the position
                    worldMatrix.TranslationVector = transfoComp.WorldMatrix.TranslationVector;
                }

                // draw the sprite
                sprite3DBatch.Draw(texture, ref worldMatrix, ref sourceRegion, ref elementSize, ref color, sprite.Orientation, SwizzleMode.None, renderItem.Depth);
            }

            sprite3DBatch.End();
        }