Beispiel #1
0
        public void DdsDirectXCompability()
        {
            var model = new Models(1);

            model.AddImageFromFile(TestData.Directory + "small_scaled.png");
            model.Apply();
            model.Export.Quality = 100;
            var origTex = (TextureArray2D)model.Pipelines[0].Image;
            // normal colors
            var origColors = origTex.GetPixelColors(0, 0);

            // colors multiplied by 100 for integer precision formats
            model.Pipelines[0].Color.Formula = "I0 * 100";
            model.Apply();
            var integerTex    = (TextureArray2D)model.Pipelines[0].Image;
            var origColors100 = integerTex.GetPixelColors(0, 0);

            Color[] newColors = null;

            var    eFmt      = model.Export.Formats.First(fmt => fmt.Extension == "dds");
            string errors    = "";
            int    numErrors = 0;

            foreach (var format in eFmt.Formats)
            {
                try
                {
                    // export to dds
                    var isIntegerPrecision = IsIntegerPrecisionFormat(format);
                    var desc = new ExportDescription(ExportDir + "tmp", "dds", model.Export);
                    desc.FileFormat = format;
                    if (isIntegerPrecision)
                    {
                        desc.Multiplier = 100.0f;
                    }
                    model.Export.Export(origTex, desc);

                    // load with directx dds loader
                    DDSTextureLoader.CreateDDSTextureFromFile(Device.Get().Handle, Device.Get().ContextHandle, ExportDir + "tmp.dds",
                                                              out var resource, out var resourceView, 0, out var alphaMode);

                    // convert to obtain color data
                    using (var newTex = model.Export.convert.ConvertFromRaw(resourceView, origTex.Size, Format.R32G32B32A32_Float, isIntegerPrecision))
                    {
                        resourceView.Dispose();
                        resource.Dispose();

                        newColors = newTex.GetPixelColors(0, 0);
                        // only compare with red channel since some formats only store red
                        if (isIntegerPrecision)
                        {
                            TestData.CompareColors(origColors100, newColors, Color.Channel.R, 1.0f);
                        }
                        else
                        {
                            TestData.CompareColors(origColors, newColors, Color.Channel.R, 0.1f);
                        }
                    }
                }
                catch (Exception e)
                {
                    errors += $"{format}: {e.Message}\n";
                    ++numErrors;
                }
            }

            if (errors.Length > 0)
            {
                throw new Exception($"directX compability failed for {numErrors}/{eFmt.Formats.Count} formats:\n" + errors);
            }
        }
Beispiel #2
0
        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            = ExportDescription.GetExportFormat(extension);
            models.Display.IsExporting = true;

            // init layers
            for (var i = 0; i < models.Images.NumLayers; ++i)
            {
                AvailableLayers.Add(new ListItemViewModel <int>
                {
                    Cargo = i,
                    Name  = "Layer " + i
                });
            }

            models.ExportConfig.Layer = models.Display.ActiveLayer;
            selectedLayer             = AvailableLayers[models.Display.ActiveLayer];
            Debug.Assert(selectedLayer.Cargo == models.Display.ActiveLayer);

            // init mipmaps
            for (var i = 0; i < models.Images.NumMipmaps; ++i)
            {
                AvailableMipmaps.Add(new ListItemViewModel <int>
                {
                    Cargo = i,
                    Name  = "Mipmap " + i
                });
            }

            models.ExportConfig.Mipmap = models.Display.ActiveMipmap;
            selectedMipmap             = AvailableMipmaps[models.Display.ActiveMipmap];
            Debug.Assert(selectedMipmap.Cargo == models.Display.ActiveMipmap);

            // 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.ExportConfig.Layer = -1;
            }

            // 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.ExportConfig.Mipmap = -1;
            }

            // 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.ExportConfig.PropertyChanged += ExportConfigOnPropertyChanged;
            models.Settings.PropertyChanged     += SettingsOnPropertyChanged;

            if (models.ExportConfig.CropEnd == Float3.Zero)
            {
                // assume cropping was not set
                SetMaxCropping();
            }
        }
Beispiel #3
0
        public override async void Execute()
        {
            // make sure only one image is visible
            if (models.NumEnabled != 1)
            {
                models.Window.ShowErrorDialog("Exactly one image equation should be visible when exporting.");
                return;
            }

            // get active final image
            var id  = models.GetFirstEnabledPipeline();
            var tex = models.Pipelines[id].Image;

            if (tex == null)
            {
                return;              // not yet computed?
            }
            float multiplier = 1.0f;

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (models.Display.Multiplier != 1.0f)
            {
                if (models.Window.ShowYesNoDialog(
                        $"Color multiplier is currently set to {models.Display.MultiplierString}. Do you want to include the multiplier in the export?",
                        "Keep Color Multiplier?"))
                {
                    multiplier = models.Display.Multiplier;
                }
            }

            if (path.InitFromEquations(models))
            {
                // open save file dialog
                Debug.Assert(path.Directory != null);
                Debug.Assert(path.Filename != null);
            }

            // set proposed filename
            var firstImageId = models.Pipelines[id].Color.FirstImageId;

            if (exportFormat == null)
            {
                exportFormat = models.Images.Images[firstImageId].OriginalFormat;
            }

            var sfd = new SaveFileDialog
            {
                Filter           = GetFilter(path.Extension, tex.Is3D),
                InitialDirectory = path.Directory,
                FileName         = path.Filename
            };

            if (sfd.ShowDialog(models.Window.TopmostWindow) != true)
            {
                return;
            }

            path.UpdateFromFilename(sfd.FileName);

            var viewModel = new ExportViewModel(models, path.Extension, exportFormat.Value, sfd.FileName, tex.Is3D, models.Statistics[id].Stats);
            var dia       = new ExportDialog(viewModel);

            if (models.Window.ShowDialog(dia) != true)
            {
                return;
            }

            var desc = new ExportDescription(tex, path.Directory + "/" + path.Filename, path.Extension)
            {
                Multiplier  = multiplier,
                Mipmap      = models.ExportConfig.Mipmap,
                Layer       = models.ExportConfig.Layer,
                UseCropping = models.ExportConfig.UseCropping,
                CropStart   = models.ExportConfig.CropStart,
                CropEnd     = models.ExportConfig.CropEnd,
                Overlay     = models.Overlay.Overlay
            };

            desc.TrySetFormat(viewModel.SelectedFormatValue);
            exportFormat = desc.FileFormat;

            models.Export.ExportAsync(desc);

            // export additional zoom boxes?
            if (viewModel.HasZoomBox && viewModel.ExportZoomBox)
            {
                for (int i = 0; i < models.ZoomBox.Boxes.Count; ++i)
                {
                    var box   = models.ZoomBox.Boxes[i];
                    var zdesc = new ExportDescription(tex, $"{path.Directory}/{path.Filename}_zoom{i}",
                                                      path.Extension)
                    {
                        Multiplier  = multiplier,
                        Mipmap      = models.ExportConfig.Mipmap,
                        Layer       = models.ExportConfig.Layer,
                        UseCropping = true,
                        CropStart   = new Float3(box.Start, 0.0f),
                        CropEnd     = new Float3(box.End, 1.0f),
                        Overlay     = viewModel.ZoomBorders ? models.Overlay.Overlay : null,
                        Scale       = viewModel.ZoomBoxScale
                    };
                    zdesc.TrySetFormat(viewModel.SelectedFormatValue);

                    await models.Progress.WaitForTaskAsync();

                    models.Export.ExportAsync(zdesc);
                }
            }
        }
Beispiel #4
0
        private void TryExportAllFormatsAndCompareGray(string outputExtension, bool onlySrgb = false)
        {
            var model = new Models(2);

            model.AddImageFromFile(TestData.Directory + "gray.png");
            model.Apply();
            var tex = (TextureArray2D)model.Pipelines[0].Image;

            var eFmt = ExportDescription.GetExportFormat(outputExtension);

            string errors    = "";
            int    numErrors = 0;

            var lastTexel = tex.Size.Product - 1;

            Color[] colors = null;
            var     i      = 0;

            foreach (var format in eFmt.Formats)
            {
                if (onlySrgb && format.GetDataType() != PixelDataType.Srgb)
                {
                    continue;
                }
                try
                {
                    int numTries = 0;
                    while (true)
                    {
                        try
                        {
                            var integerPrecision = IsIntegerPrecisionFormat(format);
                            var desc             = new ExportDescription(tex, ExportDir + "gray" + ++i, outputExtension);
                            desc.FileFormat = format;
                            desc.Quality    = 100;
                            if (integerPrecision)
                            {
                                desc.Multiplier = 100.0f;
                            }

                            model.Export.Export(desc);
                            Thread.Sleep(1);

                            // load and compare gray tone
                            using (var newTex = new TextureArray2D(IO.LoadImage($"{ExportDir}gray{i}.{outputExtension}")))
                            {
                                Assert.AreEqual(8, newTex.Size.Width);
                                Assert.AreEqual(4, newTex.Size.Height);
                                colors = newTex.GetPixelColors(LayerMipmapSlice.Mip0);
                                // compare last texel
                                var grayColor = colors[lastTexel];

                                float tolerance = 0.01f;
                                if (format.IsLessThan8Bit())
                                {
                                    tolerance = 0.1f;
                                }

                                // some formats don't write to red
                                // ReSharper disable once CompareOfFloatsByEqualityOperator
                                //if(grayColor.Red != 0.0f) Assert.AreEqual(TestData.Gray, grayColor.Red, tolerance);
                                if (integerPrecision)
                                {
                                    Assert.AreEqual(TestData.Gray * 100.0f, grayColor.Red, 1.0f);
                                }
                                else
                                {
                                    Assert.AreEqual(TestData.Gray, grayColor.Red, tolerance);
                                }
                                //else Assert.AreEqual(TestData.Gray, grayColor.Green, tolerance);
                                break;
                            }
                        }
                        catch (Exception)
                        {
                            ++numTries;
                            if (numTries > 3)
                            {
                                throw;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    errors += $"{format.ToString()}: {e.Message}\n";
                    ++numErrors;
                }
            }

            if (errors.Length > 0)
            {
                throw new Exception($"gray comparision failed for {numErrors}/{eFmt.Formats.Count} formats:\n" + errors);
            }
        }