Example #1
0
        public RenderBatch(GraphicsDevice device, int primitivesPerBatch, bool enableAlphaBlend)
        {
            this.device = device;
            if (enableAlphaBlend)
            {
                BasicEffect be = new BasicEffect(device);
                Effect                = be;
                fxMatrices            = be;
                be.TextureEnabled     = true;
                be.VertexColorEnabled = true;
                be.LightingEnabled    = false;
                fxParamTexture        = Effect.Parameters["Texture"];
            }
            else
            {
                AlphaTestEffect ate = new AlphaTestEffect(device);
                Effect                 = ate;
                fxMatrices             = ate;
                ate.VertexColorEnabled = true;
                ate.ReferenceAlpha     = 128;
                fxParamTexture         = Effect.Parameters["Texture"];
            }

            this.maxPrimitivesPerBatch = primitivesPerBatch;
        }
Example #2
0
        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            int count = this.bones.Count;

            if (Model.sharedDrawBoneMatrices == null || Model.sharedDrawBoneMatrices.Length < count)
            {
                Model.sharedDrawBoneMatrices = new Matrix[count];
            }
            this.CopyAbsoluteBoneTransformsTo(Model.sharedDrawBoneMatrices);
            foreach (ModelMesh modelMesh in (ReadOnlyCollection <ModelMesh>) this.Meshes)
            {
                foreach (Effect effect in modelMesh.Effects)
                {
                    IEffectMatrices effectMatrices = effect as IEffectMatrices;
                    if (effectMatrices == null)
                    {
                        throw new InvalidOperationException();
                    }
                    effectMatrices.World      = Model.sharedDrawBoneMatrices[modelMesh.ParentBone.Index] * world;
                    effectMatrices.View       = view;
                    effectMatrices.Projection = projection;
                }
                modelMesh.Draw();
            }
        }
Example #3
0
        private void DrawAllModels(IEffectMatrices effect)
        {
            foreach (var entity in ActiveEntities)
            {
                if (_modelMapper.Has(entity))
                {
                    var model     = _modelMapper.Get(entity).Model;
                    var transform = _transformMapper.Get(entity);

                    if (model.VertexBuffer != null && model.IndexBuffer != null & model.PrimitiveCount != 0)
                    {
                        var sphere = BoundingSphere.CreateFromBoundingBox(model.BoundingBox);

                        if (CameraSystem.ActiveLens.BoundingFrustum.Intersects(sphere.Transform(transform.WorldMatrix)))
                        {
                            effect.World = transform.WorldMatrix;
                            DrawMesh((Effect)effect, model, _graphicsDevice);
                        }
                    }
                }
                else if (_primitiveMapper.Has(entity))
                {
                    var primitive = _primitiveMapper.Get(entity);
                    var transform = _transformMapper.Get(entity);

                    effect.World = transform.WorldMatrix;
                    Primitives.Instance.Draw((Effect)effect, primitive.Type);
                }
            }
        }
Example #4
0
        public RenderBatch(GraphicsDevice device, int primitivesPerBatch, bool enableAlphaBlend)
        {
            this.device = device;
            if (enableAlphaBlend)
            {
                BasicEffect be = new BasicEffect(device);
                Effect = be;
                fxMatrices = be;
                be.TextureEnabled = true;
                be.VertexColorEnabled = true;
                be.LightingEnabled = false;
                fxParamTexture = Effect.Parameters["Texture"];
            }
            else
            {
                AlphaTestEffect ate = new AlphaTestEffect(device);
                Effect = ate;
                fxMatrices = ate;
                ate.VertexColorEnabled = true;
                ate.ReferenceAlpha = 128;
                fxParamTexture = Effect.Parameters["Texture"];
            }

            this.maxPrimitivesPerBatch = primitivesPerBatch;
        }
Example #5
0
        /// <summary>
        /// Draws the model meshes.
        /// </summary>
        /// <param name="world">The world transform.</param>
        /// <param name="view">The view transform.</param>
        /// <param name="projection">The projection transform.</param>
        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            int boneCount = this.Bones.Count;

            if (sharedDrawBoneMatrices == null ||
                sharedDrawBoneMatrices.Length < boneCount)
            {
                sharedDrawBoneMatrices = new Matrix[boneCount];
            }

            // Look up combined bone matrices for the entire model.
            CopyAbsoluteBoneTransformsTo(sharedDrawBoneMatrices);

            // Draw the model.
            foreach (ModelMesh mesh in Meshes)
            {
                foreach (Effect effect in mesh.Effects)
                {
                    IEffectMatrices effectMatricies = effect as IEffectMatrices;
                    if (effectMatricies == null)
                    {
                        throw new InvalidOperationException();
                    }
                    effectMatricies.World      = sharedDrawBoneMatrices[mesh.ParentBone.Index] * world;
                    effectMatricies.View       = view;
                    effectMatricies.Projection = projection;
                }

                mesh.Draw();
            }
        }
Example #6
0
        public override void Update(BaseCamera camera, ref Matrix world)
        {
            // Matrices
            IEffectMatrices effectMatrices = (IEffectMatrices)_effect;

            effectMatrices.World      = world;
            effectMatrices.View       = camera.View;
            effectMatrices.Projection = camera.Projection;
        }
Example #7
0
        /// <summary>
        /// Applies this camera to the specified effect.
        /// </summary>
        /// <param name="effect">The effect to apply this camera to.</param>
        public void ApplyTo(IEffectMatrices effectMatrices)
        {
            if (_isDirty)
            {
                Recalculate();
            }

            effectMatrices.View       = _view;
            effectMatrices.Projection = _projection;
        }
Example #8
0
        internal static void SetViewport(this IEffectMatrices effect, Rectangle viewport)
        {
            if (effect != null)
            {
                Matrix projection      = Matrix.CreateOrthographicOffCenter(viewport.Left, viewport.Right, viewport.Bottom, viewport.Top, 0, 1);
                Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

                effect.World      = Matrix.Identity;
                effect.View       = Matrix.Identity;
                effect.Projection = halfPixelOffset * projection;
            }
        }
Example #9
0
        public static Vector2 GetOrtho(Vector3 v3)
        {
            Vector2         output = Vector2.Zero;
            IEffectMatrices eff    = View.basicEffect;
            Matrix          worldViewProjection = eff.World * eff.View * eff.Projection;
            Vector4         result = Vector4.Transform(v3, worldViewProjection);

            result /= result.W;
            Viewport vp        = Program.MainView.graphics.GraphicsDevice.Viewport;
            Matrix   invClient = Matrix.Invert(Matrix.CreateOrthographicOffCenter(0, vp.Width, vp.Height, 0, -1, 1));

            output = Vector2.Transform(new Vector2(result.X, result.Y), invClient);
            return(output);
        }
Example #10
0
        public override void Draw(GameTime gameTime)
        {
            if (_terrainModel.Effect is IEffectMatrices)
            {
                IEffectMatrices effectMatrices = (IEffectMatrices)_terrainModel.Effect;
                effectMatrices.World      = Matrix.Identity;
                effectMatrices.View       = _camera.View;
                effectMatrices.Projection = _camera.Projection;
            }

            /*GraphicsDevice.RasterizerState = new RasterizerState
             * {
             *      FillMode = FillMode.WireFrame
             * };*/


            _terrainModel.Draw();
        }
Example #11
0
        /// <summary>
        /// Normal Drawn Function.
        /// </summary>
        /// <param name="gt">The gt.</param>
        /// <param name="obj">The obj.</param>
        /// <param name="cam">The cam.</param>
        /// <param name="lights">The lights.</param>
        /// <param name="render">The render.</param>
        public void Drawn(GameTime gt, PloobsEngine.SceneControl.IObject obj, PloobsEngine.Cameras.ICamera cam, System.Collections.Generic.IList <PloobsEngine.Light.ILight> lights, PloobsEngine.SceneControl.RenderHelper render)
        {
            if (first)
            {
                _terrainModel.Initialize(cam, render.device);
                first = false;
            }

            if (_terrainModel.Effect is IEffectMatrices)
            {
                IEffectMatrices effectMatrices = (IEffectMatrices)_terrainModel.Effect;
                effectMatrices.World      = obj.WorldMatrix;
                effectMatrices.View       = cam.View;
                effectMatrices.Projection = cam.Projection;
            }

            render.SetSamplerStates(SamplerState.LinearWrap, 6);
            _terrainModel.Draw();
            render.SetSamplerStates(ginfo.SamplerState, 6);
        }
Example #12
0
 public void Draw(Matrix world, Matrix view, Matrix projection)
 {
     Matrix[] destinationBoneTransforms = new Matrix[this.bones.Count];
     this.CopyAbsoluteBoneTransformsTo(destinationBoneTransforms);
     foreach (ModelMesh modelMesh in (ReadOnlyCollection <ModelMesh>) this.Meshes)
     {
         foreach (Effect effect in modelMesh.Effects)
         {
             IEffectMatrices effectMatrices = effect as IEffectMatrices;
             if (effectMatrices == null)
             {
                 throw new InvalidOperationException();
             }
             effectMatrices.World      = destinationBoneTransforms[modelMesh.ParentBone.Index] * world;
             effectMatrices.View       = view;
             effectMatrices.Projection = projection;
         }
         modelMesh.Draw();
     }
 }
Example #13
0
        public override void Draw(GraphicsDevice graphicsDevice, Matrix cameraRotation, Matrix view, Matrix projection)
        {
            Viewport savedViewport = graphicsDevice.Viewport;

            graphicsDevice.Viewport = new Viewport(
                graphicsDevice.Viewport.Width - _size,
                0, _size, _size);

            graphicsDevice.DepthStencilState = DepthStencilState.None;
            graphicsDevice.BlendState        = BlendState.AlphaBlend;
            graphicsDevice.RasterizerState   = new RasterizerState
            {
                FillMode = FillMode.Solid
            };

            if (_effect is IEffectMatrices)
            {
                IEffectMatrices effectMatrices = (IEffectMatrices)_effect;
                effectMatrices.World = cameraRotation;
            }

            if (_effect is BasicEffect)
            {
                ((BasicEffect)_effect).Alpha = _isCubeActive ? 1.0f : 0.7f;                  // TODO: Make non-hover alpha configurable.
            }

            graphicsDevice.Indices = _cubeIndices;
            graphicsDevice.SetVertexBuffer(_cubeVertices);
            foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                                                     _cubeVertices.VertexCount, 0, _cubeIndices.IndexCount / 3);
            }

            graphicsDevice.Indices  = null;
            graphicsDevice.Viewport = savedViewport;

            graphicsDevice.BlendState        = BlendState.Opaque;
            graphicsDevice.DepthStencilState = DepthStencilState.Default;
        }
Example #14
0
        public override void Draw(GraphicsDevice graphicsDevice, Matrix cameraRotation, Matrix view, Matrix projection)
        {
            if (!_options.ShowGrid)
            {
                return;
            }

            if (_lineEffect is IEffectMatrices)
            {
                IEffectMatrices effectMatrices = (IEffectMatrices)_lineEffect;
                effectMatrices.World      = Matrix.Identity;
                effectMatrices.View       = view;
                effectMatrices.Projection = projection;
            }

            graphicsDevice.SetVertexBuffer(_lineBuffer);
            foreach (EffectPass pass in _lineEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                graphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0,
                                              _lineBuffer.VertexCount / 2);
            }
        }
Example #15
0
        public virtual void Apply()
        {
            GraphicsDevice.BlendState        = this.BlendState;
            GraphicsDevice.DepthStencilState = this.DepthStencilState;
            GraphicsDevice.RasterizerState   = this.RasterizerState;
            for (int i = 0; i < NumberOfTextures; i++)
            {
                if (this.SamplerStates[i] != null)
                {
                    GraphicsDevice.SamplerStates[i] = this.SamplerStates[i];
                }
            }

            IEffectMatrices effectMatrices = _effect as IEffectMatrices;

            if (effectMatrices != null)
            {
                effectMatrices.World      = this.World;
                effectMatrices.View       = this.View;
                effectMatrices.Projection = this.Projection;
            }

            _effect.CurrentTechnique.Passes[0].Apply();
        }
        /// <summary>
        /// Draws the model using the specified camera matrices and the default
        /// lighting model.
        /// </summary>
        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            foreach (var part in modelParts)
            {
                // use the new effect interfaces so this code will still work
                // even if someone changes the effect on the part to a new type.

                IEffectMatrices matrices = part.Effect as IEffectMatrices;
                if (matrices != null)
                {
                    matrices.World      = world;
                    matrices.View       = view;
                    matrices.Projection = projection;
                }

                IEffectLights lights = part.Effect as IEffectLights;
                if (lights != null)
                {
                    lights.EnableDefaultLighting();
                }

                part.Draw();
            }
        }
Example #17
0
        /// <summary>
        /// Simple model drawing method. The interesting part here is that
        /// the view and projection matrices are taken from the camera object.
        /// </summary>
        private void DrawModel(Model model, Matrix world)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (Effect effect in mesh.Effects)
                {
                    if (effect is BasicEffect)
                    {
                        ((BasicEffect)effect).EnableDefaultLighting();
                    }
                    if (effect is IEffectMatrices)
                    {
                        IEffectMatrices effectMatrices = (IEffectMatrices)effect;
                        effectMatrices.World      = transforms[mesh.ParentBone.Index] * world;
                        effectMatrices.View       = camera.View;
                        effectMatrices.Projection = camera.Projection;
                    }
                }
                mesh.Draw();
            }
        }
Example #18
0
 public static void Apply(IEffectMatrices effect)
 {
     effect.View       = MainCamera.ViewMatrix;
     effect.Projection = MainCamera.ProjectionMatrix;
 }
Example #19
0
 public void SetEffect <TEffect>(TEffect effect)
     where TEffect : Effect, IEffectMatrices
 {
     Effect         = effect;
     EffectMatrices = effect;
 }
Example #20
0
        private void DrawMesh(ModelMesh mesh, bool opaque, Matrix world, Matrix view, Matrix projection, Vector3?color)
        {
            int count = mesh.MeshParts.Count;

            for (int i = 0; i < count; i++)
            {
                ModelMeshPart part   = mesh.MeshParts[i];
                Effect        effect = part.Effect;

                Vector3     diffuseColor = Vector3.One;
                bool        textureEnabled = false, lightingEnabled = false, vertexColorEnabled = false;
                float       alpha       = 1.0f;
                BasicEffect basicEffect = effect as BasicEffect;
                if (basicEffect != null)
                {
                    if (basicEffect.Alpha < 1.0f && opaque)
                    {
                        continue;
                    }
                    if (basicEffect.Alpha == 1.0f && !opaque)
                    {
                        continue;
                    }

                    basicEffect.PreferPerPixelLighting = true;
                    basicEffect.SpecularPower          = 16;

                    if (color != null)
                    {
                        diffuseColor       = basicEffect.DiffuseColor;
                        textureEnabled     = basicEffect.TextureEnabled;
                        lightingEnabled    = basicEffect.LightingEnabled;
                        vertexColorEnabled = basicEffect.VertexColorEnabled;
                        alpha = basicEffect.Alpha;

                        basicEffect.DiffuseColor       = color.Value;
                        basicEffect.TextureEnabled     = false;
                        basicEffect.LightingEnabled    = false;
                        basicEffect.VertexColorEnabled = false;
                        basicEffect.Alpha = _options.SolidAndWireframeAlpha;
                    }
                }

                IEffectMatrices effectMatrices = effect as IEffectMatrices;
                if (effectMatrices != null)
                {
                    effectMatrices.World      = _boneTransforms[mesh.ParentBone.Index] * world;
                    effectMatrices.View       = view;
                    effectMatrices.Projection = projection;
                }
                else
                {
                    EffectParameter wvp = effect.Parameters.GetParameterBySemantic("WORLDVIEWPROJECTION");
                    if (wvp != null)
                    {
                        wvp.SetValue(_boneTransforms[mesh.ParentBone.Index] * world * view * projection);
                    }

                    EffectParameter w = effect.Parameters.GetParameterBySemantic("WORLD");
                    if (w != null)
                    {
                        w.SetValue(_boneTransforms[mesh.ParentBone.Index] * world);
                    }

                    EffectParameter v = effect.Parameters.GetParameterBySemantic("VIEW");
                    if (v != null)
                    {
                        v.SetValue(view);
                    }

                    EffectParameter p = effect.Parameters.GetParameterBySemantic("PROJECTION");
                    if (p != null)
                    {
                        p.SetValue(projection);
                    }
                }

                IEffectLights effectLights = effect as IEffectLights;
                if (effectLights != null)
                {
                    effectLights.EnableDefaultLighting();
                }

                int passes = effect.CurrentTechnique.Passes.Count;
                for (int j = 0; j < passes; j++)
                {
                    effect.CurrentTechnique.Passes[j].Apply();
                    DrawMeshPart(part);
                }

                if (basicEffect != null && color != null)
                {
                    basicEffect.DiffuseColor       = diffuseColor;
                    basicEffect.Alpha              = alpha;
                    basicEffect.TextureEnabled     = textureEnabled;
                    basicEffect.LightingEnabled    = lightingEnabled;
                    basicEffect.VertexColorEnabled = vertexColorEnabled;
                }
            }
        }
Example #21
0
 private void ConfigureEffectMatrices(IEffectMatrices effect, Matrix world, Matrix view, Matrix projection)
 {
     effect.World      = world;
     effect.View       = view;
     effect.Projection = projection;
 }
Example #22
0
 public void Apply(IEffectMatrices effect)
 {
     effect.View = View;
 }
Example #23
0
 public void SetEffect(Effect effect)
 {
     Effect         = effect;
     EffectMatrices = null;
 }
Example #24
0
 private void SetCamera(IEffectMatrices effect)
 {
     effect.View = Matrix.CreateLookAt(new Vector3(0, 1, 6), new Vector3(0, 1, 0), Vector3.Up);
     effect.Projection = Matrix.CreatePerspective(AspectRatio, 1, 2, 20);
 }
Example #25
0
 private void SetCamera(IEffectMatrices effect)
 {
     //from beats 37 to 40, after chessboard fades, camera altitude and target lerp to 0
     var cameraY = MathHelper.SmoothStep(1, 0, (Beat - 37) / 3F);
     effect.View = Matrix.CreateLookAt(new Vector3(0, cameraY, 8F), new Vector3(0, cameraY, 0), Vector3.Up);
     effect.Projection = Matrix.CreatePerspective(AspectRatio, 1, 3F, 100);
 }
Example #26
0
        /// <summary>
        /// Applies this camera to the specified effect.
        /// </summary>
        /// <param name="effect">The effect to apply this camera to.</param>
        public void ApplyTo(IEffectMatrices effectMatrices)
        {
            if (_isDirty)
                Recalculate();

            effectMatrices.View = _view;
            effectMatrices.Projection = _projection;
        }
        /// <summary>
        /// Draw the model using no instancing method
        /// </summary>
        /// <param name="view">View matrix of the active camera.</param>
        /// <param name="projection">Projection matrix of the active camera.</param>
        /// <param name="individualTransformations">Individual transforms of the meshes.</param>
        /// <param name="customEffect">Custom effect to be applied to the model.</param>
        private void DrawModelNoInstancing(Matrix view, Matrix projection,
                                           Dictionary <string, Matrix> individualTransformations, Effect customEffect)
        {
            Matrix baseWorld = GetWorldMatrix();

            foreach (ModelMesh mesh in _model.Model.Meshes)
            {
                Matrix localWorld = ModelTransforms[mesh.ParentBone.Index] * baseWorld;

                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    if (!(meshPart.Effect is BasicEffect))
                    {
                        IEffectMatrices iem = meshPart.Effect as IEffectMatrices;
                        if (customEffect != null)
                        {
                            customEffect.Parameters["xTexture"].SetValue(_model.Texture);
                            if (individualTransformations.ContainsKey(mesh.Name))
                            {
                                customEffect.Parameters["xWorld"].SetValue(
                                    individualTransformations[mesh.Name] *
                                    localWorld);
                            }
                            else
                            {
                                customEffect.Parameters["xWorld"].SetValue(
                                    localWorld);
                            }

                            customEffect.CurrentTechnique.Passes[0].Apply();
                        }
                        else
                        {
                            if (individualTransformations.ContainsKey(mesh.Name))
                            {
                                iem.World = individualTransformations[mesh.Name] *
                                            GetParentTransform(_model.Model, mesh.ParentBone) *
                                            baseWorld;
                            }
                            else
                            {
                                iem.World = GetParentTransform(_model.Model, mesh.ParentBone) *
                                            baseWorld;
                            }

                            iem.Projection = projection;
                            iem.View       = view;
                        }
                    }
                    else
                    {
                        BasicEffect effect = (BasicEffect)meshPart.Effect;

                        if (individualTransformations.ContainsKey(mesh.Name))
                        {
                            effect.World = individualTransformations[mesh.Name] * localWorld;
                        }
                        else
                        {
                            effect.World = localWorld;
                        }

                        effect.View       = view;
                        effect.Projection = projection;

                        effect.SpecularColor = Color.CadetBlue.ToVector3();
                        effect.SpecularPower = 64;

                        effect.EnableDefaultLighting();
                        effect.CurrentTechnique.Passes[0].Apply();
                    }
                }

                mesh.Draw();
            }
        }
Example #28
0
        public void Render(GraphicsDevice device, Camera cam)
        {
            bool devicePrepared = false;
            int  id             = cam.GetInstanceID();

            if (!CameraCullingInfo.ContainsKey(id))
            {
                return;
            }
            PooledPriorityQueue cullingInfo = CameraCullingInfo[id];

            for (int i = 0; i < cullingInfo.Count; i++)
            {
                Transform t = Application.Find <Transform>(cullingInfo[i]);
                if (t == null)
                {
                    continue;
                }
                if (!t.renderer.enabled || !t.gameObject.active)
                {
                    continue;
                }
#if DEBUG
                if (Camera.logRenderCalls)
                {
                    Debug.LogFormat("Render: {0} for {1} on {2}", this, t.gameObject, cam.gameObject);
                }
#endif
                Effect e = Material.shader.effect;
                if (!devicePrepared)
                {
                    devicePrepared = true;
                    device.SetVertexBuffer(VertexBuffer);
                    device.Indices = IndexBuffer;

                    Material.shader.ApplyPreRenderSettings(Material, UseVertexColor);
                    Material.SetBlendState(device);

                    IEffectMatrices ems = e as IEffectMatrices;
                    if (ems != null)
                    {
                        ems.World      = t.world;
                        ems.View       = cam.view;
                        ems.Projection = cam.projectionMatrix;
                    }
                }
                else
                {
                    IEffectMatrices ems = e as IEffectMatrices;
                    if (ems != null)
                    {
                        ems.World = t.world;
                    }
                }
                foreach (EffectPass pass in e.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    device.DrawIndexedPrimitives(
                        PrimitiveType.TriangleList,
                        0,
                        0,
                        VertexBuffer.VertexCount,
                        0,
                        IndexBuffer.IndexCount / 3
                        );
                }
                RenderStats.AddDrawCall(batches, VertexBuffer.VertexCount, IndexBuffer.IndexCount / 3);
            }
        }
Example #29
0
        public override void Draw(IDrawer drawer)
        {
            RefreshBuffers();
            if (_vertexArray == null)
            {
                return;
            }

            GraphicsDevice graphicsDevice = drawer.GraphicsDevice;
            Quad           rect           = drawer.DisplayedRectangle;

            // Configure default effect matrices
            _defaultEffect.World      = SceneNode.Matrix.ToMatrix4X4(SceneNode.Depth);
            _defaultEffect.View       = Matrix.CreateLookAt(Vector3.Backward, Vector3.Zero, Vector3.Up);
            _defaultEffect.Projection = Matrix.CreateOrthographicOffCenter(rect.Left, rect.Right, rect.Bottom, rect.Top, float.MinValue / 2, float.MaxValue / 2);

            drawer.SpriteBatchStack.Push(null);

            int        verticesIndex = 0;
            int        indicesIndex  = 0;
            Effect     currentEffect = null;
            EffectPass currentPass   = null;

            foreach (IVisualMesh mesh in Meshes)
            {
                // If mesh not visible, move indexes and go to next
                if (!mesh.Visible)
                {
                    verticesIndex += mesh.VertexCount;
                    indicesIndex  += mesh.TriangulationIndexCount;
                    continue;
                }

                bool meshIndexed = mesh.TriangulationIndexCount > 0;

                foreach (IVisualMeshPart part in mesh.Parts)
                {
                    Effect effect = part.Effect;
                    if (effect == null)
                    {
                        // If no effect provided, use default effect
                        effect = _defaultEffect;

                        // Enable texture if necessary
                        _defaultEffect.TextureEnabled = TextureSource?.Texture != null;//material.Textures.Count > 0;
                    }
                    else if (effect != currentEffect)
                    {
                        // Configure effect matrices
                        IEffectMatrices effectMatrices = part.EffectMatrices;
                        if (effectMatrices != null)
                        {
                            effectMatrices.World      = _defaultEffect.World;
                            effectMatrices.View       = _defaultEffect.View;
                            effectMatrices.Projection = _defaultEffect.Projection;
                        }

                        currentEffect = effect;
                    }

                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        if (pass != currentPass)
                        {
                            // Apply effect pass
                            pass.Apply();
                            currentPass = pass;
                        }

                        // Interesting links:
                        // http://www.shawnhargreaves.com/blog/spritebatch-billboards-in-a-3d-world.html
                        // https://github.com/MonoGame/MonoGame/blob/3e65abb158de2e07c72d0831dd971f594ff76a18/MonoGame.Framework/Graphics/Effect/SpriteEffect.cs#L71
                        // https://community.monogame.net/t/solved-drawing-primitives-and-spritebatch/10015/4

                        graphicsDevice.Textures[0]      = TextureSource?.Texture;
                        graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

                        graphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;
                        graphicsDevice.BlendState        = BlendState.AlphaBlend;
                        graphicsDevice.DepthStencilState = DepthStencilState.None;

                        // Draw primitives
                        if (meshIndexed)
                        {
                            int primitiveCount = GetPrimitiveCount(mesh.Type, part.TriangulationIndexCount);

                            graphicsDevice.DrawUserIndexedPrimitives(mesh.Type, _vertexArray, verticesIndex, mesh.VertexCount, _indexArray, indicesIndex, primitiveCount);
                            indicesIndex += part.TriangulationIndexCount;
                        }
                        else
                        {
                            int primitiveCount = GetPrimitiveCount(mesh.Type, part.VertexCount);

                            graphicsDevice.DrawUserPrimitives(mesh.Type, _vertexArray, verticesIndex, primitiveCount);
                            verticesIndex += part.VertexCount;
                        }
                    }
                }

                // If mesh indexed, move vertices index after all parts have been drawn.
                if (meshIndexed)
                {
                    verticesIndex += mesh.VertexCount;
                }
            }

            drawer.SpriteBatchStack.Pop();
        }