Example #1
0
        public void Draw(DrawState state)
        {
            //switch rendering mode based on the TutorialRenderMode flag
            switch (state.GetDrawFlag <TutorialRenderMode>())
            {
            case TutorialRenderMode.DepthOutput:
                //bind the depth output shader
                state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRg>().Bind(state);
                break;

            case TutorialRenderMode.DrawShadow:
                //bind the shadow rendering shader
                Shader.ShadowShader shader = state.GetShader <Shader.ShadowShader>();
                shader.TextureMap     = material.TextureMap;
                shader.TextureSampler = material.TextureMapSampler;
                shader.Bind(state);
                break;

            default:
                //no flag known specified
                material.Bind(state);
                break;
            }

            //draw the ground
            vertices.Draw(state, null, PrimitiveType.TriangleFan);
        }
Example #2
0
        /// <summary>
        /// Draw the model. This class automatically assigns shaders when drawing
        /// </summary>
        /// <param name="state"></param>
        public void Draw(DrawState state)
        {
            if (modelData == null)
            {
                throw new InvalidOperationException("ModelData is null");
            }

            if (controller != null)
            {
                controller.WaitForAsyncAnimation(state, state.FrameIndex, true);

                if (controller.IsDisposed)
                {
                    controller = null;
                }
            }

            if (controller != null && hierarchy == null)
            {
                hierarchy = new MaterialAnimationTransformHierarchy(modelData.skeleton);
            }

            if (hierarchy != null)
            {
                hierarchy.UpdateTransformHierarchy(controller.transformedBones);
            }

            ModelInstanceShaderProvider shaderProvider = this.shaderProvider;
            MaterialLightCollection     lights         = this.lights;

            ShaderProviderFlag providerFlag;

            MaterialLightCollection.LightCollectionFlag lightsFlag;

            state.GetDrawFlag(out providerFlag);
            if (providerFlag.OverrideShaderProvider)
            {
                shaderProvider = providerFlag.ShaderProvider;
            }

            state.GetDrawFlag(out lightsFlag);
            if (lightsFlag.OverrideLightCollection)
            {
                lights = lightsFlag.LightCollection;
            }

            if (shaderProvider != null)
            {
                if (controller != null)
                {
                    shaderProvider.BeginDraw(state, controller.transformedBones, hierarchy.GetMatrixData());
                }
                else
                {
                    shaderProvider.BeginDraw(state);
                }
            }

            Vector3 boundsMin, boundsMax;

            ContainmentType cullModel = ContainmentType.Contains;

            //if there is just one geometry object, then the ICullable.CullTest() call will have been suficient.
            bool skipCullTest = this.modelData != null && this.modelData.meshes.Length == 1 && this.modelData.meshes[0].geometry.Length == 1;

            if (!skipCullTest)
            {
                if (controller != null)
                {
                    cullModel = state.Culler.IntersectBox(ref controller.boundsMin, ref controller.boundsMax);
                }
                else
                {
                    cullModel = state.Culler.IntersectBox(ref modelData.staticBounds.minimum, ref modelData.staticBounds.maximum);
                }
            }

            if (cullModel != ContainmentType.Disjoint)
            {
                for (int m = 0; m < modelData.meshes.Length; m++)
                {
                    MeshData mesh = modelData.meshes[m];

                    if (shaderProvider != null)
                    {
                        shaderProvider.BeginMesh(state, mesh);
                    }

                    ContainmentType cullMesh = cullModel;

                    if (cullModel == ContainmentType.Intersects && modelData.meshes.Length > 1)
                    {
                        if (controller != null)
                        {
                            controller.ComputeMeshBounds(m, out boundsMin, out boundsMax);
                            cullMesh = state.Culler.IntersectBox(ref boundsMin, ref boundsMax);
                        }
                        else
                        {
                            cullMesh = state.Culler.IntersectBox(ref mesh.staticBounds.minimum, ref mesh.staticBounds.maximum);
                        }
                    }

                    if (cullMesh != ContainmentType.Disjoint)
                    {
                        for (int g = 0; g < mesh.geometry.Length; g++)
                        {
                            GeometryData   geom   = mesh.geometry[g];
                            MaterialShader shader = geom.MaterialShader;

                            if (shaderProvider != null && shaderProvider.BeginGeometryShaderOverride(state, geom, lights))
                            {
                                shader = null;
                            }

                            bool cullTest = true;

                            if (cullMesh == ContainmentType.Intersects && mesh.geometry.Length > 1)
                            {
                                if (controller != null)
                                {
                                    controller.ComputeGeometryBounds(m, g, out boundsMin, out boundsMax);
                                    cullTest = state.Culler.TestBox(ref boundsMin, ref boundsMax);
                                }
                                else
                                {
                                    cullTest = state.Culler.TestBox(ref geom.staticBounds.minimum, ref geom.staticBounds.maximum);
                                }
                            }

                            if (cullTest)
                            {
                                if (shader != null)
                                {
                                    shader.AnimationTransforms = hierarchy;
                                    shader.Lights = lights;
                                    shader.Bind(state);
                                }

                                geom.Vertices.Draw(state, geom.Indices, PrimitiveType.TriangleList);
                            }

                            if (shaderProvider != null)
                            {
                                shaderProvider.EndGeometry(state, geom);
                            }
                        }
                    }

                    if (shaderProvider != null)
                    {
                        shaderProvider.EndMesh(state, mesh);
                    }
                }
            }

            if (shaderProvider != null)
            {
                shaderProvider.EndDraw(state);
            }
        }
Example #3
0
        //this is called just before geometry is drawn,
        //return true to indicate the shader has been set
        public override bool BeginGeometryShaderOverride(DrawState state, GeometryData geometry, Xen.Ex.Material.MaterialLightCollection lights)
        {
            //query the draw flag,
            switch (state.GetDrawFlag <TutorialRenderMode>())
            {
            case TutorialRenderMode.DrawShadow:
            {
                //bind the shadow rendering shader...
                if (animationBoneData == null)
                {
                    Shader.ShadowShader shader = state.GetShader <Shader.ShadowShader>();

                    shader.TextureMap     = geometry.MaterialShader.TextureMap;
                    shader.TextureSampler = geometry.MaterialShader.TextureMapSampler;

                    shader.Bind(state);
                }
                else
                {
                    //bind the animating shader,

                    Shader.ShadowShaderBlend shader = state.GetShader <Shader.ShadowShaderBlend>();

                    //set the blend matrix data
                    if (animationBoneDataDirty)
                    {
                        //use the 'animationBoneDataDirty' bool so animation data is only copied once.
                        //this could happen if a single model has many pieces of geometry.
                        shader.SetBlendMatrices(animationBoneData);
                        animationBoneDataDirty = false;
                    }

                    shader.TextureMap     = geometry.MaterialShader.TextureMap;
                    shader.TextureSampler = geometry.MaterialShader.TextureMapSampler;

                    shader.Bind(state);
                }
                return(true);                       //shader was assigned
            }

            case TutorialRenderMode.DepthOutput:
            {
                //determine if alpha test is being used (in this tutorial it won't be - but do it anyway...)
                bool alphaTest = state.RenderState.AlphaTest.Enabled;

                if (alphaTest)
                {
                    //alpha test is only needed if a texture is set
                    alphaTest &= geometry.MaterialShader.TextureMap != null;
                }


                if (alphaTest)
                {
                    //bind a depth output shader that samples a texture for alpha (for alpha test compatibility)

                    if (this.animationBoneData != null)
                    {
                        //the model is animated

                        //get the shader
                        Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlphaBlend shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlphaBlend>();

                        //set animation data (it's possible this is called redundantly, so logic here could be improved)
                        if (animationBoneDataDirty)
                        {
                            shader.SetBlendMatrices(this.animationBoneData);
                            animationBoneDataDirty = false;
                        }

                        //set the texture
                        shader.AlphaTexture        = geometry.MaterialShader.TextureMap;
                        shader.AlphaTextureSampler = geometry.MaterialShader.TextureMapSampler;

                        //bind
                        shader.Bind(state);
                    }
                    else
                    {
                        //get the shader
                        Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlpha shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlpha>();

                        //set the texture
                        shader.AlphaTexture        = geometry.MaterialShader.TextureMap;
                        shader.AlphaTextureSampler = geometry.MaterialShader.TextureMapSampler;

                        shader.Bind(state);                                 // bind the basic depth out shader
                    }
                }
                else
                {
                    //bind a simple depth output shader

                    if (this.animationBoneData != null)
                    {
                        //the model is animated
                        Xen.Ex.Shaders.NonLinearDepthOutRgBlend shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgBlend>();

                        //set animation data (it's possible this is called redundantly, so logic here could be improved)
                        if (animationBoneDataDirty)
                        {
                            shader.SetBlendMatrices(this.animationBoneData);
                            animationBoneDataDirty = false;
                        }

                        //bind
                        shader.Bind(state);
                    }
                    else
                    {
                        state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRg>().Bind(state);                                // bind the basic depth out shader
                    }
                }
                return(true);                       //shader was assigned
            }
            }

            //false, because no shader has been bound (will use the model material shader)
            return(false);
        }
Example #4
0
        /// <summary>
        /// Draw all the model batch instances
        /// </summary>
        /// <param name="state"></param>
        public void Draw(DrawState state)
        {
            if (modelData == null)
            {
                throw new InvalidOperationException("ModelData is null");
            }

            if (geometry == null)
            {
                SetupGeometry();
            }

            int geometryIndex = 0;

            BatchModelShaderProvider shaderProvider = this.shaderProvider;
            MaterialLightCollection  lights         = this.lights;

            ShaderProviderFlag providerFlag;

            MaterialLightCollection.LightCollectionFlag lightsFlag;

            state.GetDrawFlag(out providerFlag);
            if (providerFlag.OverrideShaderProvider)
            {
                shaderProvider = providerFlag.ShaderProvider;
            }

            state.GetDrawFlag(out lightsFlag);
            if (lightsFlag.OverrideLightCollection)
            {
                lights = lightsFlag.LightCollection;
            }

            if (shaderProvider != null)
            {
                shaderProvider.BeginDraw(state);
            }

            //loop through the model data
            for (int m = 0; m < modelData.meshes.Length; m++)
            {
                MeshData mesh = modelData.meshes[m];

                if (shaderProvider != null)
                {
                    shaderProvider.BeginMesh(state, mesh);
                }

                for (int g = 0; g < mesh.geometry.Length; g++)
                {
                    GeometryData geom = mesh.geometry[g];
                    GeometrySet  set  = this.geometry[geometryIndex];

                    if (set.count > 0)
                    {
                        bool instancing = state.SupportsHardwareInstancing && set.count > 2;

                        if (shaderProvider == null || !shaderProvider.BeginGeometryShaderOverride(state, geom, lights, instancing))
                        {
                            MaterialShader shader = geom.MaterialShader;

                            shader.AnimationTransforms   = null;
                            shader.UseHardwareInstancing = instancing;
                            shader.Lights = lights;

                            shader.Bind(state);
                        }

                        //draw the geometry
                        if (instancing)
                        {
                            state.DrawBatch(geom.Vertices, geom.Indices, PrimitiveType.TriangleList, null, set.instances, set.count);
                        }
                        else
                        {
                            for (int i = 0; i < set.count; i++)
                            {
                                state.PushWorldMatrixMultiply(ref set.instances[i]);

                                geom.Vertices.Draw(state, geom.Indices, PrimitiveType.TriangleList);

                                state.PopWorldMatrix();
                            }
                        }

                        if (shaderProvider != null)
                        {
                            shaderProvider.EndGeometry(state, geom);
                        }
                    }


                    set.count = 0;
                    geometryIndex++;
                }

                if (shaderProvider != null)
                {
                    shaderProvider.EndMesh(state, mesh);
                }
            }

            if (shaderProvider != null)
            {
                shaderProvider.EndDraw(state);
            }

            drawCount = 0;
        }