/Users/lyon/j4p/src/graphics/raytracers/rmiRaytracer/raytracer/DoImage.java

1    package graphics.raytracers.rmiRaytracer.raytracer; 
2     
3    import java.awt.*; 
4    import java.awt.image.ColorModel; 
5    import java.awt.image.MemoryImageSource; 
6     
7    public class DoImage { 
8     
9        private Targets scene = Targets.getTargets(); 
10       private Dimension d = null; 
11    
12       private int pixels[][] = null; 
13    
14       public Dimension getSize() { 
15           return d; 
16       } 
17    
18       public void setSize(Dimension _d) { 
19           d = _d; 
20           pixels = new int[d.width][d.height]; 
21       } 
22    
23       public DoImage(Dimension _d) { 
24           d = _d; 
25           pixels = new int[d.width][d.height]; 
26       } 
27    
28       public void doTheWork() { 
29    
30           int screenWidth = d.width; 
31           int screenHeight = d.height; 
32           int pixY = 0; 
33           int pixX = 0; 
34           double deltaY = 1.0 / screenHeight; 
35           double deltaX = 1.0 / screenWidth; 
36           double tmpy = 1.0; 
37           double tmpz = 0.0; // tmpz is the projection plane 
38    
39           int screenStartLine = 0; 
40           int screenEndLine = 2 * screenHeight; 
41           for (pixY = screenStartLine; pixY < screenEndLine; pixY++) { 
42               double tmpx = -1.0; 
43               tmpy -= deltaY; 
44               pixX = renderALine(screenWidth, deltaX, tmpx, tmpy, tmpz, pixY); 
45           } 
46       } 
47    
48       /** 
49        * set the band for the image to render 
50        */ 
51       public void setBand(Dimension _band) { 
52           band = _band; 
53       } 
54    
55       private Dimension band = new Dimension(0, 200); 
56    
57       private int renderALine(int w, 
58                               double xstep, 
59                               double tmpx, 
60                               double tmpy, 
61                               double tmpz, 
62                               int pixY) { 
63           int pixX; 
64           int xMin = 0; 
65           int xMax = 2 * w; 
66           //xMax = w; 
67           for (pixX = xMin; pixX < xMax; pixX++) { 
68               tmpx += xstep; 
69               int realX = pixX / 2; 
70               int realY = pixY / 2; 
71               if (realX < band.width) continue; 
72               if (realX > band.height) continue; 
73               int c = computePixel(tmpx, tmpy, tmpz); 
74    
75    
76               addPixel(c, realX, w, realY); 
77               // visual feedback on progress 
78               // this is really slow! Using g.drawLine to draw a dot? 
79               //g.setColor(new Color(c, c, c)); 
80               //g.drawLine(realX, realY, realX, realY); 
81           } 
82           return pixX; 
83       } 
84    
85       private int computePixel(double tmpx, double tmpy, double tmpz) { 
86           Vec projP = new Vec(tmpx, tmpy, tmpz); 
87           int c = paintPix(projP); 
88           return c; 
89       } 
90    
91       private void addPixel(int c, int realX, int w, int realY) { 
92           getPixels()[realX][realY] = (255 << 24) | (c << 16) | (c << 8) | (c << 0); 
93       } 
94    
95       public static Image int2Image(int i[][]) { 
96           Toolkit tk = Toolkit.getDefaultToolkit(); 
97           int width = i.length; 
98           int height = i[0].length; 
99           int pels[] = new int[width * height]; 
100          for (int x = 0; x < width; x++) 
101              for (int y = 0; y < height; y++) 
102                  pels[x + y * width] = i[x][y]; 
103          return tk.createImage( 
104                  new MemoryImageSource(width, height, 
105                          ColorModel.getRGBdefault(), 
106                          pels, 0, width)); 
107      } 
108   
109      public Image int2SubImage(int i[][]) { 
110          int startx = band.width; 
111          int endx = band.height; 
112          int xWidth = endx - startx; 
113          int sx = 0; 
114          int subImage[][] = new int[xWidth][d.height]; 
115          for (int x = 0; x < subImage.length; x++) 
116              for (int y = 0; y < subImage[0].length; y++) 
117                  subImage[x][y] = i[x + band.width][y]; 
118   
119          return int2Image(subImage); 
120      } 
121   
122      public int[][] int2SubInt(int i[][]) { 
123          int startx = band.width; 
124          int endx = band.height; 
125          int xWidth = endx - startx; 
126          int sx = 0; 
127          int subImage[][] = new int[xWidth][d.height]; 
128          for (int x = 0; x < subImage.length; x++) 
129              for (int y = 0; y < subImage[0].length; y++) 
130                  subImage[x][y] = i[x + band.width][y]; 
131   
132          return subImage; 
133      } 
134   
135      public int[][] getSubPixels() { 
136          doTheWork(); 
137          return int2SubInt(pixels); 
138      } 
139   
140      public Image getImage() { 
141          doTheWork(); 
142          return //int2Image(pixels); 
143                  int2SubImage(pixels); 
144      } 
145   
146      public Image getSubBand() { 
147          doTheWork(); 
148          Toolkit tk = Toolkit.getDefaultToolkit(); 
149          int xSubImageWidth = band.height - band.width; 
150          int ySubImageHeight = d.height; 
151          int subImage[] = new int[xSubImageWidth * ySubImageHeight]; 
152          int i = 0; 
153          for (int y = 0; y < d.height; y++) 
154              for (int x = band.height; x < band.width; x++) 
155                      //subImage[i++] = pixels[x + d.width * y]; 
156                  System.out.println("dimension=" + band); 
157   
158          return tk.createImage( 
159                  new MemoryImageSource(xSubImageWidth, xSubImageWidth, 
160                          ColorModel.getRGBdefault(), 
161                          subImage, band.height, band.width)); 
162          // 0 is offset...in pixels. 
163          // band.width, band,height, xmin, xmax. 
164      } 
165   
166      private int paintPix(Vec projP) { 
167          double t[] = new double[1]; 
168          int color = 0; 
169          Vec R1 = new Vec(projP); 
170          R1.sub(scene.VRP); 
171          R1.normalize(); 
172   
173          t[0] = 0.0; 
174   
175          int obj = intersectObjects(scene.VRP, R1, t, 0, false); 
176   
177          /* if it does then find out how to paint the pixel */ 
178          if (t[0] > 0.0) { 
179              color = ((Target) scene.getElementAt(obj)).shade(obj, 
180                      R1, t); 
181          } 
182   
183          color += 16;  // ambient light 
184   
185          if (color > 255) 
186              color = 255; 
187   
188          return color; 
189      } 
190   
191      private int intersectObjects(Vec R0, Vec R1, double result[], int object, 
192                                   boolean shadowCheck) { 
193          double minDist = 0.0, dist; 
194          int hit = -1; 
195   
196          for (int i = 0; i < scene.getSize(); i++) { 
197              if ((shadowCheck == true) && (object == i)) 
198                  continue; 
199              dist = ((Target) scene.getElementAt(i)).intersectTest(R0, 
200                      R1, i); 
201   
202              if (dist == 0.0) 
203                  continue; 
204   
205              /* save the first t */ 
206              if ((minDist == 0.0) && (dist > 0.0)) { 
207                  minDist = dist; 
208                  hit = i; 
209              } else if ((dist > 0.0) && (dist < minDist)) { 
210                  minDist = dist; 
211                  hit = i; 
212              } 
213          } 
214          result[0] = minDist; 
215          return hit; 
216      } 
217   
218      public int[][] getPixels() { 
219          return pixels; 
220      } 
221  } 
222