mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
[Broken] Optimise /imgprint to use native bitmap pixel getters.
This commit is contained in:
parent
e29a3d31c6
commit
4d06b62f8e
@ -34,42 +34,21 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
internal int Mode, Direction;
|
internal int Mode, Direction;
|
||||||
internal bool Layer;
|
internal bool Layer;
|
||||||
internal string Filename;
|
internal string Filename;
|
||||||
|
Vec3S32 dx, dy, adj;
|
||||||
|
PaletteEntry cur = default(PaletteEntry);
|
||||||
|
|
||||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
|
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
|
||||||
Vec3U16 p0 = Clamp(marks[0]);
|
Vec3U16 p0 = Clamp(marks[0]);
|
||||||
PaletteEntry[] palette = ImagePalette.GetPalette(Mode);
|
PaletteEntry[] palette = ImagePalette.GetPalette(Mode);
|
||||||
PaletteEntry cur = default(PaletteEntry);
|
|
||||||
|
|
||||||
IPalette selector = null;
|
IPalette selector = null;
|
||||||
if (Mode == 6) selector = new GrayscalePalette();
|
if (Mode == 6) selector = new GrayscalePalette();
|
||||||
else selector = new RgbPalette();
|
else selector = new RgbPalette();
|
||||||
selector.SetAvailableBlocks(palette);
|
selector.SetAvailableBlocks(palette);
|
||||||
|
CalcDirectionVectors(Direction);
|
||||||
Vec3S32 dx, dy, adj;
|
|
||||||
CalcMul(Layer, Direction, out dx, out dy, out adj);
|
|
||||||
|
|
||||||
for (int yy = 0; yy < Source.Height; yy++)
|
using (PixelGetter getter = new PixelGetter(Source)) {
|
||||||
for (int xx = 0; xx < Source.Width; xx++)
|
getter.Init();
|
||||||
{
|
getter.Iterate(P => OutputPixel(P, selector, output));
|
||||||
ushort X = (ushort)(p0.X + dx.X * xx + dy.X * yy);
|
|
||||||
ushort Y = (ushort)(p0.Y + dx.Y * xx + dy.Y * yy);
|
|
||||||
ushort Z = (ushort)(p0.Z + dx.Z * xx + dy.Z * yy);
|
|
||||||
|
|
||||||
Draw.Color col = Source.GetPixel(xx, yy);
|
|
||||||
cur.R = col.R; cur.G = col.G; cur.B = col.B;
|
|
||||||
int position;
|
|
||||||
cur.Block = selector.BestMatch(cur, out position);
|
|
||||||
if (Mode == 1 || Mode == 3) {
|
|
||||||
int threshold = Mode == 1 ? 20 : 3;
|
|
||||||
// Back layer block
|
|
||||||
if (position <= threshold) {
|
|
||||||
X = (ushort)(X + adj.X);
|
|
||||||
Z = (ushort)(Z + adj.Z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col.A < 20) cur.Block = Block.air;
|
|
||||||
output(Place(X, Y, Z, cur.Block, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Source.Dispose();
|
Source.Dispose();
|
||||||
@ -79,9 +58,32 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
Player.Message(p, "Finished printing image using " + ImagePalette.Names[Mode]);
|
Player.Message(p, "Finished printing image using " + ImagePalette.Names[Mode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalcMul(bool layer, int dir,
|
void OutputPixel(Pixel P, IPalette selector, Action<DrawOpBlock> output) {
|
||||||
out Vec3S32 signX, out Vec3S32 signY, out Vec3S32 adj) {
|
ushort x = (ushort)(Origin.X + dx.X * P.X + dy.X * P.Y);
|
||||||
signX = default(Vec3S32); signY = default(Vec3S32); adj = default(Vec3S32);
|
ushort y = (ushort)(Origin.Y + dx.Y * P.X + dy.Y * P.Y);
|
||||||
|
ushort z = (ushort)(Origin.Z + dx.Z * P.X + dy.Z * P.Y);
|
||||||
|
|
||||||
|
byte alpha = (byte)(P.ARGB >> 24);
|
||||||
|
if (alpha < 20) { output(Place(x, y, z, Block.air, 0)); return; }
|
||||||
|
cur.R = (byte)(P.ARGB >> 16);
|
||||||
|
cur.G = (byte)(P.ARGB >> 16);
|
||||||
|
cur.B = (byte)(P.ARGB >> 16);
|
||||||
|
|
||||||
|
int position;
|
||||||
|
byte block = selector.BestMatch(cur, out position);
|
||||||
|
if (Mode == 1 || Mode == 3) {
|
||||||
|
int threshold = Mode == 1 ? 20 : 3;
|
||||||
|
// Back layer block
|
||||||
|
if (position <= threshold) {
|
||||||
|
x = (ushort)(x + adj.X);
|
||||||
|
z = (ushort)(z + adj.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output(Place(x, y, z, cur.Block, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalcDirectionVectors(int dir) {
|
||||||
|
dx = default(Vec3S32); dy = default(Vec3S32); adj = default(Vec3S32);
|
||||||
|
|
||||||
// Calculate back layer offset
|
// Calculate back layer offset
|
||||||
if (dir == 0) adj.Z = 1;
|
if (dir == 0) adj.Z = 1;
|
||||||
@ -89,17 +91,17 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (dir == 2) adj.X = -1;
|
if (dir == 2) adj.X = -1;
|
||||||
if (dir == 3) adj.X = 1;
|
if (dir == 3) adj.X = 1;
|
||||||
|
|
||||||
if (layer) {
|
if (Layer) {
|
||||||
if (dir == 0) { signX.X = 1; signY.Z = -1; }
|
if (dir == 0) { dx.X = 1; dy.Z = -1; }
|
||||||
if (dir == 1) { signX.X = -1; signY.Z = 1; }
|
if (dir == 1) { dx.X = -1; dy.Z = 1; }
|
||||||
if (dir == 2) { signX.Z = 1; signY.X = 1; }
|
if (dir == 2) { dx.Z = 1; dy.X = 1; }
|
||||||
if (dir == 3) { signX.Z = -1; signY.X = -1; }
|
if (dir == 3) { dx.Z = -1; dy.X = -1; }
|
||||||
} else {
|
} else {
|
||||||
signY.Y = 1; // Oriented upwards
|
dy.Y = 1; // Oriented upwards
|
||||||
if (dir == 0) signX.X = 1;
|
if (dir == 0) dx.X = 1;
|
||||||
if (dir == 1) signX.X = -1;
|
if (dir == 1) dx.X = -1;
|
||||||
if (dir == 2) signX.Z = 1;
|
if (dir == 2) dx.Z = 1;
|
||||||
if (dir == 3) signX.Z = -1;
|
if (dir == 3) dx.Z = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,7 @@ namespace MCGalaxy.Drawing {
|
|||||||
int* row = (int*)(scan0 + y * data.Stride);
|
int* row = (int*)(scan0 + y * data.Stride);
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
pixel.X = (ushort)x;
|
pixel.X = (ushort)x;
|
||||||
int argb = row[x];
|
pixel.ARGB = row[x];
|
||||||
|
|
||||||
pixel.R = (byte)(argb >> 16);
|
|
||||||
pixel.G = (byte)(argb >> 8);
|
|
||||||
pixel.B = (byte)(argb >> 8);
|
|
||||||
callback(pixel);
|
callback(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,12 +67,7 @@ namespace MCGalaxy.Drawing {
|
|||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
pixel.X = (ushort)x; pixel.Y = (ushort)y;
|
pixel.X = (ushort)x; pixel.Y = (ushort)y;
|
||||||
Color col = bmp.GetPixel(x, y);
|
pixel.ARGB = bmp.GetPixel(x, y).ToArgb(); // R/G/B properties incur overhead
|
||||||
int argb = col.ToArgb(); // R/G/B properties incur overhead
|
|
||||||
|
|
||||||
pixel.R = (byte)(argb >> 16);
|
|
||||||
pixel.G = (byte)(argb >> 8);
|
|
||||||
pixel.B = (byte)(argb >> 8);
|
|
||||||
callback(pixel);
|
callback(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,6 +81,6 @@ namespace MCGalaxy.Drawing {
|
|||||||
|
|
||||||
public struct Pixel {
|
public struct Pixel {
|
||||||
public ushort X, Y;
|
public ushort X, Y;
|
||||||
public byte R, G, B;
|
public int ARGB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user