public Layer Copy(Layer layer) { Layer copy = (Layer)layer.Clone(); _layers.Add(copy); return copy; }
public Layer Add(Int32 width, Int32 height) { Layer layer = new Layer(width, height); _layers.Add(layer); return layer; }
public Layer Add(FastBitmap bitmap) { Layer layer = new Layer(bitmap); _layers.Add(layer); return layer; }
public Layer Add() { Layer layer = new Layer(_image.Width, _image.Height); _layers.Add(layer); return layer; }
public void BumpMap(Layer bumpmap, Int32 azimuth, Int32 elevation, Int32 bevelwidth, Boolean lightzalways1) { bumpmap._bitmap.Lock(); _bitmap.Lock(); for (Int32 row = 0; row < _bitmap.Height; row++) { for (Int32 col = 0; col < _bitmap.Width; col++) { // calculate normal for point (col, row) // this is an approximation of the derivative // I personally haven't figured out why it's // the way it is // normal_z is constant, I think this means // the longer the vector is, the more it lays // in the xy plane Byte[] x = new Byte[6]; x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1); x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 0); x[2] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1); x[3] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1); x[4] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 0); x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1); Single normal_x = x[0] + x[1] + x[2] - x[3] - x[4] - x[5]; x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1); x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row + 1); x[2] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1); x[3] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1); x[4] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row - 1); x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1); Single normal_y = x[0] + x[1] + x[2] - x[3] - x[4] - x[5]; Single normal_z = (6F * 255F) / bevelwidth; Single length = (Single)Math.Sqrt( normal_x * normal_x + normal_y * normal_y + normal_z * normal_z); if (length != 0) { normal_x /= length; normal_y /= length; normal_z /= length; } // convert to radians Double azimuth_rad = azimuth / 180.0 * Math.PI; Double elevation_rad = elevation / 180.0 * Math.PI; // light vector -- this is the location of the light // source but it also serves as the direction with // origin <0, 0, 0> // the formulas to calculate x, y and z are those to // rotate a point in 3D space // if lightzalways1 is true, light_z is set to 1 // because we want full color intensity for that pixel; // if we set light_z to (Single)Math.Sin(elevation_rad), // which is the correct way to calculate light_z, the // color is more dark, but when we ignore light_z, the // light source is straight above the pixel and // therefore sin(elevation_rad) is always 1 Single light_x = (Single)(Math.Cos(azimuth_rad) * Math.Cos(elevation_rad)); Single light_y = (Single)(Math.Sin(azimuth_rad) * Math.Cos(elevation_rad)); Single light_z = 1F; if (!lightzalways1) light_z = (Single)Math.Sin(elevation_rad); // the normal and light vector are unit vectors, so // taking the dot product of these two yields the // cosine of the angle between them Single cos_light_normal = 0; cos_light_normal += normal_x * light_x; cos_light_normal += normal_y * light_y; cos_light_normal += normal_z * light_z; // get pixel (col, row) of this layer, calculate color // and set pixel back with new color Color c = _bitmap.GetPixel(col, row); Single r = c.R; Single g = c.G; Single b = c.B; r *= cos_light_normal; g *= cos_light_normal; b *= cos_light_normal; Byte red = (Byte)Math.Min(Math.Round(r), 255); Byte green = (Byte)Math.Min(Math.Round(g), 255); Byte blue = (Byte)Math.Min(Math.Round(b), 255); _bitmap.SetPixel(col, row, Color.FromArgb(red, green, blue)); } } _bitmap.Unlock(); bumpmap._bitmap.Unlock(); }
public Object Clone() { Layer clone = new Layer(_bitmap.Width, _bitmap.Height); clone._bitmap = (FastBitmap)_bitmap.Clone(); return clone; }