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 quad into the zbuffer
26 int			i,j;
27 const int	*bounds		=	grid->bounds;
28 const float	*vertices	=	grid->vertices;
29 const	int	xres		=	sampleWidth - 1;
30 const	int	yres		=	sampleHeight - 1;
31 const	int	udiv		=	grid->udiv;
32 const	int	vdiv		=	grid->vdiv;
33 const	int	flags		=	grid->flags;
34 
35 
36 
37 // Iterate over every quad
38 for (j=0;j<vdiv;j++) {
39 	for (i=0;i<udiv;i++,bounds+=4,vertices+=numVertexSamples) {
40 
41 		// Trivial rejects
42 		if (bounds[1] < left)		continue;
43 		if (bounds[3] < top)		continue;
44 		if (bounds[0] >= right)		continue;
45 		if (bounds[2] >= bottom)	continue;
46 
47 		// Extract the quad corners
48 		const float	*v0	=	vertices;
49 		const float	*v1	=	vertices + numVertexSamples;
50 		const float	*v2	=	v1 + udiv*numVertexSamples;
51 		const float	*v3	=	v2 + numVertexSamples;
52 
53 		int	xmin	=	bounds[0] - left;	// Convert the bound into the current bucket
54 		int	ymin	=	bounds[2] - top;
55 		int	xmax	=	bounds[1] - left;
56 		int	ymax	=	bounds[3] - top;
57 
58 		xmin		=	max(xmin,0);		// Clamp the bound in the current bucket
59 		ymin		=	max(ymin,0);
60 		xmax		=	min(xmax,xres);
61 		ymax		=	min(ymax,yres);
62 
63 
64 		// This macro is used to check whether the sample is inside the quad or not
65 #define	checkPixel(__op)																						\
66 		float			aleft,atop,aright,abottom;																\
67 																												\
68 		if ((atop		= area(xcent,ycent,v0[COMP_X],v0[COMP_Y],v1[COMP_X],v1[COMP_Y])) __op 0)	continue;	\
69 		if ((aright		= area(xcent,ycent,v1[COMP_X],v1[COMP_Y],v3[COMP_X],v3[COMP_Y])) __op 0)	continue;	\
70 		if ((abottom	= area(xcent,ycent,v3[COMP_X],v3[COMP_Y],v2[COMP_X],v2[COMP_Y])) __op 0)	continue;	\
71 		if ((aleft		= area(xcent,ycent,v2[COMP_X],v2[COMP_Y],v0[COMP_X],v0[COMP_Y])) __op 0)	continue;	\
72 																												\
73 		const float u	=	aleft / (aleft + aright);															\
74 		const float v	=	atop / (atop + abottom);															\
75 		const float	z	=	(v0[COMP_Z]*(1-u) + v1[COMP_Z]*u)*(1-v) + (v2[COMP_Z]*(1-u) + v3[COMP_Z]*u)*v;
76 
77 
78 #define	recordPixel()														\
79 		float	*sample		=	&fb[y][x*SAMPLES_PER_PIXEL];				\
80 		if (z < sample[0] || (flags & RASTER_SHADE_HIDDEN)) {				\
81 			if (z > CRenderer::clipMin) {							\
82 				if (flags & RASTER_UNSHADED) {								\
83 					shadeGrid(grid,FALSE);									\
84 					rasterDrawPrimitives(grid);								\
85 					return;													\
86 				}															\
87 																			\
88 				sample[0]	=	z;											\
89 				if (flags & RASTER_MATTE ) {								\
90 					initv(sample,0);										\
91 				} else {													\
92 					sample[1]	=	(v0[3]*(1-u) + v1[3]*u)*(1-v) + (v2[3]*(1-u) + v3[3]*u)*v;		\
93 					sample[2]	=	(v0[4]*(1-u) + v1[4]*u)*(1-v) + (v2[4]*(1-u) + v3[4]*u)*v;		\
94 					sample[3]	=	(v0[5]*(1-u) + v1[5]*u)*(1-v) + (v2[5]*(1-u) + v3[5]*u)*v;		\
95 				}															\
96 																			\
97 				COcclusionNode	*cNode	=	getNode(x,y);					\
98 																			\
99 				touchNode(cNode,z);											\
100 			}																\
101 		}
102 
103 
104 
105 		float a	= area(v0[COMP_X],v0[COMP_Y],v1[COMP_X],v1[COMP_Y],v2[COMP_X],v2[COMP_Y]);
106 		if (fabsf(a) < C_EPSILON)  a = area(v1[COMP_X],v1[COMP_Y],v3[COMP_X],v3[COMP_Y],v2[COMP_X],v2[COMP_Y]);
107 		if (a > 0) {
108 
109 			if (flags & (RASTER_DRAW_BACK | RASTER_SHADE_BACKFACE)) {
110 
111 				float	xcent,ycent;
112 				int		x,y;
113 				for (		ycent=top+	ymin+0.5001011f,y=ymin;y<=ymax;y++,ycent++) {
114 					for (	xcent=left+	xmin+0.5001011f,x=xmin;x<=xmax;x++,xcent++) {
115 
116 						checkPixel(<);
117 
118 						recordPixel();
119 
120 					}
121 				}
122 			}
123 		} else {
124 			if (flags & (RASTER_DRAW_FRONT | RASTER_SHADE_BACKFACE)) {
125 
126 				float	xcent,ycent;
127 				int		x,y;
128 				for (		ycent=top+	ymin+0.5001011f,y=ymin;y<=ymax;y++,ycent++) {
129 					for (	xcent=left+	xmin+0.5001011f,x=xmin;x<=xmax;x++,xcent++) {
130 
131 						checkPixel(>);
132 
133 						recordPixel();
134 					}
135 				}
136 			}
137 		}
138 
139 
140 	}
141 
142 	vertices	+=	numVertexSamples;
143 }
144 
145