internal override ModelBase Serialize() { return(new GMLinuxOptionsModel { id = Id, name = "Linux", option_linux_display_name = DisplayName, option_linux_version = Version, option_linux_maintainer_email = MaintainerEmail, option_linux_homepage = Homepage, option_linux_short_desc = ShortDescription, option_linux_long_desc = LongDescription, option_linux_splash_screen = SplashScreen, option_linux_display_splash = DisplaySplash, option_linux_icon = Icon, option_linux_start_fullscreen = StartFullscreen, option_linux_allow_fullscreen = AllowFullscreen, option_linux_interpolate_pixels = InterpolatePixels, option_linux_display_cursor = DisplayCursor, option_linux_sync = Vsync, option_linux_resize_window = ResizeWindow, option_linux_scale = ScaleMode, option_linux_texture_page = TexturePage.ToString(), option_linux_enable_steam = EnableSteam, option_linux_disable_sandbox = DisableSandbox }); }
internal override ModelBase Serialize() { return(new GMMacOptionsModel { id = Id, name = "macOS", option_mac_display_name = DisplayName, option_mac_app_id = AppId, option_mac_version = Version, option_mac_output_dir = OutputDirectory, option_mac_team_id = TeamId, option_mac_signing_identity = SigningIdentity, option_mac_copyright = Copyright, option_mac_splash_png = SplashPng, option_mac_icon_png = IconPng, option_mac_menu_dock = MenuDock, option_mac_display_cursor = DisplayCursor, option_mac_start_fullscreen = StartFullscreen, option_mac_allow_fullscreen = AllowFullscreenSwitching, option_mac_interpolate_pixels = InterpolatePixels, option_mac_vsync = Vsync, option_mac_resize_window = ResizeWindow, option_mac_scale = Scale, option_mac_texture_page = TexturePage.ToString(), option_mac_build_app_store = AppStore, option_mac_allow_incoming_network = AllowIncomingNetwork, option_mac_allow_outgoing_network = AllowOutgoingNetwork, option_mac_app_category = AppCategory, option_mac_enable_steam = EnableSteam, option_mac_disable_sandbox = DisableSandbox }); }
internal override ModelBase Serialize() { return(new GMWindowsOptionsModel { id = Id, name = "Windows", option_windows_display_name = DisplayName, option_windows_executable_name = ExecutableName, option_windows_version = Version, option_windows_company_info = CompanyInfo, option_windows_product_info = ProductInfo, option_windows_copyright_info = CopyrightInfo, option_windows_description_info = DescriptionInfo, option_windows_display_cursor = DisplayCursor, option_windows_icon = Icon, option_windows_save_location = SaveLocation, option_windows_splash_screen = SplashScreen, option_windows_use_splash = UseSplash, option_windows_start_fullscreen = StartFullscreen, option_windows_allow_fullscreen_switching = AllowFullscreenSwitching, option_windows_interpolate_pixels = InterpolatePixels, option_windows_vsync = Vsync, option_windows_resize_window = ResizeWindow, option_windows_borderless = Borderless, option_windows_scale = Scale, option_windows_sleep_margin = SleepMargin, option_windows_texture_page = TexturePage.ToString(), option_windows_installer_finished = InstallerFinished, option_windows_installer_header = InstallerHeader, option_windows_license = License, option_windows_nsis_file = NsisFile, option_windows_enable_steam = EnableSteam, option_windows_disable_sandbox = DisableSandbox }); }
protected TexturePage GetTexturePage(ushort tPage) { TexturePage texturePage = new TexturePage { tPage = tPage, tp = (tPage >> 7) & 0x001, //(tPage >> 7) & 0x003, abr = 0, //(tPage >> 5) & 0x003, x = (tPage << 6) & 0x1c0, //(tPage << 6) & 0x7c0, y = (tPage << 4) & 0x100, //((tPage << 4) & 0x100) + ((tPage >> 2) & 0x200), pixels = null }; ushort[,] pixels = new ushort[_ImageHeight, _ImageWidth]; int scaledX = texturePage.x; int scaledY = texturePage.y; for (int y = 0; y < _ImageHeight; y++) { int yOffset = (scaledY + y) * _TotalWidth; for (int x = 0; x < _ImageWidth;) { int xOffset = scaledX; // / 2; try { if (texturePage.tp == 0) // 4 bit { xOffset += x / 4; ushort val = _TextureData[yOffset + xOffset]; pixels[y, x++] = (ushort)(val & 0x000F); pixels[y, x++] = (ushort)((val & 0x00F0) >> 4); pixels[y, x++] = (ushort)((val & 0x0F00) >> 8); pixels[y, x++] = (ushort)((val & 0xF000) >> 12); } else if (texturePage.tp == 1) // 8 bit { xOffset += x; xOffset /= 2; ushort val = _TextureData[yOffset + xOffset]; pixels[y, x++] = (ushort)(val & 0x00FF); pixels[y, x++] = (ushort)((val & 0xFF00) >> 8); } else if (texturePage.tp == 2) // 16 bit { xOffset += x; ushort val = _TextureData[yOffset + xOffset]; pixels[y, x++] = val; } } catch (Exception ex) { } } } texturePage.pixels = pixels; return(texturePage); }
public RenderingTextureAllocator(RenderingDevice device, Description description) { logger.Info("Rendering texture allocated of size \"" + description.Size + "\"."); Pages = new TexturePage[description.Size.Z]; for (int i = 0; i < description.Size.Z; ++i) { Pages[i] = new TexturePage(new VectorInt2(description.Size.X, description.Size.Y)); } Size = description.Size; }
public TextureRegion(int x, int y, TexturePage page, TextureBuffer buffer) { this.x = x; this.y = y; this.page = page; this.buffer = buffer; width = page.width; bytesPerPixel = TextureUtil.GetBytesPerPixel(page.format); bytes = page.bytes; floatConverter = new ByteToFloatConverter { bytes = page.bytes }; }
protected Color[] GetGreyscalePalette(int index) { TexturePage tPage = _TPages[(ushort)index]; int paletteSize = (tPage.tp == 0) ? 16 : 256; Color[] greyPalette = new Color[paletteSize]; for (int i = 0; i < paletteSize; i++) { int luma = (i * 256) / paletteSize; greyPalette[i] = Color.FromArgb(luma, luma, luma); } return(greyPalette); }
protected Bitmap GetTextureAsBitmap(int index, Color[] palette) { Bitmap tex = new Bitmap(_ImageWidth, _ImageHeight); TexturePage texturePage = _TPages[index]; for (int y = 0; y < _ImageHeight; y++) { for (int x = 0; x < _ImageWidth; x++) { int pixel = texturePage.pixels[y, x]; tex.SetPixel(x, y, palette[pixel]); } } return(tex); }
public TexturePage Alloc(string name, int width, int height, TextureFormat format) { int num = Clamp(width); int num2 = Clamp(height); int num3 = Time.frameCount % 2; foreach (TexturePage item in activePages[num3]) { freePages.Add(item); } activePages[num3].Clear(); for (int i = 0; i < freePages.Count; i++) { TexturePage texturePage = freePages[i]; if (texturePage.width == num && texturePage.height == num2 && texturePage.format == format) { freePages.RemoveAt(i); texturePage.SetName(name); return(texturePage); } } return(new TexturePage(name, num, num2, format)); }
internal override ModelBase Serialize() { return(new GMHtml5OptionsModel { id = Id, name = "HTML5", option_html5_allow_fullscreen = AllowFullscreen, option_html5_browser_title = BrowserTitle, option_html5_centregame = CentreGame, option_html5_display_cursor = DisplayCursor, option_html5_facebook_app_display_name = FacebookAppDisplayName, option_html5_facebook_id = FacebookId, option_html5_flurry_enable = FlurryEnable, option_html5_flurry_id = FlurryId, option_html5_foldername = FolderName, option_html5_google_analytics_enable = GoogleAnalyticsEnable, option_html5_google_tracking_id = GoogleTrackingId, option_html5_icon = Icon, option_html5_index = Index, option_html5_interpolate_pixels = InterpolatePixels, option_html5_jsprepend = JsPrepend, option_html5_loadingbar = LoadingBar, option_html5_localrunalert = LocalRunAlert, option_html5_outputdebugtoconsole = OutDebugToConsole, option_html5_outputname = OutputName, option_html5_scale = ScaleMode, option_html5_splash_png = SplashPng, option_html5_texture_page = TexturePage.ToString(), option_html5_usebuiltinfont = UseBuiltinFont, option_html5_usebuiltinparticles = UseBuiltinParticles, option_html5_usesplash = UseSplash, option_html5_use_facebook = UseFacebook, option_html5_version = Version, option_html5_webgl = WebGl }); }
public void BuildTexturesFromPolygonData(Gex3PlaystationPolygonTextureData[] texData, ushort[] texturePages, bool drawGreyScaleFirst, bool quantizeBounds, CDC.Objects.ExportOptions options) { if (_TPages == null) { List <TexturePage> tPages = new List <TexturePage>(); for (int i = 0; i < texturePages.Length; i++) { ushort tPage = (ushort)(texturePages[i] & 0x0000FFFFu); if (tPages.FindIndex(x => x.tPage == tPage) < 0) { tPages.Add(GetTexturePage(tPage)); } } _TPages = tPages.ToArray(); _TextureCount = _TPages.Length; _Textures = new Bitmap[_TPages.Length]; } // hashtable to store counts of palette usage Hashtable palettes = new Hashtable(); bool debugTextureCollisions = false; // initialize textures if (drawGreyScaleFirst) { for (int i = 0; i < _TextureCount; i++) { _Textures[i] = GetTextureAsBitmap(i, GetGreyscalePalette(i)); } } else { Color chromaKey = Color.FromArgb(1, 128, 128, 128); //Color chromaKey = Color.FromArgb(255, 128, 128, 128); for (int i = 0; i < _TextureCount; i++) { _Textures[i] = new Bitmap(_ImageWidth, _ImageHeight); for (int y = 0; y < _ImageHeight; y++) { for (int x = 0; x < _ImageWidth; x++) { _Textures[i].SetPixel(x, y, chromaKey); } } } } Dictionary <int, Dictionary <int, ulong> > handledPixels = new Dictionary <int, Dictionary <int, ulong> >(); //Dictionary<int, ulong> handledPixels = new Dictionary<int, ulong>(); // use the polygon data to colour in all possible parts of the textures foreach (Gex3PlaystationPolygonTextureData poly in texData) { TexturePage texturePage = _TPages[poly.textureID]; bool dumpPreviousTextureVersion = false; bool wrotePixels = false; List <byte[]> textureHashes = new List <byte[]>(); Bitmap previousTexture = (Bitmap)_Textures[poly.textureID].Clone(); Dictionary <int, ulong> polyPixelList = new Dictionary <int, ulong>(); if (handledPixels.ContainsKey(poly.textureID)) { polyPixelList = handledPixels[poly.textureID]; } int uMin = 255; int uMax = 0; int vMin = 255; int vMax = 0; Color[] palette = GetPalette(poly.textureID, poly.CLUT); //bool exportAllPaletteVariations = false; //if (exportAllPaletteVariations) //{ // if (!Directory.Exists("Texture_Debugging")) // { // Directory.CreateDirectory("Texture_Debugging"); // } // //string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-row_{1:X4}-column_{2:X4}-CLUT_{3:X4}.png", poly.textureID, poly.paletteColumn, poly.paletteRow, poly.CLUT); // string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-CLUT_{3:X4}-row_{1:X4}-column_{2:X4}.png", poly.textureID, poly.paletteColumn, poly.paletteRow, poly.CLUT); // if (!File.Exists(fileName)) // { // Bitmap currentVariation = GetTextureAsBitmap(poly.textureID, palette); // currentVariation.Save(fileName, ImageFormat.Png); // } //} if (options.UseEachUniqueTextureCLUTVariation) { CreateARGBTextureFromCLUTIfNew(poly.textureID, poly.CLUT, palette); } // some basic sanity-checking for bad palette information obtained via incorrect parsing of data bool paletteIsValid = true; //if ((poly.paletteColumn % 2) == 1) //{ // paletteIsValid = false; //} //int numTransparentColours = 0; //foreach (Color c in palette) //{ // if (c.A == 0) // { // numTransparentColours++; // } //} //if (numTransparentColours > 1) //{ // paletteIsValid = false; //} //if (!paletteIsValid) //{ // palette = GetGreyscalePalette(); // Console.WriteLine(string.Format("Invalid palette detected for texture ID {0}: row {1}, column {2}", poly.textureID, poly.paletteRow, poly.paletteColumn)); //} // get the rectangle defined by the minimum and maximum U and V coords foreach (int u in poly.u) { uMin = Math.Min(uMin, u); uMax = Math.Max(uMax, u); } foreach (int v in poly.v) { vMin = Math.Min(vMin, v); vMax = Math.Max(vMax, v); } int width = uMax - uMin; for (int b = 0; b < 8; b++) { if ((1 << b) >= width) { width = 1 << b; break; } } int height = vMax - vMin; for (int b = 0; b < 8; b++) { if ((1 << b) >= height) { height = 1 << b; break; } } // if specified, quantize the rectangle's boundaries //if (quantizeBounds) //{ // while ((uMin % width) > 0) // { // uMin--; // } // while ((uMax % width) > 0) // { // uMax++; // } // while ((vMin % height) > 0) // { // vMin--; // } // while ((vMax % height) > 0) // { // vMax++; // } // if (uMin < 0) // { // uMin = 0; // } // if (uMax > 256) // { // uMax = 256; // } // if (vMin < 0) // { // vMin = 0; // } // if (vMax > 256) // { // vMax = 256; // } //} //// if specified, quantize the rectangle's boundaries to a multiple of 16 if (quantizeBounds) { //int quantizeRes = 16; int quantizeRes = 16; while ((uMin % quantizeRes) > 0) { uMin--; } while ((uMax % quantizeRes) > 0) { uMax++; } while ((vMin % quantizeRes) > 0) { vMin--; } while ((vMax % quantizeRes) > 0) { vMax++; } if (uMin < 0) { uMin = 0; } if (uMax > 256) { uMax = 256; } if (vMin < 0) { vMin = 0; } if (vMax > 256) { vMax = 256; } } for (int y = vMin; y < vMax; y++) { for (int x = uMin; x < uMax; x++) { int dataOffset = (_ImageHeight * y) + x; int pixel = texturePage.pixels[y, x]; Color pixelColour = palette[pixel]; uint materialAlpha = (poly.materialColour & 0xFF000000) >> 24; //materialAlpha = 255; //if (materialAlpha < 255) //{ // pixelColour = Color.FromArgb((byte)materialAlpha, palette[pixel].R, palette[pixel].G, palette[pixel].B); //} //ulong checkPixels = ((ulong)materialAlpha << 56) | ((ulong)palette[pixel].R << 48) | ((ulong)palette[pixel].G << 40) // | ((ulong)palette[pixel].B << 32) | ((ulong)materialAlpha << 24); ulong checkPixels = ((ulong)palette[pixel].A << 56) | ((ulong)palette[pixel].R << 48) | ((ulong)palette[pixel].G << 40) | ((ulong)palette[pixel].B << 32); bool writePixels = true; if (polyPixelList.ContainsKey(dataOffset)) { if (polyPixelList[dataOffset] != checkPixels) { bool drawPixels = true; //if (materialAlpha == 0) //{ // //Console.WriteLine("Debug: Material has an alpha of 0 - ignoring"); // drawPixels = false; //} //if (materialAlpha < 0x40) //{ // //Console.WriteLine("Debug: Material has an alpha of less than 0x40 - ignoring"); // drawPixels = false; //} if (!poly.textureUsed) { //Console.WriteLine("Debug: polygon does not use a texture - ignoring"); drawPixels = false; } if (!poly.visible) { //Console.WriteLine("Debug: polygon is invisible - ignoring"); drawPixels = false; } if (drawPixels) { if ((uMin != 0) && (vMin != 0)) { dumpPreviousTextureVersion = true; } //Console.WriteLine(string.Format("Warning: pixels with offset {0} in texture with ID {1} have already been written with a different value. Existing: 0x{2:X16}, New: 0x{3:X16}", dataOffset, poly.textureID, polyPixelList[dataOffset], checkPixels)); } else { //Console.WriteLine(string.Format("Warning: not updating pixels with offset {0} in texture with ID {1}, because the new values are for a polygon that is not drawn/invisible, or has no texture. Existing: 0x{2:X16}, Ignored: 0x{3:X16}", dataOffset, poly.textureID, polyPixelList[dataOffset], checkPixels)); writePixels = false; } } } else { polyPixelList.Add(dataOffset, checkPixels); } if (writePixels) { _Textures[poly.textureID].SetPixel(x, y, pixelColour); wrotePixels = true; } } } if (handledPixels.ContainsKey(poly.textureID)) { handledPixels[poly.textureID] = polyPixelList; } else { handledPixels.Add(poly.textureID, polyPixelList); } if (wrotePixels) { // add or update palette list string paletteIDString = poly.textureID.ToString() + "-" + poly.CLUT.ToString(); if (palettes.Contains(paletteIDString)) { int palCount = (int)palettes[paletteIDString]; palCount++; palettes[paletteIDString] = palCount; } else { int newPalCount = 1; palettes.Add(paletteIDString, newPalCount); } } if (debugTextureCollisions) { if (dumpPreviousTextureVersion) { if (!Directory.Exists("Texture_Debugging")) { Directory.CreateDirectory("Texture_Debugging"); } // dump each overwritten version of the texture for debugging byte[] previousHash = new MD5CryptoServiceProvider().ComputeHash(ImageToByteArray(previousTexture)); if (!ListContainsByteArray(textureHashes, previousHash)) { int fileNum = 0; bool gotFilename = false; string fileName = ""; while (!gotFilename) { fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-version_{1:X8}.png", poly.textureID, fileNum); if (!File.Exists(fileName)) { gotFilename = true; } fileNum++; } if (fileName != "") { //_Textures[poly.textureID].Save(fileName, ImageFormat.Png); previousTexture.Save(fileName, ImageFormat.Png); } textureHashes.Add(previousHash); } } } } if (!drawGreyScaleFirst) { bool exportAllPaletteVariations = false; if (exportAllPaletteVariations) { foreach (string pID in palettes.Keys) { int useCount = (int)palettes[pID]; string[] palDecode2 = pID.Split('-'); int tID = int.Parse(palDecode2[0]); ushort clut = ushort.Parse(palDecode2[1]); for (int texNum = 0; texNum < _Textures.Length; texNum++) { TexturePage texturePage = _TPages[texNum]; Bitmap exportTemp = (Bitmap)_Textures[texNum].Clone(); Color[] pal = GetPalette(texNum, clut); bool exportThisTexture = false; for (int y = 0; y < _ImageHeight; y++) { for (int x = 0; x < _ImageWidth; x++) { bool pixChroma = (exportTemp.GetPixel(x, y).A == 1); if (pixChroma) { exportThisTexture = true; int pixel = texturePage.pixels[y, x]; Color pixelColour = pal[pixel]; if (pixChroma) { exportTemp.SetPixel(x, y, pixelColour); } } } } if (exportThisTexture) { if (!Directory.Exists("Texture_Debugging")) { Directory.CreateDirectory("Texture_Debugging"); } string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-count_{1:X8}-palette_texture_ID_{2:X8}-clut_{4:X8}.png", texNum, useCount, tID, clut); exportTemp.Save(fileName, ImageFormat.Png); } } } } List <int> allTexturesWithPalettes = new List <int>(); foreach (string pID in palettes.Keys) { string[] pd = pID.Split('-'); int txID = int.Parse(pd[0]); ushort clut = ushort.Parse(pd[1]); if (!allTexturesWithPalettes.Contains(txID)) { if (clut != 0) { allTexturesWithPalettes.Add(txID); } } } for (int texNum = 0; texNum < _Textures.Length; texNum++) { TexturePage texturePage = _TPages[texNum]; // find the most frequently-used palette string palID = ""; int palCount = 0; ushort mostCommonPaletteClut = 0; bool hasAtLeastOneVisiblePixel = false; foreach (string pID in palettes.Keys) { string[] pd = pID.Split('-'); int txID = int.Parse(pd[0]); bool considerPalette = true; // don't use palettes from other textures unless there were no palettes found for this texture if (allTexturesWithPalettes.Contains(texNum)) { if (txID != texNum) { considerPalette = false; } } if (considerPalette) { ushort clut = ushort.Parse(pd[1]); int pCount = (int)palettes[pID]; if (pCount > palCount) { palID = pID; if (clut != 0) { mostCommonPaletteClut = clut; } // don't use palettes with column/row zero or with odd column numbers unless there's no other choice //if ((pc != 0) && (pr != 0) && (pc % 2 == 0)) //{ // break; //} } } } Color[] commonPalette = GetPalette(texNum, mostCommonPaletteClut); // use a greyscale palette instead of column 0, row 0, because column 0, row 0 is always garbage that makes // the texture impossible to view properly, and full of random transparent pixels if (options.AlwaysUseGreyscaleForMissingPalettes || mostCommonPaletteClut == 0) { commonPalette = GetGreyscalePalette(texNum); } for (int y = 0; y < _ImageHeight; y++) { for (int x = 0; x < _ImageWidth; x++) { if (!hasAtLeastOneVisiblePixel) { if (_Textures[texNum].GetPixel(x, y).A > 1) { hasAtLeastOneVisiblePixel = true; } } bool pixChroma = (_Textures[texNum].GetPixel(x, y).A == 1); if (pixChroma) { int dataOffset = (_ImageHeight * y) + x; int pixel = texturePage.pixels[y, x]; Color pixelColour = commonPalette[pixel]; if (pixChroma) { _Textures[texNum].SetPixel(x, y, pixelColour); } } } } if ((!hasAtLeastOneVisiblePixel) && (options.UnhideCompletelyTransparentTextures)) { for (int y = 0; y < _Textures[texNum].Width; y++) { for (int x = 0; x < _Textures[texNum].Height; x++) { Color pix = _Textures[texNum].GetPixel(x, y); if (pix.A < 2) { _Textures[texNum].SetPixel(x, y, Color.FromArgb(128, pix.R, pix.G, pix.B)); } } } } } } // dump all textures as PNGs for debugging //texNum = 0; //foreach (Bitmap tex in _Textures) //{ // tex.Save(@"C:\Debug\Tex-" + texNum + ".png", ImageFormat.Png); // texNum++; //} }
protected Color[] GetPalette(int index, ushort clut) { TexturePage texturePage = _TPages[index]; return(GetTextureClut(clut, texturePage.tp == 0 ? 16 : 256).colours); }
public void Release(TexturePage page) { int num = (Time.frameCount + 1) % 2; activePages[num].Add(page); }
/// <summary> Removes and compresses texture space. Updates all buffers with texture coordinates.</summary> public bool GarbageCollect(bool checkTime = true) { if (GarbageCollectionInProgress) { return(false); } // We don't want to garbage collect the texture all the time because it will make the program very slow. // So if we just collected it and only a bit of time elapsed, if it's already full again we must give up. long elapsedTicks = Stopwatch.GetTimestamp() - GarbageCollectionLastTimestamp; float elapsedSeconds = (float)elapsedTicks / Stopwatch.Frequency; if (checkTime && elapsedSeconds < GarbageCollectionWaitSeconds) { logger.Warn("Garbage collection of texture (size " + Size + ") was aborted because only " + elapsedSeconds + " seconds elapsed " + "since the last collection. (Minimum time: " + GarbageCollectionWaitSeconds + " seconds)"); return(false); } // Start garbage collection try { logger.Info("Started garbage collecting of texture (size " + Size + ") after " + elapsedSeconds + " seconds."); GarbageCollectionInProgress = true; // Collect var map = new Map(this); var usedTextures = new HashSet <Map.Entry>(); var adjustEvent = new List <GarbageCollectionAdjustDelegate>(); foreach (var collectDelegate in GarbageCollectionCollectEvent) { var adjustDelegate = collectDelegate(this, map, usedTextures); if (adjustDelegate != null) { adjustEvent.Add(adjustDelegate); } } logger.Error("Removed " + (AvailableTextures.Count - usedTextures.Count) + " textures of previously " + AvailableTextures.Count + "."); // Reset for (int i = 0; i < Size.Z; ++i) { Pages[i] = new TexturePage(new VectorInt2(Size.X, Size.Y)); } AvailableTextures.Clear(); // Read textures that were still used var usedTexturesSorted = usedTextures.ToArray(); Array.Sort(usedTexturesSorted, new GarbageCollectionTextureOrder()); foreach (Map.Entry usedTexture in usedTexturesSorted) { if (AllocateTexture(usedTexture.Texture) == null) { logger.Error("Unable to add texture after garbage collecting texture!"); } } // Adjust foreach (var adjustDelegate in adjustEvent) { adjustDelegate(this, map); } // Finished return(true); } finally { logger.Info("Garbage collection of texture (size " + Size + ") finished."); GarbageCollectionLastTimestamp = Stopwatch.GetTimestamp(); GarbageCollectionInProgress = false; } }
public TextureRegion Lock(int x, int y, int width, int height) { TexturePage page = pool.Alloc(name, width, height, format); return(new TextureRegion(x, y, page, this)); }