Monday, April 02, 2007

Bump mapping Source code

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

No comments: