public void Export(STGenericTexture texture, TextureExportSettings settings, string filePath) { List <Surface> surfaces = texture.GetSurfaces(settings.ArrayLevel, settings.ExportArrays); var format = texture.Platform.OutputFormat; ASTC atsc = new ASTC(); atsc.Width = texture.Width; atsc.Height = texture.Height; atsc.Depth = texture.Depth; atsc.BlockDimX = (byte)TextureFormatHelper.GetBlockWidth(format); atsc.BlockDimY = (byte)TextureFormatHelper.GetBlockHeight(format); atsc.BlockDimZ = (byte)TextureFormatHelper.GetBlockDepth(format); atsc.DataBlock = ByteUtils.CombineArray(surfaces[0].mipmaps.ToArray()); atsc.Save(new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite)); }
public void Export(STGenericTexture texture, TextureExportSettings settings, string filePath) { List <Surface> surfaces = texture.GetSurfaces(settings.ArrayLevel, settings.ExportArrays); DDS dds = new DDS(); dds.MainHeader = new DDS.Header(); dds.MainHeader.Width = texture.Width; dds.MainHeader.Height = texture.Height; dds.MainHeader.Depth = texture.Depth; dds.MainHeader.MipCount = (uint)texture.MipCount; dds.MainHeader.PitchOrLinearSize = (uint)surfaces[0].mipmaps[0].Length; if (surfaces.Count > 1) //Use DX10 format for array surfaces as it can do custom amounts { dds.SetFlags(Platform.OutputFormat, true, texture.IsCubemap); } else { dds.SetFlags(Platform.OutputFormat, false, texture.IsCubemap); } if (dds.IsDX10) { if (dds.Dx10Header == null) { dds.Dx10Header = new DDS.DX10Header(); } dds.Dx10Header.ResourceDim = 3; if (texture.IsCubemap) { dds.Dx10Header.ArrayCount = (uint)(texture.ArrayCount / 6); } else { dds.Dx10Header.ArrayCount = (uint)texture.ArrayCount; } } dds.Save(filePath, surfaces); }
public void LoadOpenGLTexture(STGenericTexture GenericTexture, int ArrayStartIndex = 0, bool LoadArrayLevels = false) { if (!Runtime.OpenTKInitialized || GLInitialized || IsFailedState) { return; } width = (int)GenericTexture.Width; height = (int)GenericTexture.Height; IsCubeMap = GenericTexture.ArrayCount == 6; ApplySurfaceInformation(GenericTexture.SurfaceType); if (GenericTexture.ArrayCount == 0) { GenericTexture.ArrayCount = 1; } List <STGenericTexture.Surface> Surfaces = new List <STGenericTexture.Surface>(); try { if (UseMipmaps && GenericTexture.ArrayCount == 1) { //Load surfaces with mip maps Surfaces = GenericTexture.GetSurfaces(ArrayStartIndex, false, 6); } else { //Only load first mip level. Will be generated after for (int i = 0; i < GenericTexture.ArrayCount; i++) { if (i >= ArrayStartIndex && i <= ArrayStartIndex + 6) //Only load up to 6 faces { Surfaces.Add(new STGenericTexture.Surface() { mipmaps = new List <byte[]>() { GenericTexture.GetSurface(i, 0) } }); } } } if (Surfaces.Count == 0 || Surfaces[0].mipmaps[0].Length == 0) { return; } IsCubeMap = Surfaces.Count == 6; ImageSize = Surfaces[0].mipmaps[0].Length; if (IsCubeMap) { TextureTarget = TextureTarget.TextureCubeMap; } //Open GL decoder has issues with certain width/heights so use in tool converters if necessary if ((!IsPow2(width) || !IsPow2(height)) && GenericTexture.IsBCNCompressed() || GenericTexture.IsASTC() || GenericTexture.Platform.OutputFormat == TexFormat.BC5_SNORM) { UseOpenGLDecoder = false; } pixelInternalFormat = PixelInternalFormat.Rgba; pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; if (GenericTexture.Platform is Imaging.CTRSwizzle || GenericTexture.Platform is Imaging.GamecubeSwizzle || GenericTexture.Platform is Imaging.NitroSwizzle || GenericTexture.IsASTC()) { pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Bgra; UseOpenGLDecoder = false; } else if (UseOpenGLDecoder) { SetPixelFormats(GenericTexture.Platform.OutputFormat); } GLInitialized = true; for (int i = 0; i < Surfaces.Count; i++) { for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++) { uint width = Math.Max(1, GenericTexture.Width >> MipLevel); uint height = Math.Max(1, GenericTexture.Height >> MipLevel); if (!UseOpenGLDecoder) { Surfaces[i].mipmaps[MipLevel] = TryDecodeSurface(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture); } } } TexID = GenerateOpenGLTexture(this, Surfaces); Surfaces.Clear(); } catch { IsFailedState = true; GLInitialized = false; return; } }
public void LoadOpenGLTexture(STGenericTexture GenericTexture, int ArrayStartIndex = 0, bool LoadArrayLevels = false) { if (!Runtime.OpenTKInitialized || GLInitialized || IsFailedState) { return; } width = (int)GenericTexture.Width; height = (int)GenericTexture.Height; switch (GenericTexture.SurfaceType) { case STSurfaceType.Texture1D: TextureTarget = TextureTarget.Texture1D; break; case STSurfaceType.Texture2D: TextureTarget = TextureTarget.Texture2D; break; case STSurfaceType.Texture2D_Array: TextureTarget = TextureTarget.Texture2DArray; break; case STSurfaceType.Texture2D_Mulitsample: TextureTarget = TextureTarget.Texture2DMultisample; break; case STSurfaceType.Texture2D_Multisample_Array: TextureTarget = TextureTarget.Texture2DMultisampleArray; break; case STSurfaceType.Texture3D: TextureTarget = TextureTarget.Texture3D; break; case STSurfaceType.TextureCube: IsCubeMap = true; TextureTarget = TextureTarget.TextureCubeMap; break; case STSurfaceType.TextureCube_Array: IsCubeMap = true; TextureTarget = TextureTarget.TextureCubeMapArray; break; } if (GenericTexture.ArrayCount == 0) { GenericTexture.ArrayCount = 1; } List <STGenericTexture.Surface> Surfaces = new List <STGenericTexture.Surface>(); try { if (UseMipmaps && GenericTexture.ArrayCount == 1) { //Load surfaces with mip maps Surfaces = GenericTexture.GetSurfaces(ArrayStartIndex, false, 6); } else { //Only load first mip level. Will be generated after for (int i = 0; i < GenericTexture.ArrayCount; i++) { if (i >= ArrayStartIndex && i <= ArrayStartIndex + 6) //Only load up to 6 faces { Surfaces.Add(new STGenericTexture.Surface() { mipmaps = new List <byte[]>() { GenericTexture.GetImageData(i, 0) } }); } } } if (Surfaces.Count == 0 || Surfaces[0].mipmaps[0].Length == 0) { return; } IsCubeMap = Surfaces.Count == 6; ImageSize = Surfaces[0].mipmaps[0].Length; if (IsCubeMap) { TextureTarget = TextureTarget.TextureCubeMap; } //Force RGBA and use ST for decoding for weird width/heights //Open GL decoder has issues with certain width/heights Console.WriteLine($"width pow {width} {IsPow2(width)}"); Console.WriteLine($"height pow {height} {IsPow2(height)}"); if (!IsPow2(width) || !IsPow2(height)) { UseOpenGLDecoder = false; } pixelInternalFormat = PixelInternalFormat.Rgba; pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; if (GenericTexture.Platform is Imaging.CTRSwizzle || GenericTexture.Platform is Imaging.GamecubeSwizzle || GenericTexture.Platform is Imaging.NitroSwizzle) { UseOpenGLDecoder = false; pixelFormat = OpenTK.Graphics.OpenGL.PixelFormat.Bgra; } if (UseOpenGLDecoder) { SetPixelFormats(GenericTexture.Platform.OutputFormat); } GLInitialized = true; for (int i = 0; i < Surfaces.Count; i++) { for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++) { uint width = Math.Max(1, GenericTexture.Width >> MipLevel); uint height = Math.Max(1, GenericTexture.Height >> MipLevel); if (!UseOpenGLDecoder) { Surfaces[i].mipmaps[MipLevel] = TryDecodeSurface(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture); } } } TexID = GenerateOpenGLTexture(this, Surfaces); if (IsCubeMap) { TextureWrapS = TextureWrapMode.Clamp; TextureWrapT = TextureWrapMode.Clamp; TextureWrapR = TextureWrapMode.Clamp; TextureMinFilter = TextureMinFilter.LinearMipmapLinear; TextureMagFilter = TextureMagFilter.Linear; } Surfaces.Clear(); } catch { IsFailedState = true; GLInitialized = false; return; } }