1 package com.insanityengine.ghia.renderer;
2
3 import java.awt.*;
4 import java.awt.image.*;
5
6 import java.util.*;
7
8 import com.insanityengine.ghia.m3.*;
9 import com.insanityengine.ghia.libograf.*;
10 import com.insanityengine.ghia.pixels.*;
11
12 import com.insanityengine.ghia.util.*;
13
14 /***
15 *
16 * <P>
17 * This implementation of RendererInterface uses a zsorted list of polygons to make your
18 * fall in love with it! And you will! Everyone will mock you because this peice of code
19 * holds your fancy! Bwhaahahahahhahaha!
20 * </P>
21 *
22 * <table border="1">
23 * <topic>TestResults</topic>
24 * <TH>TestName</TH>
25 * <TH>Results</TH>
26 * <TH>SnapShot</TH>
27 * <TR valign="top">
28 * <TD>Light</TD>
29 * <TD>1646 fps</TD>
30 * <TD><img src="http://ghia.sourceforge.net/images/old_snaps/ZortPolyRenderer_Light.gif"/></TD>
31 * </TR>
32 * <TR valign="top">
33 * <TD>GeomLoader</TD>
34 * <TD>97510/60.306=1616.9204 * 4725 = 7639948 tps = 76 kts</TD>
35 * <TD><img src="http://ghia.sourceforge.net/images/old_snaps/ZortPolyRenderer_Geom.gif"/></TD>
36 * </TR>
37 * </TABLE>
38 *
39 * @author BrianHammond
40 *
41 * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/renderer/ZortPolyRenderer.java,v 1.8 2005/03/26 23:42:41 brian Exp $
42 *
43 */
44
45 public class ZortPolyRenderer implements RendererInterface, PixelBufferReadInterface {
46
47 /***
48 *
49 * Constructor
50 *
51 */
52 public ZortPolyRenderer() {
53 initColors();
54 }
55
56 /***
57 *
58 * Constructor
59 *
60 * @param width of the display
61 * @param height of the display
62 * @param component to use to create offscreen buffer
63 *
64 */
65 public ZortPolyRenderer( int width, int height, Component component ) {
66 initColors();
67 init( width, height, component );
68 }
69
70 /***
71 *
72 * Initialize this ZortPolyRenderer, call this *after* the component
73 * has been made visible or you will suffer!
74 *
75 * @param width of the display
76 * @param height of the display
77 * @param component to use to create offscreen buffer
78 *
79 */
80 public void init( int width, int height, Component component ) {
81 setObserver( component );
82
83 w = width;
84 h = height;
85
86 frustrum.setSize( width, height );
87
88 image = null;
89 this.component = component;
90 }
91
92 /***
93 *
94 * Render the next scene
95 *
96 * @param gl to use to render
97 *
98 */
99 public void render( LiboGraf gl ) {
100 if ( graphicsReady() ) {
101 invokeDrawers( gl );
102 happyPants( graphics );
103 gl.getGraphics().drawImage( image, 0, 0, observer );
104 }
105 }
106
107 /***
108 *
109 * Get the clear color
110 *
111 * @return the clear color
112 *
113 */
114 public int getClearColor() {
115 return 0;
116 }
117
118 /***
119 *
120 * Set the clear color
121 *
122 * @return color to clear with
123 *
124 */
125 public void setClearColor( int color ) {
126 }
127
128 /***
129 *
130 * Set depth testing policy
131 *
132 * @param testDepth false disables test
133 *
134 */
135 public void setDepthTesting( boolean testDepth ) { }
136
137 /***
138 *
139 * Clear the depth buffer
140 *
141 */
142 public void clearDepthBuffer() {
143 }
144
145 /***
146 *
147 * Clear the pixel/color buffer
148 *
149 */
150 public void clearColorBuffer() {
151 clear();
152 }
153
154 /***
155 *
156 * Set the shading method
157 *
158 * @param method may be listed in M3_Constants
159 *
160 */
161 public void setShadingMethod( int method ) {
162 }
163
164 /***
165 *
166 * Set the texture function
167 *
168 * @param function may be listed in M3_Constants
169 *
170 */
171 public void setTextureFunction( int function ) {
172 }
173
174 /***
175 *
176 * Draw a polygon
177 *
178 * @param count of points
179 * @param ptz the array of Pt3 to draw
180 *
181 */
182 public void drawPolygon( int count, Pt3[] ptz ) {
183
184 if ( graphicsReady() ) {
185 frustrum.toScreen( count, ptz );
186
187 if ( zcurr > 0 && !frustrum.offScreen( count, ptz ) ) {
188 if ( true ) {
189
190 polyz.add( new PrettyPoly( count, ptz, zcurr ) );
191
192 } else {
193 Polygon poly = mkPolygon( count, ptz );
194
195 int c = zToC( zcurr );
196 c = 128 + c / 2;
197 graphics.setColor( new Color( c, c, c ) );
198 graphics.fillPolygon( poly );
199 }
200 }
201
202 }
203 }
204
205 /***
206 *
207 * Set the current normal
208 *
209 * @param point to use as the current normal
210 *
211 */
212 public void setNormal( Pt3 point ) {
213 zcurr = point.z;
214 normal.set( point );
215 }
216
217 /***
218 *
219 * Set the current ImageSkin
220 *
221 * @param imageskin to use
222 *
223 */
224 public void setSkin( ImageSkin skin ) {
225 }
226
227
228
229
230 /***
231 *
232 * Clear the buffer
233 *
234 */
235 public void clear() {
236 if ( graphicsReady() ) {
237 graphics.setColor( Color.black );
238 graphics.fillRect( 0, 0, w, h );
239 }
240 }
241
242 /***
243 *
244 * Set the image observer
245 *
246 * @param observer to use
247 *
248 */
249 public void setObserver( java.awt.image.ImageObserver observer ) {
250 this.observer = observer;
251 }
252
253 /***
254 *
255 * Determines the width of the buffer.
256 *
257 * @return the width of this buffer
258 *
259 */
260 public int getWidth() {
261 return w;
262 }
263
264 /***
265 *
266 * Determines the height of the buffer.
267 *
268 * @return the height of this buffer
269 *
270 */
271 public int getHeight() {
272 return h;
273 }
274
275 /***
276 *
277 * Because this uses a PixelGrabber it may be slow-ish...
278 *
279 * @return array of pixel data
280 *
281 */
282 public int[] getPixels() {
283 ImageSkin skin = new ImageSkin( image, observer );
284 return skin.getPixels();
285 }
286
287
288
289
290 /***
291 *
292 * Some renderers are big babys about when it is ok to mess with their goodies.
293 * Hence this cheesy add/remove Drawer mess
294 *
295 * @param drawer to call per frame
296 *
297 */
298 public void addDrawer( DrawingInterface drawer ) {
299 registry.addDrawer( drawer );
300 }
301
302 /***
303 *
304 * Some renderers are big babys about when it is ok to mess with their goodies.
305 * Hence this cheesy add/remove Drawer mess
306 *
307 * @param drawer to call per frame
308 *
309 */
310 public void removeDrawer( DrawingInterface drawer ) {
311 registry.removeDrawer( drawer );
312 }
313
314 /***
315 *
316 * Invoke any registered DrawingInterfaces
317 *
318 */
319 public void invokeDrawers( LiboGraf gl ) {
320 registry.invokeDrawers( gl );
321 }
322
323
324
325 private int w, h;
326 private Image image = null;
327 private Graphics graphics = null;
328 private ImageObserver observer = null;
329 private Component component = null;
330
331 private DrawerRegistry registry = new DrawerRegistry();
332
333 private Frustrum frustrum = new Frustrum();
334
335 private ArrayList polyz = new ArrayList();
336 private float zcurr = 1;
337 private static Color [] colorz = null;
338
339 private Pt3 normal = new Pt3();
340
341
342
343 private final boolean graphicsReady() {
344 boolean ok = false;
345 if ( null == graphics ) {
346 image = component.createImage( w, h );
347 if ( null == image ) {
348 } else {
349 ok = true;
350 graphics = image.getGraphics();
351 }
352 System.out.println( "" + " image = " + image + " graphics = " + graphics );
353 } else {
354 ok = true;
355 }
356 return ok;
357 }
358
359 private final void happyPants( LiboGraf gl ) {
360 happyPants( gl.getGraphics() );
361 }
362
363 private final void happyPants( Graphics graphics ) {
364 Collections.sort( polyz );
365 int sz = polyz.size();
366 for ( int i = 0 ; i < sz ; ++i ) {
367 ( ( PrettyPoly ) polyz.get( i ) ).draw( graphics );
368 }
369 polyz.clear();
370 }
371
372 private final static int zToC( float z ) {
373 return 0 + ( int ) (
374 255 * (
375 ( ( z + 0.4 ) * ( z + 0.4 ) / 1.96 )
376 )
377 );
378 }
379
380 private final static Color zToColor( int n ) {
381 return colorz[ n ];
382 }
383
384 private final static Color zToColor( float z ) {
385 return zToColor( zToC( z ) );
386 }
387
388 synchronized private final static void initColors() {
389 if ( null == colorz ) {
390 colorz = new Color[ 255 ];
391 for ( int i = 0 ; i < 255 ; ++i ) {
392 colorz[ i ] = new Color( i, i / 2, 255 - i );
393
394
395
396
397
398
399
400 }
401 }
402 }
403
404 private static final Polygon mkPolygon( int count, Pt3[] ptz ) {
405 Polygon poly = new Polygon();
406 addToPolygon( poly, count, ptz );
407 return poly;
408 }
409
410 private static final float addToPolygon( Polygon poly, int count, Pt3[] ptz ) {
411 float zavg = 0;
412 for ( int i = 0 ; i < count ; ++i ) {
413 poly.addPoint( ( int ) ptz[ i ].x, ( int ) ptz[ i ].y );
414 zavg += ptz[ i ].z;
415 }
416 return zavg / count;
417 }
418
419 private class PrettyPoly implements Comparable {
420
421 public PrettyPoly() {
422 }
423
424 public PrettyPoly( int count, Pt3[] ptz ) {
425 init( count, ptz, 1 );
426 }
427
428 public PrettyPoly( int count, Pt3[] ptz, float z ) {
429 init( count, ptz, z );
430 }
431
432 public void init( int count, Pt3[] ptz, float z ) {
433 this.poly = new Polygon();
434 this.zpos = ZortPolyRenderer.addToPolygon( poly, count, ptz );
435 this.z = z;
436
437 x = y = 0;
438 for ( int i = 0 ; i < count ; ++i ) {
439 x += ( int ) ptz[ i ].x;
440 y += ( int ) ptz[ i ].y;
441 }
442 x /= count;
443 y /= count;
444 }
445
446 public void draw( Graphics graphics ) {
447 graphics.setColor( ZortPolyRenderer.zToColor( z ) );
448 graphics.fillPolygon( poly );
449 }
450
451 public int compareTo( Object o ) {
452 return ( int ) ( 100 * zpos - ( ( PrettyPoly ) o ).zpos );
453 }
454
455
456
457 private Polygon poly;
458 private float z = 0;
459 private float zpos;
460
461 int x, y;
462 }
463 };
464
465 /***
466 *
467 * $Log: ZortPolyRenderer.java,v $
468 * Revision 1.8 2005/03/26 23:42:41 brian
469 * fix links
470 *
471 * Revision 1.7 2005/03/19 17:50:02 brian
472 * repackaging
473 *
474 * Revision 1.6 2005/03/12 04:58:47 brian
475 * call the methods set instead of copy
476 *
477 * Revision 1.5 2004/09/16 11:00:20 brian
478 * added expensive getPixels impl... but how to mark it as such programmaticly?
479 *
480 * Revision 1.4 2004/09/11 14:37:21 brian
481 * added RendererConsumer and stuff
482 *
483 * Revision 1.3 2004/09/09 03:07:51 brian
484 * remove cool visual debugging
485 *
486 * Revision 1.2 2004/09/09 03:05:09 brian
487 * better with tuns of wacky debug visuals you'll love
488 *
489 * Revision 1.1 2004/09/09 00:14:56 brian
490 * barely works...
491 *
492 *
493 */