textures (patches) rendering added

This commit is contained in:
codeimp 2007-10-08 14:29:31 +00:00
parent 6df14416da
commit aa73caad3c
15 changed files with 150 additions and 28 deletions

View file

@ -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

View file

@ -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

View file

@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.IO;
namespace CodeImp.DoomBuilder.Data
{
internal class DirectoryReader : DataReader
internal sealed class DirectoryReader : DataReader
{
#region ================== Constants

View file

@ -29,7 +29,7 @@ using System.IO;
namespace CodeImp.DoomBuilder.Data
{
internal class FileImage : ImageData
internal sealed class FileImage : ImageData
{
#region ================== Variables

View file

@ -6,7 +6,7 @@ using System.Text;
namespace CodeImp.DoomBuilder.Data
{
internal class FlatImage : ImageData
internal sealed class FlatImage : ImageData
{
#region ================== Constants

View file

@ -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

View file

@ -28,7 +28,7 @@ using CodeImp.DoomBuilder.IO;
namespace CodeImp.DoomBuilder.Data
{
internal class PatchNames
internal sealed class PatchNames
{
#region ================== Constants

View file

@ -28,7 +28,7 @@ using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.Data
{
internal class Playpal
internal sealed class Playpal
{
#region ================== Constants

View file

@ -6,7 +6,7 @@ using System.Text;
namespace CodeImp.DoomBuilder.Data
{
internal class SpriteImage : ImageData
internal sealed class SpriteImage : ImageData
{
#region ================== Constants

View file

@ -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();

View file

@ -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)

View file

@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.IO;
namespace CodeImp.DoomBuilder.Data
{
internal class WADReader : DataReader
internal sealed class WADReader : DataReader
{
#region ================== Constants

View file

@ -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

View file

@ -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
}
}

View file

@ -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);
}
}
}