diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp | 838 |
1 files changed, 419 insertions, 419 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp index 557bb48..b57b319 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CTRTextureGouraudAdd.cpp | |||
@@ -1,419 +1,419 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "IrrCompileConfig.h" | 5 | #include "IrrCompileConfig.h" |
6 | #include "CTRTextureGouraud.h" | 6 | #include "CTRTextureGouraud.h" |
7 | 7 | ||
8 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ | 8 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ |
9 | 9 | ||
10 | namespace irr | 10 | namespace irr |
11 | { | 11 | { |
12 | namespace video | 12 | namespace video |
13 | { | 13 | { |
14 | 14 | ||
15 | class CTRTextureGouraudAdd : public CTRTextureGouraud | 15 | class CTRTextureGouraudAdd : public CTRTextureGouraud |
16 | { | 16 | { |
17 | public: | 17 | public: |
18 | 18 | ||
19 | //! constructor | 19 | //! constructor |
20 | CTRTextureGouraudAdd(IZBuffer* zbuffer); | 20 | CTRTextureGouraudAdd(IZBuffer* zbuffer); |
21 | 21 | ||
22 | //! draws an indexed triangle list | 22 | //! draws an indexed triangle list |
23 | virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); | 23 | virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); |
24 | 24 | ||
25 | protected: | 25 | protected: |
26 | 26 | ||
27 | }; | 27 | }; |
28 | 28 | ||
29 | //! constructor | 29 | //! constructor |
30 | CTRTextureGouraudAdd::CTRTextureGouraudAdd(IZBuffer* zbuffer) | 30 | CTRTextureGouraudAdd::CTRTextureGouraudAdd(IZBuffer* zbuffer) |
31 | : CTRTextureGouraud(zbuffer) | 31 | : CTRTextureGouraud(zbuffer) |
32 | { | 32 | { |
33 | #ifdef _DEBUG | 33 | #ifdef _DEBUG |
34 | setDebugName("CTRTextureGouraudAdd"); | 34 | setDebugName("CTRTextureGouraudAdd"); |
35 | #endif | 35 | #endif |
36 | } | 36 | } |
37 | 37 | ||
38 | 38 | ||
39 | //! draws an indexed triangle list | 39 | //! draws an indexed triangle list |
40 | void CTRTextureGouraudAdd::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) | 40 | void CTRTextureGouraudAdd::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) |
41 | { | 41 | { |
42 | const S2DVertex *v1, *v2, *v3; | 42 | const S2DVertex *v1, *v2, *v3; |
43 | 43 | ||
44 | u16 color; | 44 | u16 color; |
45 | f32 tmpDiv; // temporary division factor | 45 | f32 tmpDiv; // temporary division factor |
46 | f32 longest; // saves the longest span | 46 | f32 longest; // saves the longest span |
47 | s32 height; // saves height of triangle | 47 | s32 height; // saves height of triangle |
48 | u16* targetSurface; // target pointer where to plot pixels | 48 | u16* targetSurface; // target pointer where to plot pixels |
49 | s32 spanEnd; // saves end of spans | 49 | s32 spanEnd; // saves end of spans |
50 | f32 leftdeltaxf; // amount of pixels to increase on left side of triangle | 50 | f32 leftdeltaxf; // amount of pixels to increase on left side of triangle |
51 | f32 rightdeltaxf; // amount of pixels to increase on right side of triangle | 51 | f32 rightdeltaxf; // amount of pixels to increase on right side of triangle |
52 | s32 leftx, rightx; // position where we are | 52 | s32 leftx, rightx; // position where we are |
53 | f32 leftxf, rightxf; // same as above, but as f32 values | 53 | f32 leftxf, rightxf; // same as above, but as f32 values |
54 | s32 span; // current span | 54 | s32 span; // current span |
55 | u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels | 55 | u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels |
56 | s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values | 56 | s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values |
57 | s32 leftStepR, leftStepG, leftStepB, | 57 | s32 leftStepR, leftStepG, leftStepB, |
58 | rightStepR, rightStepG, rightStepB; // color steps | 58 | rightStepR, rightStepG, rightStepB; // color steps |
59 | s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. | 59 | s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. |
60 | s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values | 60 | s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values |
61 | s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values | 61 | s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values |
62 | s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span | 62 | s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span |
63 | core::rect<s32> TriangleRect; | 63 | core::rect<s32> TriangleRect; |
64 | 64 | ||
65 | s32 leftZValue, rightZValue; | 65 | s32 leftZValue, rightZValue; |
66 | s32 leftZStep, rightZStep; | 66 | s32 leftZStep, rightZStep; |
67 | s32 spanZValue, spanZStep; // ZValues when drawing a span | 67 | s32 spanZValue, spanZStep; // ZValues when drawing a span |
68 | TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; | 68 | TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; |
69 | 69 | ||
70 | lockedSurface = (u16*)RenderTarget->lock(); | 70 | lockedSurface = (u16*)RenderTarget->lock(); |
71 | lockedZBuffer = ZBuffer->lock(); | 71 | lockedZBuffer = ZBuffer->lock(); |
72 | lockedTexture = (u16*)Texture->lock(); | 72 | lockedTexture = (u16*)Texture->lock(); |
73 | 73 | ||
74 | for (s32 i=0; i<triangleCount; ++i) | 74 | for (s32 i=0; i<triangleCount; ++i) |
75 | { | 75 | { |
76 | v1 = &vertices[*indexList]; | 76 | v1 = &vertices[*indexList]; |
77 | ++indexList; | 77 | ++indexList; |
78 | v2 = &vertices[*indexList]; | 78 | v2 = &vertices[*indexList]; |
79 | ++indexList; | 79 | ++indexList; |
80 | v3 = &vertices[*indexList]; | 80 | v3 = &vertices[*indexList]; |
81 | ++indexList; | 81 | ++indexList; |
82 | 82 | ||
83 | // back face culling | 83 | // back face culling |
84 | 84 | ||
85 | if (BackFaceCullingEnabled) | 85 | if (BackFaceCullingEnabled) |
86 | { | 86 | { |
87 | s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - | 87 | s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - |
88 | ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); | 88 | ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); |
89 | 89 | ||
90 | if (z < 0) | 90 | if (z < 0) |
91 | continue; | 91 | continue; |
92 | } | 92 | } |
93 | 93 | ||
94 | //near plane clipping | 94 | //near plane clipping |
95 | 95 | ||
96 | if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) | 96 | if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) |
97 | continue; | 97 | continue; |
98 | 98 | ||
99 | // sort for width for inscreen clipping | 99 | // sort for width for inscreen clipping |
100 | 100 | ||
101 | if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); | 101 | if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); |
102 | if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); | 102 | if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); |
103 | if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); | 103 | if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); |
104 | 104 | ||
105 | if ((v1->Pos.X - v3->Pos.X) == 0) | 105 | if ((v1->Pos.X - v3->Pos.X) == 0) |
106 | continue; | 106 | continue; |
107 | 107 | ||
108 | TriangleRect.UpperLeftCorner.X = v1->Pos.X; | 108 | TriangleRect.UpperLeftCorner.X = v1->Pos.X; |
109 | TriangleRect.LowerRightCorner.X = v3->Pos.X; | 109 | TriangleRect.LowerRightCorner.X = v3->Pos.X; |
110 | 110 | ||
111 | // sort for height for faster drawing. | 111 | // sort for height for faster drawing. |
112 | 112 | ||
113 | if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); | 113 | if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); |
114 | if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); | 114 | if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); |
115 | if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); | 115 | if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); |
116 | 116 | ||
117 | TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; | 117 | TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; |
118 | TriangleRect.LowerRightCorner.Y = v3->Pos.Y; | 118 | TriangleRect.LowerRightCorner.Y = v3->Pos.Y; |
119 | 119 | ||
120 | if (!TriangleRect.isRectCollided(ViewPortRect)) | 120 | if (!TriangleRect.isRectCollided(ViewPortRect)) |
121 | continue; | 121 | continue; |
122 | 122 | ||
123 | // calculate height of triangle | 123 | // calculate height of triangle |
124 | height = v3->Pos.Y - v1->Pos.Y; | 124 | height = v3->Pos.Y - v1->Pos.Y; |
125 | if (!height) | 125 | if (!height) |
126 | continue; | 126 | continue; |
127 | 127 | ||
128 | // calculate longest span | 128 | // calculate longest span |
129 | 129 | ||
130 | longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); | 130 | longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); |
131 | 131 | ||
132 | spanEnd = v2->Pos.Y; | 132 | spanEnd = v2->Pos.Y; |
133 | span = v1->Pos.Y; | 133 | span = v1->Pos.Y; |
134 | leftxf = (f32)v1->Pos.X; | 134 | leftxf = (f32)v1->Pos.X; |
135 | rightxf = (f32)v1->Pos.X; | 135 | rightxf = (f32)v1->Pos.X; |
136 | 136 | ||
137 | leftZValue = v1->ZValue; | 137 | leftZValue = v1->ZValue; |
138 | rightZValue = v1->ZValue; | 138 | rightZValue = v1->ZValue; |
139 | 139 | ||
140 | leftR = rightR = video::getRed(v1->Color)<<8; | 140 | leftR = rightR = video::getRed(v1->Color)<<8; |
141 | leftG = rightG = video::getGreen(v1->Color)<<8; | 141 | leftG = rightG = video::getGreen(v1->Color)<<8; |
142 | leftB = rightB = video::getBlue(v1->Color)<<8; | 142 | leftB = rightB = video::getBlue(v1->Color)<<8; |
143 | leftTx = rightTx = v1->TCoords.X; | 143 | leftTx = rightTx = v1->TCoords.X; |
144 | leftTy = rightTy = v1->TCoords.Y; | 144 | leftTy = rightTy = v1->TCoords.Y; |
145 | 145 | ||
146 | targetSurface = lockedSurface + span * SurfaceWidth; | 146 | targetSurface = lockedSurface + span * SurfaceWidth; |
147 | zTarget = lockedZBuffer + span * SurfaceWidth; | 147 | zTarget = lockedZBuffer + span * SurfaceWidth; |
148 | 148 | ||
149 | if (longest < 0.0f) | 149 | if (longest < 0.0f) |
150 | { | 150 | { |
151 | tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); | 151 | tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); |
152 | rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; | 152 | rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; |
153 | rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); | 153 | rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); |
154 | rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); | 154 | rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); |
155 | rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); | 155 | rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); |
156 | rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); | 156 | rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); |
157 | rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); | 157 | rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); |
158 | rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); | 158 | rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); |
159 | 159 | ||
160 | tmpDiv = 1.0f / (f32)height; | 160 | tmpDiv = 1.0f / (f32)height; |
161 | leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; | 161 | leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; |
162 | leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); | 162 | leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); |
163 | leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); | 163 | leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); |
164 | leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); | 164 | leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); |
165 | leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); | 165 | leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); |
166 | leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); | 166 | leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); |
167 | leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); | 167 | leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); |
168 | } | 168 | } |
169 | else | 169 | else |
170 | { | 170 | { |
171 | tmpDiv = 1.0f / (f32)height; | 171 | tmpDiv = 1.0f / (f32)height; |
172 | rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; | 172 | rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; |
173 | rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); | 173 | rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); |
174 | rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); | 174 | rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); |
175 | rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); | 175 | rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); |
176 | rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); | 176 | rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); |
177 | rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); | 177 | rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); |
178 | rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); | 178 | rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); |
179 | 179 | ||
180 | tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); | 180 | tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); |
181 | leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; | 181 | leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; |
182 | leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); | 182 | leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); |
183 | leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); | 183 | leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); |
184 | leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); | 184 | leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); |
185 | leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); | 185 | leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); |
186 | leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); | 186 | leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); |
187 | leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); | 187 | leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); |
188 | } | 188 | } |
189 | 189 | ||
190 | 190 | ||
191 | // do it twice, once for the first half of the triangle, | 191 | // do it twice, once for the first half of the triangle, |
192 | // end then for the second half. | 192 | // end then for the second half. |
193 | 193 | ||
194 | for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) | 194 | for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) |
195 | { | 195 | { |
196 | if (spanEnd > ViewPortRect.LowerRightCorner.Y) | 196 | if (spanEnd > ViewPortRect.LowerRightCorner.Y) |
197 | spanEnd = ViewPortRect.LowerRightCorner.Y; | 197 | spanEnd = ViewPortRect.LowerRightCorner.Y; |
198 | 198 | ||
199 | // if the span <0, than we can skip these spans, | 199 | // if the span <0, than we can skip these spans, |
200 | // and proceed to the next spans which are really on the screen. | 200 | // and proceed to the next spans which are really on the screen. |
201 | if (span < ViewPortRect.UpperLeftCorner.Y) | 201 | if (span < ViewPortRect.UpperLeftCorner.Y) |
202 | { | 202 | { |
203 | // we'll use leftx as temp variable | 203 | // we'll use leftx as temp variable |
204 | if (spanEnd < ViewPortRect.UpperLeftCorner.Y) | 204 | if (spanEnd < ViewPortRect.UpperLeftCorner.Y) |
205 | { | 205 | { |
206 | leftx = spanEnd - span; | 206 | leftx = spanEnd - span; |
207 | span = spanEnd; | 207 | span = spanEnd; |
208 | } | 208 | } |
209 | else | 209 | else |
210 | { | 210 | { |
211 | leftx = ViewPortRect.UpperLeftCorner.Y - span; | 211 | leftx = ViewPortRect.UpperLeftCorner.Y - span; |
212 | span = ViewPortRect.UpperLeftCorner.Y; | 212 | span = ViewPortRect.UpperLeftCorner.Y; |
213 | } | 213 | } |
214 | 214 | ||
215 | leftxf += leftdeltaxf*leftx; | 215 | leftxf += leftdeltaxf*leftx; |
216 | rightxf += rightdeltaxf*leftx; | 216 | rightxf += rightdeltaxf*leftx; |
217 | targetSurface += SurfaceWidth*leftx; | 217 | targetSurface += SurfaceWidth*leftx; |
218 | zTarget += SurfaceWidth*leftx; | 218 | zTarget += SurfaceWidth*leftx; |
219 | leftZValue += leftZStep*leftx; | 219 | leftZValue += leftZStep*leftx; |
220 | rightZValue += rightZStep*leftx; | 220 | rightZValue += rightZStep*leftx; |
221 | 221 | ||
222 | leftR += leftStepR*leftx; | 222 | leftR += leftStepR*leftx; |
223 | leftG += leftStepG*leftx; | 223 | leftG += leftStepG*leftx; |
224 | leftB += leftStepB*leftx; | 224 | leftB += leftStepB*leftx; |
225 | rightR += rightStepR*leftx; | 225 | rightR += rightStepR*leftx; |
226 | rightG += rightStepG*leftx; | 226 | rightG += rightStepG*leftx; |
227 | rightB += rightStepB*leftx; | 227 | rightB += rightStepB*leftx; |
228 | 228 | ||
229 | leftTx += leftTxStep*leftx; | 229 | leftTx += leftTxStep*leftx; |
230 | leftTy += leftTyStep*leftx; | 230 | leftTy += leftTyStep*leftx; |
231 | rightTx += rightTxStep*leftx; | 231 | rightTx += rightTxStep*leftx; |
232 | rightTy += rightTyStep*leftx; | 232 | rightTy += rightTyStep*leftx; |
233 | } | 233 | } |
234 | 234 | ||
235 | 235 | ||
236 | // the main loop. Go through every span and draw it. | 236 | // the main loop. Go through every span and draw it. |
237 | 237 | ||
238 | while (span < spanEnd) | 238 | while (span < spanEnd) |
239 | { | 239 | { |
240 | leftx = (s32)(leftxf); | 240 | leftx = (s32)(leftxf); |
241 | rightx = (s32)(rightxf + 0.5f); | 241 | rightx = (s32)(rightxf + 0.5f); |
242 | 242 | ||
243 | // perform some clipping | 243 | // perform some clipping |
244 | // thanks to a correction by hybrid | 244 | // thanks to a correction by hybrid |
245 | // calculations delayed to correctly propagate to textures etc. | 245 | // calculations delayed to correctly propagate to textures etc. |
246 | s32 tDiffLeft=0, tDiffRight=0; | 246 | s32 tDiffLeft=0, tDiffRight=0; |
247 | if (leftx<ViewPortRect.UpperLeftCorner.X) | 247 | if (leftx<ViewPortRect.UpperLeftCorner.X) |
248 | tDiffLeft=ViewPortRect.UpperLeftCorner.X-leftx; | 248 | tDiffLeft=ViewPortRect.UpperLeftCorner.X-leftx; |
249 | else | 249 | else |
250 | if (leftx>ViewPortRect.LowerRightCorner.X) | 250 | if (leftx>ViewPortRect.LowerRightCorner.X) |
251 | tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; | 251 | tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; |
252 | 252 | ||
253 | if (rightx<ViewPortRect.UpperLeftCorner.X) | 253 | if (rightx<ViewPortRect.UpperLeftCorner.X) |
254 | tDiffRight=ViewPortRect.UpperLeftCorner.X-rightx; | 254 | tDiffRight=ViewPortRect.UpperLeftCorner.X-rightx; |
255 | else | 255 | else |
256 | if (rightx>ViewPortRect.LowerRightCorner.X) | 256 | if (rightx>ViewPortRect.LowerRightCorner.X) |
257 | tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; | 257 | tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; |
258 | 258 | ||
259 | // draw the span | 259 | // draw the span |
260 | if (rightx + tDiffRight - leftx - tDiffLeft) | 260 | if (rightx + tDiffRight - leftx - tDiffLeft) |
261 | { | 261 | { |
262 | tmpDiv = 1.0f / (f32)(rightx - leftx); | 262 | tmpDiv = 1.0f / (f32)(rightx - leftx); |
263 | spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); | 263 | spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); |
264 | spanZValue = leftZValue+tDiffLeft*spanZStep; | 264 | spanZValue = leftZValue+tDiffLeft*spanZStep; |
265 | 265 | ||
266 | spanStepR = (s32)((rightR - leftR) * tmpDiv); | 266 | spanStepR = (s32)((rightR - leftR) * tmpDiv); |
267 | spanR = leftR+tDiffLeft*spanStepR; | 267 | spanR = leftR+tDiffLeft*spanStepR; |
268 | spanStepG = (s32)((rightG - leftG) * tmpDiv); | 268 | spanStepG = (s32)((rightG - leftG) * tmpDiv); |
269 | spanG = leftG+tDiffLeft*spanStepG; | 269 | spanG = leftG+tDiffLeft*spanStepG; |
270 | spanStepB = (s32)((rightB - leftB) * tmpDiv); | 270 | spanStepB = (s32)((rightB - leftB) * tmpDiv); |
271 | spanB = leftB+tDiffLeft*spanStepB; | 271 | spanB = leftB+tDiffLeft*spanStepB; |
272 | 272 | ||
273 | spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); | 273 | spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); |
274 | spanTx = leftTx + tDiffLeft*spanTxStep; | 274 | spanTx = leftTx + tDiffLeft*spanTxStep; |
275 | spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); | 275 | spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); |
276 | spanTy = leftTy+tDiffLeft*spanTyStep; | 276 | spanTy = leftTy+tDiffLeft*spanTyStep; |
277 | 277 | ||
278 | hSpanBegin = targetSurface + leftx+tDiffLeft; | 278 | hSpanBegin = targetSurface + leftx+tDiffLeft; |
279 | spanZTarget = zTarget + leftx+tDiffLeft; | 279 | spanZTarget = zTarget + leftx+tDiffLeft; |
280 | hSpanEnd = targetSurface + rightx+tDiffRight; | 280 | hSpanEnd = targetSurface + rightx+tDiffRight; |
281 | 281 | ||
282 | while (hSpanBegin < hSpanEnd) | 282 | while (hSpanBegin < hSpanEnd) |
283 | { | 283 | { |
284 | if (spanZValue > *spanZTarget) | 284 | if (spanZValue > *spanZTarget) |
285 | { | 285 | { |
286 | //*spanZTarget = spanZValue; | 286 | //*spanZTarget = spanZValue; |
287 | color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; | 287 | color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; |
288 | 288 | ||
289 | s32 basis = *hSpanBegin; | 289 | s32 basis = *hSpanBegin; |
290 | s32 r = (video::getRed(basis)<<3) + (video::getRed(color)<<3); | 290 | s32 r = (video::getRed(basis)<<3) + (video::getRed(color)<<3); |
291 | if (r > 255) r = 255; | 291 | if (r > 255) r = 255; |
292 | s32 g = (video::getGreen(basis)<<3) + (video::getGreen(color)<<3); | 292 | s32 g = (video::getGreen(basis)<<3) + (video::getGreen(color)<<3); |
293 | if (g > 255) g = 255; | 293 | if (g > 255) g = 255; |
294 | s32 b = (video::getBlue(basis)<<3) + (video::getBlue(color)<<3); | 294 | s32 b = (video::getBlue(basis)<<3) + (video::getBlue(color)<<3); |
295 | if (b > 255) b = 255; | 295 | if (b > 255) b = 255; |
296 | 296 | ||
297 | *hSpanBegin = video::RGB16(r, g, b); | 297 | *hSpanBegin = video::RGB16(r, g, b); |
298 | } | 298 | } |
299 | 299 | ||
300 | spanR += spanStepR; | 300 | spanR += spanStepR; |
301 | spanG += spanStepG; | 301 | spanG += spanStepG; |
302 | spanB += spanStepB; | 302 | spanB += spanStepB; |
303 | 303 | ||
304 | spanTx += spanTxStep; | 304 | spanTx += spanTxStep; |
305 | spanTy += spanTyStep; | 305 | spanTy += spanTyStep; |
306 | 306 | ||
307 | spanZValue += spanZStep; | 307 | spanZValue += spanZStep; |
308 | ++hSpanBegin; | 308 | ++hSpanBegin; |
309 | ++spanZTarget; | 309 | ++spanZTarget; |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | leftxf += leftdeltaxf; | 313 | leftxf += leftdeltaxf; |
314 | rightxf += rightdeltaxf; | 314 | rightxf += rightdeltaxf; |
315 | ++span; | 315 | ++span; |
316 | targetSurface += SurfaceWidth; | 316 | targetSurface += SurfaceWidth; |
317 | zTarget += SurfaceWidth; | 317 | zTarget += SurfaceWidth; |
318 | leftZValue += leftZStep; | 318 | leftZValue += leftZStep; |
319 | rightZValue += rightZStep; | 319 | rightZValue += rightZStep; |
320 | 320 | ||
321 | leftR += leftStepR; | 321 | leftR += leftStepR; |
322 | leftG += leftStepG; | 322 | leftG += leftStepG; |
323 | leftB += leftStepB; | 323 | leftB += leftStepB; |
324 | rightR += rightStepR; | 324 | rightR += rightStepR; |
325 | rightG += rightStepG; | 325 | rightG += rightStepG; |
326 | rightB += rightStepB; | 326 | rightB += rightStepB; |
327 | 327 | ||
328 | leftTx += leftTxStep; | 328 | leftTx += leftTxStep; |
329 | leftTy += leftTyStep; | 329 | leftTy += leftTyStep; |
330 | rightTx += rightTxStep; | 330 | rightTx += rightTxStep; |
331 | rightTy += rightTyStep; | 331 | rightTy += rightTyStep; |
332 | } | 332 | } |
333 | 333 | ||
334 | if (triangleHalf>0) // break, we've gout only two halves | 334 | if (triangleHalf>0) // break, we've gout only two halves |
335 | break; | 335 | break; |
336 | 336 | ||
337 | 337 | ||
338 | // setup variables for second half of the triangle. | 338 | // setup variables for second half of the triangle. |
339 | 339 | ||
340 | if (longest < 0.0f) | 340 | if (longest < 0.0f) |
341 | { | 341 | { |
342 | tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); | 342 | tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); |
343 | 343 | ||
344 | rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; | 344 | rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; |
345 | rightxf = (f32)v2->Pos.X; | 345 | rightxf = (f32)v2->Pos.X; |
346 | 346 | ||
347 | rightZValue = v2->ZValue; | 347 | rightZValue = v2->ZValue; |
348 | rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); | 348 | rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); |
349 | 349 | ||
350 | rightR = video::getRed(v2->Color)<<8; | 350 | rightR = video::getRed(v2->Color)<<8; |
351 | rightG = video::getGreen(v2->Color)<<8; | 351 | rightG = video::getGreen(v2->Color)<<8; |
352 | rightB = video::getBlue(v2->Color)<<8; | 352 | rightB = video::getBlue(v2->Color)<<8; |
353 | rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); | 353 | rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); |
354 | rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); | 354 | rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); |
355 | rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); | 355 | rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); |
356 | 356 | ||
357 | rightTx = v2->TCoords.X; | 357 | rightTx = v2->TCoords.X; |
358 | rightTy = v2->TCoords.Y; | 358 | rightTy = v2->TCoords.Y; |
359 | rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); | 359 | rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); |
360 | rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); | 360 | rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); |
361 | } | 361 | } |
362 | else | 362 | else |
363 | { | 363 | { |
364 | tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); | 364 | tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); |
365 | 365 | ||
366 | leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; | 366 | leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; |
367 | leftxf = (f32)v2->Pos.X; | 367 | leftxf = (f32)v2->Pos.X; |
368 | 368 | ||
369 | leftZValue = v2->ZValue; | 369 | leftZValue = v2->ZValue; |
370 | leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); | 370 | leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); |
371 | 371 | ||
372 | leftR = video::getRed(v2->Color)<<8; | 372 | leftR = video::getRed(v2->Color)<<8; |
373 | leftG = video::getGreen(v2->Color)<<8; | 373 | leftG = video::getGreen(v2->Color)<<8; |
374 | leftB = video::getBlue(v2->Color)<<8; | 374 | leftB = video::getBlue(v2->Color)<<8; |
375 | leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); | 375 | leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); |
376 | leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); | 376 | leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); |
377 | leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); | 377 | leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); |
378 | 378 | ||
379 | leftTx = v2->TCoords.X; | 379 | leftTx = v2->TCoords.X; |
380 | leftTy = v2->TCoords.Y; | 380 | leftTy = v2->TCoords.Y; |
381 | leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); | 381 | leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); |
382 | leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); | 382 | leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); |
383 | } | 383 | } |
384 | 384 | ||
385 | 385 | ||
386 | spanEnd = v3->Pos.Y; | 386 | spanEnd = v3->Pos.Y; |
387 | } | 387 | } |
388 | 388 | ||
389 | } | 389 | } |
390 | 390 | ||
391 | RenderTarget->unlock(); | 391 | RenderTarget->unlock(); |
392 | ZBuffer->unlock(); | 392 | ZBuffer->unlock(); |
393 | Texture->unlock(); | 393 | Texture->unlock(); |
394 | } | 394 | } |
395 | 395 | ||
396 | } // end namespace video | 396 | } // end namespace video |
397 | } // end namespace irr | 397 | } // end namespace irr |
398 | 398 | ||
399 | #endif // _IRR_COMPILE_WITH_SOFTWARE_ | 399 | #endif // _IRR_COMPILE_WITH_SOFTWARE_ |
400 | 400 | ||
401 | namespace irr | 401 | namespace irr |
402 | { | 402 | { |
403 | namespace video | 403 | namespace video |
404 | { | 404 | { |
405 | 405 | ||
406 | ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer) | 406 | ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer) |
407 | { | 407 | { |
408 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ | 408 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ |
409 | return new CTRTextureGouraudAdd(zbuffer); | 409 | return new CTRTextureGouraudAdd(zbuffer); |
410 | #else | 410 | #else |
411 | return 0; | 411 | return 0; |
412 | #endif // _IRR_COMPILE_WITH_SOFTWARE_ | 412 | #endif // _IRR_COMPILE_WITH_SOFTWARE_ |
413 | } | 413 | } |
414 | 414 | ||
415 | } // end namespace video | 415 | } // end namespace video |
416 | } // end namespace irr | 416 | } // end namespace irr |
417 | 417 | ||
418 | 418 | ||
419 | 419 | ||