aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp
new file mode 100644
index 0000000..d15ba04
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp
@@ -0,0 +1,313 @@
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 CTRTextureFlatWire : public CTRTextureGouraud
16{
17public:
18
19 CTRTextureFlatWire(IZBuffer* zbuffer)
20 : CTRTextureGouraud(zbuffer)
21 {
22 #ifdef _DEBUG
23 setDebugName("CTRTextureFlatWire");
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 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
43 s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
44 core::rect<s32> TriangleRect;
45
46 s32 leftZValue, rightZValue;
47 s32 leftZStep, rightZStep;
48 TZBufferType* zTarget; // target of ZBuffer;
49
50 lockedSurface = (u16*)RenderTarget->lock();
51 lockedZBuffer = ZBuffer->lock();
52 lockedTexture = (u16*)Texture->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 leftTx = rightTx = v1->TCoords.X;
121 leftTy = rightTy = v1->TCoords.Y;
122
123 targetSurface = lockedSurface + span * SurfaceWidth;
124 zTarget = lockedZBuffer + span * SurfaceWidth;
125
126 if (longest < 0.0f)
127 {
128 tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
129 rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
130 rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
131 rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
132 rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
133
134 tmpDiv = 1.0f / (f32)height;
135 leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
136 leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
137 leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
138 leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
139 }
140 else
141 {
142 tmpDiv = 1.0f / (f32)height;
143 rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
144 rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
145 rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
146 rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
147
148 tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
149 leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
150 leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
151 leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
152 leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
153 }
154
155
156 // do it twice, once for the first half of the triangle,
157 // end then for the second half.
158
159 for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
160 {
161 if (spanEnd > ViewPortRect.LowerRightCorner.Y)
162 spanEnd = ViewPortRect.LowerRightCorner.Y;
163
164 // if the span <0, than we can skip these spans,
165 // and proceed to the next spans which are really on the screen.
166 if (span < ViewPortRect.UpperLeftCorner.Y)
167 {
168 // we'll use leftx as temp variable
169 if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
170 {
171 leftx = spanEnd - span;
172 span = spanEnd;
173 }
174 else
175 {
176 leftx = ViewPortRect.UpperLeftCorner.Y - span;
177 span = ViewPortRect.UpperLeftCorner.Y;
178 }
179
180 leftxf += leftdeltaxf*leftx;
181 rightxf += rightdeltaxf*leftx;
182 targetSurface += SurfaceWidth*leftx;
183 zTarget += SurfaceWidth*leftx;
184 leftZValue += leftZStep*leftx;
185 rightZValue += rightZStep*leftx;
186
187 leftTx += leftTxStep*leftx;
188 leftTy += leftTyStep*leftx;
189 rightTx += rightTxStep*leftx;
190 rightTy += rightTyStep*leftx;
191 }
192
193
194 // the main loop. Go through every span and draw it.
195
196 while (span < spanEnd)
197 {
198 leftx = (s32)(leftxf);
199 rightx = (s32)(rightxf + 0.5f);
200
201 // perform some clipping
202
203 if (leftx>=ViewPortRect.UpperLeftCorner.X &&
204 leftx<=ViewPortRect.LowerRightCorner.X)
205 {
206 if (leftZValue > *(zTarget + leftx))
207 {
208 *(zTarget + leftx) = leftZValue;
209 *(targetSurface + leftx) = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)];
210 }
211 }
212
213
214 if (rightx>=ViewPortRect.UpperLeftCorner.X &&
215 rightx<=ViewPortRect.LowerRightCorner.X)
216 {
217 if (rightZValue > *(zTarget + rightx))
218 {
219 *(zTarget + rightx) = rightZValue;
220 *(targetSurface + rightx) = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)];
221 }
222
223 }
224
225
226 leftxf += leftdeltaxf;
227 rightxf += rightdeltaxf;
228 ++span;
229 targetSurface += SurfaceWidth;
230 zTarget += SurfaceWidth;
231 leftZValue += leftZStep;
232 rightZValue += rightZStep;
233
234 leftTx += leftTxStep;
235 leftTy += leftTyStep;
236 rightTx += rightTxStep;
237 rightTy += rightTyStep;
238 }
239
240 if (triangleHalf>0) // break, we've gout only two halves
241 break;
242
243
244 // setup variables for second half of the triangle.
245
246 if (longest < 0.0f)
247 {
248 tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
249
250 rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
251 rightxf = (f32)v2->Pos.X;
252
253 rightZValue = v2->ZValue;
254 rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
255
256 rightTx = v2->TCoords.X;
257 rightTy = v2->TCoords.Y;
258 rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
259 rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
260 }
261 else
262 {
263 tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
264
265 leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
266 leftxf = (f32)v2->Pos.X;
267
268 leftZValue = v2->ZValue;
269 leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
270
271 leftTx = v2->TCoords.X;
272 leftTy = v2->TCoords.Y;
273 leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
274 leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
275 }
276
277
278 spanEnd = v3->Pos.Y;
279 }
280
281 }
282
283 RenderTarget->unlock();
284 ZBuffer->unlock();
285 Texture->unlock();
286
287 }
288};
289
290} // end namespace video
291} // end namespace irr
292
293#endif // _IRR_COMPILE_WITH_SOFTWARE_
294
295namespace irr
296{
297namespace video
298{
299
300//! creates a flat triangle renderer
301ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer)
302{
303 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
304 return new CTRTextureFlatWire(zbuffer);
305 #else
306 return 0;
307 #endif // _IRR_COMPILE_WITH_SOFTWARE_
308}
309
310} // end namespace video
311} // end namespace irr
312
313