예제 #1
0
        public static Texture2D Get(uint surfaceID, uint surfaceTextureID, PaletteChanges paletteChanges)
        {
            if (surfaceID >> 24 != 0x8)
            {
                return(Get(surfaceID));
            }

            var surface = DatManager.PortalDat.ReadFromDat <Surface>(surfaceID);

            if (surface.ColorValue != 0)
            {
                // swatch
                var swatch = new Texture2D(GameView.Instance.GraphicsDevice, 1, 1);
                var a      = surface.ColorValue >> 24;
                var r      = (surface.ColorValue >> 16) & 0xFF;
                var g      = (surface.ColorValue >> 8) & 0xFF;
                var b      = surface.ColorValue & 0xFF;
                a = 0;
                swatch.SetDataAsync(new Microsoft.Xna.Framework.Color[] { new Microsoft.Xna.Framework.Color(r, g, b, a) });
                return(swatch);
            }

            var surfaceTexture = DatManager.PortalDat.ReadFromDat <SurfaceTexture>(surfaceTextureID);

            return(GetTexture(surfaceTexture.Textures[0], surface, paletteChanges));
        }
예제 #2
0
        private static Texture2D GetTexture(uint textureID, Surface surface = null, PaletteChanges paletteChanges = null, bool useCache = true)
        {
            //Console.WriteLine($"-> GetTexture({textureID:X8})");

            var texturePalette = new TexturePalette(textureID, paletteChanges);

            if (useCache && Textures.TryGetValue(texturePalette, out var cached))
            {
                return(cached);
            }

            var texture = LoadTexture(textureID, false, surface, paletteChanges);

            if (useCache)
            {
                Textures.Add(texturePalette, texture);
            }
            else
            {
                Uncached.Add(texture);
            }

            return(texture);
        }
예제 #3
0
        public void BuildStatic(GfxObj gfxObj, Dictionary <TextureFormat, TextureAtlasChain> textureAtlasChains, Dictionary <uint, uint> textureChanges = null, PaletteChanges paletteChanges = null)
        {
            BaseFormats_Solid = new Dictionary <TextureFormatChain, GfxObjInstance_TextureFormat>();

            BaseFormats_Alpha = new Dictionary <TextureFormatChain, GfxObjInstance_TextureFormat>();

            Vertices = new List <VertexPositionNormalTextures>();

            var vertexTable = new Dictionary <VertexPositionNormalTextures, short>();

            foreach (var poly in gfxObj.Polygons)
            {
                // get actual transformed texture -- cannot rely on poly.Texture original format
                var surfaceIdx = poly._polygon.PosSurface;
                var surfaceID  = gfxObj._gfxObj.Surfaces[surfaceIdx];

                var textureId = TextureCache.GetSurfaceTextureID(surfaceID, textureChanges);
                var texture   = TextureCache.Get(surfaceID, textureId, paletteChanges);

                var textureFormat = new TextureFormat(texture.Format, texture.Width, texture.Height, gfxObj.HasWrappingUVs);

                if (!textureAtlasChains.TryGetValue(textureFormat, out var textureAtlasChain))
                {
                    textureAtlasChain = new TextureAtlasChain(textureFormat);
                    textureAtlasChains.Add(textureFormat, textureAtlasChain);
                }

                var surface = DatManager.PortalDat.ReadFromDat <ACE.DatLoader.FileTypes.Surface>(surfaceID);

                var surfaceTextureId = TextureCache.GetSurfaceTextureID(surfaceID, textureChanges);

                var surfaceTexturePalette = new SurfaceTexturePalette(surfaceID, surfaceTextureId, paletteChanges);

                var atlasIdx = textureAtlasChain.GetAtlasIdx(surfaceTexturePalette);

                var textureAtlas = textureAtlasChain.TextureAtlases[atlasIdx];

                var baseFormats = (surface.Type & AlphaSurfaceTypes) == 0 ? BaseFormats_Solid : BaseFormats_Alpha;

                if (!baseFormats.TryGetValue(textureAtlas.TextureFormatChain, out var baseFormat))
                {
                    baseFormat = new GfxObjInstance_TextureFormat(textureAtlas);
                    baseFormats.Add(textureAtlas.TextureFormatChain, baseFormat);
                }

                var textureIdx = textureAtlas.Textures[surfaceTexturePalette];

                baseFormat.AddPolygon(poly, gfxObj.VertexArray, surfaceID, Vertices, vertexTable, textureIdx);
            }
        }
예제 #4
0
        public GfxObjInstance_Shared(GfxObj gfxObj, Dictionary <TextureFormat, TextureAtlasChain> textureAtlasChains, Dictionary <uint, uint> textureChanges = null, PaletteChanges paletteChanges = null)
        {
            GfxObj = gfxObj;

            BuildStatic(gfxObj, textureAtlasChains, textureChanges, paletteChanges);

            Instances = new List <VertexInstance>();
        }
예제 #5
0
        private static Texture2D LoadTexture(uint textureID, bool useDummy = false, Surface surface = null, PaletteChanges paletteChanges = null)
        {
            //Console.WriteLine($"--> TextureCache.LoadTexture({textureID:X8})");

            if (textureID >> 24 == 0x04)
            {
                return(LoadPalette(textureID));
            }
            else if (textureID >> 24 == 0x0F)
            {
                return(LoadPaletteSet(textureID));
            }

            var isClipMap = surface != null && surface.Type.HasFlag(SurfaceType.Base1ClipMap);

            MainWindow.Instance.Status.WriteLine($"Loading texture {textureID:X8}");

            var texture = DatManager.PortalDat.ReadFromDat <ACE.DatLoader.FileTypes.Texture>(textureID);

            if (texture.SourceData == null)
            {
                texture = DatManager.HighResDat.ReadFromDat <ACE.DatLoader.FileTypes.Texture>(textureID);
            }

            var surfaceFormat = SurfaceFormat.Color;

            switch (texture.Format)
            {
            case SurfacePixelFormat.PFID_DXT1:
                surfaceFormat = SurfaceFormat.Dxt1;
                break;

            case SurfacePixelFormat.PFID_DXT3:
                surfaceFormat = SurfaceFormat.Dxt3;
                break;

            case SurfacePixelFormat.PFID_DXT5:
                //if (!isClipMap)
                surfaceFormat = SurfaceFormat.Dxt5;
                break;

            case SurfacePixelFormat.PFID_CUSTOM_LSCAPE_ALPHA:
            case SurfacePixelFormat.PFID_A8:
            case SurfacePixelFormat.PFID_P8:        // indexed color
                surfaceFormat = SurfaceFormat.Alpha8;
                break;
            }

            var width  = texture.Width;
            var height = texture.Height;

            var data = new byte[texture.SourceData.Length];

            Array.Copy(texture.SourceData, data, data.Length);  // fixme: multiple rgb reversals

            if (surfaceFormat == SurfaceFormat.Color)
            {
                switch (texture.Format)
                {
                case SurfacePixelFormat.PFID_R8G8B8:
                case SurfacePixelFormat.PFID_CUSTOM_LSCAPE_R8G8B8:
                    data = AddAlpha(data);
                    break;

                case SurfacePixelFormat.PFID_INDEX16:
                    data = IndexToColor(texture, isClipMap, paletteChanges);
                    break;

                case SurfacePixelFormat.PFID_CUSTOM_RAW_JPEG:
                case SurfacePixelFormat.PFID_R5G6B5:
                case SurfacePixelFormat.PFID_A4R4G4B4:
                    //case SurfacePixelFormat.PFID_DXT5:
                    var bitmap = texture.GetBitmap();
                    var _tex   = GetTexture2DFromBitmap(GameView.Instance.GraphicsDevice, bitmap);
                    //if (isClipMap)
                    //AdjustClip(_tex);
                    return(_tex);

                case SurfacePixelFormat.PFID_A8R8G8B8:
                    ConvertToABGR(data);
                    break;
                }
            }

            Texture2D tex = null;

            if (useDummy)
            {
                if (surfaceFormat == SurfaceFormat.Alpha8)
                {
                    tex = new Texture2D(GameView.Instance.GraphicsDevice, 1, 1, false, SurfaceFormat.Alpha8);
                    var alpha = new byte[1];
                    alpha[0] = 255;
                    tex.SetDataAsync(alpha);
                }
                else
                {
                    tex = new Texture2D(GameView.Instance.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
                    var color = new Microsoft.Xna.Framework.Color[1];
                    color[0].A = data[3];
                    color[0].R = data[2];
                    color[0].G = data[1];
                    color[0].B = data[0];
                    tex.SetDataAsync(color);
                }
            }
            else
            {
                if (UseMipMaps && surfaceFormat == SurfaceFormat.Color && texture.Width == texture.Height)
                {
                    tex = GenerateMipMaps(data, texture.Width);
                }
                else
                {
                    tex = new Texture2D(GameView.Instance.GraphicsDevice, texture.Width, texture.Height, false, surfaceFormat);
                    tex.SetDataAsync(data);
                }
            }
            return(tex);
        }
예제 #6
0
        // 0x08 - Surface - contains a 0x05 SurfaceTexture, along with additional type info (clipmask)
        // 0x05 - SurfaceTexture - contains a list of 0x06 textures
        // 0x06 - Texture - image format and data

        public static Texture2D Get(uint fileID, Dictionary <uint, uint> textureChanges = null, PaletteChanges paletteChanges = null, bool useCache = true)
        {
            //Console.WriteLine($"TextureCache.Get({fileID:X8})");

            if (fileID >> 24 == 0x01)
            {
                // gfxobj
                var gfxObj = DatManager.PortalDat.ReadFromDat <ACE.DatLoader.FileTypes.GfxObj>(fileID);

                var     surfaceID = gfxObj.Surfaces[0];
                Surface surface   = DatManager.PortalDat.ReadFromDat <Surface>(surfaceID);

                if (surface.ColorValue != 0)
                {
                    // swatch
                    var swatch = new Texture2D(GameView.Instance.GraphicsDevice, 1, 1);
                    var a      = surface.ColorValue >> 24;
                    var r      = (surface.ColorValue >> 16) & 0xFF;
                    var g      = (surface.ColorValue >> 8) & 0xFF;
                    var b      = surface.ColorValue & 0xFF;
                    swatch.SetDataAsync(new Microsoft.Xna.Framework.Color[] { new Microsoft.Xna.Framework.Color(r, g, b, a) });
                    return(swatch);
                }

                var textureId = surface.OrigTextureId;

                if (textureChanges != null && textureChanges.TryGetValue(textureId, out var newTextureId))
                {
                    textureId = newTextureId;
                }

                var surfaceTexture = DatManager.PortalDat.ReadFromDat <SurfaceTexture>(textureId);

                return(GetTexture(surfaceTexture.Textures[0], surface));
            }
            else if (fileID >> 24 == 0x04)
            {
                // palette
                return(GetTexture(fileID));
            }
            else if (fileID >> 24 == 0x0F)
            {
                // palette set
                return(GetTexture(fileID));
            }

            else if (fileID >> 24 == 0x05)
            {
                // surface texture
                var surfaceTexture = DatManager.PortalDat.ReadFromDat <SurfaceTexture>(fileID);

                return(GetTexture(surfaceTexture.Textures[0], null, paletteChanges, useCache));
            }
            else if (fileID >> 24 == 0x06)
            {
                // texture
                return(GetTexture(fileID, null, paletteChanges, useCache));
            }

            else if (fileID >> 24 == 0x08)
            {
                // surface
                var surface = DatManager.PortalDat.ReadFromDat <Surface>(fileID);

                if (surface.ColorValue != 0)
                {
                    // swatch
                    var swatch = new Texture2D(GameView.Instance.GraphicsDevice, 1, 1);
                    var a      = surface.ColorValue >> 24;
                    var r      = (surface.ColorValue >> 16) & 0xFF;
                    var g      = (surface.ColorValue >> 8) & 0xFF;
                    var b      = surface.ColorValue & 0xFF;
                    a = 0;
                    swatch.SetDataAsync(new Microsoft.Xna.Framework.Color[] { new Microsoft.Xna.Framework.Color(r, g, b, a) });
                    return(swatch);
                }

                var textureId = surface.OrigTextureId;

                if (textureChanges != null && textureChanges.TryGetValue(textureId, out var newTextureId))
                {
                    textureId = newTextureId;
                }

                var surfaceTexture = DatManager.PortalDat.ReadFromDat <SurfaceTexture>(textureId);

                return(GetTexture(surfaceTexture.Textures[0], surface, paletteChanges, useCache));
            }
            return(null);
        }
예제 #7
0
        private static byte[] IndexToColor(ACE.DatLoader.FileTypes.Texture texture, bool isClipMap = false, PaletteChanges paletteChanges = null)
        {
            var colors = GetColors(texture);

            var palette = DatManager.PortalDat.ReadFromDat <Palette>((uint)texture.DefaultPaletteId);

            // Make a copy of the Palette Colors, so we don't inadvertently save them back to the dat File Cache
            var paletteColors = palette.Colors.ToList();

            // Apply any custom palette colors, if any, to our loaded palette (note, this may be all of them!)
            if (paletteChanges != null)
            {
                for (var i = 0; i < paletteChanges.CloSubPalettes.Count; i++)
                {
                    var subpalette = paletteChanges.CloSubPalettes[i];

                    var newPalette = DatManager.PortalDat.ReadFromDat <Palette>(paletteChanges.PaletteIds[i]);

                    foreach (var range in subpalette.Ranges)
                    {
                        var offset    = (int)range.Offset;
                        var numColors = (int)range.NumColors;

                        for (var j = 0; j < numColors; j++)
                        {
                            paletteColors[j + offset] = newPalette.Colors[j + offset];
                        }
                    }
                }
            }

            var output = new byte[texture.Width * texture.Height * 4];

            for (int i = 0; i < texture.Height; i++)
            {
                for (int j = 0; j < texture.Width; j++)
                {
                    int idx          = (i * texture.Width) + j;
                    var color        = colors[idx];
                    var paletteColor = paletteColors[color];

                    byte a = Convert.ToByte((paletteColor & 0xFF000000) >> 24);
                    byte r = Convert.ToByte((paletteColor & 0xFF0000) >> 16);
                    byte g = Convert.ToByte((paletteColor & 0xFF00) >> 8);
                    byte b = Convert.ToByte(paletteColor & 0xFF);

                    if (isClipMap && color < 8)
                    {
                        r = g = b = a = 0;
                    }

                    output[idx * 4]     = r;
                    output[idx * 4 + 1] = g;
                    output[idx * 4 + 2] = b;
                    output[idx * 4 + 3] = a;
                }
            }
            return(output);
        }
예제 #8
0
 public TexturePalette(uint textureId, PaletteChanges paletteChanges = null)
 {
     TextureId      = textureId;
     PaletteChanges = paletteChanges;
 }
예제 #9
0
 public SurfaceTexturePalette(uint origSurfaceId, uint surfaceTextureId, PaletteChanges paletteChanges = null)
 {
     OrigSurfaceId    = origSurfaceId;
     SurfaceTextureId = surfaceTextureId;
     PaletteChanges   = paletteChanges;
 }
예제 #10
0
 public GfxObjTexturePalette(uint gfxObjId, Dictionary <uint, uint> textureChanges = null, PaletteChanges paletteChanges = null)
 {
     GfxObjId       = gfxObjId;
     TextureChanges = textureChanges;
     PaletteChanges = paletteChanges;
 }