struct Point
{
int X;
int Y;
};
Constructor()
{
Point** pt;
pt = new Point*[nWidth];
for(int i = 0; i < nWidth; i++)
{
pt [i] = new Point[nHeight];
}
}
Destructor()
{
for(int i =0; i < nwidth; i++)
{
delete[] pt[i];
}
if(pt)
{
delete[] pt;
}
}
BumpMapProcessing()
{
UpdateBumpMap();
BYTE* pSrc = srcImage->ImageData;
BYTE* pDest = destImage->ImageData;
int xOffset,yOffset;
//OffsetFilter( )or OffsetFilterAbs() or OffsetFilterAntiAlias ()....
int scanline = srcImage->widthstep; or srcImage->width * srcImage->nChannels ;
for(int y = 0; y < nHeight; y++)
{
for(int x =0; x < nWidth; x++)
{
xOffset = pt[x,y].X;
yOffset = pt[x,y].Y;
if( yOffset >= 0 && yOffset < nHeight && xOffset >=0 && xOffset < nWidth)
{
pDest[0] = pSrc[ (yOffset * scanline) + ( xOffset * 3) ];
pDest[1] = pSrc[ (yOffset * scanline) + ( xOffset * 3) + 1];
pDest[2] = pSrc[ (yOffset * scanline) + ( xOffset * 3) + 2];
}
pDest = pDest + 3;
}
}
}
UpdateBumpMap()
{
//Initialize the points...
// if it is anti alias means we must use the floating points otherwise integer points...
}
//Look the following flow of Bump mapping ....
//Sphere is also called the bump mapping process...
// all the bump mapping follows this standard...
public static bool Sphere(Bitmap b, bool bSmoothing)
{
int nWidth = b.Width;
int nHeight = b.Height;
FloatPoint [,] fp = new FloatPoint[nWidth, nHeight];
Point [,] pt = new Point[nWidth, nHeight];
Point mid = new Point();
mid.X = nWidth/2;
mid.Y = nHeight/2;
double theta, radius;
double newX, newY;
for (int x = 0; x < nWidth; ++x)
for (int y = 0; y < nHeight; ++y)
{
int trueX = x - mid.X;
int trueY = y - mid.Y;
theta = Math.Atan2((trueY),(trueX));
radius = Math.Sqrt(trueX*trueX + trueY*trueY);
double newRadius = radius * radius/(Math.Max(mid.X, mid.Y));
newX = mid.X + (newRadius * Math.Cos(theta));
if (newX > 0 && newX < nWidth)
{
fp[x, y].X = newX;
pt[x, y].X = (int) newX;
}
else
{
fp[x, y].X = fp[x,y].Y = 0.0;
pt[x, y].X = pt[x,y].Y = 0;
}
newY = mid.Y + (newRadius * Math.Sin(theta));
if (newY > 0 && newY < nHeight && newX > 0 && newX < nWidth)
{
fp[x, y].Y = newY;
pt[x, y].Y = (int) newY;
}
else
{
fp[x, y].X = fp[x,y].Y = 0.0;
pt[x, y].X = pt[x,y].Y = 0;
}
}
if(bSmoothing)
OffsetFilterAbs(b, pt);
else
OffsetFilterAntiAlias(b, fp);
return true;
}
public static bool OffsetFilter(Bitmap b, Point[,] offset )
{
Bitmap bSrc = (Bitmap)b.Clone();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int scanline = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
byte * pSrc = (byte *)(void *)SrcScan0;
int nOffset = bmData.Stride - b.Width*3;
int nWidth = b.Width;
int nHeight = b.Height;
int xOffset, yOffset;
for(int y=0;y < nHeight;++y)
{
for(int x=0; x < nWidth; ++x )
{
xOffset = offset[x,y].X;
yOffset = offset[x,y].Y;
if (y+yOffset >= 0 && y+yOffset < nHeight && x+xOffset >= 0 && x+xOffset < nWidth)
{
p[0] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3)];
p[1] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 1];
p[2] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 2];
}
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
public static bool OffsetFilterAntiAlias(Bitmap b, FloatPoint[,] fp)
{
Bitmap bSrc = (Bitmap)b.Clone();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int scanline = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
byte * pSrc = (byte *)(void *)SrcScan0;
int nOffset = bmData.Stride - b.Width*3;
int nWidth = b.Width;
int nHeight = b.Height;
double xOffset, yOffset;
double fraction_x, fraction_y, one_minus_x, one_minus_y;
int ceil_x, ceil_y, floor_x, floor_y;
Byte p1, p2;
for(int y=0;y < nHeight;++y)
{
for(int x=0; x < nWidth; ++x )
{
xOffset = fp[x,y].X;
yOffset = fp[x,y].Y;
// Setup
floor_x = (int)Math.Floor(xOffset);
floor_y = (int)Math.Floor(yOffset);
ceil_x = floor_x + 1;
ceil_y = floor_y + 1;
fraction_x = xOffset - floor_x;
fraction_y = yOffset - floor_y;
one_minus_x = 1.0 - fraction_x;
one_minus_y = 1.0 - fraction_y;
if (floor_y >= 0 && ceil_y < nHeight && floor_x >= 0 && ceil_x < nWidth)
{
// Blue
p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3]) +
fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3]));
p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3]) +
fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x]));
p[x * 3 + y*scanline] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
// Green
p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 1]) +
fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 1]));
p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 1]) +
fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 1]));
p[x * 3 + y*scanline + 1] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
// Red
p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 2]) +
fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 2]));
p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 2]) +
fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 2]));
p[x * 3 + y*scanline + 2] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
}
}
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
public static bool OffsetFilterAbs(Bitmap b, Point[,] offset )
{
Bitmap bSrc = (Bitmap)b.Clone();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int scanline = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
byte * pSrc = (byte *)(void *)SrcScan0;
int nOffset = bmData.Stride - b.Width*3;
int nWidth = b.Width;
int nHeight = b.Height;
int xOffset, yOffset;
for(int y=0;y < nHeight;++y)
{
for(int x=0; x < nWidth; ++x )
{
xOffset = offset[x,y].X;
yOffset = offset[x,y].Y;
if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth)
{
p[0] = pSrc[(yOffset * scanline) + (xOffset * 3)];
p[1] = pSrc[(yOffset * scanline) + (xOffset * 3) + 1];
p[2] = pSrc[(yOffset * scanline) + (xOffset * 3) + 2];
}
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
Monday, April 02, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment