/// <summary>
 /// Determines whether width and height flags are set, so <see cref="DdsHeader.Width" /> and
 /// <see cref="DdsHeader.Height" /> contain valid values.
 /// </summary>
 /// <returns>
 /// <c>true</c> if dimensions flags are set; otherwise, <c>false</c>.
 /// </returns>
 public static bool AreDimensionsSet(this DdsHeader ddsHeader)
 {
     return((ddsHeader.Flags & DdsFlags.Width) != 0 && (ddsHeader.Flags & DdsFlags.Height) != 0);
 }
Beispiel #2
0
        //////////////////////////////////////////////

        public static void WriteFile(Stream output, DDSTextureTools.DDSImage image)
        {
            DdsHeader header = new DdsHeader();

            // For non-compressed textures, we need pixel width.
            //int pixelWidth = 0;

            // Identify if we're a compressed image
            bool isCompressed =
                image.Format == DDSTextureTools.DDSImage.FormatEnum.DXT1 ||
                image.Format == DDSTextureTools.DDSImage.FormatEnum.DXT3 ||
                image.Format == DDSTextureTools.DDSImage.FormatEnum.DXT5 ||
                image.Format == DDSTextureTools.DDSImage.FormatEnum.BC5;

            int width  = image.Surfaces[0].Size.X;
            int height = image.Surfaces[0].Size.Y;

            //// Compute mip map count..
            int mipCount  = image.Cubemap ? image.Surfaces.Length / 6 : image.Surfaces.Length;
            int mipWidth  = width;           // surface.Width;
            int mipHeight = height;          // surface.Height;

            // Populate bulk of our DdsHeader
            header.m_size        = header.Size();
            header.m_headerFlags = (uint)(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_TEXTURE);

            if (isCompressed)
            {
                header.m_headerFlags |= (uint)(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_LINEARSIZE);
            }
            else
            {
                header.m_headerFlags |= (uint)(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_PITCH);
            }

            if (mipCount > 1)
            {
                header.m_headerFlags |= (uint)(DdsHeader.HeaderFlags.DDS_HEADER_FLAGS_MIPMAP);
            }

            header.m_height = (uint)height;          // surface.Height;
            header.m_width  = (uint)width;           // surface.Width;

            if (isCompressed)
            {
                // Compresssed textures have the linear flag set.So pitchOrLinearSize
                // needs to contain the entire size of the DXT block.
                int blockCount = ((width + 3) / 4) * ((height + 3) / 4);
                int blockSize  = (image.Format == DDSTextureTools.DDSImage.FormatEnum.DXT1) ? 8 : 16;
                header.m_pitchOrLinearSize = (uint)(blockCount * blockSize);
            }
            else
            {
                int pixelWidth = 0;

                // Non-compressed textures have the pitch flag set. So pitchOrLinearSize
                // needs to contain the row pitch of the main image. DWORD aligned too.
                switch (image.Format)
                {
                case DDSTextureTools.DDSImage.FormatEnum.A8R8G8B8:
                case DDSTextureTools.DDSImage.FormatEnum.X8R8G8B8:
                case DDSTextureTools.DDSImage.FormatEnum.A8B8G8R8:
                case DDSTextureTools.DDSImage.FormatEnum.X8B8G8R8:
                    pixelWidth = 4;                    // 32bpp
                    break;

                case DDSTextureTools.DDSImage.FormatEnum.A1R5G5B5:
                case DDSTextureTools.DDSImage.FormatEnum.A4R4G4B4:
                case DDSTextureTools.DDSImage.FormatEnum.R5G6B5:
                    pixelWidth = 2;                    // 16bpp
                    break;

                case DDSTextureTools.DDSImage.FormatEnum.R8G8B8:
                    pixelWidth = 3;                    // 24bpp
                    break;

                case DDSTextureTools.DDSImage.FormatEnum.R16G16B16A16:
                    pixelWidth = 8;                    // 64bpp
                    break;
                }

                // Compute row pitch
                header.m_pitchOrLinearSize = (uint)((int)header.m_width * pixelWidth);

                ////#if	APPLY_PITCH_ALIGNMENT
                //// Align to DWORD, if we need to.. (see notes about pitch alignment all over this code)
                //header.m_pitchOrLinearSize = (uint)( ( (int)header.m_pitchOrLinearSize + 3 ) & ( ~3 ) );
                ////#endif	//APPLY_PITCH_ALIGNMENT
            }

            header.m_depth        = 0;
            header.m_mipMapCount  = (mipCount == 1) ? 0 : (uint)mipCount;
            header.m_reserved1_0  = 0;
            header.m_reserved1_1  = 0;
            header.m_reserved1_2  = 0;
            header.m_reserved1_3  = 0;
            header.m_reserved1_4  = 0;
            header.m_reserved1_5  = 0;
            header.m_reserved1_6  = 0;
            header.m_reserved1_7  = 0;
            header.m_reserved1_8  = 0;
            header.m_reserved1_9  = 0;
            header.m_reserved1_10 = 0;

            // Populate our DdsPixelFormat object
            header.m_pixelFormat.Initialise(image.Format);

            // Populate miscellanous header flags
            header.m_surfaceFlags = (uint)DdsHeader.SurfaceFlags.DDS_SURFACE_FLAGS_TEXTURE;

            if (mipCount > 1)
            {
                header.m_surfaceFlags |= (uint)DdsHeader.SurfaceFlags.DDS_SURFACE_FLAGS_MIPMAP;
            }
            if (image.Cubemap)
            {
                header.m_surfaceFlags |= (uint)DdsHeader.SurfaceFlags.DDS_SURFACE_FLAGS_CUBEMAP;
            }

            header.m_cubemapFlags = image.Cubemap ? (uint)DdsHeader.CubemapFlags.DDS_CUBEMAP_ALLFACES : 0;
            header.m_reserved2_0  = 0;
            header.m_reserved2_1  = 0;
            header.m_reserved2_2  = 0;

            // Write out our DDS tag
            Utility.WriteUInt32(output, 0x20534444);               // 'DDS '

            // Write out the header
            header.Write(output);

            //DDSSquish.SquishFlags squishFlags = /*ddsToken.*/GetSquishFlags( fileFormat );

            //// Our output data array will be sized as necessary
            //byte[] outputData;

            // Reset our mip width & height variables...
            mipWidth  = width;           // surface.Width;
            mipHeight = height;          // surface.Height;

            //// Figure out how much total work each mip map is
            //Size[] writeSizes = new Size[ mipCount ];
            //int[] mipPixels = new int[ mipCount ];
            //int[] pixelsCompleted = new int[ mipCount ]; // # pixels completed once we have reached this mip
            //long totalPixels = 0;
            //for( int mipLoop = 0; mipLoop < mipCount; mipLoop++ )
            //{
            //   Size writeSize = new Size( ( mipWidth > 0 ) ? mipWidth : 1, ( mipHeight > 0 ) ? mipHeight : 1 );
            //   writeSizes[ mipLoop ] = writeSize;

            //   int thisMipPixels = writeSize.Width * writeSize.Height;
            //   mipPixels[ mipLoop ] = thisMipPixels;

            //   if( mipLoop == 0 )
            //   {
            //      pixelsCompleted[ mipLoop ] = 0;
            //   }
            //   else
            //   {
            //      pixelsCompleted[ mipLoop ] = pixelsCompleted[ mipLoop - 1 ] + mipPixels[ mipLoop - 1 ];
            //   }

            //   totalPixels += thisMipPixels;
            //   mipWidth /= 2;
            //   mipHeight /= 2;
            //}

            //mipWidth = width;// surface.Width;
            //mipHeight = height;// surface.Height;

            for (int nSurface = 0; nSurface < image.Surfaces.Length; nSurface++)
            //for( int mipLoop = 0; mipLoop < mipCount; mipLoop++ )
            {
                DDSTextureTools.DDSImage.Surface surface = image.Surfaces[nSurface];
                //TextureTools.DDSImage.Surface surface = image.Surfaces[ mipLoop ];

                //Size writeSize = writeSizes[ mipLoop ];
                //Surface writeSurface = new Surface( writeSize );

                //if( mipLoop == 0 )
                //{
                //   // No point resampling the first level.. it's got exactly what we want.
                //   writeSurface = surface;
                //}
                //else
                //{
                //   // I'd love to have a UI component to select what kind of resampling, but
                //   // there's hardly any space for custom UI stuff in the Save Dialog. And I'm
                //   // not having any scrollbars in there..!
                //   // Also, note that each mip level is formed from the main level, to reduce
                //   // compounded errors when generating mips.
                //   writeSurface.SuperSamplingFitSurface( surface );
                //}

                //DdsSquish.ProgressFn progressFn =
                //    delegate( int workDone, int workTotal )
                //    {
                //       long thisMipPixelsDone = workDone * (long)mipWidth;
                //       long previousMipsPixelsDone = pixelsCompleted[ mipLoop ];
                //       double progress = (double)( (double)thisMipPixelsDone + (double)previousMipsPixelsDone ) / (double)totalPixels;
                //       progressCallback( this, new ProgressEventArgs( 100.0 * progress ) );
                //    };

                //if( ( /*ddsToken.m_*/fileFormat >= DdsFileFormat.DDS_FORMAT_DXT1 ) &&
                //   ( /*ddsToken.m_*/fileFormat <= DdsFileFormat.DDS_FORMAT_DXT5 ) )
                //{
                //   outputData = DDSSquish.CompressImage( writeSurface, squishFlags/*,
                //      ( progressCallback == null ) ? null : progressFn*/
                //                                                         );
                //}
                //else
                //{
                //   Trace.Assert( false );

                //               int mipPitch = pixelWidth * writeSurface.Width;

                //               // From the DDS documents I read, I'd expected the pitch of each mip level to be
                //               // DWORD aligned. As it happens, that's not the case. Re-aligning the pitch of
                //               // each level results in later mips getting sheared as the pitch is incorrect.
                //               // So, the following line is intentionally optional. Maybe the documentation
                //               // is referring to the pitch when accessing the mip directly.. who knows.
                //               //
                //               // Infact, all the talk of non-compressed textures having DWORD alignment of pitch
                //               // seems to be bollocks.. If I apply alignment, then they fail to load in 3rd Party
                //               // or Microsoft DDS viewing applications.
                //               //

                //#if	APPLY_PITCH_ALIGNMENT
                //               mipPitch = ( mipPitch + 3 ) & ( ~3 );
                //#endif // APPLY_PITCH_ALIGNMENT

                //               outputData = new byte[ mipPitch * writeSurface.Height ];
                //               outputData.Initialize();

                //               for( int y = 0; y < writeSurface.Height; y++ )
                //               {
                //                  for( int x = 0; x < writeSurface.Width; x++ )
                //                  {
                //                     // Get colour from surface
                //                     ColorBgra pixelColour = writeSurface.GetPoint( x, y );
                //                     uint pixelData = 0;

                //                     switch( ddsToken.m_fileFormat )
                //                     {
                //                     case DdsFileFormat.DDS_FORMAT_A8R8G8B8:
                //                        {
                //                           pixelData = ( (uint)pixelColour.A << 24 ) |
                //                                    ( (uint)pixelColour.R << 16 ) |
                //                                    ( (uint)pixelColour.G << 8 ) |
                //                                    ( (uint)pixelColour.B << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_X8R8G8B8:
                //                        {
                //                           pixelData = ( (uint)pixelColour.R << 16 ) |
                //                                    ( (uint)pixelColour.G << 8 ) |
                //                                    ( (uint)pixelColour.B << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_A8B8G8R8:
                //                        {
                //                           pixelData = ( (uint)pixelColour.A << 24 ) |
                //                                    ( (uint)pixelColour.B << 16 ) |
                //                                    ( (uint)pixelColour.G << 8 ) |
                //                                    ( (uint)pixelColour.R << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_X8B8G8R8:
                //                        {
                //                           pixelData = ( (uint)pixelColour.B << 16 ) |
                //                                    ( (uint)pixelColour.G << 8 ) |
                //                                    ( (uint)pixelColour.R << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_A1R5G5B5:
                //                        {
                //                           pixelData = ( (uint)( ( pixelColour.A != 0 ) ? 1 : 0 ) << 15 ) |
                //                                    ( (uint)( pixelColour.R >> 3 ) << 10 ) |
                //                                    ( (uint)( pixelColour.G >> 3 ) << 5 ) |
                //                                    ( (uint)( pixelColour.B >> 3 ) << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_A4R4G4B4:
                //                        {
                //                           pixelData = ( (uint)( pixelColour.A >> 4 ) << 12 ) |
                //                                    ( (uint)( pixelColour.R >> 4 ) << 8 ) |
                //                                    ( (uint)( pixelColour.G >> 4 ) << 4 ) |
                //                                    ( (uint)( pixelColour.B >> 4 ) << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_R8G8B8:
                //                        {
                //                           pixelData = ( (uint)pixelColour.R << 16 ) |
                //                                    ( (uint)pixelColour.G << 8 ) |
                //                                    ( (uint)pixelColour.B << 0 );
                //                           break;
                //                        }

                //                     case DdsFileFormat.DDS_FORMAT_R5G6B5:
                //                        {
                //                           pixelData = ( (uint)( pixelColour.R >> 3 ) << 11 ) |
                //                                    ( (uint)( pixelColour.G >> 2 ) << 5 ) |
                //                                    ( (uint)( pixelColour.B >> 3 ) << 0 );
                //                           break;
                //                        }
                //                     }

                //                     // pixelData contains our target data.. so now set the pixel bytes
                //                     int pixelOffset = ( y * mipPitch ) + ( x * pixelWidth );
                //                     for( int loop = 0; loop < pixelWidth; loop++ )
                //                     {
                //                        outputData[ pixelOffset + loop ] = (byte)( ( pixelData >> ( 8 * loop ) ) & 0xff );
                //                     }
                //                  }

                //                  if( progressCallback != null )
                //                  {
                //                     long thisMipPixelsDone = ( y + 1 ) * (long)mipWidth;
                //                     long previousMipsPixelsDone = pixelsCompleted[ mipLoop ];
                //                     double progress = (double)( (double)thisMipPixelsDone + (double)previousMipsPixelsDone ) / (double)totalPixels;
                //                     progressCallback( this, new ProgressEventArgs( 100.0 * progress ) );
                //                  }
                //               }
                //}

                // Write the data for this mip level out..
                output.Write(surface.Data, 0, surface.Data.Length);
                //output.Write( outputData, 0, outputData.GetLength( 0 ) );

                //mipWidth = mipWidth / 2;
                //mipHeight = mipHeight / 2;
            }
        }
 /// <summary>
 /// Checks if dds resource should have the <see cref="DdsHeaderDxt10" /> header.
 /// </summary>
 /// <returns>
 /// <c>true</c> if dds resource should have the <see cref="DdsHeaderDxt10" /> header;
 /// otherwise <c>false</c>.
 /// </returns>
 public static bool ShouldHaveDxt10Header(this DdsHeader ddsHeader)
 {
     return((ddsHeader.PixelFormat.Flags == DdsPixelFormatFlags.FourCC) && (ddsHeader.PixelFormat.FourCC == DdsFourCC.DX10));
 }
Beispiel #4
0
    public static void CreateDDSTextureFromMemory(Device d3dDevice,
                                                  DataPointer dataPointer,
                                                  out Resource texture,
                                                  out ShaderResourceView textureView,
                                                  int maxsize                   = 0,
                                                  ResourceUsage usage           = ResourceUsage.Default,
                                                  BindFlags bindFlags           = BindFlags.ShaderResource,
                                                  CpuAccessFlags cpuAccessFlags = CpuAccessFlags.None,
                                                  ResourceOptionFlags miscFlags = ResourceOptionFlags.None,
                                                  bool forceSRGB                = false
                                                  )
    {
        texture     = null;
        textureView = null;

        if (d3dDevice == null)
        {
            throw new SharpDXException(Result.InvalidArg);
        }

        // Validate DDS file in memory
        if (dataPointer.Size < (sizeof(uint) + DdsHeader.SIZE))
        {
            throw new SharpDXException(Result.Fail);
        }

        uint magicNumber = Marshal.PtrToStructure <uint>(dataPointer.Pointer);

        if (magicNumber != DDS_MAGIC)
        {
            throw new SharpDXException(Result.Fail);
        }

        DdsHeader header = Marshal.PtrToStructure <DdsHeader>(dataPointer.Pointer + sizeof(uint));

        // Verify header to validate DDS file
        if (header.size != DdsHeader.SIZE ||
            header.ddspf.size != DdsPixelFormat.SIZE)
        {
            throw new SharpDXException(Result.Fail);
        }

        // Check for DX10 extension
        DdsHeaderDxt10?headerDxt10;

        bool bDXT10Header = false;

        if ((header.ddspf.flags & DDS_FOURCC) != 0 &&
            (MakeFourCC('D', 'X', '1', '0') == header.ddspf.fourCC))
        {
            // Must be long enough for both headers and magic value
            if (dataPointer.Size < (DdsHeader.SIZE + sizeof(uint) + DdsHeaderDxt10.SIZE))
            {
                throw new SharpDXException(Result.Fail);
            }

            bDXT10Header = true;
            headerDxt10  = Marshal.PtrToStructure <DdsHeaderDxt10>(dataPointer.Pointer + sizeof(uint) + DdsHeader.SIZE);
        }
        else
        {
            headerDxt10 = null;
        }

        int offset = sizeof(uint)
                     + DdsHeader.SIZE
                     + (bDXT10Header ? DdsHeaderDxt10.SIZE : 0);

        CreateTextureFromDDS(d3dDevice, header, headerDxt10,
                             dataPointer.Pointer + offset, dataPointer.Size - offset, maxsize,
                             usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
                             out texture, out textureView);
    }
Beispiel #5
0
        uint[] baseImage; //ARGB uint array
        #endregion

        public Dds(DdsFormat ddsFormat, int width, int height, uint[] imageData)
        {
            if (imageData.Length != width * height)
                throw new ArgumentException("Image data must contain width * height elements");

            header = new DdsHeader(ddsFormat, width, height);
            baseImage = (uint[])imageData.Clone();
        }
Beispiel #6
0
 public DdsProcessor(DdsHeader ddsHeader, DdsHeaderDxt10 ddsHeaderDxt10)
 {
     this.DdsHeader      = ddsHeader;
     this.DdsHeaderDxt10 = ddsHeaderDxt10;
 }
Beispiel #7
0
 public Dxt1Dds(DdsHeader header, PfimConfig config) : base(header, config)
 {
 }
Beispiel #8
0
        private Texture2D CreateTextureFromDds(BinaryReader reader, DdsHeader header, bool vflip, bool staging)
        {
            var width  = header.Width;
            var height = header.Height;
            var depth  = header.Depth;

            var arraySize = 1;
            var format    = Format.Unknown;
            var isCubeMap = false;

            var mipCount = header.MipMapCount;

            if (mipCount == 0)
            {
                mipCount = 1;
            }

            if (HeaderDxt10 != null)
            {
                arraySize = HeaderDxt10.ArraySize;
                if (arraySize == 0)
                {
                    throw new InvalidDataException();
                }

                format = HeaderDxt10.DxgiFormat;

                switch (format)
                {
                case Format.AI44:
                case Format.IA44:
                case Format.P8:
                case Format.A8P8:
                    throw new NotSupportedException();

                default:
                    if (BitsPerPixel(HeaderDxt10.DxgiFormat) == 0)
                    {
                        throw new NotSupportedException();
                    }
                    break;
                }

                switch (HeaderDxt10.ResourceDimension)
                {
                case ResourceDimension.Texture1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if (((int)header.Flags & _ddsHeight) != 0 && height != 1)
                    {
                        throw new InvalidDataException();
                    }
                    height = depth = 1;
                    break;

                case ResourceDimension.Texture2D:
                    if ((HeaderDxt10.MiscFlag & ResourceOptionFlags.TextureCube) != 0)
                    {
                        arraySize *= 6;
                        isCubeMap  = true;
                    }
                    depth = 1;
                    break;

                case ResourceDimension.Texture3D:
                    if (((int)header.Flags & _ddsVolume) == 0)
                    {
                        throw new InvalidDataException();
                    }

                    if (arraySize > 1)
                    {
                        throw new NotSupportedException();
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            else
            {
                format = GetDxgiFormat(header.PixelFormat);

                if (format == Format.Unknown)
                {
                    throw new NotSupportedException();
                }

                if (((int)header.Flags & _ddsVolume) != 0)
                {
                }
                else
                {
                    if ((header.Caps2 & _ddsCubemap) != 0)
                    {
                        // We require all six faces to be defined
                        if ((header.Caps2 & _ddsCubemapAllFaces) != _ddsCubemapAllFaces)
                        {
                            throw new NotSupportedException();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth = 1;

                    // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
                }

                Debug.Assert(BitsPerPixel(format) != 0);
            }

            var rectangles = new DataRectangle[mipCount * arraySize];

            var skipMip = 0;
            var twidth  = 0;
            var theight = 0;
            var tdepth  = 0;

            FillInitData(reader, width, height, depth, mipCount, arraySize, format, vflip, ref twidth, ref theight,
                         ref tdepth, ref skipMip, ref rectangles);

            return(new Texture2D(Renderer.Device, new Texture2DDescription
            {
                Width = width,
                Height = height,
                BindFlags = staging ? BindFlags.None : BindFlags.ShaderResource,
                Usage = staging ? ResourceUsage.Staging : ResourceUsage.Default,
                Format = format,
                ArraySize = arraySize,
                MipLevels = mipCount,
                OptionFlags = isCubeMap ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None,
                CpuAccessFlags = staging ? CpuAccessFlags.Read : CpuAccessFlags.None,
                SampleDescription = new SampleDescription(1, 0)
            }, rectangles));
        }
 /// <summary>
 /// Gets a value indicating whether determines whether this resource is a cubemap.
 /// </summary>
 /// <returns>
 /// <c>true</c> if this resource is a cubemap; otherwise, <c>false</c>.
 /// </returns>
 public static bool IsCubemap(this DdsHeader ddsHeader)
 {
     return((ddsHeader.Caps2 & DdsCaps2.Cubemap) != 0);
 }
Beispiel #10
0
        internal static void WriteUncompressed(string filename, BitmapContent bitmapContent)
        {
            using (var writer = new BinaryWriter(new FileStream(filename, FileMode.Create, FileAccess.Write)))
            {
                // Write signature ("DDS ")
                writer.Write((byte)0x44);
                writer.Write((byte)0x44);
                writer.Write((byte)0x53);
                writer.Write((byte)0x20);

                var header = new DdsHeader();
                header.dwSize              = 124;
                header.dwFlags             = Ddsd.Caps | Ddsd.Width | Ddsd.Height | Ddsd.Pitch | Ddsd.PixelFormat;
                header.dwWidth             = (uint)bitmapContent.Width;
                header.dwHeight            = (uint)bitmapContent.Height;
                header.dwPitchOrLinearSize = (uint)(bitmapContent.Width * 4);
                header.dwDepth             = (uint)0;
                header.dwMipMapCount       = (uint)0;

                writer.Write((uint)header.dwSize);
                writer.Write((uint)header.dwFlags);
                writer.Write((uint)header.dwHeight);
                writer.Write((uint)header.dwWidth);
                writer.Write((uint)header.dwPitchOrLinearSize);
                writer.Write((uint)header.dwDepth);
                writer.Write((uint)header.dwMipMapCount);

                // 11 unsed and reserved DWORDS.
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);

                SurfaceFormat format;
                if (!bitmapContent.TryGetFormat(out format) || format != SurfaceFormat.Color)
                {
                    throw new NotSupportedException("Unsupported bitmap content!");
                }

                header.ddspf.dwSize        = 32;
                header.ddspf.dwFlags       = Ddpf.AlphaPixels | Ddpf.Rgb;
                header.ddspf.dwFourCC      = 0;
                header.ddspf.dwRgbBitCount = 32;
                header.ddspf.dwRBitMask    = 0x000000ff;
                header.ddspf.dwGBitMask    = 0x0000ff00;
                header.ddspf.dwBBitMask    = 0x00ff0000;
                header.ddspf.dwABitMask    = 0xff000000;

                // Write the DDS_PIXELFORMAT
                writer.Write((uint)header.ddspf.dwSize);
                writer.Write((uint)header.ddspf.dwFlags);
                writer.Write((uint)header.ddspf.dwFourCC);
                writer.Write((uint)header.ddspf.dwRgbBitCount);
                writer.Write((uint)header.ddspf.dwRBitMask);
                writer.Write((uint)header.ddspf.dwGBitMask);
                writer.Write((uint)header.ddspf.dwBBitMask);
                writer.Write((uint)header.ddspf.dwABitMask);

                header.dwCaps  = DdsCaps.Texture;
                header.dwCaps2 = 0;

                // Continue reading DDS_HEADER
                writer.Write((uint)header.dwCaps);
                writer.Write((uint)header.dwCaps2);

                // More reserved unused DWORDs.
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);

                // Write out the face data.
                writer.Write(bitmapContent.GetPixelData());
            }
        }
 public DdsFile()
 {
     m_header = new DdsHeader();
 }
Beispiel #12
0
        /// <summary>
        /// Creates valid DDS Header for entry's texture.
        /// </summary>
        /// <param name="entry">Valid BA2TextureFileEntry instance.</param>
        /// <returns>
        /// Valid DDS Header.
        /// </returns>
        /// <exception cref="System.NotSupportedException">Entry DDS format is not supported.</exception>
        private DdsHeader CreateDdsHeaderForEntry(BA2TextureFileEntry entry)
        {
            var        header = new DdsHeader();
            DxgiFormat format = (DxgiFormat)entry.Format;

            header.dwSize        = 124; // sizeof(DDS_HEADER)
            header.dwHeaderFlags = Dds.DDS_HEADER_FLAGS_TEXTURE |
                                   Dds.DDS_HEADER_FLAGS_LINEARSIZE | Dds.DDS_HEADER_FLAGS_MIPMAP;
            header.dwHeight       = (uint)entry.TextureHeight;
            header.dwWidth        = (uint)entry.TextureWidth;
            header.dwMipMapCount  = (uint)entry.NumberOfMipmaps;
            header.ddspf.dwSize   = 32; // sizeof(DDS_PIXELFORMAT);
            header.dwSurfaceFlags = Dds.DDS_SURFACE_FLAGS_TEXTURE | Dds.DDS_SURFACE_FLAGS_MIPMAP;

            switch (format)
            {
            case DxgiFormat.BC1_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_FOURCC;
                header.ddspf.dwFourCC      = (uint)Dds.MakeFourCC('D', 'X', 'T', '1');
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight / 2u;
                break;

            case DxgiFormat.BC2_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_FOURCC;
                header.ddspf.dwFourCC      = (uint)Dds.MakeFourCC('D', 'X', 'T', '3');
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight;
                break;

            case DxgiFormat.BC3_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_FOURCC;
                header.ddspf.dwFourCC      = (uint)Dds.MakeFourCC('D', 'X', 'T', '5');
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight;
                break;

            case DxgiFormat.BC5_UNORM:
                header.ddspf.dwFlags = Dds.DDS_FOURCC;
                // ATI2
                header.ddspf.dwFourCC      = (uint)Dds.MakeFourCC('D', 'X', 'T', '5');
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight;
                break;

            case DxgiFormat.BC7_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_FOURCC;
                header.ddspf.dwFourCC      = (uint)Dds.MakeFourCC('B', 'C', '7', '\0');
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight;
                break;

            case DxgiFormat.B8G8R8A8_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_RGBA;
                header.ddspf.dwRGBBitCount = 32;
                header.ddspf.dwRBitMask    = 0x00FF0000;
                header.ddspf.dwGBitMask    = 0x0000FF00;
                header.ddspf.dwBBitMask    = 0x000000FF;
                header.ddspf.dwABitMask    = 0xFF000000;
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight * 4u;
                break;

            case DxgiFormat.R8_UNORM:
                header.ddspf.dwFlags       = Dds.DDS_RGB;
                header.ddspf.dwRGBBitCount = 8;
                header.ddspf.dwRBitMask    = 0xFF;
                header.dwPitchOrLinearSize = (uint)entry.TextureWidth * (uint)entry.TextureHeight;
                break;

            default:
                throw new NotSupportedException($"DDS format \"{format.ToString()}\" is not supported.");
            }

            return(header);
        }
Beispiel #13
0
 public DDSLoader(string filename)
 {
     if (DdsHeader.GetInfo(filename, out DdsHeader header, out HeaderDXT10? header10, out int offset, out byte[] buffer))
     {
         TextureData = LoadTexture(header, header10, buffer, offset, 0);
     }
Beispiel #14
0
 public static bool GetInfo(string filename, out DdsHeader header, out HeaderDXT10?header10, out int offset, out byte[] buffer)
 {
     buffer = File.ReadAllBytes(filename);
     return(GetInfo(buffer, out header, out header10, out offset));
 }
Beispiel #15
0
        public void InjectDds(TagSerializer serializer, TagDeserializer deserializer, Bitmap bitmap, int imageIndex, Stream ddsStream)
        {
            var resource    = bitmap.Resources[imageIndex].Resource;
            var newResource = (resource == null);
            ResourceSerializationContext    resourceContext;
            BitmapTextureResourceDefinition definition;

            if (newResource)
            {
                // Create a new resource reference
                resource = new ResourceReference
                {
                    DefinitionFixups = new List <ResourceDefinitionFixup>(),
                    D3DObjectFixups  = new List <D3DObjectFixup>(),
                    Type             = 1, // TODO: Map out this type enum instead of using numbers
                    Unknown68        = 1
                };
                bitmap.Resources[imageIndex].Resource = resource;
                resourceContext = new ResourceSerializationContext(resource);
                definition      = new BitmapTextureResourceDefinition
                {
                    Texture = new D3DPointer <BitmapTextureResourceDefinition.BitmapDefinition>
                    {
                        Definition = new BitmapTextureResourceDefinition.BitmapDefinition()
                    }
                };
            }
            else
            {
                // Deserialize the old definition
                resourceContext = new ResourceSerializationContext(resource);
                definition      = deserializer.Deserialize <BitmapTextureResourceDefinition>(resourceContext);
            }
            if (definition.Texture == null || definition.Texture.Definition == null)
            {
                throw new ArgumentException("Invalid bitmap definition");
            }
            var texture   = definition.Texture.Definition;
            var imageData = bitmap.Images[imageIndex];

            // Read the DDS header and modify the definition to match
            var dds      = DdsHeader.Read(ddsStream);
            var dataSize = (int)(ddsStream.Length - ddsStream.Position);

            texture.Data            = new ResourceDataReference(dataSize, new ResourceAddress(ResourceAddressType.Resource, 0));
            texture.Width           = (short)dds.Width;
            texture.Height          = (short)dds.Height;
            texture.Depth           = (sbyte)Math.Max(1, dds.Depth);
            texture.Levels          = (sbyte)Math.Max(1, dds.MipMapCount);
            texture.Type            = BitmapDdsFormatDetection.DetectType(dds);
            texture.D3DFormatUnused = (int)((dds.D3D10Format != DxgiFormat.Bc5UNorm) ? dds.FourCc : DdsFourCc.FromString("ATI2"));
            texture.Format          = BitmapDdsFormatDetection.DetectFormat(dds);

            // Set flags based on the format
            switch (texture.Format)
            {
            case BitmapFormat.Dxt1:
            case BitmapFormat.Dxt3:
            case BitmapFormat.Dxt5:
            case BitmapFormat.Dxn:
                texture.Flags = BitmapFlags.Compressed;
                break;

            default:
                texture.Flags = BitmapFlags.None;
                break;
            }
            if ((texture.Width & (texture.Width - 1)) == 0 && (texture.Height & (texture.Height - 1)) == 0)
            {
                texture.Flags |= BitmapFlags.PowerOfTwoDimensions;
            }

            // If creating a new image, then add a new resource, otherwise replace the existing one
            if (newResource)
            {
                _resourceManager.Add(resource, ResourceLocation.Textures, ddsStream);
            }
            else
            {
                _resourceManager.Replace(resource, ddsStream);
            }

            // Serialize the new resource definition
            serializer.Serialize(resourceContext, definition);

            // Modify the image data in the bitmap tag to match the definition
            imageData.Width       = texture.Width;
            imageData.Height      = texture.Height;
            imageData.Depth       = texture.Depth;
            imageData.Type        = texture.Type;
            imageData.Format      = texture.Format;
            imageData.Flags       = texture.Flags;
            imageData.MipmapCount = (sbyte)(texture.Levels - 1);
            imageData.DataOffset  = texture.Data.Address.Offset;
            imageData.DataSize    = texture.Data.Size;
            imageData.Unknown15   = texture.Unknown35;
        }
 /// <summary>
 /// Gets a value indicating whether determines whether this resource is a volume texture.
 /// </summary>
 /// <returns>
 /// <c>true</c> if this resource is a volume texture; otherwise, <c>false</c>.
 /// </returns>
 public static bool IsVolumeTexture(this DdsHeader ddsHeader)
 {
     return((ddsHeader.Caps2 & DdsCaps2.Volume) != 0);
 }
Beispiel #17
0
 public Bc4sDds(DdsHeader header, PfimConfig config) : base(header, config)
 {
 }
 /// <summary>
 /// Gets a value indicating whether determines whether this resource contains compressed surface data.
 /// </summary>
 /// <value>
 /// <c>true</c> if this resource contains compressed surface data; otherwise, <c>false</c>.
 /// </value>
 public static bool IsCompressed(this DdsHeader ddsHeader)
 {
     return((ddsHeader.Flags & DdsFlags.LinearSize) != 0);
 }
Beispiel #19
0
        static internal TextureContent Import(string filename, ContentImporterContext context)
        {
            var identity = new ContentIdentity(filename);
            TextureContent output = null;

            using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
            {
                // Read signature ("DDS ")
                var valid = reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x53;
                valid = valid && reader.ReadByte() == 0x20;
                if (!valid)
                    throw new ContentLoadException("Invalid file signature");

                var header = new DdsHeader();

                // Read DDS_HEADER
                header.dwSize = reader.ReadUInt32();
                if (header.dwSize != 124)
                    throw new ContentLoadException("Invalid DDS_HEADER dwSize value");
                header.dwFlags = (Ddsd)reader.ReadUInt32();
                header.dwHeight = reader.ReadUInt32();
                header.dwWidth = reader.ReadUInt32();
                header.dwPitchOrLinearSize = reader.ReadUInt32();
                header.dwDepth = reader.ReadUInt32();
                header.dwMipMapCount = reader.ReadUInt32();
                // The next 11 DWORDs are reserved and unused
                for (int i = 0; i < 11; ++i)
                    reader.ReadUInt32();
                // Read DDS_PIXELFORMAT
                header.ddspf.dwSize = reader.ReadUInt32();
                if (header.ddspf.dwSize != 32)
                    throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value");
                header.ddspf.dwFlags = (Ddpf)reader.ReadUInt32();
                header.ddspf.dwFourCC = (FourCC)reader.ReadUInt32();
                header.ddspf.dwRgbBitCount = reader.ReadUInt32();
                header.ddspf.dwRBitMask = reader.ReadUInt32();
                header.ddspf.dwGBitMask = reader.ReadUInt32();
                header.ddspf.dwBBitMask = reader.ReadUInt32();
                header.ddspf.dwABitMask = reader.ReadUInt32();
                // Continue reading DDS_HEADER
                header.dwCaps = (DdsCaps)reader.ReadUInt32();
                header.dwCaps2 = (DdsCaps2)reader.ReadUInt32();
                // dwCaps3 unused
                reader.ReadUInt32();
                // dwCaps4 unused
                reader.ReadUInt32();
                // dwReserved2 unused
                reader.ReadUInt32();

                // Check for the existence of the DDS_HEADER_DXT10 struct next
                if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10)
                {
                    throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found");
                }

                int faceCount = 1;
                int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1);
                if (header.dwCaps.HasFlag(DdsCaps.Complex))
                {
                    if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap))
                    {
                        if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces))
                            throw new ContentLoadException("Incomplete cubemap in DDS file");
                        faceCount = 6;
                        output = new TextureCubeContent() { Identity = identity };
                    }
                    else
                    {
                        output = new Texture2DContent() { Identity = identity };
                    }
                }
                else
                {
                    output = new Texture2DContent() { Identity = identity };
                }

                bool rbSwap;
                var format = GetSurfaceFormat(ref header.ddspf, out rbSwap);

                for (int f = 0; f < faceCount; ++f)
                {
                    var w = (int)header.dwWidth;
                    var h = (int)header.dwHeight;
                    var mipMaps = new MipmapChain();
                    for (int m = 0; m < mipMapCount; ++m)
                    {
                        var content = CreateBitmapContent(format, w, h);
                        var byteCount = GetBitmapSize(format, w, h);
                        var bytes = reader.ReadBytes(byteCount);
                        content.SetPixelData(bytes);
                        mipMaps.Add(content);
                        w = MathHelper.Max(1, w / 2);
                        h = MathHelper.Max(1, h / 2);
                    }
                    output.Faces[f] = mipMaps;
                }
            }

            return output;
        }
 /// <summary>
 /// Gets a value indicating whether determines whether this resource contains alpha data.
 /// </summary>
 /// <value>
 /// <c>true</c> if this resource contains alpha data; otherwise, <c>false</c>.
 /// </value>
 public static bool HasAlpha(this DdsHeader ddsHeader)
 {
     return((ddsHeader.PixelFormat.Flags & DdsPixelFormatFlags.AlphaPixels) != 0);
 }
Beispiel #21
0
        static internal TextureContent Import(string filename, ContentImporterContext context)
        {
            var            identity = new ContentIdentity(filename);
            TextureContent output   = null;

            using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
            {
                // Read signature ("DDS ")
                var valid = reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x53;
                valid = valid && reader.ReadByte() == 0x20;
                if (!valid)
                {
                    throw new ContentLoadException("Invalid file signature");
                }

                var header = new DdsHeader();

                // Read DDS_HEADER
                header.dwSize = reader.ReadUInt32();
                if (header.dwSize != 124)
                {
                    throw new ContentLoadException("Invalid DDS_HEADER dwSize value");
                }
                header.dwFlags             = (Ddsd)reader.ReadUInt32();
                header.dwHeight            = reader.ReadUInt32();
                header.dwWidth             = reader.ReadUInt32();
                header.dwPitchOrLinearSize = reader.ReadUInt32();
                header.dwDepth             = reader.ReadUInt32();
                header.dwMipMapCount       = reader.ReadUInt32();
                // The next 11 DWORDs are reserved and unused
                for (int i = 0; i < 11; ++i)
                {
                    reader.ReadUInt32();
                }
                // Read DDS_PIXELFORMAT
                header.ddspf.dwSize = reader.ReadUInt32();
                if (header.ddspf.dwSize != 32)
                {
                    throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value");
                }
                header.ddspf.dwFlags       = (Ddpf)reader.ReadUInt32();
                header.ddspf.dwFourCC      = (FourCC)reader.ReadUInt32();
                header.ddspf.dwRgbBitCount = reader.ReadUInt32();
                header.ddspf.dwRBitMask    = reader.ReadUInt32();
                header.ddspf.dwGBitMask    = reader.ReadUInt32();
                header.ddspf.dwBBitMask    = reader.ReadUInt32();
                header.ddspf.dwABitMask    = reader.ReadUInt32();
                // Continue reading DDS_HEADER
                header.dwCaps  = (DdsCaps)reader.ReadUInt32();
                header.dwCaps2 = (DdsCaps2)reader.ReadUInt32();
                // dwCaps3 unused
                reader.ReadUInt32();
                // dwCaps4 unused
                reader.ReadUInt32();
                // dwReserved2 unused
                reader.ReadUInt32();

                // Check for the existence of the DDS_HEADER_DXT10 struct next
                if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10)
                {
                    throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found");
                }

                int faceCount   = 1;
                int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1);
                if (header.dwCaps.HasFlag(DdsCaps.Complex))
                {
                    if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap))
                    {
                        if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces))
                        {
                            throw new ContentLoadException("Incomplete cubemap in DDS file");
                        }
                        faceCount = 6;
                        output    = new TextureCubeContent()
                        {
                            Identity = identity
                        };
                    }
                    else
                    {
                        output = new Texture2DContent()
                        {
                            Identity = identity
                        };
                    }
                }
                else
                {
                    output = new Texture2DContent()
                    {
                        Identity = identity
                    };
                }

                bool rbSwap;
                var  format = GetSurfaceFormat(ref header.ddspf, out rbSwap);

                for (int f = 0; f < faceCount; ++f)
                {
                    var w       = (int)header.dwWidth;
                    var h       = (int)header.dwHeight;
                    var mipMaps = new MipmapChain();
                    for (int m = 0; m < mipMapCount; ++m)
                    {
                        var content   = CreateBitmapContent(format, w, h);
                        var byteCount = GetBitmapSize(format, w, h);
                        var bytes     = reader.ReadBytes(byteCount);
                        content.SetPixelData(bytes);
                        mipMaps.Add(content);
                        w = MathHelper.Max(1, w / 2);
                        h = MathHelper.Max(1, h / 2);
                    }
                    output.Faces[f] = mipMaps;
                }
            }

            return(output);
        }
 /// <summary>
 /// Gets a value indicating whether determines whether this resource contains mipmap data.
 /// </summary>
 /// <value>
 /// <c>true</c> if this resource contains mipmap data; otherwise, <c>false</c>.
 /// </value>
 public static bool HasMipmaps(this DdsHeader ddsHeader)
 {
     return((ddsHeader.Caps1 & DdsCaps1.MipMap) != 0 && (ddsHeader.Flags & DdsFlags.MipMapCount) != 0);
 }
Beispiel #23
0
    private static void CreateTextureFromDDS(
        Device d3dDevice,
        DdsHeader header,
        DdsHeaderDxt10?headerDxt10,
        IntPtr bitData,
        int bitSize,
        int maxsize,
        ResourceUsage usage,
        BindFlags bindFlags,
        CpuAccessFlags cpuAccessFlags,
        ResourceOptionFlags miscFlags,
        bool forceSRGB,
        out Resource texture,
        out ShaderResourceView textureView)
    {
        Result hr = Result.Ok;

        int width  = (int)header.width;
        int height = (int)header.height;
        int depth  = (int)header.depth;

        ResourceDimension resDim = ResourceDimension.Unknown;
        uint arraySize           = 1;

        SharpDX.DXGI.Format format = SharpDX.DXGI.Format.Unknown;
        bool isCubeMap             = false;

        int mipCount = (int)header.mipMapCount;

        if (0 == mipCount)
        {
            mipCount = 1;
        }

        if (headerDxt10.HasValue)
        {
            DdsHeaderDxt10 d3d10ext = headerDxt10.Value;

            arraySize = d3d10ext.arraySize;
            if (arraySize == 0)
            {
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.InvalidData));
            }

            switch (d3d10ext.dxgiFormat)
            {
            case Format.AI44:
            case Format.IA44:
            case Format.P8:
            case Format.A8P8:
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));

            default:
                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
                }
                break;
            }

            format = d3d10ext.dxgiFormat;

            switch (d3d10ext.resourceDimension)
            {
            case ResourceDimension.Texture1D:
                // D3DX writes 1D textures with a fixed Height of 1
                if ((header.flags & DDS_HEIGHT) != 0 && height != 1)
                {
                    throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.InvalidData));
                }
                height = depth = 1;
                break;

            case ResourceDimension.Texture2D:
                if ((d3d10ext.miscFlag & ResourceOptionFlags.TextureCube) != 0)
                {
                    arraySize *= 6;
                    isCubeMap  = true;
                }
                depth = 1;
                break;

            case ResourceDimension.Texture3D:
                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) == 0)
                {
                    throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.InvalidData));
                }

                if (arraySize > 1)
                {
                    throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.InvalidData));
                }
                break;

            default:
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.InvalidData));
            }

            resDim = d3d10ext.resourceDimension;
        }
        else
        {
            format = GetDXGIFormat(header.ddspf);

            if (format == Format.Unknown)
            {
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
            }

            if ((header.flags & DDS_HEADER_FLAGS_VOLUME) != 0)
            {
                resDim = ResourceDimension.Texture3D;
            }
            else
            {
                if ((header.caps2 & DDS_CUBEMAP) != 0)
                {
                    // We require all six faces to be defined
                    if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                    {
                        throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
                    }

                    arraySize = 6;
                    isCubeMap = true;
                }

                depth  = 1;
                resDim = ResourceDimension.Texture2D;

                // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
            }

            Debug.Assert(BitsPerPixel(format) != 0);
        }

        // Bound sizes (for security purposes we don't trust DDS file metadata larger than the D3D 11.x hardware requirements)
        if (mipCount > Resource.MaximumMipLevels)
        {
            throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
        }

        switch (resDim)
        {
        case ResourceDimension.Texture1D:
            if ((arraySize > Resource.MaximumTexture1DArraySize) ||
                (width > Resource.MaximumTexture1DSize))
            {
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
            }
            break;

        case ResourceDimension.Texture2D:
            if (isCubeMap)
            {
                // This is the right bound because we set arraySize to (NumCubes*6) above
                if ((arraySize > Resource.MaximumTexture2DArraySize) ||
                    (width > Resource.MaximumTextureCubeSize) ||
                    (height > Resource.MaximumTextureCubeSize))
                {
                    throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
                }
            }
            else if ((arraySize > Resource.MaximumTexture2DArraySize) ||
                     (width > Resource.MaximumTexture2DSize) ||
                     (height > Resource.MaximumTexture2DSize))
            {
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
            }
            break;

        case ResourceDimension.Texture3D:
            if ((arraySize > 1) ||
                (width > Resource.MaximumTexture3DSize) ||
                (height > Resource.MaximumTexture3DSize) ||
                (depth > Resource.MaximumTexture3DSize))
            {
                throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
            }
            break;

        default:
            throw new SharpDXException(ErrorCodeHelper.ToResult(ErrorCode.NotSupported));
        }

        // Create the texture
        DataBox[] initData = new DataBox[mipCount * arraySize];

        FillInitData(width, height, depth, mipCount, (int)arraySize, format, maxsize, bitSize, bitData,
                     out int twidth, out int theight, out int tdepth, out int skipMip, initData);

        CreateD3DResources(d3dDevice, resDim, twidth, theight, tdepth, mipCount - skipMip, (int)arraySize,
                           format, usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
                           isCubeMap, initData, out texture, out textureView);
    }
 /// <summary>
 ///
 /// </summary>
 /// <param name="ddsHeader"><see cref="DdsHeader" /></param>
 /// <returns></returns>
 public static int TextureCount(this DdsHeader ddsHeader)
 {
     return(ddsHeader.HasMipmaps() ? (int)ddsHeader.MipMapCount : 1);
 }
Beispiel #25
0
        public Dds(Stream s)
        {
            header = new DdsHeader(s);

            byte[] buffer = new byte[header.DataSize];
            if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
                throw new IOException(String.Format("Failed to read DDS data.  At 0x{0:X8}.", s.Position));

            var decoder = header.Decoder;
            if (decoder == null)
                throw new FormatException("File is not a supported DDS format");

            if (header.IsBlockCompressed)
            {
                // Decompress
                byte[] pixelData = DdsSquish.DecompressImage(buffer, (int)header.width, (int)header.height, header.SquishFourCC);

                // Convert R, G, B, A byte array to ARGB uint array...
                baseImage = new uint[pixelData.Length / sizeof(uint)];
                Enumerable.Range(0, baseImage.Length).AsParallel()
                    .ForAll(i => baseImage[i] = decoder(BitConverter.ToUInt32(pixelData, i * sizeof(uint))));
            }
            else
            {
                // Convert encoded data to ARGB uint array
                baseImage = new uint[header.width * header.height];
                int rowPitch = buffer.Length / (int)header.height;
                int pixelSize = (int)header.UncompressedPixelSize;
                Enumerable.Range(0, (int)header.width).AsParallel()
                    .ForAll(destX => Enumerable.Range(0, (int)header.height).AsParallel()
                        .ForAll(destY =>
                        {
                            // Compute pixel offsets
                            int srcPixelOffset = (destY * rowPitch) + (destX * pixelSize);
                            int destPixelOffset = (destY * (int)header.width) + destX;

                            // Build our pixel colour as a DWORD - parallelism overhead costs too much
                            uint pixelColour = 0;
                            for (int loop = 0; loop < pixelSize; loop++)
                                pixelColour |= (uint)(buffer[srcPixelOffset + loop] << (8 * loop));

                            // delegate takes care of calculation
                            baseImage[destPixelOffset] = decoder(pixelColour);
                        }));
            }

        }
Beispiel #26
0
 public Bc7Dds(DdsHeader header, PfimConfig config) : base(header, config)
 {
     currentBlock = new byte[CompressedBytesPerBlock];
 }