コード例 #1
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var viewport = context.GraphicsDevice.Viewport;

            for (int i = fromIndex; i <= toIndex; i++)
            {
                var skybox = (SkyboxComponent)renderItems[i].DrawContext;

                // Setup the intensity
                skyboxEffect.Parameters.Set(SkyboxKeys.Intensity, skybox.Intensity);

                // Setup the rotation
                skyboxEffect.Parameters.Set(SkyboxKeys.SkyMatrix, Matrix.RotationQuaternion(skybox.Entity.Transform.Rotation));

                skyboxEffect.SetOutput(CurrentRenderFrame.RenderTargets);
                skyboxEffect.SetViewport(viewport);
                skyboxEffect.Draw();
            }

            // Make sure to fully restore the current render frame
            CurrentRenderFrame.Activate(context);

            // Restore the viewport: TODO: We should add a method to Push/Pop Target/Depth/Stencil/Viewport on the GraphicsDevice
            context.GraphicsDevice.SetViewport(viewport);
        }
コード例 #2
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var graphicsDevice = context.GraphicsDevice;
            var destination = new RectangleF(0, 0, 1, 1);

            spriteBatch.Begin(SpriteSortMode.FrontToBack, graphicsDevice.BlendStates.Opaque, graphicsDevice.SamplerStates.LinearClamp, graphicsDevice.DepthStencilStates.None);

            for(var i = fromIndex; i <= toIndex; ++i)
            {
                var background = (BackgroundComponent)renderItems[i].DrawContext;
                var texture = background.Texture;
                if (texture == null)
                    continue;
                
                var target = CurrentRenderFrame;

                var imageBufferMinRatio = Math.Min(texture.ViewWidth / (float)target.Width, texture.ViewHeight / (float)target.Height);
                var sourceSize = new Vector2(target.Width * imageBufferMinRatio, target.Height * imageBufferMinRatio);
                var source = new RectangleF((texture.ViewWidth - sourceSize.X) / 2, (texture.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);

                spriteBatch.Draw(texture, destination, source, Color.White, 0, Vector2.Zero);
            }

            spriteBatch.End();
        }
コード例 #3
0
 protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
 {
     if (lightComponentForwardRenderer != null)
     {
         lightComponentForwardRenderer.Draw(context);
     }
 }
コード例 #4
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var graphicsDevice = context.GraphicsDevice;
            var destination = new RectangleF(0, 0, 1, 1);

            // find the last background to display with valid texture
            BackgroundComponent background = null;
            for (var i = toIndex; i >= fromIndex; --i)
            {
                background = (BackgroundComponent)renderItems[i].DrawContext;
                if (background.Texture != null)
                    break;
            }

            // Abort if not valid background component
            if (background == null || background.Texture == null)
                return;

            var texture = background.Texture;
            var target = CurrentRenderFrame;
            var imageBufferMinRatio = Math.Min(texture.ViewWidth / (float)target.Width, texture.ViewHeight / (float)target.Height);
            var sourceSize = new Vector2(target.Width * imageBufferMinRatio, target.Height * imageBufferMinRatio);
            var source = new RectangleF((texture.ViewWidth - sourceSize.X) / 2, (texture.ViewHeight - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);

            spriteBatch.Parameters.Add(BackgroundEffectKeys.Intensity, background.Intensity);
            spriteBatch.Begin(SpriteSortMode.FrontToBack, graphicsDevice.BlendStates.Opaque, graphicsDevice.SamplerStates.LinearClamp, graphicsDevice.DepthStencilStates.None, null, backgroundEffect);
            spriteBatch.Draw(texture, destination, source, Color.White, 0, Vector2.Zero);
            spriteBatch.End();
        }
コード例 #5
0
        public ShadowMapRenderer(string effectName)
        {
            if (effectName == null)
            {
                throw new ArgumentNullException("effectName");
            }
            this.effectName            = effectName;
            atlases                    = new FastListStruct <ShadowMapAtlasTexture>(16);
            shadowMapTextures          = new PoolListStruct <LightShadowMapTexture>(16, CreateLightShadowMapTexture);
            LightComponentsWithShadows = new Dictionary <LightComponent, LightShadowMapTexture>(16);

            opaqueRenderItems      = new RenderItemCollection(512, false);
            transparentRenderItems = new RenderItemCollection(512, true);

            renderers = new Dictionary <Type, ILightShadowMapRenderer>();

            ShadowCamera = new CameraComponent {
                UseCustomViewMatrix = true, UseCustomProjectionMatrix = true
            };

            // Creates a model renderer for the shadows casters
            shadowModelComponentRenderer = new ModelComponentRenderer(effectName + ".ShadowMapCaster")
            {
                CullingMode = CullingMode.None,
                Callbacks   =
                {
                    UpdateMeshes = FilterCasters,
                }
            };

            shadowCasterParameters = new ParameterCollection();
            shadowCasterParameters.Set(ParadoxEffectBaseKeys.ExtensionPostVertexStageShader, ShadowMapCasterExtension);
        }
コード例 #6
0
 protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
 {
     if (lightComponentForwardRenderer != null)
     {
         lightComponentForwardRenderer.Draw(context);
     }
 }
コード例 #7
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            skyboxProcessor = SceneInstance.GetProcessor <SkyboxProcessor>();
            if (skyboxProcessor == null)
            {
                return;
            }

            var skybox = skyboxProcessor.ActiveSkyboxBackground;

            // do not draw if no active skybox or the skybox is not included in the current entity group
            if (skybox == null || !CurrentCullingMask.Contains(skybox.Entity.Group))
            {
                return;
            }

            // Copy camera/pass parameters
            context.Parameters.CopySharedTo(skyboxEffect.Parameters);

            // Show irradiance in the background
            if (skybox.Background == SkyboxBackground.Irradiance)
            {
                foreach (var parameterKeyValue in skybox.Skybox.DiffuseLightingParameters)
                {
                    if (parameterKeyValue.Key == SkyboxKeys.Shader)
                    {
                        skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                    }
                    else
                    {
                        skyboxEffect.Parameters.SetObject(parameterKeyValue.Key.ComposeWith("skyboxColor"), parameterKeyValue.Value);
                    }
                }
            }
            else
            {
                // TODO: Should we better use composition on "skyboxColor" for parameters?

                // Copy Skybox parameters
                if (skybox.Skybox != null)
                {
                    foreach (var parameterKeyValue in skybox.Skybox.Parameters)
                    {
                        if (parameterKeyValue.Key == SkyboxKeys.Shader)
                        {
                            skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                        }
                        else
                        {
                            skyboxEffect.Parameters.SetObject(parameterKeyValue.Key, parameterKeyValue.Value);
                        }
                    }
                }
            }

            // Fake as the skybox was in front of all others (as opaque are rendered back to front)
            opaqueList.Add(new RenderItem(this, skybox, float.NegativeInfinity));
        }
コード例 #8
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var cameraState = context.GetCurrentCamera();

            if (cameraState == null)
                return;

            UpdateParameters(context, cameraState);
        }
コード例 #9
0
 public void Draw(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
     if (Enabled)
     {
         PreDrawCoreInternal(context);
         DrawCore(context, renderItems, fromIndex, toIndex);
         PostDrawCoreInternal(context);
     }
 }
コード例 #10
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            skyboxProcessor = SceneInstance.GetProcessor<SkyboxProcessor>();
            if (skyboxProcessor == null)
            {
                return;
            }

            var skybox = skyboxProcessor.ActiveSkyboxBackground;

            // do not draw if no active skybox or the skybox is not included in the current entity group
            if (skybox == null || !CurrentCullingMask.Contains(skybox.Entity.Group))
                return;

            // Copy camera/pass parameters
            context.Parameters.CopySharedTo(skyboxEffect.Parameters);

            // Show irradiance in the background
            if (skybox.Background == SkyboxBackground.Irradiance)
            {
                foreach (var parameterKeyValue in skybox.Skybox.DiffuseLightingParameters)
                {
                    if (parameterKeyValue.Key == SkyboxKeys.Shader)
                    {
                        skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                    }
                    else
                    {
                        skyboxEffect.Parameters.SetObject(parameterKeyValue.Key.ComposeWith("skyboxColor"), parameterKeyValue.Value);
                    }
                }
            }
            else
            {
                // TODO: Should we better use composition on "skyboxColor" for parameters?

                // Copy Skybox parameters
                if (skybox.Skybox != null)
                {
                    foreach (var parameterKeyValue in skybox.Skybox.Parameters)
                    {
                        if (parameterKeyValue.Key == SkyboxKeys.Shader)
                        {
                            skyboxEffect.Parameters.Set(SkyboxKeys.Shader, (ShaderSource)parameterKeyValue.Value);
                        }
                        else
                        {
                            skyboxEffect.Parameters.SetObject(parameterKeyValue.Key, parameterKeyValue.Value);
                        }
                    }
                }
            }

            // Fake as the skybox was in front of all others (as opaque are rendered back to front)
            opaqueList.Add(new RenderItem(this, skybox, float.NegativeInfinity));
        }
コード例 #11
0
        public void Prepare(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            if (Context == null)
            {
                Initialize(context);
            }
            else if (Context != context)
            {
                throw new InvalidOperationException("Cannot use a different context between Load and Draw");
            }

            PrepareCore(context, opaqueList, transparentList);
        }
コード例 #12
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var backgroundProcessor = SceneInstance.GetProcessor<BackgroundComponentProcessor>();
            if (backgroundProcessor == null)
                return;

            foreach (var backgroundComponent in backgroundProcessor.Backgrounds)
            {
                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(backgroundComponent.Entity.Group))
                    continue;

                opaqueList.Add(new RenderItem(this, backgroundComponent, float.NegativeInfinity)); // render background first so that it can replace a clear frame
                return; // draw only one background by group
            }
        }
コード例 #13
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);
            var viewMat = viewParameters.Get(TransformationKeys.View);
            var projMat = viewParameters.Get(TransformationKeys.Projection);

            Matrix viewInv;

            Matrix.Invert(ref viewMat, out viewInv);

            for (var i = fromIndex; i <= toIndex; i++)
            {
                var renderItem              = renderItems[i];
                var particleSystemState     = (ParticleSystemProcessor.ParticleSystemComponentState)renderItem.DrawContext;
                var particleSystemComponent = particleSystemState.ParticleSystemComponent;

                particleSystemComponent.ParticleSystem.Draw(device, context, ref viewMat, ref projMat, ref viewInv, particleSystemComponent.Color);
            }

            // TODO Part of the renderer code is not thread safe - need to split the buffer building and the rendering to speed up the process

            /*
             * var itemCount = toIndex - fromIndex + 1; // Inclusive
             * var renderItemList = renderItems.GetRange(fromIndex, itemCount);
             *
             * TaskList.Dispatch(
             *  renderItemList,
             *  8,
             *  8,
             *  (i, renderItem) =>
             *  {
             *      var particleSystemState = (ParticleSystemProcessor.ParticleSystemComponentState)renderItem.DrawContext;
             *      var particleSystemComponent = particleSystemState.ParticleSystemComponent;
             *
             *      particleSystemComponent.ParticleSystem.Draw(device, context, ref viewMat, ref projMat, ref viewInv, particleSystemComponent.Color);
             *  }
             *  );
             * //*/
        }
コード例 #14
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var uiProcessor = SceneInstance.GetProcessor<UIComponentProcessor>();
            if (uiProcessor == null)
                return;

            foreach (var uiRoot in uiProcessor.UIRoots)
            {
                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(uiRoot.UIComponent.Entity.Group))
                    continue;

                // skips empty UI elements
                if(uiRoot.UIComponent.RootElement == null)
                    continue;

                // Project the position
                // TODO: This code is duplicated from SpriteComponent -> unify it at higher level?
                var worldPosition = new Vector4(uiRoot.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

                float projectedZ;
                if (uiRoot.UIComponent.IsFullScreen)
                {
                    projectedZ = -uiRoot.TransformComponent.WorldMatrix.M43;
                }
                else
                {
                    Vector4 projectedPosition;
                    var cameraComponent = context.Tags.Get(CameraComponentRenderer.Current);
                    if (cameraComponent == null)
                        continue;

                    Vector4.Transform(ref worldPosition, ref cameraComponent.ViewProjectionMatrix, out projectedPosition);
                    projectedZ = projectedPosition.Z / projectedPosition.W;
                }

                transparentList.Add(new RenderItem(this, uiRoot, projectedZ));
            }
        }
コード例 #15
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            // If no camera, early exit
            var camera = context.GetCurrentCamera();
            if (camera == null)
            {
                return;
            }

            // Copy the ViewProjectionMatrix from the camera as it is not automatically picked up by the ModelComponentRenderer
            modelRenderer.ViewProjectionMatrix = camera.ViewProjectionMatrix;
            var sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current);
            var cameraRenderMode = sceneCameraRenderer != null ? sceneCameraRenderer.Mode : null;

            if (cameraRenderMode != null)
            {
                modelRenderer.RasterizerState = cameraRenderMode.GetDefaultRasterizerState(false);
                modelRenderer.RasterizerStateForInvertedGeometry = cameraRenderMode.GetDefaultRasterizerState(true);
            }                   

            modelRenderer.Prepare(context, opaqueList, transparentList);
        }
コード例 #16
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            // Early out if particle system processor doesn't exist
            particleSystemProcessor = SceneInstance.GetProcessor <ParticleSystemProcessor>();
            if (particleSystemProcessor == null)
            {
                return;
            }

            // Early out if camera doesn't exist
            var camera = context.GetCurrentCamera();

            if (camera == null)
            {
                return;
            }

            var viewProjectionMatrix = camera.ViewProjectionMatrix;

            foreach (var particleSystemState in particleSystemProcessor.ParticleSystems)
            {
                // Perform culling on group and accept
                // TODO Should culling be performed on a per-sprite basis or batched?
                if (!CurrentCullingMask.Contains(particleSystemState.ParticleSystemComponent.Entity.Group))
                {
                    continue;
                }

                // Project the position to find depth for sorting
                var     worldPosition = new Vector4(particleSystemState.TransformComponent.WorldMatrix.TranslationVector, 1.0f);
                Vector4 projectedPosition;
                Vector4.Transform(ref worldPosition, ref viewProjectionMatrix, out projectedPosition);
                var projectedZ = projectedPosition.Z / projectedPosition.W;

                //var list = true ? transparentList : opaqueList;
                //list.Add(new RenderItem(this, particleSystemState, projectedZ));
                transparentList.Add(new RenderItem(this, particleSystemState, projectedZ));
            }
        }
コード例 #17
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            spriteProcessor = SceneInstance.GetProcessor<SpriteProcessor>();
            if (spriteProcessor == null)
            {
                return;
            }

            // If no camera, early exit
            var camera = context.GetCurrentCamera();
            if (camera == null)
            {
                return;
            }
            var viewProjectionMatrix = camera.ViewProjectionMatrix;

            foreach (var spriteState in spriteProcessor.Sprites)
            {
                var sprite = spriteState.SpriteComponent.CurrentSprite;
                if(sprite == null || sprite.Texture == null || sprite.Region.Width <= 0 || sprite.Region.Height <= 0f)
                    continue;

                // Perform culling on group and accept
                if (!CurrentCullingMask.Contains(spriteState.SpriteComponent.Entity.Group))
                    continue;

                // 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.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

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

                var list = sprite.IsTransparent ? transparentList : opaqueList;

                list.Add(new RenderItem(this, spriteState, projectedZ));
            }
        }
コード例 #18
0
        public void Prepare(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            if (!Enabled)
            {
                return;
            }

            if (Context == null)
            {
                Initialize(context);
            }
            else if (Context != context)
            {
                throw new InvalidOperationException("Cannot use a different context between Load and Draw");
            }

            if (SceneCameraRenderer != null)
            {
                CurrentCullingMask = SceneCameraRenderer.CullingMask;
            }

            PrepareCore(context, opaqueList, transparentList);
        }
コード例 #19
0
 protected abstract void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex);
コード例 #20
0
 protected abstract void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList);
コード例 #21
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();
        }
コード例 #22
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();
        }
コード例 #23
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 = new Color4(RuntimeIdHelper.ToRuntimeId(spriteComp));

                // 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, renderItem.Depth);
            }

            sprite3DBatch.End();
        }
コード例 #24
0
 protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
     modelRenderer.Draw(context, renderItems, fromIndex, toIndex);
 }
コード例 #25
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            // build the list of the UI elements to render
            uiElementStates.Clear();
            for (var i = fromIndex; i <= toIndex; ++i)
            {
                var renderItem = renderItems[i];
                uiElementStates.Add((UIComponentProcessor.UIComponentState)renderItem.DrawContext);
            }

            // evaluate the current draw time (game instance is null for thumbnails)
            var drawTime = game != null ? game.DrawTime : new GameTime();
            
            // update the rendering context
            renderingContext.Time = drawTime;
            renderingContext.RenderTarget = CurrentRenderFrame.RenderTargets[0]; // TODO: avoid hardcoded index 0

            // cache the ratio between viewport and target.
            var viewportSize = context.GraphicsDevice.Viewport.Size;
            viewportTargetRatio = new Vector2(viewportSize.X / renderingContext.RenderTarget.Width, viewportSize.Y / renderingContext.RenderTarget.Height);

            // compact all the pointer events that happened since last frame to avoid performing useless hit tests.
            CompactPointerEvents();

            // allocate temporary graphics resources if needed
            Texture scopedDepthBuffer = null;
            foreach (var uiElement in uiElementStates)
            {
                if (uiElement.UIComponent.IsFullScreen)
                {
                    var renderTarget = renderingContext.RenderTarget;
                    var description = TextureDescription.New2D(renderTarget.Width, renderTarget.Height, PixelFormat.D24_UNorm_S8_UInt, TextureFlags.DepthStencil);
                    scopedDepthBuffer = PushScopedResource(context.Allocator.GetTemporaryTexture(description));
                    break;
                }
            }
            
            // render the UI elements of all the entities
            foreach (var uiElementState in uiElementStates)
            {
                var uiComponent = uiElementState.UIComponent;
                var rootElement = uiComponent.RootElement;
                if (rootElement == null)
                    continue;

                var updatableRootElement = (IUIElementUpdate)rootElement;

                // calculate the size of the virtual resolution depending on target size (UI canvas)
                var virtualResolution = uiComponent.VirtualResolution;
                var targetSize = new Vector2(renderingContext.RenderTarget.Width, renderingContext.RenderTarget.Height);
                if (uiComponent.IsFullScreen)
                {
                    // update the virtual resolution of the renderer
                    if (uiComponent.VirtualResolutionMode == VirtualResolutionMode.FixedWidthAdaptableHeight)
                        virtualResolution.Y = virtualResolution.X * targetSize.Y / targetSize.X;
                    if (uiComponent.VirtualResolutionMode == VirtualResolutionMode.FixedHeightAdaptableWidth)
                        virtualResolution.X = virtualResolution.Y * targetSize.X / targetSize.Y;
                }
                
                // Update the view parameters
                if (uiComponent.IsFullScreen)
                {
                    viewParameters.Update(uiComponent.Entity, virtualResolution);
                }
                else
                {
                    var cameraComponent = context.Tags.Get(CameraComponentRenderer.Current);
                    viewParameters.Update(uiComponent.Entity, cameraComponent);
                }
                
                // Analyze the input and trigger the UI element touch and key events
                // Note: this is done before measuring/arranging/drawing the element in order to avoid one frame latency on clicks.
                //       But by doing so the world matrices taken for hit test are the ones calculated during last frame.
                using (Profiler.Begin(UIProfilerKeys.TouchEventsUpdate))
                {
                    foreach (var uiState in uiElementStates)
                    {
                        if (uiState.UIComponent.RootElement == null)
                            continue;

                        UpdateMouseOver(uiState);
                        UpdateTouchEvents(uiState, drawTime);
                    }
                }

                // update the rendering context values specific to this element
                renderingContext.Resolution = virtualResolution;
                renderingContext.ViewMatrix = viewParameters.ViewMatrix;
                renderingContext.ProjectionMatrix = viewParameters.ProjectionMatrix;
                renderingContext.ViewProjectionMatrix = viewParameters.ViewProjectionMatrix;
                renderingContext.DepthStencilBuffer = uiComponent.IsFullScreen ? scopedDepthBuffer : CurrentRenderFrame.DepthStencil;
                renderingContext.ShouldSnapText = uiComponent.SnapText;

                // calculate an estimate of the UI real size by projecting the element virtual resolution on the screen
                var virtualOrigin = viewParameters.ViewProjectionMatrix.Row4;
                var virtualWidth = new Vector4(virtualResolution.X/2, 0, 0, 1);
                var virtualHeight = new Vector4(0, virtualResolution.Y / 2, 0, 1);
                var transformedVirtualWidth = Vector4.Zero; 
                var transformedVirtualHeight = Vector4.Zero;
                for (int i = 0; i < 4; i++)
                {
                    transformedVirtualWidth[i] = virtualWidth[0] * viewParameters.ViewProjectionMatrix[0 + i] + viewParameters.ViewProjectionMatrix[12 + i];
                    transformedVirtualHeight[i] = virtualHeight[1] * viewParameters.ViewProjectionMatrix[4 + i] + viewParameters.ViewProjectionMatrix[12 + i];
                }
                var projectedOrigin = virtualOrigin.XY() / virtualOrigin.W;
                var projectedVirtualWidth = viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin);
                var projectedVirtualHeight = viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin);
                
                // update layouting context.
                layoutingContext.VirtualResolution = virtualResolution;
                layoutingContext.RealResolution = viewportSize;
                layoutingContext.RealVirtualResolutionRatio = new Vector2(projectedVirtualWidth.Length() / virtualResolution.X, projectedVirtualHeight.Length() / virtualResolution.Y);
                rootElement.LayoutingContext = layoutingContext;

                // perform the time-based updates of the UI element
                updatableRootElement.Update(drawTime);

                // update the UI element disposition
                rootElement.Measure(virtualResolution);
                rootElement.Arrange(virtualResolution, false);

                // update the UI element hierarchical properties
                var rootMatrix = Matrix.Translation(-virtualResolution / 2); // UI world is rotated of 180degrees along Ox
                updatableRootElement.UpdateWorldMatrix(ref rootMatrix, rootMatrix != uiElementState.LastRootMatrix);
                updatableRootElement.UpdateElementState(0);
                uiElementState.LastRootMatrix = rootMatrix;

                // clear and set the Depth buffer as required
                if (uiComponent.IsFullScreen)
                {
                    context.GraphicsDevice.Clear(renderingContext.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil);
                }
                context.GraphicsDevice.SetDepthAndRenderTarget(renderingContext.DepthStencilBuffer, renderingContext.RenderTarget);

                // start the image draw session
                renderingContext.StencilTestReferenceValue = 0;
                batch.Begin(ref viewParameters.ViewProjectionMatrix, context.GraphicsDevice.BlendStates.AlphaBlend, uiSystem.KeepStencilValueState, renderingContext.StencilTestReferenceValue);

                // Render the UI elements in the final render target
                ReccursiveDrawWithClipping(context, rootElement);

                // end the image draw session
                batch.End();
            }

            // clear the list of compacted pointer events of time frame
            ClearPointerEvents();

            // revert the depth stencil buffer to the default value 
            context.GraphicsDevice.SetDepthAndRenderTargets(CurrentRenderFrame.DepthStencil, CurrentRenderFrame.RenderTargets);
        }
コード例 #26
0
        private void PrepareRenderMeshes(RenderModel renderModel, List<Mesh> meshes, ref FastListStruct<RenderMesh> renderMeshes, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            // Add new render meshes
            for (int i = renderMeshes.Count; i < meshes.Count; i++)
            {
                var renderMesh = new RenderMesh(renderModel, meshes[i]);
                renderMeshes.Add(renderMesh);
            }

            // Create the bounding frustum locally on the stack, so that frustum.Contains is performed with boundingBox that is also on the stack
            var frustum = new BoundingFrustum(ref ViewProjectionMatrix);

            for (int i = 0; i < renderMeshes.Count; i++)
            {
                var renderMesh = renderMeshes[i];
                // Update the model hierarchy
                var modelViewHierarchy = renderModel.ModelComponent.ModelViewHierarchy;
                modelViewHierarchy.UpdateRenderMesh(renderMesh);

                if (!renderMesh.Enabled)
                {
                    continue;
                }

                // Upload skinning blend matrices
                BoundingBoxExt boundingBox;
                skinningUpdater.Update(modelViewHierarchy, renderMesh, out boundingBox);

                // Fast AABB transform: http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
                // Compute transformed AABB (by world)
                // TODO: CullingMode should be pluggable
                // TODO: This should not be necessary. Add proper bounding boxes to gizmos etc.
                if (CullingMode == CullingMode.Frustum && boundingBox.Extent != Vector3.Zero && !frustum.Contains(ref boundingBox))
                {
                    continue;
                }

                // 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(renderMesh.WorldMatrix.TranslationVector, 1.0f);
                Vector4 projectedPosition;
                Vector4.Transform(ref worldPosition, ref ViewProjectionMatrix, out projectedPosition);
                var projectedZ = projectedPosition.Z / projectedPosition.W;

                renderMesh.RasterizerState = renderMesh.IsGeometryInverted ? RasterizerStateForInvertedGeometry : RasterizerState;

                renderMesh.UpdateMaterial();

                var list = renderMesh.HasTransparency ? transparentList : opaqueList;
                list.Add(new RenderItem(this, renderMesh, projectedZ));
            }
        }
コード例 #27
0
        private void PrepareModels(RenderContext context, List<RenderModel> renderModels, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            var preRenderModel = Callbacks.PreRenderModel;

            foreach (var renderModel in renderModels)
            {
                var modelComponent = renderModel.ModelComponent;
                var meshes = modelComponent.Model.Meshes;
                int meshCount = meshes.Count;
                if (meshCount == 0)
                {
                    continue;
                }

                if (preRenderModel != null && !preRenderModel(context, renderModel))
                {
                    continue;
                }

                // Always prepare the slot for the render meshes even if they are not used.
                for (int i = renderModel.RenderMeshesPerEffectSlot.Count; i <= modelRenderSlot; i++)
                {
                    renderModel.RenderMeshesPerEffectSlot.Add(new FastListStruct<RenderMesh>(meshCount));
                }

                PrepareRenderMeshes(renderModel, meshes, ref renderModel.RenderMeshesPerEffectSlot.Items[modelRenderSlot], opaqueList, transparentList);
            }
        }
コード例 #28
0
ファイル: RenderList.cs プロジェクト: ybwsfl/OpenSAGE
 public RenderBucket()
 {
     RenderItems = new RenderItemCollection();
 }
コード例 #29
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            spriteProcessor = SceneInstance.GetProcessor <SpriteStudioProcessor>();
            if (spriteProcessor == null)
            {
                return;
            }

            // If no camera, early exit
            var camera = context.GetCurrentCamera();

            if (camera == null)
            {
                return;
            }
            var viewProjectionMatrix = camera.ViewProjectionMatrix;

            foreach (var spriteState in spriteProcessor.Sprites)
            {
                var worldMatrix = spriteState.TransformComponent.WorldMatrix;

                var worldPosition = new Vector4(worldMatrix.TranslationVector, 1.0f);

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

                transparentList.Add(new RenderItem(this, spriteState, projectedZ));

                //for (var index = 0; index < ssSheet.Sheet.NodesInfo.Count; index++)
                //{
                //    var node = ssSheet.Sheet.NodesInfo[index];
                //    var sprite = ssSheet.Sheet.SpriteSheet.Sprites[index];

                //    if (sprite?.Texture == null || sprite.Region.Width <= 0 || sprite.Region.Height <= 0f)
                //        continue;

                //    // Perform culling on group and accept
                //    if (!CurrentCullingMask.Contains(spriteState.SpriteStudioComponent.Entity.Group))
                //        continue;

                //    var worldMatrix = node.WorldTransform * spriteState.TransformComponent.WorldMatrix;

                //    // 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(worldMatrix.TranslationVector, 1.0f);

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

                //    var list = sprite.IsTransparent ? transparentList : opaqueList;

                //    list.Add(new RenderItem(this, new SpriteItem
                //    {
                //        Sprite = sprite,
                //        Data = spriteState,
                //        Node = node
                //    }, projectedZ));
                //}
            }
        }
コード例 #30
0
        protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
        {
            spriteProcessor = SceneInstance.GetProcessor<SpriteStudioProcessor>();
            if (spriteProcessor == null)
            {
                return;
            }

            // If no camera, early exit
            var camera = context.GetCurrentCamera();
            if (camera == null)
            {
                return;
            }
            var viewProjectionMatrix = camera.ViewProjectionMatrix;

            foreach (var spriteState in spriteProcessor.Sprites)
            {
                var worldMatrix = spriteState.TransformComponent.WorldMatrix;

                var worldPosition = new Vector4(worldMatrix.TranslationVector, 1.0f);

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

                transparentList.Add(new RenderItem(this, spriteState, projectedZ));

                //for (var index = 0; index < ssSheet.Sheet.NodesInfo.Count; index++)
                //{
                //    var node = ssSheet.Sheet.NodesInfo[index];
                //    var sprite = ssSheet.Sheet.SpriteSheet.Sprites[index];

                //    if (sprite?.Texture == null || sprite.Region.Width <= 0 || sprite.Region.Height <= 0f)
                //        continue;

                //    // Perform culling on group and accept
                //    if (!CurrentCullingMask.Contains(spriteState.SpriteStudioComponent.Entity.Group))
                //        continue;

                //    var worldMatrix = node.WorldTransform * spriteState.TransformComponent.WorldMatrix;

                //    // 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(worldMatrix.TranslationVector, 1.0f);

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

                //    var list = sprite.IsTransparent ? transparentList : opaqueList;

                //    list.Add(new RenderItem(this, new SpriteItem
                //    {
                //        Sprite = sprite,
                //        Data = spriteState,
                //        Node = node
                //    }, projectedZ));
                //}
            }
        }
コード例 #31
0
 protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
 }
コード例 #32
0
 protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
 {
     modelRenderer.Prepare(context, opaqueList, transparentList);
 }
コード例 #33
0
 protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
     // Nothing to draw for this camera
 }
コード例 #34
0
 protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
 {
 }
コード例 #35
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItems, int fromIndex, int toIndex)
        {
            var viewport = context.GraphicsDevice.Viewport;

            for (int i = fromIndex; i <= toIndex; i++)
            {
                var skybox = (SkyboxComponent)renderItems[i].DrawContext;

                // Setup the intensity
                skyboxEffect.Parameters.Set(SkyboxKeys.Intensity, skybox.Intensity);

                // Setup the rotation
                skyboxEffect.Parameters.Set(SkyboxKeys.SkyMatrix, Matrix.RotationQuaternion(skybox.Entity.Transform.Rotation));

                skyboxEffect.SetOutput(CurrentRenderFrame.RenderTargets);
                skyboxEffect.SetViewport(viewport);
                skyboxEffect.Draw();
            }

            // Make sure to fully restore the current render frame
            CurrentRenderFrame.Activate(context);

            // Restore the viewport: TODO: We should add a method to Push/Pop Target/Depth/Stencil/Viewport on the GraphicsDevice
            context.GraphicsDevice.SetViewport(viewport);
        }
コード例 #36
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();
        }
コード例 #37
0
ファイル: RenderList.cs プロジェクト: OpenSAGE/OpenSAGE
 public RenderBucket(string name)
 {
     RenderItemName = name;
     RenderItems    = new RenderItemCollection();
 }
コード例 #38
0
 protected override void PrepareCore(RenderContext context, RenderItemCollection opaqueList, RenderItemCollection transparentList)
 {
     // If there is a list of models to render, use this list directly
     if (RenderModels != null)
     {
         PrepareModels(context, RenderModels, opaqueList, transparentList);
     }
     else
     {
         // Otherwise, use the models from the ModelProcessor
         var modelProcessor = SceneInstance.GetProcessor<ModelProcessor>();
         renderModelCollections.Clear();
         modelProcessor.QueryModelGroupsByMask(CurrentCullingMask, renderModelCollections);
         foreach (var renderModelGroup in renderModelCollections)
         {
             PrepareModels(context, renderModelGroup, opaqueList, transparentList);
         }
     }
 }
コード例 #39
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItemList, int fromIndex, int toIndex)
        {
            if (dynamicEffectCompiler == null)
            {
                throw new InvalidOperationException("This instance is not correctly initialized (no EffectName)");
            }

            // Get all meshes from render models
            meshesToRender.Clear();
            for(int i = fromIndex; i <= toIndex; i++)
            {
                meshesToRender.Add((RenderMesh)renderItemList[i].DrawContext);
            }

            // Slow path there is a callback
            if (Callbacks.UpdateMeshes != null)
            {
                Callbacks.UpdateMeshes(context, ref meshesToRender);
            }

            // Fetch callback on PreRenderGroup
            var preRenderMesh = Callbacks.PreRenderMesh;

            for (int i = 0; i < meshesToRender.Count; i++)
            {
                var renderMesh = meshesToRender[i];

                // If the EntityGroup is changing, call the callback to allow to plug specific parameters for this group
                if (preRenderMesh != null)
                {
                    preRenderMesh(context, renderMesh);
                }

                // Update Effect and mesh
                UpdateEffect(context, renderMesh, context.Parameters);

                // Draw the mesh
                renderMesh.Draw(context);
            }
        }