mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 22:41:46 +00:00
textures (patches) rendering added
This commit is contained in:
parent
6df14416da
commit
aa73caad3c
15 changed files with 150 additions and 28 deletions
|
@ -8,7 +8,7 @@ using System.Collections.Specialized;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class DataLocationList : List<DataLocation>
|
||||
internal sealed class DataLocationList : List<DataLocation>
|
||||
{
|
||||
#region ================== Constructors
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class DataManager : IDisposable
|
||||
internal sealed class DataManager : IDisposable
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Properties
|
||||
|
||||
// Disposing
|
||||
public Playpal Palette { get { return palette; } }
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class DirectoryReader : DataReader
|
||||
internal sealed class DirectoryReader : DataReader
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ using System.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class FileImage : ImageData
|
||||
internal sealed class FileImage : ImageData
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Text;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class FlatImage : ImageData
|
||||
internal sealed class FlatImage : ImageData
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Properties
|
||||
private string name;
|
||||
private long longname;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected float scaledwidth;
|
||||
protected float scaledheight;
|
||||
|
||||
// GDI bitmap
|
||||
protected Bitmap bitmap;
|
||||
|
@ -65,8 +69,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public PixelColor* PixelData { get { return pixeldata; } }
|
||||
public Bitmap Bitmap { get { return bitmap; } }
|
||||
public Texture Texture { get { return texture; } }
|
||||
public bool IsLoaded { get { return (bitmap == null); } }
|
||||
public bool IsLoaded { get { return (bitmap != null); } }
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public int Width { get { return width; } }
|
||||
public int Height { get { return height; } }
|
||||
public float ScaledWidth { get { return scaledwidth; } }
|
||||
public float ScaledHeight { get { return scaledheight; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ using CodeImp.DoomBuilder.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class PatchNames
|
||||
internal sealed class PatchNames
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class Playpal
|
||||
internal sealed class Playpal
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Text;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class SpriteImage : ImageData
|
||||
internal sealed class SpriteImage : ImageData
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -21,12 +21,17 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class TextureImage : ImageData
|
||||
internal sealed unsafe class TextureImage : ImageData
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
@ -35,8 +40,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#region ================== Variables
|
||||
|
||||
private List<TexturePatch> patches;
|
||||
private int width;
|
||||
private int height;
|
||||
private float scalex;
|
||||
private float scaley;
|
||||
|
||||
|
@ -56,6 +59,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
this.height = height;
|
||||
this.scalex = scalex;
|
||||
this.scaley = scaley;
|
||||
this.scaledwidth = (float)width * scalex;
|
||||
this.scaledheight = (float)height * scaley;
|
||||
this.patches = new List<TexturePatch>();
|
||||
SetName(name);
|
||||
|
||||
|
@ -90,9 +95,36 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// This loads the image
|
||||
public override void LoadImage()
|
||||
{
|
||||
uint datalength = (uint)(width * height * sizeof(PixelColor));
|
||||
DoomPictureReader reader = new DoomPictureReader(General.Map.Data.Palette);
|
||||
BitmapData bitmapdata;
|
||||
PixelColor* pixels;
|
||||
Stream patchdata;
|
||||
|
||||
// Leave when already loaded
|
||||
if(this.IsLoaded) return;
|
||||
|
||||
// Create texture bitmap
|
||||
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
pixels = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
|
||||
|
||||
// Go for all patches
|
||||
foreach(TexturePatch p in patches)
|
||||
{
|
||||
// Get the patch data stream
|
||||
patchdata = General.Map.Data.GetPatchData(p.lumpname);
|
||||
if(patchdata != null)
|
||||
{
|
||||
// Read the patch and draw it onto the memory
|
||||
patchdata.Seek(0, SeekOrigin.Begin);
|
||||
reader.DrawToPixelData(patchdata, pixels, width, height, p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
bitmap.UnlockBits(bitmapdata);
|
||||
|
||||
// Pass on to base
|
||||
base.LoadImage();
|
||||
|
|
|
@ -32,9 +32,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
internal struct TexturePatch
|
||||
{
|
||||
private string lumpname;
|
||||
private int x;
|
||||
private int y;
|
||||
public string lumpname;
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
// Constructor
|
||||
public TexturePatch(string lumpname, int x, int y)
|
||||
|
|
|
@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal class WADReader : DataReader
|
||||
internal sealed class WADReader : DataReader
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ using CodeImp.DoomBuilder.Geometry;
|
|||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -63,45 +64,103 @@ namespace CodeImp.DoomBuilder.IO
|
|||
#region ================== Methods
|
||||
|
||||
// This creates a Bitmap from the given data
|
||||
// Returns null on failure
|
||||
public Bitmap ReadAsBitmap(Stream stream)
|
||||
{
|
||||
// TODO: Read as pixel data and copy pixels
|
||||
return null;
|
||||
BitmapData bitmapdata;
|
||||
PixelColor* pixeldata;
|
||||
PixelColor* targetdata;
|
||||
int width, height, x, y;
|
||||
Bitmap bmp;
|
||||
|
||||
// Read pixel data
|
||||
pixeldata = ReadAsPixelData(stream, out width, out height, out x, out y);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
// Create bitmap and lock pixels
|
||||
bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory((void*)targetdata, (void*)pixeldata, new UIntPtr((uint)(width * height * sizeof(PixelColor))));
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
return bmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed loading picture
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// This draws the picture to the given pixel color data
|
||||
// Throws exception on failure
|
||||
public void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
|
||||
{
|
||||
// TODO: Read as pixel data and copy pixels
|
||||
PixelColor* pixeldata;
|
||||
int width, height, ox, oy, tx, ty;
|
||||
|
||||
// Read pixel data
|
||||
pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
// Go for all source pixels
|
||||
// We don't care about the original image offset, so reuse ox/oy
|
||||
for(ox = 0; ox < width; ox++)
|
||||
{
|
||||
for(oy = 0; oy < height; oy++)
|
||||
{
|
||||
// Copy this pixel?
|
||||
if(pixeldata[oy * width + ox].a > 0.5f)
|
||||
{
|
||||
// Calculate target pixel and copy when within bounds
|
||||
tx = x + ox;
|
||||
ty = y + oy;
|
||||
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
|
||||
target[ty * targetwidth + tx] = pixeldata[oy * width + ox];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This creates pixel color data from the given data
|
||||
// Returns null on failure
|
||||
public PixelColor* ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety)
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
PixelColor* pixeldata = null;
|
||||
uint datalength = 0;
|
||||
int y, count, p;
|
||||
|
||||
int[] columns;
|
||||
int dataoffset;
|
||||
|
||||
// Initialize
|
||||
width = 0;
|
||||
height = 0;
|
||||
offsetx = 0;
|
||||
offsety = 0;
|
||||
|
||||
dataoffset = (int)stream.Position;
|
||||
|
||||
// Need at least 4 bytes
|
||||
if((stream.Length - stream.Position) < 4) return null;
|
||||
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
// Read size and offset
|
||||
width = reader.ReadInt16();
|
||||
height = reader.ReadInt16();
|
||||
offsetx = reader.ReadInt16();
|
||||
offsety = reader.ReadInt16();
|
||||
|
||||
// Skip the column addresses
|
||||
stream.Seek(4 * width, SeekOrigin.Current);
|
||||
// Read the column addresses
|
||||
columns = new int[width];
|
||||
for(int x = 0; x < width; x++) columns[x] = reader.ReadInt32();
|
||||
|
||||
// Allocate memory
|
||||
datalength = (uint)(sizeof(PixelColor) * width * height);
|
||||
|
@ -111,6 +170,9 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// Go for all columns
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
// Seek to column start
|
||||
stream.Seek(dataoffset + columns[x], SeekOrigin.Begin);
|
||||
|
||||
// Read first post start
|
||||
y = reader.ReadByte();
|
||||
|
||||
|
@ -143,6 +205,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
// Return pointer
|
||||
return pixeldata;
|
||||
#if !DEBUG
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
|
@ -152,6 +215,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// Return nothing
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -61,6 +61,21 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This blends two colors with respect to alpha
|
||||
public PixelColor Blend(PixelColor a, PixelColor b)
|
||||
{
|
||||
PixelColor c = new PixelColor();
|
||||
float ba;
|
||||
|
||||
ba = (float)a.a * 0.003921568627450980392156862745098f;
|
||||
c.r = (byte)((float)a.r * (1f - ba) + (float)b.r * ba);
|
||||
c.g = (byte)((float)a.g * (1f - ba) + (float)b.g * ba);
|
||||
c.b = (byte)((float)a.b * (1f - ba) + (float)b.b * ba);
|
||||
c.a = (byte)((float)a.a * (1f - ba) + ba);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// This draws a pixel alpha blended
|
||||
private void DrawPixelAlpha(int x, int y, PixelColor c)
|
||||
{
|
||||
float a;
|
||||
|
||||
// Draw only when within range
|
||||
if((x >= 0) && (x < width) && (y >= 0) && (y < height))
|
||||
{
|
||||
|
@ -223,10 +225,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
else
|
||||
{
|
||||
// Blend with pixel
|
||||
a = (float)c.a * 0.003921568627450980392156862745098f;
|
||||
if((int)p->a + (int)c.a > 255) p->a = 255; else p->a += c.a;
|
||||
p->r = (byte)((float)p->r * (1f - (float)c.a) + (float)c.r * (float)c.a);
|
||||
p->g = (byte)((float)p->g * (1f - (float)c.a) + (float)c.g * (float)c.a);
|
||||
p->b = (byte)((float)p->b * (1f - (float)c.a) + (float)c.b * (float)c.a);
|
||||
p->r = (byte)((float)p->r * (1f - a) + (float)c.r * a);
|
||||
p->g = (byte)((float)p->g * (1f - a) + (float)c.g * a);
|
||||
p->b = (byte)((float)p->b * (1f - a) + (float)c.b * a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue