• Create Account

#ActualDan Violet Sagmiller

Posted 09 March 2013 - 08:18 AM

I have some code that adds a texture to another texture using the alpha mask of another texture.  But I'm getting really wonky results.

First, All images are 64x64 PNG files, stored with no compression.

I have 4 masks, used for the 4 corners that would make up an image (The image is all white, but the blue shows the alpha.  It was the easiest way to show that here.

Next, I have 4 textures to mess with: (dirt, grass, concrete and pavement)

I put together a C# App to Create images.  I start with a black 64x64 image, and start adding the pieces I want.  For instance, mixing NE with 2 gives me this:
It looks pretty accurate, but for some reason much brighter.

When I combine 3 & NW, I get this:
Again hard to notice, but some of the tones are brighter.

Now for the real kicker.  Now I take the first image (green in the top right corner) and call the same method to add the concrete to the top left corner, and I get this:

Obviously, my code is doing something very wrong, but I'm not sure what, because it starts out so close.
Here is my code (C#, which doesn't support AND/OR on Bytes, which is pretty dumb, so everything is cast to int and back.)

        public void Paint(Bitmap canvas, Bitmap mask, Bitmap newLayer)
{
var rect = new Rectangle(0, 0, newLayer.Width, newLayer.Height);
var bitsInput = newLayer.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bitsOutput = canvas.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
for (int y = 0; y < newLayer.Height; y++)
{
byte* ptrInput = (byte*)bitsInput.Scan0 + y * bitsInput.Stride;
byte* ptrOutput = (byte*)bitsOutput.Scan0 + y * bitsOutput.Stride;
for (int x = 0; x < newLayer.Width; x++)
{
int msk = (int)ptrMask[4 * x + 3];
//blue
ptrOutput[4 * x + 0] = (byte)
(
(int)ptrOutput[4 * x + 0] |
(msk & (int)ptrInput[4 * x + 0])
);
//green
ptrOutput[4 * x + 1] = (byte)
(
(int)ptrOutput[4 * x * 1] |
(msk & (int)ptrInput[4 * x + 1])
);
//red
ptrOutput[4 * x + 2] = (byte)
(
(int)ptrOutput[4 * x * 2] |
(msk & (int)ptrInput[4 * x + 2])
);
ptrOutput[4 * x + 3] = 255;
}
}
}
newLayer.UnlockBits(bitsInput);
canvas.UnlockBits(bitsOutput);

}


The general logic is canvas = canvas OR (mask AND cover)

#1Dan Violet Sagmiller

Posted 09 March 2013 - 08:11 AM

I have some code that adds a texture to another texture using the alpha mask of another texture.  But I'm getting really wonky results.

First, All images are 64x64 PNG files, stored with no compression.

I have 4 masks, used for the 4 corners that would make up an image (The image is all white, but the blue shows the alpha.  It was the easiest way to show that here.

Next, I have 4 textures to mess with: (dirt, grass, concrete and pavement)

I put together a C# App to Create images.  I start with a black 64x64 image, and start adding the pieces I want.  For instance, mixing NE with 4 gives me this:

It looks pretty accurate, but for some reason much brighter.

When I combine 3 & NW, I get this:
Again hard to notice, but some of the tones are brighter.

Now for the real kicker.  Now I take the first image (green in the top right corner) and call the same method to add the concrete to the top left corner, and I get this:

Obviously, my code is doing something very wrong, but I'm not sure what, because it starts out so close.
Here is my code (C#, which doesn't support AND/OR on Bytes, which is pretty dumb, so everything is cast to int and back.)

        public void Paint(Bitmap canvas, Bitmap mask, Bitmap newLayer)
{
var rect = new Rectangle(0, 0, newLayer.Width, newLayer.Height);
var bitsInput = newLayer.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bitsOutput = canvas.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
for (int y = 0; y < newLayer.Height; y++)
{
byte* ptrInput = (byte*)bitsInput.Scan0 + y * bitsInput.Stride;
byte* ptrOutput = (byte*)bitsOutput.Scan0 + y * bitsOutput.Stride;
for (int x = 0; x < newLayer.Width; x++)
{
int msk = (int)ptrMask[4 * x + 3];
//blue
ptrOutput[4 * x + 0] = (byte)
(
(int)ptrOutput[4 * x + 0] |
(msk & (int)ptrInput[4 * x + 0])
);
//green
ptrOutput[4 * x + 1] = (byte)
(
(int)ptrOutput[4 * x * 1] |
(msk & (int)ptrInput[4 * x + 1])
);
//red
ptrOutput[4 * x + 2] = (byte)
(
(int)ptrOutput[4 * x * 2] |
(msk & (int)ptrInput[4 * x + 2])
);
ptrOutput[4 * x + 3] = 255;
}
}
}