/Users/lyon/j4p/src/ip/raul/Applet3d.java
|
1 // | The idx3d engine (and this source code) is (c)1998 by Peter Walser
2 // | Feel free to use this 3d engine for non-commercial purpose,
3 // | and please set a link to my homepage.
4 // | If you have any questions concerning the source code the
5 // | methods and algorithms: send me e-mail.
6 // |
7 // | Peter Walser
8 // | proxima@active.ch
9 // | http://www.vis.inf.ethz.ch/~pwalser
10 // | -------------------------------------------------------------
11 package ip.raul;
12
13 import java.applet.Applet;
14 import java.awt.Image;
15 import java.awt.image.ColorModel;
16 import java.awt.image.MemoryImageSource;
17 import java.awt.image.PixelGrabber;
18 import java.util.Date;
19
20 public class Applet3d extends Applet {
21 // Copyright information
22 public String info = new String(
23 "idx3d Java 3d ENGINE");
24 public String copyright = new String(
25 "©1998 by Peter Walser");
26 public String version = new String(
27 "Version 2.0 BETA");
28 public String build = new String(
29 "06.10.1998");
30 public String sysinfo;
31
32 //Scene attributes
33 int w;
34 int h;
35 float centerx;
36 float centery;
37
38 //Objects and Lights
39 public idx3d_object object[];
40 public idx3d_light light[];
41 public idx3d_texture texture[];
42 public int objects = 0;
43 public int lights = 0;
44 public int textures = 0;
45 public int maxobjects = 0;
46 public int maxlights = 0;
47 public int maxtextures = 0;
48 private idx3d_matrix worldmatrix = new idx3d_matrix();
49
50 //Color management
51 public int bgcolor;
52 int alpha = 0xff000000;
53 int rbit = 0x00ff0000;
54 int gbit = 0x0000ff00;
55 int bbit = 0x000000ff;
56 private ColorModel idx_cm = ColorModel.getRGBdefault();
57
58 //Trigonometry
59 float sinus[] = new float[360];
60 float cosinus[] = new float[360];
61 final float pi = (float) 3.14159265;
62 final float deg2rad = pi / 180;
63
64 //Scene parameters
65 public float perspective = (float) 8;
66 public float zoomcorrection = (float) 0.72;
67 public int ambient = 0; //0..255
68 public int phong = 80; //0..255
69 public int reflectivity = 255; //0..255
70 public boolean staticLight = false;
71
72 //Render structures
73 int LightMap[][] = new int[256][256];
74 int ColorMap[][] = new int[256][256];
75 int EnvMap[][] = new int[256][256];
76 int StaticLightMap[][] = new int[256][256];
77 int StaticEnvMap[][] = new int[256][256];
78 int zBuffer[][];
79 int LEdgeBuffer[];
80 int REdgeBuffer[];
81 int ZEdgeBufferL[];
82 int ZEdgeBufferR[];
83 int IEdgeBufferL[];
84 int IEdgeBufferR[];
85 int NXEdgeBufferL[];
86 int NYEdgeBufferL[];
87 int NXEdgeBufferR[];
88 int NYEdgeBufferR[];
89 int TXEdgeBufferL[];
90 int TYEdgeBufferL[];
91 int TXEdgeBufferR[];
92 int TYEdgeBufferR[];
93 int zInfinite = 1000 << 16;
94 int zNear = -1 << 16;
95
96 //Output
97 Image DoubleBuffer = null;
98 int TargetPixel[];
99 int Background[];
100
101 // GENERAL METHODS
102
103 public Applet3d(int width, int height) {
104 myResize(width, height);
105 }
106
107 public void myResize(int width, int height) {
108 w = width;
109 h = height;
110 centerx = (float) w / 2;
111 centery = (float) h / 2;
112 sysinfo = getSysInfo();
113 TargetPixel = new int[w * h];
114 Background = new int[w * h];
115 LEdgeBuffer = new int[h];
116 REdgeBuffer = new int[h];
117 zBuffer = new int[w][h];
118 ZEdgeBufferL = new int[h];
119 ZEdgeBufferR = new int[h];
120 IEdgeBufferL = new int[h];
121 IEdgeBufferR = new int[h];
122 NXEdgeBufferL = new int[h];
123 NYEdgeBufferL = new int[h];
124 NXEdgeBufferR = new int[h];
125 NYEdgeBufferR = new int[h];
126 TXEdgeBufferL = new int[h];
127 TYEdgeBufferL = new int[h];
128 TXEdgeBufferR = new int[h];
129 TYEdgeBufferR = new int[h];
130
131 bgcolor = getIntColor(0, 0, 0);
132 clearBackground();
133 init_LightMap();
134 init_ColorMap();
135 init_TrigTables();
136 }
137
138 private String getSysInfo() {
139 return (System.getProperty("os.arch") +
140 " on " +
141 System.getProperty("os.name"));
142 }
143
144 private void init_LightMap() {
145 float NX;
146 float NY;
147 float NZ;
148 for (int j = 0; j < 256; j++) {
149 for (int i = 0; i < 256; i++) {
150 NX = ((float) i - 127) / 127;
151 NY = ((float) j - 127) / 127;
152 NZ =
153 (float) (1 -
154 Math.sqrt(
155 NX * NX +
156 NY * NY));
157 LightMap[i][j] =
158 crop((int) (NZ * 255), 0, 255);
159 }
160 }
161 }
162
163 public void setStatic() {
164 for (int j = 0; j < 256; j++) {
165 for (int i = 0; i < 256; i++) {
166 StaticLightMap[i][j] =
167 getIntensity(2 * i - 255,
168 2 * j - 255);
169 StaticEnvMap[i][j] =
170 getEnvironment(2 * i - 255,
171 2 * j - 255);
172 }
173 }
174 staticLight = true;
175 }
176
177 private void init_ColorMap() {
178 int H2 = 255 - phong;
179 for (int x = 0; x < 256; x++) {
180 for (int y = 0; y < H2; y++) {
181 ColorMap[y][x] = (x * y / H2);
182 }
183 for (int y = H2; y < 256; y++) {
184 ColorMap[y][x] =
185 (y +
186 (255 - y) * (x - H2) / phong);
187 }
188 }
189 }
190
191 private void init_TrigTables() {
192 for (int i = 0; i < 360; i++) {
193 sinus[i] =
194 (float) Math.sin(deg2rad * (float) i);
195 cosinus[i] =
196 (float) Math.cos(deg2rad * (float) i);
197 }
198 }
199
200 public void setPhong(int p) {
201 phong = p;
202 init_ColorMap();
203 }
204
205 public float crop(float a, float b, float c) {
206 if (a < b) return (b);
207 if (a > c - 1) return (c - 1);
208 return a;
209 }
210
211 public int crop(int a, int b, int c) {
212 if (a < b) return (b);
213 if (a > c - 1) return (c - 1);
214 return a;
215 }
216
217 public boolean inrange(int a, int b, int c) {
218 return ((a >= b) && (a < c));
219 }
220
221 public boolean inrange(float a,
222 float b,
223 float c) {
224 return ((a >= b) && (a < c));
225 }
226
227 public float rnd() {
228 return ((float) Math.random() * 2 - 1);
229 }
230
231 public idx3d_node rndNode() {
232 idx3d_vector v = new idx3d_vector();
233 v = rndVector();
234 idx3d_node r = new idx3d_node(v.x,
235 v.y,
236 v.z);
237 r.n = normalize(rndVector());
238 return r;
239 }
240
241 public idx3d_vector rndVector() {
242 idx3d_vector v = new idx3d_vector();
243 v.x = rnd();
244 v.y = rnd();
245 v.z = rnd();
246 return v;
247 }
248
249 public int rndColor() {
250 int r = (int) (Math.random() * 255);
251 int g = (int) (Math.random() * 255);
252 int b = (int) (Math.random() * 255);
253 return getIntColor(r, g, b);
254 }
255
256 // GEOMETRY FUNCTIONS
257
258 public idx3d_vector vectordist(
259 idx3d_vector v1, idx3d_vector v2) {
260 return new idx3d_vector(v1.x - v2.x,
261 v1.y - v2.y,
262 v1.z - v2.z);
263 }
264
265 public float vectorlength(idx3d_vector v) {
266 return (float) Math.sqrt(
267 v.x * v.x + v.y * v.y +
268 v.z * v.z);
269 }
270
271 public idx3d_vector normalize(idx3d_vector v) {
272 float length = vectorlength(v);
273 return new idx3d_vector(v.x / length,
274 v.y / length,
275 v.z / length);
276 }
277
278 public idx3d_vector getNormal(idx3d_vector a,
279 idx3d_vector b,
280 idx3d_vector c) {
281 idx3d_vector n = new idx3d_vector();
282 float ax = b.x - a.x;
283 float ay = b.y - a.y;
284 float az = b.z - a.z;
285 float bx = c.x - a.x;
286 float by = c.y - a.y;
287 float bz = c.z - a.z;
288 n.x = ay * bz - by * az;
289 n.y = az * bx - bz * ax;
290 n.z = ax * by - bx * ay;
291 return normalize(n);
292 }
293
294 public idx3d_matrix crossproduct(
295 idx3d_matrix a, idx3d_matrix b) {
296 idx3d_matrix c = new idx3d_matrix();
297 c.matrix[0][0] =
298 a.matrix[0][0] * b.matrix[0][0] +
299 a.matrix[0][1] * b.matrix[1][0] +
300 a.matrix[0][2] * b.matrix[2][0] +
301 a.matrix[0][3] * b.matrix[3][0];
302 c.matrix[0][1] =
303 a.matrix[0][0] * b.matrix[0][1] +
304 a.matrix[0][1] * b.matrix[1][1] +
305 a.matrix[0][2] * b.matrix[2][1] +
306 a.matrix[0][3] * b.matrix[3][1];
307 c.matrix[0][2] =
308 a.matrix[0][0] * b.matrix[0][2] +
309 a.matrix[0][1] * b.matrix[1][2] +
310 a.matrix[0][2] * b.matrix[2][2] +
311 a.matrix[0][3] * b.matrix[3][2];
312 c.matrix[0][3] =
313 a.matrix[0][0] * b.matrix[0][3] +
314 a.matrix[0][1] * b.matrix[1][3] +
315 a.matrix[0][2] * b.matrix[2][3] +
316 a.matrix[0][3] * b.matrix[3][3];
317 c.matrix[1][0] =
318 a.matrix[1][0] * b.matrix[0][0] +
319 a.matrix[1][1] * b.matrix[1][0] +
320 a.matrix[1][2] * b.matrix[2][0] +
321 a.matrix[1][3] * b.matrix[3][0];
322 c.matrix[1][1] =
323 a.matrix[1][0] * b.matrix[0][1] +
324 a.matrix[1][1] * b.matrix[1][1] +
325 a.matrix[1][2] * b.matrix[2][1] +
326 a.matrix[1][3] * b.matrix[3][1];
327 c.matrix[1][2] =
328 a.matrix[1][0] * b.matrix[0][2] +
329 a.matrix[1][1] * b.matrix[1][2] +
330 a.matrix[1][2] * b.matrix[2][2] +
331 a.matrix[1][3] * b.matrix[3][2];
332 c.matrix[1][3] =
333 a.matrix[1][0] * b.matrix[0][3] +
334 a.matrix[1][1] * b.matrix[1][3] +
335 a.matrix[1][2] * b.matrix[2][3] +
336 a.matrix[1][3] * b.matrix[3][3];
337 c.matrix[2][0] =
338 a.matrix[2][0] * b.matrix[0][0] +
339 a.matrix[2][1] * b.matrix[1][0] +
340 a.matrix[2][2] * b.matrix[2][0] +
341 a.matrix[2][3] * b.matrix[3][0];
342 c.matrix[2][1] =
343 a.matrix[2][0] * b.matrix[0][1] +
344 a.matrix[2][1] * b.matrix[1][1] +
345 a.matrix[2][2] * b.matrix[2][1] +
346 a.matrix[2][3] * b.matrix[3][1];
347 c.matrix[2][2] =
348 a.matrix[2][0] * b.matrix[0][2] +
349 a.matrix[2][1] * b.matrix[1][2] +
350 a.matrix[2][2] * b.matrix[2][2] +
351 a.matrix[2][3] * b.matrix[3][2];
352 c.matrix[2][3] =
353 a.matrix[2][0] * b.matrix[0][3] +
354 a.matrix[2][1] * b.matrix[1][3] +
355 a.matrix[2][2] * b.matrix[2][3] +
356 a.matrix[2][3] * b.matrix[3][3];
357 return c;
358 }
359
360 public idx3d_vector matrixvectorproduct(
361 idx3d_matrix b, idx3d_vector a) {
362 idx3d_vector c = new idx3d_vector();
363 c.x = a.x * b.matrix[0][0] +
364 a.y * b.matrix[0][1] +
365 a.z * b.matrix[0][2] +
366 b.matrix[0][3];
367 c.y = a.x * b.matrix[1][0] +
368 a.y * b.matrix[1][1] +
369 a.z * b.matrix[1][2] +
370 b.matrix[1][3];
371 c.z = a.x * b.matrix[2][0] +
372 a.y * b.matrix[2][1] +
373 a.z * b.matrix[2][2] +
374 b.matrix[2][3];
375 return c;
376 }
377
378 // DATA MANAGEMENT
379
380 public void addObject(int rendermode,
381 int color) {
382 objects += 1;
383
384 if (objects >= maxobjects) {
385 if (object == null) {
386 maxobjects = 2;
387 object = new idx3d_object[11];
388 } else {
389 maxobjects *= 2;
390 idx3d_object temp[] = new idx3d_object[maxobjects +
391 1];
392 System.arraycopy(object,
393 1,
394 temp,
395 1,
396 objects);
397 object = temp;
398 }
399 }
400 object[objects] =
401 new idx3d_object(rendermode, color);
402 }
403
404 public void addLight(idx3d_vector v,
405 int mode,
406 int intensity) {
407 lights += 1;
408
409 if (lights >= maxlights) {
410 if (light == null) {
411 maxlights = 10;
412 light = new idx3d_light[11];
413 } else {
414 maxlights += 10;
415 idx3d_light temp[] = new idx3d_light[maxlights +
416 1];
417 System.arraycopy(light,
418 1,
419 temp,
420 1,
421 lights);
422 light = temp;
423 }
424 }
425 if (mode == 1) v = normalize(v);
426 light[lights] =
427 new idx3d_light(v, mode, intensity);
428 }
429
430 public void addTexture(Image img) {
431 textures += 1;
432
433 if (textures >= maxtextures) {
434 if (texture == null) {
435 maxtextures = 20;
436 texture = new idx3d_texture[21];
437 } else {
438 maxtextures *= 2;
439 idx3d_texture temp[] = new idx3d_texture[maxtextures +
440 1];
441 System.arraycopy(texture,
442 1,
443 temp,
444 1,
445 textures);
446 texture = temp;
447 }
448 }
449 texture[textures] = new idx3d_texture();
450 while (img.getWidth(this) < 0 ||
451 img.getHeight(this) < 0) {
452 }
453 int width = img.getWidth(this);
454 int height = img.getHeight(this);
455 texture[textures].w = width;
456 texture[textures].h = height;
457 texture[textures].pixel =
458 new int[width][height];
459 int temp2[] = new int[width * height];
460 PixelGrabber pg = new PixelGrabber(img,
461 0,
462 0,
463 width,
464 height,
465 temp2,
466 0,
467 width);
468 try {
469 pg.grabPixels();
470 } catch (InterruptedException e) {
471 }
472 for (int j = 0; j < height; j++) {
473 for (int i = 0; i < width; i++) {
474 texture[textures].pixel[i][j] =
475 temp2[i + j * width];
476 }
477 }
478 }
479
480 public void addTriangle(int objectNr,
481 int p1,
482 int p2,
483 int p3) {
484 object[objectNr].triangles += 1;
485
486 if (object[objectNr].triangles >=
487 object[objectNr].maxtriangles) {
488 if (object[objectNr].triangle ==
489 null) {
490 object[objectNr].maxtriangles =
491 2;
492 object[objectNr].triangle =
493 new idx3d_triangle[11];
494 } else {
495 object[objectNr].maxtriangles *=
496 2;
497 idx3d_triangle temp[] = new idx3d_triangle[object[objectNr].maxtriangles +
498 1];
499 System.arraycopy(
500 object[objectNr].triangle,
501 1,
502 temp,
503 1,
504 object[objectNr].triangles);
505 object[objectNr].triangle = temp;
506 }
507 }
508 object[objectNr].triangle[object[objectNr].triangles] =
509 new idx3d_triangle(p1, p2, p3);
510 object[objectNr].triangle[object[objectNr].triangles].n =
511 getNormal(object[objectNr].node[p1].v,
512 object[objectNr].node[p3].v,
513 object[objectNr].node[p2].v);
514 }
515
516 public void addNode(int objectNr,
517 idx3d_node t) {
518 object[objectNr].nodes += 1;
519
520 if (object[objectNr].nodes >=
521 object[objectNr].maxnodes) {
522 if (object[objectNr].node == null) {
523 object[objectNr].maxnodes = 2;
524 object[objectNr].node =
525 new idx3d_node[11];
526 } else {
527 object[objectNr].maxnodes *= 2;
528 idx3d_node temp[] = new idx3d_node[object[objectNr].maxnodes +
529 1];
530 System.arraycopy(
531 object[objectNr].node,
532 1,
533 temp,
534 1,
535 object[objectNr].nodes);
536 object[objectNr].node = temp;
537 }
538 }
539 t.n = normalize(t.n);
540 object[objectNr].node[object[objectNr].nodes] =
541 t;
542 }
543
544 public void addNode(int objectNr,
545 float x,
546 float y,
547 float z) {
548 addNode(objectNr,
549 new idx3d_node(x, y, z));
550 }
551
552 // OBJECT MANIPULATION
553
554 public idx3d_matrix shiftMatrix(float dx,
555 float dy,
556 float dz) {
557 idx3d_matrix m = new idx3d_matrix();
558 m.matrix[0][3] = dx;
559 m.matrix[1][3] = dy;
560 m.matrix[2][3] = dz;
561 return m;
562 }
563
564 public idx3d_matrix scaleMatrix(float dx,
565 float dy,
566 float dz) {
567 idx3d_matrix m = new idx3d_matrix();
568 m.matrix[0][0] = dx;
569 m.matrix[1][1] = dy;
570 m.matrix[2][2] = dz;
571 return m;
572 }
573
574 public idx3d_matrix rotateMatrix(float dx,
575 float dy,
576 float dz) {
577 float SIN;
578 float COS;
579 int angle;
580 idx3d_matrix out = new idx3d_matrix();
581
582 if (dx != 0) {
583 idx3d_matrix m = new idx3d_matrix();
584 angle = ((int) dx + 1440) % 360;
585 SIN = sinus[angle];
586 COS = cosinus[angle];
587 m.matrix[1][1] = COS;
588 m.matrix[1][2] = SIN;
589 m.matrix[2][1] = -SIN;
590 m.matrix[2][2] = COS;
591 out = crossproduct(m, out);
592 }
593 if (dy != 0) {
594 idx3d_matrix m = new idx3d_matrix();
595 angle = ((int) dy + 720) % 360;
596 SIN = sinus[angle];
597 COS = cosinus[angle];
598 m.matrix[0][0] = COS;
599 m.matrix[0][2] = SIN;
600 m.matrix[2][0] = -SIN;
601 m.matrix[2][2] = COS;
602 out = crossproduct(m, out);
603 }
604 if (dz != 0) {
605 idx3d_matrix m = new idx3d_matrix();
606 angle = ((int) dz + 720) % 360;
607 SIN = sinus[angle];
608 COS = cosinus[angle];
609 m.matrix[0][0] = COS;
610 m.matrix[0][1] = SIN;
611 m.matrix[1][0] = -SIN;
612 m.matrix[1][1] = COS;
613 out = crossproduct(m, out);
614 }
615 return out;
616 }
617
618 public void shiftObject(int o,
619 float dx,
620 float dy,
621 float dz) {
622 object[o].matrix =
623 crossproduct(shiftMatrix(dx, dy, dz),
624 object[o].matrix);
625 }
626
627 public void scaleObject(int o,
628 float dx,
629 float dy,
630 float dz) {
631 object[o].matrix =
632 crossproduct(scaleMatrix(dx, dy, dz),
633 object[o].matrix);
634 }
635
636 public void rotateObject(int o,
637 float dx,
638 float dy,
639 float dz) {
640 object[o].matrix =
641 crossproduct(object[o].matrix,
642 rotateMatrix(dx, dy, dz));
643 }
644
645 public void rotateObjectWorld(int o,
646 float dx,
647 float dy,
648 float dz) {
649 object[o].matrix =
650 crossproduct(rotateMatrix(dx, dy, dz),
651 object[o].matrix);
652 }
653
654 public void rotateObject(int obj,
655 float px,
656 float py,
657 float pz,
658 float dx,
659 float dy,
660 float dz) {
661 shiftObject(obj, -px, -py, -pz);
662 rotateObject(obj, dx, dy, dz);
663 shiftObject(obj, px, py, pz);
664 }
665
666 public void shiftWorld(float dx,
667 float dy,
668 float dz) {
669 worldmatrix =
670 crossproduct(shiftMatrix(dx, dy, dz),
671 worldmatrix);
672 }
673
674 public void scaleWorld(float dx,
675 float dy,
676 float dz) {
677 worldmatrix =
678 crossproduct(scaleMatrix(dx, dy, dz),
679 worldmatrix);
680 }
681
682 public void rotateWorld(float dx,
683 float dy,
684 float dz) {
685 worldmatrix =
686 crossproduct(rotateMatrix(dx, dy, dz),
687 worldmatrix);
688 }
689
690 public void scaleObject(int obj, float d) {
691 scaleObject(obj, d, d, d);
692 }
693
694 public void scaleWorld(float d) {
695 scaleWorld(d, d, d);
696 }
697
698 // RENDERING
699
700 public Image renderScene() {
701 clearDoubleBuffer();
702 paintObjects();
703 paintImage();
704 return DoubleBuffer;
705 }
706
707 private void clearDoubleBuffer() {
708 for (int j = 0; j < h; j++) {
709 for (int i = 0; i < w; i++) {
710 zBuffer[i][j] = zInfinite;
711 }
712 }
713 for (int i = 0; i < w * h; i++) {
714 TargetPixel[i] = Background[i];
715 }
716 }
717
718 private void clearBackground() {
719 for (int i = 0; i < w * h; i++) {
720 Background[i] = bgcolor;
721 }
722 }
723
724 private void paintObjects() {
725 for (int i = 1; i <= objects; i++) {
726 object[i].matrix2 =
727 crossproduct(worldmatrix,
728 object[i].matrix);
729 for (int j = 1; j <= object[i].nodes; j++) {
730 object[i].node[j] =
731 projectNode(i,
732 object[i].node[j]);
733 }
734 for (int j = 1; j <=
735 object[i].triangles; j++) {
736 if (object[i].mode == 1) drawWireframe(
737 i,
738 object[i].triangle[j]);
739 if (object[i].mode == 2) drawFlatshaded(
740 i,
741 object[i].triangle[j]);
742 if (object[i].mode == 3) drawGouraud(
743 i,
744 object[i].triangle[j]);
745 if (object[i].mode == 4) drawPhong(
746 i,
747 object[i].triangle[j]);
748 if (object[i].mode == 5) drawEnvmapped(
749 i,
750 object[i].triangle[j]);
751 if (object[i].mode == 6) drawGouraudTexture(
752 i,
753 object[i].triangle[j]);
754 if (object[i].mode == 7) drawPhongTexture(
755 i,
756 object[i].triangle[j]);
757 if (object[i].mode == 8) drawEnvmappedTexture(
758 i,
759 object[i].triangle[j]);
760 }
761 }
762 }
763
764 private void paintImage() {
765 DoubleBuffer =
766 createImage(
767 new MemoryImageSource(w,
768 h,
769 idx_cm,
770 TargetPixel,
771 0,
772 w));
773 }
774
775 private idx3d_node projectNode(int obj,
776 idx3d_node q) {
777 idx3d_node w = q;
778 idx3d_vector mvect = matrixvectorproduct(
779 object[obj].matrix2, w.v);
780 w.n2 =
781 normalize(
782 matrixvectorproduct(
783 object[obj].matrix2,
784 w.n));
785
786 float zoom = perspective /
787 (perspective + mvect.z) *
788 zoomcorrection;
789 w.xx =
790 (int) (mvect.x * zoom * centerx +
791 centerx);
792 w.yy =
793 (int) (mvect.y * zoom * centery +
794 centery);
795 w.zz = (int) (mvect.z * 65536);
796 return w;
797 }
798
799 private int getIntensity(int nx, int ny) {
800 if (staticLight) return StaticLightMap[nx /
801 2 +
802 127][ny /
803 2 +
804 127];
805 int nz = LightMap[nx / 2 + 127][ny / 2 +
806 127];
807 int intensity = ambient;
808 for (int i = 1; i <= lights; i++) {
809 if (light[i].mode == 1) {
810 intensity +=
811 crop(
812 (light[i].intensity *
813 (int) Math.abs(
814 nx * light[i].x +
815 ny * light[i].y +
816 nz * light[i].z) >>
817 8) >>
818 8,
819 0,
820 255);
821 }
822 if (light[i].mode == 2) {
823 // POINT LIGHT ALGORITHM TO BE IMPLEMENTED HERE
824 }
825 }
826 return crop(intensity, 0, 255);
827 }
828
829 private int getIntensity(idx3d_vector v) {
830 return getIntensity((int) (v.x * 255),
831 (int) (v.y * 255));
832 }
833
834 private int getEnvironment(int nx, int ny) {
835 if (staticLight) return StaticEnvMap[nx /
836 2 +
837 127][ny /
838 2 +
839 127];
840 int env = EnvMap[nx / 2 + 127][ny / 2 +
841 127];
842 return crop(
843 ambient +
844 getIntensity(nx, ny) * env *
845 reflectivity /
846 65536,
847 0,
848 255);
849 }
850
851 public int getIntColor(int r, int g, int b) {
852 return alpha | (r << 16) | (g << 8) | b;
853 }
854
855 private int getColor(int c, int intensity) {
856 int r = ColorMap[intensity][(rbit & c) >>
857 16];
858 int g = ColorMap[intensity][(gbit & c) >>
859 8];
860 int b = ColorMap[intensity][(bbit & c)];
861 return getIntColor(r, g, b);
862 }
863
864 private int getGray(int c) {
865 return (((rbit & c) >> 16) +
866 ((gbit & c) >> 8) +
867 (bbit & c)) /
868 3;
869 //return (bbit&c);
870 }
871
872 public void setBackground(Image TempImage) {
873 PixelGrabber pg = new PixelGrabber(
874 TempImage,
875 0,
876 0,
877 w,
878 h,
879 Background,
880 0,
881 w);
882 try {
883 pg.grabPixels();
884 } catch (InterruptedException e) {
885 }
886 }
887
888 public void setEnvironment(Image TempImage) {
889 int temp[] = new int[256 * 256];
890 PixelGrabber pg = new PixelGrabber(
891 TempImage,
892 0,
893 0,
894 256,
895 256,
896 temp,
897 0,
898 256);
899 try {
900 pg.grabPixels();
901 } catch (InterruptedException e) {
902 }
903 for (int i = 0; i < 256; i++) {
904 for (int j = 0; j < 256; j++) {
905 EnvMap[i][j] =
906 getGray(temp[i + j * 256]);
907 }
908 }
909 }
910
911 // RENDERMODES
912
913 private void drawLine(idx3d_node q1,
914 idx3d_node q2,
915 int color) {
916 idx3d_node temp;
917 int dx = (int) Math.abs(q1.xx - q2.xx);
918 int dy = (int) Math.abs(q1.yy - q2.yy);
919 int dz = 0;
920 int x, y, z;
921 int x2, y2;
922
923 if (dx > dy) {
924 if (q1.xx > q2.xx) {
925 temp = q1;
926 q1 = q2;
927 q2 = temp;
928 }
929 if (dx > 0) {
930 dz = (q2.zz - q1.zz) / dx;
931 dy = ((q2.yy - q1.yy) << 16) /
932 dx;
933 }
934 z = q1.zz;
935 y = q1.yy << 16;
936 for (x = q1.xx; x <= q2.xx; x++) {
937 y2 = y >> 16;
938 if (inrange(x, 0, w) &&
939 inrange(y2, 0, h)) {
940 if (z < zBuffer[x][y2]) {
941 TargetPixel[x + y2 * w] =
942 color;
943 zBuffer[x][y2] = z;
944 }
945 }
946 z += dz;
947 y += dy;
948 }
949 } else {
950 if (q1.yy > q2.yy) {
951 temp = q1;
952 q1 = q2;
953 q2 = temp;
954 }
955 if (dy > 0) {
956 dz = (q2.zz - q1.zz) / dy;
957 dx = ((q2.xx - q1.xx) << 16) /
958 dy;
959 }
960 z = q1.zz;
961 x = q1.xx << 16;
962 for (y = q1.yy; y <= q2.yy; y++) {
963 x2 = x >> 16;
964 if (inrange(x2, 0, w) &&
965 inrange(y, 0, h)) {
966 if (z < zBuffer[x2][y]) {
967 TargetPixel[x2 + y * w] =
968 color;
969 zBuffer[x2][y] = z;
970 }
971 }
972 z += dz;
973 x += dx;
974 }
975 }
976 }
977
978 private void drawWireframe(int obj,
979 idx3d_triangle t) {
980
981 int c = object[obj].color;
982
983 idx3d_node p1 = object[obj].node[t.p1];
984 idx3d_node p2 = object[obj].node[t.p2];
985 idx3d_node p3 = object[obj].node[t.p3];
986
987 drawLine(p1, p2, c);
988 drawLine(p2, p3, c);
989 drawLine(p1, p3, c);
990 }
991
992 private void drawFlatshaded(int obj,
993 idx3d_triangle t) {
994 idx3d_vector n = normalize(
995 matrixvectorproduct(
996 object[obj].matrix, t.n));
997
998
999 idx3d_node temp1;
1000
1001 idx3d_node p1 = object[obj].node[t.p1];
1002 idx3d_node p2 = object[obj].node[t.p2];
1003 idx3d_node p3 = object[obj].node[t.p3];
1004
1005 if (p1.yy > p2.yy) {
1006 temp1 = p1;
1007 p1 = p2;
1008 p2 = temp1;
1009 }
1010 if (p2.yy > p3.yy) {
1011 temp1 = p2;
1012 p2 = p3;
1013 p3 = temp1;
1014 }
1015 if (p1.yy > p2.yy) {
1016 temp1 = p1;
1017 p1 = p2;
1018 p2 = temp1;
1019 }
1020
1021 int x1 = p1.xx << 16;
1022 int x2 = p2.xx << 16;
1023 int x3 = p3.xx << 16;
1024 int y1 = p1.yy << 16;
1025 int y2 = p2.yy << 16;
1026 int y3 = p3.yy << 16;
1027
1028 int dx1 = 0;
1029 int dx2 = 0;
1030 int dx3 = 0;
1031 int dz1 = 0;
1032 int dz2 = 0;
1033 int dz3 = 0;
1034 int dy;
1035 if (y2 != y1) {
1036 dy = (y2 - y1) >> 16;
1037 dx1 = (x2 - x1) / dy;
1038 dz1 = (p2.zz - p1.zz) / dy;
1039 }
1040 if (y3 != y2) {
1041 dy = (y3 - y2) >> 16;
1042 dx2 = (x3 - x2) / dy;
1043 dz2 = (p3.zz - p2.zz) / dy;
1044 }
1045 if (y3 != y1) {
1046 dy = (y3 - y1) >> 16;
1047 dx3 = (x3 - x1) / dy;
1048 dz3 = (p3.zz - p1.zz) / dy;
1049 }
1050
1051 int xL = x1;
1052 int xR = x1;
1053 int zL = p1.zz;
1054 int zR = p1.zz;
1055
1056 y1 = y1 >> 16;
1057 y2 = y2 >> 16;
1058 y3 = y3 >> 16;
1059
1060 for (int k = y1; k < y2; k++) {
1061 if ((k >= 0) && (k < h)) {
1062 LEdgeBuffer[k] = xL >> 16;
1063 REdgeBuffer[k] = xR >> 16;
1064 ZEdgeBufferL[k] = zL;
1065 ZEdgeBufferR[k] = zR;
1066 }
1067 xL += dx1;
1068 xR += dx3;
1069 zL += dz1;
1070 zR += dz3;
1071 }
1072 xL = x2;
1073 zL = p2.zz;
1074 for (int k = y2; k <= y3; k++) {
1075 if ((k >= 0) && (k < h)) {
1076 LEdgeBuffer[k] = xL >> 16;
1077 REdgeBuffer[k] = xR >> 16;
1078 ZEdgeBufferL[k] = zL;
1079 ZEdgeBufferR[k] = zR;
1080 }
1081 xL += dx2;
1082 xR += dx3;
1083 zL += dz2;
1084 zR += dz3;
1085 }
1086
1087 y1 = crop(y1, 0, h);
1088 y3 = crop(y3, 0, h);
1089
1090 for (int j = y1; j <= y3; j++) drawFlatshadedLine(
1091 j,
1092 getColor(object[obj].color,
1093 getIntensity(n)));
1094 }
1095
1096 private void drawGouraud(int obj,
1097 idx3d_triangle t) {
1098
1099 idx3d_node temp1;
1100
1101 idx3d_node p1 = object[obj].node[t.p1];
1102 idx3d_node p2 = object[obj].node[t.p2];
1103 idx3d_node p3 = object[obj].node[t.p3];
1104
1105 if (p1.yy > p2.yy) {
1106 temp1 = p1;
1107 p1 = p2;
1108 p2 = temp1;
1109 }
1110 if (p2.yy > p3.yy) {
1111 temp1 = p2;
1112 p2 = p3;
1113 p3 = temp1;
1114 }
1115 if (p1.yy > p2.yy) {
1116 temp1 = p1;
1117 p1 = p2;
1118 p2 = temp1;
1119 }
1120
1121 int i1 = getIntensity(p1.n2) << 8;
1122 int i2 = getIntensity(p2.n2) << 8;
1123 int i3 = getIntensity(p3.n2) << 8;
1124
1125 int x1 = p1.xx << 16;
1126 int x2 = p2.xx << 16;
1127 int x3 = p3.xx << 16;
1128 int y1 = p1.yy << 16;
1129 int y2 = p2.yy << 16;
1130 int y3 = p3.yy << 16;
1131
1132 int dx1 = 0;
1133 int dx2 = 0;
1134 int dx3 = 0;
1135 int dz1 = 0;
1136 int dz2 = 0;
1137 int dz3 = 0;
1138 int di1 = 0;
1139 int di2 = 0;
1140 int di3 = 0;
1141 int dy;
1142 if (y2 != y1) {
1143 dy = (y2 - y1) >> 16;
1144 dx1 = (x2 - x1) / dy;
1145 dz1 = (p2.zz - p1.zz) / dy;
1146 di1 = (i2 - i1) / dy;
1147 }
1148 if (y3 != y2) {
1149 dy = (y3 - y2) >> 16;
1150 dx2 = (x3 - x2) / dy;
1151 dz2 = (p3.zz - p2.zz) / dy;
1152 di2 = (i3 - i2) / dy;
1153 }
1154 if (y3 != y1) {
1155 dy = (y3 - y1) >> 16;
1156 dx3 = (x3 - x1) / dy;
1157 dz3 = (p3.zz - p1.zz) / dy;
1158 di3 = (i3 - i1) / dy;
1159 }
1160
1161 int xL = x1;
1162 int xR = x1;
1163 int zL = p1.zz;
1164 int zR = p1.zz;
1165 int iL = i1;
1166 int iR = i1;
1167
1168 y1 = y1 >> 16;
1169 y2 = y2 >> 16;
1170 y3 = y3 >> 16;
1171
1172 for (int k = y1; k < y2; k++) {
1173 if ((k >= 0) && (k < h)) {
1174 LEdgeBuffer[k] = xL >> 16;
1175 REdgeBuffer[k] = xR >> 16;
1176 ZEdgeBufferL[k] = zL;
1177 ZEdgeBufferR[k] = zR;
1178 IEdgeBufferL[k] = iL;
1179 IEdgeBufferR[k] = iR;
1180 }
1181 xL += dx1;
1182 xR += dx3;
1183 zL += dz1;
1184 zR += dz3;
1185 iL += di1;
1186 iR += di3;
1187 }
1188 xL = x2;
1189 zL = p2.zz;
1190 iL = i2;
1191 for (int k = y2; k <= y3; k++) {
1192 if ((k >= 0) && (k < h)) {
1193 LEdgeBuffer[k] = xL >> 16;
1194 REdgeBuffer[k] = xR >> 16;
1195 ZEdgeBufferL[k] = zL;
1196 ZEdgeBufferR[k] = zR;
1197 IEdgeBufferL[k] = iL;
1198 IEdgeBufferR[k] = iR;
1199 }
1200 xL += dx2;
1201 xR += dx3;
1202 zL += dz2;
1203 zR += dz3;
1204 iL += di2;
1205 iR += di3;
1206 }
1207
1208 y1 = crop(y1, 0, h);
1209 y3 = crop(y3, 0, h);
1210
1211 for (int j = y1; j <= y3; j++) drawGouraudLine(
1212 j, object[obj].color);
1213 }
1214
1215 private void drawPhong(int obj,
1216 idx3d_triangle t) {
1217
1218 idx3d_node temp1;
1219
1220 idx3d_node p1 = object[obj].node[t.p1];
1221 idx3d_node p2 = object[obj].node[t.p2];
1222 idx3d_node p3 = object[obj].node[t.p3];
1223
1224 if (p1.yy > p2.yy) {
1225 temp1 = p1;
1226 p1 = p2;
1227 p2 = temp1;
1228 }
1229 if (p2.yy > p3.yy) {
1230 temp1 = p2;
1231 p2 = p3;
1232 p3 = temp1;
1233 }
1234 if (p1.yy > p2.yy) {
1235 temp1 = p1;
1236 p1 = p2;
1237 p2 = temp1;
1238 }
1239
1240 int x1 = p1.xx << 16;
1241 int x2 = p2.xx << 16;
1242 int x3 = p3.xx << 16;
1243 int y1 = p1.yy << 16;
1244 int y2 = p2.yy << 16;
1245 int y3 = p3.yy << 16;
1246
1247 int nx1 = (int) (65536 * p1.n2.x);
1248 int nx2 = (int) (65536 * p2.n2.x);
1249 int nx3 = (int) (65536 * p3.n2.x);
1250 int ny1 = (int) (65536 * p1.n2.y);
1251 int ny2 = (int) (65536 * p2.n2.y);
1252 int ny3 = (int) (65536 * p3.n2.y);
1253
1254 int dx1 = 0;
1255 int dx2 = 0;
1256 int dx3 = 0;
1257 int dz1 = 0;
1258 int dz2 = 0;
1259 int dz3 = 0;
1260 int dnx1 = 0;
1261 int dnx2 = 0;
1262 int dnx3 = 0;
1263 int dny1 = 0;
1264 int dny2 = 0;
1265 int dny3 = 0;
1266 int dy;
1267 if (y2 != y1) {
1268 dy = (y2 - y1) >> 16;
1269 dx1 = (x2 - x1) / dy;
1270 dz1 = (p2.zz - p1.zz) / dy;
1271 dnx1 = (nx2 - nx1) / dy;
1272 dny1 = (ny2 - ny1) / dy;
1273 }
1274 if (y3 != y2) {
1275 dy = (y3 - y2) >> 16;
1276 dx2 = (x3 - x2) / dy;
1277 dz2 = (p3.zz - p2.zz) / dy;
1278 dnx2 = (nx3 - nx2) / dy;
1279 dny2 = (ny3 - ny2) / dy;
1280 }
1281 if (y3 != y1) {
1282 dy = (y3 - y1) >> 16;
1283 dx3 = (x3 - x1) / dy;
1284 dz3 = (p3.zz - p1.zz) / dy;
1285 dnx3 = (nx3 - nx1) / dy;
1286 dny3 = (ny3 - ny1) / dy;
1287 }
1288
1289 int xL = x1;
1290 int xR = x1;
1291 int zL = p1.zz;
1292 int zR = p1.zz;
1293 int nxL = nx1;
1294 int nxR = nx1;
1295 int nyL = ny1;
1296 int nyR = ny1;
1297
1298 y1 = y1 >> 16;
1299 y2 = y2 >> 16;
1300 y3 = y3 >> 16;
1301
1302 for (int k = y1; k < y2; k++) {
1303 if ((k >= 0) && (k < h)) {
1304 LEdgeBuffer[k] = xL >> 16;
1305 REdgeBuffer[k] = xR >> 16;
1306 ZEdgeBufferL[k] = zL;
1307 ZEdgeBufferR[k] = zR;
1308 NXEdgeBufferL[k] = nxL;
1309 NXEdgeBufferR[k] = nxR;
1310 NYEdgeBufferL[k] = nyL;
1311 NYEdgeBufferR[k] = nyR;
1312 }
1313 xL += dx1;
1314 xR += dx3;
1315 zL += dz1;
1316 zR += dz3;
1317 nxL += dnx1;
1318 nxR += dnx3;
1319 nyL += dny1;
1320 nyR += dny3;
1321 }
1322 xL = x2;
1323 zL = p2.zz;
1324 nxL = nx2;
1325 nyL = ny2;
1326 for (int k = y2; k <= y3; k++) {
1327 if ((k >= 0) && (k < h)) {
1328 LEdgeBuffer[k] = xL >> 16;
1329 REdgeBuffer[k] = xR >> 16;
1330 ZEdgeBufferL[k] = zL;
1331 ZEdgeBufferR[k] = zR;
1332 NXEdgeBufferL[k] = nxL;
1333 NXEdgeBufferR[k] = nxR;
1334 NYEdgeBufferL[k] = nyL;
1335 NYEdgeBufferR[k] = nyR;
1336 }
1337 xL += dx2;
1338 xR += dx3;
1339 zL += dz2;
1340 zR += dz3;
1341 nxL += dnx2;
1342 nxR += dnx3;
1343 nyL += dny2;
1344 nyR += dny3;
1345 }
1346
1347 y1 = crop(y1, 0, h);
1348 y3 = crop(y3, 0, h);
1349
1350 for (int j = y1; j <= y3; j++) drawPhongLine(
1351 j, object[obj].color);
1352 }
1353
1354 private void drawEnvmapped(int obj,
1355 idx3d_triangle t) {
1356
1357 idx3d_node temp1;
1358
1359 idx3d_node p1 = object[obj].node[t.p1];
1360 idx3d_node p2 = object[obj].node[t.p2];
1361 idx3d_node p3 = object[obj].node[t.p3];
1362
1363 if (p1.yy > p2.yy) {
1364 temp1 = p1;
1365 p1 = p2;
1366 p2 = temp1;
1367 }
1368 if (p2.yy > p3.yy) {
1369 temp1 = p2;
1370 p2 = p3;
1371 p3 = temp1;
1372 }
1373 if (p1.yy > p2.yy) {
1374 temp1 = p1;
1375 p1 = p2;
1376 p2 = temp1;
1377 }
1378
1379 int x1 = p1.xx << 16;
1380 int x2 = p2.xx << 16;
1381 int x3 = p3.xx << 16;
1382 int y1 = p1.yy << 16;
1383 int y2 = p2.yy << 16;
1384 int y3 = p3.yy << 16;
1385
1386 int nx1 = (int) (65536 * p1.n2.x);
1387 int nx2 = (int) (65536 * p2.n2.x);
1388 int nx3 = (int) (65536 * p3.n2.x);
1389 int ny1 = (int) (65536 * p1.n2.y);
1390 int ny2 = (int) (65536 * p2.n2.y);
1391 int ny3 = (int) (65536 * p3.n2.y);
1392
1393 int dx1 = 0;
1394 int dx2 = 0;
1395 int dx3 = 0;
1396 int dz1 = 0;
1397 int dz2 = 0;
1398 int dz3 = 0;
1399 int dnx1 = 0;
1400 int dnx2 = 0;
1401 int dnx3 = 0;
1402 int dny1 = 0;
1403 int dny2 = 0;
1404 int dny3 = 0;
1405 int dy;
1406 if (y2 != y1) {
1407 dy = (y2 - y1) >> 16;
1408 dx1 = (x2 - x1) / dy;
1409 dz1 = (p2.zz - p1.zz) / dy;
1410 dnx1 = (nx2 - nx1) / dy;
1411 dny1 = (ny2 - ny1) / dy;
1412 }
1413 if (y3 != y2) {
1414 dy = (y3 - y2) >> 16;
1415 dx2 = (x3 - x2) / dy;
1416 dz2 = (p3.zz - p2.zz) / dy;
1417 dnx2 = (nx3 - nx2) / dy;
1418 dny2 = (ny3 - ny2) / dy;
1419 }
1420 if (y3 != y1) {
1421 dy = (y3 - y1) >> 16;
1422 dx3 = (x3 - x1) / dy;
1423 dz3 = (p3.zz - p1.zz) / dy;
1424 dnx3 = (nx3 - nx1) / dy;
1425 dny3 = (ny3 - ny1) / dy;
1426 }
1427
1428 int xL = x1;
1429 int xR = x1;
1430 int zL = p1.zz;
1431 int zR = p1.zz;
1432 int nxL = nx1;
1433 int nxR = nx1;
1434 int nyL = ny1;
1435 int nyR = ny1;
1436
1437 y1 = y1 >> 16;
1438 y2 = y2 >> 16;
1439 y3 = y3 >> 16;
1440
1441 for (int k = y1; k < y2; k++) {
1442 if ((k >= 0) && (k < h)) {
1443 LEdgeBuffer[k] = xL >> 16;
1444 REdgeBuffer[k] = xR >> 16;
1445 ZEdgeBufferL[k] = zL;
1446 ZEdgeBufferR[k] = zR;
1447 NXEdgeBufferL[k] = nxL;
1448 NXEdgeBufferR[k] = nxR;
1449 NYEdgeBufferL[k] = nyL;
1450 NYEdgeBufferR[k] = nyR;
1451 }
1452 xL += dx1;
1453 xR += dx3;
1454 zL += dz1;
1455 zR += dz3;
1456 nxL += dnx1;
1457 nxR += dnx3;
1458 nyL += dny1;
1459 nyR += dny3;
1460 }
1461 xL = x2;
1462 zL = p2.zz;
1463 nxL = nx2;
1464 nyL = ny2;
1465 for (int k = y2; k <= y3; k++) {
1466 if ((k >= 0) && (k < h)) {
1467 LEdgeBuffer[k] = xL >> 16;
1468 REdgeBuffer[k] = xR >> 16;
1469 ZEdgeBufferL[k] = zL;
1470 ZEdgeBufferR[k] = zR;
1471 NXEdgeBufferL[k] = nxL;
1472 NXEdgeBufferR[k] = nxR;
1473 NYEdgeBufferL[k] = nyL;
1474 NYEdgeBufferR[k] = nyR;
1475 }
1476 xL += dx2;
1477 xR += dx3;
1478 zL += dz2;
1479 zR += dz3;
1480 nxL += dnx2;
1481 nxR += dnx3;
1482 nyL += dny2;
1483 nyR += dny3;
1484 }
1485
1486 y1 = crop(y1, 0, h);
1487 y3 = crop(y3, 0, h);
1488
1489 for (int j = y1; j <= y3; j++) drawEnvmappedLine(
1490 j, object[obj].color);
1491 }
1492
1493 private void drawGouraudTexture(int obj,
1494 idx3d_triangle t) {
1495
1496 idx3d_node temp1;
1497
1498 idx3d_node p1 = object[obj].node[t.p1];
1499 idx3d_node p2 = object[obj].node[t.p2];
1500 idx3d_node p3 = object[obj].node[t.p3];
1501
1502 if (p1.yy > p2.yy) {
1503 temp1 = p1;
1504 p1 = p2;
1505 p2 = temp1;
1506 }
1507 if (p2.yy > p3.yy) {
1508 temp1 = p2;
1509 p2 = p3;
1510 p3 = temp1;
1511 }
1512 if (p1.yy > p2.yy) {
1513 temp1 = p1;
1514 p1 = p2;
1515 p2 = temp1;
1516 }
1517
1518 int i1 = getIntensity(p1.n2) << 8;
1519 int i2 = getIntensity(p2.n2) << 8;
1520 int i3 = getIntensity(p3.n2) << 8;
1521
1522 int x1 = p1.xx << 16;
1523 int x2 = p2.xx << 16;
1524 int x3 = p3.xx << 16;
1525 int y1 = p1.yy << 16;
1526 int y2 = p2.yy << 16;
1527 int y3 = p3.yy << 16;
1528 float tw = (float) texture[object[obj].texture].w *
1529 65536;
1530 float th = (float) texture[object[obj].texture].h *
1531 65536;
1532 int tx1 = (int) (tw * p1.tx);
1533 int tx2 = (int) (tw * p2.tx);
1534 int tx3 = (int) (tw * p3.tx);
1535 int ty1 = (int) (th * p1.ty);
1536 int ty2 = (int) (th * p2.ty);
1537 int ty3 = (int) (th * p3.ty);
1538
1539 int dx1 = 0;
1540 int dx2 = 0;
1541 int dx3 = 0;
1542 int dz1 = 0;
1543 int dz2 = 0;
1544 int dz3 = 0;
1545 int di1 = 0;
1546 int di2 = 0;
1547 int di3 = 0;
1548 int dtx1 = 0;
1549 int dtx2 = 0;
1550 int dtx3 = 0;
1551 int dty1 = 0;
1552 int dty2 = 0;
1553 int dty3 = 0;
1554 int dy;
1555 if (y2 != y1) {
1556 dy = (y2 - y1) >> 16;
1557 dx1 = (x2 - x1) / dy;
1558 dz1 = (p2.zz - p1.zz) / dy;
1559 di1 = (i2 - i1) / dy;
1560 dtx1 = (tx2 - tx1) / dy;
1561 dty1 = (ty2 - ty1) / dy;
1562 }
1563 if (y3 != y2) {
1564 dy = (y3 - y2) >> 16;
1565 dx2 = (x3 - x2) / dy;
1566 dz2 = (p3.zz - p2.zz) / dy;
1567 di2 = (i3 - i2) / dy;
1568 dtx2 = (tx3 - tx2) / dy;
1569 dty2 = (ty3 - ty2) / dy;
1570 }
1571 if (y3 != y1) {
1572 dy = (y3 - y1) >> 16;
1573 dx3 = (x3 - x1) / dy;
1574 dz3 = (p3.zz - p1.zz) / dy;
1575 di3 = (i3 - i1) / dy;
1576 dtx3 = (tx3 - tx1) / dy;
1577 dty3 = (ty3 - ty1) / dy;
1578 }
1579
1580 int xL = x1;
1581 int xR = x1;
1582 int zL = p1.zz;
1583 int zR = p1.zz;
1584 int iL = i1;
1585 int iR = i1;
1586 int txL = tx1;
1587 int txR = tx1;
1588 int tyL = ty1;
1589 int tyR = ty1;
1590
1591 y1 = y1 >> 16;
1592 y2 = y2 >> 16;
1593 y3 = y3 >> 16;
1594
1595 for (int k = y1; k < y2; k++) {
1596 if ((k >= 0) && (k < h)) {
1597 LEdgeBuffer[k] = xL >> 16;
1598 REdgeBuffer[k] = xR >> 16;
1599 ZEdgeBufferL[k] = zL;
1600 ZEdgeBufferR[k] = zR;
1601 IEdgeBufferL[k] = iL;
1602 IEdgeBufferR[k] = iR;
1603 TXEdgeBufferL[k] = txL;
1604 TXEdgeBufferR[k] = txR;
1605 TYEdgeBufferL[k] = tyL;
1606 TYEdgeBufferR[k] = tyR;
1607 }
1608 xL += dx1;
1609 xR += dx3;
1610 zL += dz1;
1611 zR += dz3;
1612 iL += di1;
1613 iR += di3;
1614 txL += dtx1;
1615 txR += dtx3;
1616 tyL += dty1;
1617 tyR += dty3;
1618 }
1619 xL = x2;
1620 zL = p2.zz;
1621 iL = i2;
1622 txL = tx2;
1623 tyL = ty2;
1624 for (int k = y2; k <= y3; k++) {
1625 if ((k >= 0) && (k < h)) {
1626 LEdgeBuffer[k] = xL >> 16;
1627 REdgeBuffer[k] = xR >> 16;
1628 ZEdgeBufferL[k] = zL;
1629 ZEdgeBufferR[k] = zR;
1630 IEdgeBufferL[k] = iL;
1631 IEdgeBufferR[k] = iR;
1632 TXEdgeBufferL[k] = txL;
1633 TXEdgeBufferR[k] = txR;
1634 TYEdgeBufferL[k] = tyL;
1635 TYEdgeBufferR[k] = tyR;
1636 }
1637 xL += dx2;
1638 xR += dx3;
1639 zL += dz2;
1640 zR += dz3;
1641 iL += di2;
1642 iR += di3;
1643 txL += dtx2;
1644 txR += dtx3;
1645 tyL += dty2;
1646 tyR += dty3;
1647 }
1648
1649 y1 = crop(y1, 0, h);
1650 y3 = crop(y3, 0, h);
1651
1652 for (int j = y1; j <= y3; j++) drawGouraudTextureLine(
1653 j, object[obj].texture);
1654 }
1655
1656 private void drawPhongTexture(int obj,
1657 idx3d_triangle t) {
1658
1659 idx3d_node temp1;
1660
1661 idx3d_node p1 = object[obj].node[t.p1];
1662 idx3d_node p2 = object[obj].node[t.p2];
1663 idx3d_node p3 = object[obj].node[t.p3];
1664
1665 if (p1.yy > p2.yy) {
1666 temp1 = p1;
1667 p1 = p2;
1668 p2 = temp1;
1669 }
1670 if (p2.yy > p3.yy) {
1671 temp1 = p2;
1672 p2 = p3;
1673 p3 = temp1;
1674 }
1675 if (p1.yy > p2.yy) {
1676 temp1 = p1;
1677 p1 = p2;
1678 p2 = temp1;
1679 }
1680
1681 int x1 = p1.xx << 16;
1682 int x2 = p2.xx << 16;
1683 int x3 = p3.xx << 16;
1684 int y1 = p1.yy << 16;
1685 int y2 = p2.yy << 16;
1686 int y3 = p3.yy << 16;
1687
1688 int nx1 = (int) (65536 * p1.n2.x);
1689 int nx2 = (int) (65536 * p2.n2.x);
1690 int nx3 = (int) (65536 * p3.n2.x);
1691 int ny1 = (int) (65536 * p1.n2.y);
1692 int ny2 = (int) (65536 * p2.n2.y);
1693 int ny3 = (int) (65536 * p3.n2.y);
1694
1695 float tw = (float) texture[object[obj].texture].w *
1696 65536;
1697 float th = (float) texture[object[obj].texture].h *
1698 65536;
1699 int tx1 = (int) (tw * p1.tx);
1700 int tx2 = (int) (tw * p2.tx);
1701 int tx3 = (int) (tw * p3.tx);
1702 int ty1 = (int) (th * p1.ty);
1703 int ty2 = (int) (th * p2.ty);
1704 int ty3 = (int) (th * p3.ty);
1705
1706 int dx1 = 0;
1707 int dx2 = 0;
1708 int dx3 = 0;
1709 int dz1 = 0;
1710 int dz2 = 0;
1711 int dz3 = 0;
1712 int dnx1 = 0;
1713 int dnx2 = 0;
1714 int dnx3 = 0;
1715 int dny1 = 0;
1716 int dny2 = 0;
1717 int dny3 = 0;
1718 int dtx1 = 0;
1719 int dtx2 = 0;
1720 int dtx3 = 0;
1721 int dty1 = 0;
1722 int dty2 = 0;
1723 int dty3 = 0;
1724 int dy;
1725 if (y2 != y1) {
1726 dy = (y2 - y1) >> 16;
1727 dx1 = (x2 - x1) / dy;
1728 dz1 = (p2.zz - p1.zz) / dy;
1729 dnx1 = (nx2 - nx1) / dy;
1730 dny1 = (ny2 - ny1) / dy;
1731 dtx1 = (tx2 - tx1) / dy;
1732 dty1 = (ty2 - ty1) / dy;
1733 }
1734 if (y3 != y2) {
1735 dy = (y3 - y2) >> 16;
1736 dx2 = (x3 - x2) / dy;
1737 dz2 = (p3.zz - p2.zz) / dy;
1738 dnx2 = (nx3 - nx2) / dy;
1739 dny2 = (ny3 - ny2) / dy;
1740 dtx2 = (tx3 - tx2) / dy;
1741 dty2 = (ty3 - ty2) / dy;
1742 }
1743 if (y3 != y1) {
1744 dy = (y3 - y1) >> 16;
1745 dx3 = (x3 - x1) / dy;
1746 dz3 = (p3.zz - p1.zz) / dy;
1747 dnx3 = (nx3 - nx1) / dy;
1748 dny3 = (ny3 - ny1) / dy;
1749 dtx3 = (tx3 - tx1) / dy;
1750 dty3 = (ty3 - ty1) / dy;
1751 }
1752
1753 int xL = x1;
1754 int xR = x1;
1755 int zL = p1.zz;
1756 int zR = p1.zz;
1757 int nxL = nx1;
1758 int nxR = nx1;
1759 int nyL = ny1;
1760 int nyR = ny1;
1761 int txL = tx1;
1762 int txR = tx1;
1763 int tyL = ty1;
1764 int tyR = ty1;
1765
1766 y1 = y1 >> 16;
1767 y2 = y2 >> 16;
1768 y3 = y3 >> 16;
1769
1770 for (int k = y1; k < y2; k++) {
1771 if ((k >= 0) && (k < h)) {
1772 LEdgeBuffer[k] = xL >> 16;
1773 REdgeBuffer[k] = xR >> 16;
1774 ZEdgeBufferL[k] = zL;
1775 ZEdgeBufferR[k] = zR;
1776 NXEdgeBufferL[k] = nxL;
1777 NXEdgeBufferR[k] = nxR;
1778 NYEdgeBufferL[k] = nyL;
1779 NYEdgeBufferR[k] = nyR;
1780 TXEdgeBufferL[k] = txL;
1781 TXEdgeBufferR[k] = txR;
1782 TYEdgeBufferL[k] = tyL;
1783 TYEdgeBufferR[k] = tyR;
1784 }
1785 xL += dx1;
1786 xR += dx3;
1787 zL += dz1;
1788 zR += dz3;
1789 nxL += dnx1;
1790 nxR += dnx3;
1791 nyL += dny1;
1792 nyR += dny3;
1793 txL += dtx1;
1794 txR += dtx3;
1795 tyL += dty1;
1796 tyR += dty3;
1797 }
1798 xL = x2;
1799 zL = p2.zz;
1800 nxL = nx2;
1801 nyL = ny2;
1802 txL = tx2;
1803 tyL = ty2;
1804 for (int k = y2; k <= y3; k++) {
1805 if ((k >= 0) && (k < h)) {
1806 LEdgeBuffer[k] = xL >> 16;
1807 REdgeBuffer[k] = xR >> 16;
1808 ZEdgeBufferL[k] = zL;
1809 ZEdgeBufferR[k] = zR;
1810 NXEdgeBufferL[k] = nxL;
1811 NXEdgeBufferR[k] = nxR;
1812 NYEdgeBufferL[k] = nyL;
1813 NYEdgeBufferR[k] = nyR;
1814 TXEdgeBufferL[k] = txL;
1815 TXEdgeBufferR[k] = txR;
1816 TYEdgeBufferL[k] = tyL;
1817 TYEdgeBufferR[k] = tyR;
1818 }
1819 xL += dx2;
1820 xR += dx3;
1821 zL += dz2;
1822 zR += dz3;
1823 nxL += dnx2;
1824 nxR += dnx3;
1825 nyL += dny2;
1826 nyR += dny3;
1827 txL += dtx2;
1828 txR += dtx3;
1829 tyL += dty2;
1830 tyR += dty3;
1831 }
1832
1833 y1 = crop(y1, 0, h);
1834 y3 = crop(y3, 0, h);
1835
1836 for (int j = y1; j <= y3; j++) drawPhongTextureLine(
1837 j, object[obj].texture);
1838 }
1839
1840 private void drawEnvmappedTexture(int obj,
1841 idx3d_triangle t) {
1842
1843 idx3d_node temp1;
1844
1845 idx3d_node p1 = object[obj].node[t.p1];
1846 idx3d_node p2 = object[obj].node[t.p2];
1847 idx3d_node p3 = object[obj].node[t.p3];
1848
1849 if (p1.yy > p2.yy) {
1850 temp1 = p1;
1851 p1 = p2;
1852 p2 = temp1;
1853 }
1854 if (p2.yy > p3.yy) {
1855 temp1 = p2;
1856 p2 = p3;
1857 p3 = temp1;
1858 }
1859 if (p1.yy > p2.yy) {
1860 temp1 = p1;
1861 p1 = p2;
1862 p2 = temp1;
1863 }
1864
1865 int x1 = p1.xx << 16;
1866 int x2 = p2.xx << 16;
1867 int x3 = p3.xx << 16;
1868 int y1 = p1.yy << 16;
1869 int y2 = p2.yy << 16;
1870 int y3 = p3.yy << 16;
1871
1872 int nx1 = (int) (65536 * p1.n2.x);
1873 int nx2 = (int) (65536 * p2.n2.x);
1874 int nx3 = (int) (65536 * p3.n2.x);
1875 int ny1 = (int) (65536 * p1.n2.y);
1876 int ny2 = (int) (65536 * p2.n2.y);
1877 int ny3 = (int) (65536 * p3.n2.y);
1878
1879 float tw = (float) texture[object[obj].texture].w *
1880 65536;
1881 float th = (float) texture[object[obj].texture].h *
1882 65536;
1883 int tx1 = (int) (tw * p1.tx);
1884 int tx2 = (int) (tw * p2.tx);
1885 int tx3 = (int) (tw * p3.tx);
1886 int ty1 = (int) (th * p1.ty);
1887 int ty2 = (int) (th * p2.ty);
1888 int ty3 = (int) (th * p3.ty);
1889
1890 int dx1 = 0;
1891 int dx2 = 0;
1892 int dx3 = 0;
1893 int dz1 = 0;
1894 int dz2 = 0;
1895 int dz3 = 0;
1896 int dnx1 = 0;
1897 int dnx2 = 0;
1898 int dnx3 = 0;
1899 int dny1 = 0;
1900 int dny2 = 0;
1901 int dny3 = 0;
1902 int dtx1 = 0;
1903 int dtx2 = 0;
1904 int dtx3 = 0;
1905 int dty1 = 0;
1906 int dty2 = 0;
1907 int dty3 = 0;
1908 int dy;
1909 if (y2 != y1) {
1910 dy = (y2 - y1) >> 16;
1911 dx1 = (x2 - x1) / dy;
1912 dz1 = (p2.zz - p1.zz) / dy;
1913 dnx1 = (nx2 - nx1) / dy;
1914 dny1 = (ny2 - ny1) / dy;
1915 dtx1 = (tx2 - tx1) / dy;
1916 dty1 = (ty2 - ty1) / dy;
1917 }
1918 if (y3 != y2) {
1919 dy = (y3 - y2) >> 16;
1920 dx2 = (x3 - x2) / dy;
1921 dz2 = (p3.zz - p2.zz) / dy;
1922 dnx2 = (nx3 - nx2) / dy;
1923 dny2 = (ny3 - ny2) / dy;
1924 dtx2 = (tx3 - tx2) / dy;
1925 dty2 = (ty3 - ty2) / dy;
1926 }
1927 if (y3 != y1) {
1928 dy = (y3 - y1) >> 16;
1929 dx3 = (x3 - x1) / dy;
1930 dz3 = (p3.zz - p1.zz) / dy;
1931 dnx3 = (nx3 - nx1) / dy;
1932 dny3 = (ny3 - ny1) / dy;
1933 dtx3 = (tx3 - tx1) / dy;
1934 dty3 = (ty3 - ty1) / dy;
1935 }
1936
1937 int xL = x1;
1938 int xR = x1;
1939 int zL = p1.zz;
1940 int zR = p1.zz;
1941 int nxL = nx1;
1942 int nxR = nx1;
1943 int nyL = ny1;
1944 int nyR = ny1;
1945 int txL = tx1;
1946 int txR = tx1;
1947 int tyL = ty1;
1948 int tyR = ty1;
1949
1950 y1 = y1 >> 16;
1951 y2 = y2 >> 16;
1952 y3 = y3 >> 16;
1953
1954 for (int k = y1; k < y2; k++) {
1955 if ((k >= 0) && (k < h)) {
1956 LEdgeBuffer[k] = xL >> 16;
1957 REdgeBuffer[k] = xR >> 16;
1958 ZEdgeBufferL[k] = zL;
1959 ZEdgeBufferR[k] = zR;
1960 NXEdgeBufferL[k] = nxL;
1961 NXEdgeBufferR[k] = nxR;
1962 NYEdgeBufferL[k] = nyL;
1963 NYEdgeBufferR[k] = nyR;
1964 TXEdgeBufferL[k] = txL;
1965 TXEdgeBufferR[k] = txR;
1966 TYEdgeBufferL[k] = tyL;
1967 TYEdgeBufferR[k] = tyR;
1968 }
1969 xL += dx1;
1970 xR += dx3;
1971 zL += dz1;
1972 zR += dz3;
1973 nxL += dnx1;
1974 nxR += dnx3;
1975 nyL += dny1;
1976 nyR += dny3;
1977 txL += dtx1;
1978 txR += dtx3;
1979 tyL += dty1;
1980 tyR += dty3;
1981 }
1982 xL = x2;
1983 zL = p2.zz;
1984 nxL = nx2;
1985 nyL = ny2;
1986 txL = tx2;
1987 tyL = ty2;
1988 for (int k = y2; k <= y3; k++) {
1989 if ((k >= 0) && (k < h)) {
1990 LEdgeBuffer[k] = xL >> 16;
1991 REdgeBuffer[k] = xR >> 16;
1992 ZEdgeBufferL[k] = zL;
1993 ZEdgeBufferR[k] = zR;
1994 NXEdgeBufferL[k] = nxL;
1995 NXEdgeBufferR[k] = nxR;
1996 NYEdgeBufferL[k] = nyL;
1997 NYEdgeBufferR[k] = nyR;
1998 TXEdgeBufferL[k] = txL;
1999 TXEdgeBufferR[k] = txR;
2000 TYEdgeBufferL[k] = tyL;
2001 TYEdgeBufferR[k] = tyR;
2002 }
2003 xL += dx2;
2004 xR += dx3;
2005 zL += dz2;
2006 zR += dz3;
2007 nxL += dnx2;
2008 nxR += dnx3;
2009 nyL += dny2;
2010 nyR += dny3;
2011 txL += dtx2;
2012 txR += dtx3;
2013 tyL += dty2;
2014 tyR += dty3;
2015 }
2016
2017 y1 = crop(y1, 0, h);
2018 y3 = crop(y3, 0, h);
2019
2020 for (int j = y1; j <= y3; j++) drawEnvmappedTextureLine(
2021 j, object[obj].texture);
2022 }
2023
2024
2025 private void drawFlatshadedLine(int y,
2026 int color) {
2027 if ((y >= 0) && (y < h)) {
2028 int xL = LEdgeBuffer[y];
2029 int xR = REdgeBuffer[y];
2030 int zL = ZEdgeBufferL[y];
2031 int zR = ZEdgeBufferR[y];
2032 if ((xL != xR)) {
2033 if (xL > xR) {
2034 int temp;
2035 temp = xL;
2036 xL = xR;
2037 xR = temp;
2038 temp = zL;
2039 zL = zR;
2040 zR = temp;
2041 }
2042 int dz = (zR - zL) / (xR - xL);
2043 int z = zL;
2044
2045 xL = crop(xL, 0, w);
2046 xR = crop(xR, 0, w);
2047
2048 int offset = y * w;
2049
2050 for (int x = xL; x < xR; x++) {
2051 if (z < zBuffer[x][y]) {
2052 TargetPixel[x + offset] =
2053 color;
2054 zBuffer[x][y] = z;
2055 }
2056 z += dz;
2057 }
2058 }
2059 }
2060 }
2061
2062 private void drawGouraudLine(int y,
2063 int color) {
2064 if ((y >= 0) && (y < h)) {
2065 int xL = LEdgeBuffer[y];
2066 int xR = REdgeBuffer[y];
2067 int zL = ZEdgeBufferL[y];
2068 int zR = ZEdgeBufferR[y];
2069 int iL = IEdgeBufferL[y];
2070 int iR = IEdgeBufferR[y];
2071 if ((xL != xR)) {
2072 if (xL > xR) {
2073 int temp;
2074 temp = xL;
2075 xL = xR;
2076 xR = temp;
2077 temp = zL;
2078 zL = zR;
2079 zR = temp;
2080 temp = iL;
2081 iL = iR;
2082 iR = temp;
2083 }
2084 int dx = (xR - xL);
2085 int dz = (zR - zL) / dx;
2086 int di = (iR - iL) / dx;
2087 int z = zL;
2088 int i = iL;
2089
2090 xL = crop(xL, 0, w);
2091 xR = crop(xR, 0, w);
2092
2093 int offset = y * w;
2094
2095 for (int x = xL; x < xR; x++) {
2096 if (z < zBuffer[x][y]) {
2097 TargetPixel[x + offset] =
2098 getColor(color, i >> 8);
2099 zBuffer[x][y] = z;
2100 }
2101 z += dz;
2102 i += di;
2103 }
2104 }
2105 }
2106 }
2107
2108 private void drawPhongLine(int y, int color) {
2109 if ((y >= 0) && (y < h)) {
2110 int xL = LEdgeBuffer[y];
2111 int xR = REdgeBuffer[y];
2112 int zL = ZEdgeBufferL[y];
2113 int zR = ZEdgeBufferR[y];
2114 int nxL = NXEdgeBufferL[y];
2115 int nxR = NXEdgeBufferR[y];
2116 int nyL = NYEdgeBufferL[y];
2117 int nyR = NYEdgeBufferR[y];
2118 if ((xL != xR)) {
2119 if (xL > xR) {
2120 int temp;
2121 temp = xL;
2122 xL = xR;
2123 xR = temp;
2124 temp = zL;
2125 zL = zR;
2126 zR = temp;
2127 temp = nxL;
2128 nxL = nxR;
2129 nxR = temp;
2130 temp = nyL;
2131 nyL = nyR;
2132 nyR = temp;
2133 }
2134 int dx = (xR - xL);
2135 int dz = (zR - zL) / dx;
2136 int dnx = (nxR - nxL) / dx;
2137 int dny = (nyR - nyL) / dx;
2138 int z = zL;
2139 int nx = nxL;
2140 int ny = nyL;
2141
2142 xL = crop(xL, 0, w);
2143 xR = crop(xR, 0, w);
2144
2145 int offset = y * w;
2146
2147 for (int x = xL; x < xR; x++) {
2148 if (z < zBuffer[x][y]) {
2149 TargetPixel[x + offset] =
2150 getColor(color,
2151 getIntensity(
2152 nx /
2153 256,
2154 ny /
2155 256));
2156 zBuffer[x][y] = z;
2157 }
2158 z += dz;
2159 nx += dnx;
2160 ny += dny;
2161 }
2162 }
2163 }
2164 }
2165
2166 private void drawEnvmappedLine(int y,
2167 int color) {
2168 if ((y >= 0) && (y < h)) {
2169 int xL = LEdgeBuffer[y];
2170 int xR = REdgeBuffer[y];
2171 int zL = ZEdgeBufferL[y];
2172 int zR = ZEdgeBufferR[y];
2173 int nxL = NXEdgeBufferL[y];
2174 int nxR = NXEdgeBufferR[y];
2175 int nyL = NYEdgeBufferL[y];
2176 int nyR = NYEdgeBufferR[y];
2177 if ((xL != xR)) {
2178 if (xL > xR) {
2179 int temp;
2180 temp = xL;
2181 xL = xR;
2182 xR = temp;
2183 temp = zL;
2184 zL = zR;
2185 zR = temp;
2186 temp = nxL;
2187 nxL = nxR;
2188 nxR = temp;
2189 temp = nyL;
2190 nyL = nyR;
2191 nyR = temp;
2192 }
2193 int dx = (xR - xL);
2194 int dz = (zR - zL) / dx;
2195 int dnx = (nxR - nxL) / dx;
2196 int dny = (nyR - nyL) / dx;
2197 int z = zL;
2198 int nx = nxL;
2199 int ny = nyL;
2200
2201 xL = crop(xL, 0, w);
2202 xR = crop(xR, 0, w);
2203
2204 int offset = y * w;
2205
2206 for (int x = xL; x < xR; x++) {
2207 if (z < zBuffer[x][y]) {
2208 TargetPixel[x + offset] =
2209 getColor(color,
2210 getEnvironment(
2211 nx /
2212 256,
2213 ny /
2214 256));
2215 zBuffer[x][y] = z;
2216 }
2217 z += dz;
2218 nx += dnx;
2219 ny += dny;
2220 }
2221 }
2222 }
2223 }
2224
2225 private void drawGouraudTextureLine(int y,
2226 int t) {
2227 if ((y >= 0) && (y < h)) {
2228 int xL = LEdgeBuffer[y];
2229 int xR = REdgeBuffer[y];
2230 int zL = ZEdgeBufferL[y];
2231 int zR = ZEdgeBufferR[y];
2232 int iL = IEdgeBufferL[y];
2233 int iR = IEdgeBufferR[y];
2234 int txL = TXEdgeBufferL[y];
2235 int txR = TXEdgeBufferR[y];
2236 int tyL = TYEdgeBufferL[y];
2237 int tyR = TYEdgeBufferR[y];
2238 if ((xL != xR)) {
2239 if (xL > xR) {
2240 int temp;
2241 temp = xL;
2242 xL = xR;
2243 xR = temp;
2244 temp = zL;
2245 zL = zR;
2246 zR = temp;
2247 temp = iL;
2248 iL = iR;
2249 iR = temp;
2250 temp = txL;
2251 txL = txR;
2252 txR = temp;
2253 temp = tyL;
2254 tyL = tyR;
2255 tyR = temp;
2256 }
2257 int dx = (xR - xL);
2258 int dz = (zR - zL) / dx;
2259 int di = (iR - iL) / dx;
2260 int dtx = (txR - txL) / dx;
2261 int dty = (tyR - tyL) / dx;
2262 int z = zL;
2263 int i = iL;
2264 int tx = txL;
2265 int ty = tyL;
2266
2267 xL = crop(xL, 0, w);
2268 xR = crop(xR, 0, w);
2269
2270 int offset = y * w;
2271
2272 for (int x = xL; x < xR; x++) {
2273 if (z < zBuffer[x][y]) {
2274 tx = (int) Math.abs(tx);
2275 ty = (int) Math.abs(ty);
2276 TargetPixel[x + offset] =
2277 getColor(
2278 texture[t].pixel[(tx >>
2279 16) %
2280 texture[t].w][(ty >>
2281 16) %
2282 texture[t].h],
2283 i >> 8);
2284 zBuffer[x][y] = z;
2285 }
2286 z += dz;
2287 i += di;
2288 tx += dtx;
2289 ty += dty;
2290 }
2291 }
2292 }
2293 }
2294
2295 private void drawPhongTextureLine(int y,
2296 int t) {
2297 if ((y >= 0) && (y < h)) {
2298 int xL = LEdgeBuffer[y];
2299 int xR = REdgeBuffer[y];
2300 int zL = ZEdgeBufferL[y];
2301 int zR = ZEdgeBufferR[y];
2302 int nxL = NXEdgeBufferL[y];
2303 int nxR = NXEdgeBufferR[y];
2304 int nyL = NYEdgeBufferL[y];
2305 int nyR = NYEdgeBufferR[y];
2306 int txL = TXEdgeBufferL[y];
2307 int txR = TXEdgeBufferR[y];
2308 int tyL = TYEdgeBufferL[y];
2309 int tyR = TYEdgeBufferR[y];
2310 if ((xL != xR)) {
2311 if (xL > xR) {
2312 int temp;
2313 temp = xL;
2314 xL = xR;
2315 xR = temp;
2316 temp = zL;
2317 zL = zR;
2318 zR = temp;
2319 temp = nxL;
2320 nxL = nxR;
2321 nxR = temp;
2322 temp = nyL;
2323 nyL = nyR;
2324 nyR = temp;
2325 temp = txL;
2326 txL = txR;
2327 txR = temp;
2328 temp = tyL;
2329 tyL = tyR;
2330 tyR = temp;
2331 }
2332 int dx = (xR - xL);
2333 int dz = (zR - zL) / dx;
2334 int dtx = (txR - txL) / dx;
2335 int dty = (tyR - tyL) / dx;
2336 int dnx = (nxR - nxL) / dx;
2337 int dny = (nyR - nyL) / dx;
2338 int z = zL;
2339 int nx = nxL;
2340 int ny = nyL;
2341 int tx = txL;
2342 int ty = tyL;
2343
2344 xL = crop(xL, 0, w);
2345 xR = crop(xR, 0, w);
2346
2347 int offset = y * w;
2348
2349 for (int x = xL; x < xR; x++) {
2350 if (z < zBuffer[x][y]) {
2351 tx = (int) Math.abs(tx);
2352 ty = (int) Math.abs(ty);
2353 TargetPixel[x + offset] =
2354 getColor(
2355 texture[t].pixel[(tx >>
2356 16) %
2357 texture[t].w][(ty >>
2358 16) %
2359 texture[t].h],
2360 getIntensity(
2361 nx / 256,
2362 ny / 256));
2363 zBuffer[x][y] = z;
2364 }
2365 z += dz;
2366 nx += dnx;
2367 ny += dny;
2368 tx += dtx;
2369 ty += dty;
2370 }
2371 }
2372 }
2373 }
2374
2375 private void drawEnvmappedTextureLine(int y,
2376 int t) {
2377 if ((y >= 0) && (y < h)) {
2378 int xL = LEdgeBuffer[y];
2379 int xR = REdgeBuffer[y];
2380 int zL = ZEdgeBufferL[y];
2381 int zR = ZEdgeBufferR[y];
2382 int nxL = NXEdgeBufferL[y];
2383 int nxR = NXEdgeBufferR[y];
2384 int nyL = NYEdgeBufferL[y];
2385 int nyR = NYEdgeBufferR[y];
2386 int txL = TXEdgeBufferL[y];
2387 int txR = TXEdgeBufferR[y];
2388 int tyL = TYEdgeBufferL[y];
2389 int tyR = TYEdgeBufferR[y];
2390 if ((xL != xR)) {
2391 if (xL > xR) {
2392 int temp;
2393 temp = xL;
2394 xL = xR;
2395 xR = temp;
2396 temp = zL;
2397 zL = zR;
2398 zR = temp;
2399 temp = nxL;
2400 nxL = nxR;
2401 nxR = temp;
2402 temp = nyL;
2403 nyL = nyR;
2404 nyR = temp;
2405 temp = txL;
2406 txL = txR;
2407 txR = temp;
2408 temp = tyL;
2409 tyL = tyR;
2410 tyR = temp;
2411 }
2412 int dx = (xR - xL);
2413 int dz = (zR - zL) / dx;
2414 int dtx = (txR - txL) / dx;
2415 int dty = (tyR - tyL) / dx;
2416 int dnx = (nxR - nxL) / dx;
2417 int dny = (nyR - nyL) / dx;
2418 int z = zL;
2419 int nx = nxL;
2420 int ny = nyL;
2421 int tx = txL;
2422 int ty = tyL;
2423
2424 xL = crop(xL, 0, w);
2425 xR = crop(xR, 0, w);
2426
2427 int offset = y * w;
2428
2429 for (int x = xL; x < xR; x++) {
2430 if (z < zBuffer[x][y]) {
2431 tx = (int) Math.abs(tx);
2432 ty = (int) Math.abs(ty);
2433 TargetPixel[x + offset] =
2434 getColor(
2435 texture[t].pixel[(tx >>
2436 16) %
2437 texture[t].w][(ty >>
2438 16) %
2439 texture[t].h],
2440 getEnvironment(
2441 nx / 256,
2442 ny / 256));
2443 zBuffer[x][y] = z;
2444 }
2445 z += dz;
2446 nx += dnx;
2447 ny += dny;
2448 tx += dtx;
2449 ty += dty;
2450 }
2451 }
2452 }
2453 }
2454
2455 // SPECIAL FUNCTIONS TO CREATE OBJECTS
2456
2457 public void generateField(float data[][],
2458 int xmax,
2459 int ymax,
2460 int rm,
2461 int c) {
2462 float xtemp;
2463 float ytemp;
2464 float ztemp;
2465 int q1;
2466 int q2;
2467 int q3;
2468 int q4;
2469 idx3d_node v;
2470 addObject(rm, c);
2471 rotateObject(objects, (float) 90, 0, 0);
2472 float xscale = 2 / (float) (xmax - 1);
2473 float yscale = 2 / (float) (ymax - 1);
2474 for (int i = 0; i < xmax; i++) {
2475 for (int j = 0; j < ymax; j++) {
2476 xtemp = -1 + xscale * (float) i;
2477 ytemp = -1 + yscale * (float) j;
2478 ztemp = data[i][j];
2479 v =
2480 new idx3d_node(xtemp,
2481 ytemp,
2482 ztemp);
2483 if ((j > 0) && (i > 0)) {
2484 v.n.x = (data[i - 1][j] -
2485 data[i][j]) /
2486 xscale;
2487 v.n.y = (data[i][j - 1] -
2488 data[i][j]) /
2489 yscale;
2490 v.n.z = (float) 1;
2491 }
2492 v.n.z = (float) 1;
2493 v.tx = (float) i /
2494 (float) (xmax - 1);
2495 v.ty = (float) j /
2496 (float) (ymax - 1);
2497 addNode(objects, v);
2498 }
2499 }
2500 for (int i = 0; i < (xmax - 1); i++) {
2501 for (int j = 0; j < (ymax - 1); j++) {
2502 q1 = j + xmax * i + 1;
2503 q2 = j + 1 + xmax * i + 1;
2504 q3 = j + xmax * (i + 1) + 1;
2505 q4 = j + 1 + xmax * (i + 1) + 1;
2506
2507 addTriangle(objects, q1, q2, q3);
2508 addTriangle(objects, q3, q2, q4);
2509 }
2510 }
2511 }
2512
2513 public void generateScanObject(int obj,
2514 int rows,
2515 int cols) {
2516
2517 int k;
2518 int sw = 0;
2519
2520
2521 float tmpx, tmpz, dx, dy;
2522
2523 //normalize the whole thing
2524 for (int j = 0; j < cols; j++)
2525 for (int i = 1; i < rows; i++) {
2526 k = j * rows + i;
2527 tmpx = object[obj].node[k].v.x;
2528 tmpz = object[obj].node[k].v.z;
2529 if (i == 1)
2530 object[obj].node[k].n =
2531 normalize(
2532 new idx3d_vector(
2533 tmpx,
2534 1,
2535 tmpz));
2536 else if (i == rows - 1)
2537 object[obj].node[k].n =
2538 normalize(
2539 new idx3d_vector(
2540 tmpx,
2541 -1,
2542 tmpz));
2543 else {
2544 dx =
2545 object[obj].node[k - 1].v.x -
2546 object[obj].node[k + 1].v.x;
2547 dy =
2548 object[obj].node[k - 1].v.y -
2549 object[obj].node[k + 1].v.y;
2550 object[obj].node[k].n =
2551 normalize(
2552 new idx3d_vector(
2553 tmpx,
2554 dx / dy,
2555 tmpz));
2556 }
2557 object[obj].node[k].tx =
2558 (float) (j) /
2559 (float) (cols - 1);
2560 object[obj].node[k].ty =
2561 (float) (i - 1) /
2562 (float) (rows - 1);
2563 }
2564
2565 // Create triangles
2566
2567 for (int col = 0; col < cols; col++) {
2568 for (int row = 1; row < rows; row++) {
2569 //don't add triangles if the x or z of it are 0, thus solving the holes
2570 sw = 0;
2571 k = col * rows + row;
2572 tmpx = object[obj].node[k].v.x;
2573 tmpz = object[obj].node[k].v.z;
2574 if ((tmpx == 0) || (tmpz == 0)) sw =
2575 1;
2576 k = (col + 1) * rows + row;
2577 tmpx = object[obj].node[k].v.x;
2578 tmpz = object[obj].node[k].v.z;
2579 if ((tmpx == 0) || (tmpz == 0)) sw =
2580 1;
2581 k = col * rows + row + 1;
2582 tmpx = object[obj].node[k].v.x;
2583 tmpz = object[obj].node[k].v.z;
2584 if ((tmpx == 0) || (tmpz == 0)) sw =
2585 1;
2586 // sw=0;
2587 if (sw == 0) {
2588 addTriangle(obj,
2589 (rows * col +
2590 row),
2591 (rows *
2592 (col + 1) +
2593 row),
2594 (rows * col +
2595 row +
2596 1));
2597 addTriangle(obj,
2598 (rows * col +
2599 row +
2600 1),
2601 (rows *
2602 (col + 1) +
2603 row),
2604 (rows *
2605 (col + 1) +
2606 row +
2607 1));
2608 }
2609 }
2610 }
2611 }
2612
2613 public void generateScanObject1(int obj,
2614 int rows,
2615 int cols) {
2616 int k;
2617 float tmpx, tmpz, dx, dy;
2618
2619 //normalize the whole thing
2620 for (int j = 0; j < cols; j++)
2621 for (int i = 1; i < rows; i++) {
2622 k = j * rows + i;
2623 tmpx = object[obj].node[k].v.x;
2624 tmpz = object[obj].node[k].v.z;
2625 if (i == 1)
2626 object[obj].node[k].n =
2627 normalize(
2628 new idx3d_vector(
2629 tmpx,
2630 1,
2631 tmpz));
2632 else if (i == rows - 1)
2633 object[obj].node[k].n =
2634 normalize(
2635 new idx3d_vector(
2636 tmpx,
2637 -1,
2638 tmpz));
2639 else {
2640 dx =
2641 object[obj].node[k - 1].v.x -
2642 object[obj].node[k + 1].v.x;
2643 dy =
2644 object[obj].node[k - 1].v.y -
2645 object[obj].node[k + 1].v.y;
2646 object[obj].node[k].n =
2647 normalize(
2648 new idx3d_vector(
2649 tmpx,
2650 dx / dy,
2651 tmpz));
2652 }
2653 object[obj].node[k].tx =
2654 (float) (j) /
2655 (float) (cols - 1);
2656 object[obj].node[k].ty =
2657 (float) (i - 1) /
2658 (float) (rows - 1);
2659 }
2660
2661 // Create triangles
2662
2663 for (int col = 0; col < cols; col++) {
2664 for (int row = 1; row < rows; row++) {
2665 addTriangle(obj,
2666 (rows * col + row),
2667 (rows * (col + 1) +
2668 row),
2669 (rows * col + row +
2670 1));
2671 addTriangle(obj,
2672 (rows * col + row +
2673 1),
2674 (rows * (col + 1) +
2675 row),
2676 (rows * (col + 1) +
2677 row +
2678 1));
2679 }
2680 }
2681 }
2682
2683 public void generateRotationObject(int obj,
2684 int steps) {
2685 double alpha = 2 * pi / ((double) steps);
2686
2687 int start = 1;
2688 int end = object[obj].nodes + 1;
2689 int t_nodes = object[obj].nodes;
2690
2691 //Adjust normals of existing points
2692 object[obj].node[1].n =
2693 normalize(
2694 new idx3d_vector(
2695 object[obj].node[1].v.x,
2696 (float) 1,
2697 object[obj].node[1].v.z));
2698 object[obj].node[t_nodes].n =
2699 normalize(
2700 new idx3d_vector(
2701 object[obj].node[t_nodes].v.x,
2702 (float) -1,
2703 object[obj].node[t_nodes].v.z));
2704 for (int i = 2; i < t_nodes; i++) {
2705 object[obj].node[i].n =
2706 normalize(
2707 new idx3d_vector(
2708 object[obj].node[i].v.x,
2709 (object[obj].node[i -
2710 1].v.x -
2711 object[obj].node[i +
2712 1].v.x) /
2713 (object[obj].node[i -
2714 1].v.y -
2715 object[obj].node[i +
2716 1].v.y),
2717 object[obj].node[i].v.z));
2718 object[obj].node[i].tx = 0;
2719 object[obj].node[i].ty =
2720 (float) (i - 1) /
2721 (float) (t_nodes - 1);
2722 }
2723
2724 //Create new nodes
2725
2726 for (int j = 1; j < (steps + 1); j++) {
2727 for (int i = start; i < end; i++) {
2728 float qx = (float) (object[obj].node[i].v.x *
2729 Math.cos(
2730 j *
2731 alpha) +
2732 object[obj].node[i].v.z *
2733 Math.sin(
2734 j *
2735 alpha));
2736 float qz = (float) (object[obj].node[i].v.z *
2737 Math.cos(
2738 j *
2739 alpha) -
2740 object[obj].node[i].v.x *
2741 Math.sin(
2742 j *
2743 alpha));
2744 idx3d_node w = new idx3d_node(qx,
2745 object[obj].node[i].v.y,
2746 qz);
2747 if (i == start)
2748 w.n =
2749 normalize(
2750 new idx3d_vector(qx,
2751 1,
2752 qz));
2753 else if (i == end - 1)
2754 w.n =
2755 normalize(
2756 new idx3d_vector(qx,
2757 -1,
2758 qz));
2759 else
2760 w.n =
2761 normalize(
2762 new idx3d_vector(qx,
2763 (object[obj].node[i -
2764 1].v.x -
2765 object[obj].node[i +
2766 1].v.x) /
2767 (object[obj].node[i -
2768 1].v.y -
2769 object[obj].node[i +
2770 1].v.y),
2771 qz));
2772 w.ty = (float) (i - 1) /
2773 (float) (t_nodes - 1);
2774 w.tx = (float) (j - 1) /
2775 (float) (steps - 1);
2776 addNode(obj, w);
2777 }
2778 }
2779
2780 // Create triangles
2781 for (int col = 0; col < steps; col++) {
2782 for (int row = 1; row < t_nodes; row++) {
2783 addTriangle(obj,
2784 (t_nodes * col + row),
2785 (t_nodes * (col + 1) +
2786 row),
2787 (t_nodes * col + row +
2788 1));
2789 addTriangle(obj,
2790 (t_nodes * col + row +
2791 1),
2792 (t_nodes * (col + 1) +
2793 row),
2794 (t_nodes * (col + 1) +
2795 row +
2796 1));
2797 }
2798 }
2799 }
2800
2801 // BEMCHMARK
2802
2803 public String getFPS(int frames) {
2804 long idx_time1;
2805 long idx_time2;
2806 double fps;
2807
2808
2809 idx_time1 = new Date().getTime();
2810
2811 for (int i = 0; i < frames; i++) {
2812 rotateWorld((float) Math.random(),
2813 (float) Math.random(),
2814 (float) Math.random());
2815 renderScene();
2816 }
2817
2818 idx_time2 = new Date().getTime();
2819
2820 fps =
2821 (double) frames /
2822 ((double) (idx_time2 - idx_time1) / 1000);
2823 fps = (double) ((int) (fps * 100)) / 100;
2824 return new String(
2825 "Benchmark: " + fps + " FPS");
2826 }
2827 }
2828
2829
2830 class idx3d_matrix {
2831 float matrix[][] = new float[4][4];
2832
2833 public idx3d_matrix() {
2834 matrix[0][0] = (float) 1;
2835 matrix[1][1] = (float) 1;
2836 matrix[2][2] = (float) 1;
2837 matrix[3][3] = (float) 1;
2838 }
2839 }
2840
2841 class idx3d_object {
2842 int mode = 1;
2843 int color;
2844
2845 idx3d_triangle triangle[];
2846 idx3d_node node[];
2847
2848 int triangles = 0;
2849 int maxtriangles = 0;
2850 int nodes = 0;
2851 int maxnodes = 0;
2852 int texture;
2853 idx3d_matrix matrix = new idx3d_matrix();
2854 idx3d_matrix matrix2 = new idx3d_matrix();
2855
2856 public idx3d_object(int rm, int col) {
2857 mode = rm;
2858 color = col;
2859 }
2860 }
2861
2862 class idx3d_node {
2863 idx3d_vector v = new idx3d_vector();
2864 idx3d_vector n = new idx3d_vector();
2865 idx3d_vector n2 = new idx3d_vector();
2866 int xx; //Coordinates of the
2867 int yy; // screen projection
2868 int zz; //distance for z-buffer
2869 float tx; // Horizontal texture position (0..1+)
2870 float ty; // Vertical texture position (0..1+)
2871
2872 public idx3d_node(float x, float y, float z) {
2873 v.x = x;
2874 v.y = y;
2875 v.z = z;
2876 n.x = (float) 0;
2877 n.y = (float) 0;
2878 n.z = (float) 1;
2879 }
2880 }
2881
2882 class idx3d_triangle {
2883 int p1;
2884 int p2;
2885 int p3;
2886 idx3d_vector n = new idx3d_vector();
2887
2888 public idx3d_triangle(int q1,
2889 int q2,
2890 int q3) {
2891 p1 = q1;
2892 p2 = q2;
2893 p3 = q3;
2894 }
2895 }
2896
2897 class idx3d_light {
2898 int x;
2899 int y;
2900 int z;
2901 int mode = 0; //0=parallel light, 1=point light
2902 int intensity = 255;
2903
2904 public idx3d_light(idx3d_vector lvect,
2905 int lmode,
2906 int lintensity) {
2907 x = (int) (lvect.x * 255);
2908 y = (int) (lvect.y * 255);
2909 z = (int) (lvect.z * 255);
2910 mode = lmode;
2911 intensity = lintensity;
2912 }
2913 }
2914
2915 class idx3d_texture {
2916 int w;
2917 int h;
2918 int pixel[][];
2919 }
2920