aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp
new file mode 100644
index 0000000..216e1a1
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp
@@ -0,0 +1,300 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "IrrCompileConfig.h"
6#include "CTRTextureGouraud.h"
7
8#ifdef _IRR_COMPILE_WITH_SOFTWARE_
9
10namespace irr
11{
12namespace video
13{
14
15class CTRFlat : public CTRTextureGouraud
16{
17public:
18
19 CTRFlat(IZBuffer* zbuffer)
20 : CTRTextureGouraud(zbuffer)
21 {
22 #ifdef _DEBUG
23 setDebugName("CTRFlat");
24 #endif
25 }
26
27 //! draws an indexed triangle list
28 virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
29 {
30 const S2DVertex *v1, *v2, *v3;
31
32 u16 color;
33 f32 tmpDiv; // temporary division factor
34 f32 longest; // saves the longest span
35 s32 height; // saves height of triangle
36 u16* targetSurface; // target pointer where to plot pixels
37 s32 spanEnd; // saves end of spans
38 f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
39 f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
40 s32 leftx, rightx; // position where we are
41 f32 leftxf, rightxf; // same as above, but as f32 values
42 s32 span; // current span
43 u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
44 core::rect<s32> TriangleRect;
45
46 s32 leftZValue, rightZValue;
47 s32 leftZStep, rightZStep;
48 s32 spanZValue, spanZStep; // ZValues when drawing a span
49 TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
50
51 lockedSurface = (u16*)RenderTarget->lock();
52 lockedZBuffer = ZBuffer->lock();
53
54 for (s32 i=0; i<triangleCount; ++i)
55 {
56 v1 = &vertices[*indexList];
57 ++indexList;
58 v2 = &vertices[*indexList];
59 ++indexList;
60 v3 = &vertices[*indexList];
61 ++indexList;
62
63 // back face culling
64
65 if (BackFaceCullingEnabled)
66 {
67 s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
68 ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
69
70 if (z < 0)
71 continue;
72 }
73
74 //near plane clipping
75
76 if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
77 continue;
78
79 // sort for width for inscreen clipping
80
81 if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
82 if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
83 if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
84
85 if ((v1->Pos.X - v3->Pos.X) == 0)
86 continue;
87
88 TriangleRect.UpperLeftCorner.X = v1->Pos.X;
89 TriangleRect.LowerRightCorner.X = v3->Pos.X;
90
91 // sort for height for faster drawing.
92
93 if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
94 if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
95 if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
96
97 TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
98 TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
99
100 if (!TriangleRect.isRectCollided(ViewPortRect))
101 continue;
102
103 // calculate height of triangle
104 height = v3->Pos.Y - v1->Pos.Y;
105 if (!height)
106 continue;
107
108 // calculate longest span
109
110 longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
111
112 spanEnd = v2->Pos.Y;
113 span = v1->Pos.Y;
114 leftxf = (f32)v1->Pos.X;
115 rightxf = (f32)v1->Pos.X;
116
117 leftZValue = v1->ZValue;
118 rightZValue = v1->ZValue;
119
120 color = v1->Color;
121
122 targetSurface = lockedSurface + span * SurfaceWidth;
123 zTarget = lockedZBuffer + span * SurfaceWidth;
124
125 if (longest < 0.0f)
126 {
127 tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
128 rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
129 rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
130
131 tmpDiv = 1.0f / (f32)height;
132 leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
133 leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
134 }
135 else
136 {
137 tmpDiv = 1.0f / (f32)height;
138 rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
139 rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
140
141 tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
142 leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
143 leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
144 }
145
146
147 // do it twice, once for the first half of the triangle,
148 // end then for the second half.
149
150 for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
151 {
152 if (spanEnd > ViewPortRect.LowerRightCorner.Y)
153 spanEnd = ViewPortRect.LowerRightCorner.Y;
154
155 // if the span <0, than we can skip these spans,
156 // and proceed to the next spans which are really on the screen.
157 if (span < ViewPortRect.UpperLeftCorner.Y)
158 {
159 // we'll use leftx as temp variable
160 if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
161 {
162 leftx = spanEnd - span;
163 span = spanEnd;
164 }
165 else
166 {
167 leftx = ViewPortRect.UpperLeftCorner.Y - span;
168 span = ViewPortRect.UpperLeftCorner.Y;
169 }
170
171 leftxf += leftdeltaxf*leftx;
172 rightxf += rightdeltaxf*leftx;
173 targetSurface += SurfaceWidth*leftx;
174 zTarget += SurfaceWidth*leftx;
175 leftZValue += leftZStep*leftx;
176 rightZValue += rightZStep*leftx;
177 }
178
179
180 // the main loop. Go through every span and draw it.
181
182 while (span < spanEnd)
183 {
184 leftx = (s32)(leftxf);
185 rightx = (s32)(rightxf + 0.5f);
186
187 // perform some clipping
188
189 // TODO: clipping is not correct when leftx is clipped.
190
191 if (leftx<ViewPortRect.UpperLeftCorner.X)
192 leftx = ViewPortRect.UpperLeftCorner.X;
193 else
194 if (leftx>ViewPortRect.LowerRightCorner.X)
195 leftx = ViewPortRect.LowerRightCorner.X;
196
197 if (rightx<ViewPortRect.UpperLeftCorner.X)
198 rightx = ViewPortRect.UpperLeftCorner.X;
199 else
200 if (rightx>ViewPortRect.LowerRightCorner.X)
201 rightx = ViewPortRect.LowerRightCorner.X;
202
203 // draw the span
204
205 if (rightx - leftx != 0)
206 {
207 tmpDiv = 1.0f / (rightx - leftx);
208 spanZValue = leftZValue;
209 spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
210
211 hSpanBegin = targetSurface + leftx;
212 spanZTarget = zTarget + leftx;
213 hSpanEnd = targetSurface + rightx;
214
215 while (hSpanBegin < hSpanEnd)
216 {
217 if (spanZValue > *spanZTarget)
218 {
219 *spanZTarget = spanZValue;
220 *hSpanBegin = color;
221 }
222
223 spanZValue += spanZStep;
224 ++hSpanBegin;
225 ++spanZTarget;
226 }
227 }
228
229 leftxf += leftdeltaxf;
230 rightxf += rightdeltaxf;
231 ++span;
232 targetSurface += SurfaceWidth;
233 zTarget += SurfaceWidth;
234 leftZValue += leftZStep;
235 rightZValue += rightZStep;
236 }
237
238 if (triangleHalf>0) // break, we've gout only two halves
239 break;
240
241
242 // setup variables for second half of the triangle.
243
244 if (longest < 0.0f)
245 {
246 tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
247
248 rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
249 rightxf = (f32)v2->Pos.X;
250
251 rightZValue = v2->ZValue;
252 rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
253 }
254 else
255 {
256 tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
257
258 leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
259 leftxf = (f32)v2->Pos.X;
260
261 leftZValue = v2->ZValue;
262 leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
263 }
264
265
266 spanEnd = v3->Pos.Y;
267 }
268
269 }
270
271 RenderTarget->unlock();
272 ZBuffer->unlock();
273 }
274};
275
276} // end namespace video
277} // end namespace irr
278
279#endif // _IRR_COMPILE_WITH_SOFTWARE_
280
281namespace irr
282{
283namespace video
284{
285
286//! creates a flat triangle renderer
287ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer)
288{
289 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
290 return new CTRFlat(zbuffer);
291 #else
292 return 0;
293 #endif // _IRR_COMPILE_WITH_SOFTWARE_
294}
295
296} // end namespace video
297} // end namespace irr
298
299
300