diff --git a/Source/Core/Controls/ThingBrowserControl.cs b/Source/Core/Controls/ThingBrowserControl.cs index fcdc0277..2cfad769 100755 --- a/Source/Core/Controls/ThingBrowserControl.cs +++ b/Source/Core/Controls/ThingBrowserControl.cs @@ -229,7 +229,7 @@ namespace CodeImp.DoomBuilder.Controls if(thinginfo.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) && (thinginfo.Sprite.Length > DataManager.INTERNAL_PREFIX.Length)) { - spritetex.Image = General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetBitmap(); + spritetex.Image = General.Map.Data.GetSpriteImage(thinginfo.Sprite).GetSpritePreview(); return; } diff --git a/Source/Core/Controls/ThingInfoPanel.cs b/Source/Core/Controls/ThingInfoPanel.cs index dbd3c174..57b46eb6 100755 --- a/Source/Core/Controls/ThingInfoPanel.cs +++ b/Source/Core/Controls/ThingInfoPanel.cs @@ -118,7 +118,7 @@ namespace CodeImp.DoomBuilder.Controls if(ti.Sprite.ToLowerInvariant().StartsWith(DataManager.INTERNAL_PREFIX) && (ti.Sprite.Length > DataManager.INTERNAL_PREFIX.Length)) { spritename.Text = ""; - spritetex.Image = General.Map.Data.GetSpriteImage(ti.Sprite).GetBitmap(); + spritetex.Image = General.Map.Data.GetSpriteImage(ti.Sprite).GetSpritePreview(); } else if((ti.Sprite.Length <= 8) && (ti.Sprite.Length > 0)) { diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index b383e929..3e9b0eee 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -1101,7 +1101,7 @@ namespace CodeImp.DoomBuilder.Data if(!img.LoadFailed) { // HiResImage will not give us it's actual scale - Bitmap texture = img.GetBitmap(); + Bitmap texture = img.GetSkyboxBitmap(); lock (texture) { scale = new Vector2D((float)img.Width / texture.Width, (float)img.Height / texture.Height); @@ -3255,7 +3255,7 @@ namespace CodeImp.DoomBuilder.Data // Use the built-in texture ImageData tex = LoadInternalTexture("MissingSky3D.png"); - Bitmap bmp = tex.GetBitmap(); + Bitmap bmp = tex.GetSkyboxBitmap(); Bitmap sky; lock (bmp) { diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs index f569ee37..dec6249e 100755 --- a/Source/Core/Data/ImageData.cs +++ b/Source/Core/Data/ImageData.cs @@ -186,7 +186,7 @@ namespace CodeImp.DoomBuilder.Data } // This returns the bitmap image - public Bitmap GetBitmap() + Bitmap GetBitmap() { // Image loaded successfully? if(!loadfailed && (imagestate == ImageLoadState.Ready) && (bitmap != null)) @@ -196,6 +196,41 @@ namespace CodeImp.DoomBuilder.Data return (loadfailed ? Properties.Resources.Failed : Properties.Resources.Hourglass); } + public int GetAlphaTestWidth() + { + return GetBitmap().Width; + } + + public int GetAlphaTestHeight() + { + return GetBitmap().Height; + } + + public bool AlphaTestPixel(int x, int y) + { + return GetBitmap().GetPixel(x, y).A > 0; + } + + public Image GetBackgroundBitmap() + { + return GetBitmap(); + } + + public Bitmap GetSkyboxBitmap() + { + return GetBitmap(); + } + + public Bitmap ExportBitmap() + { + return GetBitmap(); + } + + public Bitmap GetSpritePreview() + { + return GetBitmap(); + } + // Loads the image directly. This is needed by the background loader for some patches. public Bitmap LocalGetBitmap() { diff --git a/Source/Core/Data/ResourceImage.cs b/Source/Core/Data/ResourceImage.cs index c1097046..a1ffedee 100755 --- a/Source/Core/Data/ResourceImage.cs +++ b/Source/Core/Data/ResourceImage.cs @@ -85,7 +85,8 @@ namespace CodeImp.DoomBuilder.Data //mxd public override Image GetPreview() { - return base.GetBitmap(); + Stream bitmapdata = assembly.GetManifestResourceStream(resourcename); + return Image.FromStream(bitmapdata); } #endregion diff --git a/Source/Core/Windows/GridSetupForm.cs b/Source/Core/Windows/GridSetupForm.cs index d977d42e..94e896f6 100755 --- a/Source/Core/Windows/GridSetupForm.cs +++ b/Source/Core/Windows/GridSetupForm.cs @@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.Windows showbackground.Checked = true; backgroundname = General.Map.Grid.BackgroundName; backgroundsource = General.Map.Grid.BackgroundSource; - General.DisplayZoomedImage(backgroundimage, General.Map.Grid.Background.GetBitmap()); + General.DisplayZoomedImage(backgroundimage, General.Map.Grid.Background.GetBackgroundBitmap()); } else { @@ -94,7 +94,7 @@ namespace CodeImp.DoomBuilder.Windows backgroundsource = GridSetup.SOURCE_TEXTURES; ImageData img = General.Map.Data.GetTextureImage(result); img.LoadImage(); - General.DisplayZoomedImage(backgroundimage, img.GetBitmap()); + General.DisplayZoomedImage(backgroundimage, img.GetBackgroundBitmap()); } } @@ -110,7 +110,7 @@ namespace CodeImp.DoomBuilder.Windows backgroundsource = GridSetup.SOURCE_FLATS; ImageData img = General.Map.Data.GetFlatImage(result); img.LoadImage(); - General.DisplayZoomedImage(backgroundimage, img.GetBitmap()); + General.DisplayZoomedImage(backgroundimage, img.GetBackgroundBitmap()); } } @@ -125,7 +125,7 @@ namespace CodeImp.DoomBuilder.Windows backgroundsource = GridSetup.SOURCE_FILE; ImageData img = new FileImage(Path.GetFileNameWithoutExtension(backgroundname), backgroundname, false, 1.0f, 1.0f); img.LoadImage(); - General.DisplayZoomedImage(backgroundimage, new Bitmap(img.GetBitmap())); + General.DisplayZoomedImage(backgroundimage, new Bitmap(img.GetBackgroundBitmap())); img.Dispose(); } } diff --git a/Source/Plugins/BuilderModes/IO/WavefrontExporter.cs b/Source/Plugins/BuilderModes/IO/WavefrontExporter.cs index 21bfe2b5..13678401 100755 --- a/Source/Plugins/BuilderModes/IO/WavefrontExporter.cs +++ b/Source/Plugins/BuilderModes/IO/WavefrontExporter.cs @@ -95,7 +95,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO } if(!id.IsImageLoaded) id.LoadImage(); - Bitmap bmp = id.GetBitmap(); + Bitmap bmp = id.ExportBitmap(); lock (bmp) { bmp.Save(Path.Combine(settings.ObjPath, Path.GetFileNameWithoutExtension(s) + ".PNG"), ImageFormat.Png); @@ -123,7 +123,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO } if(!id.IsImageLoaded) id.LoadImage(); - Bitmap bmp = id.GetBitmap(); + Bitmap bmp = id.ExportBitmap(); // Handle duplicate names string flatname = s; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs index d00d0465..2ca6960c 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs @@ -519,36 +519,34 @@ namespace CodeImp.DoomBuilder.BuilderModes if(!BuilderPlug.Me.AlphaBasedTextureHighlighting || !Texture.IsImageLoaded || extrafloor == null || RenderPass == RenderPass.Solid || (!Texture.IsTranslucent && !Texture.IsMasked)) return true; - // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead - Bitmap image = Texture.GetBitmap(); + // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead + int imageWidth = Texture.GetAlphaTestWidth(); + int imageHeight = Texture.GetAlphaTestHeight(); - lock (image) - { - // Fetch ZDoom fields - float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f)); - Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f)); - Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f)); - Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight); + // Fetch ZDoom fields + float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationceiling", 0.0f)); + Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningceiling", 0.0f), level.sector.Fields.GetValue("ypanningceiling", 0.0f)); + Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscaleceiling", 1.0f), level.sector.Fields.GetValue("yscaleceiling", 1.0f)); + Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight); - // Texture coordinates - Vector2D o = pickintersect; - o = o.GetRotated(rotate); - o.y = -o.y; - o = (o + offset) * scale * texscale; - o.x = (o.x * image.Width) % image.Width; - o.y = (o.y * image.Height) % image.Height; + // Texture coordinates + Vector2D o = pickintersect; + o = o.GetRotated(rotate); + o.y = -o.y; + o = (o + offset) * scale * texscale; + o.x = (o.x * imageWidth) % imageWidth; + o.y = (o.y * imageHeight) % imageHeight; - // Make sure coordinates are inside of texture dimensions... - if (o.x < 0) o.x += image.Width; - if (o.y < 0) o.y += image.Height; + // Make sure coordinates are inside of texture dimensions... + if (o.x < 0) o.x += imageWidth; + if (o.y < 0) o.y += imageHeight; - // Make final texture coordinates... - int ox = General.Clamp((int)Math.Floor(o.x), 0, image.Width - 1); - int oy = General.Clamp((int)Math.Floor(o.y), 0, image.Height - 1); + // Make final texture coordinates... + int ox = General.Clamp((int)Math.Floor(o.x), 0, imageWidth - 1); + int oy = General.Clamp((int)Math.Floor(o.y), 0, imageHeight - 1); - // Check pixel alpha - return (image.GetPixel(ox, oy).A > 0); - } + // Check pixel alpha + return Texture.AlphaTestPixel(ox, oy); } return false; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs index 4327dd8c..8dc4bf31 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs @@ -452,35 +452,33 @@ namespace CodeImp.DoomBuilder.BuilderModes return true; // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead - Bitmap image = Texture.GetBitmap(); + int imageWidth = Texture.GetAlphaTestWidth(); + int imageHeight = Texture.GetAlphaTestHeight(); - lock (image) - { - // Fetch ZDoom fields - float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f)); - Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f)); - Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f)); - Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight); + // Fetch ZDoom fields + float rotate = Angle2D.DegToRad(level.sector.Fields.GetValue("rotationfloor", 0.0f)); + Vector2D offset = new Vector2D(level.sector.Fields.GetValue("xpanningfloor", 0.0f), level.sector.Fields.GetValue("ypanningfloor", 0.0f)); + Vector2D scale = new Vector2D(level.sector.Fields.GetValue("xscalefloor", 1.0f), level.sector.Fields.GetValue("yscalefloor", 1.0f)); + Vector2D texscale = new Vector2D(1.0f / Texture.ScaledWidth, 1.0f / Texture.ScaledHeight); - // Texture coordinates - Vector2D o = pickintersect; - o = o.GetRotated(rotate); - o.y = -o.y; - o = (o + offset) * scale * texscale; - o.x = (o.x * image.Width) % image.Width; - o.y = (o.y * image.Height) % image.Height; + // Texture coordinates + Vector2D o = pickintersect; + o = o.GetRotated(rotate); + o.y = -o.y; + o = (o + offset) * scale * texscale; + o.x = (o.x * imageWidth) % imageWidth; + o.y = (o.y * imageHeight) % imageHeight; - // Make sure coordinates are inside of texture dimensions... - if (o.x < 0) o.x += image.Width; - if (o.y < 0) o.y += image.Height; + // Make sure coordinates are inside of texture dimensions... + if (o.x < 0) o.x += imageWidth; + if (o.y < 0) o.y += imageHeight; - // Make final texture coordinates... - int ox = General.Clamp((int)Math.Floor(o.x), 0, image.Width - 1); - int oy = General.Clamp((int)Math.Floor(o.y), 0, image.Height - 1); + // Make final texture coordinates... + int ox = General.Clamp((int)Math.Floor(o.x), 0, imageWidth - 1); + int oy = General.Clamp((int)Math.Floor(o.y), 0, imageHeight - 1); - // Check pixel alpha - return (image.GetPixel(ox, oy).A > 0); - } + // Check pixel alpha + return Texture.AlphaTestPixel(ox, oy); } return false; diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs index 371b2dd3..d477b6f0 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddle3D.cs @@ -344,29 +344,27 @@ namespace CodeImp.DoomBuilder.BuilderModes if(Sidedef != Sidedef.Line.Front) u = 1.0f - u; // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead - Bitmap image = Texture.GetBitmap(); + int imageWidth = Texture.GetAlphaTestWidth(); + int imageHeight = Texture.GetAlphaTestHeight(); - lock (image) - { - // Determine texture scale... - Vector2D imgscale = new Vector2D((float)Texture.Width / image.Width, (float)Texture.Height / image.Height); - Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale; + // Determine texture scale... + Vector2D imgscale = new Vector2D((float)Texture.Width / imageWidth, (float)Texture.Height / imageHeight); + Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale; - // Get correct offset to texture space... - float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid"); - int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / texscale.x + (texoffsetx / imgscale.x)) % image.Width); + // Get correct offset to texture space... + float texoffsetx = Sidedef.OffsetX + sourceside.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid") + UniFields.GetFloat(sourceside.Fields, "offsetx_mid"); + int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(sourceside.Fields, "scalex_mid", 1.0f) / texscale.x + (texoffsetx / imgscale.x)) % imageWidth); - float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid"); - int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / texscale.y - (texoffsety / imgscale.y)) % image.Height); + float texoffsety = Sidedef.OffsetY + sourceside.OffsetY + UniFields.GetFloat(Sidedef.Fields, "offsety_mid") + UniFields.GetFloat(sourceside.Fields, "offsety_mid"); + int oy = (int)Math.Ceiling(((pickintersect.z - sourceside.Sector.CeilHeight) * UniFields.GetFloat(sourceside.Fields, "scaley_mid", 1.0f) / texscale.y - (texoffsety / imgscale.y)) % imageHeight); - // Make sure offsets are inside of texture dimensions... - if (ox < 0) ox += image.Width; - if (oy < 0) oy += image.Height; + // Make sure offsets are inside of texture dimensions... + if (ox < 0) ox += imageWidth; + if (oy < 0) oy += imageHeight; - // Check pixel alpha - Point pixelpos = new Point(General.Clamp(ox, 0, image.Width - 1), General.Clamp(image.Height - oy, 0, image.Height - 1)); - return (image.GetPixel(pixelpos.X, pixelpos.Y).A > 0 && base.PickAccurate(@from, to, dir, ref u_ray)); - } + // Check pixel alpha + Point pixelpos = new Point(General.Clamp(ox, 0, imageWidth - 1), General.Clamp(imageHeight - oy, 0, imageHeight - 1)); + return (Texture.AlphaTestPixel(pixelpos.X, pixelpos.Y) && base.PickAccurate(@from, to, dir, ref u_ray)); } // Return texture name diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs index 38463b23..abf3d541 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualMiddleDouble.cs @@ -296,43 +296,41 @@ namespace CodeImp.DoomBuilder.BuilderModes new Line2D(from, to).GetIntersection(Sidedef.Line.Line, out u); if(Sidedef != Sidedef.Line.Front) u = 1.0f - u; - // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead - Bitmap image = Texture.GetBitmap(); + // Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead + int imageWidth = Texture.GetAlphaTestWidth(); + int imageHeight = Texture.GetAlphaTestHeight(); - lock (image) + // Determine texture scale... + Vector2D imgscale = new Vector2D((float)Texture.Width / imageWidth, (float)Texture.Height / imageHeight); + Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale; + + // Get correct offset to texture space... + int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(Sidedef.Fields, "scalex_mid", 1.0f) / texscale.x + + ((Sidedef.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid")) / imgscale.x)) + % imageWidth); + + int oy; + if (repeatmidtex) { - // Determine texture scale... - Vector2D imgscale = new Vector2D((float)Texture.Width / image.Width, (float)Texture.Height / image.Height); - Vector2D texscale = (Texture is HiResImage) ? imgscale * Texture.Scale : Texture.Scale; - - // Get correct offset to texture space... - int ox = (int)Math.Floor((u * Sidedef.Line.Length * UniFields.GetFloat(Sidedef.Fields, "scalex_mid", 1.0f) / texscale.x - + ((Sidedef.OffsetX + UniFields.GetFloat(Sidedef.Fields, "offsetx_mid")) / imgscale.x)) - % image.Width); - - int oy; - if (repeatmidtex) - { - bool pegbottom = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag); - float zoffset = (pegbottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilHeight); - oy = (int)Math.Floor(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y - - ((Sidedef.OffsetY - UniFields.GetFloat(Sidedef.Fields, "offsety_mid")) / imgscale.y)) - % image.Height); - } - else - { - float zoffset = bottomclipplane.GetZ(pickintersect); - oy = (int)Math.Ceiling(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y) % image.Height); - } - - // Make sure offsets are inside of texture dimensions... - if (ox < 0) ox += image.Width; - if (oy < 0) oy += image.Height; - - // Check pixel alpha - Point pixelpos = new Point(General.Clamp(ox, 0, image.Width - 1), General.Clamp(image.Height - oy, 0, image.Height - 1)); - return (image.GetPixel(pixelpos.X, pixelpos.Y).A > 0 && base.PickAccurate(from, to, dir, ref u_ray)); + bool pegbottom = Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag); + float zoffset = (pegbottom ? Sidedef.Sector.FloorHeight : Sidedef.Sector.CeilHeight); + oy = (int)Math.Floor(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y + - ((Sidedef.OffsetY - UniFields.GetFloat(Sidedef.Fields, "offsety_mid")) / imgscale.y)) + % imageHeight); } + else + { + float zoffset = bottomclipplane.GetZ(pickintersect); + oy = (int)Math.Ceiling(((pickintersect.z - zoffset) * UniFields.GetFloat(Sidedef.Fields, "scaley_mid", 1.0f) / texscale.y) % imageHeight); + } + + // Make sure offsets are inside of texture dimensions... + if (ox < 0) ox += imageWidth; + if (oy < 0) oy += imageHeight; + + // Check pixel alpha + Point pixelpos = new Point(General.Clamp(ox, 0, imageWidth - 1), General.Clamp(imageHeight - oy, 0, imageHeight - 1)); + return (Texture.AlphaTestPixel(pixelpos.X, pixelpos.Y) && base.PickAccurate(from, to, dir, ref u_ray)); } // Return texture name