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> /// creates a thumbnail for one image layer/mipmap /// </summary> /// <param name="size">maximum width/height of the thumbnail</param> /// <param name="texture">source texture</param> /// <param name="dstFormat">destination texture format</param> /// <param name="layer">source layer</param> /// <returns>texture with width, height smaller or equal to size. One layer and one mipmap</returns> public TextureArray2D CreateThumbnail(int size, ITexture texture, SharpDX.DXGI.Format dstFormat, int layer) { Debug.Assert(ImageFormat.IsSupported(dstFormat)); Debug.Assert(ImageFormat.IsSupported(texture.Format)); // determine dimensions of output texture var width = 0; var height = 0; if (texture.Size.Width > texture.Size.Height) { width = size; height = (texture.Size.Height * size) / texture.Size.Width; } else { height = size; width = (texture.Size.Width * size) / texture.Size.Height; } Debug.Assert(width <= size); Debug.Assert(height <= size); var res = new TextureArray2D(1, 1, new Size3(width, height), dstFormat, false); var dev = Device.Get(); quad.Bind(false); if (texture.Is3D) { dev.Pixel.Set(convert3D.Pixel); } else { dev.Pixel.Set(convert2D.Pixel); } // compute which mipmap has the closest fit var mipmap = 0; var curWidth = texture.Size.Width; while (curWidth >= width) { ++mipmap; curWidth /= 2; } // mipmap just jumped over the optimal size mipmap = Math.Max(0, mipmap - 1); ITexture tmpTex = null; if (texture.NumMipmaps < mipmap + 1) { // generate new texture with mipmaps tmpTex = texture.GenerateMipmapLevels(mipmap + 1); dev.Pixel.SetShaderResource(0, tmpTex.GetSrView(layer, mipmap)); } else { dev.Pixel.SetShaderResource(0, texture.GetSrView(layer, mipmap)); } dev.Pixel.SetSampler(0, sampler); dev.OutputMerger.SetRenderTargets(res.GetRtView(0, 0)); dev.SetViewScissors(width, height); dev.DrawFullscreenTriangle(); // remove bindings dev.Pixel.SetShaderResource(0, null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); quad.Unbind(); tmpTex?.Dispose(); return(res); }