~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/CTRTextureGouraudWire.cpp

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2002-2011 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
 
 
10
namespace irr
 
11
{
 
12
namespace video
 
13
{
 
14
 
 
15
class CTRTextureGouraudWire : public CTRTextureGouraud
 
16
{
 
17
public:
 
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
 
 
347
namespace irr
 
348
{
 
349
namespace video
 
350
{
 
351
 
 
352
//! creates a flat triangle renderer
 
353
ITriangleRenderer* 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