/// <summary> /// Gets the 'nth' texture which references the given content type. /// </summary> /// <remarks> /// If the 'nth' texture unit which references the content type doesn't /// exist, then this method returns an arbitrary high-value outside the /// valid range to index texture units. /// </remarks> public int GetTextureUnitWithContentTypeIndex(TextureContentType contentType, int index) { if (!contentTypeLookupBuilt) { shadowContentTypeLookup = new List<int>(); for (int i=0; i<textureUnitStates.Count; ++i) { if (((TextureUnitState)textureUnitStates[i]).ContentType == TextureContentType.Shadow) shadowContentTypeLookup.Add(i); } contentTypeLookupBuilt = true; } switch(contentType) { case TextureContentType.Shadow: if (index < shadowContentTypeLookup.Count) return shadowContentTypeLookup[index]; break; default: // Simple iteration for (int i=0; i<textureUnitStates.Count; ++i) { if (((TextureUnitState)textureUnitStates[i]).ContentType == TextureContentType.Shadow) { if (index == 0) return i; else --index; } } break; } // not found - return out of range return textureUnitStates.Count + 1; }
/// <summary> /// Constructor. /// </summary> public TextureUnitState(Pass parent, string textureName, int texCoordSet) { this.parent = parent; isBlank = true; colorBlendMode.blendType = LayerBlendType.Color; SetColorOperation(LayerBlendOperation.Modulate); this.TextureAddressing = TextureAddressing.Wrap; // set alpha blending options alphaBlendMode.operation = LayerBlendOperationEx.Modulate; alphaBlendMode.blendType = LayerBlendType.Alpha; alphaBlendMode.source1 = LayerBlendSource.Texture; alphaBlendMode.source2 = LayerBlendSource.Current; // default filtering and anisotropy minFilter = FilterOptions.Linear; magFilter = FilterOptions.Linear; mipFilter = FilterOptions.Point; maxAnisotropy = MaterialManager.Instance.DefaultAnisotropy; isDefaultFiltering = true; isDefaultAniso = true; // texture modification params scrollU = scrollV = 0; transU = transV = 0; scaleU = scaleV = 1; rotate = 0; texMatrix = Matrix4.Identity; animDuration = 0; textureType = TextureType.TwoD; textureSrcMipmaps = -1; bindingType = GpuProgramType.Fragment; contentType = TextureContentType.Named; // texture params SetTextureName(textureName, textureType, textureSrcMipmaps); this.TextureCoordSet = texCoordSet; parent.DirtyHash(); }
/// <summary> /// Add a Texture name to the end of the frame container. /// </summary> /// <remarks> /// Applies to both fixed-function and programmable pipeline. /// </remarks> /// <param name="name">The name of the texture.</param> public void AddFrameTextureName(string name) { contentType = TextureContentType.Named; frames[numFrames] = name; // Add blank pointer, load on demand frameTextures[numFrames] = null; // Load immediately if Material loaded if (IsLoaded) Load(); // Tell parent to recalculate hash parent.DirtyHash(); }
/// <summary> /// Sets this texture layer to use a single texture, given the name of the texture to use on this layer. /// </summary> /// <remarks> /// Applies to both fixed-function and programmable pipeline. /// </remarks> /// <param name="name">Name of the texture.</param> /// <param name="type">Type of texture this is.</param> public void SetTextureName(string name, TextureType type, int mipmaps, bool alpha) { contentType = TextureContentType.Named; if(type == TextureType.CubeMap) { // delegate to cube texture implementation SetCubicTextureName(name, true); } else { frames[0] = name; frameTextures[0] = null; numFrames = 1; currentFrame = 0; isCubic = false; textureType = type; textureSrcMipmaps = mipmaps; isAlpha = alpha; if(name.Length == 0) { isBlank = true; return; } if (this.IsLoaded) { Load(); // reload } // Tell parent to recalculate hash (for sorting) parent.DirtyHash(); } }
/// <summary> /// Sets this texture layer to use a combination of 6 texture maps, each one relating to a face of a cube. /// </summary> /// <remarks> /// Cubic textures are made up of 6 separate texture images. Each one of these is an orthoganal view of the /// world with a FOV of 90 degrees and an aspect ratio of 1:1. You can generate these from 3D Studio by /// rendering a scene to a reflection map of a transparent cube and saving the output files. /// <p/> /// Cubic maps can be used either for skyboxes (complete wrap-around skies, like space) or as environment /// maps to simulate reflections. The system deals with these 2 scenarios in different ways: /// <ul> /// <li> /// <p> /// For cubic environment maps, the 6 textures are combined into a single 'cubic' texture map which /// is then addressed using 3D texture coordinates. This is required because you don't know what /// face of the box you're going to need to address when you render an object, and typically you /// need to reflect more than one face on the one object, so all 6 textures are needed to be /// 'active' at once. Cubic environment maps are enabled by calling this method with the forUVW /// parameter set to true, and then calling <code>SetEnvironmentMap(true)</code>. /// </p> /// <p> /// Note that not all cards support cubic environment mapping. /// </p> /// </li> /// <li> /// <p> /// For skyboxes, the 6 textures are kept separate and used independently for each face of the skybox. /// This is done because not all cards support 3D cubic maps and skyboxes do not need to use 3D /// texture coordinates so it is simpler to render each face of the box with 2D coordinates, changing /// texture between faces. /// </p> /// <p> /// Skyboxes are created by calling SceneManager.SetSkyBox. /// </p> /// </li> /// </ul> /// <p/> /// Applies to both fixed-function and programmable pipeline. /// </remarks> /// <param name="textureNames"> /// 6 versions of this texture with the suffixes _fr, _bk, _up, _dn, _lf, and _rt (before the extension) which /// make up the 6 sides of the box. The textures must all be the same size and be powers of 2 in width & height. /// If you can't make your texture names conform to this, use the alternative method of the same name which takes /// an array of texture names instead. /// </param> /// <param name="forUVW"> /// Set to true if you want a single 3D texture addressable with 3D texture coordinates rather than /// 6 separate textures. Useful for cubic environment mapping. /// </param> public void SetCubicTextureName(string[] textureNames, bool forUVW) { contentType = TextureContentType.Named; numFrames = forUVW ? 1 : 6; currentFrame = 0; isCubic = true; textureType = forUVW ? TextureType.CubeMap : TextureType.TwoD; for(int i = 0; i < numFrames; i++) { frames[i] = textureNames[i]; frameTextures[i] = null; } // tell parent we need recompiling, will cause reload too parent.NotifyNeedsRecompile(); }
/// <summary> /// Sets this texture layer to use a combination of 6 texture maps, each one relating to a face of a cube. /// </summary> /// <remarks> /// Cubic textures are made up of 6 separate texture images. Each one of these is an orthoganal view of the /// world with a FOV of 90 degrees and an aspect ratio of 1:1. You can generate these from 3D Studio by /// rendering a scene to a reflection map of a transparent cube and saving the output files. /// <p/> /// Cubic maps can be used either for skyboxes (complete wrap-around skies, like space) or as environment /// maps to simulate reflections. The system deals with these 2 scenarios in different ways: /// <ol> /// <li> /// <p> /// For cubic environment maps, the 6 textures are combined into a single 'cubic' texture map which /// is then addressed using 3D texture coordinates. This is required because you don't know what /// face of the box you're going to need to address when you render an object, and typically you /// need to reflect more than one face on the one object, so all 6 textures are needed to be /// 'active' at once. Cubic environment maps are enabled by calling this method with the forUVW /// parameter set to true, and then calling <code>SetEnvironmentMap(true)</code>. /// </p> /// <p> /// Note that not all cards support cubic environment mapping. /// </p> /// </li> /// <li> /// <p> /// For skyboxes, the 6 textures are kept separate and used independently for each face of the skybox. /// This is done because not all cards support 3D cubic maps and skyboxes do not need to use 3D /// texture coordinates so it is simpler to render each face of the box with 2D coordinates, changing /// texture between faces. /// </p> /// <p> /// Skyboxes are created by calling SceneManager.SetSkyBox. /// </p> /// </li> /// </ul> /// <p/> /// Applies to both fixed-function and programmable pipeline. /// </remarks> /// <param name="textureName"> /// The basic name of the texture e.g. brickwall.jpg, stonefloor.png. There must be 6 versions /// of this texture with the suffixes _fr, _bk, _up, _dn, _lf, and _rt (before the extension) which /// make up the 6 sides of the box. The textures must all be the same size and be powers of 2 in width & height. /// If you can't make your texture names conform to this, use the alternative method of the same name which takes /// an array of texture names instead. /// </param> /// <param name="forUVW"> /// Set to true if you want a single 3D texture addressable with 3D texture coordinates rather than /// 6 separate textures. Useful for cubic environment mapping. /// </param> public void SetCubicTextureName(string textureName, bool forUVW) { if(forUVW) { // pass in the single texture name SetCubicTextureName(new string[] { textureName }, forUVW); } else { contentType = TextureContentType.Named; string[] postfixes = {"_fr", "_bk", "_lf", "_rt", "_up", "_dn"}; string[] fullNames = new string[6]; string baseName; string ext; int pos = textureName.LastIndexOf("."); baseName = textureName.Substring(0, pos); ext = textureName.Substring(pos); for(int i = 0; i < 6; i++) { fullNames[i] = baseName + postfixes[i] + ext; } SetCubicTextureName(fullNames, forUVW); } }
/// <summary> /// Sets the names of the texture images for an animated texture. /// </summary> /// <remarks> /// Animated textures are just a series of images making up the frames of the animation. All the images /// must be the same size, and their names must have a frame number appended before the extension, e.g. /// if you specify a name of "wall.jpg" with 3 frames, the image names must be "wall_1.jpg" and "wall_2.jpg". /// <p/> /// You can change the active frame on a texture layer by setting the CurrentFrame property. /// </remarks> /// <param name="names">An array containing the array names to use for the animation.</param> /// <param name="numFrames">Number of frames to be used for this animation.</param> /// <param name="duration"> /// Total length of the animation sequence. When set to 0, automatic animation does not occur. /// In that scenario, the values can be changed manually by setting the CurrentFrame property. /// </param> public void SetAnimatedTextureName(string[] names, int numFrames, float duration) { contentType = TextureContentType.Named; if(numFrames > MaxAnimationFrames) { throw new AxiomException("Maximum number of texture animation frames exceeded!"); } this.numFrames = numFrames; this.animDuration = duration; this.currentFrame = 0; this.isCubic = false; // copy the texture names Array.Copy(names, 0, frames, 0, numFrames); // if material is already loaded, load this immediately if(IsLoaded) { Load(); // tell parent to recalculate the hash parent.DirtyHash(); } }
/// <summary> /// Sets the names of the texture images for an animated texture. /// </summary> /// <remarks> /// Animated textures are just a series of images making up the frames of the animation. All the images /// must be the same size, and their names must have a frame number appended before the extension, e.g. /// if you specify a name of "wall.jpg" with 3 frames, the image names must be "wall_1.jpg" and "wall_2.jpg". /// <p/> /// You can change the active frame on a texture layer by setting the CurrentFrame property. /// <p/> /// Note: If you can't make your texture images conform to the naming standard layed out here, you /// can call the alternative SetAnimatedTextureName method which takes an array of names instead. /// </remarks> /// <param name="name">The base name of the series of textures to use.</param> /// <param name="numFrames">Number of frames to be used for this animation.</param> /// <param name="duration"> /// Total length of the animation sequence. When set to 0, automatic animation does not occur. /// In that scenario, the values can be changed manually by setting the CurrentFrame property. /// </param> public void SetAnimatedTextureName(string name, int numFrames, float duration) { string ext, baseName; contentType = TextureContentType.Named; // split up the base name and file extension int pos = name.LastIndexOf("."); baseName = name.Substring(0, pos); ext = name.Substring(pos); string[] names = new string[numFrames]; // loop through and create the real texture names from the base name for(int i = 0; i < numFrames; i++) { names[i] = string.Format("{0}_{1}{2}", baseName, i, ext); } // call the overloaded method, passing in our final texture names SetAnimatedTextureName(names, numFrames, duration); }