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