/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