1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "Clipper.hpp"
17 #include "Polygon.hpp"
18 #include "Renderer.hpp"
23 Clipper::Clipper(bool symmetricNormalizedDepth)
25 n = symmetricNormalizedDepth ? -1.0f : 0.0f;
32 unsigned int Clipper::computeClipFlags(const float4 &v)
34 return ((v.x > v.w) ? CLIP_RIGHT : 0) |
35 ((v.y > v.w) ? CLIP_TOP : 0) |
36 ((v.z > v.w) ? CLIP_FAR : 0) |
37 ((v.x < -v.w) ? CLIP_LEFT : 0) |
38 ((v.y < -v.w) ? CLIP_BOTTOM : 0) |
39 ((v.z < n * v.w) ? CLIP_NEAR : 0) |
40 Clipper::CLIP_FINITE; // FIXME: xyz finite
43 bool Clipper::clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
45 if(clipFlagsOr & CLIP_FRUSTUM)
47 if(clipFlagsOr & CLIP_NEAR) clipNear(polygon);
49 if(clipFlagsOr & CLIP_FAR) clipFar(polygon);
51 if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon);
53 if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon);
55 if(clipFlagsOr & CLIP_TOP) clipTop(polygon);
57 if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon);
61 if(clipFlagsOr & CLIP_USER)
63 DrawData &data = *draw.data;
66 if(draw.clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]);
68 if(draw.clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]);
70 if(draw.clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]);
72 if(draw.clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]);
74 if(draw.clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]);
76 if(draw.clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]);
80 return polygon.n >= 3;
83 void Clipper::clipNear(Polygon &polygon)
85 const float4 **V = polygon.P[polygon.i];
86 const float4 **T = polygon.P[polygon.i + 1];
90 for(int i = 0; i < polygon.n; i++)
92 int j = i == polygon.n - 1 ? 0 : i + 1;
94 float di = V[i]->z - n * V[i]->w;
95 float dj = V[j]->z - n * V[j]->w;
103 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
104 T[t++] = &polygon.B[polygon.b++];
111 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
112 T[t++] = &polygon.B[polygon.b++];
121 void Clipper::clipFar(Polygon &polygon)
123 const float4 **V = polygon.P[polygon.i];
124 const float4 **T = polygon.P[polygon.i + 1];
128 for(int i = 0; i < polygon.n; i++)
130 int j = i == polygon.n - 1 ? 0 : i + 1;
132 float di = V[i]->w - V[i]->z;
133 float dj = V[j]->w - V[j]->z;
141 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
142 T[t++] = &polygon.B[polygon.b++];
149 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
150 T[t++] = &polygon.B[polygon.b++];
159 void Clipper::clipLeft(Polygon &polygon)
161 const float4 **V = polygon.P[polygon.i];
162 const float4 **T = polygon.P[polygon.i + 1];
166 for(int i = 0; i < polygon.n; i++)
168 int j = i == polygon.n - 1 ? 0 : i + 1;
170 float di = V[i]->w + V[i]->x;
171 float dj = V[j]->w + V[j]->x;
179 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
180 T[t++] = &polygon.B[polygon.b++];
187 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
188 T[t++] = &polygon.B[polygon.b++];
197 void Clipper::clipRight(Polygon &polygon)
199 const float4 **V = polygon.P[polygon.i];
200 const float4 **T = polygon.P[polygon.i + 1];
204 for(int i = 0; i < polygon.n; i++)
206 int j = i == polygon.n - 1 ? 0 : i + 1;
208 float di = V[i]->w - V[i]->x;
209 float dj = V[j]->w - V[j]->x;
217 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
218 T[t++] = &polygon.B[polygon.b++];
225 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
226 T[t++] = &polygon.B[polygon.b++];
235 void Clipper::clipTop(Polygon &polygon)
237 const float4 **V = polygon.P[polygon.i];
238 const float4 **T = polygon.P[polygon.i + 1];
242 for(int i = 0; i < polygon.n; i++)
244 int j = i == polygon.n - 1 ? 0 : i + 1;
246 float di = V[i]->w - V[i]->y;
247 float dj = V[j]->w - V[j]->y;
255 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
256 T[t++] = &polygon.B[polygon.b++];
263 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
264 T[t++] = &polygon.B[polygon.b++];
273 void Clipper::clipBottom(Polygon &polygon)
275 const float4 **V = polygon.P[polygon.i];
276 const float4 **T = polygon.P[polygon.i + 1];
280 for(int i = 0; i < polygon.n; i++)
282 int j = i == polygon.n - 1 ? 0 : i + 1;
284 float di = V[i]->w + V[i]->y;
285 float dj = V[j]->w + V[j]->y;
293 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
294 T[t++] = &polygon.B[polygon.b++];
301 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
302 T[t++] = &polygon.B[polygon.b++];
311 void Clipper::clipPlane(Polygon &polygon, const Plane &p)
313 const float4 **V = polygon.P[polygon.i];
314 const float4 **T = polygon.P[polygon.i + 1];
318 for(int i = 0; i < polygon.n; i++)
320 int j = i == polygon.n - 1 ? 0 : i + 1;
322 float di = p.A * V[i]->x + p.B * V[i]->y + p.C * V[i]->z + p.D * V[i]->w;
323 float dj = p.A * V[j]->x + p.B * V[j]->y + p.C * V[j]->z + p.D * V[j]->w;
331 clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
332 T[t++] = &polygon.B[polygon.b++];
339 clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
340 T[t++] = &polygon.B[polygon.b++];
349 inline void Clipper::clipEdge(float4 &Vo, const float4 &Vi, const float4 &Vj, float di, float dj) const
351 float D = 1.0f / (dj - di);
353 Vo.x = (dj * Vi.x - di * Vj.x) * D;
354 Vo.y = (dj * Vi.y - di * Vj.y) * D;
355 Vo.z = (dj * Vi.z - di * Vj.z) * D;
356 Vo.w = (dj * Vi.w - di * Vj.w) * D;