public class ScanExample extends MISApplet { //----- LIGHTING INFO double light1[][] = { { 1, 1, 1 }, // DIRECTION { 1.0, 1.0, 1.0 } // COLOR }; double light2[][] = { {-1, 0, 0 }, // DIRECTION { 0.6, 0.0, 0.0 } // COLOR }; double lights[][][] = { light1, light2 }; //----- SURFACE COLOR INFO double ambientColor[] = { 0.3, 0.3, 0.3 }; // RGB double diffuseColor[] = { 0.6, 0.6, 0.6 }; // RGB public void initialize() { // INITIALIZE // SET ALL LIGHT DIRECTION VECTORS TO UNIT LENGTH for (int l = 0 ; l < lights.length ; l++) { double lightDir[] = lights[l][0]; normalize(lightDir); } } public void initFrame(double time) { // ANIMATE THE LIGHT DIRECTION EVERY FRAME double lightDir[] = lights[0][0]; lightDir[0] = Math.sin(4 * time); normalize(lightDir); } // VECTORS USED FOR INTERNAL LIGHTING COMPUTATION double normal[] = new double[3]; double RGB[] = new double[3]; // STANDARD COLORS PACKED INTO A SINGLE INTEGER int black = pack(0,0,0); int white = pack(255,255,255); // CALLED ONCE PER FRAME public void computeImage(double time) { // SET ALL PIXEL COLORS initFrame(time); // CLEAR OUT THE FRAME BUFFER for (int i = 0 ; i < pix.length ; i++) pix[i] = black; for (int x = 0 ; x < W ; x++) for (int y = 0 ; y < H ; y++) { int i = xy2i(x, y); // USE x,y TO COMPUTE POINT ON VIRTUAL UNIT SPHERE double X = (double)(x - W/2) / (W/3); double Y = (double)(H/2 - y) / (W/3); // IF ON THE VIRTUAL SPHERE, COMPUTE SHADING double RR = X * X + Y * Y; if (RR < 1.0) { double Z = Math.sqrt(1 - RR); // AMBIENT COMPONENT DOES NOT DEPEND ON LIGHT SOURCES for (int j = 0 ; j < 3 ; j++) RGB[j] = ambientColor[j]; normal[0] = X; normal[1] = Y; normal[2] = Z; // FOR EACH LIGHT SOURCE: for (int l = 0 ; l < lights.length ; l++) { // COMPUTE DIFFUSE LIGHTING, AND ADD IT TO RGB double lightDir[] = lights[l][0]; double lightRgb[] = lights[l][1]; double diffuseFactor = dot(normal, lightDir); if (diffuseFactor > 0) for (int j = 0 ; j < 3 ; j++) RGB[j] += diffuseColor[j] * diffuseFactor * lightRgb[j]; } // PACK THE FINAL COLOR INTO THE OUTPUT IMAGE PIXEL int red = (int)(255 * RGB[0]); int grn = (int)(255 * RGB[1]); int blu = (int)(255 * RGB[2]); pix[i] = pack(red, grn, blu); } } } //----- MISC. VECTOR MATH ROUTINES double dot(double a[], double b[]) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } void normalize(double v[]) { double d = dot(v, v); v[0] /= d; v[1] /= d; v[2] /= d; } }