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