OSDN Git Service

Remove unnecessary assert.h includes.
[android-x86/external-swiftshader.git] / src / Renderer / Clipper.cpp
1 // SwiftShader Software Renderer
2 //
3 // Copyright(c) 2005-2012 TransGaming Inc.
4 //
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,
6 // transcribed, stored in a retrieval system, translated into any human or computer
7 // language by any means, or disclosed to third parties without the explicit written
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9 // or implied, including but not limited to any patent rights, are granted to you.
10 //
11
12 #include "Clipper.hpp"
13
14 #include "Polygon.hpp"
15 #include "Renderer.hpp"
16 #include "Debug.hpp"
17
18 #include <malloc.h>
19
20 namespace sw
21 {
22         Clipper::Clipper()
23         {
24         }
25
26         Clipper::~Clipper()
27         {
28         }
29
30         bool Clipper::clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw)
31         {
32                 DrawData &data = *draw.data;
33
34                 polygon.b = 0;
35
36                 if(clipFlagsOr & 0x0000003F)
37                 {
38                         if(clipFlagsOr & CLIP_NEAR)   clipNear(polygon);
39                         if(polygon.n >= 3) {
40                         if(clipFlagsOr & CLIP_FAR)    clipFar(polygon);
41                         if(polygon.n >= 3) {
42                         if(clipFlagsOr & CLIP_LEFT)   clipLeft(polygon, data);
43                         if(polygon.n >= 3) {
44                         if(clipFlagsOr & CLIP_RIGHT)  clipRight(polygon, data);
45                         if(polygon.n >= 3) {
46                         if(clipFlagsOr & CLIP_TOP)    clipTop(polygon, data);
47                         if(polygon.n >= 3) {
48                         if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon, data);
49                         }}}}}
50                 }
51
52                 if(clipFlagsOr & 0x00003F00)
53                 {
54                         if(polygon.n >= 3) {
55                         if(draw.clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]);
56                         if(polygon.n >= 3) {
57                         if(draw.clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]);
58                         if(polygon.n >= 3) {
59                         if(draw.clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]);
60                         if(polygon.n >= 3) {
61                         if(draw.clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]);
62                         if(polygon.n >= 3) {
63                         if(draw.clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]);
64                         if(polygon.n >= 3) {
65                         if(draw.clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]);
66                         }}}}}}
67                 }
68
69                 return polygon.n >= 3;
70         }
71
72         void Clipper::clipNear(Polygon &polygon)
73         {
74                 if(polygon.n == 0) return;
75
76                 const float4 **V = polygon.P[polygon.i];
77                 const float4 **T = polygon.P[polygon.i + 1];
78
79                 int t = 0;
80
81                 for(int i = 0; i < polygon.n; i++)
82                 {
83                         int j = i == polygon.n - 1 ? 0 : i + 1;
84
85                         float di = V[i]->z;
86                         float dj = V[j]->z;
87
88                         if(di >= 0)
89                         {
90                                 T[t++] = V[i];
91
92                                 if(dj < 0)
93                                 {
94                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
95                                         polygon.B[polygon.b].z = 0;
96                                         T[t++] = &polygon.B[polygon.b++];
97                                 }
98                         }
99                         else
100                         {
101                                 if(dj > 0)
102                                 {
103                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
104                                         polygon.B[polygon.b].z = 0;
105                                         T[t++] = &polygon.B[polygon.b++];
106                                 }
107                         }
108                 }
109
110                 polygon.n = t;
111                 polygon.i += 1;
112         }
113
114         void Clipper::clipFar(Polygon &polygon)
115         {
116                 if(polygon.n == 0) return;
117
118                 const float4 **V = polygon.P[polygon.i];
119                 const float4 **T = polygon.P[polygon.i + 1];
120
121                 int t = 0;
122
123                 for(int i = 0; i < polygon.n; i++)
124                 {
125                         int j = i == polygon.n - 1 ? 0 : i + 1;
126
127                         float di = V[i]->w - V[i]->z;
128                         float dj = V[j]->w - V[j]->z;
129
130                         if(di >= 0)
131                         {
132                                 T[t++] = V[i];
133
134                                 if(dj < 0)
135                                 {
136                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
137                                         polygon.B[polygon.b].z = polygon.B[polygon.b].w;
138                                         T[t++] = &polygon.B[polygon.b++];
139                                 }
140                         }
141                         else
142                         {
143                                 if(dj > 0)
144                                 {
145                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
146                                         polygon.B[polygon.b].z = polygon.B[polygon.b].w;
147                                         T[t++] = &polygon.B[polygon.b++];
148                                 }
149                         }
150                 }
151
152                 polygon.n = t;
153                 polygon.i += 1;
154         }
155
156         void Clipper::clipLeft(Polygon &polygon, const DrawData &data)
157         {
158                 if(polygon.n == 0) return;
159
160                 const float4 **V = polygon.P[polygon.i];
161                 const float4 **T = polygon.P[polygon.i + 1];
162
163                 int t = 0;
164
165                 for(int i = 0; i < polygon.n; i++)
166                 {
167                         int j = i == polygon.n - 1 ? 0 : i + 1;
168
169                         float di = V[i]->w + (V[i]->x + data.halfPixelX[0] * V[i]->w);
170                         float dj = V[j]->w + (V[j]->x + data.halfPixelX[0] * V[j]->w);
171
172                         if(di >= 0)
173                         {
174                                 T[t++] = V[i];
175
176                                 if(dj < 0)
177                                 {
178                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
179                                 //      polygon.B[polygon.b].x = -polygon.B[polygon.b].w;
180                                         T[t++] = &polygon.B[polygon.b++];
181                                 }
182                         }
183                         else
184                         {
185                                 if(dj > 0)
186                                 {
187                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
188                                 //      polygon.B[polygon.b].x = -polygon.B[polygon.b].w;
189                                         T[t++] = &polygon.B[polygon.b++];
190                                 }
191                         }
192                 }
193
194                 polygon.n = t;
195                 polygon.i += 1;
196         }
197
198         void Clipper::clipRight(Polygon &polygon, const DrawData &data)
199         {
200                 if(polygon.n == 0) return;
201
202                 const float4 **V = polygon.P[polygon.i];
203                 const float4 **T = polygon.P[polygon.i + 1];
204
205                 int t = 0;
206
207                 for(int i = 0; i < polygon.n; i++)
208                 {
209                         int j = i == polygon.n - 1 ? 0 : i + 1;
210
211                         float di = V[i]->w - (V[i]->x + data.halfPixelX[0] * V[i]->w);
212                         float dj = V[j]->w - (V[j]->x + data.halfPixelX[0] * V[j]->w);
213
214                         if(di >= 0)
215                         {
216                                 T[t++] = V[i];
217
218                                 if(dj < 0)
219                                 {
220                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
221                                 //      polygon.B[polygon.b].x = polygon.B[polygon.b].w;
222                                         T[t++] = &polygon.B[polygon.b++];
223                                 }
224                         }
225                         else
226                         {
227                                 if(dj > 0)
228                                 {
229                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
230                                 //      polygon.B[polygon.b].x = polygon.B[polygon.b].w;
231                                         T[t++] = &polygon.B[polygon.b++];
232                                 }
233                         }
234                 }
235
236                 polygon.n = t;
237                 polygon.i += 1;
238         }
239
240         void Clipper::clipTop(Polygon &polygon, const DrawData &data)
241         {
242                 if(polygon.n == 0) return;
243
244                 const float4 **V = polygon.P[polygon.i];
245                 const float4 **T = polygon.P[polygon.i + 1];
246
247                 int t = 0;
248
249                 for(int i = 0; i < polygon.n; i++)
250                 {
251                         int j = i == polygon.n - 1 ? 0 : i + 1;
252
253                         float di = V[i]->w - (V[i]->y + data.halfPixelY[0] * V[i]->w);
254                         float dj = V[j]->w - (V[j]->y + data.halfPixelY[0] * V[j]->w);
255
256                         if(di >= 0)
257                         {
258                                 T[t++] = V[i];
259
260                                 if(dj < 0)
261                                 {
262                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
263                                 //      polygon.B[polygon.b].y = polygon.B[polygon.b].w;
264                                         T[t++] = &polygon.B[polygon.b++];
265                                 }
266                         }
267                         else
268                         {
269                                 if(dj > 0)
270                                 {
271                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
272                                 //      polygon.B[polygon.b].y = polygon.B[polygon.b].w;
273                                         T[t++] = &polygon.B[polygon.b++];
274                                 }
275                         }
276                 }
277
278                 polygon.n = t;
279                 polygon.i += 1;
280         }
281
282         void Clipper::clipBottom(Polygon &polygon, const DrawData &data)
283         {
284                 if(polygon.n == 0) return;
285
286                 const float4 **V = polygon.P[polygon.i];
287                 const float4 **T = polygon.P[polygon.i + 1];
288
289                 int t = 0;
290
291                 for(int i = 0; i < polygon.n; i++)
292                 {
293                         int j = i == polygon.n - 1 ? 0 : i + 1;
294
295                         float di = V[i]->w + (V[i]->y + data.halfPixelY[0] * V[i]->w);
296                         float dj = V[j]->w + (V[j]->y + data.halfPixelY[0] * V[j]->w);
297
298                         if(di >= 0)
299                         {
300                                 T[t++] = V[i];
301
302                                 if(dj < 0)
303                                 {
304                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
305                                 //      polygon.B[polygon.b].y = -polygon.B[polygon.b].w;
306                                         T[t++] = &polygon.B[polygon.b++];
307                                 }
308                         }
309                         else
310                         {
311                                 if(dj > 0)
312                                 {
313                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
314                                 //      polygon.B[polygon.b].y = -polygon.B[polygon.b].w;
315                                         T[t++] = &polygon.B[polygon.b++];
316                                 }
317                         }
318                 }
319
320                 polygon.n = t;
321                 polygon.i += 1;
322         }
323
324         void Clipper::clipPlane(Polygon &polygon, const Plane &p)
325         {
326                 if(polygon.n == 0) return;
327
328                 const float4 **V = polygon.P[polygon.i];
329                 const float4 **T = polygon.P[polygon.i + 1];
330
331                 int t = 0;
332
333                 for(int i = 0; i < polygon.n; i++)
334                 {
335                         int j = i == polygon.n - 1 ? 0 : i + 1;
336
337                         float di = p.A * V[i]->x + p.B * V[i]->y + p.C * V[i]->z + p.D * V[i]->w;
338                         float dj = p.A * V[j]->x + p.B * V[j]->y + p.C * V[j]->z + p.D * V[j]->w;
339
340                         if(di >= 0)
341                         {
342                                 T[t++] = V[i];
343
344                                 if(dj < 0)
345                                 {
346                                         clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj);
347                                         T[t++] = &polygon.B[polygon.b++];
348                                 }
349                         }
350                         else
351                         {
352                                 if(dj > 0)
353                                 {
354                                         clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di);
355                                         T[t++] = &polygon.B[polygon.b++];
356                                 }
357                         }
358                 }
359
360                 polygon.n = t;
361                 polygon.i += 1;
362         }
363
364         inline void Clipper::clipEdge(float4 &Vo, const float4 &Vi, const float4 &Vj, float di, float dj) const
365         {
366                 float D = 1.0f / (dj - di);
367
368                 Vo.x = (dj * Vi.x - di * Vj.x) * D;
369                 Vo.y = (dj * Vi.y - di * Vj.y) * D;
370                 Vo.z = (dj * Vi.z - di * Vj.z) * D;
371                 Vo.w = (dj * Vi.w - di * Vj.w) * D;
372         }
373 }