private void ImportTexture(ITexture tex, string file, GliFormat imgOriginalFormat, string alias) { try { models.Images.AddImage(tex, true, file, imgOriginalFormat, alias); 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.CloneWithMipmaps(models.Images.NumMipmaps); models.Scaling.WriteMipmaps(tmp); ImportTexture(tmp, file, imgOriginalFormat, alias); } else { // don't just discard the mipmaps models.Window.ShowErrorDialog(e); } } catch (Exception e) { models.Window.ShowErrorDialog(e); } 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, ScalingModel scaling) { 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(LayerMipmapCount.One, new Size3(width, height), dstFormat, false); // 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); var dev = Device.Get(); ITexture tmpTex = null; if (texture.NumMipmaps < mipmap + 1) { // generate new texture with mipmaps tmpTex = texture.CloneWithMipmaps(mipmap + 1); scaling.WriteMipmaps(tmpTex); dev.Pixel.SetShaderResource(0, tmpTex.GetSrView(new LayerMipmapSlice(layer, mipmap))); } else { dev.Pixel.SetShaderResource(0, texture.GetSrView(new LayerMipmapSlice(layer, mipmap))); } quad.Bind(false); if (texture.Is3D) { dev.Pixel.Set(convert3D.Pixel); } else { dev.Pixel.Set(convert2D.Pixel); } dev.Pixel.SetSampler(0, sampler); dev.OutputMerger.SetRenderTargets(res.GetRtView(LayerMipmapSlice.Mip0)); dev.SetViewScissors(width, height); dev.DrawFullscreenTriangle(1); // remove bindings dev.Pixel.SetShaderResource(0, null); dev.OutputMerger.SetRenderTargets((RenderTargetView)null); quad.Unbind(); tmpTex?.Dispose(); return(res); }