private static List<Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart) { ushort textureCount = reader.ReadUInt16(); ushort padding = reader.ReadUInt16(); // Usually 0xFFFF? uint textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart. uint stringTableOffset = reader.ReadUInt32(); // One filename per texture. relative to chunkStart. List<Texture2D> textureList = new List<Texture2D>(); // Get all Texture Names reader.BaseStream.Position = chunkStart + stringTableOffset; StringTable stringTable = StringTable.FromStream(reader); for (int t = 0; t < textureCount; t++) { // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file. reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20); BinaryTextureImage texture = new BinaryTextureImage(); texture.Load(reader, chunkStart + 0x20, t); Texture2D texture2D = new Texture2D(texture.Width, texture.Height); texture2D.Name = stringTable[t]; texture2D.PixelData = texture.GetData(); textureList.Add(texture2D); string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t)); } return textureList; }
private static List <Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart) { ushort textureCount = reader.ReadUInt16(); ushort padding = reader.ReadUInt16(); // Usually 0xFFFF? uint textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart. uint stringTableOffset = reader.ReadUInt32(); // One filename per texture. relative to chunkStart. List <Texture2D> textureList = new List <Texture2D>(); // Get all Texture Names reader.BaseStream.Position = chunkStart + stringTableOffset; StringTable stringTable = StringTable.FromStream(reader); for (int t = 0; t < textureCount; t++) { // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file. reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20); BinaryTextureImage texture = new BinaryTextureImage(); texture.Load(reader, chunkStart + 0x20, t); Texture2D texture2D = new Texture2D(texture.Width, texture.Height); texture2D.Name = stringTable[t]; texture2D.PixelData = texture.GetData(); textureList.Add(texture2D); string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t)); } return(textureList); }
public void LoadTEX1FromStream(EndianBinaryReader reader, long tagStart, bool dumpTextures) { ushort numTextures = reader.ReadUInt16(); Trace.Assert(reader.ReadUInt16() == 0xFFFF); // Padding int textureHeaderDataOffset = reader.ReadInt32(); int stringTableOffset = reader.ReadInt32(); // Texture Names reader.BaseStream.Position = tagStart + stringTableOffset; StringTable nameTable = StringTable.FromStream(reader); Textures = new BindingList <Texture>(); for (int t = 0; t < numTextures; t++) { // Reset the stream position to the start of this header as loading the actual data of the texture // moves the stream head around. reader.BaseStream.Position = tagStart + textureHeaderDataOffset + (t * 0x20); BinaryTextureImage compressedTex = new BinaryTextureImage(); string tempFileName = string.Format("TextureDump/{1}_{0}.png", nameTable[t], t); if (!m_allowTextureCache || !File.Exists(tempFileName)) { compressedTex.Load(reader, tagStart + 0x20 /* Size of TEX1 header?*/, t); } else { compressedTex.LoadImageFromDisk(tempFileName); } Texture texture = new Texture(nameTable[t], compressedTex); Textures.Add(texture); if (dumpTextures) { compressedTex.SaveImageToDisk(string.Format("TextureDump/{2}__{0}_{1}_{3}.png", texture.Name, compressedTex.Format, t, compressedTex.PaletteFormat)); } } }
public void WriteObj(string f) { //string dirPath = Path.GetDirectoryName(f); string fileName = $"{ AppContext.BaseDirectory }\\{ Path.GetFileNameWithoutExtension(f) }"; StringWriter objWriter = new StringWriter(); StringWriter mtlWriter = new StringWriter(); objWriter.WriteLine("# dumped with booldozer"); objWriter.WriteLine($"mtllib { fileName }.mtl"); foreach (var vert in verticies) { objWriter.WriteLine($"v {vert.X} {vert.Y} {vert.Z}"); } if (normals.Count != 0) { foreach (var vert in normals) { objWriter.WriteLine($"vn { vert.X } { vert.Y } { vert.Z }"); } } if (uvs.Count != 0) { foreach (var vert in uvs) { objWriter.WriteLine($"vt { vert.X } { 1 - vert.Y }"); } } objWriter.WriteLine(); int index = 0; foreach (DrawElement drw in drawelements) { Material mat = materials[drw.matIndex]; GXBatch shp = shapes[drw.shapeIndex]; mtlWriter.WriteLine($"newmtl { index }"); mtlWriter.WriteLine($"Kd { ((mat.color & 0xFF000000) >> 24) / 255 } { ((mat.color & 0x00FF0000) >> 16) / 255 } { ((mat.color & 0x0000FF00) >> 8) / 255 }"); mtlWriter.WriteLine($"d { (mat.color & 0x000000FF) / 255 }"); if (mat.num_tev_stages > 0) { TexObj texObj = texobjs[mat.stages[0].texobj_index]; mtlWriter.WriteLine($"map_Kd { index }.png"); BinaryTextureImage tex = textures[texObj.textureIndex]; tex.SaveImageToDisk($"{ AppContext.BaseDirectory }\\{ index }.png", tex.GetData(), tex.Width, tex.Height); } objWriter.WriteLine($"o { index }"); objWriter.WriteLine($"usemtl { index }"); for (int i = 0; i < shp.RawVertices.Count; i += 3) { string[] verts = new string[3] { "", "", "" }; for (int j = 0; j < 3; j++) { string pos = ""; string uv = ""; string norm = ""; if (shp.ActiveAttributes.Contains(GXAttribute.Position)) { pos = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Position)] + 1) }/"; } if (shp.ActiveAttributes.Contains(GXAttribute.Tex0)) { uv = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Tex0)] + 1) }"; } if (shp.ActiveAttributes.Contains(GXAttribute.Normal)) { norm = $"/{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Normal)] + 1) }/"; } verts[j] = $"{ pos }{ uv }{ norm }"; } objWriter.WriteLine($"f { verts[0] } { verts[1] } { verts[2] }"); } index++; } using (FileStream s = new FileStream($"{ fileName }.obj", FileMode.Create, FileAccess.Write)) { EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big); w.Write(objWriter.ToString().ToCharArray()); } using (FileStream s = new FileStream($"{ fileName }.mtl", FileMode.Create, FileAccess.Write)) { EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big); w.Write(mtlWriter.ToString().ToCharArray()); } }