/// <summary> /// Defines the texture from a bitmap. /// All texture levels will be generated until the texture size is no longer divisible by two. /// </summary> /// <param name="format">The format to encode the new texture as.</param> /// <param name="intFormat">The type of interpolation to use</param> /// <param name="bmp">The bitmap that will define the texture.</param> public void DefineTextureFromBitmap(GxTextureFormat format, GxInterpolationFormat intFormat, int numMipmaps, Bitmap bmp) { if (!SupportedTextureFormats.Contains(format)) { throw new ArgumentOutOfRangeException("format", "Unsupported format."); } if (bmp == null) { throw new ArgumentNullException("bmp"); } // Define all possible texture levels until the size // of the texture can no longer be divided by two int currentWidth = bmp.Width, currentHeight = bmp.Height; for (int mipmapLevel = 0; mipmapLevel < numMipmaps; mipmapLevel++) { if (mipmapLevel == 0) { DefineMainLevelFromBitmap(format, intFormat, bmp); } else { DefineLevelDataFromBitmap(mipmapLevel, intFormat, DownscaleBitmap(mipmapLevel, intFormat, bmp)); } if ((currentWidth % 2) != 0 || (currentHeight % 2) != 0) { break; } currentWidth /= 2; currentHeight /= 2; } }
/// <summary> /// Create a TPL texture file from the specified model. /// </summary> /// <param name="model">The model to create the TPL file from.</param> /// <param name="textureIndexMapping">The correspondence between textures images in the model and the generated TPL texture indices.</param> public Tpl(ObjMtlModel model, GxInterpolationFormat intFormat, int numMipmaps, out Dictionary <Bitmap, int> textureIndexMapping) { if (model == null) { throw new ArgumentNullException("model"); } // Gather all material definitions in the model IEnumerable <ObjMtlMaterial> allMaterials = model.Objects .SelectMany(o => o.Value.Meshes).Select(m => m.Material); Dictionary <Bitmap, int> textureIndexMappingInt = new Dictionary <Bitmap, int>(); foreach (ObjMtlMaterial mat in allMaterials) { // Create and add texture for diffuse map if (mat.DiffuseTextureMap != null && !textureIndexMappingInt.ContainsKey(mat.DiffuseTextureMap)) { int textureIndex = Count; TplTexture texture = new TplTexture(GxTextureFormat.CMPR, intFormat, numMipmaps, mat.DiffuseTextureMap); Add(texture); textureIndexMappingInt.Add(mat.DiffuseTextureMap, textureIndex); } } // Replace the 'out' variable at the end so it does not get // modified if an exception textureIndexMapping = textureIndexMappingInt; }
/// <summary> /// Downscales a bitmap image with a specified interpolation algorithm /// </summary> /// <param name="level">The bitmap level fr downscaling</param> /// <param name="intFormat">The type of interpolation to use</param> /// <param name="bmp">The bitmap to downscale</param> /// <returns>The downscaled bitmap</returns> internal Bitmap DownscaleBitmap(int level, GxInterpolationFormat intFormat, Bitmap bmp) { if (intFormat == GxInterpolationFormat.NearestNeighbor) { return(DownscaleBitmapNearestNeighbor(level, bmp)); } else { return(new Bitmap(bmp, width >> level, height >> level)); } }
/// <summary> /// Defines a texture and the respective mipmap levels of the texture from the respective files, starting from level 1. /// /// </summary> /// <param name="format">The format to encode the new texture as.</param> /// <param name="intFormat">The type of interpolation to use.</param> /// <param name="path">The path to the level 1 bitmap.</param> public void DefineAllLevelsFromFiles(GxTextureFormat format, GxInterpolationFormat intFormat, String path) { int currentMipmapLevel = 1; // Iterates until no more mipmap levels exist. while (File.Exists(path)) { DefineLevelDataFromBitmap(currentMipmapLevel, intFormat, new Bitmap(path)); currentMipmapLevel++; // Gets the path to the next mipmap. path = Regex.Replace(path, @"\d{1,}(?=\..{3,4}$)", currentMipmapLevel.ToString()); } }
/// <summary> /// Defines the texture from a bitmap. /// All texture levels will be generated (if the provided bitmap is not specified as level 0) until the texture size is no longer divisible by two. /// </summary> /// <param name="format">The format to encode the new texture as.</param> /// <param name="intFormat">The type of interpolation to use</param> /// <param name="bmp">The bitmap that will define the texture.</param> /// <param name="path">The path to the bitmap file.</param> public void DefineTextureFromBitmap(GxTextureFormat format, GxInterpolationFormat intFormat, int numMipmaps, Bitmap bmp, String path = "") { if (!SupportedTextureFormats.Contains(format)) { throw new ArgumentOutOfRangeException("format", "Unsupported format."); } if (bmp == null) { throw new ArgumentNullException("bmp"); } // If the filename ends in '_0.???(?)' or ' 0.???(?)', import them from the respective files, otherwise, generate them. if (Regex.IsMatch(path, @"(_| )0(?=\..{3,4}$)")) { DefineMainLevelFromBitmap(format, intFormat, bmp); // Gets the path to the potential level 1 mipmap of the texture. path = Regex.Replace(path, @"\d{1,}(?=\..{3,4}$)", "1"); DefineAllLevelsFromFiles(format, intFormat, path); } else { // Define all possible texture levels until the size // of the texture can no longer be divided by two int currentWidth = bmp.Width, currentHeight = bmp.Height; for (int mipmapLevel = 0; mipmapLevel < numMipmaps; mipmapLevel++) { if (mipmapLevel == 0) { DefineMainLevelFromBitmap(format, intFormat, bmp); } else { DefineLevelDataFromBitmap(mipmapLevel, intFormat, DownscaleBitmap(mipmapLevel, intFormat, bmp)); } if ((currentWidth % 2) != 0 || (currentHeight % 2) != 0) { break; } currentWidth /= 2; currentHeight /= 2; } } }
/// <summary>Define the main level of the texture from the given bitmap.</summary> public void DefineMainLevelFromBitmap(GxTextureFormat newFormat, GxInterpolationFormat intFormat, Bitmap bmp) { if (!SupportedTextureFormats.Contains(newFormat)) { throw new ArgumentOutOfRangeException("newFormat", "Unsupported format."); } if (bmp == null) { throw new ArgumentNullException("bmp"); } format = newFormat; width = bmp.Width; height = bmp.Height; encodedLevelData = new List <byte[]>(); DefineLevelDataFromBitmap(0, intFormat, bmp); }
private void mipmapInterpolationDropDownItemClicked(object sender, EventArgs e) { string text = ((ToolStripMenuItem)sender).Text; GxInterpolationFormat intEnum = EnumUtils.GetValueFromDescription <GxInterpolationFormat>(text); intFormat = intEnum; foreach (ToolStripMenuItem item in mipMapIntItems) { if (item.Text == text) { item.Checked = true; } else if (item.Checked) { item.Checked = false; } } }
public void Load(ObjMtlModel model, GxInterpolationFormat intFormat, int numMipmaps, List <int> textureIds, out Dictionary <Bitmap, int> textureIndexMapping) { if (model == null) { throw new ArgumentNullException("model"); } // Gather all material definitions in the model IEnumerable <ObjMtlMaterial> allMaterials = model.Objects .SelectMany(o => o.Value.Meshes).Select(m => m.Material); Dictionary <Bitmap, int> textureIndexMappingInt = new Dictionary <Bitmap, int>(); int textureCount = 0; foreach (ObjMtlMaterial mat in allMaterials) { // Create and add texture for diffuse map if (mat.DiffuseTextureMap != null && !BitmapComparision.ContainsBitmap(textureIndexMappingInt, mat.DiffuseTextureMap)) { if (textureCount >= textureIds.Count) { throw new InvalidObjMtlFileException("Too many textures to import"); } TplTexture texture = new TplTexture(GxTextureFormat.CMPR, intFormat, numMipmaps, mat.DiffuseTextureMap); this[textureIds[textureCount]] = texture; textureIndexMappingInt.Add(mat.DiffuseTextureMap, textureIds[textureCount]); ++textureCount; } } // Replace the 'out' variable at the end so it does not get // modified if an exception textureIndexMapping = textureIndexMappingInt; }
/// <summary> /// Create or replace the specified texture level from the specified bitmap. /// New texture levels must be created in order. /// </summary> public void DefineLevelDataFromBitmap(int level, GxInterpolationFormat intFormat, Bitmap bmp) { if (level > LevelCount) // We allow to either replace an existing level or to generate the next level { throw new ArgumentOutOfRangeException("level"); } if (bmp == null) { throw new ArgumentNullException("bmp"); } // Check that the bitmap is of the appropiate size to replace this texture int levelWidth = width >> level; int levelHeight = height >> level; if (bmp.Width != levelWidth || bmp.Height != levelHeight) { throw new ArgumentOutOfRangeException("bmp", "Bitmap doesn't have the correct dimensions to replace this level."); } // Extract the BMP data as an array of ARGB8 pixels BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] levelData = new byte[bmpData.Height * bmpData.Stride]; Marshal.Copy(bmpData.Scan0, levelData, 0, bmpData.Height * bmpData.Stride); bmp.UnlockBits(bmpData); // LockBits gives us the data as ARGB when seen as uint, // so we need to shuffle the bitmap data accordingly to go to RGBA SwapRgbaFromToArgbAsUint(levelData, bmpData.Width, bmpData.Height, bmpData.Stride); // Encode the data to the given format DefineLevelData(level, bmpData.Stride, levelData); }
/// <summary> /// Create a TPL texture file from the specified model. /// </summary> /// <param name="model">The model to create the TPL file from.</param> /// <param name="textureIndexMapping">The correspondence between textures images in the model and the generated TPL texture indices.</param> public Tpl(ObjMtlModel model, GxInterpolationFormat intFormat, int numMipmaps, out Dictionary <Bitmap, int> textureIndexMapping) { if (model == null) { throw new ArgumentNullException("model"); } // Gather all material definitions in the model IEnumerable <ObjMtlMaterial> allMaterials = model.Objects .SelectMany(o => o.Value.Meshes).Select(m => m.Material); Dictionary <Bitmap, int> textureIndexMappingInt = new Dictionary <Bitmap, int>(); foreach (ObjMtlMaterial mat in allMaterials) { // Create and add texture for diffuse map if (mat.DiffuseTextureMap != null && !textureIndexMappingInt.ContainsKey(mat.DiffuseTextureMap)) { int textureIndex = Count; Match materialPreset = Regex.Match(mat.Name, @"(?<=TEX_)[^\]]*"); GxTextureFormat format = GxTextureFormat.CMPR; if (materialPreset.Success) { switch (materialPreset.Value) { case "RGB5A3": format = GxTextureFormat.RGB5A3; break; case "RGB565": format = GxTextureFormat.RGB565; break; case "RGBA8": format = GxTextureFormat.RGBA8; break; case "I4": format = GxTextureFormat.I4; break; case "I8": format = GxTextureFormat.I8; break; case "IA4": format = GxTextureFormat.IA4; break; default: break; } } TplTexture texture = new TplTexture(format, intFormat, numMipmaps, mat.DiffuseTextureMap); Add(texture); textureIndexMappingInt.Add(mat.DiffuseTextureMap, textureIndex); } } // Replace the 'out' variable at the end so it does not get // modified if an exception textureIndexMapping = textureIndexMappingInt; }
/// <summary> /// Create a new texture from the given bitmap. /// </summary> /// <param name="intFormat">The type of interpolation to use</param> /// <param name="bmp">The bitmap to build the texture from.</param> public TplTexture(GxTextureFormat format, GxInterpolationFormat intFormat, int numMipmaps, Bitmap bmp) { DefineTextureFromBitmap(format, intFormat, numMipmaps, bmp); }