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