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