1 package com.insanityengine.ghia.renderer;
2
3 import java.awt.*;
4 import java.awt.image.*;
5 import java.awt.event.*;
6 import java.applet.*;
7
8 import com.insanityengine.ghia.m3.*;
9 import com.insanityengine.ghia.libograf.*;
10 import com.insanityengine.ghia.pixels.*;
11
12 /***
13 *
14 * <P>
15 * This renderer uses the BufferBase for the bulk of it's functionality
16 * but implements the tricky drawPolygon method
17 * </P>
18 *
19 * <P>
20 * It uses two buffers the height of the display and uses a simplistic
21 * line drawing algorithm to update the maximum and mininum x values
22 * for each scanline as well as information about the depth and texture
23 * coordinate at each point. (scanPolyEdge)
24 * </P>
25 *
26 * <P>
27 * Obviously this algorithm only works for concave polygons. If you have
28 * convex polygons, you are a freak. I'm sorry, but it's true.
29 * </P>
30 *
31 * <P>
32 * Once each edge of the polygon have been scanned, each scanline is
33 * rasterized with an embarrasingly bad implementation which uses the
34 * information gathered above, the current skin, shading mode, etc
35 * to raster the scanline with zbuffer lovin'. (rasterPoly)
36 * </P>
37 *
38 * <P>
39 * I'm sure your implementation will be much better, all you need to do is
40 * derive a class from BufferBase and implement the drawPolygon method or
41 * implement RendererInterface.
42 * </P>
43 *
44 * <table border="1">
45 * <topic>TestResults</topic>
46 * <TH>TestName</TH>
47 * <TH>Results</TH>
48 * <TH>SnapShot</TH>
49 * <TR valign="top">
50 * <TD>Light</TD>
51 * <TD>51fps</TD>
52 * <TD><img src="http://ghia.sourceforge.net/images/old_snaps/Memagery_Light.gif"/></TD>
53 * </TR>
54 * <TR valign="top">
55 * <TD>GeomLoader</TD>
56 * <TD>1102/61.640=17.878002 * 4725 = 84475 tps = 84 kts</TD>
57 * <TD><img src="http://ghia.sourceforge.net/images/old_snaps/Memagery_Geom.gif"/></TD>
58 * </TR>
59 * </TABLE>
60 *
61 * @author BrianHammond
62 *
63 * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/renderer/Memagery.java,v 1.9 2005/03/26 23:42:41 brian Exp $
64 *
65 */
66 public class Memagery extends RendererBase {
67
68 /***
69 *
70 * Constructor
71 *
72 */
73 public Memagery() {
74 }
75
76 /***
77 *
78 * Draw a polygon
79 *
80 * @param count of points
81 * @param ptz the array of Pt3 to draw
82 *
83 */
84 public void drawPolygon( int number, Pt3 ptz[] ) {
85
86 if ( normal.z < 0 ) return;
87
88
89 frustrum.toScreen( number, ptz );
90 if ( frustrum.offScreen( number, ptz ) ) return;
91
92 initScantron();
93
94
95 float maxz, minz;
96 maxz = minz = ptz[ number - 1 ].z;
97
98 int i, j;
99 for ( i = 0 ; i < number ; i++ ) {
100 j = i + 1;
101 if ( j >= number ) j = 0;
102
103 scannie.scanPolyEdge( ptz[ i ], ptz[ j ] );
104
105 if ( ptz[ i ].z > maxz ) maxz = ptz[ i ].z;
106 if ( ptz[ i ].z < minz ) minz = ptz[ i ].z;
107 }
108
109
110 rasterPoly( minz, maxz );
111 }
112
113
114
115 /***
116 *
117 * rasterPoly: blech
118 *
119 * @param minz
120 * @param maxz
121 *
122 */
123 private final void rasterPoly( float minz, float maxz ) {
124 int i, j, n;
125 float diffz = maxz - minz;
126
127 if ( 0 == diffz ) diffz = 1;
128
129 int x0, x1, xd;
130 float z, zinc, fz = 1;
131
132
133 int pix = 0xFF00FF00;
134
135 int idx, edx, bidx, pidx;
136
137
138 float tx, ty, txi, tyi;
139 int isx, isy, iidx;
140
141
142 int ix, iy;
143 int img_w = 0, img_h = 0;
144
145 int shadeMask;
146
147 if ( null != skin ) {
148 img_w = skin.getWidth();
149 img_h = skin.getHeight();
150 }
151
152 if ( M3_Constants.NORM_SHADE == shade_method ) fz = 0.1f + 0.9f * normal.z;
153
154 for ( i = 0, bidx = 0 ; i < h ; i++, bidx += w ) {
155 if ( !scannie.hasCandy( i ) ) continue;
156
157 xd = ( int ) scannie.getDistance( i );
158
159
160 z = scannie.getLz( i );
161 zinc = ( scannie.getRz( i ) - scannie.getLz( i ) ) / xd;
162
163
164 tx = ( scannie.getLtx( i )* img_w );
165 ty = ( scannie.getLty( i )* img_h );
166
167 txi = ( scannie.getRtx( i ) * img_w - tx ) / xd;
168 tyi = ( scannie.getRty( i ) * img_h - ty ) / xd;
169
170
171 z = scannie.getLz( i );
172 j = ( int ) scannie.getLx( i );
173
174 idx = bidx + j;
175 edx = idx + xd;
176 for (
177 ;
178 idx <= edx && j < w ;
179 idx++, j++, z += zinc,
180 tx += txi, ty += tyi
181 ) {
182 if ( j < 0 ) continue;
183
184 if ( !zbuffer.set( idx, z ) ) continue;
185
186 if ( null != skin ) {
187 pix = ( int ) skin.getPixelAt( ( int ) ( tx ), ( int ) ( ty ) );
188 }
189
190 switch( shade_method ) {
191
192
193 default:
194 shadeMask = 0xFFFFFFFF;
195 break;
196
197 case M3_Constants.NORM_SHADE:
198 n = ( int ) ( 255 * fz );
199 shadeMask = ( 0xFF << 24 | n << 16 | n << 8 | n );
200 break;
201
202 case M3_Constants.DEPTH_SHADE:
203 if ( 0 == diffz ) fz = 0.1f;
204 else fz = ( z - minz ) / diffz;
205 if ( fz < 0.1 ) fz = 0.1f;
206
207 n = ( int ) ( 255 * fz );
208 shadeMask = ( 0xFF << 24 | n << 16 | n << 8 | n );
209 break;
210
211 case M3_Constants.PHONG_SHADE:
212 if ( 0 == diffz ) fz = 1;
213 else fz = ( z - minz ) / diffz;
214
215 pidx = ( int ) ( 255 * fz );
216
217 if ( pidx < 0 ) pidx = 0;
218 if ( pidx > 255 ) pidx = 255;
219
220 n = ( int ) phongo[ pidx ];
221 shadeMask = ( 0xFF << 24 | n << 16 | n << 8 | n );
222 break;
223 }
224
225
226 pixels[ idx ] = pix & shadeMask;
227 }
228 }
229 }
230
231
232
233 private Scantron scannie;
234 private DrawerRegistry registry = new DrawerRegistry();
235
236 /***
237 *
238 * initScantron
239 *
240 */
241 final private void initScantron() {
242 if ( null == scannie ) {
243 scannie = new Scantron( w, h );
244 }
245 scannie.reset();
246 }
247 };
248
249 /***
250 *
251 * $Log: Memagery.java,v $
252 * Revision 1.9 2005/03/26 23:42:41 brian
253 * fix links
254 *
255 * Revision 1.8 2005/03/25 03:07:54 brian
256 * centralize more cruft
257 *
258 * Revision 1.7 2005/03/25 02:45:25 brian
259 * split up a bit
260 *
261 * Revision 1.6 2005/03/19 17:50:02 brian
262 * repackaging
263 *
264 * Revision 1.5 2005/02/17 03:31:13 brian
265 * good stuff???
266 *
267 * Revision 1.4 2004/09/11 19:40:57 brian
268 * use normal.z to bail early
269 *
270 * Revision 1.3 2004/09/11 14:37:21 brian
271 * added RendererConsumer and stuff
272 *
273 * Revision 1.2 2004/09/05 03:41:31 brian
274 * refactored to have the render method of the renderers invoke the drawingIfz
275 *
276 * Revision 1.1 2004/09/02 13:17:16 brian
277 * the big reorg
278 *
279 * Revision 1.10 2004/09/01 01:52:47 brian
280 * added test results (ok, and images) to javadoc
281 *
282 * Revision 1.9 2004/09/01 01:10:42 brian
283 * fix class level javadoc placement
284 *
285 * Revision 1.8 2004/09/01 00:11:06 brian
286 * author, log and header stuff
287 *
288 *
289 */