diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj index 862059e0603402e3495868ebd40d7914be4241d1..356382542d42487aea87226606b6c6143d706bc7 100644 --- a/Source/Core/Builder.csproj +++ b/Source/Core/Builder.csproj @@ -204,7 +204,6 @@ <Compile Include="Data\PatchNames.cs" /> <Compile Include="Data\PK3Reader.cs" /> <Compile Include="Data\Playpal.cs" /> - <Compile Include="Data\PreviewManager.cs" /> <Compile Include="Data\ResourceImage.cs" /> <Compile Include="Data\SimpleTextureImage.cs" /> <Compile Include="Data\SpriteImage.cs" /> diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 585a4c0c5ff4655e029f6e08e287c8d03d130e73..a378bd3872f8e7d3e0bb872126a8e2105c37b477 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -105,9 +105,6 @@ namespace CodeImp.DoomBuilder.Data private int threadsfinished; private bool notifiedbusy; - // Image previews - private PreviewManager previews; - // Special images private ImageData missingtexture3d; private ImageData unknowntexture3d; @@ -172,7 +169,6 @@ namespace CodeImp.DoomBuilder.Data internal IEnumerable<DataReader> Containers { get { return containers; } } public Playpal Palette { get { return palette; } } - public PreviewManager Previews { get { return previews; } } public ICollection<ImageData> Textures { get { return textures.Values; } } public ICollection<ImageData> Flats { get { return flats.Values; } } public List<string> TextureNames { get { return texturenames; } } @@ -184,7 +180,9 @@ namespace CodeImp.DoomBuilder.Data public ImageData Hourglass3D { get { return hourglass3d; } } public ImageData Crosshair3D { get { return crosshair; } } public ImageData CrosshairBusy3D { get { return crosshairbusy; } } - public ImageData WhiteTexture { get { return whitetexture; } } + public Texture LoadingTexture { get; private set; } + public Texture FailedTexture { get; private set; } + public ImageData WhiteTexture { get { return whitetexture; } } public ImageData BlackTexture { get { return blacktexture; } } //mxd public ImageData ThingTexture { get { return thingtexture; } } //mxd internal ImageData FolderTexture { get { return foldertexture; } } //mxd @@ -204,7 +202,7 @@ namespace CodeImp.DoomBuilder.Data get { if(imageque != null) - return (backgroundloader != null) && backgroundloader.Any(x => x.IsAlive) && ((imageque.Count > 0) || previews.IsLoading); + return (backgroundloader != null) && backgroundloader.Any(x => x.IsAlive) && ((imageque.Count > 0)); return false; } } @@ -236,16 +234,14 @@ namespace CodeImp.DoomBuilder.Data // Constructor internal DataManager() { - // We have no destructor - GC.SuppressFinalize(this); + FailedTexture = new Texture(General.Map.Graphics, Properties.Resources.Failed); + LoadingTexture = new Texture(General.Map.Graphics, Properties.Resources.Hourglass); - // Load special images (mxd: the rest is loaded in LoadInternalTextures()) - whitetexture = new ResourceImage("CodeImp.DoomBuilder.Resources.White.png") { UseColorCorrection = false }; + // Load special images (mxd: the rest is loaded in LoadInternalTextures()) + whitetexture = new ResourceImage("CodeImp.DoomBuilder.Resources.White.png") { UseColorCorrection = false }; whitetexture.LoadImage(); - whitetexture.CreateTexture(); blacktexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Black.png") { UseColorCorrection = false }; //mxd blacktexture.LoadImage(); //mxd - blacktexture.CreateTexture(); //mxd unknownimage = new UnknownImage(Properties.Resources.UnknownImage); //mxd. There should be only one! //mxd. Textures browser images @@ -268,7 +264,6 @@ namespace CodeImp.DoomBuilder.Data foreach(ImageData data in commenttextures) { data.LoadImage(); - data.CreateTexture(); } } @@ -356,7 +351,6 @@ namespace CodeImp.DoomBuilder.Data flatnamesshorttofull = new Dictionary<long, long>(); //mxd flatnamesfulltoshort = new Dictionary<long, long>(); //mxd imageque = new Queue<ImageData>(); - previews = new PreviewManager(); texturesets = new List<MatchingTextureSet>(); usedtextures = new Dictionary<long, bool>(); //mxd usedflats = new Dictionary<long, bool>(); //mxd @@ -634,10 +628,6 @@ namespace CodeImp.DoomBuilder.Data // Stop background loader StopBackgroundLoader(); - // Dispose preview manager - previews.Dispose(); - previews = null; - // Dispose decorate decorate.Dispose(); @@ -845,72 +835,55 @@ namespace CodeImp.DoomBuilder.Data } else { - // Process previews only when we don't have images to process - // because these are lower priority than the actual images - if(previews.BackgroundLoad()) - { - // Wait a bit and update icon - if(!notifiedbusy) - { - notifiedbusy = true; - General.MainWindow.UpdateStatus(); - } - } - else - { - bool lastthread = false; - lock (syncobject) - { - threadsfinished++; - if (threadsfinished == backgroundloader.Length) - lastthread = true; - } + bool lastthread = false; + lock (syncobject) + { + threadsfinished++; + if (threadsfinished == backgroundloader.Length) + lastthread = true; + } - if (lastthread) + if (lastthread) + { + // Timing + if (loadfinishtime == 0) { - // Timing - if (loadfinishtime == 0) + //mxd. Release PK3 files + foreach (DataReader reader in containers) + { + if (reader is PK3Reader) (reader as PK3Reader).BatchMode = false; + } + + loadfinishtime = Clock.CurrentTime; + string deltatimesec = ((loadfinishtime - loadstarttime) / 1000.0f).ToString("########0.00"); + General.WriteLogLine("Resources loading took " + deltatimesec + " seconds"); + loadstarttime = 0; //mxd + + lock (syncobject) { - //mxd. Release PK3 files - foreach (DataReader reader in containers) - { - if (reader is PK3Reader) (reader as PK3Reader).BatchMode = false; - } - - loadfinishtime = Clock.CurrentTime; - string deltatimesec = ((loadfinishtime - loadstarttime) / 1000.0f).ToString("########0.00"); - General.WriteLogLine("Resources loading took " + deltatimesec + " seconds"); - loadstarttime = 0; //mxd - - lock (syncobject) - { - threadsfinished = 0; - } - - //mxd. Show more detailed message - if (notifiedbusy) - { - notifiedbusy = false; - General.MainWindow.ResourcesLoaded(deltatimesec); - } + threadsfinished = 0; } - else if (notifiedbusy) //mxd. Sould never happen (?) + + //mxd. Show more detailed message + if (notifiedbusy) { notifiedbusy = false; - General.MainWindow.UpdateStatus(); + General.MainWindow.ResourcesLoaded(deltatimesec); } } - - // Wait until there's more to do. - lock (syncobject) + else if (notifiedbusy) //mxd. Sould never happen (?) { - if (imageque.Count == 0) Monitor.Wait(syncobject); + notifiedbusy = false; + General.MainWindow.UpdateStatus(); } } - } - if (image == null) - Thread.Sleep(1); + // Wait until there's more to do. + lock (syncobject) + { + if (imageque.Count == 0) Monitor.Wait(syncobject); + } + } } while (true); } @@ -925,7 +898,8 @@ namespace CodeImp.DoomBuilder.Data { // Add for loading img.ImageState = ImageLoadState.Loading; - lock(syncobject) { imageque.Enqueue(img); Monitor.Pulse(syncobject); } + img.PreviewState = ImageLoadState.Loading; + lock (syncobject) { imageque.Enqueue(img); Monitor.Pulse(syncobject); } } // Unload this image? @@ -933,7 +907,8 @@ namespace CodeImp.DoomBuilder.Data { // Add for unloading img.ImageState = ImageLoadState.Unloading; - lock(syncobject) { imageque.Enqueue(img); Monitor.Pulse(syncobject); } + img.PreviewState = ImageLoadState.Unloading; + lock (syncobject) { imageque.Enqueue(img); Monitor.Pulse(syncobject); } } } @@ -954,13 +929,13 @@ namespace CodeImp.DoomBuilder.Data modeldefentries.Remove(type); return false; } - - #endregion - - #region ================== Palette - // This loads the PLAYPAL palette - private void LoadPalette() + #endregion + + #region ================== Palette + + // This loads the PLAYPAL palette + private void LoadPalette() { // Go for all opened containers for(int i = containers.Count - 1; i >= 0; i--) @@ -1001,9 +976,6 @@ namespace CodeImp.DoomBuilder.Data list.Remove(img.LongName); list.Add(img.LongName, img); counter++; - - // Add to preview manager - previews.AddImage(img); } } } @@ -1070,9 +1042,6 @@ namespace CodeImp.DoomBuilder.Data { nametranslation.Remove(img.LongName); } - - // Add to preview manager - previews.AddImage(img); } } } @@ -1246,7 +1215,6 @@ namespace CodeImp.DoomBuilder.Data crosshairbusy = LoadInternalTexture("CrosshairBusy.png"); thingtexture.UseColorCorrection = false; - thingtexture.CreateTexture(); } //mxd @@ -1303,9 +1271,6 @@ namespace CodeImp.DoomBuilder.Data { nametranslation.Remove(img.LongName); } - - // Add to preview manager - previews.AddImage(img); } } } @@ -1434,8 +1399,6 @@ namespace CodeImp.DoomBuilder.Data textures[img.LongName] = replacer; //replaced = true; - // Add to preview manager - previews.AddImage(replacer); counter++; } @@ -1448,8 +1411,6 @@ namespace CodeImp.DoomBuilder.Data flats[img.LongName] = replacer; //replaced = true; - // Add to preview manager - previews.AddImage(replacer); counter++; } @@ -1461,8 +1422,6 @@ namespace CodeImp.DoomBuilder.Data sprites[img.LongName] = replacer; //replaced = true; - // Add to preview manager - previews.AddImage(replacer); counter++; } @@ -1586,9 +1545,6 @@ namespace CodeImp.DoomBuilder.Data // Add to collection sprites.Add(image.LongName, image); - - // Add to preview manager - previews.AddImage(image); } } else @@ -1634,9 +1590,6 @@ namespace CodeImp.DoomBuilder.Data { image = sprites[info.SpriteLongName]; } - - // Add to preview manager - if(image != null) previews.AddImage(image); } } } @@ -2460,9 +2413,6 @@ namespace CodeImp.DoomBuilder.Data // Add to collection sprites.Add(sprite.LongName, sprite); - - // Add to preview manager - previews.AddImage(sprite); } // Apply VOXELDEF settings to the preview image... @@ -2828,9 +2778,6 @@ namespace CodeImp.DoomBuilder.Data textures[camteximage.LongName] = camteximage; flats[camteximage.LongName] = camteximage; - // Add to preview manager - previews.AddImage(camteximage); - // Add to container's texture set currentreader.TextureSet.AddFlat(camteximage); currentreader.TextureSet.AddTexture(camteximage); @@ -3304,7 +3251,6 @@ namespace CodeImp.DoomBuilder.Data // Use the built-in texture ImageData tex = LoadInternalTexture("MissingSky3D.png"); - tex.CreateTexture(); Bitmap bmp = tex.GetBitmap(); Bitmap sky; lock (bmp) diff --git a/Source/Core/Data/DynamicBitmapImage.cs b/Source/Core/Data/DynamicBitmapImage.cs index a27b23285fc017821bae33280f2b5ee65fd479fa..0ac7dbc84ab7e632494c7bfb259028e1fd13c24e 100755 --- a/Source/Core/Data/DynamicBitmapImage.cs +++ b/Source/Core/Data/DynamicBitmapImage.cs @@ -69,7 +69,6 @@ namespace CodeImp.DoomBuilder.Data // Reload the resource public void ReloadResource() { - CreateTexture(); } #endregion diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index 33f519d72a7bb3ee2e175cddb15d96ae74757a2a..05fdeff1123f0decf8b878a2b91b81ea9c818fb3 100755 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -68,7 +68,6 @@ namespace CodeImp.DoomBuilder.Data // Loading private ImageLoadState previewstate; private ImageLoadState imagestate; - private int previewindex; private bool loadfailed; private bool allowunload; @@ -79,9 +78,10 @@ namespace CodeImp.DoomBuilder.Data // GDI bitmap private Bitmap _bitmap; protected Bitmap bitmap { get { return _bitmap; } } - - // Direct3D texture - private int mipmaplevels; // 0 = all mipmaps + private Bitmap previewbitmap; + + // Direct3D texture + private int mipmaplevels; // 0 = all mipmaps protected bool dynamictexture; private Texture texture; @@ -104,7 +104,7 @@ namespace CodeImp.DoomBuilder.Data public bool HasPatchWithSameName { get { return hasPatchWithSameName; } } //mxd internal bool HasLongName { get { return hasLongName; } } //mxd public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } } - public Texture Texture { get { return texture; } } + public Texture Texture { get { return GetTexture(); } } public bool IsPreviewLoaded { get { return (previewstate == ImageLoadState.Ready); } } public bool IsImageLoaded { get { return (imagestate == ImageLoadState.Ready); } } public bool LoadFailed { get { return loadfailed; } } @@ -117,7 +117,6 @@ namespace CodeImp.DoomBuilder.Data public int MipMapLevels { get { return mipmaplevels; } set { mipmaplevels = value; } } public virtual int Width { get { return width; } } public virtual int Height { get { return height; } } - internal int PreviewIndex { get { return previewindex; } set { previewindex = value; } } //mxd. Scaled texture size is integer in ZDoom. public virtual float ScaledWidth { get { return (float)Math.Round(width * scale.x); } } public virtual float ScaledHeight { get { return (float)Math.Round(height * scale.y); } } @@ -256,6 +255,7 @@ namespace CodeImp.DoomBuilder.Data LocalLoadResult loadResult = LocalLoadImage(); ConvertImageFormat(loadResult); + MakeImagePreview(loadResult); General.MainWindow.RunOnUIThread(() => { @@ -272,7 +272,9 @@ namespace CodeImp.DoomBuilder.Data // Image is ready imagestate = ImageLoadState.Ready; + previewstate = ImageLoadState.Ready; _bitmap = loadResult.bitmap; + previewbitmap = loadResult.preview; if (loadResult.uiThreadWork != null) loadResult.uiThreadWork(); }); @@ -311,6 +313,7 @@ namespace CodeImp.DoomBuilder.Data } public Bitmap bitmap; + public Bitmap preview; public List<LogMessage> messages; public Action uiThreadWork; } @@ -517,28 +520,89 @@ namespace CodeImp.DoomBuilder.Data loadResult.bitmap = bitmap; } - - // This creates the Direct3D texture - public virtual void CreateTexture() + + // Dimensions of a single preview image + const int MAX_PREVIEW_SIZE = 256; //mxd + + // This makes a preview for the given image and updates the image settings + private void MakeImagePreview(LocalLoadResult loadResult) + { + if (loadResult.bitmap == null) + return; + + Bitmap image = loadResult.bitmap; + Bitmap preview; + + int imagewidth = image.Width; + int imageheight = image.Height; + + // Determine preview size + float scalex = (imagewidth > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imagewidth) : 1.0f; + float scaley = (imageheight > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imageheight) : 1.0f; + float scale = Math.Min(scalex, scaley); + int previewwidth = (int)(imagewidth * scale); + int previewheight = (int)(imageheight * scale); + if (previewwidth < 1) previewwidth = 1; + if (previewheight < 1) previewheight = 1; + + //mxd. Expected and actual image sizes and format match? + if (previewwidth == imagewidth && previewheight == imageheight && image.PixelFormat == PixelFormat.Format32bppArgb) + { + preview = new Bitmap(image); + } + else + { + // Make new image + preview = new Bitmap(previewwidth, previewheight, PixelFormat.Format32bppArgb); + Graphics g = Graphics.FromImage(preview); + g.PageUnit = GraphicsUnit.Pixel; + //g.CompositingQuality = CompositingQuality.HighQuality; //mxd + g.InterpolationMode = InterpolationMode.NearestNeighbor; + //g.SmoothingMode = SmoothingMode.HighQuality; //mxd + g.PixelOffsetMode = PixelOffsetMode.None; + //g.Clear(Color.Transparent); //mxd + + // Draw image onto atlas + Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight); + RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect); + if (imgrect.Width < 1.0f) + { + imgrect.X -= 0.5f - imgrect.Width * 0.5f; + imgrect.Width = 1.0f; + } + if (imgrect.Height < 1.0f) + { + imgrect.Y -= 0.5f - imgrect.Height * 0.5f; + imgrect.Height = 1.0f; + } + g.DrawImage(image, imgrect); + g.Dispose(); + } + + loadResult.preview = preview; + } + + Texture GetTexture() { - // Only do this when texture is not created yet - if(((texture == null) || (texture.Disposed)) && this.IsImageLoaded && !loadfailed) - { - Bitmap img = bitmap; - if(loadfailed) img = Properties.Resources.Failed; + if (texture != null) + return texture; + else if (loadfailed) + return General.Map.Data.FailedTexture; + else if (imagestate == ImageLoadState.Loading) + return General.Map.Data.LoadingTexture; - texture = new Texture(General.Map.Graphics, img); - - if(dynamictexture) - { - if((width != texture.Width) || (height != texture.Height)) - throw new Exception("Could not create a texture with the same size as the image."); - } + texture = new Texture(General.Map.Graphics, bitmap); + + if (dynamictexture) + { + if ((width != texture.Width) || (height != texture.Height)) + throw new Exception("Could not create a texture with the same size as the image."); + } #if DEBUG - texture.Tag = name; //mxd. Helps with tracking undisposed resources... + texture.Tag = name; //mxd. Helps with tracking undisposed resources... #endif - } + return texture; } // This updates a dynamic texture @@ -556,37 +620,10 @@ namespace CodeImp.DoomBuilder.Data // This destroys the Direct3D texture public void ReleaseTexture() { - // Trash it - if(texture != null) texture.Dispose(); + texture?.Dispose(); texture = null; } - // This draws a preview - public virtual void DrawPreview(Graphics target, Point targetpos) - { - // Preview ready? - if(!loadfailed && (previewstate == ImageLoadState.Ready)) - { - // Draw preview - General.Map.Data.Previews.DrawPreview(previewindex, target, targetpos); - } - // Loading failed? - else if(loadfailed) - { - // Draw error bitmap - targetpos = new Point(targetpos.X + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Width) >> 1), - targetpos.Y + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Height) >> 1)); - target.DrawImageUnscaled(Properties.Resources.Failed, targetpos); - } - else - { - // Draw loading bitmap - targetpos = new Point(targetpos.X + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Width) >> 1), - targetpos.Y + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Height) >> 1)); - target.DrawImageUnscaled(Properties.Resources.Hourglass, targetpos); - } - } - // This returns a preview image public virtual Image GetPreview() { @@ -594,7 +631,7 @@ namespace CodeImp.DoomBuilder.Data if(previewstate == ImageLoadState.Ready) { // Make a copy - return General.Map.Data.Previews.GetPreviewCopy(previewindex); + return new Bitmap(previewbitmap); } // Loading failed? diff --git a/Source/Core/Data/PreviewManager.cs b/Source/Core/Data/PreviewManager.cs deleted file mode 100755 index 7463c1f7e82c0985e3587a983bdf5dfe6abd7cc4..0000000000000000000000000000000000000000 --- a/Source/Core/Data/PreviewManager.cs +++ /dev/null @@ -1,279 +0,0 @@ - -#region ================== Copyright (c) 2007 Pascal vd Heiden - -/* - * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com - * This program is released under GNU General Public License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#endregion - -#region ================== Namespaces - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Drawing.Drawing2D; - -#endregion - -namespace CodeImp.DoomBuilder.Data -{ - public class PreviewManager - { - #region ================== Constants - - // Image format - private const PixelFormat IMAGE_FORMAT = PixelFormat.Format32bppArgb; - - // Dimensions of a single preview image - public const int MAX_PREVIEW_SIZE = 256; //mxd - - #endregion - - #region ================== Variables - - // Images - private List<Bitmap> images; - - // Processing - private Queue<ImageData> imageque; - private static object syncroot = new object(); //mxd - - // Disposing - private bool isdisposed; - - #endregion - - #region ================== Properties - - // Disposing - internal bool IsDisposed { get { return isdisposed; } } - - // Loading - internal bool IsLoading - { - get - { - return (imageque.Count > 0); - } - } - - #endregion - - #region ================== Constructor / Disposer - - // Constructor - internal PreviewManager() - { - // Initialize - images = new List<Bitmap>(); - imageque = new Queue<ImageData>(); - - // We have no destructor - GC.SuppressFinalize(this); - } - - // Disposer - internal void Dispose() - { - // Not already disposed? - if(!isdisposed) - { - // Clean up - foreach(Bitmap b in images) b.Dispose(); - images = null; - - // Done - isdisposed = true; - } - } - - #endregion - - #region ================== Private Methods - - // This makes a preview for the given image and updates the image settings - private void MakeImagePreview(ImageData img) - { - lock(img) - { - // Load image if needed - if(!img.IsImageLoaded && !img.LoadFailed) img.LoadImage(false); - int imagewidth, imageheight; - Bitmap image = img.GetBitmap(); //mxd - Bitmap preview; - lock (image) - { - if (!img.LoadFailed) - { - imagewidth = img.Width; - imageheight = img.Height; - } - else - { - Size size = image.Size; //mxd - imagewidth = size.Width; - imageheight = size.Height; - } - - // Determine preview size - float scalex = (img.Width > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imagewidth) : 1.0f; - float scaley = (img.Height > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imageheight) : 1.0f; - float scale = Math.Min(scalex, scaley); - int previewwidth = (int)(imagewidth * scale); - int previewheight = (int)(imageheight * scale); - if (previewwidth < 1) previewwidth = 1; - if (previewheight < 1) previewheight = 1; - - //mxd. Expected and actual image sizes and format match? - if (previewwidth == imagewidth && previewheight == imageheight && image.PixelFormat == IMAGE_FORMAT) - { - preview = new Bitmap(image); - } - else - { - // Make new image - preview = new Bitmap(previewwidth, previewheight, IMAGE_FORMAT); - Graphics g = Graphics.FromImage(preview); - g.PageUnit = GraphicsUnit.Pixel; - //g.CompositingQuality = CompositingQuality.HighQuality; //mxd - g.InterpolationMode = InterpolationMode.NearestNeighbor; - //g.SmoothingMode = SmoothingMode.HighQuality; //mxd - g.PixelOffsetMode = PixelOffsetMode.None; - //g.Clear(Color.Transparent); //mxd - - // Draw image onto atlas - Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight); - RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect); - if (imgrect.Width < 1.0f) - { - imgrect.X -= 0.5f - imgrect.Width * 0.5f; - imgrect.Width = 1.0f; - } - if (imgrect.Height < 1.0f) - { - imgrect.Y -= 0.5f - imgrect.Height * 0.5f; - imgrect.Height = 1.0f; - } - g.DrawImage(image, imgrect); - g.Dispose(); - } - } - - // Unload image if no longer needed - if(!img.IsReferenced) img.UnloadImage(); - - lock(images) - { - // Set numbers - img.PreviewIndex = images.Count; - img.PreviewState = ImageLoadState.Ready; - - // Add to previews list - images.Add(preview); - } - } - } - - #endregion - - #region ================== Public Methods - - // This draws a preview centered in a target - internal void DrawPreview(int previewindex, Graphics target, Point targetpos) - { - Bitmap image; - - // Get the preview we need - lock(images) { image = images[previewindex]; } - - // Adjust offset for the size of the preview image - targetpos.X += (MAX_PREVIEW_SIZE - image.Width) >> 1; - targetpos.Y += (MAX_PREVIEW_SIZE - image.Height) >> 1; - - // Draw from atlas to target - lock(syncroot) - { - target.DrawImageUnscaled(image, targetpos.X, targetpos.Y); - } - } - - // This returns a copy of the preview - internal Bitmap GetPreviewCopy(int previewindex) - { - Bitmap image; - - // Get the preview we need - lock(images) { image = images[previewindex]; } - - // Make a copy - lock(syncroot) - { - return new Bitmap(image); - } - } - - // Background loading - // Return true when we have more work to do, so that the - // thread will not wait too long before calling again - internal bool BackgroundLoad() - { - // Get next item - ImageData image = null; - lock(imageque) - { - // Fetch next image to process - if(imageque.Count > 0) image = imageque.Dequeue(); - } - - // Any image to process? - if(image != null) - { - // Make image preview? - if(!image.IsPreviewLoaded) MakeImagePreview(image); - } - - return (image != null); - } - - // This adds an image for preview creation - internal void AddImage(ImageData image) - { - lock(imageque) - { - // Add to list - image.PreviewState = ImageLoadState.Loading; - imageque.Enqueue(image); - } - } - - - #if DEBUG - /*internal void DumpAtlases() - { - lock(images) - { - int index = 0; - foreach(Bitmap a in images) - { - lock(a) - { - string file = Path.Combine(General.AppPath, "atlas" + index++ + ".png"); - a.Save(file, ImageFormat.Png); - } - } - } - }*/ - #endif - - #endregion - } -} diff --git a/Source/Core/Editing/GridSetup.cs b/Source/Core/Editing/GridSetup.cs index 31a253f82f903fa9a9f6b24292730f790102ae71..6b668d1cab60ee3f986b03af2fd63308ca07321d 100755 --- a/Source/Core/Editing/GridSetup.cs +++ b/Source/Core/Editing/GridSetup.cs @@ -235,7 +235,6 @@ namespace CodeImp.DoomBuilder.Editing // Make sure it is loaded backimage.LoadImage(); - backimage.CreateTexture(); } // This returns the next higher coordinate diff --git a/Source/Core/GZBuilder/md3/ModelReader.cs b/Source/Core/GZBuilder/md3/ModelReader.cs index e6f76bfac2e9bd73598a539504b39d8f5b5b77fe..96e03289a54c9d9c2e608a21e205b73c0a7c81e8 100755 --- a/Source/Core/GZBuilder/md3/ModelReader.cs +++ b/Source/Core/GZBuilder/md3/ModelReader.cs @@ -147,10 +147,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 //add loaded data to ModeldefEntry mde.Model.Meshes.AddRange(result.Meshes); - //prepare UnknownTexture3D... just in case :) - if(General.Map.Data.UnknownTexture3D.Texture == null || General.Map.Data.UnknownTexture3D.Texture.Disposed) - General.Map.Data.UnknownTexture3D.CreateTexture(); - //load texture List<string> errors = new List<string>(); @@ -282,9 +278,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 if (!image.IsImageLoaded) image.LoadImage(); - if (image.Texture == null) - image.CreateTexture(); - t = image.Texture; break; @@ -304,9 +297,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 if (!image.IsImageLoaded) image.LoadImage(); - if (image.Texture == null) - image.CreateTexture(); - t = image.Texture; } } @@ -323,9 +313,6 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3 if (!image.IsImageLoaded) image.LoadImage(); - if (image.Texture == null) - image.CreateTexture(); - t = image.Texture; } } diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index 34ced7698f5b57a17656f5c03cefbc1841b3da69..2926c88642ed548b8127aa11995a3e42b143d9ce 100755 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -58,6 +58,7 @@ namespace CodeImp.DoomBuilder internal static bool MessageBeep(MessageBeepType type) { return true; } internal static void ZeroMemory(IntPtr dest, int size) { } internal static int SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam) { return 0; } + internal static int PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam) { return 0; } #else [DllImport("user32.dll")] @@ -72,7 +73,10 @@ namespace CodeImp.DoomBuilder [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)] internal static extern int SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", EntryPoint = "PostMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)] + internal static extern int PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", SetLastError = true)] internal static extern bool MessageBeep(MessageBeepType type); //[DllImport("kernel32.dll")] @@ -108,6 +112,7 @@ namespace CodeImp.DoomBuilder // SendMessage API internal const int WM_USER = 0x400; + internal const int WM_UIACTION = WM_USER + 1; internal const int WM_SYSCOMMAND = 0x112; internal const int WM_MOUSEHWHEEL = 0x020E; // [ZZ] internal const int SC_KEYMENU = 0xF100; diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 95644c9ad421eb3f70e4e1c509d43cbbdd19f0d9..350a57c070f46dc7b19178a735c2abea86c9ef2f 100755 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -1329,7 +1329,6 @@ namespace CodeImp.DoomBuilder.Rendering sprite.SetUsedInMap(true); continue; } - if(sprite.Texture == null) sprite.CreateTexture(); graphics.SetTexture(sprite.Texture); @@ -1560,10 +1559,6 @@ namespace CodeImp.DoomBuilder.Rendering // Set the rendertarget to the surface texture graphics.StartRendering(true, General.Colors.Background.WithAlpha(0).ToColorValue(), surfacetex, false); - // Make sure anything we need is loaded - General.Map.Data.UnknownTexture3D.CreateTexture(); - General.Map.Data.MissingTexture3D.CreateTexture(); //mxd - // Set transformations UpdateTransformations(); @@ -1614,9 +1609,6 @@ namespace CodeImp.DoomBuilder.Rendering if(texture != null) { - // Make sure the texture is loaded - if(!texture.IsImageLoaded) texture.LoadImage(); - if(texture.Texture == null) texture.CreateTexture(); t = texture.Texture; } else diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 1fa39127504318fff74b3c19b5196ed54a70675d..bd92225255e0049ac53cc8e20aa6f6f417927188 100755 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -759,10 +759,6 @@ namespace CodeImp.DoomBuilder.Rendering else curtexture = General.Map.Data.Hourglass3D; - // Create Direct3D texture if still needed - if((curtexture.Texture == null) || curtexture.Texture.Disposed) - curtexture.CreateTexture(); - // Apply texture graphics.SetTexture(curtexture.Texture); @@ -858,10 +854,6 @@ namespace CodeImp.DoomBuilder.Rendering else curtexture = group.Key; - // Create Direct3D texture if still needed - if((curtexture.Texture == null) || curtexture.Texture.Disposed) - curtexture.CreateTexture(); - // Apply texture graphics.SetTexture(curtexture.Texture); @@ -1037,10 +1029,6 @@ namespace CodeImp.DoomBuilder.Rendering else curtexture = General.Map.Data.Hourglass3D; - // Create Direct3D texture if still needed - if((curtexture.Texture == null) || curtexture.Texture.Disposed) - curtexture.CreateTexture(); - // Apply texture graphics.SetTexture(curtexture.Texture); curtexturename = g.Texture.LongName; @@ -1170,10 +1158,6 @@ namespace CodeImp.DoomBuilder.Rendering else curtexture = General.Map.Data.Hourglass3D; - // Create Direct3D texture if still needed - if((curtexture.Texture == null) || curtexture.Texture.Disposed) - curtexture.CreateTexture(); - // Apply texture graphics.SetTexture(curtexture.Texture); curtexturename = t.Texture.LongName; @@ -2019,12 +2003,10 @@ namespace CodeImp.DoomBuilder.Rendering // Texture if (crosshairbusy) { - if(General.Map.Data.CrosshairBusy3D.Texture == null) General.Map.Data.CrosshairBusy3D.CreateTexture(); graphics.SetTexture(General.Map.Data.CrosshairBusy3D.Texture); } else { - if(General.Map.Data.Crosshair3D.Texture == null) General.Map.Data.Crosshair3D.CreateTexture(); graphics.SetTexture(General.Map.Data.Crosshair3D.Texture); } diff --git a/Source/Core/Rendering/SurfaceManager.cs b/Source/Core/Rendering/SurfaceManager.cs index 689fa01171a9dd7cce54e32bc6c449976c7d28a3..7c5a3b7ed0a91a9e3b356f592d0c6c4657add683 100755 --- a/Source/Core/Rendering/SurfaceManager.cs +++ b/Source/Core/Rendering/SurfaceManager.cs @@ -588,11 +588,7 @@ namespace CodeImp.DoomBuilder.Rendering } else { - if(img.IsImageLoaded && !img.LoadFailed) - { - if(img.Texture == null) img.CreateTexture(); - } - else + if(!img.IsImageLoaded || img.LoadFailed) { img = General.Map.Data.WhiteTexture; } diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 5ddb0b484662c643ee980000a5d0bf599b71f7cd..42e9ef942c4f4afc3e8c0c53b61076facf853868 100755 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -4112,6 +4112,24 @@ namespace CodeImp.DoomBuilder.Windows #region ================== Threadsafe updates + object syncobject = new object(); + List<System.Action> queuedActions = new List<System.Action>(); + + void ProcessQueuedUIActions() + { + List<System.Action> queue; + lock (syncobject) + { + queue = queuedActions; + queuedActions = new List<System.Action>(); + } + + foreach (System.Action action in queue) + { + action(); + } + } + public void RunOnUIThread(System.Action action) { if (!InvokeRequired) @@ -4120,7 +4138,15 @@ namespace CodeImp.DoomBuilder.Windows } else { - Invoke(action); + bool notify; + lock (syncobject) + { + notify = queuedActions.Count == 0; + queuedActions.Add(action); + } + + if (notify) + General.PostMessage(Handle, General.WM_UIACTION, IntPtr.Zero, IntPtr.Zero); } } @@ -4177,7 +4203,11 @@ namespace CodeImp.DoomBuilder.Windows // Notify message? switch(m.Msg) { - case General.WM_SYSCOMMAND: + case General.WM_UIACTION: + ProcessQueuedUIActions(); + break; + + case General.WM_SYSCOMMAND: // We don't want to open a menu when ALT is pressed if(m.WParam.ToInt32() != General.SC_KEYMENU) { diff --git a/Source/Plugins/VisplaneExplorer/VisplaneExplorerMode.cs b/Source/Plugins/VisplaneExplorer/VisplaneExplorerMode.cs index 8e9a0d6f63efafa29f635493889924bfce3473e1..58c12504d9fb98962c167724de2d255ee9a51e38 100755 --- a/Source/Plugins/VisplaneExplorer/VisplaneExplorerMode.cs +++ b/Source/Plugins/VisplaneExplorer/VisplaneExplorerMode.cs @@ -281,7 +281,6 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer image.UseColorCorrection = false; image.MipMapLevels = 1; image.LoadImage(); - image.CreateTexture(); // Make custom presentation CustomPresentation p = new CustomPresentation();