protected virtual TextureModel OnLoadTexture(string texturePath) { try { //Check if is embedded material if (texturePath.StartsWith("*") && int.TryParse(texturePath.Substring(1, texturePath.Length - 1), out int idx) && embeddedTextures.Count > idx) { return(OnLoadEmbeddedTexture(embeddedTextures[idx])); } else { var ext = Path.GetExtension(texturePath); if (string.IsNullOrEmpty(ext) || !SupportedTextureFormats.Contains(ext.TrimStart('.').ToLowerInvariant())) { Log(HelixToolkit.Logger.LogLevel.Warning, $"Load Texture Failed. Texture Format not supported = {ext}."); return(null); } return(configuration?.TextureLoader?.Load(path, texturePath, Logger)); } } catch (Exception ex) { Log(HelixToolkit.Logger.LogLevel.Warning, $"Load Texture Exception. Texture Path = {texturePath}. Exception: {ex.Message}"); } return(null); }
/// <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>Define the main level of the texture from the given properties.</summary> public void DefineMainLevel(GxTextureFormat newFormat, int newWidth, int newHeight, int newImageStride, byte[] newImageData) { if (SupportedTextureFormats.Contains(newFormat)) { throw new ArgumentOutOfRangeException("newFormat", "Unsupported format."); } if (newWidth <= 0) { throw new ArgumentOutOfRangeException("newWidth"); } if (newHeight <= 0) { throw new ArgumentOutOfRangeException("newHeight"); } if (newImageStride < 0) { throw new ArgumentOutOfRangeException("newImageStride"); } if (newImageStride < newWidth * 4) { throw new ArgumentOutOfRangeException("newImageStride", "Stride is too small to contain a row of data."); } if (newImageData == null) { throw new ArgumentNullException("newImageData"); } format = newFormat; width = newWidth; height = newHeight; encodedLevelData = new List <byte[]>(); DefineLevelData(0, newImageStride, newImageData); }
protected virtual TextureModel OnLoadTexture(string texturePath, out string actualPath) { actualPath = texturePath; try { //Check if is embedded material if (texturePath.StartsWith("*") && int.TryParse(texturePath.Substring(1, texturePath.Length - 1), out int idx) && embeddedTextures.Count > idx) { return(OnLoadEmbeddedTexture(embeddedTextures[idx])); } else if (embeddedTextureDict.TryGetValue(texturePath, out var embeddedTex)) { return(OnLoadEmbeddedTexture(embeddedTex)); } else { var ext = Path.GetExtension(texturePath); if (string.IsNullOrEmpty(ext) || !SupportedTextureFormats.Contains(ext.TrimStart('.').ToLowerInvariant())) { logger.LogWarning("Load Texture Failed. Texture Format not supported = {}.", ext); return(null); } actualPath = configuration?.TexturePathResolver?.Resolve(path, texturePath); return(string.IsNullOrEmpty(actualPath) ? null : new TextureModel(actualPath)); } } catch (Exception ex) { logger.LogWarning("Load Texture Exception. Texture Path = {}. Exception: {}", texturePath, ex.Message); } return(null); }
/// <summary> /// Reads a texture with the specified characteristics from a binary stream. /// </summary> internal void LoadTextureData(EndianBinaryReader input, GcGame game, GcTextureFormat format, int totalLevelSize, int width, int height, int levelCount) { if (!SupportedTextureFormats.Contains(format)) { throw new InvalidTplFileException("Unsupported texture format."); } int remainingSize = totalLevelSize; this.format = format; this.width = width; this.height = height; for (int level = 0; level < levelCount; level++) { byte[] levelData = new byte[CalculateSizeOfLevel(level)]; // Try to read as many bytes as we can into the level data buffer, // but we may not be able to due to bugs in F-Zero GX / SMB2. int sizeToRead = Math.Min(levelData.Length, remainingSize); input.Read(levelData, 0, sizeToRead); remainingSize -= sizeToRead; encodedLevelData.Add(levelData); } if (TplVersionDetails.VerifyCorrectSize(game) && SizeOfTextureData(game) != totalLevelSize) { throw new InvalidTplFileException("Texture size doesn't match expected size."); } }
/// <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); }
/// <summary> /// Reads a texture with the specified characteristics from a binary stream. /// </summary> internal void LoadTextureData(EndianBinaryReader input, GxGame game, GxTextureFormat format, int width, int height, int levelCount) { if (!SupportedTextureFormats.Contains(format)) { throw new InvalidTplFileException("Unsupported texture format."); } this.format = format; this.width = width; this.height = height; for (int level = 0; level < levelCount; level++) { byte[] levelData = new byte[CalculateSizeOfLevel(level)]; input.Read(levelData, 0, CalculateSizeOfLevel(level, (game == GxGame.FZeroGX))); if (game == GxGame.SuperMonkeyBallDX) { if (format == GxTextureFormat.CMPR) { // Swap pallete byte order for (int i = 0; i < levelData.Length; i += 8) { byte temp = levelData[i]; levelData[i] = levelData[i + 1]; levelData[i + 1] = temp; temp = levelData[i + 2]; levelData[i + 2] = levelData[i + 3]; levelData[i + 3] = temp; } } } encodedLevelData.Add(levelData); } }