1 package com.insanityengine.ghia.renderer.Edjo;
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.renderer.*;
9 import com.insanityengine.ghia.m3.*;
10 import com.insanityengine.ghia.libograf.*;
11 import com.insanityengine.ghia.pixels.*;
12
13 /***
14 *
15 * <P>
16 * This renderer uses the BufferBase for the bulk of it's functionality
17 * but implements the tricky drawPolygon method
18 * </P>
19 *
20 *
21 * @author BrianHammond
22 *
23 * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/renderer/Edjo/Edjo.java,v 1.7 2005/03/26 04:59:18 brian Exp $
24 *
25 */
26 public class Edjo extends RendererBase {
27
28 /***
29 *
30 * Constructor
31 *
32 */
33 public Edjo() {
34 }
35
36 /***
37 *
38 * Draw a polygon
39 *
40 * @param count of points
41 * @param ptz the array of Pt3 to draw
42 *
43 */
44 public void drawPolygon( int number, Pt3 ptz[] ) {
45 if ( onScreen( number, ptz ) ) {
46 setupEdges( number, ptz );
47 scanEdges();
48 }
49 }
50
51
52
53 private int edgeCount;
54 private Edge edges[] = null;
55
56 private Hit minHit = new Hit();
57 private Hit maxHit = new Hit();
58 private Hit tmpHit = new Hit();
59
60 Hit texStart = new Hit();
61 Hit texStop = new Hit();
62
63 private int shadeMask;
64
65 /***
66 *
67 * onScreen
68 *
69 * @param number
70 * @param ptz
71 *
72 * @return a boolean
73 *
74 */
75 private final boolean onScreen( int number, Pt3 ptz[] ) {
76 if ( normal.z < 0 ) return false;
77 frustrum.toScreen( number, ptz );
78 if ( frustrum.offScreen( number, ptz ) ) return false;
79 return true;
80 }
81
82 /***
83 *
84 * setupEdges
85 *
86 * @param number
87 * @param ptz
88 *
89 */
90 private final void setupEdges( int number, Pt3 ptz[] ) {
91 if ( null == edges ) {
92 edges = new Edge[ ptz.length ];
93 for ( int i = 0 ; i < edges.length ; i++ ) {
94 edges[ i ] = new Edge();
95 }
96 }
97
98 edgeCount = 0;
99 for ( int i = 0, next ; i < number ; i++ ) {
100
101 next = i + 1;
102 if ( next >= number ) {
103 next = 0;
104 }
105 edges[ edgeCount++ ].set( ptz[ i ], ptz[ next ] );
106 }
107
108
109 int n = ( int ) ( 255 * normal.z );
110 shadeMask = ( 0xFF << 24 | n << 16 | n << 8 | n );
111 }
112
113 /***
114 *
115 * scanEdges
116 *
117 */
118 private final void scanEdges() {
119
120 int y = ( int ) findMin();
121 int maxY = ( int ) ( findMax() );
122
123 if ( 0 == y && 0 == maxY ) return;
124
125 if ( ++maxY >= h ) maxY = h - 1;
126
127 for ( ; y < maxY ; y++ ) {
128 if ( 0 <= y && findHits( y ) ) {
129 scanLine( y );
130 }
131 }
132 }
133
134 /***
135 *
136 * findMin
137 *
138 * @return a float
139 *
140 */
141 private final float findMin() {
142 float min = edges[ 0 ].getMin();
143 for ( int i = 1 ; i < edgeCount ; i++ ) {
144 if ( edges[ i ].getMin() < min ) {
145 min = edges[ i ].getMin();
146 }
147 }
148 return min;
149 }
150
151 /***
152 *
153 * findMax
154 *
155 * @return a float
156 *
157 */
158 private final float findMax() {
159 float max = edges[ 0 ].getMax();
160 for ( int i = 1 ; i < edgeCount ; i++ ) {
161 if ( edges[ i ].getMax() > max ) {
162 max = edges[ i ].getMax();
163 }
164 }
165 return max;
166 }
167
168 /***
169 *
170 * findHits
171 *
172 * @return a boolean
173 *
174 */
175 public final boolean findHits( int y ) {
176 boolean found = false;
177 for ( int i = 0 ; i < edgeCount ; i++ ) {
178 if ( edges[ i ].hit( y, tmpHit ) ) {
179 if ( !found ) {
180 found = true;
181 maxHit.copy( tmpHit );
182 minHit.copy( tmpHit );
183 } else {
184 if ( tmpHit.min < minHit.min ) minHit.copy( tmpHit );
185 if ( tmpHit.max > minHit.max ) maxHit.copy( tmpHit );
186 }
187 }
188
189 }
190 return found;
191 }
192
193 /***
194 *
195 * scanLine
196 *
197 * @param y
198 *
199 */
200 private final void scanLine( int y ) {
201 if ( skin == null ) {
202 simpleScanLine( y );
203 } else {
204 textureScanLine( y );
205 }
206 }
207
208 /***
209 *
210 * simpleScanLine
211 *
212 * @param y
213 *
214 */
215 private void simpleScanLine( int y ) {
216
217
218 int min = ( int ) minHit.min;
219 int max = ( int ) maxHit.max;
220
221 int len = max - min;
222
223
224 float zstart = minHit.what.zAt( minHit.when );
225 float zstop = maxHit.what.zAt( maxHit.when );
226 float zstep = ( zstop - zstart ) / len;
227
228
229
230 if ( min < 0 ) {
231 zstart += zstep * -min;
232 min = 0;
233 }
234
235
236 if ( max >= w ) max = w - 1;
237
238
239 int idx = y * w + min;
240 max = idx + max - min;
241
242 for ( ; idx < max ; idx++, zstart += zstep ) {
243 if ( zbuffer.set( idx, zstart ) ) {
244 pixels[ idx ] = 0xFF0000FF & shadeMask;
245 }
246 }
247 }
248
249 /***
250 *
251 * textureScanLine
252 *
253 * @param y
254 *
255 */
256 private final void textureScanLine( int y ) {
257
258
259 int min = ( int ) minHit.min;
260 int max = ( int ) maxHit.max;
261
262 int len = max - min;
263
264
265 float zstart = minHit.what.zAt( minHit.when );
266 float zstop = maxHit.what.zAt( maxHit.when );
267 float zstep = ( zstop - zstart ) / len;
268
269
270 minHit.tex( texStart );
271 maxHit.tex( texStop );
272
273
274 float sStep = ( texStop.min - texStart.min ) / len;
275 float tStep = ( texStop.max - texStart.max ) / len;
276
277
278
279 if ( min < 0 ) {
280 texStart.min += sStep * -min;
281 texStart.max += tStep * -min;
282 zstart += zstep * -min;
283 min = 0;
284 }
285
286
287 if ( max >= w ) max = w - 1;
288
289
290 int idx = y * w + min;
291 max = idx + max - min;
292
293
294
295
296
297
298
299
300 for (
301 ;
302 idx < max
303 ;
304 idx++,
305 zstart += zstep,
306
307 texStart.min += sStep, texStart.max += tStep
308 ) {
309 if ( zbuffer.set( idx, zstart ) ) {
310
311
312
313
314
315
316
317
318
319
320 pixels[ idx ] = skin.getPixelAtCoord( texStart.min, texStart.max ) & shadeMask;
321 }
322 }
323 }
324
325 };
326
327 /***
328 *
329 * $Log: Edjo.java,v $
330 * Revision 1.7 2005/03/26 04:59:18 brian
331 * got too fancy with textures in this spot...
332 *
333 * Revision 1.6 2005/03/26 03:46:55 brian
334 * break it up a bit
335 *
336 * Revision 1.5 2005/03/26 03:35:45 brian
337 * texturing strongly broken...
338 *
339 * Revision 1.4 2005/03/25 13:42:41 brian
340 * actually works
341 *
342 * Revision 1.3 2005/03/25 13:37:55 brian
343 * significantly less broken
344 *
345 * Revision 1.2 2005/03/25 04:13:20 brian
346 * still does not work
347 *
348 * Revision 1.1 2005/03/25 04:02:19 brian
349 * does not work
350 *
351 *
352 */