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); }
//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); }