Exemplo n.º 1
0
 /// <summary></summary>
 /// <param name="shaderProvider"></param>
 public ShaderProviderFlag(ModelInstanceShaderProvider shaderProvider)
 {
     this.overrideShaderProvider = true;
     if (shaderProvider != null && shaderProvider.ProviderModifiesWorldMatrixInBeginDraw)
     {
         throw new ArgumentException("shaderProvider.ProviderModifiesWorldMatrixInBeginDraw cannot be true for ShaderProviderFlag");
     }
     this.shaderProvider = shaderProvider;
 }
Exemplo n.º 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);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Extend the <see cref="ModelInstanceShaderProvider"/> abstract class to override shaders or world matrices used by this model instance
 /// </summary>
 /// <param name="provider"></param>
 public void SetShaderOverride(ModelInstanceShaderProvider provider)
 {
     shaderProvider = provider;
 }