mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 03:55:18 -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 bool Layer;
|
||||
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) {
|
||||
Vec3U16 p0 = Clamp(marks[0]);
|
||||
PaletteEntry[] palette = ImagePalette.GetPalette(Mode);
|
||||
PaletteEntry cur = default(PaletteEntry);
|
||||
|
||||
IPalette selector = null;
|
||||
if (Mode == 6) selector = new GrayscalePalette();
|
||||
else selector = new RgbPalette();
|
||||
selector.SetAvailableBlocks(palette);
|
||||
|
||||
Vec3S32 dx, dy, adj;
|
||||
CalcMul(Layer, Direction, out dx, out dy, out adj);
|
||||
CalcDirectionVectors(Direction);
|
||||
|
||||
for (int yy = 0; yy < Source.Height; yy++)
|
||||
for (int xx = 0; xx < Source.Width; xx++)
|
||||
{
|
||||
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));
|
||||
using (PixelGetter getter = new PixelGetter(Source)) {
|
||||
getter.Init();
|
||||
getter.Iterate(P => OutputPixel(P, selector, output));
|
||||
}
|
||||
|
||||
Source.Dispose();
|
||||
@ -79,9 +58,32 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
Player.Message(p, "Finished printing image using " + ImagePalette.Names[Mode]);
|
||||
}
|
||||
|
||||
void CalcMul(bool layer, int dir,
|
||||
out Vec3S32 signX, out Vec3S32 signY, out Vec3S32 adj) {
|
||||
signX = default(Vec3S32); signY = default(Vec3S32); adj = default(Vec3S32);
|
||||
void OutputPixel(Pixel P, IPalette selector, Action<DrawOpBlock> output) {
|
||||
ushort x = (ushort)(Origin.X + dx.X * P.X + dy.X * P.Y);
|
||||
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
|
||||
if (dir == 0) adj.Z = 1;
|
||||
@ -89,17 +91,17 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
if (dir == 2) adj.X = -1;
|
||||
if (dir == 3) adj.X = 1;
|
||||
|
||||
if (layer) {
|
||||
if (dir == 0) { signX.X = 1; signY.Z = -1; }
|
||||
if (dir == 1) { signX.X = -1; signY.Z = 1; }
|
||||
if (dir == 2) { signX.Z = 1; signY.X = 1; }
|
||||
if (dir == 3) { signX.Z = -1; signY.X = -1; }
|
||||
if (Layer) {
|
||||
if (dir == 0) { dx.X = 1; dy.Z = -1; }
|
||||
if (dir == 1) { dx.X = -1; dy.Z = 1; }
|
||||
if (dir == 2) { dx.Z = 1; dy.X = 1; }
|
||||
if (dir == 3) { dx.Z = -1; dy.X = -1; }
|
||||
} else {
|
||||
signY.Y = 1; // Oriented upwards
|
||||
if (dir == 0) signX.X = 1;
|
||||
if (dir == 1) signX.X = -1;
|
||||
if (dir == 2) signX.Z = 1;
|
||||
if (dir == 3) signX.Z = -1;
|
||||
dy.Y = 1; // Oriented upwards
|
||||
if (dir == 0) dx.X = 1;
|
||||
if (dir == 1) dx.X = -1;
|
||||
if (dir == 2) dx.Z = 1;
|
||||
if (dir == 3) dx.Z = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,11 +54,7 @@ namespace MCGalaxy.Drawing {
|
||||
int* row = (int*)(scan0 + y * data.Stride);
|
||||
for (int x = 0; x < width; x++) {
|
||||
pixel.X = (ushort)x;
|
||||
int argb = row[x];
|
||||
|
||||
pixel.R = (byte)(argb >> 16);
|
||||
pixel.G = (byte)(argb >> 8);
|
||||
pixel.B = (byte)(argb >> 8);
|
||||
pixel.ARGB = row[x];
|
||||
callback(pixel);
|
||||
}
|
||||
}
|
||||
@ -71,12 +67,7 @@ namespace MCGalaxy.Drawing {
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
pixel.X = (ushort)x; pixel.Y = (ushort)y;
|
||||
Color col = bmp.GetPixel(x, y);
|
||||
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);
|
||||
pixel.ARGB = bmp.GetPixel(x, y).ToArgb(); // R/G/B properties incur overhead
|
||||
callback(pixel);
|
||||
}
|
||||
}
|
||||
@ -90,6 +81,6 @@ namespace MCGalaxy.Drawing {
|
||||
|
||||
public struct Pixel {
|
||||
public ushort X, Y;
|
||||
public byte R, G, B;
|
||||
public int ARGB;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user