1 //////////////////////////////////////////////////////////////////////
2 //
3 //                             Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 //	This library is free software; you can redistribute it and/or
10 //	modify it under the terms of the GNU Lesser General Public
11 //	License as published by the Free Software Foundation; either
12 //	version 2.1 of the License, or (at your option) any later version.
13 //
14 //	This library is distributed in the hope that it will be useful,
15 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //	Lesser General Public License for more details.
18 //
19 //	You should have received a copy of the GNU Lesser General Public
20 //	License along with this library; if not, write to the Free Software
21 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 
25 // This is the portion of Pixie that draws a point into the stochastic
26 
27 
28 int			i;
29 const int	*bounds		=	grid->bounds;
30 const float	*vertices	=	grid->vertices;
31 const float	*sizes		=	grid->sizes;
32 const	int	xres		=	sampleWidth - 1;
33 const	int	yres		=	sampleHeight - 1;
34 
35 
36 ///////////////////////////////////////////////////////////////////////////////////////////
37 //
38 //   Here're some macros that make the rasterization job easier for us
39 //
40 ///////////////////////////////////////////////////////////////////////////////////////////
41 
42 // Shade _very_ early if we know we are guaranteed to have to anyway
43 // Points are always facing the screen, so there's no point checking if
44 // they're visible before deciding to shade if RASTER_SHADE_HIDDEN is true
45 
46 #ifdef STOCHASTIC_UNSHADED
47 #ifdef STOCHASTIC_UNDERCULL
48 	if (grid->flags & RASTER_SHADE_HIDDEN) {
49 		shadeGrid(grid,FALSE);
50 		rasterDrawPrimitives(grid);
51 		return;
52 	}
53 #endif
54 #endif
55 
56 
57 #ifdef STOCHASTIC_EXTRA_SAMPLES
58 #define	displacement	(10 + CRenderer::numExtraSamples)
59 #else
60 #define	displacement	10
61 #endif
62 
63 
64 
65 ///////////////////////////////////////////////////////////////////////////////////////////
66 //  This macro checks the pixel LOD against the object LOD level
67 #ifdef STOCHASTIC_LOD
68 	const float importance = grid->object->attributes->lodImportance;
69 
70 	#define lodCheck()																			\
71 		if (importance >= 0) {																	\
72 			if (pixel->jimp > importance)		continue;										\
73 		} else {																				\
74 			if ((1-pixel->jimp) >= -importance)	continue;										\
75 		}
76 #else
77 	#define lodCheck()
78 #endif
79 
80 
81 
82 
83 //////////////////////////////////////////////////////////////////////////////////////////
84 // The following macro is used to draw extra samples for each pixels if any
85 #ifdef STOCHASTIC_EXTRA_SAMPLES
86 
87 #ifdef STOCHASTIC_MOVING
88 #define	drawExtraSamples()	{														\
89 	int				currentSample;													\
90 	const	float	*s0	=	v0+10;													\
91 	float			*dest;															\
92 																					\
93 	for (dest=nSample->extraSamples,currentSample=CRenderer::numExtraSamples;currentSample>0;currentSample--,s0++) {		\
94 		*dest++		=	(s0[0]*(1-jt)+s0[displacement]*jt);							\
95 	}																				\
96 }
97 
98 #else
99 #define	drawExtraSamples()	{														\
100 	int				currentSample;													\
101 	const	float	*s0	=	v0+10;													\
102 	float			*dest;															\
103 																					\
104 	for (dest=nSample->extraSamples,currentSample=CRenderer::numExtraSamples;currentSample>0;currentSample--,s0++) {		\
105 		*dest++		=	s0[currentSample];											\
106 	}																				\
107 }
108 #endif
109 
110 #else
111 #define	drawExtraSamples()
112 #endif
113 
114 
115 
116 
117 
118 //////////////////////////////////////////////////////////////////////////////////////////
119 // This big ass macro is for computing the final color/opacity of a pixel
120 #ifndef STOCHASTIC_TRANSPARENT
121 // Non transparent
122 	#ifndef STOCHASTIC_MOVING
123 		// Non Moving
124 		#ifndef STOCHASTIC_MATTE
125 			// Non Matte
126 			#define colorOpacityUpdate()													\
127 				movvv(nSample->color,v0 + 3);												\
128 				initv(nSample->opacity,1);
129 		#else
130 			// Matte
131 			#define colorOpacityUpdate()													\
132 				initv(nSample->color,0);													\
133 				initv(nSample->opacity,-1);													\
134 				initv(pixel->first.opacity,-1);
135 		#endif
136 	#else
137 		// Moving
138 		#ifndef STOCHASTIC_MATTE
139 			// Non Matte
140 			#define colorOpacityUpdate()													\
141 				interpolatev(nSample->color,v0+3,v0+3+displacement,jt);						\
142 				initv(nSample->opacity,1);
143 		#else
144 			// Matte
145 			#define colorOpacityUpdate()													\
146 				initv(nSample->color,0);													\
147 				initv(nSample->color,-1);													\
148 				initv(pixel->first.opacity,-1);
149 		#endif
150 	#endif
151 #else
152 	// Transparent
153 	#ifndef STOCHASTIC_MOVING
154 		// Non Moving
155 		#ifndef STOCHASTIC_MATTE
156 			// Non Matte
157 			#define colorOpacityUpdate()													\
158 				movvv(nSample->color,v0+3);													\
159 				movvv(nSample->opacity,v0+6);
160 		#else
161 			// Matte
162 			#define colorOpacityUpdate()													\
163 				initv(nSample->color,0);													\
164 				initv(nSample->opacity,0);													\
165 				subvv(nSample->opacity,v0+6);												\
166 				movvv(pixel->first.opacity,nSample->opacity);
167 		#endif
168 	#else
169 		// Moving
170 		#ifndef STOCHASTIC_MATTE
171 			// Non Matte
172 			#define colorOpacityUpdate()													\
173 				interpolatev(nSample->color,v0+3,v0+3+displacement,jt);						\
174 				interpolatev(nSample->opacity,v0+6,v0+6+displacement,jt);
175 		#else
176 			// Matte
177 			#define colorOpacityUpdate()													\
178 				initv(nSample->color,0);													\
179 				interpolatev(nSample->opacity,v0+6,v0+6+displacement,jt);					\
180 				nSample->opacity[0] = -nSample->opacity[0];									\
181 				nSample->opacity[1] = -nSample->opacity[1];									\
182 				nSample->opacity[2] = -nSample->opacity[2];									\
183 				movvv(pixel->first.opacity,nSample->opacity);
184 		#endif
185 	#endif
186 #endif
187 
188 #ifndef STOCHASTIC_TRANSPARENT
189 //    Non Transparent
190 #ifndef STOCHASTIC_MOVING
191 //	  Non Moving
192 #define	drawPixel() 																\
193 	if (z < pixel->z) {																\
194 		updateOpaque();																\
195 		nSample							=	&pixel->last;							\
196 		nSample->z						=	z;										\
197 		colorOpacityUpdate();														\
198 		drawExtraSamples();															\
199 		depthFilterIf();															\
200 		pixel->z						=	z;										\
201 		depthFilterTouchNode();														\
202 	} depthFilterElse();
203 
204 
205 #else
206 //	  Moving
207 #define	drawPixel() 																\
208 	if (z < pixel->z) {																\
209 		updateOpaque();																\
210 		nSample							=	&pixel->last;							\
211 		nSample->z						=	z;										\
212 		colorOpacityUpdate();														\
213 		drawExtraSamples();															\
214 		depthFilterIf();															\
215 		pixel->z						=	z;										\
216 		depthFilterTouchNode();														\
217 	} depthFilterElse();
218 
219 #endif
220 
221 
222 #else
223 //    Transparent
224 #ifndef STOCHASTIC_MOVING
225 //	  Non Moving
226 #define	drawPixel() 																\
227 	if (z < pixel->z) {																\
228 		findSample(nSample,z);														\
229 		nSample->z						=	z;										\
230 		colorOpacityUpdate();														\
231 		drawExtraSamples();															\
232 		updateTransparent(depthFilterIf,depthFilterElse);							\
233 	}
234 
235 
236 #else
237 //	  Moving
238 #define	drawPixel() 																\
239 	if (z < pixel->z) {																\
240 		findSample(nSample,z);														\
241 		nSample->z						=	z;										\
242 		colorOpacityUpdate();														\
243 		drawExtraSamples();															\
244 		updateTransparent(depthFilterIf,depthFilterElse);							\
245 	}
246 
247 #endif
248 
249 
250 #endif
251 
252 
253 //////////////////////////////////////////////////////////////////////////////////////////
254 // These macros decide whether we should draw a guad or not
255 #ifdef STOCHASTIC_UNSHADED
256 // We're not shaded yet, so if we pass the depth test, we need to back and shade the grid
257 // Note: we dealt with RASTER_SHADE_HIDDEN very early, no need to do so here
258 #define drawPixelCheck()															\
259 	if (z < pixel->z) {																\
260 		shadeGrid(grid,FALSE);														\
261 		rasterDrawPrimitives(grid);													\
262 		return;																		\
263 	} depthFilterElse();
264 #else
265 #define drawPixelCheck()															\
266 	CFragment *nSample;																\
267 	drawPixel();
268 #endif
269 
270 
271 ///////////////////////////////////////////////////////////////////////////////////////////
272 //
273 //   Here's the code that actually iterates over the quads and draws them
274 //
275 ///////////////////////////////////////////////////////////////////////////////////////////
276 
277 // Iterate over every quad
278 for (i=grid->numVertices;i>0;i--,vertices+=numVertexSamples,bounds+=4,sizes+=2) {
279 
280 	// Trivial rejects
281 	if (bounds[1] < left)		continue;
282 	if (bounds[3] < top)		continue;
283 	if (bounds[0] >= right)		continue;
284 	if (bounds[2] >= bottom)	continue;
285 
286 	int	xmin	=	bounds[0] - left;	// Convert the bound into the current bucket
287 	int	ymin	=	bounds[2] - top;
288 	int	xmax	=	bounds[1] - left;
289 	int	ymax	=	bounds[3] - top;
290 
291 	xmin		=	max(xmin,0);		// Clamp the bound in the current bucket
292 	ymin		=	max(ymin,0);
293 	xmax		=	min(xmax,xres);
294 	ymax		=	min(ymax,yres);
295 
296 	const float	*v0	=	vertices;
297 	int			x,y;
298 	for (y=ymin;y<=ymax;y++) {
299 		for (x=xmin;x<=xmax;x++) {
300 			CPixel			*pixel	=	fb[y]+x;
301 
302 			lodCheck();
303 
304 			const float		xcent	=	pixel->xcent;
305 			const float		ycent	=	pixel->ycent;
306 
307 
308 #ifdef STOCHASTIC_MOVING
309 			const	float	jt		=	pixel->jt;
310 			vector	v0movTmp;
311 			interpolatev(v0movTmp,v0,(v0+displacement),jt);
312 			v0						=	v0movTmp;
313 			const	float	size	=	sizes[0]*(1-jt) + sizes[1]*jt;
314 #else
315 			const	float	size	=	sizes[0];
316 #endif
317 
318 #ifdef STOCHASTIC_FOCAL_BLUR
319 			vector	v0focTmp;
320 			v0focTmp[COMP_X]		=	v0[COMP_X] + pixel->jdx*vertices[9];
321 			v0focTmp[COMP_Y]		=	v0[COMP_Y] + pixel->jdy*vertices[9];
322 			v0focTmp[COMP_Z]		=	v0[COMP_Z];
323 			v0						=	v0focTmp;
324 #endif
325 
326 			const	float	dx		=	xcent - v0[0];
327 			const	float	dy		=	ycent - v0[1];
328 
329 			v0	=	vertices;
330 
331 			if ((dx*dx + dy*dy) < (size*size)) {
332 				const	float	z	=	v0[2];
333 
334 				drawPixelCheck();
335 			}
336 		}
337 	}
338 }
339 
340 
341 
342 #undef	lodCheck
343 #undef	drawPixelCheck
344 #undef	drawPixel
345 #undef	drawExtraSamples
346 #undef	displacement
347 #undef	colorOpacityUpdate
348 
349