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