public void ModifyD3DTX(DDS_Master dds) { mWidth = dds.header.dwWidth; mHeight = dds.header.dwHeight; mSurfaceFormat = DDS_Functions.Get_T3Format_FromFourCC(dds.header.ddspf.dwFourCC); //mDepth = dds.header.dwDepth; }
public void ModifyD3DTX(DDS_Master dds) //ISSUE HERE WITH DXT5 AND MIP MAPS WITH UPSCALED TEXTURES { mWidth = dds.header.dwWidth; //this is correct mHeight = dds.header.dwHeight; //this is correct mSurfaceFormat = DDS_Functions.Get_T3Format_FromFourCC(dds.header.ddspf.dwFourCC); //this is correct mDepth = dds.header.dwDepth; mNumMipLevels = dds.header.dwMipMapCount; List <byte[]> ddsData = dds.textureData; ddsData.Reverse(); mPixelData.Clear(); //this is correct mPixelData = ddsData; //this is correct StreamHeader newStreamHeader = new StreamHeader() { mRegionCount = (int)dds.header.dwMipMapCount, //this is correct mAuxDataCount = mStreamHeader.mAuxDataCount, //this is correct mTotalDataSize = (int)ByteFunctions.Get2DByteArrayTotalSize(mPixelData) //this is correct }; mStreamHeader = newStreamHeader; //this is correct List <RegionStreamHeader> regionStreamHeader = new List <RegionStreamHeader>(); //this is correct uint[,] mipMapResolutions = DDS_Functions.DDS_CalculateMipResolutions(mNumMipLevels, mWidth, mHeight); bool blockSizeDouble = DDS_Functions.DDS_CompressionBool(dds.header); for (int i = 0; i < mStreamHeader.mRegionCount; i++) { RegionStreamHeader region = new RegionStreamHeader() { mDataSize = (uint)mPixelData[i].Length, mFaceIndex = 0, //NOTE: for cubemap textures this will need to change mMipCount = 1, //NOTE: for cubemap textures this will need to change mMipIndex = (mStreamHeader.mRegionCount - 1) - i, mPitch = DDS_Functions.DDS_ComputePitchValue(mipMapResolutions[mStreamHeader.mRegionCount - i, 0], blockSizeDouble), //this is correct mSlicePitch = mPixelData[i].Length, //this is correct }; regionStreamHeader.Add(region); } regionStreamHeader.Reverse(); mRegionHeaders = regionStreamHeader.ToArray(); UpdateArrayCapacities(); PrintConsole(); }
public void ModifyD3DTX(DDS_Master dds) { mWidth = dds.header.dwWidth; mHeight = dds.header.dwHeight; mSurfaceFormat = DDS_Functions.Get_T3Format_FromFourCC(dds.header.ddspf.dwFourCC); mDepth = dds.header.dwDepth; mNumMipLevels = dds.header.dwMipMapCount; List <byte[]> ddsData = new List <byte[]>(dds.textureData); //this is correct ddsData.Reverse(); //this is correct mPixelData.Clear(); //this is correct mPixelData = ddsData; //this is correct StreamHeader newStreamHeader = new StreamHeader() { mRegionCount = (int)dds.header.dwMipMapCount, mAuxDataCount = mStreamHeader.mAuxDataCount, mTotalDataSize = (int)ByteFunctions.Get2DByteArrayTotalSize(mPixelData) //this is correct }; mStreamHeader = newStreamHeader; RegionStreamHeader[] regionStreamHeader = new RegionStreamHeader[mStreamHeader.mRegionCount]; uint[,] mipMapResolutions = DDS_Functions.DDS_CalculateMipResolutions(mNumMipLevels, mWidth, mHeight); bool blockSizeDouble = DDS_Functions.DDS_CompressionBool(dds.header); for (int i = 0; i < regionStreamHeader.Length; i++) { regionStreamHeader[i] = new RegionStreamHeader() { mDataSize = (uint)mPixelData[i].Length, mFaceIndex = 0, //NOTE: for cubemap textures this will need to change mMipCount = 1, //NOTE: for cubemap textures this will need to change mMipIndex = (regionStreamHeader.Length - 1) - i, //mMipIndex = (regionStreamHeader.Length - 1) - i, mPitch = DDS_Functions.DDS_ComputePitchValue(mipMapResolutions[regionStreamHeader.Length - i, 0], blockSizeDouble), //this is correct mSlicePitch = mPixelData[i].Length, //this is correct }; } mRegionHeaders = regionStreamHeader; UpdateArrayCapacities(); //PrintConsole(); }
/// <summary> /// Matches a given DDS file on the disk to a D3DTX object. /// </summary> /// <param name="ddsPath"></param> /// <param name="d3dtx"></param> /// <param name="options"></param> public void Match_DDS_With_D3DTX(string ddsPath, D3DTX_Master d3dtx, DDS_Matching_Options options) { //load in the DDS image using DirectXTexNet ScratchImage scratchImage = TexHelper.Instance.LoadFromDDSFile(ddsPath, DDS_FLAGS.NONE); //create our main variables that will be used when doing conversion operations int d3dtx_width = 0; int d3dtx_height = 0; int d3dtx_mipAmount = 0; T3SurfaceFormat d3dtx_format = T3SurfaceFormat.eSurface_DXT1; T3SurfaceGamma d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //assign the values depending on which version is active if (d3dtx.d3dtx9 != null) { d3dtx_width = (int)d3dtx.d3dtx9.mWidth; d3dtx_height = (int)d3dtx.d3dtx9.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx9.mNumMipLevels; d3dtx_format = d3dtx.d3dtx9.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx9.mSurfaceGamma; } else if (d3dtx.d3dtx8 != null) { d3dtx_width = (int)d3dtx.d3dtx8.mWidth; d3dtx_height = (int)d3dtx.d3dtx8.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx8.mNumMipLevels; d3dtx_format = d3dtx.d3dtx8.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx8.mSurfaceGamma; } else if (d3dtx.d3dtx7 != null) { d3dtx_width = (int)d3dtx.d3dtx7.mWidth; d3dtx_height = (int)d3dtx.d3dtx7.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx7.mNumMipLevels; d3dtx_format = d3dtx.d3dtx7.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx7.mSurfaceGamma; } else if (d3dtx.d3dtx6 != null) { d3dtx_width = (int)d3dtx.d3dtx6.mWidth; d3dtx_height = (int)d3dtx.d3dtx6.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx6.mNumMipLevels; d3dtx_format = d3dtx.d3dtx6.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } else if (d3dtx.d3dtx5 != null) { d3dtx_width = (int)d3dtx.d3dtx5.mWidth; d3dtx_height = (int)d3dtx.d3dtx5.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx5.mNumMipLevels; d3dtx_format = d3dtx.d3dtx5.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } else if (d3dtx.d3dtx4 != null) { d3dtx_width = (int)d3dtx.d3dtx4.mWidth; d3dtx_height = (int)d3dtx.d3dtx4.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx4.mNumMipLevels; d3dtx_format = d3dtx.d3dtx4.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } //-------------------------------------- CONVERSION START -------------------------------------- //change the compression if needed if (options.MatchCompression) { DXGI_FORMAT dxgi_format = DDS_Functions.GetSurfaceFormatAsDXGI(d3dtx_format, d3dtx_gamma); scratchImage.Convert(dxgi_format, TEX_FILTER_FLAGS.DITHER, 0.0f); } //rescale the image to match if needed if (options.MatchResolution) { scratchImage.Resize(d3dtx_width, d3dtx_height, TEX_FILTER_FLAGS.CUBIC); } //generate mip maps if needed if (options.GenerateMipMaps) { if (options.MatchMipMapCount) { scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, d3dtx_mipAmount, false); } else { scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, 0, false); } } //resave the newly modified DDS scratchImage.SaveToDDSFile(DDS_FLAGS.NONE, ddsPath); }
/// <summary> /// Writes a D3DTX into a DDS file on the disk. /// </summary> /// <param name="d3dtx"></param> /// <param name="destinationPath"></param> public void Write_D3DTX_AsDDS(D3DTX_Master d3dtx, string destinationPath) { byte[] finalData = new byte[0]; //turn our header data into bytes to be written into a file byte[] dds_header = ByteFunctions.Combine(ByteFunctions.GetBytes("DDS "), DDS_Functions.GetHeaderBytes(header)); //copy the dds header to the file finalData = ByteFunctions.Combine(finalData, dds_header); if (d3dtx.d3dtx4 != null) { //copy the images for (int i = d3dtx.d3dtx4.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx4.mPixelData[i]); } } else if (d3dtx.d3dtx5 != null) { //copy the images for (int i = d3dtx.d3dtx5.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx5.mPixelData[i]); } } else if (d3dtx.d3dtx6 != null) { //copy the images for (int i = d3dtx.d3dtx6.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx6.mPixelData[i]); } } else if (d3dtx.d3dtx7 != null) { //copy the images for (int i = d3dtx.d3dtx7.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx7.mPixelData[i]); } } else if (d3dtx.d3dtx8 != null) { //copy the images for (int i = d3dtx.d3dtx8.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx8.mPixelData[i]); } } else if (d3dtx.d3dtx9 != null) { //copy the images for (int i = d3dtx.d3dtx9.mPixelData.Count - 1; i >= 0; i--) { finalData = ByteFunctions.Combine(finalData, d3dtx.d3dtx9.mPixelData[i]); } } //write the file to the disk File.WriteAllBytes(destinationPath, finalData); }
/// <summary> /// Parses the data from a DDS byte array. (Can also read just the header only) /// </summary> /// <param name="fileData"></param> /// <param name="headerOnly"></param> private void GetData(byte[] fileData, bool headerOnly) { ConsoleFunctions.SetConsoleColor(ConsoleColor.Black, ConsoleColor.White); Console.WriteLine("Total Source Texture Byte Size = {0}", fileData.Length); //which byte offset we are on for the source texture (will be changed as we go through the file) byte[] headerBytes = ByteFunctions.AllocateBytes(124, fileData, 4); //skip past the 'DDS ' //this will automatically read all of the byte data in the header header = DDS_Functions.GetHeaderFromBytes(headerBytes); ConsoleFunctions.SetConsoleColor(ConsoleColor.Black, ConsoleColor.White); Console.WriteLine("DDS Height = {0}", header.dwHeight); Console.WriteLine("DDS Width = {0}", header.dwWidth); Console.WriteLine("DDS Mip Map Count = {0}", header.dwMipMapCount); Console.WriteLine("DDS Compression = {0}", header.ddspf.dwFourCC); if (headerOnly) { return; } //--------------------------EXTRACT DDS TEXTURE DATA-------------------------- //calculate dds header length (we add 4 because we skipped the 4 bytes which contain the ddsPrefix, it isn't necessary to parse this data) uint ddsHeaderLength = 4 + header.dwSize; //calculate the length of just the dds texture data uint ddsTextureDataLength = (uint)sourceFileData.Length - ddsHeaderLength; //allocate a byte array of dds texture length byte[] ddsTextureData = new byte[ddsTextureDataLength]; //copy the data from the source byte array past the header (so we are only getting texture data) Array.Copy(sourceFileData, ddsHeaderLength, ddsTextureData, 0, ddsTextureData.Length); //if there are no mip maps if (header.dwMipMapCount <= 1) { textureData = new(); textureData.Add(ddsTextureData); Console.WriteLine("DDS Texture Byte Size = {0}", textureData[0].Length); } else //if there are mip maps { //get mip resolutions //calculated mip resolutions [Pixel Value, Width or Height (0 or 1)] mipMapResolutions = DDS_Functions.DDS_CalculateMipResolutions(header.dwMipMapCount, header.dwWidth, header.dwHeight); //get byte sizes uint[] byteSizes = DDS_Functions.DDS_GetImageByteSizes(mipMapResolutions, DDS_Functions.DDS_CompressionBool(header)); textureData = new(); int test = ddsTextureData.Length; int offset = 0; for (int i = 0; i < byteSizes.Length; i++) { byte[] temp = new byte[byteSizes[i]]; //issue length Array.Copy(ddsTextureData, offset, temp, 0, temp.Length); offset += temp.Length - 1; textureData.Add(temp); test -= (int)byteSizes[i]; } } }
/// <summary> /// Create a DDS file from a D3DTX /// </summary> /// <param name="d3dtx"></param> public DDS_Master(D3DTX_Master d3dtx) { header = DDS_Functions.GetPresetHeader(); T3SurfaceFormat surfaceFormat = T3SurfaceFormat.eSurface_DXT1; if (d3dtx.d3dtx4 != null) { header.dwWidth = d3dtx.d3dtx4.mWidth; header.dwHeight = d3dtx.d3dtx4.mHeight; header.dwMipMapCount = d3dtx.d3dtx4.mNumMipLevels; surfaceFormat = d3dtx.d3dtx4.mSurfaceFormat; } else if (d3dtx.d3dtx5 != null) { header.dwWidth = d3dtx.d3dtx5.mWidth; header.dwHeight = d3dtx.d3dtx5.mHeight; header.dwMipMapCount = d3dtx.d3dtx5.mNumMipLevels; surfaceFormat = d3dtx.d3dtx5.mSurfaceFormat; } else if (d3dtx.d3dtx6 != null) { header.dwWidth = d3dtx.d3dtx6.mWidth; header.dwHeight = d3dtx.d3dtx6.mHeight; header.dwMipMapCount = d3dtx.d3dtx6.mNumMipLevels; surfaceFormat = d3dtx.d3dtx6.mSurfaceFormat; } else if (d3dtx.d3dtx7 != null) { header.dwWidth = d3dtx.d3dtx7.mWidth; header.dwHeight = d3dtx.d3dtx7.mHeight; header.dwMipMapCount = d3dtx.d3dtx7.mNumMipLevels; //header.dwDepth = d3dtx.d3dtx7.mDepth; surfaceFormat = d3dtx.d3dtx7.mSurfaceFormat; } else if (d3dtx.d3dtx8 != null) { header.dwWidth = d3dtx.d3dtx8.mWidth; header.dwHeight = d3dtx.d3dtx8.mHeight; header.dwMipMapCount = d3dtx.d3dtx8.mNumMipLevels; header.dwDepth = d3dtx.d3dtx8.mDepth; surfaceFormat = d3dtx.d3dtx8.mSurfaceFormat; } else if (d3dtx.d3dtx9 != null) { header.dwWidth = d3dtx.d3dtx9.mWidth; header.dwHeight = d3dtx.d3dtx9.mHeight; header.dwMipMapCount = d3dtx.d3dtx9.mNumMipLevels; header.dwDepth = d3dtx.d3dtx9.mDepth; surfaceFormat = d3dtx.d3dtx9.mSurfaceFormat; } DDS_PIXELFORMAT new_ddspf = new DDS_PIXELFORMAT(); new_ddspf.dwFourCC = DDS_Functions.Get_FourCC_FromTellale(surfaceFormat); switch (surfaceFormat) { case Telltale.T3SurfaceFormat.eSurface_A8: new_ddspf.dwABitMask = 255; header.dwCaps = 4198408; //DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP break; case Telltale.T3SurfaceFormat.eSurface_ARGB8: new_ddspf.dwABitMask = 255; new_ddspf.dwRBitMask = 255; new_ddspf.dwGBitMask = 255; new_ddspf.dwBBitMask = 255; header.dwCaps = 4198408; //DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP break; } header.ddspf = new_ddspf; }
public void TEST_WriteDDSToDisk(string destinationPath) { //THIS WORKS string extension = Path.GetExtension(destinationPath); string newPath = destinationPath.Remove(destinationPath.Length - extension.Length, extension.Length); newPath += "_parseTest" + extension; byte[] finalData = new byte[0]; //turn our header data into bytes to be written into a file byte[] dds_header = ByteFunctions.Combine(ByteFunctions.GetBytes("DDS "), DDS_Functions.GetHeaderBytes(header)); //copy the dds header to the file finalData = ByteFunctions.Combine(finalData, dds_header); //copy the images for (int i = 0; i <= textureData.Count - 1; i++) { finalData = ByteFunctions.Combine(finalData, textureData[i]); } //write the file to the disk File.WriteAllBytes(newPath, finalData); }