• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "Clipper.hpp"
16 
17 #include "Polygon.hpp"
18 #include "Renderer.hpp"
19 
20 namespace {
21 
clipEdge(sw::float4 & Vo,const sw::float4 & Vi,const sw::float4 & Vj,float di,float dj)22 inline void clipEdge(sw::float4 &Vo, const sw::float4 &Vi, const sw::float4 &Vj, float di, float dj)
23 {
24 	float D = 1.0f / (dj - di);
25 
26 	Vo.x = (dj * Vi.x - di * Vj.x) * D;
27 	Vo.y = (dj * Vi.y - di * Vj.y) * D;
28 	Vo.z = (dj * Vi.z - di * Vj.z) * D;
29 	Vo.w = (dj * Vi.w - di * Vj.w) * D;
30 }
31 
clipNear(sw::Polygon & polygon)32 void clipNear(sw::Polygon &polygon)
33 {
34 	const sw::float4 **V = polygon.P[polygon.i];
35 	const sw::float4 **T = polygon.P[polygon.i + 1];
36 
37 	int t = 0;
38 
39 	for(int i = 0; i < polygon.n; i++)
40 	{
41 		int j = i == polygon.n - 1 ? 0 : i + 1;
42 
43 		float di = V[i]->z;
44 		float dj = V[j]->z;
45 
46 		if(di >= 0)
47 		{
48 			T[t++] = V[i];
49 
50 			if(dj < 0)
51 			{
52 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
53 				T[t++] = &polygon.B[polygon.b++];
54 			}
55 		}
56 		else
57 		{
58 			if(dj > 0)
59 			{
60 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
61 				T[t++] = &polygon.B[polygon.b++];
62 			}
63 		}
64 	}
65 
66 	polygon.n = t;
67 	polygon.i += 1;
68 }
69 
clipFar(sw::Polygon & polygon)70 void clipFar(sw::Polygon &polygon)
71 {
72 	const sw::float4 **V = polygon.P[polygon.i];
73 	const sw::float4 **T = polygon.P[polygon.i + 1];
74 
75 	int t = 0;
76 
77 	for(int i = 0; i < polygon.n; i++)
78 	{
79 		int j = i == polygon.n - 1 ? 0 : i + 1;
80 
81 		float di = V[i]->w - V[i]->z;
82 		float dj = V[j]->w - V[j]->z;
83 
84 		if(di >= 0)
85 		{
86 			T[t++] = V[i];
87 
88 			if(dj < 0)
89 			{
90 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
91 				T[t++] = &polygon.B[polygon.b++];
92 			}
93 		}
94 		else
95 		{
96 			if(dj > 0)
97 			{
98 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
99 				T[t++] = &polygon.B[polygon.b++];
100 			}
101 		}
102 	}
103 
104 	polygon.n = t;
105 	polygon.i += 1;
106 }
107 
clipLeft(sw::Polygon & polygon)108 void clipLeft(sw::Polygon &polygon)
109 {
110 	const sw::float4 **V = polygon.P[polygon.i];
111 	const sw::float4 **T = polygon.P[polygon.i + 1];
112 
113 	int t = 0;
114 
115 	for(int i = 0; i < polygon.n; i++)
116 	{
117 		int j = i == polygon.n - 1 ? 0 : i + 1;
118 
119 		float di = V[i]->w + V[i]->x;
120 		float dj = V[j]->w + V[j]->x;
121 
122 		if(di >= 0)
123 		{
124 			T[t++] = V[i];
125 
126 			if(dj < 0)
127 			{
128 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
129 				T[t++] = &polygon.B[polygon.b++];
130 			}
131 		}
132 		else
133 		{
134 			if(dj > 0)
135 			{
136 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
137 				T[t++] = &polygon.B[polygon.b++];
138 			}
139 		}
140 	}
141 
142 	polygon.n = t;
143 	polygon.i += 1;
144 }
145 
clipRight(sw::Polygon & polygon)146 void clipRight(sw::Polygon &polygon)
147 {
148 	const sw::float4 **V = polygon.P[polygon.i];
149 	const sw::float4 **T = polygon.P[polygon.i + 1];
150 
151 	int t = 0;
152 
153 	for(int i = 0; i < polygon.n; i++)
154 	{
155 		int j = i == polygon.n - 1 ? 0 : i + 1;
156 
157 		float di = V[i]->w - V[i]->x;
158 		float dj = V[j]->w - V[j]->x;
159 
160 		if(di >= 0)
161 		{
162 			T[t++] = V[i];
163 
164 			if(dj < 0)
165 			{
166 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
167 				T[t++] = &polygon.B[polygon.b++];
168 			}
169 		}
170 		else
171 		{
172 			if(dj > 0)
173 			{
174 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
175 				T[t++] = &polygon.B[polygon.b++];
176 			}
177 		}
178 	}
179 
180 	polygon.n = t;
181 	polygon.i += 1;
182 }
183 
clipTop(sw::Polygon & polygon)184 void clipTop(sw::Polygon &polygon)
185 {
186 	const sw::float4 **V = polygon.P[polygon.i];
187 	const sw::float4 **T = polygon.P[polygon.i + 1];
188 
189 	int t = 0;
190 
191 	for(int i = 0; i < polygon.n; i++)
192 	{
193 		int j = i == polygon.n - 1 ? 0 : i + 1;
194 
195 		float di = V[i]->w - V[i]->y;
196 		float dj = V[j]->w - V[j]->y;
197 
198 		if(di >= 0)
199 		{
200 			T[t++] = V[i];
201 
202 			if(dj < 0)
203 			{
204 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
205 				T[t++] = &polygon.B[polygon.b++];
206 			}
207 		}
208 		else
209 		{
210 			if(dj > 0)
211 			{
212 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
213 				T[t++] = &polygon.B[polygon.b++];
214 			}
215 		}
216 	}
217 
218 	polygon.n = t;
219 	polygon.i += 1;
220 }
221 
clipBottom(sw::Polygon & polygon)222 void clipBottom(sw::Polygon &polygon)
223 {
224 	const sw::float4 **V = polygon.P[polygon.i];
225 	const sw::float4 **T = polygon.P[polygon.i + 1];
226 
227 	int t = 0;
228 
229 	for(int i = 0; i < polygon.n; i++)
230 	{
231 		int j = i == polygon.n - 1 ? 0 : i + 1;
232 
233 		float di = V[i]->w + V[i]->y;
234 		float dj = V[j]->w + V[j]->y;
235 
236 		if(di >= 0)
237 		{
238 			T[t++] = V[i];
239 
240 			if(dj < 0)
241 			{
242 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
243 				T[t++] = &polygon.B[polygon.b++];
244 			}
245 		}
246 		else
247 		{
248 			if(dj > 0)
249 			{
250 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
251 				T[t++] = &polygon.B[polygon.b++];
252 			}
253 		}
254 	}
255 
256 	polygon.n = t;
257 	polygon.i += 1;
258 }
259 
260 }  // anonymous namespace
261 
262 namespace sw {
263 
ComputeClipFlags(const float4 & v,bool depthClipEnable)264 unsigned int Clipper::ComputeClipFlags(const float4 &v, bool depthClipEnable)
265 {
266 	int depthClipFlags = ((v.z > v.w) ? CLIP_FAR : 0) |
267 	                     ((v.z < 0) ? CLIP_NEAR : 0);
268 	return ((v.x > v.w) ? CLIP_RIGHT : 0) |
269 	       ((v.y > v.w) ? CLIP_TOP : 0) |
270 	       ((v.x < -v.w) ? CLIP_LEFT : 0) |
271 	       ((v.y < -v.w) ? CLIP_BOTTOM : 0) |
272 	       (depthClipEnable ? depthClipFlags : 0) |
273 	       Clipper::CLIP_FINITE;  // FIXME: xyz finite
274 }
275 
Clip(Polygon & polygon,int clipFlagsOr,const DrawCall & draw)276 bool Clipper::Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
277 {
278 	if(clipFlagsOr & CLIP_FRUSTUM)
279 	{
280 		if(clipFlagsOr & CLIP_NEAR) clipNear(polygon);
281 		if(polygon.n >= 3)
282 		{
283 			if(clipFlagsOr & CLIP_FAR) clipFar(polygon);
284 			if(polygon.n >= 3)
285 			{
286 				if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon);
287 				if(polygon.n >= 3)
288 				{
289 					if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon);
290 					if(polygon.n >= 3)
291 					{
292 						if(clipFlagsOr & CLIP_TOP) clipTop(polygon);
293 						if(polygon.n >= 3)
294 						{
295 							if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon);
296 						}
297 					}
298 				}
299 			}
300 		}
301 	}
302 
303 	return polygon.n >= 3;
304 }
305 
306 }  // namespace sw
307