You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

684 lines
23 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. //#define NEW_TEXTURE_3D_METHOD
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Collections.Generic;
  7. using UnityEditorInternal;
  8. using System;
  9. using System.IO;
  10. namespace AmplifyShaderEditor
  11. {
  12. public class ASETextureArrayCreator : EditorWindow
  13. {
  14. [MenuItem( "Window/Amplify Shader Editor/Texture Array Creator", false, 1001 )]
  15. static void ShowWindow()
  16. {
  17. ASETextureArrayCreator window = EditorWindow.GetWindow<ASETextureArrayCreator>();
  18. window.titleContent.text = "Texture Array";
  19. window.minSize = new Vector2( 302, 350 );
  20. window.Show();
  21. }
  22. private const string ClearButtonStr = "Clear";
  23. private const string TextureFilter = "t:Texture2D";
  24. private const string BuildArrayMessage = "Build Array";
  25. private const string BuildTexture3DMessage = "Build Texture 3D";
  26. private const string ArrayFilename = "NewTextureArray";
  27. private const string Texture3DFilename = "NewTexture3D";
  28. private DragAndDropTool m_dragAndDropTool;
  29. private Rect m_draggableArea;
  30. [SerializeField]
  31. private List<Texture2D> m_allTextures;
  32. [SerializeField]
  33. private ReorderableList m_listTextures = null;
  34. [SerializeField]
  35. private bool m_tex3DMode = false;
  36. [SerializeField]
  37. private bool m_linearMode = false;
  38. [SerializeField]
  39. private string m_folderPath = "Assets/";
  40. [SerializeField]
  41. private string m_fileName = "NewTextureArray";
  42. [SerializeField]
  43. private bool m_filenameChanged = false;
  44. [SerializeField]
  45. private TextureWrapMode m_wrapMode = TextureWrapMode.Repeat;
  46. [SerializeField]
  47. private FilterMode m_filterMode = FilterMode.Bilinear;
  48. [SerializeField]
  49. private int m_anisoLevel = 1;
  50. [SerializeField]
  51. private int m_previewSize = 16;
  52. [SerializeField]
  53. private bool m_mipMaps = true;
  54. [SerializeField]
  55. private int m_selectedSizeX = 4;
  56. [SerializeField]
  57. private int m_selectedSizeY = 4;
  58. [SerializeField]
  59. private TextureFormat m_selectedFormatEnum = TextureFormat.ARGB32;
  60. [SerializeField]
  61. private int m_quality = 100;
  62. private int[] m_sizes = { 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
  63. private string[] m_sizesStr = { "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192" };
  64. private static Dictionary<int, int> MipCount = new Dictionary<int, int>() { { 32, 6 }, { 64, 7 }, { 128, 8 }, { 256, 9 }, { 512, 10 }, { 1024, 11 }, { 2048, 12 }, { 4096, 13 }, { 8192, 14 } };
  65. private static List<TextureFormat> UncompressedFormats = new List<TextureFormat>() { TextureFormat.ARGB32, TextureFormat.RGBA32, TextureFormat.RGB24, TextureFormat.Alpha8 };
  66. private GUIStyle m_contentStyle = null;
  67. private GUIStyle m_pathButtonStyle = null;
  68. private GUIContent m_pathButtonContent = new GUIContent();
  69. private Vector2 m_scrollPos;
  70. private Texture m_lastSaved;
  71. private bool m_lockRatio = true;
  72. private string m_message = string.Empty;
  73. private void OnEnable()
  74. {
  75. m_draggableArea = new Rect( 0, 0, 1, 1 );
  76. m_dragAndDropTool = new DragAndDropTool();
  77. m_dragAndDropTool.OnValidDropObjectEvt += OnValidObjectsDropped;
  78. if( m_contentStyle == null )
  79. {
  80. m_contentStyle = new GUIStyle( GUIStyle.none );
  81. m_contentStyle.margin = new RectOffset( 6, 4, 5, 5 );
  82. }
  83. m_pathButtonStyle = null;
  84. if( m_allTextures == null )
  85. m_allTextures = new List<Texture2D>();
  86. if( m_listTextures == null )
  87. {
  88. m_listTextures = new ReorderableList( m_allTextures, typeof( Texture2D ), true, true, true, true );
  89. m_listTextures.elementHeight = 16;
  90. m_listTextures.drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) =>
  91. {
  92. m_allTextures[ index ] = (Texture2D)EditorGUI.ObjectField( rect, "Texture " + index, m_allTextures[ index ], typeof( Texture2D ), false );
  93. };
  94. m_listTextures.drawHeaderCallback = ( Rect rect ) =>
  95. {
  96. m_previewSize = EditorGUI.IntSlider( rect, "Texture List", m_previewSize, 16, 64 );
  97. if( (float)m_previewSize != m_listTextures.elementHeight )
  98. m_listTextures.elementHeight = m_previewSize;
  99. };
  100. m_listTextures.onAddCallback = ( list ) =>
  101. {
  102. m_allTextures.Add( null );
  103. };
  104. m_listTextures.onRemoveCallback = ( list ) =>
  105. {
  106. m_allTextures.RemoveAt( list.index );
  107. };
  108. }
  109. }
  110. private void OnDestroy()
  111. {
  112. m_dragAndDropTool.Destroy();
  113. m_dragAndDropTool = null;
  114. if( m_allTextures != null )
  115. {
  116. m_allTextures.Clear();
  117. m_allTextures = null;
  118. }
  119. }
  120. void OnGUI()
  121. {
  122. if( m_pathButtonStyle == null )
  123. m_pathButtonStyle = "minibutton";
  124. m_scrollPos = EditorGUILayout.BeginScrollView( m_scrollPos, GUILayout.Height( position.height ) );
  125. float cachedWidth = EditorGUIUtility.labelWidth;
  126. EditorGUIUtility.labelWidth = 100;
  127. EditorGUILayout.BeginVertical( m_contentStyle );
  128. string buildButtonStr = m_tex3DMode ? BuildTexture3DMessage : BuildArrayMessage;
  129. // build button
  130. EditorGUILayout.BeginHorizontal();
  131. EditorGUI.BeginDisabledGroup( m_allTextures.Count <= 0 );
  132. if( GUILayout.Button( buildButtonStr, "prebutton", GUILayout.Height( 20 ) ) )
  133. {
  134. bool showWarning = false;
  135. for( int i = 0; i < m_allTextures.Count; i++ )
  136. {
  137. if( m_allTextures[ i ].width != m_sizes[ m_selectedSizeX ] || m_allTextures[ i ].height != m_sizes[ m_selectedSizeY ] )
  138. {
  139. showWarning = true;
  140. }
  141. }
  142. if( !showWarning )
  143. {
  144. m_message = string.Empty;
  145. if( m_tex3DMode )
  146. BuildTexture3D();
  147. else
  148. BuildArray();
  149. }
  150. else if( EditorUtility.DisplayDialog( "Warning!", "Some textures need to be resized to fit the selected size. Do you want to continue?", "Yes", "No" ) )
  151. {
  152. m_message = string.Empty;
  153. if( m_tex3DMode )
  154. BuildTexture3D();
  155. else
  156. BuildArray();
  157. }
  158. }
  159. EditorGUI.EndDisabledGroup();
  160. EditorGUI.BeginDisabledGroup( m_lastSaved == null );
  161. GUIContent icon = EditorGUIUtility.IconContent( "icons/d_ViewToolZoom.png" );
  162. if( GUILayout.Button( icon, "prebutton", GUILayout.Width( 28 ), GUILayout.Height( 20 ) ) )
  163. {
  164. EditorGUIUtility.PingObject( m_lastSaved );
  165. }
  166. EditorGUI.EndDisabledGroup();
  167. EditorGUILayout.EndHorizontal();
  168. // message
  169. if( !string.IsNullOrEmpty( m_message ) )
  170. if( GUILayout.Button( "BUILD REPORT (click to hide):\n\n" + m_message, "helpbox" ) )
  171. m_message = string.Empty;
  172. // options
  173. EditorGUILayout.BeginHorizontal();
  174. EditorGUILayout.PrefixLabel( "Size" );
  175. EditorGUIUtility.labelWidth = 16;
  176. m_selectedSizeX = EditorGUILayout.Popup( "X", m_selectedSizeX, m_sizesStr );
  177. EditorGUI.BeginDisabledGroup( m_lockRatio );
  178. m_selectedSizeY = EditorGUILayout.Popup( "Y", m_lockRatio ? m_selectedSizeX : m_selectedSizeY, m_sizesStr );
  179. EditorGUI.EndDisabledGroup();
  180. EditorGUIUtility.labelWidth = 100;
  181. m_lockRatio = GUILayout.Toggle( m_lockRatio, "L", "minibutton", GUILayout.Width( 18 ) );
  182. EditorGUILayout.EndHorizontal();
  183. EditorGUI.BeginChangeCheck();
  184. m_tex3DMode = EditorGUILayout.Toggle( "Texture 3D", m_tex3DMode );
  185. if( EditorGUI.EndChangeCheck() )
  186. {
  187. if( !m_filenameChanged )
  188. {
  189. m_fileName = m_tex3DMode ? Texture3DFilename:ArrayFilename;
  190. }
  191. }
  192. m_linearMode = EditorGUILayout.Toggle( "Linear", m_linearMode );
  193. m_mipMaps = EditorGUILayout.Toggle( "Mip Maps", m_mipMaps );
  194. m_wrapMode = (TextureWrapMode)EditorGUILayout.EnumPopup( "Wrap Mode", m_wrapMode );
  195. m_filterMode = (FilterMode)EditorGUILayout.EnumPopup( "Filter Mode", m_filterMode );
  196. m_anisoLevel = EditorGUILayout.IntSlider( "Aniso Level", m_anisoLevel, 0, 16 );
  197. m_selectedFormatEnum = (TextureFormat)EditorGUILayout.EnumPopup( "Format", m_selectedFormatEnum );
  198. if( m_selectedFormatEnum == TextureFormat.DXT1Crunched )
  199. {
  200. m_selectedFormatEnum = TextureFormat.DXT1;
  201. Debug.Log( "Texture Array does not support crunched DXT1 format. Changing to DXT1..." );
  202. }
  203. else if( m_selectedFormatEnum == TextureFormat.DXT5Crunched )
  204. {
  205. m_selectedFormatEnum = TextureFormat.DXT5;
  206. Debug.Log( "Texture Array does not support crunched DXT5 format. Changing to DXT5..." );
  207. }
  208. m_quality = EditorGUILayout.IntSlider( "Format Quality", m_quality, 0, 100 );
  209. EditorGUILayout.Separator();
  210. EditorGUILayout.LabelField( "Path and Name" );
  211. EditorGUILayout.BeginHorizontal();
  212. m_pathButtonContent.text = m_folderPath;
  213. Vector2 buttonSize = m_pathButtonStyle.CalcSize( m_pathButtonContent );
  214. if( GUILayout.Button( m_pathButtonContent, m_pathButtonStyle, GUILayout.MaxWidth( Mathf.Min( position.width * 0.5f, buttonSize.x ) ) ) )
  215. {
  216. string folderpath = EditorUtility.OpenFolderPanel( "Save Texture Array to folder", "Assets/", "" );
  217. folderpath = FileUtil.GetProjectRelativePath( folderpath );
  218. if( string.IsNullOrEmpty( folderpath ) )
  219. m_folderPath = "Assets/";
  220. else
  221. m_folderPath = folderpath + "/";
  222. }
  223. EditorGUI.BeginChangeCheck();
  224. m_fileName = EditorGUILayout.TextField( m_fileName, GUILayout.ExpandWidth( true ) );
  225. if( EditorGUI.EndChangeCheck() )
  226. {
  227. m_filenameChanged = true;
  228. }
  229. EditorGUILayout.LabelField( ".asset", GUILayout.MaxWidth( 40 ) );
  230. EditorGUILayout.EndHorizontal();
  231. EditorGUILayout.Separator();
  232. // list
  233. EditorGUILayout.Separator();
  234. if( GUILayout.Button( ClearButtonStr ) )
  235. {
  236. m_allTextures.Clear();
  237. }
  238. if( m_listTextures != null )
  239. m_listTextures.DoLayoutList();
  240. GUILayout.Space( 20 );
  241. EditorGUILayout.EndVertical();
  242. EditorGUIUtility.labelWidth = cachedWidth;
  243. EditorGUILayout.EndScrollView();
  244. m_draggableArea.size = position.size;
  245. m_dragAndDropTool.TestDragAndDrop( m_draggableArea );
  246. }
  247. public void OnValidObjectsDropped( UnityEngine.Object[] droppedObjs )
  248. {
  249. for( int objIdx = 0; objIdx < droppedObjs.Length; objIdx++ )
  250. {
  251. Texture2D tex = droppedObjs[ objIdx ] as Texture2D;
  252. if( tex != null )
  253. {
  254. m_allTextures.Add( tex );
  255. }
  256. else
  257. {
  258. DefaultAsset asset = droppedObjs[ objIdx ] as DefaultAsset;
  259. if( asset != null )
  260. {
  261. string path = AssetDatabase.GetAssetPath( asset );
  262. if( AssetDatabase.IsValidFolder( path ) )
  263. {
  264. string[] pathArr = { path };
  265. string[] texInDir = AssetDatabase.FindAssets( TextureFilter, pathArr );
  266. for( int texIdx = 0; texIdx < texInDir.Length; texIdx++ )
  267. {
  268. Texture2D internalTex = AssetDatabase.LoadAssetAtPath<Texture2D>( AssetDatabase.GUIDToAssetPath( texInDir[ texIdx ] ));
  269. if( internalTex != null )
  270. {
  271. m_allTextures.Add( internalTex );
  272. }
  273. }
  274. }
  275. }
  276. }
  277. }
  278. }
  279. private void CopyToArray( ref Texture2D from, ref Texture2DArray to, int arrayIndex, int mipLevel, bool compressed = true )
  280. {
  281. if( compressed )
  282. {
  283. Graphics.CopyTexture( from, 0, mipLevel, to, arrayIndex, mipLevel );
  284. }
  285. else
  286. {
  287. to.SetPixels( from.GetPixels(), arrayIndex, mipLevel );
  288. to.Apply();
  289. }
  290. }
  291. #if NEW_TEXTURE_3D_METHOD
  292. private void BuildTexture3D()
  293. {
  294. int sizeX = m_sizes[ m_selectedSizeX ];
  295. int sizeY = m_sizes[ m_selectedSizeY ];
  296. Texture3D texture3D = new Texture3D( sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps );
  297. texture3D.wrapMode = m_wrapMode;
  298. texture3D.filterMode = m_filterMode;
  299. texture3D.anisoLevel = m_anisoLevel;
  300. //texture3D.Apply( false );
  301. RenderTexture cache = RenderTexture.active;
  302. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default );
  303. rt.Create();
  304. List<Texture2D> textures = new List<Texture2D>( m_allTextures.Count );
  305. for( int i = 0; i < m_allTextures.Count; i++ )
  306. {
  307. // build report
  308. int widthChanges = m_allTextures[ i ].width < sizeX ? -1 : m_allTextures[ i ].width > sizeX ? 1 : 0;
  309. int heightChanges = m_allTextures[ i ].height < sizeY ? -1 : m_allTextures[ i ].height > sizeY ? 1 : 0;
  310. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  311. m_message += m_allTextures[ i ].name + " was upscaled\n";
  312. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  313. m_message += m_allTextures[ i ].name + " was downscaled\n";
  314. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  315. m_message += m_allTextures[ i ].name + " changed dimensions\n";
  316. // blit image to upscale or downscale the image to any size
  317. RenderTexture.active = rt;
  318. bool cachedsrgb = GL.sRGBWrite;
  319. GL.sRGBWrite = !m_linearMode;
  320. Graphics.Blit( m_allTextures[ i ], rt );
  321. GL.sRGBWrite = cachedsrgb;
  322. textures.Add( new Texture2D( sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode ));
  323. textures[ i ].ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, m_mipMaps );
  324. RenderTexture.active = null;
  325. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( m_selectedFormatEnum ) ) < 0;
  326. if( isCompressed )
  327. {
  328. EditorUtility.CompressTexture( textures[ i ], m_selectedFormatEnum, m_quality );
  329. // t2d.Apply( false );
  330. }
  331. textures[ i ].Apply( false );
  332. }
  333. rt.Release();
  334. RenderTexture.active = cache;
  335. if( m_message.Length > 0 )
  336. m_message = m_message.Substring( 0, m_message.Length - 1 );
  337. int sizeZ = textures.Count;
  338. Color[] colors = new Color[ sizeX * sizeY * sizeZ ];
  339. int idx = 0;
  340. for( int z = 0; z < sizeZ; z++ )
  341. {
  342. for( int y = 0; y < sizeY; y++ )
  343. {
  344. for( int x = 0; x < sizeX; x++, idx++ )
  345. {
  346. colors[ idx ] = textures[ z ].GetPixel(x,y);
  347. }
  348. }
  349. }
  350. texture3D.SetPixels( colors );
  351. texture3D.Apply();
  352. string path = m_folderPath + m_fileName + ".asset";
  353. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  354. if( outfile != null )
  355. {
  356. EditorUtility.CopySerialized( texture3D, outfile );
  357. AssetDatabase.SaveAssets();
  358. EditorGUIUtility.PingObject( outfile );
  359. m_lastSaved = outfile;
  360. }
  361. else
  362. {
  363. AssetDatabase.CreateAsset( texture3D, path );
  364. EditorGUIUtility.PingObject( texture3D );
  365. m_lastSaved = texture3D;
  366. }
  367. }
  368. #else
  369. private void BuildTexture3D()
  370. {
  371. int sizeX = m_sizes[ m_selectedSizeX ];
  372. int sizeY = m_sizes[ m_selectedSizeY ];
  373. int mipCount = m_mipMaps ? MipCount[ Mathf.Max( sizeX, sizeY ) ] : 1;
  374. Texture3D texture3D = new Texture3D( sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps );
  375. texture3D.wrapMode = m_wrapMode;
  376. texture3D.filterMode = m_filterMode;
  377. texture3D.anisoLevel = m_anisoLevel;
  378. texture3D.Apply( false );
  379. RenderTexture cache = RenderTexture.active;
  380. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default );
  381. rt.Create();
  382. List<List<Color>> mipColor = new List<List<Color>>();
  383. if( m_mipMaps )
  384. {
  385. for( int i = 0; i < mipCount; i++ )
  386. {
  387. mipColor.Add( new List<Color>() );
  388. }
  389. }
  390. else
  391. {
  392. mipColor.Add( new List<Color>() );
  393. }
  394. for( int i = 0; i < m_allTextures.Count; i++ )
  395. {
  396. // build report
  397. int widthChanges = m_allTextures[ i ].width < sizeX ? -1 : m_allTextures[ i ].width > sizeX ? 1 : 0;
  398. int heightChanges = m_allTextures[ i ].height < sizeY ? -1 : m_allTextures[ i ].height > sizeY ? 1 : 0;
  399. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  400. m_message += m_allTextures[ i ].name + " was upscaled\n";
  401. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  402. m_message += m_allTextures[ i ].name + " was downscaled\n";
  403. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  404. m_message += m_allTextures[ i ].name + " changed dimensions\n";
  405. // blit image to upscale or downscale the image to any size
  406. RenderTexture.active = rt;
  407. bool cachedsrgb = GL.sRGBWrite;
  408. GL.sRGBWrite = !m_linearMode;
  409. Graphics.Blit( m_allTextures[ i ], rt );
  410. GL.sRGBWrite = cachedsrgb;
  411. Texture2D t2d = new Texture2D( sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode );
  412. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, m_mipMaps );
  413. RenderTexture.active = null;
  414. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( m_selectedFormatEnum ) ) < 0;
  415. if( isCompressed )
  416. {
  417. EditorUtility.CompressTexture( t2d, m_selectedFormatEnum, m_quality );
  418. // t2d.Apply( false );
  419. }
  420. t2d.Apply( false );
  421. if( m_mipMaps )
  422. {
  423. for( int mip = 0; mip < mipCount; mip++ )
  424. {
  425. mipColor[ mip ].AddRange( t2d.GetPixels( mip ) );
  426. }
  427. }
  428. else
  429. {
  430. mipColor[ 0 ].AddRange( t2d.GetPixels( 0 ) );
  431. }
  432. }
  433. rt.Release();
  434. RenderTexture.active = cache;
  435. if( m_message.Length > 0 )
  436. m_message = m_message.Substring( 0, m_message.Length - 1 );
  437. for( int i = 0; i < mipCount; i++ )
  438. {
  439. texture3D.SetPixels( mipColor[ i ].ToArray(), i );
  440. }
  441. texture3D.Apply( false );
  442. string path = m_folderPath + m_fileName + ".asset";
  443. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  444. if( outfile != null )
  445. {
  446. EditorUtility.CopySerialized( texture3D, outfile );
  447. AssetDatabase.SaveAssets();
  448. EditorGUIUtility.PingObject( outfile );
  449. m_lastSaved = outfile;
  450. }
  451. else
  452. {
  453. AssetDatabase.CreateAsset( texture3D, path );
  454. EditorGUIUtility.PingObject( texture3D );
  455. m_lastSaved = texture3D;
  456. }
  457. }
  458. #endif
  459. private void BuildTexture3DAutoMips()
  460. {
  461. int sizeX = m_sizes[ m_selectedSizeX ];
  462. int sizeY = m_sizes[ m_selectedSizeY ];
  463. Texture3D texture3D = new Texture3D( sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps );
  464. texture3D.wrapMode = m_wrapMode;
  465. texture3D.filterMode = m_filterMode;
  466. texture3D.anisoLevel = m_anisoLevel;
  467. texture3D.Apply( false );
  468. RenderTexture cache = RenderTexture.active;
  469. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default );
  470. rt.Create();
  471. List<Color> texColors = new List<Color>();
  472. for( int i = 0; i < m_allTextures.Count; i++ )
  473. {
  474. // build report
  475. int widthChanges = m_allTextures[ i ].width < sizeX ? -1 : m_allTextures[ i ].width > sizeX ? 1 : 0;
  476. int heightChanges = m_allTextures[ i ].height < sizeY ? -1 : m_allTextures[ i ].height > sizeY ? 1 : 0;
  477. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  478. m_message += m_allTextures[ i ].name + " was upscaled\n";
  479. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  480. m_message += m_allTextures[ i ].name + " was downscaled\n";
  481. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  482. m_message += m_allTextures[ i ].name + " changed dimensions\n";
  483. // blit image to upscale or downscale the image to any size
  484. RenderTexture.active = rt;
  485. bool cachedsrgb = GL.sRGBWrite;
  486. GL.sRGBWrite = !m_linearMode;
  487. Graphics.Blit( m_allTextures[ i ], rt );
  488. GL.sRGBWrite = cachedsrgb;
  489. Texture2D t2d = new Texture2D( sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode );
  490. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, m_mipMaps );
  491. RenderTexture.active = null;
  492. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( m_selectedFormatEnum ) ) < 0;
  493. if( isCompressed )
  494. {
  495. EditorUtility.CompressTexture( t2d, m_selectedFormatEnum, m_quality );
  496. t2d.Apply( false );
  497. }
  498. texColors.AddRange( t2d.GetPixels() );
  499. }
  500. rt.Release();
  501. RenderTexture.active = cache;
  502. if( m_message.Length > 0 )
  503. m_message = m_message.Substring( 0, m_message.Length - 1 );
  504. texture3D.SetPixels( texColors.ToArray() );
  505. texture3D.Apply();
  506. string path = m_folderPath + m_fileName + ".asset";
  507. Texture3D outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture3D;
  508. if( outfile != null )
  509. {
  510. EditorUtility.CopySerialized( texture3D, outfile );
  511. AssetDatabase.SaveAssets();
  512. EditorGUIUtility.PingObject( outfile );
  513. m_lastSaved = outfile;
  514. }
  515. else
  516. {
  517. AssetDatabase.CreateAsset( texture3D, path );
  518. EditorGUIUtility.PingObject( texture3D );
  519. m_lastSaved = texture3D;
  520. }
  521. }
  522. private void BuildArray()
  523. {
  524. int sizeX = m_sizes[ m_selectedSizeX ];
  525. int sizeY = m_sizes[ m_selectedSizeY ];
  526. Texture2DArray textureArray = new Texture2DArray( sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps, m_linearMode );
  527. textureArray.wrapMode = m_wrapMode;
  528. textureArray.filterMode = m_filterMode;
  529. textureArray.anisoLevel = m_anisoLevel;
  530. textureArray.Apply( false );
  531. RenderTexture cache = RenderTexture.active;
  532. RenderTexture rt = new RenderTexture( sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default );
  533. rt.Create();
  534. for( int i = 0; i < m_allTextures.Count; i++ )
  535. {
  536. // build report
  537. int widthChanges = m_allTextures[ i ].width < sizeX ? -1 : m_allTextures[ i ].width > sizeX ? 1 : 0;
  538. int heightChanges = m_allTextures[ i ].height < sizeY ? -1 : m_allTextures[ i ].height > sizeY ? 1 : 0;
  539. if( ( widthChanges < 0 && heightChanges <= 0 ) || ( widthChanges <= 0 && heightChanges < 0 ) )
  540. m_message += m_allTextures[ i ].name + " was upscaled\n";
  541. else if( ( widthChanges > 0 && heightChanges >= 0 ) || ( widthChanges >= 0 && heightChanges > 0 ) )
  542. m_message += m_allTextures[ i ].name + " was downscaled\n";
  543. else if( ( widthChanges > 0 && heightChanges < 0 ) || ( widthChanges < 0 && heightChanges > 0 ) )
  544. m_message += m_allTextures[ i ].name + " changed dimensions\n";
  545. // blit image to upscale or downscale the image to any size
  546. RenderTexture.active = rt;
  547. bool cachedsrgb = GL.sRGBWrite;
  548. GL.sRGBWrite = !m_linearMode;
  549. Graphics.Blit( m_allTextures[ i ], rt );
  550. GL.sRGBWrite = cachedsrgb;
  551. Texture2D t2d = new Texture2D( sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode );
  552. t2d.ReadPixels( new Rect( 0, 0, sizeX, sizeY ), 0, 0, m_mipMaps );
  553. RenderTexture.active = null;
  554. bool isCompressed = UncompressedFormats.FindIndex( x => x.Equals( m_selectedFormatEnum ) ) < 0;
  555. if( isCompressed )
  556. {
  557. EditorUtility.CompressTexture( t2d, m_selectedFormatEnum, m_quality );
  558. t2d.Apply( false );
  559. }
  560. if( m_mipMaps )
  561. {
  562. int maxSize = Mathf.Max( sizeX, sizeY );
  563. for( int mip = 0; mip < MipCount[ maxSize ]; mip++ )
  564. {
  565. CopyToArray( ref t2d, ref textureArray, i, mip, isCompressed );
  566. }
  567. }
  568. else
  569. {
  570. CopyToArray( ref t2d, ref textureArray, i, 0, isCompressed );
  571. }
  572. }
  573. rt.Release();
  574. RenderTexture.active = cache;
  575. if( m_message.Length > 0 )
  576. m_message = m_message.Substring( 0, m_message.Length - 1 );
  577. string path = m_folderPath + m_fileName + ".asset";
  578. Texture2DArray outfile = AssetDatabase.LoadMainAssetAtPath( path ) as Texture2DArray;
  579. if( outfile != null )
  580. {
  581. EditorUtility.CopySerialized( textureArray, outfile );
  582. AssetDatabase.SaveAssets();
  583. EditorGUIUtility.PingObject( outfile );
  584. m_lastSaved = outfile;
  585. }
  586. else
  587. {
  588. AssetDatabase.CreateAsset( textureArray, path );
  589. EditorGUIUtility.PingObject( textureArray );
  590. m_lastSaved = textureArray;
  591. }
  592. }
  593. }
  594. }