Пример #1
0
        private static BaseBitmap ConvertGen3Bitmap(byte[] primaryData, byte[] secondaryData, BitmapTextureInteropDefinition definition, Bitmap bitmap, int imageIndex, bool isPaired, int pairIndex, BitmapTextureInteropDefinition otherDefinition, bool forDDS)
        {
            if (primaryData == null && secondaryData == null)
            {
                return(null);
            }

            using (var result = new MemoryStream())
            {
                int mipLevelCount = definition.MipmapCount;
                int layerCount    = definition.BitmapType == BitmapType.CubeMap ? 6 : definition.Depth;

                if (definition.BitmapType == BitmapType.Array && mipLevelCount > 1)
                {
                    mipLevelCount          = 1;
                    definition.MipmapCount = 1;
                }

                if (!forDDS)
                {
                    // order for d3d9, all faces first, then mipmaps
                    for (int mipLevel = 0; mipLevel < mipLevelCount; mipLevel++)
                    {
                        for (int layerIndex = 0; layerIndex < layerCount; layerIndex++)
                        {
                            if (definition.BitmapType == BitmapType.CubeMap) // swap cubemap faces
                            {
                                if (layerIndex == 2)
                                {
                                    layerIndex = 3;
                                }
                                else if (layerIndex == 3)
                                {
                                    layerIndex = 2;
                                }
                            }

                            ConvertGen3BitmapData(result, primaryData, secondaryData, definition, bitmap, imageIndex, mipLevel, layerIndex, isPaired, pairIndex, otherDefinition);

                            if (definition.BitmapType == BitmapType.CubeMap)
                            {
                                if (layerIndex == 3)
                                {
                                    layerIndex = 2;
                                }
                                else if (layerIndex == 2)
                                {
                                    layerIndex = 3;
                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int layerIndex = 0; layerIndex < layerCount; layerIndex++)
                    {
                        if (definition.BitmapType == BitmapType.CubeMap) // swap cubemap faces
                        {
                            if (layerIndex == 2)
                            {
                                layerIndex = 3;
                            }
                            else if (layerIndex == 3)
                            {
                                layerIndex = 2;
                            }
                        }

                        for (int mipLevel = 0; mipLevel < mipLevelCount; mipLevel++)
                        {
                            ConvertGen3BitmapData(result, primaryData, secondaryData, definition, bitmap, imageIndex, mipLevel, layerIndex, isPaired, pairIndex, otherDefinition);
                        }

                        if (definition.BitmapType == BitmapType.CubeMap)
                        {
                            if (layerIndex == 3)
                            {
                                layerIndex = 2;
                            }
                            else if (layerIndex == 2)
                            {
                                layerIndex = 3;
                            }
                        }
                    }
                }

                var resultData = result.ToArray();

                BaseBitmap resultBitmap = new BaseBitmap(bitmap.Images[imageIndex]);


                var newFormat = BitmapUtils.GetEquivalentBitmapFormat(bitmap.Images[imageIndex].Format);
                resultBitmap.UpdateFormat(newFormat);

                if (BitmapUtils.RequiresDecompression(resultBitmap.Format, (uint)resultBitmap.Width, (uint)resultBitmap.Height))
                {
                    resultBitmap.Format = BitmapFormat.A8R8G8B8;
                }

                if (!BitmapUtils.IsCompressedFormat(resultBitmap.Format))
                {
                    resultBitmap.Flags &= ~BitmapFlags.Compressed;
                }
                else
                {
                    resultBitmap.Flags |= BitmapFlags.Compressed;
                }

                //
                // Update resource definition/image, truncate DXN to level 4x4
                //

                resultBitmap.Data = resultData;

                if (resultBitmap.Format == BitmapFormat.Dxn) // wouldn't be required if d3d9 supported non power of two DXN and with mips less than 8x8
                {
                    GenerateCompressedMipMaps(resultBitmap);
                }


                if (resultBitmap.Type == BitmapType.Array) // for HO, arrays use the index of Texture3D
                {
                    resultBitmap.Type = BitmapType.Texture3D;
                }

                return(resultBitmap);
            }
        }
Пример #2
0
        private static bool ConvertImage(BaseBitmap bitmap)
        {
            BitmapFormat targetFormat = bitmap.Format;
            var          data         = bitmap.Data;
            bool         DXTFlip      = false;

            switch (bitmap.Format)
            {
            case BitmapFormat.Dxt5aMono:
            case BitmapFormat.Dxt3aMono:
                targetFormat  = BitmapFormat.Y8;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.Dxt3aAlpha:
            case BitmapFormat.Dxt5aAlpha:
                targetFormat  = BitmapFormat.A8;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.DxnMonoAlpha:
            case BitmapFormat.Dxt5a:
            case BitmapFormat.AY8:
                targetFormat  = BitmapFormat.A8Y8;;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.A4R4G4B4:
            case BitmapFormat.R5G6B5:
                targetFormat = BitmapFormat.A8R8G8B8;
                break;

            case BitmapFormat.A8Y8:
            case BitmapFormat.Y8:
            case BitmapFormat.A8:
            case BitmapFormat.A8R8G8B8:
            case BitmapFormat.X8R8G8B8:
            case BitmapFormat.A16B16G16R16F:
            case BitmapFormat.A32B32G32R32F:
            case BitmapFormat.V8U8:
                break;

            case BitmapFormat.Dxt1:
            case BitmapFormat.Dxt3:
            case BitmapFormat.Dxt5:
            case BitmapFormat.Dxn:
                if (bitmap.Height != bitmap.NearestHeight || bitmap.Width != bitmap.NearestWidth)
                {
                    targetFormat  = BitmapFormat.A8R8G8B8;
                    bitmap.Flags &= ~BitmapFlags.Compressed;
                    DXTFlip       = true;
                }
                break;

            case BitmapFormat.Ctx1:
                bitmap.UpdateFormat(BitmapFormat.Dxn);
                data         = BitmapDecoder.Ctx1ToDxn(data, bitmap.NearestWidth, bitmap.NearestHeight);
                targetFormat = BitmapFormat.Dxn;
                break;

            default:
                throw new Exception($"Unsupported bitmap format {bitmap.Format}");
            }

            if (targetFormat != bitmap.Format)
            {
                data = BitmapDecoder.DecodeBitmap(data, bitmap.Format, bitmap.NearestWidth, bitmap.NearestHeight);
                data = BitmapDecoder.EncodeBitmap(data, targetFormat, bitmap.NearestWidth, bitmap.NearestHeight);

                bool reformat = false;

                if (bitmap.NearestHeight != bitmap.Height || bitmap.NearestWidth != bitmap.Width)
                {
                    reformat = true;
                }

                if (reformat)
                {
                    var compressionFactor = BitmapFormatUtils.GetCompressionFactor(targetFormat);
                    int fixedSize         = (int)(bitmap.Width * bitmap.Height / compressionFactor);
                    int tilePitch         = (int)(bitmap.NearestWidth / compressionFactor);
                    int pitch             = (int)(bitmap.Width / compressionFactor);

                    byte[] fixedData    = new byte[fixedSize];
                    int    numberOfPass = bitmap.Height;   // encode does not give back block compressed data.
                    for (int i = 0; i < numberOfPass; i++) // may need to compute an offset for special bitmaps
                    {
                        Array.Copy(data, i * tilePitch, fixedData, i * pitch, pitch);
                    }
                    data = fixedData;
                }

                bitmap.UpdateFormat(targetFormat);
                bitmap.Data = data;
            }

            bitmap.Data = data;

            if (DXTFlip)
            {
                return(false);
            }

            return(true);
        }