示例#1
0
        /// <summary>
        ///    Internal method returns whether required capabilities for this program is supported.
        /// </summary>
        protected bool AreRequiredCapabilitiesSupported()
        {
            HardwareCaps caps = Root.Instance.RenderSystem.Caps;

            // If skeletal animation is being done, we need support for UBYTE4
            if (this.IsSkeletalAnimationIncluded &&
                !caps.CheckCap(Capabilities.VertexFormatUByte4))
            {
                return(false);
            }

            // Vertex texture fetch required?
            if (vertexTextureFetchRequired && !caps.CheckCap(Capabilities.VertexTextureFetch))
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        ///    Compilation method for Techniques.  See <see cref="Axiom.Core.Material"/>
        /// </summary>
        /// <param name="autoManageTextureUnits">
        ///    Determines whether or not the engine should split up extra texture unit requests
        ///    into extra passes if the hardware does not have enough available units.
        /// </param>
        internal string Compile(bool autoManageTextureUnits)
        {
            string compileErrors;

            // assume not supported unless it proves otherwise
            isSupported = false;

            // grab a ref to the current hardware caps
            HardwareCaps caps             = Root.Instance.RenderSystem.Caps;
            int          numAvailTexUnits = caps.TextureUnitCount;

            // check requirements for each pass
            for (int i = 0; i < passes.Count; i++)
            {
                Pass pass = (Pass)passes[i];

                bool tooManyTextures      = false;
                int  numTexUnitsRequested = pass.NumTextureUnitStages;
                if (pass.HasFragmentProgram)
                {
                    // check texture units

                    // check fragment program version
                    if (!pass.FragmentProgram.IsSupported)
                    {
                        // can't do this one
                        tooManyTextures = true;
                    }
                    else
                    {
                        numAvailTexUnits = pass.FragmentProgram.SamplerCount;
                        if (numTexUnitsRequested > numAvailTexUnits)
                        {
                            // can't do this, since programmable passes cannot be split automatically
                            tooManyTextures = true;
                        }
                    }
                }
                else
                {
                    if (numTexUnitsRequested > numAvailTexUnits)
                    {
                        if (!autoManageTextureUnits)
                        {
                            tooManyTextures = true;
                        }
                        else if (pass.HasVertexProgram)
                        {
                            tooManyTextures = true;
                        }
                    }
                    if (tooManyTextures)
                    {
                        // Can't do this one
                        compileErrors = "Pass " + i +
                                        ": Too many texture units for the current hardware and " +
                                        "cannot split programmable passes.";
                        return(compileErrors);
                    }
                }
                if (pass.HasVertexProgram)
                {
                    // Check vertex program version
                    if (!pass.VertexProgram.IsSupported)
                    {
                        // Can't do this one
                        compileErrors = "Pass " + i +
                                        ": Vertex program " + pass.VertexProgram.Name +
                                        " cannot be used - ";
                        if (pass.VertexProgram.HasCompileError)
                        {
                            compileErrors += "compile error.";
                        }
                        else
                        {
                            compileErrors += "not supported.";
                        }
                        return(compileErrors);
                    }
                }
                if (pass.HasFragmentProgram)
                {
                    // check texture units

                    // check fragment program version
                    if (!pass.FragmentProgram.IsSupported)
                    {
                        // can't do this one
                        compileErrors = "Pass " + i +
                                        ": Fragment program " + pass.FragmentProgram.Name +
                                        " cannot be used - ";
                        if (pass.FragmentProgram.HasCompileError)
                        {
                            compileErrors += "compile error.";
                        }
                        else
                        {
                            compileErrors += "not supported.";
                        }
                        return(compileErrors);
                    }
                }
                else
                {
                    // check support for a few fixed function options while we are here
                    for (int j = 0; j < pass.NumTextureUnitStages; j++)
                    {
                        TextureUnitState texUnit = pass.GetTextureUnitState(j);

                        // check to make sure we have some cube mapping support
                        if (texUnit.Is3D && !caps.CheckCap(Capabilities.CubeMapping))
                        {
                            compileErrors = "Pass " + i + " Tex " + texUnit +
                                            ": Cube maps not supported by current environment.";
                            return(compileErrors);
                        }
                        // Any 3D textures? NB we make the assumption that any
                        // card capable of running fragment programs can support
                        // 3D textures, which has to be true, surely?
                        if (texUnit.TextureType == TextureType.ThreeD && !caps.CheckCap(Capabilities.Texture3D))
                        {
                            // Fail
                            compileErrors = "Pass " + i + " Tex " + texUnit +
                                            ": Volume textures not supported by current environment.";
                            return(compileErrors);
                        }
                        // if this is a Dot3 blending layer, make sure we can support it
                        if (texUnit.ColorBlendMode.operation == LayerBlendOperationEx.DotProduct && !caps.CheckCap(Capabilities.Dot3))
                        {
                            compileErrors = "Pass " + i + " Tex " + texUnit +
                                            ": DOT3 blending not supported by current environment.";
                            return(compileErrors);
                        }
                    }

                    // keep splitting until the texture units required for this pass are available
                    // Note: Split will call Technique.CreatePass,
                    // which adds the new pass to the end of the list
                    // of passes.  Is that always the right behavior?
                    while (numTexUnitsRequested > numAvailTexUnits)
                    {
                        // split this pass up into more passes
                        pass = pass.Split(numAvailTexUnits);
                        numTexUnitsRequested = pass.NumTextureUnitStages;
                    }
                }
            }             // for

            // if we made it this far, we are good to go!
            isSupported = true;

            // CompileIlluminationPasses() used to be called here, but it is now done on
            // demand since it the illumination passes are only needed for additive shadows
            // and we (multiverse) don't use them.
            // Now compile for categorised illumination, in case we need it later
            // Compile for categorised illumination on demand
            ClearIlluminationPasses();
            illuminationPassesCompilationPhase = IlluminationPassesState.NotCompiled;
            return("");
        }