public void LoadDDS(string FileName, byte[] FileData = null) { TexName = STGenericTexture.SetNameFromPath(FileName); DDS dds = new DDS(); if (FileData != null) { dds.Load(new FileReader(new MemoryStream(FileData))); } else { dds.Load(new FileReader(FileName)); } MipCount = dds.header.mipmapCount; TexWidth = dds.header.width; TexHeight = dds.header.height; arrayLength = 1; if (dds.header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) { arrayLength = 6; } DataBlockOutput.Add(dds.bdata); Format = (CTR_3DS.PICASurfaceFormat)CTR_3DS.ConvertToPICAFormat(dds.Format); }
public void Load(TGLP texture, int Index) { CanReplace = true; SheetIndex = Index; TextureTGLP = texture; Height = TextureTGLP.SheetHeight; Width = TextureTGLP.SheetWidth; var BFNTFormat = (CTR_3DS.PICASurfaceFormat)TextureTGLP.Format; Format = CTR_3DS.ConvertPICAToGenericFormat(BFNTFormat); if (Format == TEX_FORMAT.A4) { RedChannel = STChannelType.Alpha; GreenChannel = STChannelType.Alpha; BlueChannel = STChannelType.Alpha; AlphaChannel = STChannelType.Alpha; } PlatformSwizzle = PlatformSwizzle.Platform_3DS; ImageKey = "Texture"; SelectedImageKey = "Texture"; }
public override void Replace(string FileName) { CTR_3DSTextureImporter importer = new CTR_3DSTextureImporter(); CTR_3DSImporterSettings settings = new CTR_3DSImporterSettings(); settings.LoadBitMap(FileName); importer.LoadSettings(new List <CTR_3DSImporterSettings>() { settings, }); settings.MipCount = 1; settings.Format = CTR_3DS.ConvertToPICAFormat(Format); if (importer.ShowDialog() == DialogResult.OK) { if (settings.GenerateMipmaps && !settings.IsFinishedCompressing) { settings.DataBlockOutput.Clear(); settings.DataBlockOutput.Add(settings.GenerateMips()); } ApplySettings(settings); UpdateEditor(); } }
public byte[] DecodeImage(STGenericTexture texture, byte[] data, uint width, uint height, int array, int mip) { var settings = new CTR_3DS.SwizzleSettings() { Orientation = SwizzleMode, }; return(ImageUtility.ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format, settings))); }
public void SetupSettings() { if (SelectedIndex == -1) { return; } if (Thread != null && Thread.IsAlive) { Thread.Abort(); } if (formatComboBox.SelectedItem is CTR_3DS.PICASurfaceFormat) { SelectedTexSettings.Format = (CTR_3DS.PICASurfaceFormat)formatComboBox.SelectedItem; listViewCustom1.Items[SelectedIndex].SubItems[1].Text = SelectedTexSettings.Format.ToString(); } HeightLabel.Text = $"Height: {SelectedTexSettings.TexHeight}"; WidthLabel.Text = $"Width: {SelectedTexSettings.TexWidth}"; Bitmap bitmap = Toolbox.Library.Imaging.GetLoadingImage(); pictureBox1.Image = bitmap; Thread = new Thread((ThreadStart)(() => { SelectedTexSettings.IsFinishedCompressing = false; ToggleOkButton(false); var mips = SelectedTexSettings.GenerateMipList(); SelectedTexSettings.DataBlockOutput.Clear(); SelectedTexSettings.DataBlockOutput.Add(Utils.CombineByteArray(mips.ToArray())); ToggleOkButton(true); SelectedTexSettings.IsFinishedCompressing = true; bitmap = CTR_3DS.DecodeBlockToBitmap(mips[0], (int)SelectedTexSettings.TexWidth, (int)SelectedTexSettings.TexHeight, SelectedTexSettings.Format); bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker) delegate { pictureBox1.Image = bitmap; pictureBox1.Refresh(); int size = Utils.GetSizeInBytes(mips); dataSizeLbl.Text = $"Data Size: {STMath.GetFileSize(size, 5)}"; }); } mips.Clear(); })); Thread.Start(); }
public void LoadBitMap(Image Image, string FileName) { DecompressedData.Clear(); TexName = STGenericTexture.SetNameFromPath(FileName); Format = CTR_3DS.ConvertToPICAFormat(Runtime.PreferredTexFormat); GenerateMipmaps = true; LoadImage(new Bitmap(Image)); }
private void ApplyCtpkTexture(TextureEntry tex) { CtpkTexture = tex; Width = tex.Width; Height = tex.Height; MipCount = tex.MipCount; ArrayCount = tex.FaceCount; Text = tex.Name; Format = CTR_3DS.ConvertPICAToGenericFormat(tex.PicaFormat); PlatformSwizzle = PlatformSwizzle.Platform_3DS; }
public void Save(System.IO.Stream stream) { using (var writer = new FileWriter(stream, true)) { writer.Write(Width); writer.Write(Height); writer.Write((byte)CTR_3DS.ConvertToPICAFormat(Format)); writer.Write((byte)MipCount); writer.Write((ushort)0); //Padding writer.WriteString(Text); writer.Position = 0x80; writer.Write(ImageData); } }
public void LoadSupportedFormats(TEX_FORMAT[] Formats) { formatComboBox.Items.Clear(); foreach (TEX_FORMAT format in Formats) { var CtrFormat = CTR_3DS.ConvertToPICAFormat(format); formatComboBox.Items.Add(CtrFormat); } var CtrDefaultFormat = CTR_3DS.ConvertToPICAFormat(Runtime.PreferredTexFormat); if (formatComboBox.Items.Contains(CtrDefaultFormat)) { formatComboBox.SelectedItem = CtrDefaultFormat; } }
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel) { if (bitmap == null || image == null) { return; //Image is likely disposed and not needed to be applied } MipCount = 1; var CtrFormat = CTR_3DS.ConvertToPICAFormat(Format); try { //Create image block from bitmap first var data = GenerateMipsAndCompress(bitmap, MipCount, Format); //Swizzle and create surface /* var surface = GX2.CreateGx2Texture(data, Text, * (uint)image.TileMode, * (uint)0, * (uint)image.Width, * (uint)image.Height, * (uint)1, * (uint)Gx2Format, * (uint)0, * (uint)1, * (uint)MipCount * ); * * image.Swizzle = (byte)surface.swizzle; * image.BCLIMFormat = ConvertFormatGenericToBflim(Format); * image.Height = (ushort)surface.height; * image.Width = (ushort)surface.width;*/ Width = image.Width; Height = image.Height; // ImageData = surface.data; IsEdited = true; LoadOpenGLTexture(); LibraryGUI.UpdateViewport(); } catch (Exception ex) { STErrorDialog.Show("Failed to swizzle and compress image " + Text, "Error", ex.ToString()); } }
public override void Replace(string FileName) { CTR_3DSTextureImporter importer = new CTR_3DSTextureImporter(); CTR_3DSImporterSettings settings = new CTR_3DSImporterSettings(); if (Utils.GetExtension(FileName) == ".dds" || Utils.GetExtension(FileName) == ".dds2") { settings.LoadDDS(FileName); importer.LoadSettings(new List <CTR_3DSImporterSettings>() { settings, }); ApplySettings(settings); UpdateEditor(); } else { settings.LoadBitMap(FileName); settings.Format = CTR_3DS.ConvertToPICAFormat(Format); if (MipCount == 1) { settings.MipCount = 1; } importer.LoadSettings(new List <CTR_3DSImporterSettings>() { settings, }); if (importer.ShowDialog() == DialogResult.OK) { if (settings.GenerateMipmaps && !settings.IsFinishedCompressing) { settings.DataBlockOutput.Clear(); settings.DataBlockOutput.Add(settings.GenerateMips()); } Console.WriteLine($"ImageSize {this.ImageData.Length} {settings.DataBlockOutput[0]}"); ApplySettings(settings); UpdateEditor(); } } }
private void ApplySettings(CTR_3DSImporterSettings settings) { if (this.Width != settings.TexWidth) { throw new Exception("The image should be the same width as the original!"); } if (this.Height != settings.TexHeight) { throw new Exception("The image should be the same height as the original!"); } this.TextureTGLP.SheetDataList[SheetIndex] = settings.DataBlockOutput[0]; this.TextureTGLP.Format = (ushort)CTR_3DS.ConvertToPICAFormat(settings.GenericFormat); this.Format = settings.GenericFormat; this.MipCount = settings.MipCount; this.Depth = settings.Depth; this.ArrayCount = (uint)settings.DataBlockOutput.Count; }
public List <byte[]> GenerateMipList(int SurfaceLevel = 0) { Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); List <byte[]> mipmaps = new List <byte[]>(); mipmaps.Add(CTR_3DS.EncodeBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format)); for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { int width = Image.Width / 2; int height = Image.Width / 2; if (Format == CTR_3DS.PICASurfaceFormat.ETC1 || Format == CTR_3DS.PICASurfaceFormat.ETC1A4) { if (width < 16) { break; } if (height < 16) { break; } } else { if (width < 8) { break; } if (height < 8) { break; } } Image = BitmapExtension.Resize(Image, width, height); mipmaps.Add(CTR_3DS.EncodeBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format)); } Image.Dispose(); return(mipmaps); }
public void LoadTexture(H3DTexture texture) { ImageKey = "Texture"; SelectedImageKey = "Texture"; Texture = texture; Text = texture.Name; Width = (uint)texture.Width; Height = (uint)texture.Height; MipCount = texture.MipmapSize; Format = CTR_3DS.ConvertPICAToGenericFormat( (CTR_3DS.PICASurfaceFormat)texture.Format); if (texture.IsCubeTexture) { } }
public void Load(System.IO.Stream stream) { PlatformSwizzle = PlatformSwizzle.Platform_3DS; CanSave = true; using (var reader = new FileReader(stream)) { Width = reader.ReadUInt32(); Height = reader.ReadUInt32(); byte FormatCtr = reader.ReadByte(); MipCount = reader.ReadByte(); ushort padding = reader.ReadUInt16(); Text = reader.ReadZeroTerminatedString(); Format = CTR_3DS.ConvertPICAToGenericFormat((CTR_3DS.PICASurfaceFormat)FormatCtr); reader.Position = 0x80; ImageData = reader.ReadBytes((int)reader.BaseStream.Length - 0x80); } }
public byte[] Save() { MemoryStream mem = new MemoryStream(); using (var writer = new FileWriter(mem)) { writer.Write(Width); writer.Write(Height); writer.Write((byte)CTR_3DS.ConvertToPICAFormat(Format)); writer.Write((byte)MipCount); writer.Write((ushort)0); //Padding writer.WriteString(Text); writer.Position = 0x80; writer.Write(ImageData); } return(mem.ToArray()); }
public void Read(FileReader reader, CTXB ctxb) { string Magic = reader.ReadSignature(4, "ctxb"); uint FileSize = reader.ReadUInt32(); uint ChunkCount = reader.ReadUInt32(); reader.ReadUInt32(); //padding uint ChunkOffset = reader.ReadUInt32(); uint TextureDataOffset = reader.ReadUInt32(); for (int i = 0; i < ChunkCount; i++) { Chunks.Add(new Chunk(reader)); } for (int i = 0; i < ChunkCount; i++) { for (int t = 0; t < Chunks[i].Textures.Count; t++) { var texWrapper = new TextureWrapper(); texWrapper.Text = $"Texture {t}"; texWrapper.ImageKey = "texture"; texWrapper.SelectedImageKey = texWrapper.ImageKey; if (Chunks[i].Textures[t].Name != string.Empty) { texWrapper.Text = Chunks[i].Textures[t].Name; } texWrapper.Width = Chunks[i].Textures[t].Width; texWrapper.Height = Chunks[i].Textures[t].Height; texWrapper.Format = CTR_3DS.ConvertPICAToGenericFormat(Chunks[i].Textures[t].PicaFormat); reader.SeekBegin(TextureDataOffset + Chunks[i].Textures[t].DataOffset); texWrapper.ImageData = reader.ReadBytes((int)Chunks[i].Textures[t].ImageSize); ctxb.Nodes.Add(texWrapper); } } }
public void LoadTexture(Texture texture) { ImageKey = "Texture"; SelectedImageKey = "Texture"; Texture = texture; Text = texture.Name; //Cube maps will use multiple images //Break at the end as we only need the first part for generic things foreach (var image in texture.Images) { Width = image.Width; Height = image.Height; MipCount = image.MipCount; Format = CTR_3DS.ConvertPICAToGenericFormat( (CTR_3DS.PICASurfaceFormat)image.ImageFormat); break; } }
public List <byte[]> GenerateMipList(int SurfaceLevel = 0) { MipCount = 1; Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); List <byte[]> mipmaps = new List <byte[]>(); mipmaps.Add(CTR_3DS.EncodeBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, Format)); //while (Image.Width / 2 > 0 && Image.Height / 2 > 0) // for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2); mipmaps.Add(CTR_3DS.EncodeBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format)); } Image.Dispose(); return(mipmaps); }
public void LoadBitMap(string FileName) { DecompressedData.Clear(); TexName = STGenericTexture.SetNameFromPath(FileName); Format = CTR_3DS.ConvertToPICAFormat(Runtime.PreferredTexFormat); GenerateMipmaps = true; //If a texture is .tga, we need to convert it Bitmap Image = null; if (Utils.GetExtension(FileName) == ".tga") { Image = Paloma.TargaImage.LoadTargaImage(FileName); } else { Image = new Bitmap(FileName); } LoadImage(Image); }
public void Read(FileReader reader) { //Magic and ID not pointed to for sub entries so just skip them for now // uint magic = reader.ReadUInt32(); // if (magic != Identifier) // throw new Exception($"Invalid texture header magic! Expected {Identifier.ToString("x")}. Got {Identifier.ToString("x")}"); // ID = reader.ReadUInt32(); PlatformSwizzle = PlatformSwizzle.Platform_3DS; ImageSize = reader.ReadUInt32(); ID2 = reader.ReadUInt32(); reader.Seek(0x8); Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); reader.Seek(3); var numMips = reader.ReadByte(); reader.Seek(0x14); byte FormatCtr = reader.ReadByte(); reader.Seek(3); MipCount = 1; Format = CTR_3DS.ConvertPICAToGenericFormat((CTR_3DS.PICASurfaceFormat)FormatCtr); Parameters = new ImageParameters(); Parameters.FlipY = true; properties = new POWEProperties(); properties.ID = ID2; properties.Width = Width; properties.Height = Height; properties.NumMips = numMips; properties.Format = Format; }
public byte[] EncodeImage(STGenericTexture texture, byte[] data, uint width, uint height, int array, int mip) { return(CTR_3DS.EncodeBlock(data, (int)width, (int)height, Format)); }
private void ConvertFormat(uint Version) { if (Version <= 11) { Format = CTR_3DS.ConvertPICAToGenericFormat(SurfFormatOld); } else { switch (SurfFormat) { case SurfaceFormat.T_BC1_UNORM: Format = TEX_FORMAT.BC1_UNORM; break; case SurfaceFormat.T_BC1_SRGB: Format = TEX_FORMAT.BC1_UNORM_SRGB; break; case SurfaceFormat.T_BC2_UNORM: Format = TEX_FORMAT.BC2_UNORM; break; case SurfaceFormat.T_BC2_SRGB: Format = TEX_FORMAT.BC2_UNORM_SRGB; break; case SurfaceFormat.T_BC3_UNORM: Format = TEX_FORMAT.BC3_UNORM; break; case SurfaceFormat.T_BC3_SRGB: Format = TEX_FORMAT.BC3_UNORM_SRGB; break; case SurfaceFormat.T_BC4_UNORM: Format = TEX_FORMAT.BC4_UNORM; break; case SurfaceFormat.T_BC4_SNORM: Format = TEX_FORMAT.BC4_SNORM; break; case SurfaceFormat.T_BC5_UNORM: Format = TEX_FORMAT.BC5_UNORM; break; case SurfaceFormat.T_BC5_SNORM: Format = TEX_FORMAT.BC5_SNORM; break; case SurfaceFormat.TC_R8_G8_UNORM: Format = TEX_FORMAT.R8G8_UNORM; break; case SurfaceFormat.TC_R8_G8_B8_A8_SRGB: Format = TEX_FORMAT.R8G8B8A8_UNORM_SRGB; break; case SurfaceFormat.TCS_R8_G8_B8_A8: Format = TEX_FORMAT.R8G8B8A8_UNORM; break; case SurfaceFormat.TC_R8_UNORM: Format = TEX_FORMAT.R8_UNORM; break; case SurfaceFormat.TCS_R5_G6_B5_UNORM: Format = TEX_FORMAT.B5G6R5_UNORM; break; case SurfaceFormat.ETC1: Format = TEX_FORMAT.ETC1_UNORM; break; case SurfaceFormat.ETC1_A4: Format = TEX_FORMAT.ETC1_A4; break; case SurfaceFormat.L4: Format = TEX_FORMAT.L4; break; case SurfaceFormat.L8: Format = TEX_FORMAT.L8; break; case SurfaceFormat.LA4: Format = TEX_FORMAT.LA4; break; case SurfaceFormat.LA8: Format = TEX_FORMAT.LA8; break; case SurfaceFormat.HIL08: Format = TEX_FORMAT.HIL08; break; case SurfaceFormat.TC_R8_G8_B8_A8_UNORM: Format = TEX_FORMAT.R8G8B8A8_UNORM; break; case SurfaceFormat.TC_R4_G4_B4_UNORM: Format = TEX_FORMAT.B4G4R4A4_UNORM; break; case SurfaceFormat.TC_R8_G8_B8_UNORM: Format = TEX_FORMAT.R8G8B8A8_UNORM; break; case SurfaceFormat.TC_R4_R4_SNORM: Format = TEX_FORMAT.R4G4_UNORM; break; case SurfaceFormat.A4: Format = TEX_FORMAT.A4; break; default: throw new Exception("Format unsupported! " + SurfFormat); } } }
public Bitmap GetBitmap(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0) { uint width = Math.Max(1, Width >> MipLevel); uint height = Math.Max(1, Height >> MipLevel); byte[] data = GetImageData(ArrayLevel, MipLevel, DepthLevel); byte[] paletteData = GetPaletteData(); if (Format == TEX_FORMAT.R8G8B8A8_UNORM) { return(BitmapExtension.GetBitmap(ConvertBgraToRgba(data), (int)width, (int)height)); } try { if (data == null) { throw new Exception("Data is null!"); } if (PlatformSwizzle == PlatformSwizzle.Platform_3DS) { var Image = BitmapExtension.GetBitmap(ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format)), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Image.RotateFlip(RotateFlipType.RotateNoneFlipY); //It's upside down for some reason so flip it return(Image); } if (PlatformSwizzle == PlatformSwizzle.Platform_Gamecube) { return(BitmapExtension.GetBitmap(Decode_Gamecube.DecodeData(data, paletteData, width, height, Format, PaletteFormat), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); } switch (Format) { case TEX_FORMAT.R4G4_UNORM: return(BitmapExtension.GetBitmap(R4G4.Decompress(data, (int)width, (int)height, false), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); case TEX_FORMAT.BC5_SNORM: return(DDSCompressor.DecompressBC5(data, (int)width, (int)height, true)); case TEX_FORMAT.ETC1_UNORM: return(BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, false), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); case TEX_FORMAT.ETC1_A4: return(BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, true), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); case TEX_FORMAT.R5G5B5A1_UNORM: case TEX_FORMAT.LA8: case TEX_FORMAT.L8: return(BitmapExtension.GetBitmap(RGBAPixelDecoder.Decode(data, (int)width, (int)height, Format), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); } if (Runtime.UseDirectXTexDecoder) { return(BitmapExtension.GetBitmap(DecodeBlock(data, width, height, Format, new byte[0], Parameters), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); } else { return(DecodeNotDirectXTex(data, width, height, Format)); } } catch (Exception ex) { /* Forms.STErrorDialog.Show($"Texture failed to load!", "Texture [GetBitmap({MipLevel},{ArrayLevel})]", DebugInfo() + " \n" + ex); * * try * { * return DecodeNotDirectXTex(data, width, height, Format); * } * catch * { * Forms.STErrorDialog.Show($"Texture failed to load!", "Texture [GetBitmap({MipLevel},{ArrayLevel})]", DebugInfo() + " \n" + ex); * }*/ return(null); } }
/// <summary> /// Decodes a byte array of image data given the source image in bytes, width, height, and DXGI format. /// </summary> /// <param name="byte[]">The byte array of the image</param> /// <param name="Width">The width of the image in pixels.</param> /// <param name="Height">The height of the image in pixels.</param> /// <param name=" DDS.DXGI_FORMAT">The image format.</param> /// <returns>Returns a byte array of decoded data. </returns> public static byte[] DecodeBlock(byte[] data, uint Width, uint Height, TEX_FORMAT Format, byte[] paletteData, ImageParameters parameters, PALETTE_FORMAT PaletteFormat = PALETTE_FORMAT.None, PlatformSwizzle PlatformSwizzle = PlatformSwizzle.None) { if (data == null) { throw new Exception($"Data is null!"); } if (Format <= 0) { throw new Exception($"Invalid Format!"); } if (data.Length <= 0) { throw new Exception($"Data is empty!"); } if (Width <= 0) { throw new Exception($"Invalid width size {Width}!"); } if (Height <= 0) { throw new Exception($"Invalid height size {Height}!"); } byte[] imageData = new byte[0]; bool DontSwapRG = false; if (PlatformSwizzle == PlatformSwizzle.Platform_3DS) { imageData = CTR_3DS.DecodeBlock(data, (int)Width, (int)Height, Format); DontSwapRG = true; } else if (PlatformSwizzle == PlatformSwizzle.Platform_Gamecube) { imageData = Decode_Gamecube.DecodeData(data, paletteData, Width, Height, Format, PaletteFormat); } else { if (Format == TEX_FORMAT.R32G8X24_FLOAT) { imageData = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, DDS.DXGI_FORMAT.DXGI_FORMAT_R32G8X24_TYPELESS); } if (Format == TEX_FORMAT.BC5_SNORM) { imageData = DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true, true); } if (Format == TEX_FORMAT.L8) { return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format)); } if (Format == TEX_FORMAT.LA8) { return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format)); } if (Format == TEX_FORMAT.R5G5B5A1_UNORM) { return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format)); } if (IsCompressed(Format)) { imageData = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format); } else { if (IsAtscFormat(Format)) { imageData = ASTCDecoder.DecodeToRGBA8888(data, (int)GetBlockWidth(Format), (int)GetBlockHeight(Format), 1, (int)Width, (int)Height, 1); } else { imageData = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format); } // imageData = RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format); } } if (parameters.DontSwapRG || DontSwapRG) { return(imageData); } else { return(ConvertBgraToRgba(imageData)); } }
public void Load(System.IO.Stream stream) { CanSave = false; Renderer = new CMB_Renderer(); DrawableContainer.Drawables.Add(Renderer); Skeleton = new STSkeleton(); //These models/skeletons come out massive so scale them with an overridden scale Skeleton.PreviewScale = Renderer.PreviewScale; Skeleton.BonePointScale = 40; Renderer.Skeleton = Skeleton; DrawableContainer.Drawables.Add(Skeleton); cmb.ReadCMB(stream); Text = cmb.Header.Name; DrawableContainer.Name = Text; //Load textures if (cmb.TexturesChunk != null) { texFolder = new TextureFolder("Texture"); TreeNode meshFolder = new TreeNode("Meshes"); TreeNode materialFolder = new TreeNode("Materials"); TreeNode skeletonFolder = new TreeNode("Skeleton"); bool HasTextures = cmb.TexturesChunk.Textures != null && cmb.TexturesChunk.Textures.Count != 0; bool HasMeshes = cmb.MeshesChunk.SHP.SEPDs != null && cmb.MeshesChunk.SHP.SEPDs.Count != 0; bool HasSkeleton = cmb.SkeletonChunk != null && cmb.SkeletonChunk.Bones.Count != 0; bool HasMaterials = cmb.MaterialsChunk != null && cmb.MaterialsChunk.Materials.Count != 0; if (HasSkeleton) { var bonesOrdered = cmb.SkeletonChunk.Bones.OrderBy(x => x.ID).ToList(); foreach (var bone in bonesOrdered) { STBone genericBone = new STBone(Skeleton); genericBone.parentIndex = bone.ParentID; genericBone.Checked = true; genericBone.Text = $"Bone {bone.ID}"; genericBone.RotationType = STBone.BoneRotationType.Euler; genericBone.Position = new OpenTK.Vector3( bone.Translation.X, bone.Translation.Y, bone.Translation.Z ); genericBone.EulerRotation = new OpenTK.Vector3( bone.Rotation.X, bone.Rotation.Y, bone.Rotation.Z ); genericBone.Scale = new OpenTK.Vector3( bone.Scale.X, bone.Scale.Y, bone.Scale.Z ); Skeleton.bones.Add(genericBone); } foreach (var bone in Skeleton.bones) { if (bone.Parent == null) { skeletonFolder.Nodes.Add(bone); } } Skeleton.reset(); Skeleton.update(); } if (HasTextures) { int texIndex = 0; foreach (var tex in cmb.TexturesChunk.Textures) { var texWrapper = new CTXB.TextureWrapper(new CTXB.Texture()); texWrapper.Text = $"Texture {texIndex++}"; texWrapper.ImageKey = "texture"; texWrapper.SelectedImageKey = texWrapper.ImageKey; if (tex.Name != string.Empty) { texWrapper.Text = tex.Name; } texWrapper.Width = tex.Width; texWrapper.Height = tex.Height; CTXB.Texture.TextureFormat Format = (CTXB.Texture.TextureFormat)((tex.DataType << 16) | tex.ImageFormat); texWrapper.Format = CTR_3DS.ConvertPICAToGenericFormat(CTXB.Texture.FormatList[Format]); texWrapper.ImageData = tex.ImageData; texFolder.Nodes.Add(texWrapper); Renderer.TextureList.Add(texWrapper); } } if (HasMaterials) { int materialIndex = 0; foreach (var mat in cmb.MaterialsChunk.Materials) { H3DMaterial H3D = ToH3DMaterial(mat); CMBMaterialWrapper material = new CMBMaterialWrapper(mat, this, H3D); material.Text = $"Material {materialIndex++}"; materialFolder.Nodes.Add(material); Materials.Add(material); bool HasDiffuse = false; foreach (var tex in mat.TextureMappers) { if (tex.TextureID != -1) { CMBTextureMapWrapper matTexture = new CMBTextureMapWrapper(tex, this); matTexture.TextureIndex = tex.TextureID; material.TextureMaps.Add(matTexture); if (tex.TextureID < Renderer.TextureList.Count && tex.TextureID >= 0) { matTexture.Name = Renderer.TextureList[tex.TextureID].Text; material.Nodes.Add(matTexture.Name); } if (!HasDiffuse && matTexture.Name != "bg_syadowmap") //Quick hack till i do texture env stuff { matTexture.Type = STGenericMatTexture.TextureType.Diffuse; HasDiffuse = true; } } } } } if (HasMeshes) { int MeshIndex = 0; foreach (var mesh in cmb.MeshesChunk.MSHS.Meshes) { STGenericMaterial mat = Materials[mesh.MaterialIndex]; CmbMeshWrapper genericMesh = new CmbMeshWrapper(mat); genericMesh.Text = $"Mesh_{MeshIndex++}_ID_{mesh.VisIndex}"; genericMesh.MaterialIndex = mesh.MaterialIndex; var shape = cmb.MeshesChunk.SHP.SEPDs[mesh.SEPDIndex]; genericMesh.Mesh = shape; List <ushort> SkinnedBoneTable = new List <ushort>(); foreach (var prim in shape.PRMS) { if (prim.BoneIndices != null) { SkinnedBoneTable.AddRange(prim.BoneIndices); } } //Now load the vertex and face data foreach (var prm in shape.PRMS) { if (shape.HasPosition) { int VertexCount = prm.VertexCount; for (int v = 0; v < VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = new OpenTK.Vector3( prm.Vertices.Position[v].X, prm.Vertices.Position[v].Y, prm.Vertices.Position[v].Z); if (shape.HasNormal) { vert.nrm = new OpenTK.Vector3( prm.Vertices.Normal[v].X, prm.Vertices.Normal[v].Y, prm.Vertices.Normal[v].Z).Normalized(); } if (shape.HasColor) { vert.col = new OpenTK.Vector4( prm.Vertices.Color[v].X, prm.Vertices.Color[v].Y, prm.Vertices.Color[v].Z, prm.Vertices.Color[v].W).Normalized(); } if (shape.HasUV0) { vert.uv0 = new OpenTK.Vector2(prm.Vertices.UV0[v].X, -prm.Vertices.UV0[v].Y + 1); } if (shape.HasUV1) { vert.uv1 = new OpenTK.Vector2(prm.Vertices.UV1[v].X, -prm.Vertices.UV1[v].Y + 1); } if (shape.HasUV2) { vert.uv2 = new OpenTK.Vector2(prm.Vertices.UV2[v].X, -prm.Vertices.UV2[v].Y + 1); } if (prm.SkinningMode == SkinningMode.Smooth) { //Indices if (shape.HasIndices) { if (shape.BoneDimensionCount >= 1) { vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].X); } if (shape.BoneDimensionCount >= 2) { vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].Y); } if (shape.BoneDimensionCount >= 3) { vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].Z); } if (shape.BoneDimensionCount >= 4) { vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].W); } } //Weights if (shape.HasWeights) { if (shape.BoneDimensionCount >= 1) { vert.boneWeights.Add(prm.Vertices.BoneWeights[v].X); } if (shape.BoneDimensionCount >= 2) { vert.boneWeights.Add(prm.Vertices.BoneWeights[v].Y); } if (shape.BoneDimensionCount >= 3) { vert.boneWeights.Add(prm.Vertices.BoneWeights[v].Z); } if (shape.BoneDimensionCount >= 4) { vert.boneWeights.Add(prm.Vertices.BoneWeights[v].W); } } } if (prm.SkinningMode == SkinningMode.Rigid) { int boneId = (int)prm.Vertices.BoneIndices[v].X; vert.boneIds.Add(boneId); vert.boneWeights.Add(1); vert.pos = OpenTK.Vector3.TransformPosition(vert.pos, Skeleton.bones[boneId].Transform); if (shape.HasNormal) { vert.nrm = OpenTK.Vector3.TransformNormal(vert.nrm, Skeleton.bones[boneId].Transform); } } if (prm.SkinningMode == SkinningMode.Mixed) { int boneId = prm.BoneIndices[0]; vert.boneIds.Add(boneId); vert.boneWeights.Add(1); vert.pos = OpenTK.Vector3.TransformPosition(vert.pos, Skeleton.bones[boneId].Transform); if (shape.HasNormal) { vert.nrm = OpenTK.Vector3.TransformNormal(vert.nrm, Skeleton.bones[boneId].Transform); } } genericMesh.vertices.Add(vert); } } STGenericPolygonGroup group = new STGenericPolygonGroup(); genericMesh.PolygonGroups.Add(group); for (int i = 0; i < prm.FaceIndices.Count; i++) { group.faces.Add((int)prm.FaceIndices[i].X); group.faces.Add((int)prm.FaceIndices[i].Y); group.faces.Add((int)prm.FaceIndices[i].Z); } } Renderer.Meshes.Add(genericMesh); meshFolder.Nodes.Add(genericMesh); } } if (meshFolder.Nodes.Count > 0) { Nodes.Add(meshFolder); } if (skeletonFolder.Nodes.Count > 0) { Nodes.Add(skeletonFolder); } if (materialFolder.Nodes.Count > 0) { Nodes.Add(materialFolder); } if (texFolder.Nodes.Count > 0) { Nodes.Add(texFolder); } } }