Export selection as image: potentially decreased memory usage when also exporting brightmaps

This commit is contained in:
biwa 2020-10-17 12:42:23 +02:00
parent 14e4162d35
commit 0a1e40f11d

View file

@ -98,17 +98,48 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
/// Exports the sectors to images /// Exports the sectors to images
/// </summary> /// </summary>
public void Export() public void Export()
{
// Do the normally textured image and the brightmap after each other because creating the image requires
// consecutively free memory, and creating two big images at the same time has a higher chance to fail.
// Because of the GC there's of course no guarantee that the memory is freed in time
// Normally textures image
using (Bitmap image = CreateImage(false))
{
if (settings.Tiles)
SaveImageAsTiles(image);
else
image.Save(Path.Combine(settings.Path, settings.Name) + settings.Extension, settings.ImageFormat);
}
// The brightmap
if(settings.Brightmap)
{
using (Bitmap image = CreateImage(true))
{
if (settings.Tiles)
SaveImageAsTiles(image, "_brightmap");
else
image.Save(Path.Combine(settings.Path, settings.Name) + "_brightmap" + settings.Extension, settings.ImageFormat);
}
}
}
/// <summary>
/// Create the image ready to be exported
/// </summary>
/// <param name="asbrightmap">True if the image should be a brightmap, false if normally textured</param>
/// <returns>The image to be exported</returns>
private Bitmap CreateImage(bool asbrightmap)
{ {
Bitmap texturebitmap = null; Bitmap texturebitmap = null;
Bitmap brightmapbitmap = null;
Graphics gbrightmap = null;
Graphics gtexture = null; Graphics gtexture = null;
Vector2D offset; Vector2D offset;
Vector2D size; Vector2D size;
GetSizeAndOffset(out size, out offset); GetSizeAndOffset(out size, out offset);
// Normal texture // The texture
texturebitmap = new Bitmap((int)size.x, (int)size.y, settings.PixelFormat); texturebitmap = new Bitmap((int)size.x, (int)size.y, settings.PixelFormat);
gtexture = Graphics.FromImage(texturebitmap); gtexture = Graphics.FromImage(texturebitmap);
gtexture.Clear(Color.Black); // If we don't clear to black we'll see seams where the sectors touch, due to the AA gtexture.Clear(Color.Black); // If we don't clear to black we'll see seams where the sectors touch, due to the AA
@ -117,18 +148,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
gtexture.PixelOffsetMode = PixelOffsetMode.HighQuality; gtexture.PixelOffsetMode = PixelOffsetMode.HighQuality;
gtexture.SmoothingMode = SmoothingMode.AntiAlias; // Without AA the sector edges will be quite rough gtexture.SmoothingMode = SmoothingMode.AntiAlias; // Without AA the sector edges will be quite rough
// Brightmap
if (settings.Brightmap)
{
brightmapbitmap = new Bitmap((int)size.x, (int)size.y, settings.PixelFormat);
gbrightmap = Graphics.FromImage(brightmapbitmap);
gbrightmap.Clear(Color.Black); // If we don't clear to black we'll see seams where the sectors touch, due to the AA
gbrightmap.InterpolationMode = InterpolationMode.HighQualityBilinear;
gbrightmap.CompositingQuality = CompositingQuality.HighQuality;
gbrightmap.PixelOffsetMode = PixelOffsetMode.HighQuality;
gbrightmap.SmoothingMode = SmoothingMode.AntiAlias; // Without AA the sector edges will be quite rough
}
foreach (Sector s in sectors) foreach (Sector s in sectors)
{ {
GraphicsPath p = new GraphicsPath(); GraphicsPath p = new GraphicsPath();
@ -151,6 +170,14 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
p.CloseFigure(); p.CloseFigure();
} }
if (asbrightmap)
{
// Create the brightmap based on the sector brightness
SolidBrush sbrush = new SolidBrush(Color.FromArgb(255, s.Brightness, s.Brightness, s.Brightness));
gtexture.FillPath(sbrush, p);
}
else
{
Bitmap brushtexture; Bitmap brushtexture;
Vector2D textureoffset = new Vector2D(); Vector2D textureoffset = new Vector2D();
Vector2D texturescale = new Vector2D(); Vector2D texturescale = new Vector2D();
@ -188,9 +215,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
texturescale.y = 1.0 / s.Fields.GetValue("yscaleceiling", 1.0); texturescale.y = 1.0 / s.Fields.GetValue("yscaleceiling", 1.0);
} }
if (!settings.Fullbright)
brushtexture = AdjustBrightness(brushtexture, s.Brightness > 0 ? s.Brightness / 255.0f : 0.0f);
// Create the transformation matrix // Create the transformation matrix
Matrix matrix = new Matrix(); Matrix matrix = new Matrix();
matrix.Rotate(rotation); matrix.Rotate(rotation);
@ -199,36 +223,19 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO
matrix.Translate(-(float)textureoffset.x, -(float)textureoffset.y); // Texture offset matrix.Translate(-(float)textureoffset.x, -(float)textureoffset.y); // Texture offset
matrix.Scale((float)texturescale.x, (float)texturescale.y); matrix.Scale((float)texturescale.x, (float)texturescale.y);
if (!settings.Fullbright)
brushtexture = AdjustBrightness(brushtexture, s.Brightness > 0 ? s.Brightness / 255.0f : 0.0f);
// Create the texture brush and apply the matrix // Create the texture brush and apply the matrix
TextureBrush tbrush = new TextureBrush(brushtexture); TextureBrush tbrush = new TextureBrush(brushtexture);
tbrush.Transform = matrix; tbrush.Transform = matrix;
// Draw the islands of the sector // Draw the islands of the sector
gtexture.FillPath(tbrush, p); gtexture.FillPath(tbrush, p);
// Create the brightmap based on the sector brightness
if (settings.Brightmap)
{
SolidBrush sbrush = new SolidBrush(Color.FromArgb(255, s.Brightness, s.Brightness, s.Brightness));
gbrightmap.FillPath(sbrush, p);
} }
} }
// Finally save the image(s) return texturebitmap;
if (settings.Tiles)
{
SaveImageAsTiles(texturebitmap);
if (settings.Brightmap)
SaveImageAsTiles(brightmapbitmap, "_brightmap");
}
else
{
texturebitmap.Save(Path.Combine(settings.Path, settings.Name) + settings.Extension, settings.ImageFormat);
if (settings.Brightmap)
brightmapbitmap.Save(Path.Combine(settings.Path, settings.Name) + "_brightmap" + settings.Extension, settings.ImageFormat);
}
} }
/// <summary> /// <summary>