private void ImportTexture(ITexture tex, string file, GliFormat imgOriginalFormat) { try { models.Images.AddImage(tex, file, imgOriginalFormat); tex = null; // images is now owner } catch (ImagesModel.MipmapMismatch e) { // silently generate mipmaps and import if (models.Images.NumMipmaps > 1 && tex.NumMipmaps == 1) { var tmp = tex.GenerateMipmapLevels(models.Images.NumMipmaps); ImportTexture(tmp, file, imgOriginalFormat); } else { // don't just discard the mipmaps models.Window.ShowErrorDialog(e.Message); } } catch (Exception e) { models.Window.ShowErrorDialog(e.Message); } finally { tex?.Dispose(); } }
/// <summary> /// tries to add the image to the current collection. /// </summary> /// <exception cref="ImagesModel.MipmapMismatch">will be thrown if everything except the number of mipmaps matches</exception> /// <exception cref="Exception">will be thrown if the images does not match with the current set of images</exception> public void AddImage(ITexture image, string name, GliFormat originalFormat) { if (Images.Count == 0) // first image { InitDimensions(image); images.Add(new ImageData(image, name, originalFormat)); PrevNumImages = 0; OnPropertyChanged(nameof(NumImages)); OnPropertyChanged(nameof(NumLayers)); OnPropertyChanged(nameof(NumMipmaps)); OnPropertyChanged(nameof(IsHdr)); OnPropertyChanged(nameof(Size)); OnPropertyChanged(nameof(ImageType)); } else // test if compatible with previous images { TestCompability(image, name); // remember old properties var isHdr = IsHdr; images.Add(new ImageData(image, name, originalFormat)); PrevNumImages = NumImages - 1; OnPropertyChanged(nameof(NumImages)); if (isHdr != IsHdr) { OnPropertyChanged(nameof(IsHdr)); } } }
public static void SaveImage(Image image, string filename, string extension, GliFormat format, int quality = 0) { if (!Dll.image_save(image.Resource.Id, filename, extension, (uint)format, quality)) { throw new Exception(Dll.GetError()); } }
public static void CreateStorage(GliFormat format, int width, int height, int layer, int levels) { if (!create_storage((int)format, width, height, layer, levels)) { throw new Exception("create storage failed: " + GetError()); } }
internal ImageData(ITexture image, string filename, GliFormat originalFormat) { Image = image; Filename = filename; OriginalFormat = originalFormat; Alias = System.IO.Path.GetFileNameWithoutExtension(filename); }
public DllImageData(Resource resource, string filename, LayerMipmapCount lm, ImageFormat format, GliFormat originalFormat) : base(format, lm, GetSize(resource)) { Resource = resource; Filename = filename; OriginalFormat = originalFormat; }
public ImageFormat(GliFormat format) { GliFormat = format; switch (format) { case GliFormat.RGBA32_SFLOAT: DxgiFormat = Format.R32G32B32A32_Float; PixelSize = 4 * 4; break; case GliFormat.RGBA8_SRGB: DxgiFormat = Format.R8G8B8A8_UNorm_SRgb; PixelSize = 4; break; case GliFormat.RGBA8_UNORM: DxgiFormat = Format.R8G8B8A8_UNorm; PixelSize = 4; break; case GliFormat.RGBA8_SNORM: DxgiFormat = Format.R8G8B8A8_SNorm; PixelSize = 4; break; default: Debug.Assert(false); break; } }
/// <summary> /// tries to add the image to the current collection. /// </summary> /// <exception cref="ImagesModel.MipmapMismatch">will be thrown if everything except the number of mipmaps matches</exception> /// <exception cref="Exception">will be thrown if the images does not match with the current set of images</exception> public void AddImage(ITexture image, string name, GliFormat originalFormat) { if (Images.Count == 0) // first image { InitDimensions(image); images.Add(new ImageData(image, name, originalFormat)); PrevNumImages = 0; OnPropertyChanged(nameof(NumImages)); OnPropertyChanged(nameof(NumLayers)); OnPropertyChanged(nameof(NumMipmaps)); OnPropertyChanged(nameof(IsHdr)); OnPropertyChanged(nameof(Size)); OnPropertyChanged(nameof(ImageType)); } else // test if compatible with previous images { if (image.GetType() != ImageType) { throw new Exception($"{name}: Incompatible with internal texture types. Expected {ImageType.Name} but got {image.GetType().Name}"); } if (image.NumLayers != NumLayers) { throw new Exception( $"{name}: Inconsistent amount of layers. Expected {NumLayers} got {image.NumLayers}"); } if (image.Size != Size) { if (Size.Depth > 1) { throw new Exception( $"{name}: Image resolution mismatch. Expected {Size.X}x{Size.Y}x{Size.Z} but got {image.Size.X}x{image.Size.Y}x{image.Size.Z}"); } throw new Exception( $"{name}: Image resolution mismatch. Expected {Size.X}x{Size.Y} but got {image.Size.X}x{image.Size.Y}"); } if (image.NumMipmaps != NumMipmaps) { throw new ImagesModel.MipmapMismatch( $"{name}: Inconsistent amount of mipmaps. Expected {NumMipmaps} got {image.NumMipmaps}"); } // remember old properties var isHdr = IsHdr; images.Add(new ImageData(image, name, originalFormat)); PrevNumImages = NumImages - 1; OnPropertyChanged(nameof(NumImages)); if (isHdr != IsHdr) { OnPropertyChanged(nameof(IsHdr)); } } }
public ImageFormat(PixelFormat externalFormat, PixelType type, SizedInternalFormat internalFormat, bool isSrgb, bool isCompressed, GliFormat gliFormat = GliFormat.UNDEFINED) : this() { ExternalFormat = externalFormat; Type = type; InternalFormat = internalFormat; IsSrgb = isSrgb; IsCompressed = isCompressed; GliFormat = gliFormat; }
public ImageFormat(PixelFormat format, PixelType type, bool isSrgb) { ExternalFormat = format; Type = type; IsSrgb = isSrgb; IsCompressed = false; InternalFormat = (SizedInternalFormat)0; GliFormat = GliFormat.UNDEFINED; }
public ImageFormat(GliFormat format) { gli_to_opengl_format((int)format, out var intForm, out var extForm, out var pt, out var compressed, out var srgb); ExternalFormat = (PixelFormat)extForm; Type = (PixelType)pt; InternalFormat = (SizedInternalFormat)intForm; IsSrgb = srgb; IsCompressed = compressed; GliFormat = format; }
/// <param name="image">valid texture</param> /// <param name="isFile">indicates if the texture was loaded from a file</param> /// <param name="filename">original filename or proposed filename (when not directly imported)</param> /// <param name="alias">display name</param> /// <param name="originalFormat">original internal format</param> internal ImageData(ITexture image, bool isFile, [CanBeNull] string filename, [CanBeNull] string alias, GliFormat originalFormat) { Image = image; Filename = filename ?? ""; OriginalFormat = originalFormat; Alias = (alias ?? System.IO.Path.GetFileNameWithoutExtension(Filename)) ?? ""; if (isFile && File.Exists(Filename)) { LastModified = File.GetLastWriteTime(Filename); } }
public void Replace(ITexture image, GliFormat originalFormat) { if (ReferenceEquals(image, Image)) { return; } Image.Dispose(); Image = image; OriginalFormat = originalFormat; }
internal ImageData(ITexture image, string filename, GliFormat originalFormat) { Image = image; Filename = filename; OriginalFormat = originalFormat; Alias = System.IO.Path.GetFileNameWithoutExtension(filename); if (File.Exists(Filename)) { LastModified = File.GetLastWriteTime(Filename); } }
/// <summary> /// loads image into the correct texture type /// </summary> public static ITexture LoadImageTexture(string file, out GliFormat originalFormat) { using (var img = LoadImage(file)) { originalFormat = img.OriginalFormat; if (img.Is3D) { return(new Texture3D(img)); } return(new TextureArray2D(img)); } }
private static bool IsIntegerPrecisionFormat(GliFormat format) { switch (format.GetDataType()) { case PixelDataType.SInt: case PixelDataType.UInt: case PixelDataType.SScaled: case PixelDataType.UScaled: return(true); } return(false); }
// gets a suitability rating for the format based on the statistic values public int GetFormatRating(GliFormat format) { const int alphaMissWeight = 1000; // penalty if alpha channel is required but missing const int alphaMatchWeight = 5; // bonus for same alpha state const int signWeight = 10; const int unormWeight = 300; // determine basic properties of image bool hasAlpha = HasAlpha; bool isUnormed = Average.Min >= 0.0f && Average.Max <= 1.0f && Alpha.Min >= 0.0f && Alpha.Max <= 1.0f; bool isSigned = Average.Min < 0.0f; int rating = 0; // is alpha required? if (hasAlpha && !format.HasAlpha()) { rating -= alphaMissWeight; // alpha should be present if image needs alpha } else if (hasAlpha == format.HasAlpha()) { rating += alphaMatchWeight; // alpha state matching } // is a signed format required? var pixelType = format.GetDataType(); if (isSigned && !pixelType.IsSigned()) { rating -= signWeight; // signed format is required } else if (isSigned == pixelType.IsSigned()) { rating += signWeight; } // range 0 1? if (!isUnormed && pixelType == PixelDataType.UNorm) // unorm is not sufficient { rating -= unormWeight; } else if (!isUnormed && pixelType == PixelDataType.Srgb) // maybe tonemapping to srgb? better than unorm probably { rating -= unormWeight / 10; } //else if (isUnormed == pixelType.IsUnormed()) // rating += unormWeight; return(rating); }
public Image(Resource resource, string filename, LayerMipmapCount lm, ImageFormat format, GliFormat originalFormat) { Resource = resource; Filename = filename; Format = format; OriginalFormat = originalFormat; // load relevant information Layers = new List <Layer>(lm.Layers); for (var curLayer = 0; curLayer < lm.Layers; ++curLayer) { Layers.Add(new Layer(resource, curLayer, lm.Mipmaps)); } }
public Image(Resource resource, string filename, int nLayer, int nMipmaps, ImageFormat format, GliFormat originalFormat) { Resource = resource; Filename = filename; Format = format; OriginalFormat = originalFormat; // load relevant information Layers = new List <Layer>(nLayer); for (var curLayer = 0; curLayer < nLayer; ++curLayer) { Layers.Add(new Layer(resource, curLayer, nMipmaps)); } }
/// gets suitability rating for format and takes preferred format into account public int GetFormatRating(GliFormat format, GliFormat preferredFormat) { var rating = GetFormatRating(format); var preferredPixelType = preferredFormat.GetDataType(); var pixelType = format.GetDataType(); bool isSrgb = preferredPixelType == PixelDataType.Srgb; bool hasRgb = preferredFormat.HasRgb(); if (format == preferredFormat) { rating += 150; } // keep srgb specifier if (isSrgb == (format.GetDataType() == PixelDataType.Srgb)) { rating += 200; } else { rating -= 200; } // small bonus for same datatype if (preferredPixelType == pixelType) { rating += 5; } // small bonus for rgb match if (hasRgb == format.HasRgb()) { rating += 15; } // small bonus for high precision if (!preferredFormat.IsLessThan8Bit() && !format.IsLessThan8Bit()) { rating += 20; } // small bonus for kept compression if (preferredFormat.IsCompressed() && format.IsCompressed()) { rating += 10; } return(rating); }
/// <summary> /// replaces an existing image. (Name will be kept) /// </summary> /// <param name="idx">replace idx</param> /// <param name="image">new image</param> /// <param name="originalFormat">new format</param> public void ReplaceImage(int idx, ITexture image, GliFormat originalFormat) { Debug.Assert(idx < NumImages); TestCompability(image, images[idx].Filename); // remember old properties var isHdr = IsHdr; images[idx].Replace(image, originalFormat); OnPropertyChanged(nameof(ImageOrder)); if (isHdr != IsHdr) { OnPropertyChanged(nameof(IsHdr)); } }
/// <summary> /// exports a pipeline image with the given format and extension. /// Apply will be called by this method if required /// </summary> /// <param name="filename"></param> /// <param name="extension"></param> /// <param name="format"></param> /// <param name="pipelineId"></param> public void ExportPipelineImage(string filename, string extension, GliFormat format, int pipelineId = 0) { if (!Pipelines[pipelineId].IsValid) { throw new Exception($"current image formula is invalid. At least " + $"{Math.Max(Math.Max(Pipelines[pipelineId].Color.MaxImageId, Pipelines[pipelineId].Alpha.MaxImageId), 1)} " + $"images are required for it to be valid"); } // apply changes before exporting Apply(); var desc = new ExportDescription(Pipelines[pipelineId].Image, filename, extension) { FileFormat = format }; Export.Export(desc); }
public static bool IsSupported(GliFormat format) { switch (format) { // unsupported general case GliFormat.UNDEFINED: // unsupported srgb formats case GliFormat.R8_SRGB_PACK8: case GliFormat.RG8_SRGB_PACK8: // double precision case GliFormat.R64_SFLOAT_PACK64: case GliFormat.RG64_SFLOAT_PACK64: case GliFormat.RGB64_SFLOAT_PACK64: case GliFormat.RGBA64_SFLOAT_PACK64: // some extension case GliFormat.RG4_UNORM_PACK8: case GliFormat.RGB10A2_SSCALED_PACK32: case GliFormat.RGB10A2_SNORM_PACK32: // depth and stencil formats case GliFormat.D16_UNORM_PACK16: case GliFormat.D24_UNORM_PACK32: case GliFormat.D32_SFLOAT_PACK32: // unsupported GTC formats (maked gtc in gl.inl line 60+) case GliFormat.A1RGB5_UNORM_PACK16: // GTC USCALED case GliFormat.R8_USCALED_PACK8: case GliFormat.R8_SSCALED_PACK8: case GliFormat.RG8_USCALED_PACK8: case GliFormat.RG8_SSCALED_PACK8: case GliFormat.RGB8_USCALED_PACK8: case GliFormat.RGB8_SSCALED_PACK8: case GliFormat.BGR8_USCALED_PACK8: case GliFormat.BGR8_SSCALED_PACK8: case GliFormat.RGBA8_USCALED_PACK8: case GliFormat.RGBA8_SSCALED_PACK8: case GliFormat.BGRA8_USCALED_PACK8: case GliFormat.BGRA8_SSCALED_PACK8: case GliFormat.RGBA8_USCALED_PACK32: case GliFormat.RGBA8_SSCALED_PACK32: case GliFormat.RGB10A2_USCALED_PACK32: case GliFormat.BGR10A2_USCALED_PACK32: case GliFormat.BGR10A2_SSCALED_PACK32: case GliFormat.R16_USCALED_PACK16: case GliFormat.R16_SSCALED_PACK16: case GliFormat.RG16_USCALED_PACK16: case GliFormat.RG16_SSCALED_PACK16: case GliFormat.RGB16_USCALED_PACK16: case GliFormat.RGB16_SSCALED_PACK16: case GliFormat.RGBA16_USCALED_PACK16: case GliFormat.RGBA16_SSCALED_PACK16: // unsupported because the viewer is not designed for INTEGER targets case GliFormat.R8_UINT_PACK8: case GliFormat.R8_SINT_PACK8: case GliFormat.RG8_UINT_PACK8: case GliFormat.RG8_SINT_PACK8: case GliFormat.RGB8_UINT_PACK8: case GliFormat.RGB8_SINT_PACK8: case GliFormat.BGR8_UINT_PACK8: case GliFormat.BGR8_SINT_PACK8: case GliFormat.RGBA8_UINT_PACK8: case GliFormat.RGBA8_SINT_PACK8: case GliFormat.BGRA8_UINT_PACK8: case GliFormat.BGRA8_SINT_PACK8: case GliFormat.RGBA8_UINT_PACK32: case GliFormat.RGBA8_SINT_PACK32: case GliFormat.RGB10A2_UINT_PACK32: case GliFormat.RGB10A2_SINT_PACK32: case GliFormat.BGR10A2_UINT_PACK32: case GliFormat.BGR10A2_SINT_PACK32: case GliFormat.R16_UINT_PACK16: case GliFormat.R16_SINT_PACK16: case GliFormat.RG16_UINT_PACK16: case GliFormat.RG16_SINT_PACK16: case GliFormat.RGB16_UINT_PACK16: case GliFormat.RGB16_SINT_PACK16: case GliFormat.RGBA16_UINT_PACK16: case GliFormat.RGBA16_SINT_PACK16: case GliFormat.R32_UINT_PACK32: case GliFormat.R32_SINT_PACK32: case GliFormat.RG32_UINT_PACK32: case GliFormat.RG32_SINT_PACK32: case GliFormat.RGB32_UINT_PACK32: case GliFormat.RGB32_SINT_PACK32: case GliFormat.RGBA32_UINT_PACK32: case GliFormat.RGBA32_SINT_PACK32: case GliFormat.R64_UINT_PACK64: case GliFormat.R64_SINT_PACK64: case GliFormat.RG64_UINT_PACK64: case GliFormat.RG64_SINT_PACK64: case GliFormat.RGB64_UINT_PACK64: case GliFormat.RGB64_SINT_PACK64: case GliFormat.RGBA64_UINT_PACK64: case GliFormat.RGBA64_SINT_PACK64: case GliFormat.S8_UINT_PACK8: case GliFormat.D16_UNORM_S8_UINT_PACK32: case GliFormat.D24_UNORM_S8_UINT_PACK32: case GliFormat.D32_SFLOAT_S8_UINT_PACK64: return(false); case GliFormat.RGBA4_UNORM_PACK16: case GliFormat.BGRA4_UNORM_PACK16: case GliFormat.R5G6B5_UNORM_PACK16: case GliFormat.B5G6R5_UNORM_PACK16: case GliFormat.RGB5A1_UNORM_PACK16: case GliFormat.BGR5A1_UNORM_PACK16: case GliFormat.R8_UNORM_PACK8: case GliFormat.R8_SNORM_PACK8: case GliFormat.RG8_UNORM_PACK8: case GliFormat.RG8_SNORM_PACK8: case GliFormat.RGB8_UNORM_PACK8: case GliFormat.RGB8_SNORM_PACK8: case GliFormat.RGB8_SRGB_PACK8: case GliFormat.BGR8_UNORM_PACK8: case GliFormat.BGR8_SNORM_PACK8: case GliFormat.BGR8_SRGB_PACK8: case GliFormat.RGBA8_UNORM_PACK8: case GliFormat.RGBA8_SNORM_PACK8: case GliFormat.RGBA8_SRGB_PACK8: case GliFormat.BGRA8_UNORM_PACK8: case GliFormat.BGRA8_SNORM_PACK8: case GliFormat.BGRA8_SRGB_PACK8: case GliFormat.RGBA8_UNORM_PACK32: case GliFormat.RGBA8_SNORM_PACK32: case GliFormat.RGBA8_SRGB_PACK32: case GliFormat.RGB10A2_UNORM_PACK32: case GliFormat.BGR10A2_UNORM_PACK32: case GliFormat.BGR10A2_SNORM_PACK32: case GliFormat.R16_UNORM_PACK16: case GliFormat.R16_SNORM_PACK16: case GliFormat.R16_SFLOAT_PACK16: case GliFormat.RG16_UNORM_PACK16: case GliFormat.RG16_SNORM_PACK16: case GliFormat.RG16_SFLOAT_PACK16: case GliFormat.RGB16_UNORM_PACK16: case GliFormat.RGB16_SNORM_PACK16: case GliFormat.RGB16_SFLOAT_PACK16: case GliFormat.RGBA16_UNORM_PACK16: case GliFormat.RGBA16_SNORM_PACK16: case GliFormat.RGBA16_SFLOAT_PACK16: case GliFormat.R32_SFLOAT_PACK32: case GliFormat.RG32_SFLOAT_PACK32: case GliFormat.RGB32_SFLOAT_PACK32: case GliFormat.RGBA32_SFLOAT_PACK32: case GliFormat.RG11B10_UFLOAT_PACK32: case GliFormat.RGB9E5_UFLOAT_PACK32: case GliFormat.RGB_DXT1_UNORM_BLOCK8: case GliFormat.RGB_DXT1_SRGB_BLOCK8: case GliFormat.RGBA_DXT1_UNORM_BLOCK8: case GliFormat.RGBA_DXT1_SRGB_BLOCK8: case GliFormat.RGBA_DXT3_UNORM_BLOCK16: case GliFormat.RGBA_DXT3_SRGB_BLOCK16: case GliFormat.RGBA_DXT5_UNORM_BLOCK16: case GliFormat.RGBA_DXT5_SRGB_BLOCK16: case GliFormat.R_ATI1N_UNORM_BLOCK8: case GliFormat.R_ATI1N_SNORM_BLOCK8: case GliFormat.RG_ATI2N_UNORM_BLOCK16: case GliFormat.RG_ATI2N_SNORM_BLOCK16: case GliFormat.RGB_BP_UFLOAT_BLOCK16: case GliFormat.RGB_BP_SFLOAT_BLOCK16: case GliFormat.RGBA_BP_UNORM_BLOCK16: case GliFormat.RGBA_BP_SRGB_BLOCK16: case GliFormat.RGB_ETC2_UNORM_BLOCK8: case GliFormat.RGB_ETC2_SRGB_BLOCK8: case GliFormat.RGBA_ETC2_UNORM_BLOCK8: case GliFormat.RGBA_ETC2_SRGB_BLOCK8: case GliFormat.RGBA_ETC2_UNORM_BLOCK16: case GliFormat.RGBA_ETC2_SRGB_BLOCK16: case GliFormat.R_EAC_UNORM_BLOCK8: case GliFormat.R_EAC_SNORM_BLOCK8: case GliFormat.RG_EAC_UNORM_BLOCK16: case GliFormat.RG_EAC_SNORM_BLOCK16: case GliFormat.RGBA_ASTC_4X4_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_4X4_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_5X4_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_5X4_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_5X5_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_5X5_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_6X5_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_6X5_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_6X6_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_6X6_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_8X5_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_8X5_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_8X6_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_8X6_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_8X8_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_8X8_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_10X5_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_10X5_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_10X6_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_10X6_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_10X8_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_10X8_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_10X10_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_10X10_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_12X10_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_12X10_SRGB_BLOCK16: case GliFormat.RGBA_ASTC_12X12_UNORM_BLOCK16: case GliFormat.RGBA_ASTC_12X12_SRGB_BLOCK16: case GliFormat.RGB_PVRTC1_8X8_UNORM_BLOCK32: case GliFormat.RGB_PVRTC1_8X8_SRGB_BLOCK32: case GliFormat.RGB_PVRTC1_16X8_UNORM_BLOCK32: case GliFormat.RGB_PVRTC1_16X8_SRGB_BLOCK32: case GliFormat.RGBA_PVRTC1_8X8_UNORM_BLOCK32: case GliFormat.RGBA_PVRTC1_8X8_SRGB_BLOCK32: case GliFormat.RGBA_PVRTC1_16X8_UNORM_BLOCK32: case GliFormat.RGBA_PVRTC1_16X8_SRGB_BLOCK32: case GliFormat.RGBA_PVRTC2_4X4_UNORM_BLOCK8: case GliFormat.RGBA_PVRTC2_4X4_SRGB_BLOCK8: case GliFormat.RGBA_PVRTC2_8X4_UNORM_BLOCK8: case GliFormat.RGBA_PVRTC2_8X4_SRGB_BLOCK8: case GliFormat.RGB_ETC_UNORM_BLOCK8: case GliFormat.RGB_ATC_UNORM_BLOCK8: case GliFormat.RGBA_ATCA_UNORM_BLOCK16: case GliFormat.RGBA_ATCI_UNORM_BLOCK16: case GliFormat.L8_UNORM_PACK8: case GliFormat.A8_UNORM_PACK8: case GliFormat.LA8_UNORM_PACK8: case GliFormat.L16_UNORM_PACK16: case GliFormat.A16_UNORM_PACK16: case GliFormat.LA16_UNORM_PACK16: case GliFormat.BGR8_UNORM_PACK32: case GliFormat.BGR8_SRGB_PACK32: case GliFormat.RG3B2_UNORM_PACK8: return(true); } return(false); }
private void CompareAfterExport(string inputImage, string outputImage, string outputExtension, GliFormat format, Color.Channel channels = Color.Channel.Rgb, float tolerance = 0.01f) { var model = new Models(1); model.AddImageFromFile(inputImage); model.Apply(); var origTex = (TextureArray2D)model.Pipelines[0].Image; model.Export.Export(new ExportDescription(origTex, outputImage, outputExtension) { FileFormat = format, Quality = 100 }); var expTex = new TextureArray2D(IO.LoadImage(outputImage + "." + outputExtension)); foreach (var lm in origTex.LayerMipmap.Range) { var origColors = origTex.GetPixelColors(lm); var expColor = expTex.GetPixelColors(lm); TestData.CompareColors(origColors, expColor, channels, tolerance); } }
public void Replace(ITexture image, GliFormat originalFormat) { Image.Dispose(); Image = image; OriginalFormat = originalFormat; }
public ExportViewModel(ModelsEx models, string extension, GliFormat preferredFormat, string filename, bool is3D, DefaultStatistics stats) { this.models = models; this.extension = extension; this.filename = filename; this.is3D = is3D; this.usedFormat = models.Export.Formats.First(fmt => fmt.Extension == extension); models.Display.IsExporting = true; Quality = models.Settings.LastQuality; // init layers for (var i = 0; i < models.Images.NumLayers; ++i) { AvailableLayers.Add(new ListItemViewModel <int> { Cargo = i, Name = "Layer " + i }); } selectedLayer = AvailableLayers[models.Export.Layer]; Debug.Assert(selectedLayer.Cargo == models.Export.Layer); // init mipmaps for (var i = 0; i < models.Images.NumMipmaps; ++i) { AvailableMipmaps.Add(new ListItemViewModel <int> { Cargo = i, Name = "Mipmap " + i }); } selectedMipmap = AvailableMipmaps[models.Export.Mipmap]; Debug.Assert(selectedMipmap.Cargo == models.Export.Mipmap); // all layer option for ktx and dds if (models.Images.NumLayers > 1 && (extension == "ktx" || extension == "dds")) { AvailableLayers.Add(new ListItemViewModel <int> { Cargo = -1, Name = "All Layer" }); selectedLayer = AvailableLayers.Last(); models.Export.Layer = selectedLayer.Cargo; } // all mipmaps option for ktx and dds if (models.Images.NumMipmaps > 1 && (extension == "ktx" || extension == "dds")) { AvailableMipmaps.Add(new ListItemViewModel <int> { Cargo = -1, Name = "All Mipmaps" }); selectedMipmap = AvailableMipmaps.Last(); models.Export.Mipmap = selectedMipmap.Cargo; } // init available pixel data types var usedPixelTypes = new SortedSet <PixelDataType>(); foreach (var format in usedFormat.Formats) { // exclude some formats for 3d export if (is3D && format.IsExcludedFrom3DExport()) { continue; } allFormats.Add(new ListItemViewModel <GliFormat> { Cargo = format, Name = format.ToString(), ToolTip = format.GetDescription() }); formatRatings.Add(stats.GetFormatRating(format, preferredFormat)); usedPixelTypes.Add(format.GetDataType()); } if (usedPixelTypes.Count > 1) { AvailableDataTypes.Add(new ListItemViewModel <PixelDataType> { Cargo = PixelDataType.Undefined, Name = "All" }); } var preferredPixelType = preferredFormat.GetDataType(); foreach (var usedPixelType in usedPixelTypes) { AvailableDataTypes.Add(new ListItemViewModel <PixelDataType> { Cargo = usedPixelType, Name = usedPixelType.ToString(), ToolTip = usedPixelType.GetDescription() }); if (usedPixelType == preferredPixelType) { SelectedDataType = AvailableDataTypes.Last(); } } if (SelectedDataType == null) { SelectedDataType = AvailableDataTypes[0]; } // assert that those were were set by SelectedDataType Debug.Assert(AvailableFormats != null); Debug.Assert(SelectedFormat != null); // enable quality if (extension == "jpg") { hasQualityValue = true; nonSrgbExportWarnings = true; } else if (extension == "bmp") { nonSrgbExportWarnings = true; } else { SetKtxDdsQuality(); } models.Export.PropertyChanged += ExportOnPropertyChanged; if (models.Export.CropEndX == 0 && models.Export.CropEndY == 0 && models.Export.CropEndZ == 0) { // assume cropping was not set SetMaxCropping(); } }
/// gets suitability rating for format and takes preferred format into account public int GetFormatRating(GliFormat format, GliFormat preferredFormat) { var rating = GetFormatRating(format); var preferredPixelType = preferredFormat.GetDataType(); var pixelType = format.GetDataType(); bool isSrgb = preferredPixelType == PixelDataType.Srgb; bool hasRgb = preferredFormat.HasRgb(); if (format == preferredFormat) { rating += 150; } // keep srgb specifier if (isSrgb == (pixelType == PixelDataType.Srgb)) { rating += 200; } else { // prefer srgb formats over unorm etc. when converting from hdr to ldr if (!preferredFormat.IsAtMost8bit() && !preferredPixelType.IsUnormed() && pixelType == PixelDataType.Srgb) { rating -= 50; } else { rating -= 200; } } // small bonus for same datatype if (preferredPixelType == pixelType) { rating += 5; } // small bonus for rgb match if (hasRgb == format.HasRgb()) { rating += 15; } // small bonus for high precision if (!preferredFormat.IsLessThan8Bit() && !format.IsLessThan8Bit()) { rating += 20; } // small bonus for kept compression if (preferredFormat.IsCompressed() && format.IsCompressed()) { rating += 10; } // try to keep hdr formats if (!preferredFormat.IsAtMost8bit() && !format.IsAtMost8bit()) { // keep unorm property if (preferredPixelType.IsUnormed() == pixelType.IsUnormed()) { rating += 50; } } return(rating); }
private void CompareAfterExport(string inputImage, string outputImage, string outputExtension, GliFormat format, Color.Channel channels = Color.Channel.Rgb, float tolerance = 0.01f) { var model = new Models(1); model.AddImageFromFile(inputImage); model.Apply(); var origTex = (TextureArray2D)model.Pipelines[0].Image; model.Export.Quality = 100; model.Export.Export(origTex, new ExportDescription(outputImage, outputExtension, model.Export) { FileFormat = format }); var expTex = new TextureArray2D(IO.LoadImage(outputImage + "." + outputExtension)); for (int curLayer = 0; curLayer < origTex.NumLayers; ++curLayer) { for (int curMipmap = 0; curMipmap < origTex.NumMipmaps; ++curMipmap) { var origColors = origTex.GetPixelColors(curLayer, curMipmap); var expColor = expTex.GetPixelColors(curLayer, curMipmap); TestData.CompareColors(origColors, expColor, channels, tolerance); } } }
internal ImageData(ITexture image, string filename, GliFormat originalFormat) { Image = image; Filename = filename; OriginalFormat = originalFormat; }