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)); }
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); }
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); } }
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>(); }
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); }
// 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); }
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); }
public TexturePalette(uint textureId, PaletteChanges paletteChanges = null) { TextureId = textureId; PaletteChanges = paletteChanges; }
public SurfaceTexturePalette(uint origSurfaceId, uint surfaceTextureId, PaletteChanges paletteChanges = null) { OrigSurfaceId = origSurfaceId; SurfaceTextureId = surfaceTextureId; PaletteChanges = paletteChanges; }
public GfxObjTexturePalette(uint gfxObjId, Dictionary <uint, uint> textureChanges = null, PaletteChanges paletteChanges = null) { GfxObjId = gfxObjId; TextureChanges = textureChanges; PaletteChanges = paletteChanges; }