Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
TextureTool.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.IO;
5 using System.Collections.Generic;
6 using SiliconStudio.Core.Diagnostics;
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Paradox.Graphics;
9 using SiliconStudio.TextureConverter.Requests;
10 using SiliconStudio.TextureConverter.TexLibraries;
11 using System.Runtime.CompilerServices;
12 
13 namespace SiliconStudio.TextureConverter
14 {
15 
16  /// <summary>
17  /// Provides method to load images or textures, to modify them and to convert them with different texture compression format.
18  /// Input supported format : gif, png, jpe, pds (Every FreeImage supported format...), dds, pvr, ktx.
19  /// Output format : gif, png, jpe, pds (Every FreeImage supported format...), dds, pvr, ktx.
20  /// Compression format : DXT1-5, ATC, PVRTC1-2, ETC1-2, uncompressed formats (BGRA8888, RGBA8888)
21  /// Image processing : resize, flip, gamma correction
22  /// Texture utilities : Mipmap generation, normal map generation
23  /// </summary>
24  public class TextureTool : IDisposable
25  {
26 
27  /// <summary>
28  /// The list of texture processing libraries
29  /// </summary>
30  private List<ITexLibrary> textureLibraries;
31 
32  private static Logger Log = GlobalLogger.GetLogger("TextureTool");
33 
34  /// <summary>
35  /// Initializes a new instance of the <see cref="TextureTool"/> class.
36  /// </summary>
37  /// <remarks>
38  /// Creating instance of each texture processing libraries. For a multithreaded use, one instance of <see cref="TextureTool"/> should be created per thread.
39  /// </remarks>
40  public TextureTool()
41  {
42  textureLibraries = new List<ITexLibrary>
43  {
44  new AtitcTexLibrary(), // used to compress/decompress texture with ATI compression format (ATITC)
45  new DxtTexLib(), // used to compress/decompress texture to DXT1-5 and load/save *.dds compressed texture files.
46  new FITexLib(), // used to open/save common bitmap image formats.
47  new ParadoxTexLibrary(), // used to save/load paradox texture format.
48  new PvrttTexLib(), // used to compress/decompress texture to PVRTC1-2 and ETC1-2 and load/save *.pvr compressed texture file.
49  new ColorKeyTexLibrary(), // used to apply ColorKey on R8G8B8A8/B8G8R8A8_Unorm
50  new AtlasTexLibrary(), // used to create and manipulate texture atlas
51  new ArrayTexLib(), // used to create and manipulate texture array and texture cube
52  };
53  }
54 
55  /// <summary>
56  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources for each texture porcessing libraries.
57  /// </summary>
58  public void Dispose()
59  {
60  foreach (ITexLibrary library in textureLibraries)
61  {
62  library.Dispose();
63  }
64  }
65 
66 
67  /// <summary>
68  /// Creates an atlas with the given TexImage.
69  /// </summary>
70  /// <param name="textureList">The texture list.</param>
71  /// <param name="forceSquaredAtlas">boolean to decide wheter the atlas will be squared (default is false).</param>
72  /// <returns>An instance of <see cref="TexAtlas"/>.</returns>
73  /// <exception cref="TextureToolsException">No available library could create the atlas.</exception>
74  public TexAtlas CreateAtlas(List<TexImage> textureList, bool forceSquaredAtlas = false)
75  {
76  TexAtlas atlas = new TexAtlas();
77  AtlasCreationRequest request = new AtlasCreationRequest(textureList, forceSquaredAtlas);
78 
79  ITexLibrary library = FindLibrary(atlas, request);
80  if(library == null)
81  {
82  Log.Error("No available library could create the atlas.");
83  throw new TextureToolsException("No available library could create the atlas.");
84  }
85 
86  atlas.Format = textureList[0].Format;
87  foreach (TexImage texture in textureList)
88  {
89  if (texture.Format != atlas.Format)
90  {
91  Log.Error("The textures in the list must all habe the same format.");
92  throw new TextureToolsException("The textures in the list must all habe the same format.");
93  }
94  texture.Update();
95  }
96 
97  ExecuteRequest(atlas, request);
98 
99  return atlas;
100  }
101 
102 
103  /// <summary>
104  /// Retrieves the atlas from a TexImage and its corresponding layout file.
105  /// </summary>
106  /// <param name="texture">The texture.</param>
107  /// <param name="layoutFile">The layout file.</param>
108  /// <returns>An instance of <see cref="TexAtlas"/>.</returns>
109  /// <exception cref="TextureToolsException">The layout file doesn't exist. Please check the file path.</exception>
110  public TexAtlas RetrieveAtlas(TexImage texture, string layoutFile)
111  {
112  if (!File.Exists(layoutFile))
113  {
114  Log.Error("The file " + layoutFile + " doesn't exist. Please check the file path.");
115  throw new TextureToolsException("The file " + layoutFile + " doesn't exist. Please check the file path.");
116  }
117 
118  return new TexAtlas(TexAtlas.TexLayout.Import(layoutFile), texture);
119  }
120 
121 
122  /// <summary>
123  /// Creates a texture array with the given TexImage.
124  /// </summary>
125  /// <param name="textureList">The texture list.</param>
126  /// <returns>An instance of <see cref="TexImage"/> corresponding containing the texture array.</returns>
127  /// <exception cref="TextureToolsException">
128  /// No available library could create the array.
129  /// or
130  /// The textures must all have the same size and format to be in a texture array.
131  /// </exception>
132  public TexImage CreateTextureArray(List<TexImage> textureList)
133  {
134  var array = new TexImage();
135  var request = new ArrayCreationRequest(textureList);
136 
137  ITexLibrary library = FindLibrary(array, request);
138  if (library == null)
139  {
140  Log.Error("No available library could create the array.");
141  throw new TextureToolsException("No available library could create the array.");
142  }
143 
144  int width = textureList[0].Width;
145  int height = textureList[0].Height;
146  int depth = textureList[0].Depth;
147  array.Format = textureList[0].Format;
148 
149  foreach (var texture in textureList)
150  {
151  texture.Update();
152  if (texture.Width != width || texture.Height != height || texture.Depth != depth || texture.Format != array.Format)
153  {
154  Log.Error("The textures must all have the same size and format to be in a texture array.");
155  throw new TextureToolsException("The textures must all have the same size and format to be in a texture array.");
156  }
157  }
158 
159  ExecuteRequest(array, request);
160 
161  return array;
162  }
163 
164 
165  /// <summary>
166  /// Creates a texture cube with the given TexImage.
167  /// </summary>
168  /// <param name="textureList">The texture list.</param>
169  /// <returns>An instance of <see cref="TexImage"/> containing the texture cube.</returns>
170  /// <exception cref="TextureToolsException">
171  /// No available library could create the cube.
172  /// or
173  /// The number of texture in the texture list must be a multiple of 6.
174  /// or
175  /// The textures must all have the same size and format to be in a texture cube.
176  /// </exception>
177  public TexImage CreateTextureCube(List<TexImage> textureList)
178  {
179  var cube = new TexImage();
180  var request = new CubeCreationRequest(textureList);
181 
182  if (textureList.Count % 6 != 0)
183  {
184  Log.Error("The number of texture in the texture list must be a multiple of 6.");
185  throw new TextureToolsException("The number of texture in the texture list must be a multiple of 6.");
186  }
187 
188  ITexLibrary library = FindLibrary(cube, request);
189  if (library == null)
190  {
191  Log.Error("No available library could create the cube.");
192  throw new TextureToolsException("No available library could create the cube.");
193  }
194 
195  int width = textureList[0].Width;
196  int height = textureList[0].Height;
197  int depth = textureList[0].Depth;
198  cube.Format = textureList[0].Format;
199 
200  foreach (var texture in textureList)
201  {
202  texture.Update();
203  if (texture.Width != width || texture.Height != height || texture.Depth != depth || texture.Format != cube.Format)
204  {
205  Log.Error("The textures must all have the same size and format to be in a texture cube.");
206  throw new TextureToolsException("The textures must all have the same size and format to be in a texture cube.");
207  }
208  }
209 
210  ExecuteRequest(cube, request);
211 
212  return cube;
213  }
214 
215 
216  /// <summary>
217  /// Loads the Atlas corresponding to the specified layout and file.
218  /// </summary>
219  /// <param name="layout">The layout.</param>
220  /// <param name="file">The file.</param>
221  /// <returns>An isntance of <see cref="TexAtlas"/>.</returns>
222  /// <exception cref="TextureToolsException">
223  /// The file doesn't exist. Please check the file path.
224  /// or
225  /// The layout doesn't match the given atlas file.
226  /// </exception>
227  public TexAtlas LoadAtlas(TexAtlas.TexLayout layout, string file)
228  {
229  if (!File.Exists(file))
230  {
231  Log.Error("The file " + file + " doesn't exist. Please check the file path.");
232  throw new TextureToolsException("The file " + file + " doesn't exist. Please check the file path.");
233  }
234 
235  var atlas = new TexAtlas(layout, Load(new LoadingRequest(file)));
236 
237  CheckConformity(atlas, layout);
238 
239  return atlas;
240  }
241 
242 
243  /// <summary>
244  /// Loads the Atlas corresponding to the specified texture file and layout file.
245  /// </summary>
246  /// <param name="layout">The layout.</param>
247  /// <param name="file">The file.</param>
248  /// <returns>An instance of <see cref="TexAtlas"/>.</returns>
249  /// <exception cref="TextureToolsException">
250  /// The file doesn't exist. Please check the file path.
251  /// or
252  /// The layout doesn't match the given atlas file.
253  /// </exception>
254  public TexAtlas LoadAtlas(string file, string layoutFile = "")
255  {
256  if (!File.Exists(file))
257  {
258  Log.Error("The file " + file + " doesn't exist. Please check the file path.");
259  throw new TextureToolsException("The file " + file + " doesn't exist. Please check the file path.");
260  }
261 
262  if (!layoutFile.Equals("") && !File.Exists(layoutFile))
263  {
264  Log.Error("The file " + layoutFile + " doesn't exist. Please check the file path.");
265  throw new TextureToolsException("The file " + layoutFile + " doesn't exist. Please check the file path.");
266  }
267  else
268  {
269  layoutFile = Path.ChangeExtension(file, TexAtlas.TexLayout.Extension);
270  if (!File.Exists(layoutFile))
271  {
272  Log.Error("Please check that the layout file is in the same directory as the atlas, with the same name and " + TexAtlas.TexLayout.Extension + " as extension.");
273  throw new TextureToolsException("Please check that the layout file is in the same directory as the atlas, with the same name and ." + TexAtlas.TexLayout.Extension + " as extension.");
274  }
275  }
276 
277  var layout = TexAtlas.TexLayout.Import(layoutFile);
278  var atlas = new TexAtlas(layout, Load(new LoadingRequest(file)));
279 
280  CheckConformity(atlas, layout);
281 
282  return atlas;
283  }
284 
285 
286  /// <summary>
287  /// Checks the conformity of an atlas an its corresponding layout.
288  /// </summary>
289  /// <param name="atlas">The atlas.</param>
290  /// <param name="layout">The layout.</param>
291  /// <exception cref="TextureToolsException">The layout doesn't match the given atlas file.</exception>
292  private void CheckConformity(TexAtlas atlas, TexAtlas.TexLayout layout)
293  {
294  int rightestPoint = 0;
295  int lowestPoint = 0;
296  foreach (var entry in layout.TexList)
297  {
298  if (entry.Value.UOffset + entry.Value.Width > rightestPoint) rightestPoint = entry.Value.UOffset + entry.Value.Width;
299  if (entry.Value.VOffset + entry.Value.Height > lowestPoint) lowestPoint = entry.Value.VOffset + entry.Value.Height;
300  }
301 
302  if (rightestPoint > atlas.Width || lowestPoint > atlas.Height)
303  {
304  Log.Error("The layout doesn't match the given atlas file.");
305  throw new TextureToolsException("The layout doesn't match the given atlas file.");
306  }
307  }
308 
309 
310  /// <summary>
311  /// Loads the specified file.
312  /// </summary>
313  /// <remarks>
314  /// The file can be an image or a texture.
315  /// </remarks>
316  /// <param name="file">The file.</param>
317  /// <returns>An instance of <see cref="TexImage"/>.</returns>
318  /// <exception cref="TextureToolsException">The file doesn't exist. Please check the file path.</exception>
319  public TexImage Load(string file)
320  {
321  if (!File.Exists(file))
322  {
323  Log.Error("The file " + file + " doesn't exist. Please check the file path.");
324  throw new TextureToolsException("The file " + file + " doesn't exist. Please check the file path.");
325  }
326 
327  return Load(new LoadingRequest(file));
328  }
329 
330 
331  /// <summary>
332  /// Loads the specified image of the class <see cref="SiliconStudio.Paradox.Graphics.Image"/>.
333  /// </summary>
334  /// <param name="image">The image.</param>
335  /// <remarks>The ownership of the provided image is not taken by the tex tool. The user has to dispose it him-self</remarks>
336  /// <returns>An instance of the class <see cref="TexImage"/> containing your loaded image</returns>
337  public TexImage Load(SiliconStudio.Paradox.Graphics.Image image)
338  {
339  if (image == null) throw new ArgumentNullException("image");
340  return Load(new LoadingRequest(image));
341  }
342 
343 
344  /// <summary>
345  /// Loads the specified request.
346  /// </summary>
347  /// <param name="request">The request.</param>
348  /// <returns>An instance of the class <see cref="TexImage"/> containing your loaded image</returns>
349  /// <exception cref="TextureToolsException">No available library could perform the task : LoadingRequest</exception>
350  private TexImage Load(LoadingRequest request)
351  {
352  var texImage = new TexImage();
353  texImage.Name = request.FilePath == null ? "" : Path.GetFileName(request.FilePath);
354 
355  foreach (ITexLibrary library in textureLibraries)
356  {
357  if (library.CanHandleRequest(texImage, request))
358  {
359  library.Execute(texImage, request);
360  texImage.CurrentLibrary = library;
361  return texImage;
362  }
363  }
364 
365  Log.Error("No available library could load your texture : " + request.Type);
366  throw new TextureToolsException("No available library could perform the task : " + request.Type);
367  }
368 
369 
370  /// <summary>
371  /// Decompresses the specified <see cref="TexImage"/>.
372  /// </summary>
373  /// <param name="image">The <see cref="TexImage"/>.</param>
374  public void Decompress(TexImage image)
375  {
376  if (!Tools.IsCompressed(image.Format))
377  {
378  return;
379  }
380 
381  ExecuteRequest(image, new DecompressingRequest());
382  }
383 
384 
385  /// <summary>
386  /// Saves the specified <see cref="TexImage"/> into a file.
387  /// </summary>
388  /// <param name="image">The image.</param>
389  /// <param name="fileName">Name of the file.</param>
390  /// <param name="minimumMipMapSize">Minimum size of the mip map.</param>
391  public void Save(TexImage image, String fileName, int minimumMipMapSize=1)
392  {
393  if (fileName == null || fileName.Equals(""))
394  {
395  Log.Error("No file name entered.");
396  throw new TextureToolsException("No file name entered.");
397  }
398 
399  var request = new ExportRequest(fileName, minimumMipMapSize);
400 
401  if (FindLibrary(image, request) == null && Tools.IsCompressed(image.Format))
402  {
403  Log.Warning("No library can export this texture with the actual compression format. We will try to decompress it first.");
404  Decompress(image);
405  }
406 
407  ExecuteRequest(image, request);
408  }
409 
410 
411  /// <summary>
412  /// Saves the specified <see cref="TexImage"/> into a file with the specified format.
413  /// </summary>
414  /// <param name="image">The image.</param>
415  /// <param name="fileName">Name of the file.</param>
416  /// <param name="format">The new format.</param>
417  /// <param name="minimumMipMapSize">Minimum size of the mip map.</param>
418  public void Save(TexImage image, String fileName, SiliconStudio.Paradox.Graphics.PixelFormat format, int minimumMipMapSize = 1)
419  {
420  if (fileName == null || fileName.Equals(""))
421  {
422  Log.Error("No file name entered.");
423  throw new TextureToolsException("No file name entered.");
424  }
425 
426  if (minimumMipMapSize < 0)
427  {
428  Log.Error("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
429  throw new TextureToolsException("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
430  }
431 
432  if (image.Format != format && Tools.IsCompressed(format) && !Tools.IsCompressed(image.Format))
433  {
434  TexImage workingImage = (TexImage)image.Clone();
435  Compress(workingImage, format);
436  ExecuteRequest(workingImage, new ExportRequest(fileName, minimumMipMapSize));
437  workingImage.Dispose();
438  }
439  else if (image.Format != format && Tools.IsCompressed(format))
440  {
441  TexImage workingImage = (TexImage)image.Clone();
442  Decompress(workingImage);
443  Compress(workingImage, format);
444  ExecuteRequest(workingImage, new ExportRequest(fileName, minimumMipMapSize));
445  workingImage.Dispose();
446  }
447  else
448  {
449  ExecuteRequest(image, new ExportRequest(fileName, minimumMipMapSize));
450  }
451  }
452 
453 
454  /// <summary>
455  /// Switches the channel R and B.
456  /// </summary>
457  /// <remarks>
458  /// PVR texture and ATC library can't handle BGRA order, channels B and R must be switched to get the new order RGBA. (This switch is made automatically)
459  /// If the image is in a compressed format, it will be first decompressed.
460  /// </remarks>
461  /// <param name="image">The image.</param>
462  public void SwitchChannel(TexImage image)
463  {
464  if (Tools.IsCompressed(image.Format))
465  {
466  Log.Warning("You can't switch channels of a compressed texture. It will be decompressed first..");
467  Decompress(image);
468  }
469 
470  ExecuteRequest(image, new SwitchingBRChannelsRequest());
471  }
472 
473 
474  /// <summary>
475  /// Compresses the specified image into the specified format.
476  /// </summary>
477  /// <remarks>
478  /// If the image is in a compressed format, it will be first decompressed.
479  /// If the compressing library doesn't support BGRA order and the current image format is in this order, the channels R and B will be switched.
480  /// </remarks>
481  /// <param name="image">The image.</param>
482  /// <param name="format">The format.</param>
483  public void Compress(TexImage image, SiliconStudio.Paradox.Graphics.PixelFormat format, TextureQuality quality = TextureQuality.Fast)
484  {
485  if (image.Format == format) return;
486 
487  if (Tools.IsCompressed(image.Format))
488  {
489  Log.Warning("You can't compress an already compressed texture. It will be decompressed first..");
490  Decompress(image);
491  }
492 
493  var request = new CompressingRequest(format, quality);
494 
495  ExecuteRequest(image, request);
496  }
497 
498  /// <summary>
499  /// Apply a color key on the image by replacing the color passed by to this method by a white transparent color (Alpha is 0).
500  /// </summary>
501  /// <param name="image">The image.</param>
502  /// <param name="colorKey">The color key.</param>
503  public void ColorKey(TexImage image, Color colorKey)
504  {
505  if (Tools.IsCompressed(image.Format))
506  {
507  Log.Warning("You can't compress an already compressed texture. It will be decompressed first..");
508  Decompress(image);
509  }
510 
511  if (image.Format != PixelFormat.R8G8B8A8_UNorm && image.Format != PixelFormat.B8G8R8A8_UNorm)
512  {
513  Log.Error("ColorKey TextureConverter is only supporting R8G8B8A8_UNorm or B8G8R8A8_UNorm while Texture Format is [{0}]", image.Format);
514  return;
515  }
516 
517  var request = new ColorKeyRequest(colorKey);
518  ExecuteRequest(image, request);
519  }
520 
521  /// <summary>
522  /// Generates the mip maps.
523  /// </summary>
524  /// <remarks>
525  /// If the image is in a compressed format, it will be first decompressed.
526  /// </remarks>
527  /// <param name="image">The image.</param>
528  /// <param name="filter">The filter.</param>
529  public void GenerateMipMaps(TexImage image, Filter.MipMapGeneration filter)
530  {
531  if (Tools.IsCompressed(image.Format))
532  {
533  Log.Warning("You can't generate mipmaps for a compressed texture. It will be decompressed first..");
534  Decompress(image);
535  }
536 
537  ExecuteRequest(image, new MipMapsGenerationRequest(filter));
538  }
539 
540 
541  /// <summary>
542  /// Resizes the specified image to a fixed image size.
543  /// </summary>
544  /// <remarks>
545  /// If the image is in a compressed format, it will be first decompressed.
546  /// </remarks>
547  /// <param name="image">The image.</param>
548  /// <param name="width">The width.</param>
549  /// <param name="height">The height.</param>
550  /// <param name="filter">The filter.</param>
551  public void Resize(TexImage image, int width, int height, Filter.Rescaling filter)
552  {
553  if (width < 1 || height < 1)
554  {
555  Log.Error("The new size must be an integer > 0.");
556  throw new TextureToolsException("The new size must be an integer > 0.");
557  }
558 
559  // Texture already has the requested dimension
560  if (image.Width == width && image.Height == height)
561  {
562  return;
563  }
564 
565  if (Tools.IsCompressed(image.Format))
566  {
567  Log.Warning("You can't resize a compressed texture. It will be decompressed first..");
568  Decompress(image);
569  }
570 
571  ExecuteRequest(image, new FixedRescalingRequest(width, height, filter));
572  }
573 
574 
575  /// <summary>
576  /// Rescales the specified image with the specified factors.
577  /// </summary>
578  /// <remarks>
579  /// The new size will be : width = width * widthFactor and height = height * heightFactor
580  /// If the image is in a compressed format, it will be first decompressed.
581  /// </remarks>
582  /// <param name="image">The image.</param>
583  /// <param name="widthFactor">The width factor.</param>
584  /// <param name="heightFactor">The height factor.</param>
585  /// <param name="filter">The filter.</param>
586  public void Rescale(TexImage image, float widthFactor, float heightFactor, Filter.Rescaling filter)
587  {
588  if (widthFactor <= 0 || heightFactor <= 0)
589  {
590  Log.Error("The size factors must be positive floats.");
591  throw new TextureToolsException("The size factors must be positive floats.");
592  }
593 
594  // The texture dimension won't change.
595  if (widthFactor == 1 && heightFactor ==1)
596  {
597  return;
598  }
599 
600  if (Tools.IsCompressed(image.Format))
601  {
602  Log.Warning("You can't rescale a compressed texture. It will be decompressed first..");
603  Decompress(image);
604  }
605 
606  ExecuteRequest(image, new FactorRescalingRequest(widthFactor, heightFactor, filter));
607  }
608 
609 
610  /// <summary>
611  /// Generates the normal map.
612  /// </summary>
613  /// <param name="heightMap">The height map.</param>
614  /// <param name="amplitude">The amplitude.</param>
615  /// <returns>An instance of <see cref="TexImage"/> containig the normal map.</returns>
616  public TexImage GenerateNormalMap(TexImage heightMap, float amplitude)
617  {
618  if (amplitude <= 0)
619  {
620  Log.Error("The amplitude must be a positive float.");
621  throw new TextureToolsException("The amplitude must be a positive float.");
622  }
623 
624  if (Tools.IsCompressed(heightMap.Format))
625  {
626  Log.Warning("You can't generate a normal map from a compressed height hmap. It will be decompressed first..");
627  Decompress(heightMap);
628  }
629 
630  var request = new NormalMapGenerationRequest(amplitude);
631 
632  ExecuteRequest(heightMap, request);
633 
634  return request.NormalMap;
635  }
636 
637 
638  /// <summary>
639  /// Premultiplies the alpha.
640  /// </summary>
641  /// <param name="image">The image.</param>
642  public void PreMultiplyAlpha(TexImage image)
643  {
644  if (Tools.IsCompressed(image.Format))
645  {
646  Log.Warning("You can't premultiply alpha on a compressed texture. It will be decompressed first..");
647  Decompress(image);
648  }
649 
650  ExecuteRequest(image, new PreMultiplyAlphaRequest());
651  }
652 
653  /// <summary>
654  /// Create a new image from the alpha component of a reference image.
655  /// </summary>
656  /// <param name="texImage">The image from which to take the alpha</param>
657  /// <returns>The <see cref="TexImage"/> containing the alpha component as rgb color. Note: it is the user responsibility to dispose the returned image.</returns>
659  {
660  var alphaImage = (TexImage)texImage.Clone(true);
661 
662  var rowPtr = alphaImage.Data;
663  for (int i = 0; i < alphaImage.Height; i++)
664  {
665  var pByte = (byte*)rowPtr;
666  for (int x = 0; x < alphaImage.Width; x++)
667  {
668  pByte[0] = pByte[3];
669  pByte[1] = pByte[3];
670  pByte[2] = pByte[3];
671 
672  pByte += 4;
673  }
674  rowPtr = IntPtr.Add(rowPtr, alphaImage.RowPitch);
675  }
676 
677  return alphaImage;
678  }
679 
680  /// <summary>
681  /// Create a new image from region.
682  /// </summary>
683  /// <param name="texImage">The original image from which to extract the region</param>
684  /// <param name="region">The region from the original image to extract.</param>
685  /// <returns>The extracted region <see cref="TexImage"/>. Note: it is the user responsibility to dispose the returned image.</returns>
686  public unsafe Image CreateImageFromRegion(TexImage texImage, Rectangle region)
687  {
688  if (texImage.Dimension != TexImage.TextureDimension.Texture2D || Tools.IsCompressed(texImage.Format))
689  throw new NotImplementedException();
690 
691  Log.Info("Extracting region and exporting to Paradox Image ...");
692 
693  // clamp the provided region to be sure it fits in provided image
694  region.X = Math.Max(0, Math.Min(region.X, texImage.Width));
695  region.Y = Math.Max(0, Math.Min(region.Y, texImage.Height));
696  region.Width = Math.Max(0, Math.Min(region.Width, texImage.Width - region.X));
697  region.Height = Math.Max(0, Math.Min(region.Height, texImage.Height - region.Y));
698 
699  // create the paradox image
700  var pdxImage = Image.New2D(region.Width, region.Height, 1, texImage.Format);
701  if (pdxImage == null)
702  {
703  Log.Error("Image could not be created.");
704  throw new InvalidOperationException("Image could not be created.");
705  }
706 
707  // get the row pitch of the paradox image
708  var pixelBuffer = pdxImage.GetPixelBuffer(0, 0);
709  var dstRowPitch = pixelBuffer.RowStride;
710 
711  // copy the data
712  if (texImage.ArraySize > 0)
713  {
714  var rowSrcPtr = texImage.SubImageArray[0].Data;
715  var rowDstPtr = pdxImage.DataPointer;
716  rowSrcPtr = IntPtr.Add(rowSrcPtr, region.Y * texImage.RowPitch);
717  for (int i = 0; i < region.Height; i++)
718  {
719  var pSrc = ((UInt32*)rowSrcPtr) + region.X;
720  var pDst = (UInt32*)rowDstPtr;
721 
722  for (int x = 0; x < region.Width; x++)
723  *(pDst++) = *(pSrc++);
724 
725  rowSrcPtr = IntPtr.Add(rowSrcPtr, texImage.RowPitch);
726  rowDstPtr = IntPtr.Add(rowDstPtr, dstRowPitch);
727  }
728  }
729 
730  return pdxImage;
731  }
732 
733 
734  /// <summary>
735  /// Converts to paradox image.
736  /// </summary>
737  /// <param name="image">The image.</param>
738  /// <returns>The converted Paradox <see cref="SiliconStudio.Paradox.Graphics.Image"/>.</returns>
739  /// <remarks>The user is the owner of the returned image, and has to dispose it after he finishes using it</remarks>
741  {
742  var request = new ExportToParadoxRequest();
743 
744  ExecuteRequest(image, request);
745 
746  return request.PdxImage;
747  }
748 
749 
750  /// <summary>
751  /// Corrects the gamma.
752  /// </summary>
753  /// <param name="image">The image.</param>
754  /// <param name="gamma">The gamma.</param>
755  public void CorrectGamma(TexImage image, double gamma)
756  {
757  if (gamma <= 0)
758  {
759  Log.Error("The gamma must be a positive float.");
760  throw new TextureToolsException("The gamma must be a positive float.");
761  }
762 
763  if (Tools.IsCompressed(image.Format))
764  {
765  Log.Warning("You can't correct gamme on a compressed texture. It will be decompressed first..");
766  Decompress(image);
767  }
768 
769  var request = new GammaCorrectionRequest(gamma);
770 
771  ExecuteRequest(image, request);
772  }
773 
774 
775  /// <summary>
776  /// Flips the specified image horizontally or vertically.
777  /// </summary>
778  /// <param name="image">The image.</param>
779  /// <param name="orientation">The orientation <see cref="Orientation.Flip"/>.</param>
780  public void Flip(TexImage image, Orientation orientation)
781  {
782  if (Tools.IsCompressed(image.Format))
783  {
784  Log.Warning("You can't flip a compressed texture. It will be decompressed first..");
785  Decompress(image);
786  }
787 
788  var request = new FlippingRequest(orientation);
789 
790  ExecuteRequest(image, request);
791  }
792 
793  /// <summary>
794  /// Flips the specified image horizontally or vertically.
795  /// </summary>
796  /// <param name="image">The image.</param>
797  /// <param name="index">The index of the sub-image.</param>
798  /// <param name="orientation">The orientation <see cref="Orientation.Flip"/>.</param>
799  public void FlipSub(TexImage image, int index, Orientation orientation)
800  {
801  if (Tools.IsCompressed(image.Format))
802  {
803  Log.Warning("You can't flip a compressed texture. It will be decompressed first..");
804  Decompress(image);
805  }
806 
807  var request = new FlippingSubRequest(index, orientation);
808 
809  ExecuteRequest(image, request);
810  }
811 
812 
813  /// <summary>
814  /// Swaps two slices of a texture array.
815  /// </summary>
816  /// <param name="image">The image.</param>
817  /// <param name="firstIndex">The index of the first sub-image.</param>
818  /// <param name="secondIndex">The index of the second sub-image</param>
819  public void Swap(TexImage image, int firstIndex, int secondIndex)
820  {
821  var request = new SwappingRequest(firstIndex, secondIndex);
822 
823  ExecuteRequest(image, request);
824  }
825 
826 
827  /// <summary>
828  /// Finds a suitable library to handle the request.
829  /// </summary>
830  /// <param name="image">The image.</param>
831  /// <param name="request">The request.</param>
832  /// <returns>The <see cref="ITexLibrary"/> which can handle the request or null if none could.</returns>
833  private ITexLibrary FindLibrary(TexImage image, IRequest request)
834  {
835  foreach (var library in textureLibraries)
836  {
837  if (library.CanHandleRequest(image, request))
838  {
839  return library;
840  }
841  }
842 
843  return null;
844  }
845 
846 
847  /// <summary>
848  /// Extracts the TexImage corresponding to the specified name in the given atlas.
849  /// </summary>
850  /// <param name="atlas">The atlas.</param>
851  /// <param name="name">The texture name.</param>
852  /// <param name="minimumMipmapSize">The minimum size of the smallest mipmap.</param>
853  /// <returns>The TexImage texture corresponding to the specified name</returns>
854  /// <exception cref="TextureToolsException">
855  /// You must enter a texture name to extract.
856  /// or
857  /// The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.
858  /// </exception>
859  public TexImage Extract(TexAtlas atlas, string name, int minimumMipmapSize = 1)
860  {
861  if (name == null || name.Equals(""))
862  {
863  Log.Error("You must enter a texture name to extract.");
864  throw new TextureToolsException("You must enter a texture name to extract.");
865  }
866 
867  if (minimumMipmapSize < 0)
868  {
869  Log.Error("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
870  throw new TextureToolsException("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
871  }
872 
873  var request = new AtlasExtractionRequest(name, minimumMipmapSize);
874 
875  if(Tools.IsCompressed(atlas.Format))
876  {
877  Decompress(atlas);
878  }
879 
880  ExecuteRequest(atlas, request);
881 
882  return request.Texture;
883  }
884 
885 
886  /// <summary>
887  /// Extracts the TexImage corresponding to the specified indice in the given texture array.
888  /// </summary>
889  /// <param name="array">The array.</param>
890  /// <param name="indice">The indice.</param>
891  /// <param name="minimumMipmapSize">The minimum size of the smallest mipmap.</param>
892  /// <returns>The TexImage texture corresponding to the specified indice</returns>
893  /// <exception cref="TextureToolsException">
894  /// The indice you entered is not valid.
895  /// or
896  /// The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.
897  /// </exception>
898  public TexImage Extract(TexImage array, int indice, int minimumMipmapSize = 1)
899  {
900  if (indice < 0 || indice > array.ArraySize-1)
901  {
902  Log.Error("The indice you entered is not valid.");
903  throw new TextureToolsException("The indice you entered is not valid.");
904  }
905 
906  if (minimumMipmapSize < 0)
907  {
908  Log.Error("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
909  throw new TextureToolsException("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
910  }
911 
912  var request = new ArrayExtractionRequest(indice, minimumMipmapSize);
913 
914  ExecuteRequest(array, request);
915 
916  return request.Texture;
917  }
918 
919 
920  /// <summary>
921  /// Extracts every TexImage included in the atlas.
922  /// </summary>
923  /// <param name="atlas">The atlas.</param>
924  /// <param name="minimumMipmapSize">The minimum size of the smallest mipmap.</param>
925  /// <returns>The list of TexImage corresponding to each texture composing the atlas.</returns>
926  /// <exception cref="TextureToolsException">The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.</exception>
927  public List<TexImage> ExtractAll(TexAtlas atlas, int minimumMipmapSize = 1)
928  {
929  if (minimumMipmapSize < 0)
930  {
931  Log.Error("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
932  throw new TextureToolsException("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
933  }
934 
935  var request = new AtlasExtractionRequest(minimumMipmapSize);
936 
937  if (Tools.IsCompressed(atlas.Format))
938  {
939  Log.Warning("You can't extract a texture from a compressed atlas. The atlas will be decompressed first..");
940  Decompress(atlas);
941  }
942 
943  ExecuteRequest(atlas, request);
944 
945  return request.Textures;
946  }
947 
948 
949  /// <summary>
950  /// Extracts every TexImage included in the array.
951  /// </summary>
952  /// <param name="array">The array.</param>
953  /// <param name="minimumMipmapSize">The minimum size of the smallest mipmap.</param>
954  /// <returns>The list of TexImage corresponding to each element of the texture array.</returns>
955  /// <exception cref="TextureToolsException">The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.</exception>
956  public List<TexImage> ExtractAll(TexImage array, int minimumMipmapSize = 1)
957  {
958  if (minimumMipmapSize < 0)
959  {
960  Log.Error("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
961  throw new TextureToolsException("The minimup Mipmap size can't be negative. Put 0 or 1 for a complete Mipmap chain.");
962  }
963 
964  var request = new ArrayExtractionRequest(minimumMipmapSize);
965 
966  if (Tools.IsCompressed(array.Format))
967  {
968  Decompress(array);
969  }
970 
971  ExecuteRequest(array, request);
972 
973  return request.Textures;
974  }
975 
976 
977  /// <summary>
978  /// Updates a specific texture in the atlas with the given TexImage.
979  /// </summary>
980  /// <param name="atlas">The atlas.</param>
981  /// <param name="texture">The texture.</param>
982  /// <param name="name">The name of the texture to update (takes the TexImage's name if none given).</param>
983  /// <exception cref="TextureToolsException">
984  /// You must either set the Name attribute of the TexImage, or you must give the name of the texture to update in the atlas.
985  /// or
986  /// The new texture can't be a texture array.
987  /// </exception>
988  public void Update(TexAtlas atlas, TexImage texture, string name = "")
989  {
990  texture.Update();
991 
992  if (texture.Name.Equals("") && name.Equals(""))
993  {
994  Log.Error("You must either set the Name attribute of the TexImage, or you must give the name of the texture to update in the atlas.");
995  throw new TextureToolsException("You must either set the Name attribute of the TexImage, or you must give the name of the texture to update in the atlas.");
996  }
997 
998  if (texture.ArraySize > 1)
999  {
1000  Log.Error("The new texture can't be a texture array.");
1001  throw new TextureToolsException("The new texture can't be a texture array.");
1002  }
1003 
1004  CheckConformity(atlas, texture);
1005 
1006  name = name.Equals("") ? texture.Name : name;
1007 
1008  ExecuteRequest(atlas, new AtlasUpdateRequest(texture, name));
1009  }
1010 
1011 
1012  /// <summary>
1013  /// Updates a specific texture in the texture array with the given TexImage.
1014  /// </summary>
1015  /// <param name="array">The array.</param>
1016  /// <param name="texture">The texture.</param>
1017  /// <param name="indice">The indice.</param>
1018  /// <exception cref="TextureToolsException">
1019  /// The first given texture must be an array texture.
1020  /// or
1021  /// The given indice is out of range in the array texture.
1022  /// </exception>
1023  public void Update(TexImage array, TexImage texture, int indice)
1024  {
1025  texture.Update();
1026 
1027  if (array.ArraySize == 1)
1028  {
1029  Log.Error("The first given texture must be an array texture.");
1030  throw new TextureToolsException("The first given texture must be an array texture.");
1031  }
1032 
1033  if (array.ArraySize-1 < indice)
1034  {
1035  Log.Error("The given indice is out of range in the array texture.");
1036  throw new TextureToolsException("The given indice is out of range in the array texture.");
1037  }
1038 
1039  CheckConformity(array, texture);
1040 
1041  ExecuteRequest(array, new ArrayUpdateRequest(texture, indice));
1042  }
1043 
1044 
1045  /// <summary>
1046  /// Inserts a texture into a texture array at a specified position.
1047  /// </summary>
1048  /// <param name="array">The array.</param>
1049  /// <param name="texture">The texture to be added.</param>
1050  /// <param name="indice">The indice.</param>
1051  /// <exception cref="TextureToolsException">The given indice must be between 0 and the array size</exception>
1052  public void Insert(TexImage array, TexImage texture, int indice)
1053  {
1054  texture.Update();
1055 
1056  if (indice < 0 || indice > array.ArraySize)
1057  {
1058  Log.Error("The given indice must be between 0 and " + array.ArraySize);
1059  throw new TextureToolsException("The given indice must be between 0 and " + array.ArraySize);
1060  }
1061 
1062  CheckConformity(array, texture);
1063 
1064  ExecuteRequest(array, new ArrayInsertionRequest(texture, indice));
1065  }
1066 
1067 
1068  /// <summary>
1069  /// Removes the texture at a specified position from a texture array.
1070  /// </summary>
1071  /// <param name="array">The array.</param>
1072  /// <param name="indice">The indice.</param>
1073  /// <exception cref="TextureToolsException">
1074  /// The array size must be > 1.
1075  /// or
1076  /// The given indice must be between 0 and + array.ArraySize
1077  /// </exception>
1078  public void Remove(TexImage array, int indice)
1079  {
1080  if (array.ArraySize == 1)
1081  {
1082  Log.Error("The array size must be > 1.");
1083  throw new TextureToolsException("The array size must be > 1.");
1084  }
1085 
1086  if (indice < 0 || indice > array.ArraySize-1)
1087  {
1088  Log.Error("The given indice must be between 0 and " + array.ArraySize);
1089  throw new TextureToolsException("The given indice must be between 0 and " + array.ArraySize);
1090  }
1091 
1092  ExecuteRequest(array, new ArrayElementRemovalRequest(indice));
1093  }
1094 
1095 
1096  /// <summary>
1097  /// Checks the conformity of a candidate texture with a model one : check the mipmap count and the format.
1098  /// </summary>
1099  /// <param name="model">The model.</param>
1100  /// <param name="candidate">The candidate.</param>
1101  private void CheckConformity(TexImage model, TexImage candidate)
1102  {
1103  if (model.MipmapCount > 1 && candidate.MipmapCount == 1)
1104  {
1105  Log.Warning("The given texture has no mipmaps. They will be generated..");
1106  GenerateMipMaps(candidate, Filter.MipMapGeneration.Box);
1107  }
1108 
1109  if (candidate.Format != model.Format)
1110  {
1111  Log.Warning("The given texture format isn't correct. The texture will be converted..");
1112  if (Tools.IsCompressed(model.Format))
1113  {
1114  if (Tools.IsCompressed(candidate.Format)) Decompress(candidate);
1115  Compress(candidate, model.Format);
1116  }
1117  else
1118  {
1119  Decompress(candidate);
1120  if (candidate.Format != model.Format) Compress(candidate, model.Format);
1121  }
1122  }
1123  }
1124 
1125 
1126  /// <summary>
1127  /// Executes the request.
1128  /// </summary>
1129  /// <param name="image">The image.</param>
1130  /// <param name="request">The request.</param>
1131  /// <exception cref="TextureToolsException">No available library could perform the task : + request.Type</exception>
1132  private void ExecuteRequest(TexImage image, IRequest request)
1133  {
1134  // First Check if the current library can handle the request
1135  if (image.CurrentLibrary != null && image.CurrentLibrary.CanHandleRequest(image, request))
1136  {
1137  image.CurrentLibrary.Execute(image, request);
1138  }
1139  else // Otherwise, it finds another library which can handle the request
1140  {
1141  ITexLibrary library;
1142  if ((library = FindLibrary(image, request)) != null)
1143  {
1144  if (Tools.IsInBGRAOrder(image.Format) && !library.SupportBGRAOrder())
1145  {
1146  SwitchChannel(image);
1147  }
1148 
1149  if(image.CurrentLibrary != null) image.CurrentLibrary.EndLibrary(image); // Ending the use of the previous library (mainly to free memory)
1150 
1151  library.StartLibrary(image); // Preparing the new library : converting TexImage format to the library native format
1152 
1153  library.Execute(image, request);
1154 
1155  image.CurrentLibrary = library;
1156  }
1157  else // If no library could be found, an exception is thrown
1158  {
1159  Log.Error("No available library could perform the task : " + request.Type);
1160  throw new TextureToolsException("No available library could perform the task : " + request.Type);
1161  }
1162  }
1163  }
1164 
1165 
1166  static void Main(string[] args)
1167  {
1168  var texTool = new TextureTool();
1169  GlobalLogger.GlobalMessageLogged += new ConsoleLogListener();
1170 
1171 
1172  try
1173  {
1174  /*var list = new List<TexImage>();
1175  for (int i = 0; i < 3; ++i)
1176  {
1177  list.Add(texTool.Load(@"C:\dev\data\test\atlas\stones256.png"));
1178  list.Add(texTool.Load(@"C:\dev\data\test\atlas\square256.png"));
1179  }
1180 
1181  var cube = texTool.CreateTextureCube(list);
1182  //texTool.Compress(cube, Paradox.Framework.Graphics.PixelFormat.BC3_UNorm);
1183  texTool.GenerateMipMaps(cube, Filter.MipMapGeneration.Box);
1184 
1185  texTool.Save(cube, @"C:\dev\data\test\cube.pvr");
1186 
1187  /*texTool.Remove(cube, 0);
1188 
1189  texTool.Save(array, @"C:\dev\data\test\array_after.dds");
1190 
1191  foreach (var texture in list)
1192  {
1193  texture.Dispose();
1194  }
1195 
1196  cube.Dispose();*/
1197 
1198 
1199  /*var list = new List<TexImage>();
1200  for (int i = 0; i < 5; ++i)
1201  {
1202  list.Add(texTool.Load(@"C:\dev\data\test\input\atlas\stones256.png"));
1203  list.Add(texTool.Load(@"C:\dev\data\test\input\atlas\square256.png"));
1204  }
1205 
1206  var array = texTool.CreateTextureArray(list);
1207  texTool.Compress(array, Paradox.Framework.Graphics.PixelFormat.BC3_UNorm);
1208  //texTool.GenerateMipMaps(array, Filter.MipMapGeneration.Box);
1209 
1210  texTool.Save(array, @"C:\dev\data\test\array_before.dds");
1211 
1212  texTool.Remove(array, 0);
1213 
1214  texTool.Save(array, @"C:\dev\data\test\array_after.dds");
1215 
1216  foreach (var texture in list)
1217  {
1218  texture.Dispose();
1219  }
1220 
1221  array.Dispose();*/
1222 
1223 
1224  /*var list = new List<TexImage>();
1225  for (int i = 0; i < 5; ++i)
1226  {
1227  list.Add(texTool.Load(@"C:\dev\data\test\atlas\stones256.png"));
1228  list.Add(texTool.Load(@"C:\dev\data\test\atlas\square256.png"));
1229  }
1230 
1231  var array = texTool.CreateTextureArray(list);
1232  texTool.GenerateMipMaps(array, Filter.MipMapGeneration.Box);
1233 
1234  texTool.Save(array, @"C:\dev\data\test\array_before.dds");
1235 
1236  var newImg = texTool.Load(@"C:\dev\data\test\atlas\square512.png");
1237  texTool.Resize(newImg, array.Width, array.Height, Filter.Rescaling.Bilinear);
1238  texTool.Insert(array, newImg, 1);
1239 
1240  var newImg = texTool.Extract(array, 2, 16);
1241  texTool.Save(newImg, @"C:\dev\data\test\extract.png");
1242 
1243  //texTool.Save(array, @"C:\dev\data\test\array_after.dds");
1244 
1245  foreach (var texture in list)
1246  {
1247  texture.Dispose();
1248  }
1249 
1250  array.Dispose();
1251  newImg.Dispose();*/
1252 
1253  /*string[] fileList = Directory.GetFiles(@"C:\dev\data\test\input\atlas");
1254  var list = new List<TexImage>(fileList.Length);
1255 
1256  foreach(string filePath in fileList)
1257  {
1258  list.Add(texTool.Load(filePath));
1259  }
1260 
1261  var atlas = texTool.CreateAtlas(list);
1262 
1263  texTool.Save(atlas, @"C:\dev\data\test\input\atlas_WOMipMaps.png");*/
1264 
1265  /*string[] fileList = Directory.GetFiles(@"C:\dev\data\test\atlas");
1266  var list = new List<TexImage>(fileList.Length);
1267 
1268  /*foreach(string filePath in fileList)
1269  {
1270  var img = texTool.Load(filePath);
1271  list.Add(img);
1272  texTool.GenerateMipMaps(img, Filter.MipMapGeneration.Cubic);
1273  texTool.Save(img, @"C:\dev\data\test\"+img.Name);
1274  }
1275 
1276  var img = texTool.Load(@"C:\dev\data\test\atlas\rect100_128.png");
1277  list.Add(img);
1278  texTool.GenerateMipMaps(img, Filter.MipMapGeneration.Cubic);
1279  texTool.Save(img, @"C:\dev\data\test\" + img.Name);
1280 
1281  var atlas = texTool.CreateAtlas(list);
1282  //texTool.GenerateMipMaps(atlas, Filter.MipMapGeneration.Box);
1283 
1284  /*var newImg = texTool.Extract(atlas, "rect100_128.png");
1285  texTool.Save(newImg, @"C:\dev\data\test\extracted.png");
1286 
1287  texTool.Save(atlas, @"C:\dev\data\test\atlas_with_mipmaps_already.dds");
1288 
1289  /*var texImage = texTool.Extract(atlas, "stones256.png");
1290 
1291  texTool.Update(atlas, texImage, "square256.png");
1292 
1293  //var newImg = texTool.Load(@"C:\dev\data\test\atlas\stones256.png");
1294  //var newImg = texTool.Extract(atlas, "square128.png", 16);
1295  //texTool.Save(newImg, @"C:\dev\data\test\extracted.png");
1296 
1297  texTool.Save(atlas, @"C:\dev\data\test\atlas_after.dds");
1298 
1299  //newImg.Dispose();
1300  atlas.Dispose();*/
1301  }
1302  catch (TextureToolsException)
1303  {
1304  }
1305 
1306  texTool.Dispose();
1307 
1308  Log.Info("Done.");
1309  Console.ReadKey();
1310  }
1311  }
1312 }
TexImage CreateTextureArray(List< TexImage > textureList)
Creates a texture array with the given TexImage.
Definition: TextureTool.cs:132
SiliconStudio.Paradox.Graphics.Image ConvertToParadoxImage(TexImage image)
Converts to paradox image.
Definition: TextureTool.cs:740
TextureQuality
The desired texture quality.
List< TexImage > ExtractAll(TexImage array, int minimumMipmapSize=1)
Extracts every TexImage included in the array.
Definition: TextureTool.cs:956
Object Clone()
Creates a new object that is a copy of the current instance.
Definition: TexImage.cs:228
void Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resourc...
Definition: TextureTool.cs:58
Request to extract one or every textures from an atlas.
void SwitchChannel(TexImage image)
Switches the channel R and B.
Definition: TextureTool.cs:462
void Resize(TexImage image, int width, int height, Filter.Rescaling filter)
Resizes the specified image to a fixed image size.
Definition: TextureTool.cs:551
MipMapGeneration
Available filters for mipmap generation
Definition: Filter.cs:19
TextureDimension
The Different types of texture
Definition: TexImage.cs:46
void ColorKey(TexImage image, Color colorKey)
Apply a color key on the image by replacing the color passed by to this method by a white transparent...
Definition: TextureTool.cs:503
Rescaling
Available filters for rescaling operation
Definition: Filter.cs:30
Provides method to load images or textures, to modify them and to convert them with different texture...
Definition: TextureTool.cs:24
Provides method to instantiate an image 1D/2D/3D supporting TextureArray and mipmaps on the CPU or to...
Definition: Image.cs:88
TexImage Load(SiliconStudio.Paradox.Graphics.Image image)
Loads the specified image of the class SiliconStudio.Paradox.Graphics.Image.
Definition: TextureTool.cs:337
void Save(TexImage image, String fileName, int minimumMipMapSize=1)
Saves the specified TexImage into a file.
Definition: TextureTool.cs:391
Orientation
Available Orientation to flip textures
Definition: Orientation.cs:15
Allows the creation and manipulation of texture arrays.
Definition: ArrayTexLib.cs:16
void Flip(TexImage image, Orientation orientation)
Flips the specified image horizontally or vertically.
Definition: TextureTool.cs:780
void Decompress(TexImage image)
Decompresses the specified TexImage.
Definition: TextureTool.cs:374
void PreMultiplyAlpha(TexImage image)
Premultiplies the alpha.
Definition: TextureTool.cs:642
void CorrectGamma(TexImage image, double gamma)
Corrects the gamma.
Definition: TextureTool.cs:755
TexImage GenerateNormalMap(TexImage heightMap, float amplitude)
Generates the normal map.
Definition: TextureTool.cs:616
void Insert(TexImage array, TexImage texture, int indice)
Inserts a texture into a texture array at a specified position.
TexAtlas LoadAtlas(TexAtlas.TexLayout layout, string file)
Loads the Atlas corresponding to the specified layout and file.
Definition: TextureTool.cs:227
unsafe TexImage CreateImageFromAlphaComponent(TexImage texImage)
Create a new image from the alpha component of a reference image.
Definition: TextureTool.cs:658
HRESULT GenerateMipMaps(_In_ const Image &baseImage, _In_ DWORD filter, _In_ size_t levels, _Inout_ ScratchImage &mipChain, _In_ bool allow1D=false)
TexImage Extract(TexAtlas atlas, string name, int minimumMipmapSize=1)
Extracts the TexImage corresponding to the specified name in the given atlas.
Definition: TextureTool.cs:859
Base implementation for ILogger.
Definition: Logger.cs:10
TexAtlas LoadAtlas(string file, string layoutFile="")
Loads the Atlas corresponding to the specified texture file and layout file.
Definition: TextureTool.cs:254
Request to insert a specific texture in a texture array.
List< TexImage > ExtractAll(TexAtlas atlas, int minimumMipmapSize=1)
Extracts every TexImage included in the atlas.
Definition: TextureTool.cs:927
void Remove(TexImage array, int indice)
Removes the texture at a specified position from a texture array.
System.IO.File File
Request to create a texture array from a texture list.
Request to extract one or every textures from a texture array
TexAtlas CreateAtlas(List< TexImage > textureList, bool forceSquaredAtlas=false)
Creates an atlas with the given TexImage.
Definition: TextureTool.cs:74
TexImage Load(string file)
Loads the specified file.
Definition: TextureTool.cs:319
Request to remove the texture at a specified position from a texture array.
void GenerateMipMaps(TexImage image, Filter.MipMapGeneration filter)
Generates the mip maps.
Definition: TextureTool.cs:529
Request to update a specific texture in a texture array.
Request to create a texture cube from a texture list.
Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A).
Definition: Color.cs:16
A texture atlas : a texture made from a composition of many textures.
Definition: TexAtlas.cs:14
Request to premultiply the alpha on the texture
HRESULT Decompress(_In_ const Image &cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage &image)
TexImage Extract(TexImage array, int indice, int minimumMipmapSize=1)
Extracts the TexImage corresponding to the specified indice in the given texture array.
Definition: TextureTool.cs:898
Request to create an atlas from a texture list.
TexAtlas RetrieveAtlas(TexImage texture, string layoutFile)
Retrieves the atlas from a TexImage and its corresponding layout file.
Definition: TextureTool.cs:110
Temporary format containing texture data and information. Used as buffer between texture libraries...
Definition: TexImage.cs:13
TextureTool()
Initializes a new instance of the TextureTool class.
Definition: TextureTool.cs:40
Provides enumerations of the different available filter types.
Definition: Filter.cs:14
SiliconStudio.Paradox.Graphics.PixelFormat Format
Definition: TexImage.cs:23
void FlipSub(TexImage image, int index, Orientation orientation)
Flips the specified image horizontally or vertically.
Definition: TextureTool.cs:799
unsafe Image CreateImageFromRegion(TexImage texImage, Rectangle region)
Create a new image from region.
Definition: TextureTool.cs:686
void Rescale(TexImage image, float widthFactor, float heightFactor, Filter.Rescaling filter)
Rescales the specified image with the specified factors.
Definition: TextureTool.cs:586
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
Structure using the same layout than System.Drawing.Rectangle
Definition: Rectangle.cs:35
void Swap(TexImage image, int firstIndex, int secondIndex)
Swaps two slices of a texture array.
Definition: TextureTool.cs:819
Output message to log right away.
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32
void Update(TexAtlas atlas, TexImage texture, string name="")
Updates a specific texture in the atlas with the given TexImage.
Definition: TextureTool.cs:988
HRESULT Compress(_In_ const Image &srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage &cImage)
void Update(TexImage array, TexImage texture, int indice)
Updates a specific texture in the texture array with the given TexImage.
TexImage CreateTextureCube(List< TexImage > textureList)
Creates a texture cube with the given TexImage.
Definition: TextureTool.cs:177
A LogListener implementation redirecting its output to the default OS console. If console is not supp...
void Save(TexImage image, String fileName, SiliconStudio.Paradox.Graphics.PixelFormat format, int minimumMipMapSize=1)
Saves the specified TexImage into a file with the specified format.
Definition: TextureTool.cs:418
void Compress(TexImage image, SiliconStudio.Paradox.Graphics.PixelFormat format, TextureQuality quality=TextureQuality.Fast)
Compresses the specified image into the specified format.
Definition: TextureTool.cs:483