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