• 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,bool depthClipNegativeOneToOne)32 void clipNear(sw::Polygon &polygon, bool depthClipNegativeOneToOne)
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 		// When depthClipNegativeOneToOne is enabled the near plane is at z=-w, otherwise it is at z=0.
47 		if(depthClipNegativeOneToOne)
48 		{
49 			di += V[i]->w;
50 			dj += V[j]->w;
51 		}
52 
53 		if(di >= 0)
54 		{
55 			T[t++] = V[i];
56 
57 			if(dj < 0)
58 			{
59 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
60 				T[t++] = &polygon.B[polygon.b++];
61 			}
62 		}
63 		else
64 		{
65 			if(dj > 0)
66 			{
67 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
68 				T[t++] = &polygon.B[polygon.b++];
69 			}
70 		}
71 	}
72 
73 	polygon.n = t;
74 	polygon.i += 1;
75 }
76 
clipFar(sw::Polygon & polygon)77 void clipFar(sw::Polygon &polygon)
78 {
79 	const sw::float4 **V = polygon.P[polygon.i];
80 	const sw::float4 **T = polygon.P[polygon.i + 1];
81 
82 	int t = 0;
83 
84 	for(int i = 0; i < polygon.n; i++)
85 	{
86 		int j = i == polygon.n - 1 ? 0 : i + 1;
87 
88 		float di = V[i]->w - V[i]->z;
89 		float dj = V[j]->w - V[j]->z;
90 
91 		if(di >= 0)
92 		{
93 			T[t++] = V[i];
94 
95 			if(dj < 0)
96 			{
97 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
98 				T[t++] = &polygon.B[polygon.b++];
99 			}
100 		}
101 		else
102 		{
103 			if(dj > 0)
104 			{
105 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
106 				T[t++] = &polygon.B[polygon.b++];
107 			}
108 		}
109 	}
110 
111 	polygon.n = t;
112 	polygon.i += 1;
113 }
114 
clipLeft(sw::Polygon & polygon)115 void clipLeft(sw::Polygon &polygon)
116 {
117 	const sw::float4 **V = polygon.P[polygon.i];
118 	const sw::float4 **T = polygon.P[polygon.i + 1];
119 
120 	int t = 0;
121 
122 	for(int i = 0; i < polygon.n; i++)
123 	{
124 		int j = i == polygon.n - 1 ? 0 : i + 1;
125 
126 		float di = V[i]->w + V[i]->x;
127 		float dj = V[j]->w + V[j]->x;
128 
129 		if(di >= 0)
130 		{
131 			T[t++] = V[i];
132 
133 			if(dj < 0)
134 			{
135 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
136 				T[t++] = &polygon.B[polygon.b++];
137 			}
138 		}
139 		else
140 		{
141 			if(dj > 0)
142 			{
143 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
144 				T[t++] = &polygon.B[polygon.b++];
145 			}
146 		}
147 	}
148 
149 	polygon.n = t;
150 	polygon.i += 1;
151 }
152 
clipRight(sw::Polygon & polygon)153 void clipRight(sw::Polygon &polygon)
154 {
155 	const sw::float4 **V = polygon.P[polygon.i];
156 	const sw::float4 **T = polygon.P[polygon.i + 1];
157 
158 	int t = 0;
159 
160 	for(int i = 0; i < polygon.n; i++)
161 	{
162 		int j = i == polygon.n - 1 ? 0 : i + 1;
163 
164 		float di = V[i]->w - V[i]->x;
165 		float dj = V[j]->w - V[j]->x;
166 
167 		if(di >= 0)
168 		{
169 			T[t++] = V[i];
170 
171 			if(dj < 0)
172 			{
173 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
174 				T[t++] = &polygon.B[polygon.b++];
175 			}
176 		}
177 		else
178 		{
179 			if(dj > 0)
180 			{
181 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
182 				T[t++] = &polygon.B[polygon.b++];
183 			}
184 		}
185 	}
186 
187 	polygon.n = t;
188 	polygon.i += 1;
189 }
190 
clipTop(sw::Polygon & polygon)191 void clipTop(sw::Polygon &polygon)
192 {
193 	const sw::float4 **V = polygon.P[polygon.i];
194 	const sw::float4 **T = polygon.P[polygon.i + 1];
195 
196 	int t = 0;
197 
198 	for(int i = 0; i < polygon.n; i++)
199 	{
200 		int j = i == polygon.n - 1 ? 0 : i + 1;
201 
202 		float di = V[i]->w - V[i]->y;
203 		float dj = V[j]->w - V[j]->y;
204 
205 		if(di >= 0)
206 		{
207 			T[t++] = V[i];
208 
209 			if(dj < 0)
210 			{
211 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
212 				T[t++] = &polygon.B[polygon.b++];
213 			}
214 		}
215 		else
216 		{
217 			if(dj > 0)
218 			{
219 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
220 				T[t++] = &polygon.B[polygon.b++];
221 			}
222 		}
223 	}
224 
225 	polygon.n = t;
226 	polygon.i += 1;
227 }
228 
clipBottom(sw::Polygon & polygon)229 void clipBottom(sw::Polygon &polygon)
230 {
231 	const sw::float4 **V = polygon.P[polygon.i];
232 	const sw::float4 **T = polygon.P[polygon.i + 1];
233 
234 	int t = 0;
235 
236 	for(int i = 0; i < polygon.n; i++)
237 	{
238 		int j = i == polygon.n - 1 ? 0 : i + 1;
239 
240 		float di = V[i]->w + V[i]->y;
241 		float dj = V[j]->w + V[j]->y;
242 
243 		if(di >= 0)
244 		{
245 			T[t++] = V[i];
246 
247 			if(dj < 0)
248 			{
249 				clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
250 				T[t++] = &polygon.B[polygon.b++];
251 			}
252 		}
253 		else
254 		{
255 			if(dj > 0)
256 			{
257 				clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
258 				T[t++] = &polygon.B[polygon.b++];
259 			}
260 		}
261 	}
262 
263 	polygon.n = t;
264 	polygon.i += 1;
265 }
266 
267 }  // anonymous namespace
268 
269 namespace sw {
270 
Clip(Polygon & polygon,int clipFlagsOr,const DrawCall & draw)271 bool Clipper::Clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
272 {
273 	if(clipFlagsOr & CLIP_FRUSTUM)
274 	{
275 		if(clipFlagsOr & CLIP_NEAR) clipNear(polygon, draw.depthClipNegativeOneToOne);
276 		if(polygon.n >= 3)
277 		{
278 			if(clipFlagsOr & CLIP_FAR) clipFar(polygon);
279 			if(polygon.n >= 3)
280 			{
281 				if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon);
282 				if(polygon.n >= 3)
283 				{
284 					if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon);
285 					if(polygon.n >= 3)
286 					{
287 						if(clipFlagsOr & CLIP_TOP) clipTop(polygon);
288 						if(polygon.n >= 3)
289 						{
290 							if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon);
291 						}
292 					}
293 				}
294 			}
295 		}
296 	}
297 
298 	return polygon.n >= 3;
299 }
300 
301 }  // namespace sw
302