~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/CTRTextureFlatWire.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 CTRTextureFlatWire : public CTRTextureGouraud
 
16
{
 
17
public:
 
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
 
 
295
namespace irr
 
296
{
 
297
namespace video
 
298
{
 
299
 
 
300
//! creates a flat triangle renderer
 
301
ITriangleRenderer* 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