예제 #1
0
        public static bool _LoadScanline(ref XMVECTOR[] pDestination, ulong count, byte[] pSource, ulong size, DXGI_FORMAT format)
        {
            switch (format)
            {
            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT:
            {
                var msize = (size > 16 * count) ? 16 * count : size;        //16 bytes for 4 float components
                pDestination = new XMVECTOR[msize / 16];
                Array.Copy(pSource, pDestination, (int)msize / 16);
                return(true);
            }

            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_UINT:
                return(LOAD_SCANLINE <XMUINT4>(sizeof(uint) * 4, XMLoadUInt4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_SINT:
                return(LOAD_SCANLINE <XMINT4>(sizeof(int) * 4, XMLoadSInt4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_FLOAT:
                return(LOAD_SCANLINE <XMFLOAT3>(sizeof(float) * 3, XMLoadFloat3, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_UINT:
                return(LOAD_SCANLINE <XMUINT3>(sizeof(uint) * 3, XMLoadUInt3, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_SINT:
                return(LOAD_SCANLINE <XMINT3>(sizeof(int) * 3, XMLoadSInt3, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT:
                return(LOAD_SCANLINE <XMHALF4>(2 * 4, XMLoadHalf4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_UNORM:
                return(LOAD_SCANLINE <XMUSHORTN4>(sizeof(ushort) * 4, XMLoadUShortN4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_UINT:
                return(LOAD_SCANLINE <XMUSHORT4>(sizeof(ushort) * 4, XMLoadUShort4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_SNORM:
                return(LOAD_SCANLINE <XMSHORTN4>(sizeof(short) * 4, XMLoadShortN4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_SINT:
                return(LOAD_SCANLINE <XMSHORT4>(sizeof(short) * 4, XMLoadShort4, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32_FLOAT:
                return(LOAD_SCANLINE <XMFLOAT2>(sizeof(float) * 2, XMLoadFloat2, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32_UINT:
                return(LOAD_SCANLINE <XMUINT2>(sizeof(uint) * 2, XMLoadUInt2, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_R32G32_SINT:
                return(LOAD_SCANLINE <XMINT2>(sizeof(int) * 2, XMLoadSInt2, ref pSource, ref pDestination));

            case DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
            {
                ulong psize = sizeof(float) + sizeof(uint);
                if (size > psize)
                {
                    var pfloatArray = TexUtils.CopyToTypeArray <float, byte>(pSource, sizeof(byte), sizeof(float));
                    int k           = 0;
                    for (int icount = 0; icount < (int)(size - psize + 1); icount += (int)psize)
                    {
                        if (pDestination.Length < icount)
                        {
                            break;
                        }
                        pDestination[icount] = new XMVECTOR
                        {
                            r = pfloatArray[0],
                            g = pfloatArray[k + 1],
                            b = 0.0f,
                            a = 1.0f
                        };

                        k += 2;
                    }
                    return(true);
                }
            }
                return(false);
            }
            pDestination = null;
            return(false);
        }
예제 #2
0
        public static ScratchImage LoadFromFile(string pathToFile, List <OPTION> options)
        {
            FileInfo fInfo = new FileInfo(pathToFile);

            if (!fInfo.Exists)
            {
                return(null);
            }
            ulong              width                    = 0;
            ulong              height                   = 0;
            ulong              mipLevels                = 0;
            DXGI_FORMAT        format                   = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;
            TEX_FILTER_FLAGS   dwFilter                 = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT;
            TEX_FILTER_FLAGS   dwSRGB                   = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT;
            TEX_FILTER_FLAGS   dwConvert                = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT;
            TEX_COMPRESS_FLAGS dwCompress               = TEX_COMPRESS_FLAGS.TEX_COMPRESS_DEFAULT;
            TEX_FILTER_FLAGS   dwFilterOpts             = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT;
            ulong              fileType                 = CODEC_DDS;
            float              alphaThreshold           = TEX_THRESHOLD_DEFAULT;
            float              alphaWeight              = 1.0f;
            CNMAP_FLAGS        dwNormalMap              = CNMAP_FLAGS.CNMAP_DEFAULT;
            float              nmapAmplitude            = 1.0f;
            float              wicQuality               = -1.0f;
            ulong              colorKey                 = 0;
            ulong              dwRotateColor            = 0;
            float              paperWhiteNits           = 200.0f;
            float              preserveAlphaCoverageRef = 0.0f;

            uint[] swizzleElements = { 0, 1, 2, 3 };

            ulong dwOptions = 0;

            foreach (OPTION opt in options)
            {
                switch (opt.option)
                {
                case OPTIONS.OPT_WIDTH:
                {
                    if (!ulong.TryParse(opt.value, out width))
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_HEIGHT:
                {
                    if (!ulong.TryParse(opt.value, out height))
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_MIPLEVELS:
                {
                    if (!ulong.TryParse(opt.value, out mipLevels))
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_FORMAT:
                {
                    format = (DXGI_FORMAT)LookupByName(opt.value, pFormats);
                    if (format == DXGI_FORMAT.DXGI_FORMAT_UNKNOWN)
                    {
                        format = (DXGI_FORMAT)LookupByName(opt.value, pFormatAliases);
                        if (format == DXGI_FORMAT.DXGI_FORMAT_UNKNOWN)
                        {
                            return(null);
                        }
                    }
                }
                break;

                case OPTIONS.OPT_FILTER:
                {
                    dwFilter = (TEX_FILTER_FLAGS)LookupByName(opt.value, pFilters);
                    if (dwFilter == TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_ROTATE_COLOR:
                {
                    dwRotateColor = LookupByName(opt.value, pRotateColor);
                    if (dwRotateColor == 0)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_SRGBI:
                    dwSRGB |= TEX_FILTER_FLAGS.TEX_FILTER_SRGB_IN;
                    break;

                case OPTIONS.OPT_SRGBO:
                    dwSRGB |= TEX_FILTER_FLAGS.TEX_FILTER_SRGB_OUT;
                    break;

                case OPTIONS.OPT_SRGB:
                    dwSRGB |= TEX_FILTER_FLAGS.TEX_FILTER_SRGB;
                    break;

                case OPTIONS.OPT_SEPALPHA:
                    dwFilterOpts |= TEX_FILTER_FLAGS.TEX_FILTER_SEPARATE_ALPHA;
                    break;

                case OPTIONS.OPT_NO_WIC:
                    dwFilterOpts |= TEX_FILTER_FLAGS.TEX_FILTER_FORCE_NON_WIC;
                    break;

                //case OPTIONS.OPT_FILETYPE:
                //    {
                //        fileType = LookupByName(opt.value, pSaveFileTypes);
                //        if (fileType == 0)
                //            return null;
                //    }
                //    break;
                case OPTIONS.OPT_PREMUL_ALPHA:
                {
                    if (TexUtils.HasFlag(dwOptions, 1UL << (int)OPTIONS.OPT_DEMUL_ALPHA))
                    {
                        return(null);
                    }
                    //dwOptions |= (1UL << (int)OPTIONS.OPT_PREMUL_ALPHA);
                }
                break;

                case OPTIONS.OPT_DEMUL_ALPHA:
                {
                    if (TexUtils.HasFlag(dwOptions, 1UL << (int)OPTIONS.OPT_PREMUL_ALPHA))
                    {
                        return(null);
                    }
                    //dwOptions |= (1UL << (int)OPTIONS.OPT_DEMUL_ALPHA);
                }
                break;

                case OPTIONS.OPT_TA_WRAP:
                {
                    if (TexUtils.HasFlag(dwFilterOpts, TEX_FILTER_FLAGS.TEX_FILTER_MIRROR))
                    {
                        return(null);
                    }
                    dwFilterOpts |= TEX_FILTER_FLAGS.TEX_FILTER_WRAP;
                }
                break;

                case OPTIONS.OPT_TA_MIRROR:
                {
                    if (TexUtils.HasFlag(dwFilterOpts, TEX_FILTER_FLAGS.TEX_FILTER_WRAP))
                    {
                        return(null);
                    }
                    dwFilterOpts |= TEX_FILTER_FLAGS.TEX_FILTER_MIRROR;
                }
                break;

                case OPTIONS.OPT_NORMAL_MAP:
                {
                    dwNormalMap = CNMAP_FLAGS.CNMAP_DEFAULT;

                    if (opt.value.Contains('l'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_CHANNEL_LUMINANCE;
                    }
                    else if (opt.value.Contains('r'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_CHANNEL_RED;
                    }
                    else if (opt.value.Contains('g'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_CHANNEL_GREEN;
                    }
                    else if (opt.value.Contains('b'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_CHANNEL_BLUE;
                    }
                    else if (opt.value.Contains('a'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_CHANNEL_ALPHA;
                    }
                    else
                    {
                        return(null);
                    }

                    if (opt.value.Contains('m'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_MIRROR;
                    }
                    else
                    {
                        if (opt.value.Contains('u'))
                        {
                            dwNormalMap |= CNMAP_FLAGS.CNMAP_MIRROR_U;
                        }
                        if (opt.value.Contains('v'))
                        {
                            dwNormalMap |= CNMAP_FLAGS.CNMAP_MIRROR_V;
                        }
                    }

                    if (opt.value.Contains('i'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_INVERT_SIGN;
                    }
                    if (opt.value.Contains('o'))
                    {
                        dwNormalMap |= CNMAP_FLAGS.CNMAP_COMPUTE_OCCLUSION;
                    }
                }
                break;

                case OPTIONS.OPT_NORMAL_MAP_AMPLITUDE:
                {
                    if (dwNormalMap == 0)
                    {
                        return(null);
                    }
                    else if (!float.TryParse(opt.value, out nmapAmplitude))
                    {
                        return(null);
                    }
                    else if (nmapAmplitude < 0.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_ALPHA_THRESHOLD:
                {
                    if (!float.TryParse(opt.value, out alphaThreshold))
                    {
                        return(null);
                    }
                    else if (alphaThreshold < 0.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_ALPHA_WEIGHT:
                {
                    if (!float.TryParse(opt.value, out alphaWeight))
                    {
                        return(null);
                    }
                    else if (alphaWeight < 0.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_BC_COMPRESS:
                {
                    dwCompress = TEX_COMPRESS_FLAGS.TEX_COMPRESS_DEFAULT;

                    bool found = false;
                    if (opt.value.Contains('u'))
                    {
                        dwCompress |= TEX_COMPRESS_FLAGS.TEX_COMPRESS_UNIFORM;
                        found       = true;
                    }
                    if (opt.value.Contains('d'))
                    {
                        dwCompress |= TEX_COMPRESS_FLAGS.TEX_COMPRESS_DITHER;
                        found       = true;
                    }
                    if (opt.value.Contains('q'))
                    {
                        dwCompress |= TEX_COMPRESS_FLAGS.TEX_COMPRESS_BC7_QUICK;
                        found       = true;
                    }
                    if (opt.value.Contains('x'))
                    {
                        dwCompress |= TEX_COMPRESS_FLAGS.TEX_COMPRESS_BC7_USE_3SUBSETS;
                        found       = true;
                    }

                    if (TexUtils.HasFlag(dwCompress, TEX_COMPRESS_FLAGS.TEX_COMPRESS_BC7_USE_3SUBSETS | TEX_COMPRESS_FLAGS.TEX_COMPRESS_BC7_QUICK))
                    {
                        return(null);
                    }

                    if (!found)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_WIC_QUALITY:
                {
                    if (!float.TryParse(opt.value, out wicQuality))
                    {
                        return(null);
                    }
                    else if (wicQuality < 0.0f || wicQuality > 1.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_COLORKEY:
                {
                    if (!ulong.TryParse(opt.value, out colorKey))
                    {
                        if (!ulong.TryParse(opt.value, System.Globalization.NumberStyles.HexNumber, null, out colorKey))
                        {
                            return(null);
                        }
                    }
                    colorKey &= 0xFFFFFF;
                }
                break;

                case OPTIONS.OPT_X2_BIAS:
                    dwConvert |= TEX_FILTER_FLAGS.TEX_FILTER_FLOAT_X2BIAS;
                    break;

                case OPTIONS.OPT_PAPER_WHITE_NITS:
                {
                    if (!float.TryParse(opt.value, out paperWhiteNits))
                    {
                        return(null);
                    }
                    else if (paperWhiteNits > 10000.0f || paperWhiteNits <= 0.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_PRESERVE_ALPHA_COVERAGE:
                {
                    if (float.TryParse(opt.value, out preserveAlphaCoverageRef))
                    {
                        return(null);
                    }
                    else if (preserveAlphaCoverageRef < 0.0f || preserveAlphaCoverageRef > 1.0f)
                    {
                        return(null);
                    }
                }
                break;

                case OPTIONS.OPT_SWIZZLE:
                {
                    if (opt.value == null || opt.value.Length > 4)
                    {
                        return(null);
                    }
                    else if (!ParseSwizzleMask(opt.value, out swizzleElements))
                    {
                        return(null);
                    }
                }
                break;
                }
            }

            var fileTypeName = LookupByValue(fileType, pSaveFileTypes);

            if (fileType != CODEC_DDS)
            {
                mipLevels = 1;
            }

            var ext = Path.GetExtension(fInfo.FullName).ToLower();

            TexMetadata  info = new TexMetadata();
            ScratchImage image;

            if (ext == ".dds")
            {
                DDS_FLAGS ddsFlags = DDS_FLAGS.DDS_FLAGS_ALLOW_LARGE_FILES;
                if (TexUtils.HasFlag(dwOptions, 1U << (int)OPTIONS.OPT_DDS_DWORD_ALIGN))
                {
                    ddsFlags |= DDS_FLAGS.DDS_FLAGS_LEGACY_DWORD;
                }
                if (TexUtils.HasFlag(dwOptions, 1U << (int)OPTIONS.OPT_EXPAND_LUMINANCE))
                {
                    ddsFlags |= DDS_FLAGS.DDS_FLAGS_EXPAND_LUMINANCE;
                }
                if (TexUtils.HasFlag(dwOptions, 1U << (int)OPTIONS.OPT_DDS_BAD_DXTN_TAILS))
                {
                    ddsFlags |= DDS_FLAGS.DDS_FLAGS_BAD_DXTN_TAILS;
                }

                image = LoadFromDDSFile(pathToFile, ddsFlags, ref info);

                if (image == null)
                {
                    return(null);
                }

                if (IsTypeless(info.format))
                {
                    if (TexUtils.HasFlag(dwOptions, 1U << (int)OPTIONS.OPT_TYPELESS_UNORM))
                    {
                        info.format = MakeTypelessUNORM(info.format);
                    }
                    else if (TexUtils.HasFlag(dwOptions, 1U << (int)OPTIONS.OPT_TYPELESS_FLOAT))
                    {
                        info.format = MakeTypelessFLOAT(info.format);
                    }

                    if (IsTypeless(info.format))
                    {
                        return(null);
                    }

                    image.OverrideFormat(info.format);
                }
            }
            else if (ext == ".bmp")
            {
                image = LoadFromBMPEx(pathToFile, WIC_FLAGS.WIC_FLAGS_NONE | (WIC_FLAGS)dwFilter, ref info);

                if (image == null)
                {
                    return(null);
                }
            }
            else if (ext == ".tga")
            {
                image = LoadFromTGAFile(pathToFile, TGA_FLAGS.TGA_FLAGS_NONE, ref info);
                if (image == null)
                {
                    return(null);
                }
            }
            else if (ext == ".hdr")
            {
                image = LoadFromHDRFile(pathToFile, ref info);
                if (image == null)
                {
                    return(null);
                }
            }
            else if (ext == ".ppm")
            {
                image = LoadFromPortablePixMap(pathToFile, ref info);
                if (image == null)
                {
                    return(null);
                }
            }
            else if (ext == ".pfm")
            {
                image = LoadFromPortablePixMapHDR(pathToFile, ref info);
                if (image == null)
                {
                    return(null);
                }
            }
            else if (ext == ".exr")
            {
                image = LoadFromEXRFile(pathToFile, ref info);
                if (image == null)
                {
                    return(null);
                }
            }
            else
            {
                WIC_FLAGS wicFlags = WIC_FLAGS.WIC_FLAGS_NONE | (WIC_FLAGS)dwFilter;
                if (fileType == CODEC_DDS)
                {
                    wicFlags |= WIC_FLAGS.WIC_FLAGS_ALL_FRAMES;
                }

                image = LoadFromWICFile(pathToFile, ref info);
                if (image == null)
                {
                    return(null);
                }
            }

            return(null);
        }