diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp | 5444 |
1 files changed, 2722 insertions, 2722 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp index bdde929..9f0015f 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver2.cpp | |||
@@ -1,2722 +1,2722 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten |
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 "CSoftwareDriver2.h" | 6 | #include "CSoftwareDriver2.h" |
7 | 7 | ||
8 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ | 8 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ |
9 | 9 | ||
10 | #include "SoftwareDriver2_helper.h" | 10 | #include "SoftwareDriver2_helper.h" |
11 | #include "CSoftwareTexture2.h" | 11 | #include "CSoftwareTexture2.h" |
12 | #include "CSoftware2MaterialRenderer.h" | 12 | #include "CSoftware2MaterialRenderer.h" |
13 | #include "S3DVertex.h" | 13 | #include "S3DVertex.h" |
14 | #include "S4DVertex.h" | 14 | #include "S4DVertex.h" |
15 | #include "CBlit.h" | 15 | #include "CBlit.h" |
16 | 16 | ||
17 | 17 | ||
18 | #define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) ) | 18 | #define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) ) |
19 | 19 | ||
20 | 20 | ||
21 | namespace irr | 21 | namespace irr |
22 | { | 22 | { |
23 | namespace video | 23 | namespace video |
24 | { | 24 | { |
25 | 25 | ||
26 | namespace glsl | 26 | namespace glsl |
27 | { | 27 | { |
28 | 28 | ||
29 | typedef sVec4 vec4; | 29 | typedef sVec4 vec4; |
30 | typedef sVec3 vec3; | 30 | typedef sVec3 vec3; |
31 | typedef sVec2 vec2; | 31 | typedef sVec2 vec2; |
32 | 32 | ||
33 | #define in | 33 | #define in |
34 | #define uniform | 34 | #define uniform |
35 | #define attribute | 35 | #define attribute |
36 | #define varying | 36 | #define varying |
37 | 37 | ||
38 | #ifdef _MSC_VER | 38 | #ifdef _MSC_VER |
39 | #pragma warning(disable:4244) | 39 | #pragma warning(disable:4244) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | struct mat4{ | 42 | struct mat4{ |
43 | float m[4][4]; | 43 | float m[4][4]; |
44 | 44 | ||
45 | vec4 operator* ( const vec4 &in ) const | 45 | vec4 operator* ( const vec4 &in ) const |
46 | { | 46 | { |
47 | vec4 out; | 47 | vec4 out; |
48 | return out; | 48 | return out; |
49 | } | 49 | } |
50 | 50 | ||
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct mat3{ | 53 | struct mat3{ |
54 | float m[3][3]; | 54 | float m[3][3]; |
55 | 55 | ||
56 | vec3 operator* ( const vec3 &in ) const | 56 | vec3 operator* ( const vec3 &in ) const |
57 | { | 57 | { |
58 | vec3 out; | 58 | vec3 out; |
59 | return out; | 59 | return out; |
60 | } | 60 | } |
61 | }; | 61 | }; |
62 | 62 | ||
63 | const int gl_MaxLights = 8; | 63 | const int gl_MaxLights = 8; |
64 | 64 | ||
65 | 65 | ||
66 | inline float dot (float x, float y) { return x * y; } | 66 | inline float dot (float x, float y) { return x * y; } |
67 | inline float dot ( const vec2 &x, const vec2 &y) { return x.x * y.x + x.y * y.y; } | 67 | inline float dot ( const vec2 &x, const vec2 &y) { return x.x * y.x + x.y * y.y; } |
68 | inline float dot ( const vec3 &x, const vec3 &y) { return x.x * y.x + x.y * y.y + x.z * y.z; } | 68 | inline float dot ( const vec3 &x, const vec3 &y) { return x.x * y.x + x.y * y.y + x.z * y.z; } |
69 | inline float dot ( const vec4 &x, const vec4 &y) { return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w; } | 69 | inline float dot ( const vec4 &x, const vec4 &y) { return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w; } |
70 | 70 | ||
71 | inline float reflect (float I, float N) { return I - 2.0 * dot (N, I) * N; } | 71 | inline float reflect (float I, float N) { return I - 2.0 * dot (N, I) * N; } |
72 | inline vec2 reflect (const vec2 &I, const vec2 &N) { return I - N * 2.0 * dot (N, I); } | 72 | inline vec2 reflect (const vec2 &I, const vec2 &N) { return I - N * 2.0 * dot (N, I); } |
73 | inline vec3 reflect (const vec3 &I, const vec3 &N) { return I - N * 2.0 * dot (N, I); } | 73 | inline vec3 reflect (const vec3 &I, const vec3 &N) { return I - N * 2.0 * dot (N, I); } |
74 | inline vec4 reflect (const vec4 &I, const vec4 &N) { return I - N * 2.0 * dot (N, I); } | 74 | inline vec4 reflect (const vec4 &I, const vec4 &N) { return I - N * 2.0 * dot (N, I); } |
75 | 75 | ||
76 | 76 | ||
77 | inline float refract (float I, float N, float eta){ | 77 | inline float refract (float I, float N, float eta){ |
78 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); | 78 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); |
79 | if (k < 0.0) | 79 | if (k < 0.0) |
80 | return 0.0; | 80 | return 0.0; |
81 | return eta * I - (eta * dot (N, I) + sqrt (k)) * N; | 81 | return eta * I - (eta * dot (N, I) + sqrt (k)) * N; |
82 | } | 82 | } |
83 | 83 | ||
84 | inline vec2 refract (const vec2 &I, const vec2 &N, float eta){ | 84 | inline vec2 refract (const vec2 &I, const vec2 &N, float eta){ |
85 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); | 85 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); |
86 | if (k < 0.0) | 86 | if (k < 0.0) |
87 | return vec2 (0.0); | 87 | return vec2 (0.0); |
88 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); | 88 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); |
89 | } | 89 | } |
90 | 90 | ||
91 | inline vec3 refract (const vec3 &I, const vec3 &N, float eta) { | 91 | inline vec3 refract (const vec3 &I, const vec3 &N, float eta) { |
92 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); | 92 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); |
93 | if (k < 0.0) | 93 | if (k < 0.0) |
94 | return vec3 (0.0); | 94 | return vec3 (0.0); |
95 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); | 95 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); |
96 | } | 96 | } |
97 | 97 | ||
98 | inline vec4 refract (const vec4 &I, const vec4 &N, float eta) { | 98 | inline vec4 refract (const vec4 &I, const vec4 &N, float eta) { |
99 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); | 99 | const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); |
100 | if (k < 0.0) | 100 | if (k < 0.0) |
101 | return vec4 (0.0); | 101 | return vec4 (0.0); |
102 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); | 102 | return I * eta - N * (eta * dot (N, I) + sqrt (k)); |
103 | } | 103 | } |
104 | 104 | ||
105 | 105 | ||
106 | inline float length ( const vec3 &v ) { return sqrtf ( v.x * v.x + v.y * v.y + v.z * v.z ); } | 106 | inline float length ( const vec3 &v ) { return sqrtf ( v.x * v.x + v.y * v.y + v.z * v.z ); } |
107 | vec3 normalize ( const vec3 &v ) { float l = 1.f / length ( v ); return vec3 ( v.x * l, v.y * l, v.z * l ); } | 107 | vec3 normalize ( const vec3 &v ) { float l = 1.f / length ( v ); return vec3 ( v.x * l, v.y * l, v.z * l ); } |
108 | float max ( float a, float b ) { return a > b ? a : b; } | 108 | float max ( float a, float b ) { return a > b ? a : b; } |
109 | float min ( float a, float b ) { return a < b ? a : b; } | 109 | float min ( float a, float b ) { return a < b ? a : b; } |
110 | vec4 clamp ( const vec4 &a, f32 low, f32 high ) { return vec4 ( min (max(a.x,low), high), min (max(a.y,low), high), min (max(a.z,low), high), min (max(a.w,low), high) ); } | 110 | vec4 clamp ( const vec4 &a, f32 low, f32 high ) { return vec4 ( min (max(a.x,low), high), min (max(a.y,low), high), min (max(a.z,low), high), min (max(a.w,low), high) ); } |
111 | 111 | ||
112 | 112 | ||
113 | 113 | ||
114 | typedef int sampler2D; | 114 | typedef int sampler2D; |
115 | sampler2D texUnit0; | 115 | sampler2D texUnit0; |
116 | 116 | ||
117 | vec4 texture2D (sampler2D sampler, const vec2 &coord) { return vec4 (0.0); } | 117 | vec4 texture2D (sampler2D sampler, const vec2 &coord) { return vec4 (0.0); } |
118 | 118 | ||
119 | struct gl_LightSourceParameters { | 119 | struct gl_LightSourceParameters { |
120 | vec4 ambient; // Acli | 120 | vec4 ambient; // Acli |
121 | vec4 diffuse; // Dcli | 121 | vec4 diffuse; // Dcli |
122 | vec4 specular; // Scli | 122 | vec4 specular; // Scli |
123 | vec4 position; // Ppli | 123 | vec4 position; // Ppli |
124 | vec4 halfVector; // Derived: Hi | 124 | vec4 halfVector; // Derived: Hi |
125 | vec3 spotDirection; // Sdli | 125 | vec3 spotDirection; // Sdli |
126 | float spotExponent; // Srli | 126 | float spotExponent; // Srli |
127 | float spotCutoff; // Crli | 127 | float spotCutoff; // Crli |
128 | // (range: [0.0,90.0], 180.0) | 128 | // (range: [0.0,90.0], 180.0) |
129 | float spotCosCutoff; // Derived: cos(Crli) | 129 | float spotCosCutoff; // Derived: cos(Crli) |
130 | // (range: [1.0,0.0],-1.0) | 130 | // (range: [1.0,0.0],-1.0) |
131 | float constantAttenuation; // K0 | 131 | float constantAttenuation; // K0 |
132 | float linearAttenuation; // K1 | 132 | float linearAttenuation; // K1 |
133 | float quadraticAttenuation;// K2 | 133 | float quadraticAttenuation;// K2 |
134 | }; | 134 | }; |
135 | 135 | ||
136 | uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; | 136 | uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; |
137 | 137 | ||
138 | struct gl_LightModelParameters { | 138 | struct gl_LightModelParameters { |
139 | vec4 ambient; | 139 | vec4 ambient; |
140 | }; | 140 | }; |
141 | uniform gl_LightModelParameters gl_LightModel; | 141 | uniform gl_LightModelParameters gl_LightModel; |
142 | 142 | ||
143 | struct gl_LightModelProducts { | 143 | struct gl_LightModelProducts { |
144 | vec4 sceneColor; | 144 | vec4 sceneColor; |
145 | }; | 145 | }; |
146 | 146 | ||
147 | uniform gl_LightModelProducts gl_FrontLightModelProduct; | 147 | uniform gl_LightModelProducts gl_FrontLightModelProduct; |
148 | uniform gl_LightModelProducts gl_BackLightModelProduct; | 148 | uniform gl_LightModelProducts gl_BackLightModelProduct; |
149 | 149 | ||
150 | struct gl_LightProducts { | 150 | struct gl_LightProducts { |
151 | vec4 ambient; | 151 | vec4 ambient; |
152 | vec4 diffuse; | 152 | vec4 diffuse; |
153 | vec4 specular; | 153 | vec4 specular; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; | 156 | uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; |
157 | uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; | 157 | uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; |
158 | 158 | ||
159 | struct gl_MaterialParameters | 159 | struct gl_MaterialParameters |
160 | { | 160 | { |
161 | vec4 emission; // Ecm | 161 | vec4 emission; // Ecm |
162 | vec4 ambient; // Acm | 162 | vec4 ambient; // Acm |
163 | vec4 diffuse; // Dcm | 163 | vec4 diffuse; // Dcm |
164 | vec4 specular; // Scm | 164 | vec4 specular; // Scm |
165 | float shininess; // Srm | 165 | float shininess; // Srm |
166 | }; | 166 | }; |
167 | uniform gl_MaterialParameters gl_FrontMaterial; | 167 | uniform gl_MaterialParameters gl_FrontMaterial; |
168 | uniform gl_MaterialParameters gl_BackMaterial; | 168 | uniform gl_MaterialParameters gl_BackMaterial; |
169 | 169 | ||
170 | // GLSL has some built-in attributes in a vertex shader: | 170 | // GLSL has some built-in attributes in a vertex shader: |
171 | attribute vec4 gl_Vertex; // 4D vector representing the vertex position | 171 | attribute vec4 gl_Vertex; // 4D vector representing the vertex position |
172 | attribute vec3 gl_Normal; // 3D vector representing the vertex normal | 172 | attribute vec3 gl_Normal; // 3D vector representing the vertex normal |
173 | attribute vec4 gl_Color; // 4D vector representing the vertex color | 173 | attribute vec4 gl_Color; // 4D vector representing the vertex color |
174 | attribute vec4 gl_MultiTexCoord0; // 4D vector representing the texture coordinate of texture unit X | 174 | attribute vec4 gl_MultiTexCoord0; // 4D vector representing the texture coordinate of texture unit X |
175 | attribute vec4 gl_MultiTexCoord1; // 4D vector representing the texture coordinate of texture unit X | 175 | attribute vec4 gl_MultiTexCoord1; // 4D vector representing the texture coordinate of texture unit X |
176 | 176 | ||
177 | uniform mat4 gl_ModelViewMatrix; //4x4 Matrix representing the model-view matrix. | 177 | uniform mat4 gl_ModelViewMatrix; //4x4 Matrix representing the model-view matrix. |
178 | uniform mat4 gl_ModelViewProjectionMatrix; //4x4 Matrix representing the model-view-projection matrix. | 178 | uniform mat4 gl_ModelViewProjectionMatrix; //4x4 Matrix representing the model-view-projection matrix. |
179 | uniform mat3 gl_NormalMatrix; //3x3 Matrix representing the inverse transpose model-view matrix. This matrix is used for normal transformation. | 179 | uniform mat3 gl_NormalMatrix; //3x3 Matrix representing the inverse transpose model-view matrix. This matrix is used for normal transformation. |
180 | 180 | ||
181 | 181 | ||
182 | varying vec4 gl_FrontColor; // 4D vector representing the primitives front color | 182 | varying vec4 gl_FrontColor; // 4D vector representing the primitives front color |
183 | varying vec4 gl_FrontSecondaryColor; // 4D vector representing the primitives second front color | 183 | varying vec4 gl_FrontSecondaryColor; // 4D vector representing the primitives second front color |
184 | varying vec4 gl_BackColor; // 4D vector representing the primitives back color | 184 | varying vec4 gl_BackColor; // 4D vector representing the primitives back color |
185 | varying vec4 gl_TexCoord[4]; // 4D vector representing the Xth texture coordinate | 185 | varying vec4 gl_TexCoord[4]; // 4D vector representing the Xth texture coordinate |
186 | 186 | ||
187 | // shader output | 187 | // shader output |
188 | varying vec4 gl_Position; // 4D vector representing the final processed vertex position. Only available in vertex shader. | 188 | varying vec4 gl_Position; // 4D vector representing the final processed vertex position. Only available in vertex shader. |
189 | varying vec4 gl_FragColor; // 4D vector representing the final color which is written in the frame buffer. Only available in fragment shader. | 189 | varying vec4 gl_FragColor; // 4D vector representing the final color which is written in the frame buffer. Only available in fragment shader. |
190 | varying float gl_FragDepth; // float representing the depth which is written in the depth buffer. Only available in fragment shader. | 190 | varying float gl_FragDepth; // float representing the depth which is written in the depth buffer. Only available in fragment shader. |
191 | 191 | ||
192 | varying vec4 gl_SecondaryColor; | 192 | varying vec4 gl_SecondaryColor; |
193 | varying float gl_FogFragCoord; | 193 | varying float gl_FogFragCoord; |
194 | 194 | ||
195 | 195 | ||
196 | vec4 ftransform(void) | 196 | vec4 ftransform(void) |
197 | { | 197 | { |
198 | return gl_ModelViewProjectionMatrix * gl_Vertex; | 198 | return gl_ModelViewProjectionMatrix * gl_Vertex; |
199 | } | 199 | } |
200 | 200 | ||
201 | vec3 fnormal(void) | 201 | vec3 fnormal(void) |
202 | { | 202 | { |
203 | //Compute the normal | 203 | //Compute the normal |
204 | vec3 normal = gl_NormalMatrix * gl_Normal; | 204 | vec3 normal = gl_NormalMatrix * gl_Normal; |
205 | normal = normalize(normal); | 205 | normal = normalize(normal); |
206 | return normal; | 206 | return normal; |
207 | } | 207 | } |
208 | 208 | ||
209 | 209 | ||
210 | struct program1 | 210 | struct program1 |
211 | { | 211 | { |
212 | vec4 Ambient; | 212 | vec4 Ambient; |
213 | vec4 Diffuse; | 213 | vec4 Diffuse; |
214 | vec4 Specular; | 214 | vec4 Specular; |
215 | 215 | ||
216 | void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) | 216 | void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) |
217 | { | 217 | { |
218 | float nDotVP; // normal . light direction | 218 | float nDotVP; // normal . light direction |
219 | float nDotHV; // normal . light half vector | 219 | float nDotHV; // normal . light half vector |
220 | float pf; // power factor | 220 | float pf; // power factor |
221 | float attenuation; // computed attenuation factor | 221 | float attenuation; // computed attenuation factor |
222 | float d; // distance from surface to light source | 222 | float d; // distance from surface to light source |
223 | vec3 VP; // direction from surface to light position | 223 | vec3 VP; // direction from surface to light position |
224 | vec3 halfVector; // direction of maximum highlights | 224 | vec3 halfVector; // direction of maximum highlights |
225 | 225 | ||
226 | // Compute vector from surface to light position | 226 | // Compute vector from surface to light position |
227 | VP = vec3 (gl_LightSource[i].position) - ecPosition3; | 227 | VP = vec3 (gl_LightSource[i].position) - ecPosition3; |
228 | 228 | ||
229 | // Compute distance between surface and light position | 229 | // Compute distance between surface and light position |
230 | d = length(VP); | 230 | d = length(VP); |
231 | 231 | ||
232 | // Normalize the vector from surface to light position | 232 | // Normalize the vector from surface to light position |
233 | VP = normalize(VP); | 233 | VP = normalize(VP); |
234 | 234 | ||
235 | // Compute attenuation | 235 | // Compute attenuation |
236 | attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + | 236 | attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + |
237 | gl_LightSource[i].linearAttenuation * d + | 237 | gl_LightSource[i].linearAttenuation * d + |
238 | gl_LightSource[i].quadraticAttenuation * d * d); | 238 | gl_LightSource[i].quadraticAttenuation * d * d); |
239 | 239 | ||
240 | halfVector = normalize(VP + eye); | 240 | halfVector = normalize(VP + eye); |
241 | 241 | ||
242 | nDotVP = max(0.0, dot(normal, VP)); | 242 | nDotVP = max(0.0, dot(normal, VP)); |
243 | nDotHV = max(0.0, dot(normal, halfVector)); | 243 | nDotHV = max(0.0, dot(normal, halfVector)); |
244 | 244 | ||
245 | if (nDotVP == 0.0) | 245 | if (nDotVP == 0.0) |
246 | { | 246 | { |
247 | pf = 0.0; | 247 | pf = 0.0; |
248 | } | 248 | } |
249 | else | 249 | else |
250 | { | 250 | { |
251 | pf = pow(nDotHV, gl_FrontMaterial.shininess); | 251 | pf = pow(nDotHV, gl_FrontMaterial.shininess); |
252 | 252 | ||
253 | } | 253 | } |
254 | Ambient += gl_LightSource[i].ambient * attenuation; | 254 | Ambient += gl_LightSource[i].ambient * attenuation; |
255 | Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; | 255 | Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; |
256 | Specular += gl_LightSource[i].specular * pf * attenuation; | 256 | Specular += gl_LightSource[i].specular * pf * attenuation; |
257 | } | 257 | } |
258 | 258 | ||
259 | vec3 fnormal(void) | 259 | vec3 fnormal(void) |
260 | { | 260 | { |
261 | //Compute the normal | 261 | //Compute the normal |
262 | vec3 normal = gl_NormalMatrix * gl_Normal; | 262 | vec3 normal = gl_NormalMatrix * gl_Normal; |
263 | normal = normalize(normal); | 263 | normal = normalize(normal); |
264 | return normal; | 264 | return normal; |
265 | } | 265 | } |
266 | 266 | ||
267 | void ftexgen(in vec3 normal, in vec4 ecPosition) | 267 | void ftexgen(in vec3 normal, in vec4 ecPosition) |
268 | { | 268 | { |
269 | 269 | ||
270 | gl_TexCoord[0] = gl_MultiTexCoord0; | 270 | gl_TexCoord[0] = gl_MultiTexCoord0; |
271 | } | 271 | } |
272 | 272 | ||
273 | void flight(in vec3 normal, in vec4 ecPosition, float alphaFade) | 273 | void flight(in vec3 normal, in vec4 ecPosition, float alphaFade) |
274 | { | 274 | { |
275 | vec4 color; | 275 | vec4 color; |
276 | vec3 ecPosition3; | 276 | vec3 ecPosition3; |
277 | vec3 eye; | 277 | vec3 eye; |
278 | 278 | ||
279 | ecPosition3 = (vec3 (ecPosition)) / ecPosition.w; | 279 | ecPosition3 = (vec3 (ecPosition)) / ecPosition.w; |
280 | eye = vec3 (0.0, 0.0, 1.0); | 280 | eye = vec3 (0.0, 0.0, 1.0); |
281 | 281 | ||
282 | // Clear the light intensity accumulators | 282 | // Clear the light intensity accumulators |
283 | Ambient = vec4 (0.0); | 283 | Ambient = vec4 (0.0); |
284 | Diffuse = vec4 (0.0); | 284 | Diffuse = vec4 (0.0); |
285 | Specular = vec4 (0.0); | 285 | Specular = vec4 (0.0); |
286 | 286 | ||
287 | pointLight(0, normal, eye, ecPosition3); | 287 | pointLight(0, normal, eye, ecPosition3); |
288 | 288 | ||
289 | pointLight(1, normal, eye, ecPosition3); | 289 | pointLight(1, normal, eye, ecPosition3); |
290 | 290 | ||
291 | color = gl_FrontLightModelProduct.sceneColor + | 291 | color = gl_FrontLightModelProduct.sceneColor + |
292 | Ambient * gl_FrontMaterial.ambient + | 292 | Ambient * gl_FrontMaterial.ambient + |
293 | Diffuse * gl_FrontMaterial.diffuse; | 293 | Diffuse * gl_FrontMaterial.diffuse; |
294 | gl_FrontSecondaryColor = Specular * gl_FrontMaterial.specular; | 294 | gl_FrontSecondaryColor = Specular * gl_FrontMaterial.specular; |
295 | color = clamp( color, 0.0, 1.0 ); | 295 | color = clamp( color, 0.0, 1.0 ); |
296 | gl_FrontColor = color; | 296 | gl_FrontColor = color; |
297 | 297 | ||
298 | gl_FrontColor.a *= alphaFade; | 298 | gl_FrontColor.a *= alphaFade; |
299 | } | 299 | } |
300 | 300 | ||
301 | 301 | ||
302 | void vertexshader_main (void) | 302 | void vertexshader_main (void) |
303 | { | 303 | { |
304 | vec3 transformedNormal; | 304 | vec3 transformedNormal; |
305 | float alphaFade = 1.0; | 305 | float alphaFade = 1.0; |
306 | 306 | ||
307 | // Eye-coordinate position of vertex, needed in various calculations | 307 | // Eye-coordinate position of vertex, needed in various calculations |
308 | vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; | 308 | vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; |
309 | 309 | ||
310 | // Do fixed functionality vertex transform | 310 | // Do fixed functionality vertex transform |
311 | gl_Position = ftransform(); | 311 | gl_Position = ftransform(); |
312 | transformedNormal = fnormal(); | 312 | transformedNormal = fnormal(); |
313 | flight(transformedNormal, ecPosition, alphaFade); | 313 | flight(transformedNormal, ecPosition, alphaFade); |
314 | ftexgen(transformedNormal, ecPosition); | 314 | ftexgen(transformedNormal, ecPosition); |
315 | } | 315 | } |
316 | 316 | ||
317 | void fragmentshader_main (void) | 317 | void fragmentshader_main (void) |
318 | { | 318 | { |
319 | vec4 color; | 319 | vec4 color; |
320 | 320 | ||
321 | color = gl_Color; | 321 | color = gl_Color; |
322 | 322 | ||
323 | color *= texture2D(texUnit0, vec2(gl_TexCoord[0].x, gl_TexCoord[0].y) ); | 323 | color *= texture2D(texUnit0, vec2(gl_TexCoord[0].x, gl_TexCoord[0].y) ); |
324 | 324 | ||
325 | color += gl_SecondaryColor; | 325 | color += gl_SecondaryColor; |
326 | color = clamp(color, 0.0, 1.0); | 326 | color = clamp(color, 0.0, 1.0); |
327 | 327 | ||
328 | gl_FragColor = color; | 328 | gl_FragColor = color; |
329 | } | 329 | } |
330 | }; | 330 | }; |
331 | 331 | ||
332 | } | 332 | } |
333 | 333 | ||
334 | //! constructor | 334 | //! constructor |
335 | CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) | 335 | CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) |
336 | : CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter), | 336 | : CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter), |
337 | WindowId(0), SceneSourceRect(0), | 337 | WindowId(0), SceneSourceRect(0), |
338 | RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0), | 338 | RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0), |
339 | DepthBuffer(0), StencilBuffer ( 0 ), | 339 | DepthBuffer(0), StencilBuffer ( 0 ), |
340 | CurrentOut ( 12 * 2, 128 ), Temp ( 12 * 2, 128 ) | 340 | CurrentOut ( 12 * 2, 128 ), Temp ( 12 * 2, 128 ) |
341 | { | 341 | { |
342 | #ifdef _DEBUG | 342 | #ifdef _DEBUG |
343 | setDebugName("CBurningVideoDriver"); | 343 | setDebugName("CBurningVideoDriver"); |
344 | #endif | 344 | #endif |
345 | 345 | ||
346 | // create backbuffer | 346 | // create backbuffer |
347 | BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize); | 347 | BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize); |
348 | if (BackBuffer) | 348 | if (BackBuffer) |
349 | { | 349 | { |
350 | BackBuffer->fill(SColor(0)); | 350 | BackBuffer->fill(SColor(0)); |
351 | 351 | ||
352 | // create z buffer | 352 | // create z buffer |
353 | if ( params.ZBufferBits ) | 353 | if ( params.ZBufferBits ) |
354 | DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension()); | 354 | DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension()); |
355 | 355 | ||
356 | // create stencil buffer | 356 | // create stencil buffer |
357 | if ( params.Stencilbuffer ) | 357 | if ( params.Stencilbuffer ) |
358 | StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension()); | 358 | StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension()); |
359 | } | 359 | } |
360 | 360 | ||
361 | DriverAttributes->setAttribute("MaxTextures", 2); | 361 | DriverAttributes->setAttribute("MaxTextures", 2); |
362 | DriverAttributes->setAttribute("MaxIndices", 1<<16); | 362 | DriverAttributes->setAttribute("MaxIndices", 1<<16); |
363 | DriverAttributes->setAttribute("MaxTextureSize", 1024); | 363 | DriverAttributes->setAttribute("MaxTextureSize", 1024); |
364 | DriverAttributes->setAttribute("MaxLights", glsl::gl_MaxLights); | 364 | DriverAttributes->setAttribute("MaxLights", glsl::gl_MaxLights); |
365 | DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); | 365 | DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); |
366 | DriverAttributes->setAttribute("Version", 47); | 366 | DriverAttributes->setAttribute("Version", 47); |
367 | 367 | ||
368 | // create triangle renderers | 368 | // create triangle renderers |
369 | 369 | ||
370 | irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) ); | 370 | irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) ); |
371 | //BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer); | 371 | //BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer); |
372 | //BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer); | 372 | //BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer); |
373 | BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this); | 373 | BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this); |
374 | BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this ); | 374 | BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this ); |
375 | BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this ); | 375 | BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this ); |
376 | //BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer); | 376 | //BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer); |
377 | //BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer); | 377 | //BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer); |
378 | //BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer); | 378 | //BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer); |
379 | BurningShader[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud2(this); | 379 | BurningShader[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud2(this); |
380 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M1] = createTriangleRendererTextureLightMap2_M1(this); | 380 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M1] = createTriangleRendererTextureLightMap2_M1(this); |
381 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M2] = createTriangleRendererTextureLightMap2_M2(this); | 381 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M2] = createTriangleRendererTextureLightMap2_M2(this); |
382 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M4] = createTriangleRendererGTextureLightMap2_M4(this); | 382 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M4] = createTriangleRendererGTextureLightMap2_M4(this); |
383 | BurningShader[ETR_TEXTURE_LIGHTMAP_M4] = createTriangleRendererTextureLightMap2_M4(this); | 383 | BurningShader[ETR_TEXTURE_LIGHTMAP_M4] = createTriangleRendererTextureLightMap2_M4(this); |
384 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD] = createTriangleRendererTextureLightMap2_Add(this); | 384 | BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD] = createTriangleRendererTextureLightMap2_Add(this); |
385 | BurningShader[ETR_TEXTURE_GOURAUD_DETAIL_MAP] = createTriangleRendererTextureDetailMap2(this); | 385 | BurningShader[ETR_TEXTURE_GOURAUD_DETAIL_MAP] = createTriangleRendererTextureDetailMap2(this); |
386 | 386 | ||
387 | BurningShader[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire2(this); | 387 | BurningShader[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire2(this); |
388 | BurningShader[ETR_TEXTURE_GOURAUD_NOZ] = createTRTextureGouraudNoZ2(this); | 388 | BurningShader[ETR_TEXTURE_GOURAUD_NOZ] = createTRTextureGouraudNoZ2(this); |
389 | BurningShader[ETR_TEXTURE_GOURAUD_ADD] = createTRTextureGouraudAdd2(this); | 389 | BurningShader[ETR_TEXTURE_GOURAUD_ADD] = createTRTextureGouraudAdd2(this); |
390 | BurningShader[ETR_TEXTURE_GOURAUD_ADD_NO_Z] = createTRTextureGouraudAddNoZ2(this); | 390 | BurningShader[ETR_TEXTURE_GOURAUD_ADD_NO_Z] = createTRTextureGouraudAddNoZ2(this); |
391 | BurningShader[ETR_TEXTURE_GOURAUD_VERTEX_ALPHA] = createTriangleRendererTextureVertexAlpha2 ( this ); | 391 | BurningShader[ETR_TEXTURE_GOURAUD_VERTEX_ALPHA] = createTriangleRendererTextureVertexAlpha2 ( this ); |
392 | 392 | ||
393 | BurningShader[ETR_TEXTURE_GOURAUD_ALPHA] = createTRTextureGouraudAlpha(this ); | 393 | BurningShader[ETR_TEXTURE_GOURAUD_ALPHA] = createTRTextureGouraudAlpha(this ); |
394 | BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ( this ); | 394 | BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ( this ); |
395 | 395 | ||
396 | BurningShader[ETR_NORMAL_MAP_SOLID] = createTRNormalMap ( this ); | 396 | BurningShader[ETR_NORMAL_MAP_SOLID] = createTRNormalMap ( this ); |
397 | BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this ); | 397 | BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this ); |
398 | BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this ); | 398 | BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this ); |
399 | 399 | ||
400 | BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this ); | 400 | BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this ); |
401 | 401 | ||
402 | 402 | ||
403 | // add the same renderer for all solid types | 403 | // add the same renderer for all solid types |
404 | CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this); | 404 | CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this); |
405 | CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this); | 405 | CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this); |
406 | CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this ); | 406 | CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this ); |
407 | 407 | ||
408 | //!TODO: addMaterialRenderer depends on pushing order.... | 408 | //!TODO: addMaterialRenderer depends on pushing order.... |
409 | addMaterialRenderer ( smr ); // EMT_SOLID | 409 | addMaterialRenderer ( smr ); // EMT_SOLID |
410 | addMaterialRenderer ( smr ); // EMT_SOLID_2_LAYER, | 410 | addMaterialRenderer ( smr ); // EMT_SOLID_2_LAYER, |
411 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP, | 411 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP, |
412 | addMaterialRenderer ( tmr ); // EMT_LIGHTMAP_ADD, | 412 | addMaterialRenderer ( tmr ); // EMT_LIGHTMAP_ADD, |
413 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M2, | 413 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M2, |
414 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M4, | 414 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M4, |
415 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING, | 415 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING, |
416 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2, | 416 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2, |
417 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4, | 417 | addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4, |
418 | addMaterialRenderer ( smr ); // EMT_DETAIL_MAP, | 418 | addMaterialRenderer ( smr ); // EMT_DETAIL_MAP, |
419 | addMaterialRenderer ( umr ); // EMT_SPHERE_MAP, | 419 | addMaterialRenderer ( umr ); // EMT_SPHERE_MAP, |
420 | addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER, | 420 | addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER, |
421 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR, | 421 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR, |
422 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL, | 422 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL, |
423 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL_REF, | 423 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL_REF, |
424 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA, | 424 | addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA, |
425 | addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER, | 425 | addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER, |
426 | addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID, | 426 | addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID, |
427 | addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, | 427 | addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, |
428 | addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, | 428 | addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, |
429 | addMaterialRenderer ( smr ); // EMT_PARALLAX_MAP_SOLID, | 429 | addMaterialRenderer ( smr ); // EMT_PARALLAX_MAP_SOLID, |
430 | addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, | 430 | addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, |
431 | addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, | 431 | addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, |
432 | addMaterialRenderer ( tmr ); // EMT_ONETEXTURE_BLEND | 432 | addMaterialRenderer ( tmr ); // EMT_ONETEXTURE_BLEND |
433 | 433 | ||
434 | smr->drop (); | 434 | smr->drop (); |
435 | tmr->drop (); | 435 | tmr->drop (); |
436 | umr->drop (); | 436 | umr->drop (); |
437 | 437 | ||
438 | // select render target | 438 | // select render target |
439 | setRenderTarget(BackBuffer); | 439 | setRenderTarget(BackBuffer); |
440 | 440 | ||
441 | //reset Lightspace | 441 | //reset Lightspace |
442 | LightSpace.reset (); | 442 | LightSpace.reset (); |
443 | 443 | ||
444 | // select the right renderer | 444 | // select the right renderer |
445 | setCurrentShader(); | 445 | setCurrentShader(); |
446 | } | 446 | } |
447 | 447 | ||
448 | 448 | ||
449 | //! destructor | 449 | //! destructor |
450 | CBurningVideoDriver::~CBurningVideoDriver() | 450 | CBurningVideoDriver::~CBurningVideoDriver() |
451 | { | 451 | { |
452 | // delete Backbuffer | 452 | // delete Backbuffer |
453 | if (BackBuffer) | 453 | if (BackBuffer) |
454 | BackBuffer->drop(); | 454 | BackBuffer->drop(); |
455 | 455 | ||
456 | // delete triangle renderers | 456 | // delete triangle renderers |
457 | 457 | ||
458 | for (s32 i=0; i<ETR2_COUNT; ++i) | 458 | for (s32 i=0; i<ETR2_COUNT; ++i) |
459 | { | 459 | { |
460 | if (BurningShader[i]) | 460 | if (BurningShader[i]) |
461 | BurningShader[i]->drop(); | 461 | BurningShader[i]->drop(); |
462 | } | 462 | } |
463 | 463 | ||
464 | // delete Additional buffer | 464 | // delete Additional buffer |
465 | if (StencilBuffer) | 465 | if (StencilBuffer) |
466 | StencilBuffer->drop(); | 466 | StencilBuffer->drop(); |
467 | 467 | ||
468 | if (DepthBuffer) | 468 | if (DepthBuffer) |
469 | DepthBuffer->drop(); | 469 | DepthBuffer->drop(); |
470 | 470 | ||
471 | if (RenderTargetTexture) | 471 | if (RenderTargetTexture) |
472 | RenderTargetTexture->drop(); | 472 | RenderTargetTexture->drop(); |
473 | 473 | ||
474 | if (RenderTargetSurface) | 474 | if (RenderTargetSurface) |
475 | RenderTargetSurface->drop(); | 475 | RenderTargetSurface->drop(); |
476 | } | 476 | } |
477 | 477 | ||
478 | 478 | ||
479 | /*! | 479 | /*! |
480 | selects the right triangle renderer based on the render states. | 480 | selects the right triangle renderer based on the render states. |
481 | */ | 481 | */ |
482 | void CBurningVideoDriver::setCurrentShader() | 482 | void CBurningVideoDriver::setCurrentShader() |
483 | { | 483 | { |
484 | ITexture *texture0 = Material.org.getTexture(0); | 484 | ITexture *texture0 = Material.org.getTexture(0); |
485 | ITexture *texture1 = Material.org.getTexture(1); | 485 | ITexture *texture1 = Material.org.getTexture(1); |
486 | 486 | ||
487 | bool zMaterialTest = Material.org.ZBuffer != ECFN_NEVER && | 487 | bool zMaterialTest = Material.org.ZBuffer != ECFN_NEVER && |
488 | Material.org.ZWriteEnable && | 488 | Material.org.ZWriteEnable && |
489 | ( AllowZWriteOnTransparent || !Material.org.isTransparent() ); | 489 | ( AllowZWriteOnTransparent || !Material.org.isTransparent() ); |
490 | 490 | ||
491 | EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; | 491 | EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; |
492 | 492 | ||
493 | TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION); | 493 | TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION); |
494 | LightSpace.Flags &= ~VERTEXTRANSFORM; | 494 | LightSpace.Flags &= ~VERTEXTRANSFORM; |
495 | 495 | ||
496 | switch ( Material.org.MaterialType ) | 496 | switch ( Material.org.MaterialType ) |
497 | { | 497 | { |
498 | case EMT_ONETEXTURE_BLEND: | 498 | case EMT_ONETEXTURE_BLEND: |
499 | shader = ETR_TEXTURE_BLEND; | 499 | shader = ETR_TEXTURE_BLEND; |
500 | break; | 500 | break; |
501 | 501 | ||
502 | case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: | 502 | case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: |
503 | Material.org.MaterialTypeParam = 0.5f; | 503 | Material.org.MaterialTypeParam = 0.5f; |
504 | // fall through | 504 | // fall through |
505 | case EMT_TRANSPARENT_ALPHA_CHANNEL: | 505 | case EMT_TRANSPARENT_ALPHA_CHANNEL: |
506 | if ( texture0 && texture0->hasAlpha () ) | 506 | if ( texture0 && texture0->hasAlpha () ) |
507 | { | 507 | { |
508 | shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ; | 508 | shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ; |
509 | break; | 509 | break; |
510 | } | 510 | } |
511 | // fall through | 511 | // fall through |
512 | 512 | ||
513 | case EMT_TRANSPARENT_ADD_COLOR: | 513 | case EMT_TRANSPARENT_ADD_COLOR: |
514 | shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z; | 514 | shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z; |
515 | break; | 515 | break; |
516 | 516 | ||
517 | case EMT_TRANSPARENT_VERTEX_ALPHA: | 517 | case EMT_TRANSPARENT_VERTEX_ALPHA: |
518 | shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA; | 518 | shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA; |
519 | break; | 519 | break; |
520 | 520 | ||
521 | case EMT_LIGHTMAP: | 521 | case EMT_LIGHTMAP: |
522 | case EMT_LIGHTMAP_LIGHTING: | 522 | case EMT_LIGHTMAP_LIGHTING: |
523 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; | 523 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; |
524 | break; | 524 | break; |
525 | 525 | ||
526 | case EMT_LIGHTMAP_M2: | 526 | case EMT_LIGHTMAP_M2: |
527 | case EMT_LIGHTMAP_LIGHTING_M2: | 527 | case EMT_LIGHTMAP_LIGHTING_M2: |
528 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2; | 528 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2; |
529 | break; | 529 | break; |
530 | 530 | ||
531 | case EMT_LIGHTMAP_LIGHTING_M4: | 531 | case EMT_LIGHTMAP_LIGHTING_M4: |
532 | if ( texture1 ) | 532 | if ( texture1 ) |
533 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4; | 533 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4; |
534 | break; | 534 | break; |
535 | case EMT_LIGHTMAP_M4: | 535 | case EMT_LIGHTMAP_M4: |
536 | if ( texture1 ) | 536 | if ( texture1 ) |
537 | shader = ETR_TEXTURE_LIGHTMAP_M4; | 537 | shader = ETR_TEXTURE_LIGHTMAP_M4; |
538 | break; | 538 | break; |
539 | 539 | ||
540 | case EMT_LIGHTMAP_ADD: | 540 | case EMT_LIGHTMAP_ADD: |
541 | if ( texture1 ) | 541 | if ( texture1 ) |
542 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD; | 542 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD; |
543 | break; | 543 | break; |
544 | 544 | ||
545 | case EMT_DETAIL_MAP: | 545 | case EMT_DETAIL_MAP: |
546 | shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP; | 546 | shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP; |
547 | break; | 547 | break; |
548 | 548 | ||
549 | case EMT_SPHERE_MAP: | 549 | case EMT_SPHERE_MAP: |
550 | TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL; | 550 | TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL; |
551 | LightSpace.Flags |= VERTEXTRANSFORM; | 551 | LightSpace.Flags |= VERTEXTRANSFORM; |
552 | break; | 552 | break; |
553 | case EMT_REFLECTION_2_LAYER: | 553 | case EMT_REFLECTION_2_LAYER: |
554 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; | 554 | shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; |
555 | TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION; | 555 | TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION; |
556 | LightSpace.Flags |= VERTEXTRANSFORM; | 556 | LightSpace.Flags |= VERTEXTRANSFORM; |
557 | break; | 557 | break; |
558 | 558 | ||
559 | case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA: | 559 | case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA: |
560 | case EMT_NORMAL_MAP_SOLID: | 560 | case EMT_NORMAL_MAP_SOLID: |
561 | case EMT_PARALLAX_MAP_SOLID: | 561 | case EMT_PARALLAX_MAP_SOLID: |
562 | case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA: | 562 | case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA: |
563 | shader = ETR_NORMAL_MAP_SOLID; | 563 | shader = ETR_NORMAL_MAP_SOLID; |
564 | LightSpace.Flags |= VERTEXTRANSFORM; | 564 | LightSpace.Flags |= VERTEXTRANSFORM; |
565 | break; | 565 | break; |
566 | 566 | ||
567 | default: | 567 | default: |
568 | break; | 568 | break; |
569 | 569 | ||
570 | } | 570 | } |
571 | 571 | ||
572 | if ( !texture0 ) | 572 | if ( !texture0 ) |
573 | { | 573 | { |
574 | shader = ETR_GOURAUD; | 574 | shader = ETR_GOURAUD; |
575 | } | 575 | } |
576 | 576 | ||
577 | if ( Material.org.Wireframe ) | 577 | if ( Material.org.Wireframe ) |
578 | { | 578 | { |
579 | shader = ETR_TEXTURE_GOURAUD_WIRE; | 579 | shader = ETR_TEXTURE_GOURAUD_WIRE; |
580 | } | 580 | } |
581 | 581 | ||
582 | //shader = ETR_REFERENCE; | 582 | //shader = ETR_REFERENCE; |
583 | 583 | ||
584 | // switchToTriangleRenderer | 584 | // switchToTriangleRenderer |
585 | CurrentShader = BurningShader[shader]; | 585 | CurrentShader = BurningShader[shader]; |
586 | if ( CurrentShader ) | 586 | if ( CurrentShader ) |
587 | { | 587 | { |
588 | CurrentShader->setZCompareFunc ( Material.org.ZBuffer ); | 588 | CurrentShader->setZCompareFunc ( Material.org.ZBuffer ); |
589 | CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); | 589 | CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); |
590 | CurrentShader->setMaterial ( Material ); | 590 | CurrentShader->setMaterial ( Material ); |
591 | 591 | ||
592 | switch ( shader ) | 592 | switch ( shader ) |
593 | { | 593 | { |
594 | case ETR_TEXTURE_GOURAUD_ALPHA: | 594 | case ETR_TEXTURE_GOURAUD_ALPHA: |
595 | case ETR_TEXTURE_GOURAUD_ALPHA_NOZ: | 595 | case ETR_TEXTURE_GOURAUD_ALPHA_NOZ: |
596 | case ETR_TEXTURE_BLEND: | 596 | case ETR_TEXTURE_BLEND: |
597 | CurrentShader->setParam ( 0, Material.org.MaterialTypeParam ); | 597 | CurrentShader->setParam ( 0, Material.org.MaterialTypeParam ); |
598 | break; | 598 | break; |
599 | default: | 599 | default: |
600 | break; | 600 | break; |
601 | } | 601 | } |
602 | } | 602 | } |
603 | 603 | ||
604 | } | 604 | } |
605 | 605 | ||
606 | 606 | ||
607 | 607 | ||
608 | //! queries the features of the driver, returns true if feature is available | 608 | //! queries the features of the driver, returns true if feature is available |
609 | bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const | 609 | bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const |
610 | { | 610 | { |
611 | if (!FeatureEnabled[feature]) | 611 | if (!FeatureEnabled[feature]) |
612 | return false; | 612 | return false; |
613 | 613 | ||
614 | switch (feature) | 614 | switch (feature) |
615 | { | 615 | { |
616 | #ifdef SOFTWARE_DRIVER_2_BILINEAR | 616 | #ifdef SOFTWARE_DRIVER_2_BILINEAR |
617 | case EVDF_BILINEAR_FILTER: | 617 | case EVDF_BILINEAR_FILTER: |
618 | return true; | 618 | return true; |
619 | #endif | 619 | #endif |
620 | #ifdef SOFTWARE_DRIVER_2_MIPMAPPING | 620 | #ifdef SOFTWARE_DRIVER_2_MIPMAPPING |
621 | case EVDF_MIP_MAP: | 621 | case EVDF_MIP_MAP: |
622 | return true; | 622 | return true; |
623 | #endif | 623 | #endif |
624 | case EVDF_STENCIL_BUFFER: | 624 | case EVDF_STENCIL_BUFFER: |
625 | case EVDF_RENDER_TO_TARGET: | 625 | case EVDF_RENDER_TO_TARGET: |
626 | case EVDF_MULTITEXTURE: | 626 | case EVDF_MULTITEXTURE: |
627 | case EVDF_HARDWARE_TL: | 627 | case EVDF_HARDWARE_TL: |
628 | case EVDF_TEXTURE_NSQUARE: | 628 | case EVDF_TEXTURE_NSQUARE: |
629 | return true; | 629 | return true; |
630 | 630 | ||
631 | default: | 631 | default: |
632 | return false; | 632 | return false; |
633 | } | 633 | } |
634 | } | 634 | } |
635 | 635 | ||
636 | 636 | ||
637 | 637 | ||
638 | //! sets transformation | 638 | //! sets transformation |
639 | void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) | 639 | void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) |
640 | { | 640 | { |
641 | Transformation[state] = mat; | 641 | Transformation[state] = mat; |
642 | core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY ); | 642 | core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY ); |
643 | 643 | ||
644 | switch ( state ) | 644 | switch ( state ) |
645 | { | 645 | { |
646 | case ETS_VIEW: | 646 | case ETS_VIEW: |
647 | Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck ( | 647 | Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck ( |
648 | Transformation[ETS_PROJECTION], | 648 | Transformation[ETS_PROJECTION], |
649 | Transformation[ETS_VIEW] | 649 | Transformation[ETS_VIEW] |
650 | ); | 650 | ); |
651 | getCameraPosWorldSpace (); | 651 | getCameraPosWorldSpace (); |
652 | break; | 652 | break; |
653 | 653 | ||
654 | case ETS_WORLD: | 654 | case ETS_WORLD: |
655 | if ( TransformationFlag[state] & ETF_IDENTITY ) | 655 | if ( TransformationFlag[state] & ETF_IDENTITY ) |
656 | { | 656 | { |
657 | Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; | 657 | Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; |
658 | TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; | 658 | TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; |
659 | Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION]; | 659 | Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION]; |
660 | } | 660 | } |
661 | else | 661 | else |
662 | { | 662 | { |
663 | //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] ); | 663 | //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] ); |
664 | Transformation[ETS_CURRENT].setbyproduct_nocheck ( | 664 | Transformation[ETS_CURRENT].setbyproduct_nocheck ( |
665 | Transformation[ETS_VIEW_PROJECTION], | 665 | Transformation[ETS_VIEW_PROJECTION], |
666 | Transformation[ETS_WORLD] | 666 | Transformation[ETS_WORLD] |
667 | ); | 667 | ); |
668 | } | 668 | } |
669 | TransformationFlag[ETS_CURRENT] = 0; | 669 | TransformationFlag[ETS_CURRENT] = 0; |
670 | //getLightPosObjectSpace (); | 670 | //getLightPosObjectSpace (); |
671 | break; | 671 | break; |
672 | case ETS_TEXTURE_0: | 672 | case ETS_TEXTURE_0: |
673 | case ETS_TEXTURE_1: | 673 | case ETS_TEXTURE_1: |
674 | case ETS_TEXTURE_2: | 674 | case ETS_TEXTURE_2: |
675 | case ETS_TEXTURE_3: | 675 | case ETS_TEXTURE_3: |
676 | if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) ) | 676 | if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) ) |
677 | LightSpace.Flags |= VERTEXTRANSFORM; | 677 | LightSpace.Flags |= VERTEXTRANSFORM; |
678 | default: | 678 | default: |
679 | break; | 679 | break; |
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | 683 | ||
684 | //! clears the zbuffer | 684 | //! clears the zbuffer |
685 | bool CBurningVideoDriver::beginScene(bool backBuffer, bool zBuffer, | 685 | bool CBurningVideoDriver::beginScene(bool backBuffer, bool zBuffer, |
686 | SColor color, const SExposedVideoData& videoData, | 686 | SColor color, const SExposedVideoData& videoData, |
687 | core::rect<s32>* sourceRect) | 687 | core::rect<s32>* sourceRect) |
688 | { | 688 | { |
689 | CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); | 689 | CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); |
690 | WindowId = videoData.D3D9.HWnd; | 690 | WindowId = videoData.D3D9.HWnd; |
691 | SceneSourceRect = sourceRect; | 691 | SceneSourceRect = sourceRect; |
692 | 692 | ||
693 | if (backBuffer && BackBuffer) | 693 | if (backBuffer && BackBuffer) |
694 | BackBuffer->fill(color); | 694 | BackBuffer->fill(color); |
695 | 695 | ||
696 | if (zBuffer && DepthBuffer) | 696 | if (zBuffer && DepthBuffer) |
697 | DepthBuffer->clear(); | 697 | DepthBuffer->clear(); |
698 | 698 | ||
699 | memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) ); | 699 | memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) ); |
700 | return true; | 700 | return true; |
701 | } | 701 | } |
702 | 702 | ||
703 | 703 | ||
704 | //! presents the rendered scene on the screen, returns false if failed | 704 | //! presents the rendered scene on the screen, returns false if failed |
705 | bool CBurningVideoDriver::endScene() | 705 | bool CBurningVideoDriver::endScene() |
706 | { | 706 | { |
707 | CNullDriver::endScene(); | 707 | CNullDriver::endScene(); |
708 | 708 | ||
709 | return Presenter->present(BackBuffer, WindowId, SceneSourceRect); | 709 | return Presenter->present(BackBuffer, WindowId, SceneSourceRect); |
710 | } | 710 | } |
711 | 711 | ||
712 | 712 | ||
713 | //! sets a render target | 713 | //! sets a render target |
714 | bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, | 714 | bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, |
715 | bool clearZBuffer, SColor color) | 715 | bool clearZBuffer, SColor color) |
716 | { | 716 | { |
717 | if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO) | 717 | if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO) |
718 | { | 718 | { |
719 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); | 719 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); |
720 | return false; | 720 | return false; |
721 | } | 721 | } |
722 | 722 | ||
723 | if (RenderTargetTexture) | 723 | if (RenderTargetTexture) |
724 | RenderTargetTexture->drop(); | 724 | RenderTargetTexture->drop(); |
725 | 725 | ||
726 | RenderTargetTexture = texture; | 726 | RenderTargetTexture = texture; |
727 | 727 | ||
728 | if (RenderTargetTexture) | 728 | if (RenderTargetTexture) |
729 | { | 729 | { |
730 | RenderTargetTexture->grab(); | 730 | RenderTargetTexture->grab(); |
731 | setRenderTarget(((CSoftwareTexture2*)RenderTargetTexture)->getTexture()); | 731 | setRenderTarget(((CSoftwareTexture2*)RenderTargetTexture)->getTexture()); |
732 | } | 732 | } |
733 | else | 733 | else |
734 | { | 734 | { |
735 | setRenderTarget(BackBuffer); | 735 | setRenderTarget(BackBuffer); |
736 | } | 736 | } |
737 | 737 | ||
738 | if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) | 738 | if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) |
739 | { | 739 | { |
740 | if (clearZBuffer) | 740 | if (clearZBuffer) |
741 | DepthBuffer->clear(); | 741 | DepthBuffer->clear(); |
742 | 742 | ||
743 | if (clearBackBuffer) | 743 | if (clearBackBuffer) |
744 | RenderTargetSurface->fill( color ); | 744 | RenderTargetSurface->fill( color ); |
745 | } | 745 | } |
746 | 746 | ||
747 | return true; | 747 | return true; |
748 | } | 748 | } |
749 | 749 | ||
750 | 750 | ||
751 | //! sets a render target | 751 | //! sets a render target |
752 | void CBurningVideoDriver::setRenderTarget(video::CImage* image) | 752 | void CBurningVideoDriver::setRenderTarget(video::CImage* image) |
753 | { | 753 | { |
754 | if (RenderTargetSurface) | 754 | if (RenderTargetSurface) |
755 | RenderTargetSurface->drop(); | 755 | RenderTargetSurface->drop(); |
756 | 756 | ||
757 | RenderTargetSurface = image; | 757 | RenderTargetSurface = image; |
758 | RenderTargetSize.Width = 0; | 758 | RenderTargetSize.Width = 0; |
759 | RenderTargetSize.Height = 0; | 759 | RenderTargetSize.Height = 0; |
760 | 760 | ||
761 | if (RenderTargetSurface) | 761 | if (RenderTargetSurface) |
762 | { | 762 | { |
763 | RenderTargetSurface->grab(); | 763 | RenderTargetSurface->grab(); |
764 | RenderTargetSize = RenderTargetSurface->getDimension(); | 764 | RenderTargetSize = RenderTargetSurface->getDimension(); |
765 | } | 765 | } |
766 | 766 | ||
767 | setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); | 767 | setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); |
768 | 768 | ||
769 | if (DepthBuffer) | 769 | if (DepthBuffer) |
770 | DepthBuffer->setSize(RenderTargetSize); | 770 | DepthBuffer->setSize(RenderTargetSize); |
771 | 771 | ||
772 | if (StencilBuffer) | 772 | if (StencilBuffer) |
773 | StencilBuffer->setSize(RenderTargetSize); | 773 | StencilBuffer->setSize(RenderTargetSize); |
774 | } | 774 | } |
775 | 775 | ||
776 | 776 | ||
777 | 777 | ||
778 | //! sets a viewport | 778 | //! sets a viewport |
779 | void CBurningVideoDriver::setViewPort(const core::rect<s32>& area) | 779 | void CBurningVideoDriver::setViewPort(const core::rect<s32>& area) |
780 | { | 780 | { |
781 | ViewPort = area; | 781 | ViewPort = area; |
782 | 782 | ||
783 | core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); | 783 | core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); |
784 | ViewPort.clipAgainst(rendert); | 784 | ViewPort.clipAgainst(rendert); |
785 | 785 | ||
786 | Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 ); | 786 | Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 ); |
787 | 787 | ||
788 | if (CurrentShader) | 788 | if (CurrentShader) |
789 | CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); | 789 | CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); |
790 | } | 790 | } |
791 | 791 | ||
792 | /* | 792 | /* |
793 | generic plane clipping in homogenous coordinates | 793 | generic plane clipping in homogenous coordinates |
794 | special case ndc frustum <-w,w>,<-w,w>,<-w,w> | 794 | special case ndc frustum <-w,w>,<-w,w>,<-w,w> |
795 | can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w | 795 | can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w |
796 | */ | 796 | */ |
797 | 797 | ||
798 | const sVec4 CBurningVideoDriver::NDCPlane[6] = | 798 | const sVec4 CBurningVideoDriver::NDCPlane[6] = |
799 | { | 799 | { |
800 | sVec4( 0.f, 0.f, -1.f, -1.f ), // near | 800 | sVec4( 0.f, 0.f, -1.f, -1.f ), // near |
801 | sVec4( 0.f, 0.f, 1.f, -1.f ), // far | 801 | sVec4( 0.f, 0.f, 1.f, -1.f ), // far |
802 | sVec4( 1.f, 0.f, 0.f, -1.f ), // left | 802 | sVec4( 1.f, 0.f, 0.f, -1.f ), // left |
803 | sVec4( -1.f, 0.f, 0.f, -1.f ), // right | 803 | sVec4( -1.f, 0.f, 0.f, -1.f ), // right |
804 | sVec4( 0.f, 1.f, 0.f, -1.f ), // bottom | 804 | sVec4( 0.f, 1.f, 0.f, -1.f ), // bottom |
805 | sVec4( 0.f, -1.f, 0.f, -1.f ) // top | 805 | sVec4( 0.f, -1.f, 0.f, -1.f ) // top |
806 | }; | 806 | }; |
807 | 807 | ||
808 | 808 | ||
809 | 809 | ||
810 | /* | 810 | /* |
811 | test a vertex if it's inside the standard frustum | 811 | test a vertex if it's inside the standard frustum |
812 | 812 | ||
813 | this is the generic one.. | 813 | this is the generic one.. |
814 | 814 | ||
815 | f32 dotPlane; | 815 | f32 dotPlane; |
816 | for ( u32 i = 0; i!= 6; ++i ) | 816 | for ( u32 i = 0; i!= 6; ++i ) |
817 | { | 817 | { |
818 | dotPlane = v->Pos.dotProduct ( NDCPlane[i] ); | 818 | dotPlane = v->Pos.dotProduct ( NDCPlane[i] ); |
819 | core::setbit_cond( flag, dotPlane <= 0.f, 1 << i ); | 819 | core::setbit_cond( flag, dotPlane <= 0.f, 1 << i ); |
820 | } | 820 | } |
821 | 821 | ||
822 | // this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w> | 822 | // this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w> |
823 | core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 ); | 823 | core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 ); |
824 | core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 ); | 824 | core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 ); |
825 | core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 ); | 825 | core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 ); |
826 | core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 ); | 826 | core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 ); |
827 | core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 ); | 827 | core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 ); |
828 | core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 ); | 828 | core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 ); |
829 | 829 | ||
830 | */ | 830 | */ |
831 | #ifdef IRRLICHT_FAST_MATH | 831 | #ifdef IRRLICHT_FAST_MATH |
832 | 832 | ||
833 | REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const | 833 | REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const |
834 | { | 834 | { |
835 | f32 test[6]; | 835 | f32 test[6]; |
836 | u32 flag; | 836 | u32 flag; |
837 | const f32 w = - v->Pos.w; | 837 | const f32 w = - v->Pos.w; |
838 | 838 | ||
839 | // a conditional move is needed....FCOMI ( but we don't have it ) | 839 | // a conditional move is needed....FCOMI ( but we don't have it ) |
840 | // so let the fpu calculate and write it back. | 840 | // so let the fpu calculate and write it back. |
841 | // cpu makes the compare, interleaving | 841 | // cpu makes the compare, interleaving |
842 | 842 | ||
843 | test[0] = v->Pos.z + w; | 843 | test[0] = v->Pos.z + w; |
844 | test[1] = -v->Pos.z + w; | 844 | test[1] = -v->Pos.z + w; |
845 | test[2] = v->Pos.x + w; | 845 | test[2] = v->Pos.x + w; |
846 | test[3] = -v->Pos.x + w; | 846 | test[3] = -v->Pos.x + w; |
847 | test[4] = v->Pos.y + w; | 847 | test[4] = v->Pos.y + w; |
848 | test[5] = -v->Pos.y + w; | 848 | test[5] = -v->Pos.y + w; |
849 | 849 | ||
850 | flag = (IR ( test[0] ) ) >> 31; | 850 | flag = (IR ( test[0] ) ) >> 31; |
851 | flag |= (IR ( test[1] ) & 0x80000000 ) >> 30; | 851 | flag |= (IR ( test[1] ) & 0x80000000 ) >> 30; |
852 | flag |= (IR ( test[2] ) & 0x80000000 ) >> 29; | 852 | flag |= (IR ( test[2] ) & 0x80000000 ) >> 29; |
853 | flag |= (IR ( test[3] ) & 0x80000000 ) >> 28; | 853 | flag |= (IR ( test[3] ) & 0x80000000 ) >> 28; |
854 | flag |= (IR ( test[4] ) & 0x80000000 ) >> 27; | 854 | flag |= (IR ( test[4] ) & 0x80000000 ) >> 27; |
855 | flag |= (IR ( test[5] ) & 0x80000000 ) >> 26; | 855 | flag |= (IR ( test[5] ) & 0x80000000 ) >> 26; |
856 | 856 | ||
857 | /* | 857 | /* |
858 | flag = F32_LOWER_EQUAL_0 ( test[0] ); | 858 | flag = F32_LOWER_EQUAL_0 ( test[0] ); |
859 | flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1; | 859 | flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1; |
860 | flag |= F32_LOWER_EQUAL_0 ( test[2] ) << 2; | 860 | flag |= F32_LOWER_EQUAL_0 ( test[2] ) << 2; |
861 | flag |= F32_LOWER_EQUAL_0 ( test[3] ) << 3; | 861 | flag |= F32_LOWER_EQUAL_0 ( test[3] ) << 3; |
862 | flag |= F32_LOWER_EQUAL_0 ( test[4] ) << 4; | 862 | flag |= F32_LOWER_EQUAL_0 ( test[4] ) << 4; |
863 | flag |= F32_LOWER_EQUAL_0 ( test[5] ) << 5; | 863 | flag |= F32_LOWER_EQUAL_0 ( test[5] ) << 5; |
864 | */ | 864 | */ |
865 | return flag; | 865 | return flag; |
866 | } | 866 | } |
867 | 867 | ||
868 | #else | 868 | #else |
869 | 869 | ||
870 | 870 | ||
871 | REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const | 871 | REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const |
872 | { | 872 | { |
873 | u32 flag = 0; | 873 | u32 flag = 0; |
874 | 874 | ||
875 | if ( v->Pos.z <= v->Pos.w ) flag |= 1; | 875 | if ( v->Pos.z <= v->Pos.w ) flag |= 1; |
876 | if (-v->Pos.z <= v->Pos.w ) flag |= 2; | 876 | if (-v->Pos.z <= v->Pos.w ) flag |= 2; |
877 | 877 | ||
878 | if ( v->Pos.x <= v->Pos.w ) flag |= 4; | 878 | if ( v->Pos.x <= v->Pos.w ) flag |= 4; |
879 | if (-v->Pos.x <= v->Pos.w ) flag |= 8; | 879 | if (-v->Pos.x <= v->Pos.w ) flag |= 8; |
880 | 880 | ||
881 | if ( v->Pos.y <= v->Pos.w ) flag |= 16; | 881 | if ( v->Pos.y <= v->Pos.w ) flag |= 16; |
882 | if (-v->Pos.y <= v->Pos.w ) flag |= 32; | 882 | if (-v->Pos.y <= v->Pos.w ) flag |= 32; |
883 | 883 | ||
884 | /* | 884 | /* |
885 | for ( u32 i = 0; i!= 6; ++i ) | 885 | for ( u32 i = 0; i!= 6; ++i ) |
886 | { | 886 | { |
887 | core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i ); | 887 | core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i ); |
888 | } | 888 | } |
889 | */ | 889 | */ |
890 | return flag; | 890 | return flag; |
891 | } | 891 | } |
892 | 892 | ||
893 | #endif // _MSC_VER | 893 | #endif // _MSC_VER |
894 | 894 | ||
895 | u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ) | 895 | u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ) |
896 | { | 896 | { |
897 | u32 outCount = 0; | 897 | u32 outCount = 0; |
898 | s4DVertex * out = dest; | 898 | s4DVertex * out = dest; |
899 | 899 | ||
900 | const s4DVertex * a; | 900 | const s4DVertex * a; |
901 | const s4DVertex * b = source; | 901 | const s4DVertex * b = source; |
902 | 902 | ||
903 | f32 bDotPlane; | 903 | f32 bDotPlane; |
904 | 904 | ||
905 | bDotPlane = b->Pos.dotProduct ( plane ); | 905 | bDotPlane = b->Pos.dotProduct ( plane ); |
906 | 906 | ||
907 | for( u32 i = 1; i < inCount + 1; ++i) | 907 | for( u32 i = 1; i < inCount + 1; ++i) |
908 | { | 908 | { |
909 | const s32 condition = i - inCount; | 909 | const s32 condition = i - inCount; |
910 | const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1; | 910 | const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1; |
911 | 911 | ||
912 | a = &source[ index ]; | 912 | a = &source[ index ]; |
913 | 913 | ||
914 | // current point inside | 914 | // current point inside |
915 | if ( a->Pos.dotProduct ( plane ) <= 0.f ) | 915 | if ( a->Pos.dotProduct ( plane ) <= 0.f ) |
916 | { | 916 | { |
917 | // last point outside | 917 | // last point outside |
918 | if ( F32_GREATER_0 ( bDotPlane ) ) | 918 | if ( F32_GREATER_0 ( bDotPlane ) ) |
919 | { | 919 | { |
920 | // intersect line segment with plane | 920 | // intersect line segment with plane |
921 | out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); | 921 | out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); |
922 | out += 2; | 922 | out += 2; |
923 | outCount += 1; | 923 | outCount += 1; |
924 | } | 924 | } |
925 | 925 | ||
926 | // copy current to out | 926 | // copy current to out |
927 | //*out = *a; | 927 | //*out = *a; |
928 | irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 ); | 928 | irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 ); |
929 | b = out; | 929 | b = out; |
930 | 930 | ||
931 | out += 2; | 931 | out += 2; |
932 | outCount += 1; | 932 | outCount += 1; |
933 | } | 933 | } |
934 | else | 934 | else |
935 | { | 935 | { |
936 | // current point outside | 936 | // current point outside |
937 | 937 | ||
938 | if ( F32_LOWER_EQUAL_0 ( bDotPlane ) ) | 938 | if ( F32_LOWER_EQUAL_0 ( bDotPlane ) ) |
939 | { | 939 | { |
940 | // previous was inside | 940 | // previous was inside |
941 | // intersect line segment with plane | 941 | // intersect line segment with plane |
942 | out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); | 942 | out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); |
943 | out += 2; | 943 | out += 2; |
944 | outCount += 1; | 944 | outCount += 1; |
945 | } | 945 | } |
946 | // pointer | 946 | // pointer |
947 | b = a; | 947 | b = a; |
948 | } | 948 | } |
949 | 949 | ||
950 | bDotPlane = b->Pos.dotProduct ( plane ); | 950 | bDotPlane = b->Pos.dotProduct ( plane ); |
951 | 951 | ||
952 | } | 952 | } |
953 | 953 | ||
954 | return outCount; | 954 | return outCount; |
955 | } | 955 | } |
956 | 956 | ||
957 | 957 | ||
958 | u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn ) | 958 | u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn ) |
959 | { | 959 | { |
960 | u32 vOut = vIn; | 960 | u32 vOut = vIn; |
961 | 961 | ||
962 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut; | 962 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut; |
963 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut; | 963 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut; |
964 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut; | 964 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut; |
965 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut; | 965 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut; |
966 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut; | 966 | vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut; |
967 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] ); | 967 | vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] ); |
968 | return vOut; | 968 | return vOut; |
969 | } | 969 | } |
970 | 970 | ||
971 | /*! | 971 | /*! |
972 | Part I: | 972 | Part I: |
973 | apply Clip Scale matrix | 973 | apply Clip Scale matrix |
974 | From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC ) | 974 | From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC ) |
975 | 975 | ||
976 | Part II: | 976 | Part II: |
977 | Project homogeneous vector | 977 | Project homogeneous vector |
978 | homogeneous to non-homogenous coordinates ( dividebyW ) | 978 | homogeneous to non-homogenous coordinates ( dividebyW ) |
979 | 979 | ||
980 | Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A ) | 980 | Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A ) |
981 | Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w ) | 981 | Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w ) |
982 | 982 | ||
983 | 983 | ||
984 | replace w/w by 1/w | 984 | replace w/w by 1/w |
985 | */ | 985 | */ |
986 | inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const | 986 | inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const |
987 | { | 987 | { |
988 | u32 g; | 988 | u32 g; |
989 | 989 | ||
990 | for ( g = 0; g != vIn; g += 2 ) | 990 | for ( g = 0; g != vIn; g += 2 ) |
991 | { | 991 | { |
992 | if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) | 992 | if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) |
993 | continue; | 993 | continue; |
994 | 994 | ||
995 | dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; | 995 | dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; |
996 | 996 | ||
997 | const f32 w = source[g].Pos.w; | 997 | const f32 w = source[g].Pos.w; |
998 | const f32 iw = core::reciprocal ( w ); | 998 | const f32 iw = core::reciprocal ( w ); |
999 | 999 | ||
1000 | // to device coordinates | 1000 | // to device coordinates |
1001 | dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] ); | 1001 | dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] ); |
1002 | dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] ); | 1002 | dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] ); |
1003 | 1003 | ||
1004 | #ifndef SOFTWARE_DRIVER_2_USE_WBUFFER | 1004 | #ifndef SOFTWARE_DRIVER_2_USE_WBUFFER |
1005 | dest[g].Pos.z = iw * source[g].Pos.z; | 1005 | dest[g].Pos.z = iw * source[g].Pos.z; |
1006 | #endif | 1006 | #endif |
1007 | 1007 | ||
1008 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR | 1008 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR |
1009 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT | 1009 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT |
1010 | dest[g].Color[0] = source[g].Color[0] * iw; | 1010 | dest[g].Color[0] = source[g].Color[0] * iw; |
1011 | #else | 1011 | #else |
1012 | dest[g].Color[0] = source[g].Color[0]; | 1012 | dest[g].Color[0] = source[g].Color[0]; |
1013 | #endif | 1013 | #endif |
1014 | 1014 | ||
1015 | #endif | 1015 | #endif |
1016 | dest[g].LightTangent[0] = source[g].LightTangent[0] * iw; | 1016 | dest[g].LightTangent[0] = source[g].LightTangent[0] * iw; |
1017 | dest[g].Pos.w = iw; | 1017 | dest[g].Pos.w = iw; |
1018 | } | 1018 | } |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | 1021 | ||
1022 | inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const | 1022 | inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const |
1023 | { | 1023 | { |
1024 | u32 g; | 1024 | u32 g; |
1025 | 1025 | ||
1026 | for ( g = 0; g != size; g += 1 ) | 1026 | for ( g = 0; g != size; g += 1 ) |
1027 | { | 1027 | { |
1028 | s4DVertex * a = (s4DVertex*) v[g]; | 1028 | s4DVertex * a = (s4DVertex*) v[g]; |
1029 | 1029 | ||
1030 | if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) | 1030 | if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) |
1031 | continue; | 1031 | continue; |
1032 | 1032 | ||
1033 | a[1].flag = a->flag | VERTEX4D_PROJECTED; | 1033 | a[1].flag = a->flag | VERTEX4D_PROJECTED; |
1034 | 1034 | ||
1035 | // project homogenous vertex, store 1/w | 1035 | // project homogenous vertex, store 1/w |
1036 | const f32 w = a->Pos.w; | 1036 | const f32 w = a->Pos.w; |
1037 | const f32 iw = core::reciprocal ( w ); | 1037 | const f32 iw = core::reciprocal ( w ); |
1038 | 1038 | ||
1039 | // to device coordinates | 1039 | // to device coordinates |
1040 | const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer(); | 1040 | const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer(); |
1041 | a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] ); | 1041 | a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] ); |
1042 | a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] ); | 1042 | a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] ); |
1043 | 1043 | ||
1044 | #ifndef SOFTWARE_DRIVER_2_USE_WBUFFER | 1044 | #ifndef SOFTWARE_DRIVER_2_USE_WBUFFER |
1045 | a[1].Pos.z = a->Pos.z * iw; | 1045 | a[1].Pos.z = a->Pos.z * iw; |
1046 | #endif | 1046 | #endif |
1047 | 1047 | ||
1048 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR | 1048 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR |
1049 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT | 1049 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT |
1050 | a[1].Color[0] = a->Color[0] * iw; | 1050 | a[1].Color[0] = a->Color[0] * iw; |
1051 | #else | 1051 | #else |
1052 | a[1].Color[0] = a->Color[0]; | 1052 | a[1].Color[0] = a->Color[0]; |
1053 | #endif | 1053 | #endif |
1054 | #endif | 1054 | #endif |
1055 | 1055 | ||
1056 | a[1].LightTangent[0] = a[0].LightTangent[0] * iw; | 1056 | a[1].LightTangent[0] = a[0].LightTangent[0] * iw; |
1057 | a[1].Pos.w = iw; | 1057 | a[1].Pos.w = iw; |
1058 | 1058 | ||
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | 1063 | ||
1064 | /*! | 1064 | /*! |
1065 | crossproduct in projected 2D -> screen area triangle | 1065 | crossproduct in projected 2D -> screen area triangle |
1066 | */ | 1066 | */ |
1067 | inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const | 1067 | inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const |
1068 | { | 1068 | { |
1069 | return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) - | 1069 | return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) - |
1070 | ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) ); | 1070 | ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) ); |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | 1073 | ||
1074 | /*! | 1074 | /*! |
1075 | */ | 1075 | */ |
1076 | inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const | 1076 | inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const |
1077 | { | 1077 | { |
1078 | f32 z; | 1078 | f32 z; |
1079 | 1079 | ||
1080 | z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) ) | 1080 | z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) ) |
1081 | - ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) ); | 1081 | - ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) ); |
1082 | 1082 | ||
1083 | return MAT_TEXTURE ( tex )->getLODFactor ( z ); | 1083 | return MAT_TEXTURE ( tex )->getLODFactor ( z ); |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /*! | 1086 | /*! |
1087 | crossproduct in projected 2D | 1087 | crossproduct in projected 2D |
1088 | */ | 1088 | */ |
1089 | inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const | 1089 | inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const |
1090 | { | 1090 | { |
1091 | return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) - | 1091 | return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) - |
1092 | ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) ); | 1092 | ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) ); |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | /*! | 1095 | /*! |
1096 | */ | 1096 | */ |
1097 | inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const | 1097 | inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const |
1098 | { | 1098 | { |
1099 | f32 z; | 1099 | f32 z; |
1100 | z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) ) | 1100 | z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) ) |
1101 | - ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) ); | 1101 | - ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) ); |
1102 | 1102 | ||
1103 | return MAT_TEXTURE ( tex )->getLODFactor ( z ); | 1103 | return MAT_TEXTURE ( tex )->getLODFactor ( z ); |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | 1106 | ||
1107 | /*! | 1107 | /*! |
1108 | */ | 1108 | */ |
1109 | inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const | 1109 | inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const |
1110 | { | 1110 | { |
1111 | f32 f[2]; | 1111 | f32 f[2]; |
1112 | 1112 | ||
1113 | f[0] = (f32) texSize.Width - 0.25f; | 1113 | f[0] = (f32) texSize.Width - 0.25f; |
1114 | f[1] = (f32) texSize.Height - 0.25f; | 1114 | f[1] = (f32) texSize.Height - 0.25f; |
1115 | 1115 | ||
1116 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT | 1116 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT |
1117 | for ( u32 g = 0; g != vIn; g += 2 ) | 1117 | for ( u32 g = 0; g != vIn; g += 2 ) |
1118 | { | 1118 | { |
1119 | (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0]; | 1119 | (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0]; |
1120 | (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1]; | 1120 | (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1]; |
1121 | } | 1121 | } |
1122 | #else | 1122 | #else |
1123 | for ( u32 g = 0; g != vIn; g += 2 ) | 1123 | for ( u32 g = 0; g != vIn; g += 2 ) |
1124 | { | 1124 | { |
1125 | (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0]; | 1125 | (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0]; |
1126 | (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1]; | 1126 | (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1]; |
1127 | } | 1127 | } |
1128 | #endif | 1128 | #endif |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const | 1131 | inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const |
1132 | { | 1132 | { |
1133 | f32 f[2]; | 1133 | f32 f[2]; |
1134 | 1134 | ||
1135 | f[0] = (f32) texSize.Width - 0.25f; | 1135 | f[0] = (f32) texSize.Width - 0.25f; |
1136 | f[1] = (f32) texSize.Height - 0.25f; | 1136 | f[1] = (f32) texSize.Height - 0.25f; |
1137 | 1137 | ||
1138 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT | 1138 | #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT |
1139 | (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0]; | 1139 | (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0]; |
1140 | (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1]; | 1140 | (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1]; |
1141 | 1141 | ||
1142 | (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0]; | 1142 | (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0]; |
1143 | (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1]; | 1143 | (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1]; |
1144 | 1144 | ||
1145 | (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0]; | 1145 | (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0]; |
1146 | (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1]; | 1146 | (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1]; |
1147 | 1147 | ||
1148 | #else | 1148 | #else |
1149 | (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0]; | 1149 | (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0]; |
1150 | (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1]; | 1150 | (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1]; |
1151 | 1151 | ||
1152 | (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0]; | 1152 | (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0]; |
1153 | (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1]; | 1153 | (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1]; |
1154 | 1154 | ||
1155 | (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0]; | 1155 | (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0]; |
1156 | (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1]; | 1156 | (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1]; |
1157 | #endif | 1157 | #endif |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | // Vertex Cache | 1160 | // Vertex Cache |
1161 | const SVSize CBurningVideoDriver::vSize[] = | 1161 | const SVSize CBurningVideoDriver::vSize[] = |
1162 | { | 1162 | { |
1163 | { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 }, | 1163 | { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 }, |
1164 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 }, | 1164 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 }, |
1165 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 }, | 1165 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 }, |
1166 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map | 1166 | { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map |
1167 | { 0, sizeof(f32) * 3, 0 }, // core::vector3df* | 1167 | { 0, sizeof(f32) * 3, 0 }, // core::vector3df* |
1168 | }; | 1168 | }; |
1169 | 1169 | ||
1170 | 1170 | ||
1171 | 1171 | ||
1172 | /*! | 1172 | /*! |
1173 | fill a cache line with transformed, light and clipp test triangles | 1173 | fill a cache line with transformed, light and clipp test triangles |
1174 | */ | 1174 | */ |
1175 | void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex) | 1175 | void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex) |
1176 | { | 1176 | { |
1177 | u8 * source; | 1177 | u8 * source; |
1178 | s4DVertex *dest; | 1178 | s4DVertex *dest; |
1179 | 1179 | ||
1180 | source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch ); | 1180 | source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch ); |
1181 | 1181 | ||
1182 | // it's a look ahead so we never hit it.. | 1182 | // it's a look ahead so we never hit it.. |
1183 | // but give priority... | 1183 | // but give priority... |
1184 | //VertexCache.info[ destIndex ].hit = hitCount; | 1184 | //VertexCache.info[ destIndex ].hit = hitCount; |
1185 | 1185 | ||
1186 | // store info | 1186 | // store info |
1187 | VertexCache.info[ destIndex ].index = sourceIndex; | 1187 | VertexCache.info[ destIndex ].index = sourceIndex; |
1188 | VertexCache.info[ destIndex ].hit = 0; | 1188 | VertexCache.info[ destIndex ].hit = 0; |
1189 | 1189 | ||
1190 | // destination Vertex | 1190 | // destination Vertex |
1191 | dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); | 1191 | dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); |
1192 | 1192 | ||
1193 | // transform Model * World * Camera * Projection * NDCSpace matrix | 1193 | // transform Model * World * Camera * Projection * NDCSpace matrix |
1194 | const S3DVertex *base = ((S3DVertex*) source ); | 1194 | const S3DVertex *base = ((S3DVertex*) source ); |
1195 | Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos ); | 1195 | Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos ); |
1196 | 1196 | ||
1197 | //mhm ;-) maybe no goto | 1197 | //mhm ;-) maybe no goto |
1198 | if ( VertexCache.vType == 4 ) goto clipandproject; | 1198 | if ( VertexCache.vType == 4 ) goto clipandproject; |
1199 | 1199 | ||
1200 | 1200 | ||
1201 | #if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) | 1201 | #if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) |
1202 | 1202 | ||
1203 | // vertex normal in light space | 1203 | // vertex normal in light space |
1204 | if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) ) | 1204 | if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) ) |
1205 | { | 1205 | { |
1206 | if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) | 1206 | if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) |
1207 | { | 1207 | { |
1208 | LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f ); | 1208 | LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f ); |
1209 | LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f ); | 1209 | LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f ); |
1210 | } | 1210 | } |
1211 | else | 1211 | else |
1212 | { | 1212 | { |
1213 | Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal ); | 1213 | Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal ); |
1214 | 1214 | ||
1215 | // vertex in light space | 1215 | // vertex in light space |
1216 | if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) ) | 1216 | if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) ) |
1217 | Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos ); | 1217 | Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos ); |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | if ( LightSpace.Flags & NORMALIZE ) | 1220 | if ( LightSpace.Flags & NORMALIZE ) |
1221 | LightSpace.normal.normalize_xyz(); | 1221 | LightSpace.normal.normalize_xyz(); |
1222 | 1222 | ||
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | #endif | 1225 | #endif |
1226 | 1226 | ||
1227 | #if defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR ) | 1227 | #if defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR ) |
1228 | // apply lighting model | 1228 | // apply lighting model |
1229 | #if defined (SOFTWARE_DRIVER_2_LIGHTING) | 1229 | #if defined (SOFTWARE_DRIVER_2_LIGHTING) |
1230 | if ( Material.org.Lighting ) | 1230 | if ( Material.org.Lighting ) |
1231 | { | 1231 | { |
1232 | lightVertex ( dest, base->Color.color ); | 1232 | lightVertex ( dest, base->Color.color ); |
1233 | } | 1233 | } |
1234 | else | 1234 | else |
1235 | { | 1235 | { |
1236 | dest->Color[0].setA8R8G8B8 ( base->Color.color ); | 1236 | dest->Color[0].setA8R8G8B8 ( base->Color.color ); |
1237 | } | 1237 | } |
1238 | #else | 1238 | #else |
1239 | dest->Color[0].setA8R8G8B8 ( base->Color.color ); | 1239 | dest->Color[0].setA8R8G8B8 ( base->Color.color ); |
1240 | #endif | 1240 | #endif |
1241 | #endif | 1241 | #endif |
1242 | 1242 | ||
1243 | // Texture Transform | 1243 | // Texture Transform |
1244 | #if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) | 1244 | #if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) |
1245 | irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, | 1245 | irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, |
1246 | vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) | 1246 | vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) |
1247 | ); | 1247 | ); |
1248 | #else | 1248 | #else |
1249 | 1249 | ||
1250 | if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) ) | 1250 | if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) ) |
1251 | { | 1251 | { |
1252 | irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, | 1252 | irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, |
1253 | vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) | 1253 | vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) |
1254 | ); | 1254 | ); |
1255 | } | 1255 | } |
1256 | else | 1256 | else |
1257 | { | 1257 | { |
1258 | /* | 1258 | /* |
1259 | Generate texture coordinates as linear functions so that: | 1259 | Generate texture coordinates as linear functions so that: |
1260 | u = Ux*x + Uy*y + Uz*z + Uw | 1260 | u = Ux*x + Uy*y + Uz*z + Uw |
1261 | v = Vx*x + Vy*y + Vz*z + Vw | 1261 | v = Vx*x + Vy*y + Vz*z + Vw |
1262 | The matrix M for this case is: | 1262 | The matrix M for this case is: |
1263 | Ux Vx 0 0 | 1263 | Ux Vx 0 0 |
1264 | Uy Vy 0 0 | 1264 | Uy Vy 0 0 |
1265 | Uz Vz 0 0 | 1265 | Uz Vz 0 0 |
1266 | Uw Vw 0 0 | 1266 | Uw Vw 0 0 |
1267 | */ | 1267 | */ |
1268 | 1268 | ||
1269 | u32 t; | 1269 | u32 t; |
1270 | sVec4 n; | 1270 | sVec4 n; |
1271 | sVec2 srcT; | 1271 | sVec2 srcT; |
1272 | 1272 | ||
1273 | for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t ) | 1273 | for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t ) |
1274 | { | 1274 | { |
1275 | const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ]; | 1275 | const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ]; |
1276 | 1276 | ||
1277 | // texgen | 1277 | // texgen |
1278 | if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) ) | 1278 | if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) ) |
1279 | { | 1279 | { |
1280 | n.x = LightSpace.campos.x - LightSpace.vertex.x; | 1280 | n.x = LightSpace.campos.x - LightSpace.vertex.x; |
1281 | n.y = LightSpace.campos.x - LightSpace.vertex.y; | 1281 | n.y = LightSpace.campos.x - LightSpace.vertex.y; |
1282 | n.z = LightSpace.campos.x - LightSpace.vertex.z; | 1282 | n.z = LightSpace.campos.x - LightSpace.vertex.z; |
1283 | n.normalize_xyz(); | 1283 | n.normalize_xyz(); |
1284 | n.x += LightSpace.normal.x; | 1284 | n.x += LightSpace.normal.x; |
1285 | n.y += LightSpace.normal.y; | 1285 | n.y += LightSpace.normal.y; |
1286 | n.z += LightSpace.normal.z; | 1286 | n.z += LightSpace.normal.z; |
1287 | n.normalize_xyz(); | 1287 | n.normalize_xyz(); |
1288 | 1288 | ||
1289 | const f32 *view = Transformation[ETS_VIEW].pointer(); | 1289 | const f32 *view = Transformation[ETS_VIEW].pointer(); |
1290 | 1290 | ||
1291 | if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION ) | 1291 | if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION ) |
1292 | { | 1292 | { |
1293 | srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] )); | 1293 | srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] )); |
1294 | srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] )); | 1294 | srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] )); |
1295 | } | 1295 | } |
1296 | else | 1296 | else |
1297 | { | 1297 | { |
1298 | srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] )); | 1298 | srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] )); |
1299 | srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] )); | 1299 | srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] )); |
1300 | } | 1300 | } |
1301 | } | 1301 | } |
1302 | else | 1302 | else |
1303 | { | 1303 | { |
1304 | irr::memcpy32_small ( &srcT,(&base->TCoords) + t, | 1304 | irr::memcpy32_small ( &srcT,(&base->TCoords) + t, |
1305 | sizeof ( f32 ) * 2 ); | 1305 | sizeof ( f32 ) * 2 ); |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | switch ( Material.org.TextureLayer[t].TextureWrapU ) | 1308 | switch ( Material.org.TextureLayer[t].TextureWrapU ) |
1309 | { | 1309 | { |
1310 | case ETC_CLAMP: | 1310 | case ETC_CLAMP: |
1311 | case ETC_CLAMP_TO_EDGE: | 1311 | case ETC_CLAMP_TO_EDGE: |
1312 | case ETC_CLAMP_TO_BORDER: | 1312 | case ETC_CLAMP_TO_BORDER: |
1313 | dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); | 1313 | dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); |
1314 | break; | 1314 | break; |
1315 | case ETC_MIRROR: | 1315 | case ETC_MIRROR: |
1316 | dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; | 1316 | dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; |
1317 | if (core::fract(dest->Tex[t].x)>0.5f) | 1317 | if (core::fract(dest->Tex[t].x)>0.5f) |
1318 | dest->Tex[t].x=1.f-dest->Tex[t].x; | 1318 | dest->Tex[t].x=1.f-dest->Tex[t].x; |
1319 | break; | 1319 | break; |
1320 | case ETC_MIRROR_CLAMP: | 1320 | case ETC_MIRROR_CLAMP: |
1321 | case ETC_MIRROR_CLAMP_TO_EDGE: | 1321 | case ETC_MIRROR_CLAMP_TO_EDGE: |
1322 | case ETC_MIRROR_CLAMP_TO_BORDER: | 1322 | case ETC_MIRROR_CLAMP_TO_BORDER: |
1323 | dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); | 1323 | dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); |
1324 | if (core::fract(dest->Tex[t].x)>0.5f) | 1324 | if (core::fract(dest->Tex[t].x)>0.5f) |
1325 | dest->Tex[t].x=1.f-dest->Tex[t].x; | 1325 | dest->Tex[t].x=1.f-dest->Tex[t].x; |
1326 | break; | 1326 | break; |
1327 | case ETC_REPEAT: | 1327 | case ETC_REPEAT: |
1328 | default: | 1328 | default: |
1329 | dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; | 1329 | dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; |
1330 | break; | 1330 | break; |
1331 | } | 1331 | } |
1332 | switch ( Material.org.TextureLayer[t].TextureWrapV ) | 1332 | switch ( Material.org.TextureLayer[t].TextureWrapV ) |
1333 | { | 1333 | { |
1334 | case ETC_CLAMP: | 1334 | case ETC_CLAMP: |
1335 | case ETC_CLAMP_TO_EDGE: | 1335 | case ETC_CLAMP_TO_EDGE: |
1336 | case ETC_CLAMP_TO_BORDER: | 1336 | case ETC_CLAMP_TO_BORDER: |
1337 | dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); | 1337 | dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); |
1338 | break; | 1338 | break; |
1339 | case ETC_MIRROR: | 1339 | case ETC_MIRROR: |
1340 | dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; | 1340 | dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; |
1341 | if (core::fract(dest->Tex[t].y)>0.5f) | 1341 | if (core::fract(dest->Tex[t].y)>0.5f) |
1342 | dest->Tex[t].y=1.f-dest->Tex[t].y; | 1342 | dest->Tex[t].y=1.f-dest->Tex[t].y; |
1343 | break; | 1343 | break; |
1344 | case ETC_MIRROR_CLAMP: | 1344 | case ETC_MIRROR_CLAMP: |
1345 | case ETC_MIRROR_CLAMP_TO_EDGE: | 1345 | case ETC_MIRROR_CLAMP_TO_EDGE: |
1346 | case ETC_MIRROR_CLAMP_TO_BORDER: | 1346 | case ETC_MIRROR_CLAMP_TO_BORDER: |
1347 | dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); | 1347 | dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); |
1348 | if (core::fract(dest->Tex[t].y)>0.5f) | 1348 | if (core::fract(dest->Tex[t].y)>0.5f) |
1349 | dest->Tex[t].y=1.f-dest->Tex[t].y; | 1349 | dest->Tex[t].y=1.f-dest->Tex[t].y; |
1350 | break; | 1350 | break; |
1351 | case ETC_REPEAT: | 1351 | case ETC_REPEAT: |
1352 | default: | 1352 | default: |
1353 | dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; | 1353 | dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; |
1354 | break; | 1354 | break; |
1355 | } | 1355 | } |
1356 | } | 1356 | } |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | #if 0 | 1359 | #if 0 |
1360 | // tangent space light vector, emboss | 1360 | // tangent space light vector, emboss |
1361 | if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) | 1361 | if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) |
1362 | { | 1362 | { |
1363 | const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); | 1363 | const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); |
1364 | const SBurningShaderLight &light = LightSpace.Light[0]; | 1364 | const SBurningShaderLight &light = LightSpace.Light[0]; |
1365 | 1365 | ||
1366 | sVec4 vp; | 1366 | sVec4 vp; |
1367 | 1367 | ||
1368 | vp.x = light.pos.x - LightSpace.vertex.x; | 1368 | vp.x = light.pos.x - LightSpace.vertex.x; |
1369 | vp.y = light.pos.y - LightSpace.vertex.y; | 1369 | vp.y = light.pos.y - LightSpace.vertex.y; |
1370 | vp.z = light.pos.z - LightSpace.vertex.z; | 1370 | vp.z = light.pos.z - LightSpace.vertex.z; |
1371 | 1371 | ||
1372 | vp.normalize_xyz(); | 1372 | vp.normalize_xyz(); |
1373 | 1373 | ||
1374 | LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z; | 1374 | LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z; |
1375 | LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z; | 1375 | LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z; |
1376 | //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z; | 1376 | //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z; |
1377 | LightSpace.tangent.z = 0.f; | 1377 | LightSpace.tangent.z = 0.f; |
1378 | LightSpace.tangent.normalize_xyz(); | 1378 | LightSpace.tangent.normalize_xyz(); |
1379 | 1379 | ||
1380 | f32 scale = 1.f / 128.f; | 1380 | f32 scale = 1.f / 128.f; |
1381 | if ( Material.org.MaterialTypeParam > 0.f ) | 1381 | if ( Material.org.MaterialTypeParam > 0.f ) |
1382 | scale = Material.org.MaterialTypeParam; | 1382 | scale = Material.org.MaterialTypeParam; |
1383 | 1383 | ||
1384 | // emboss, shift coordinates | 1384 | // emboss, shift coordinates |
1385 | dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale; | 1385 | dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale; |
1386 | dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale; | 1386 | dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale; |
1387 | //dest->Tex[1].z = LightSpace.tangent.z * scale; | 1387 | //dest->Tex[1].z = LightSpace.tangent.z * scale; |
1388 | } | 1388 | } |
1389 | #endif | 1389 | #endif |
1390 | 1390 | ||
1391 | if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) | 1391 | if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) |
1392 | { | 1392 | { |
1393 | const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); | 1393 | const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); |
1394 | 1394 | ||
1395 | sVec4 vp; | 1395 | sVec4 vp; |
1396 | 1396 | ||
1397 | dest->LightTangent[0].x = 0.f; | 1397 | dest->LightTangent[0].x = 0.f; |
1398 | dest->LightTangent[0].y = 0.f; | 1398 | dest->LightTangent[0].y = 0.f; |
1399 | dest->LightTangent[0].z = 0.f; | 1399 | dest->LightTangent[0].z = 0.f; |
1400 | for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i ) | 1400 | for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i ) |
1401 | { | 1401 | { |
1402 | const SBurningShaderLight &light = LightSpace.Light[i]; | 1402 | const SBurningShaderLight &light = LightSpace.Light[i]; |
1403 | 1403 | ||
1404 | if ( !light.LightIsOn ) | 1404 | if ( !light.LightIsOn ) |
1405 | continue; | 1405 | continue; |
1406 | 1406 | ||
1407 | vp.x = light.pos.x - LightSpace.vertex.x; | 1407 | vp.x = light.pos.x - LightSpace.vertex.x; |
1408 | vp.y = light.pos.y - LightSpace.vertex.y; | 1408 | vp.y = light.pos.y - LightSpace.vertex.y; |
1409 | vp.z = light.pos.z - LightSpace.vertex.z; | 1409 | vp.z = light.pos.z - LightSpace.vertex.z; |
1410 | 1410 | ||
1411 | /* | 1411 | /* |
1412 | vp.x = light.pos_objectspace.x - base->Pos.X; | 1412 | vp.x = light.pos_objectspace.x - base->Pos.X; |
1413 | vp.y = light.pos_objectspace.y - base->Pos.Y; | 1413 | vp.y = light.pos_objectspace.y - base->Pos.Y; |
1414 | vp.z = light.pos_objectspace.z - base->Pos.Z; | 1414 | vp.z = light.pos_objectspace.z - base->Pos.Z; |
1415 | */ | 1415 | */ |
1416 | 1416 | ||
1417 | vp.normalize_xyz(); | 1417 | vp.normalize_xyz(); |
1418 | 1418 | ||
1419 | 1419 | ||
1420 | // transform by tangent matrix | 1420 | // transform by tangent matrix |
1421 | sVec3 l; | 1421 | sVec3 l; |
1422 | #if 1 | 1422 | #if 1 |
1423 | l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z ); | 1423 | l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z ); |
1424 | l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z ); | 1424 | l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z ); |
1425 | l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z ); | 1425 | l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z ); |
1426 | #else | 1426 | #else |
1427 | l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X ); | 1427 | l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X ); |
1428 | l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y ); | 1428 | l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y ); |
1429 | l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z ); | 1429 | l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z ); |
1430 | #endif | 1430 | #endif |
1431 | 1431 | ||
1432 | 1432 | ||
1433 | /* | 1433 | /* |
1434 | f32 scale = 1.f / 128.f; | 1434 | f32 scale = 1.f / 128.f; |
1435 | scale /= dest->LightTangent[0].b; | 1435 | scale /= dest->LightTangent[0].b; |
1436 | 1436 | ||
1437 | // emboss, shift coordinates | 1437 | // emboss, shift coordinates |
1438 | dest->Tex[1].x = dest->Tex[0].x + l.r * scale; | 1438 | dest->Tex[1].x = dest->Tex[0].x + l.r * scale; |
1439 | dest->Tex[1].y = dest->Tex[0].y + l.g * scale; | 1439 | dest->Tex[1].y = dest->Tex[0].y + l.g * scale; |
1440 | */ | 1440 | */ |
1441 | dest->Tex[1].x = dest->Tex[0].x; | 1441 | dest->Tex[1].x = dest->Tex[0].x; |
1442 | dest->Tex[1].y = dest->Tex[0].y; | 1442 | dest->Tex[1].y = dest->Tex[0].y; |
1443 | 1443 | ||
1444 | // scale bias | 1444 | // scale bias |
1445 | dest->LightTangent[0].x += l.x; | 1445 | dest->LightTangent[0].x += l.x; |
1446 | dest->LightTangent[0].y += l.y; | 1446 | dest->LightTangent[0].y += l.y; |
1447 | dest->LightTangent[0].z += l.z; | 1447 | dest->LightTangent[0].z += l.z; |
1448 | } | 1448 | } |
1449 | dest->LightTangent[0].setLength ( 0.5f ); | 1449 | dest->LightTangent[0].setLength ( 0.5f ); |
1450 | dest->LightTangent[0].x += 0.5f; | 1450 | dest->LightTangent[0].x += 0.5f; |
1451 | dest->LightTangent[0].y += 0.5f; | 1451 | dest->LightTangent[0].y += 0.5f; |
1452 | dest->LightTangent[0].z += 0.5f; | 1452 | dest->LightTangent[0].z += 0.5f; |
1453 | } | 1453 | } |
1454 | 1454 | ||
1455 | 1455 | ||
1456 | #endif | 1456 | #endif |
1457 | 1457 | ||
1458 | clipandproject: | 1458 | clipandproject: |
1459 | dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format; | 1459 | dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format; |
1460 | 1460 | ||
1461 | // test vertex | 1461 | // test vertex |
1462 | dest[0].flag |= clipToFrustumTest ( dest); | 1462 | dest[0].flag |= clipToFrustumTest ( dest); |
1463 | 1463 | ||
1464 | // to DC Space, project homogenous vertex | 1464 | // to DC Space, project homogenous vertex |
1465 | if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) | 1465 | if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) |
1466 | { | 1466 | { |
1467 | ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 ); | 1467 | ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 ); |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | //return dest; | 1470 | //return dest; |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | // | 1473 | // |
1474 | 1474 | ||
1475 | REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) | 1475 | REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) |
1476 | { | 1476 | { |
1477 | for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i ) | 1477 | for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i ) |
1478 | { | 1478 | { |
1479 | if ( VertexCache.info[ i ].index == sourceIndex ) | 1479 | if ( VertexCache.info[ i ].index == sourceIndex ) |
1480 | { | 1480 | { |
1481 | return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); | 1481 | return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); |
1482 | } | 1482 | } |
1483 | } | 1483 | } |
1484 | return 0; | 1484 | return 0; |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | 1487 | ||
1488 | /* | 1488 | /* |
1489 | Cache based on linear walk indices | 1489 | Cache based on linear walk indices |
1490 | fill blockwise on the next 16(Cache_Size) unique vertices in indexlist | 1490 | fill blockwise on the next 16(Cache_Size) unique vertices in indexlist |
1491 | merge the next 16 vertices with the current | 1491 | merge the next 16 vertices with the current |
1492 | */ | 1492 | */ |
1493 | REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face) | 1493 | REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face) |
1494 | { | 1494 | { |
1495 | SCacheInfo info[VERTEXCACHE_ELEMENT]; | 1495 | SCacheInfo info[VERTEXCACHE_ELEMENT]; |
1496 | 1496 | ||
1497 | // next primitive must be complete in cache | 1497 | // next primitive must be complete in cache |
1498 | if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 && | 1498 | if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 && |
1499 | VertexCache.indicesIndex < VertexCache.indexCount | 1499 | VertexCache.indicesIndex < VertexCache.indexCount |
1500 | ) | 1500 | ) |
1501 | { | 1501 | { |
1502 | // rewind to start of primitive | 1502 | // rewind to start of primitive |
1503 | VertexCache.indicesIndex = VertexCache.indicesRun; | 1503 | VertexCache.indicesIndex = VertexCache.indicesRun; |
1504 | 1504 | ||
1505 | irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) ); | 1505 | irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) ); |
1506 | 1506 | ||
1507 | // get the next unique vertices cache line | 1507 | // get the next unique vertices cache line |
1508 | u32 fillIndex = 0; | 1508 | u32 fillIndex = 0; |
1509 | u32 dIndex; | 1509 | u32 dIndex; |
1510 | u32 i; | 1510 | u32 i; |
1511 | u32 sourceIndex; | 1511 | u32 sourceIndex; |
1512 | 1512 | ||
1513 | while ( VertexCache.indicesIndex < VertexCache.indexCount && | 1513 | while ( VertexCache.indicesIndex < VertexCache.indexCount && |
1514 | fillIndex < VERTEXCACHE_ELEMENT | 1514 | fillIndex < VERTEXCACHE_ELEMENT |
1515 | ) | 1515 | ) |
1516 | { | 1516 | { |
1517 | switch ( VertexCache.iType ) | 1517 | switch ( VertexCache.iType ) |
1518 | { | 1518 | { |
1519 | case 1: | 1519 | case 1: |
1520 | sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ]; | 1520 | sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ]; |
1521 | break; | 1521 | break; |
1522 | case 2: | 1522 | case 2: |
1523 | sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ]; | 1523 | sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ]; |
1524 | break; | 1524 | break; |
1525 | case 4: | 1525 | case 4: |
1526 | sourceIndex = VertexCache.indicesIndex; | 1526 | sourceIndex = VertexCache.indicesIndex; |
1527 | break; | 1527 | break; |
1528 | } | 1528 | } |
1529 | 1529 | ||
1530 | VertexCache.indicesIndex += 1; | 1530 | VertexCache.indicesIndex += 1; |
1531 | 1531 | ||
1532 | // if not exist, push back | 1532 | // if not exist, push back |
1533 | s32 exist = 0; | 1533 | s32 exist = 0; |
1534 | for ( dIndex = 0; dIndex < fillIndex; ++dIndex ) | 1534 | for ( dIndex = 0; dIndex < fillIndex; ++dIndex ) |
1535 | { | 1535 | { |
1536 | if ( info[ dIndex ].index == sourceIndex ) | 1536 | if ( info[ dIndex ].index == sourceIndex ) |
1537 | { | 1537 | { |
1538 | exist = 1; | 1538 | exist = 1; |
1539 | break; | 1539 | break; |
1540 | } | 1540 | } |
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | if ( 0 == exist ) | 1543 | if ( 0 == exist ) |
1544 | { | 1544 | { |
1545 | info[fillIndex++].index = sourceIndex; | 1545 | info[fillIndex++].index = sourceIndex; |
1546 | } | 1546 | } |
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | // clear marks | 1549 | // clear marks |
1550 | for ( i = 0; i!= VERTEXCACHE_ELEMENT; ++i ) | 1550 | for ( i = 0; i!= VERTEXCACHE_ELEMENT; ++i ) |
1551 | { | 1551 | { |
1552 | VertexCache.info[i].hit = 0; | 1552 | VertexCache.info[i].hit = 0; |
1553 | } | 1553 | } |
1554 | 1554 | ||
1555 | // mark all existing | 1555 | // mark all existing |
1556 | for ( i = 0; i!= fillIndex; ++i ) | 1556 | for ( i = 0; i!= fillIndex; ++i ) |
1557 | { | 1557 | { |
1558 | for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) | 1558 | for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) |
1559 | { | 1559 | { |
1560 | if ( VertexCache.info[ dIndex ].index == info[i].index ) | 1560 | if ( VertexCache.info[ dIndex ].index == info[i].index ) |
1561 | { | 1561 | { |
1562 | info[i].hit = dIndex; | 1562 | info[i].hit = dIndex; |
1563 | VertexCache.info[ dIndex ].hit = 1; | 1563 | VertexCache.info[ dIndex ].hit = 1; |
1564 | break; | 1564 | break; |
1565 | } | 1565 | } |
1566 | } | 1566 | } |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | // fill new | 1569 | // fill new |
1570 | for ( i = 0; i!= fillIndex; ++i ) | 1570 | for ( i = 0; i!= fillIndex; ++i ) |
1571 | { | 1571 | { |
1572 | if ( info[i].hit != VERTEXCACHE_MISS ) | 1572 | if ( info[i].hit != VERTEXCACHE_MISS ) |
1573 | continue; | 1573 | continue; |
1574 | 1574 | ||
1575 | for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) | 1575 | for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) |
1576 | { | 1576 | { |
1577 | if ( 0 == VertexCache.info[dIndex].hit ) | 1577 | if ( 0 == VertexCache.info[dIndex].hit ) |
1578 | { | 1578 | { |
1579 | VertexCache_fill ( info[i].index, dIndex ); | 1579 | VertexCache_fill ( info[i].index, dIndex ); |
1580 | VertexCache.info[dIndex].hit += 1; | 1580 | VertexCache.info[dIndex].hit += 1; |
1581 | info[i].hit = dIndex; | 1581 | info[i].hit = dIndex; |
1582 | break; | 1582 | break; |
1583 | } | 1583 | } |
1584 | } | 1584 | } |
1585 | } | 1585 | } |
1586 | } | 1586 | } |
1587 | 1587 | ||
1588 | const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); | 1588 | const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); |
1589 | 1589 | ||
1590 | switch ( VertexCache.iType ) | 1590 | switch ( VertexCache.iType ) |
1591 | { | 1591 | { |
1592 | case 1: | 1592 | case 1: |
1593 | { | 1593 | { |
1594 | const u16 *p = (const u16 *) VertexCache.indices; | 1594 | const u16 *p = (const u16 *) VertexCache.indices; |
1595 | face[0] = VertexCache_getVertex ( p[ i0 ] ); | 1595 | face[0] = VertexCache_getVertex ( p[ i0 ] ); |
1596 | face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); | 1596 | face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); |
1597 | face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); | 1597 | face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); |
1598 | } | 1598 | } |
1599 | break; | 1599 | break; |
1600 | 1600 | ||
1601 | case 2: | 1601 | case 2: |
1602 | { | 1602 | { |
1603 | const u32 *p = (const u32 *) VertexCache.indices; | 1603 | const u32 *p = (const u32 *) VertexCache.indices; |
1604 | face[0] = VertexCache_getVertex ( p[ i0 ] ); | 1604 | face[0] = VertexCache_getVertex ( p[ i0 ] ); |
1605 | face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); | 1605 | face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); |
1606 | face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); | 1606 | face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); |
1607 | } | 1607 | } |
1608 | break; | 1608 | break; |
1609 | 1609 | ||
1610 | case 4: | 1610 | case 4: |
1611 | face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 ); | 1611 | face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 ); |
1612 | face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 ); | 1612 | face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 ); |
1613 | face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 ); | 1613 | face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 ); |
1614 | break; | 1614 | break; |
1615 | default: | 1615 | default: |
1616 | face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0); | 1616 | face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0); |
1617 | break; | 1617 | break; |
1618 | } | 1618 | } |
1619 | 1619 | ||
1620 | VertexCache.indicesRun += VertexCache.primitivePitch; | 1620 | VertexCache.indicesRun += VertexCache.primitivePitch; |
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | /*! | 1623 | /*! |
1624 | */ | 1624 | */ |
1625 | REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face ) | 1625 | REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face ) |
1626 | { | 1626 | { |
1627 | const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); | 1627 | const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); |
1628 | 1628 | ||
1629 | if ( VertexCache.iType == 1 ) | 1629 | if ( VertexCache.iType == 1 ) |
1630 | { | 1630 | { |
1631 | const u16 *p = (const u16 *) VertexCache.indices; | 1631 | const u16 *p = (const u16 *) VertexCache.indices; |
1632 | VertexCache_fill ( p[ i0 ], 0 ); | 1632 | VertexCache_fill ( p[ i0 ], 0 ); |
1633 | VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); | 1633 | VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); |
1634 | VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); | 1634 | VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); |
1635 | } | 1635 | } |
1636 | else | 1636 | else |
1637 | { | 1637 | { |
1638 | const u32 *p = (const u32 *) VertexCache.indices; | 1638 | const u32 *p = (const u32 *) VertexCache.indices; |
1639 | VertexCache_fill ( p[ i0 ], 0 ); | 1639 | VertexCache_fill ( p[ i0 ], 0 ); |
1640 | VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); | 1640 | VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); |
1641 | VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); | 1641 | VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | VertexCache.indicesRun += VertexCache.primitivePitch; | 1644 | VertexCache.indicesRun += VertexCache.primitivePitch; |
1645 | 1645 | ||
1646 | face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); | 1646 | face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); |
1647 | face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); | 1647 | face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); |
1648 | face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); | 1648 | face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); |
1649 | 1649 | ||
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | /*! | 1652 | /*! |
1653 | */ | 1653 | */ |
1654 | void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount, | 1654 | void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount, |
1655 | const void* indices, u32 primitiveCount, | 1655 | const void* indices, u32 primitiveCount, |
1656 | E_VERTEX_TYPE vType, | 1656 | E_VERTEX_TYPE vType, |
1657 | scene::E_PRIMITIVE_TYPE pType, | 1657 | scene::E_PRIMITIVE_TYPE pType, |
1658 | E_INDEX_TYPE iType) | 1658 | E_INDEX_TYPE iType) |
1659 | { | 1659 | { |
1660 | VertexCache.vertices = vertices; | 1660 | VertexCache.vertices = vertices; |
1661 | VertexCache.vertexCount = vertexCount; | 1661 | VertexCache.vertexCount = vertexCount; |
1662 | 1662 | ||
1663 | VertexCache.indices = indices; | 1663 | VertexCache.indices = indices; |
1664 | VertexCache.indicesIndex = 0; | 1664 | VertexCache.indicesIndex = 0; |
1665 | VertexCache.indicesRun = 0; | 1665 | VertexCache.indicesRun = 0; |
1666 | 1666 | ||
1667 | if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER ) | 1667 | if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER ) |
1668 | VertexCache.vType = 3; | 1668 | VertexCache.vType = 3; |
1669 | else | 1669 | else |
1670 | VertexCache.vType = vType; | 1670 | VertexCache.vType = vType; |
1671 | VertexCache.pType = pType; | 1671 | VertexCache.pType = pType; |
1672 | 1672 | ||
1673 | switch ( iType ) | 1673 | switch ( iType ) |
1674 | { | 1674 | { |
1675 | case EIT_16BIT: VertexCache.iType = 1; break; | 1675 | case EIT_16BIT: VertexCache.iType = 1; break; |
1676 | case EIT_32BIT: VertexCache.iType = 2; break; | 1676 | case EIT_32BIT: VertexCache.iType = 2; break; |
1677 | default: | 1677 | default: |
1678 | VertexCache.iType = iType; break; | 1678 | VertexCache.iType = iType; break; |
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | switch ( VertexCache.pType ) | 1681 | switch ( VertexCache.pType ) |
1682 | { | 1682 | { |
1683 | // most types here will not work as expected, only triangles/triangle_fan | 1683 | // most types here will not work as expected, only triangles/triangle_fan |
1684 | // is known to work. | 1684 | // is known to work. |
1685 | case scene::EPT_POINTS: | 1685 | case scene::EPT_POINTS: |
1686 | VertexCache.indexCount = primitiveCount; | 1686 | VertexCache.indexCount = primitiveCount; |
1687 | VertexCache.primitivePitch = 1; | 1687 | VertexCache.primitivePitch = 1; |
1688 | break; | 1688 | break; |
1689 | case scene::EPT_LINE_STRIP: | 1689 | case scene::EPT_LINE_STRIP: |
1690 | VertexCache.indexCount = primitiveCount+1; | 1690 | VertexCache.indexCount = primitiveCount+1; |
1691 | VertexCache.primitivePitch = 1; | 1691 | VertexCache.primitivePitch = 1; |
1692 | break; | 1692 | break; |
1693 | case scene::EPT_LINE_LOOP: | 1693 | case scene::EPT_LINE_LOOP: |
1694 | VertexCache.indexCount = primitiveCount+1; | 1694 | VertexCache.indexCount = primitiveCount+1; |
1695 | VertexCache.primitivePitch = 1; | 1695 | VertexCache.primitivePitch = 1; |
1696 | break; | 1696 | break; |
1697 | case scene::EPT_LINES: | 1697 | case scene::EPT_LINES: |
1698 | VertexCache.indexCount = 2*primitiveCount; | 1698 | VertexCache.indexCount = 2*primitiveCount; |
1699 | VertexCache.primitivePitch = 2; | 1699 | VertexCache.primitivePitch = 2; |
1700 | break; | 1700 | break; |
1701 | case scene::EPT_TRIANGLE_STRIP: | 1701 | case scene::EPT_TRIANGLE_STRIP: |
1702 | VertexCache.indexCount = primitiveCount+2; | 1702 | VertexCache.indexCount = primitiveCount+2; |
1703 | VertexCache.primitivePitch = 1; | 1703 | VertexCache.primitivePitch = 1; |
1704 | break; | 1704 | break; |
1705 | case scene::EPT_TRIANGLES: | 1705 | case scene::EPT_TRIANGLES: |
1706 | VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount; | 1706 | VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount; |
1707 | VertexCache.primitivePitch = 3; | 1707 | VertexCache.primitivePitch = 3; |
1708 | break; | 1708 | break; |
1709 | case scene::EPT_TRIANGLE_FAN: | 1709 | case scene::EPT_TRIANGLE_FAN: |
1710 | VertexCache.indexCount = primitiveCount + 2; | 1710 | VertexCache.indexCount = primitiveCount + 2; |
1711 | VertexCache.primitivePitch = 1; | 1711 | VertexCache.primitivePitch = 1; |
1712 | break; | 1712 | break; |
1713 | case scene::EPT_QUAD_STRIP: | 1713 | case scene::EPT_QUAD_STRIP: |
1714 | VertexCache.indexCount = 2*primitiveCount + 2; | 1714 | VertexCache.indexCount = 2*primitiveCount + 2; |
1715 | VertexCache.primitivePitch = 2; | 1715 | VertexCache.primitivePitch = 2; |
1716 | break; | 1716 | break; |
1717 | case scene::EPT_QUADS: | 1717 | case scene::EPT_QUADS: |
1718 | VertexCache.indexCount = 4*primitiveCount; | 1718 | VertexCache.indexCount = 4*primitiveCount; |
1719 | VertexCache.primitivePitch = 4; | 1719 | VertexCache.primitivePitch = 4; |
1720 | break; | 1720 | break; |
1721 | case scene::EPT_POLYGON: | 1721 | case scene::EPT_POLYGON: |
1722 | VertexCache.indexCount = primitiveCount+1; | 1722 | VertexCache.indexCount = primitiveCount+1; |
1723 | VertexCache.primitivePitch = 1; | 1723 | VertexCache.primitivePitch = 1; |
1724 | break; | 1724 | break; |
1725 | case scene::EPT_POINT_SPRITES: | 1725 | case scene::EPT_POINT_SPRITES: |
1726 | VertexCache.indexCount = primitiveCount; | 1726 | VertexCache.indexCount = primitiveCount; |
1727 | VertexCache.primitivePitch = 1; | 1727 | VertexCache.primitivePitch = 1; |
1728 | break; | 1728 | break; |
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) ); | 1731 | irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) ); |
1732 | } | 1732 | } |
1733 | 1733 | ||
1734 | 1734 | ||
1735 | void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, | 1735 | void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, |
1736 | const void* indexList, u32 primitiveCount, | 1736 | const void* indexList, u32 primitiveCount, |
1737 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) | 1737 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) |
1738 | 1738 | ||
1739 | { | 1739 | { |
1740 | if (!checkPrimitiveCount(primitiveCount)) | 1740 | if (!checkPrimitiveCount(primitiveCount)) |
1741 | return; | 1741 | return; |
1742 | 1742 | ||
1743 | CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); | 1743 | CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); |
1744 | 1744 | ||
1745 | // These calls would lead to crashes due to wrong index usage. | 1745 | // These calls would lead to crashes due to wrong index usage. |
1746 | // The vertex cache needs to be rewritten for these primitives. | 1746 | // The vertex cache needs to be rewritten for these primitives. |
1747 | if (pType==scene::EPT_POINTS || pType==scene::EPT_LINE_STRIP || | 1747 | if (pType==scene::EPT_POINTS || pType==scene::EPT_LINE_STRIP || |
1748 | pType==scene::EPT_LINE_LOOP || pType==scene::EPT_LINES || pType==scene::EPT_POLYGON || | 1748 | pType==scene::EPT_LINE_LOOP || pType==scene::EPT_LINES || pType==scene::EPT_POLYGON || |
1749 | pType==scene::EPT_POINT_SPRITES) | 1749 | pType==scene::EPT_POINT_SPRITES) |
1750 | return; | 1750 | return; |
1751 | 1751 | ||
1752 | if ( 0 == CurrentShader ) | 1752 | if ( 0 == CurrentShader ) |
1753 | return; | 1753 | return; |
1754 | 1754 | ||
1755 | VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType ); | 1755 | VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType ); |
1756 | 1756 | ||
1757 | const s4DVertex * face[3]; | 1757 | const s4DVertex * face[3]; |
1758 | 1758 | ||
1759 | f32 dc_area; | 1759 | f32 dc_area; |
1760 | s32 lodLevel; | 1760 | s32 lodLevel; |
1761 | u32 i; | 1761 | u32 i; |
1762 | u32 g; | 1762 | u32 g; |
1763 | u32 m; | 1763 | u32 m; |
1764 | video::CSoftwareTexture2* tex; | 1764 | video::CSoftwareTexture2* tex; |
1765 | 1765 | ||
1766 | for ( i = 0; i < (u32) primitiveCount; ++i ) | 1766 | for ( i = 0; i < (u32) primitiveCount; ++i ) |
1767 | { | 1767 | { |
1768 | VertexCache_get(face); | 1768 | VertexCache_get(face); |
1769 | 1769 | ||
1770 | // if fully outside or outside on same side | 1770 | // if fully outside or outside on same side |
1771 | if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK ) | 1771 | if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK ) |
1772 | != VERTEX4D_INSIDE | 1772 | != VERTEX4D_INSIDE |
1773 | ) | 1773 | ) |
1774 | continue; | 1774 | continue; |
1775 | 1775 | ||
1776 | // if fully inside | 1776 | // if fully inside |
1777 | if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) | 1777 | if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) |
1778 | { | 1778 | { |
1779 | dc_area = screenarea2 ( face ); | 1779 | dc_area = screenarea2 ( face ); |
1780 | if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) ) | 1780 | if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) ) |
1781 | continue; | 1781 | continue; |
1782 | else | 1782 | else |
1783 | if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) | 1783 | if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) |
1784 | continue; | 1784 | continue; |
1785 | 1785 | ||
1786 | // select mipmap | 1786 | // select mipmap |
1787 | dc_area = core::reciprocal ( dc_area ); | 1787 | dc_area = core::reciprocal ( dc_area ); |
1788 | for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) | 1788 | for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) |
1789 | { | 1789 | { |
1790 | if ( 0 == (tex = MAT_TEXTURE ( m )) ) | 1790 | if ( 0 == (tex = MAT_TEXTURE ( m )) ) |
1791 | { | 1791 | { |
1792 | CurrentShader->setTextureParam(m, 0, 0); | 1792 | CurrentShader->setTextureParam(m, 0, 0); |
1793 | continue; | 1793 | continue; |
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area ); | 1796 | lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area ); |
1797 | CurrentShader->setTextureParam(m, tex, lodLevel ); | 1797 | CurrentShader->setTextureParam(m, tex, lodLevel ); |
1798 | select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() ); | 1798 | select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() ); |
1799 | } | 1799 | } |
1800 | 1800 | ||
1801 | // rasterize | 1801 | // rasterize |
1802 | CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); | 1802 | CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); |
1803 | continue; | 1803 | continue; |
1804 | } | 1804 | } |
1805 | 1805 | ||
1806 | // else if not complete inside clipping necessary | 1806 | // else if not complete inside clipping necessary |
1807 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 ); | 1807 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 ); |
1808 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 ); | 1808 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 ); |
1809 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 ); | 1809 | irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 ); |
1810 | 1810 | ||
1811 | const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK; | 1811 | const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK; |
1812 | 1812 | ||
1813 | for ( g = 0; g != CurrentOut.ElementSize; ++g ) | 1813 | for ( g = 0; g != CurrentOut.ElementSize; ++g ) |
1814 | { | 1814 | { |
1815 | CurrentOut.data[g].flag = flag; | 1815 | CurrentOut.data[g].flag = flag; |
1816 | Temp.data[g].flag = flag; | 1816 | Temp.data[g].flag = flag; |
1817 | } | 1817 | } |
1818 | 1818 | ||
1819 | u32 vOut; | 1819 | u32 vOut; |
1820 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); | 1820 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); |
1821 | if ( vOut < 3 ) | 1821 | if ( vOut < 3 ) |
1822 | continue; | 1822 | continue; |
1823 | 1823 | ||
1824 | vOut <<= 1; | 1824 | vOut <<= 1; |
1825 | 1825 | ||
1826 | // to DC Space, project homogenous vertex | 1826 | // to DC Space, project homogenous vertex |
1827 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); | 1827 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); |
1828 | 1828 | ||
1829 | /* | 1829 | /* |
1830 | // TODO: don't stick on 32 Bit Pointer | 1830 | // TODO: don't stick on 32 Bit Pointer |
1831 | #define PointerAsValue(x) ( (u32) (u32*) (x) ) | 1831 | #define PointerAsValue(x) ( (u32) (u32*) (x) ) |
1832 | 1832 | ||
1833 | // if not complete inside clipping necessary | 1833 | // if not complete inside clipping necessary |
1834 | if ( ( test & VERTEX4D_INSIDE ) != VERTEX4D_INSIDE ) | 1834 | if ( ( test & VERTEX4D_INSIDE ) != VERTEX4D_INSIDE ) |
1835 | { | 1835 | { |
1836 | u32 v[2] = { PointerAsValue ( Temp ) , PointerAsValue ( CurrentOut ) }; | 1836 | u32 v[2] = { PointerAsValue ( Temp ) , PointerAsValue ( CurrentOut ) }; |
1837 | for ( g = 0; g != 6; ++g ) | 1837 | for ( g = 0; g != 6; ++g ) |
1838 | { | 1838 | { |
1839 | vOut = clipToHyperPlane ( (s4DVertex*) v[0], (s4DVertex*) v[1], vOut, NDCPlane[g] ); | 1839 | vOut = clipToHyperPlane ( (s4DVertex*) v[0], (s4DVertex*) v[1], vOut, NDCPlane[g] ); |
1840 | if ( vOut < 3 ) | 1840 | if ( vOut < 3 ) |
1841 | break; | 1841 | break; |
1842 | 1842 | ||
1843 | v[0] ^= v[1]; | 1843 | v[0] ^= v[1]; |
1844 | v[1] ^= v[0]; | 1844 | v[1] ^= v[0]; |
1845 | v[0] ^= v[1]; | 1845 | v[0] ^= v[1]; |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | if ( vOut < 3 ) | 1848 | if ( vOut < 3 ) |
1849 | continue; | 1849 | continue; |
1850 | 1850 | ||
1851 | } | 1851 | } |
1852 | */ | 1852 | */ |
1853 | 1853 | ||
1854 | // check 2d backface culling on first | 1854 | // check 2d backface culling on first |
1855 | dc_area = screenarea ( CurrentOut.data ); | 1855 | dc_area = screenarea ( CurrentOut.data ); |
1856 | if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) ) | 1856 | if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) ) |
1857 | continue; | 1857 | continue; |
1858 | else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) | 1858 | else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) |
1859 | continue; | 1859 | continue; |
1860 | 1860 | ||
1861 | // select mipmap | 1861 | // select mipmap |
1862 | dc_area = core::reciprocal ( dc_area ); | 1862 | dc_area = core::reciprocal ( dc_area ); |
1863 | for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) | 1863 | for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) |
1864 | { | 1864 | { |
1865 | if ( 0 == (tex = MAT_TEXTURE ( m )) ) | 1865 | if ( 0 == (tex = MAT_TEXTURE ( m )) ) |
1866 | { | 1866 | { |
1867 | CurrentShader->setTextureParam(m, 0, 0); | 1867 | CurrentShader->setTextureParam(m, 0, 0); |
1868 | continue; | 1868 | continue; |
1869 | } | 1869 | } |
1870 | 1870 | ||
1871 | lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area ); | 1871 | lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area ); |
1872 | CurrentShader->setTextureParam(m, tex, lodLevel ); | 1872 | CurrentShader->setTextureParam(m, tex, lodLevel ); |
1873 | select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() ); | 1873 | select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() ); |
1874 | } | 1874 | } |
1875 | 1875 | ||
1876 | 1876 | ||
1877 | // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) | 1877 | // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) |
1878 | for ( g = 0; g <= vOut - 6; g += 2 ) | 1878 | for ( g = 0; g <= vOut - 6; g += 2 ) |
1879 | { | 1879 | { |
1880 | // rasterize | 1880 | // rasterize |
1881 | CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1, | 1881 | CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1, |
1882 | CurrentOut.data + g + 3, | 1882 | CurrentOut.data + g + 3, |
1883 | CurrentOut.data + g + 5); | 1883 | CurrentOut.data + g + 5); |
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | } | 1886 | } |
1887 | 1887 | ||
1888 | // dump statistics | 1888 | // dump statistics |
1889 | /* | 1889 | /* |
1890 | char buf [64]; | 1890 | char buf [64]; |
1891 | sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d", | 1891 | sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d", |
1892 | vertexCount, primitiveCount, | 1892 | vertexCount, primitiveCount, |
1893 | VertexCache.CacheMiss | 1893 | VertexCache.CacheMiss |
1894 | ); | 1894 | ); |
1895 | os::Printer::log( buf ); | 1895 | os::Printer::log( buf ); |
1896 | */ | 1896 | */ |
1897 | 1897 | ||
1898 | } | 1898 | } |
1899 | 1899 | ||
1900 | 1900 | ||
1901 | //! Sets the dynamic ambient light color. The default color is | 1901 | //! Sets the dynamic ambient light color. The default color is |
1902 | //! (0,0,0,0) which means it is dark. | 1902 | //! (0,0,0,0) which means it is dark. |
1903 | //! \param color: New color of the ambient light. | 1903 | //! \param color: New color of the ambient light. |
1904 | void CBurningVideoDriver::setAmbientLight(const SColorf& color) | 1904 | void CBurningVideoDriver::setAmbientLight(const SColorf& color) |
1905 | { | 1905 | { |
1906 | LightSpace.Global_AmbientLight.setColorf ( color ); | 1906 | LightSpace.Global_AmbientLight.setColorf ( color ); |
1907 | } | 1907 | } |
1908 | 1908 | ||
1909 | 1909 | ||
1910 | //! adds a dynamic light | 1910 | //! adds a dynamic light |
1911 | s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) | 1911 | s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) |
1912 | { | 1912 | { |
1913 | (void) CNullDriver::addDynamicLight( dl ); | 1913 | (void) CNullDriver::addDynamicLight( dl ); |
1914 | 1914 | ||
1915 | SBurningShaderLight l; | 1915 | SBurningShaderLight l; |
1916 | // l.org = dl; | 1916 | // l.org = dl; |
1917 | l.Type = dl.Type; | 1917 | l.Type = dl.Type; |
1918 | l.LightIsOn = true; | 1918 | l.LightIsOn = true; |
1919 | 1919 | ||
1920 | l.AmbientColor.setColorf ( dl.AmbientColor ); | 1920 | l.AmbientColor.setColorf ( dl.AmbientColor ); |
1921 | l.DiffuseColor.setColorf ( dl.DiffuseColor ); | 1921 | l.DiffuseColor.setColorf ( dl.DiffuseColor ); |
1922 | l.SpecularColor.setColorf ( dl.SpecularColor ); | 1922 | l.SpecularColor.setColorf ( dl.SpecularColor ); |
1923 | 1923 | ||
1924 | switch ( dl.Type ) | 1924 | switch ( dl.Type ) |
1925 | { | 1925 | { |
1926 | case video::ELT_DIRECTIONAL: | 1926 | case video::ELT_DIRECTIONAL: |
1927 | l.pos.x = -dl.Direction.X; | 1927 | l.pos.x = -dl.Direction.X; |
1928 | l.pos.y = -dl.Direction.Y; | 1928 | l.pos.y = -dl.Direction.Y; |
1929 | l.pos.z = -dl.Direction.Z; | 1929 | l.pos.z = -dl.Direction.Z; |
1930 | l.pos.w = 1.f; | 1930 | l.pos.w = 1.f; |
1931 | break; | 1931 | break; |
1932 | case ELT_POINT: | 1932 | case ELT_POINT: |
1933 | case ELT_SPOT: | 1933 | case ELT_SPOT: |
1934 | LightSpace.Flags |= POINTLIGHT; | 1934 | LightSpace.Flags |= POINTLIGHT; |
1935 | l.pos.x = dl.Position.X; | 1935 | l.pos.x = dl.Position.X; |
1936 | l.pos.y = dl.Position.Y; | 1936 | l.pos.y = dl.Position.Y; |
1937 | l.pos.z = dl.Position.Z; | 1937 | l.pos.z = dl.Position.Z; |
1938 | l.pos.w = 1.f; | 1938 | l.pos.w = 1.f; |
1939 | /* | 1939 | /* |
1940 | l.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y); | 1940 | l.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y); |
1941 | l.constantAttenuation = dl.Attenuation.X; | 1941 | l.constantAttenuation = dl.Attenuation.X; |
1942 | l.linearAttenuation = dl.Attenuation.Y; | 1942 | l.linearAttenuation = dl.Attenuation.Y; |
1943 | l.quadraticAttenuation = dl.Attenuation.Z; | 1943 | l.quadraticAttenuation = dl.Attenuation.Z; |
1944 | */ | 1944 | */ |
1945 | l.radius = dl.Radius * dl.Radius; | 1945 | l.radius = dl.Radius * dl.Radius; |
1946 | l.constantAttenuation = dl.Attenuation.X; | 1946 | l.constantAttenuation = dl.Attenuation.X; |
1947 | l.linearAttenuation = 1.f / dl.Radius; | 1947 | l.linearAttenuation = 1.f / dl.Radius; |
1948 | l.quadraticAttenuation = dl.Attenuation.Z; | 1948 | l.quadraticAttenuation = dl.Attenuation.Z; |
1949 | 1949 | ||
1950 | break; | 1950 | break; |
1951 | default: | 1951 | default: |
1952 | break; | 1952 | break; |
1953 | } | 1953 | } |
1954 | 1954 | ||
1955 | LightSpace.Light.push_back ( l ); | 1955 | LightSpace.Light.push_back ( l ); |
1956 | return LightSpace.Light.size() - 1; | 1956 | return LightSpace.Light.size() - 1; |
1957 | } | 1957 | } |
1958 | 1958 | ||
1959 | //! Turns a dynamic light on or off | 1959 | //! Turns a dynamic light on or off |
1960 | void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) | 1960 | void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) |
1961 | { | 1961 | { |
1962 | if(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size()) | 1962 | if(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size()) |
1963 | { | 1963 | { |
1964 | LightSpace.Light[lightIndex].LightIsOn = turnOn; | 1964 | LightSpace.Light[lightIndex].LightIsOn = turnOn; |
1965 | } | 1965 | } |
1966 | } | 1966 | } |
1967 | 1967 | ||
1968 | //! deletes all dynamic lights there are | 1968 | //! deletes all dynamic lights there are |
1969 | void CBurningVideoDriver::deleteAllDynamicLights() | 1969 | void CBurningVideoDriver::deleteAllDynamicLights() |
1970 | { | 1970 | { |
1971 | LightSpace.reset (); | 1971 | LightSpace.reset (); |
1972 | CNullDriver::deleteAllDynamicLights(); | 1972 | CNullDriver::deleteAllDynamicLights(); |
1973 | 1973 | ||
1974 | } | 1974 | } |
1975 | 1975 | ||
1976 | //! returns the maximal amount of dynamic lights the device can handle | 1976 | //! returns the maximal amount of dynamic lights the device can handle |
1977 | u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const | 1977 | u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const |
1978 | { | 1978 | { |
1979 | return 8; | 1979 | return 8; |
1980 | } | 1980 | } |
1981 | 1981 | ||
1982 | 1982 | ||
1983 | //! sets a material | 1983 | //! sets a material |
1984 | void CBurningVideoDriver::setMaterial(const SMaterial& material) | 1984 | void CBurningVideoDriver::setMaterial(const SMaterial& material) |
1985 | { | 1985 | { |
1986 | Material.org = material; | 1986 | Material.org = material; |
1987 | 1987 | ||
1988 | #ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM | 1988 | #ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM |
1989 | for (u32 i = 0; i < 2; ++i) | 1989 | for (u32 i = 0; i < 2; ++i) |
1990 | { | 1990 | { |
1991 | setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), | 1991 | setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), |
1992 | material.getTextureMatrix(i)); | 1992 | material.getTextureMatrix(i)); |
1993 | } | 1993 | } |
1994 | #endif | 1994 | #endif |
1995 | 1995 | ||
1996 | #ifdef SOFTWARE_DRIVER_2_LIGHTING | 1996 | #ifdef SOFTWARE_DRIVER_2_LIGHTING |
1997 | Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color ); | 1997 | Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color ); |
1998 | Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color ); | 1998 | Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color ); |
1999 | Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color ); | 1999 | Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color ); |
2000 | Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color ); | 2000 | Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color ); |
2001 | 2001 | ||
2002 | core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR ); | 2002 | core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR ); |
2003 | core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG ); | 2003 | core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG ); |
2004 | core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE ); | 2004 | core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE ); |
2005 | #endif | 2005 | #endif |
2006 | 2006 | ||
2007 | setCurrentShader(); | 2007 | setCurrentShader(); |
2008 | } | 2008 | } |
2009 | 2009 | ||
2010 | 2010 | ||
2011 | /*! | 2011 | /*! |
2012 | Camera Position in World Space | 2012 | Camera Position in World Space |
2013 | */ | 2013 | */ |
2014 | void CBurningVideoDriver::getCameraPosWorldSpace () | 2014 | void CBurningVideoDriver::getCameraPosWorldSpace () |
2015 | { | 2015 | { |
2016 | Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ]; | 2016 | Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ]; |
2017 | Transformation[ETS_VIEW_INVERSE].makeInverse (); | 2017 | Transformation[ETS_VIEW_INVERSE].makeInverse (); |
2018 | TransformationFlag[ETS_VIEW_INVERSE] = 0; | 2018 | TransformationFlag[ETS_VIEW_INVERSE] = 0; |
2019 | 2019 | ||
2020 | const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer (); | 2020 | const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer (); |
2021 | 2021 | ||
2022 | /* The viewpoint is at (0., 0., 0.) in eye space. | 2022 | /* The viewpoint is at (0., 0., 0.) in eye space. |
2023 | Turning this into a vector [0 0 0 1] and multiply it by | 2023 | Turning this into a vector [0 0 0 1] and multiply it by |
2024 | the inverse of the view matrix, the resulting vector is the | 2024 | the inverse of the view matrix, the resulting vector is the |
2025 | object space location of the camera. | 2025 | object space location of the camera. |
2026 | */ | 2026 | */ |
2027 | 2027 | ||
2028 | LightSpace.campos.x = M[12]; | 2028 | LightSpace.campos.x = M[12]; |
2029 | LightSpace.campos.y = M[13]; | 2029 | LightSpace.campos.y = M[13]; |
2030 | LightSpace.campos.z = M[14]; | 2030 | LightSpace.campos.z = M[14]; |
2031 | LightSpace.campos.w = 1.f; | 2031 | LightSpace.campos.w = 1.f; |
2032 | } | 2032 | } |
2033 | 2033 | ||
2034 | void CBurningVideoDriver::getLightPosObjectSpace () | 2034 | void CBurningVideoDriver::getLightPosObjectSpace () |
2035 | { | 2035 | { |
2036 | if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) | 2036 | if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) |
2037 | { | 2037 | { |
2038 | Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; | 2038 | Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; |
2039 | TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; | 2039 | TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; |
2040 | } | 2040 | } |
2041 | else | 2041 | else |
2042 | { | 2042 | { |
2043 | Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] ); | 2043 | Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] ); |
2044 | TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY; | 2044 | TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY; |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i ) | 2047 | for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i ) |
2048 | { | 2048 | { |
2049 | SBurningShaderLight &l = LightSpace.Light[i]; | 2049 | SBurningShaderLight &l = LightSpace.Light[i]; |
2050 | 2050 | ||
2051 | Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x ); | 2051 | Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x ); |
2052 | } | 2052 | } |
2053 | } | 2053 | } |
2054 | 2054 | ||
2055 | 2055 | ||
2056 | #ifdef SOFTWARE_DRIVER_2_LIGHTING | 2056 | #ifdef SOFTWARE_DRIVER_2_LIGHTING |
2057 | 2057 | ||
2058 | //! Sets the fog mode. | 2058 | //! Sets the fog mode. |
2059 | void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, | 2059 | void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, |
2060 | f32 end, f32 density, bool pixelFog, bool rangeFog) | 2060 | f32 end, f32 density, bool pixelFog, bool rangeFog) |
2061 | { | 2061 | { |
2062 | CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); | 2062 | CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); |
2063 | LightSpace.FogColor.setA8R8G8B8 ( color.color ); | 2063 | LightSpace.FogColor.setA8R8G8B8 ( color.color ); |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | /*! | 2066 | /*! |
2067 | applies lighting model | 2067 | applies lighting model |
2068 | */ | 2068 | */ |
2069 | void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb ) | 2069 | void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb ) |
2070 | { | 2070 | { |
2071 | sVec3 dColor; | 2071 | sVec3 dColor; |
2072 | 2072 | ||
2073 | dColor = LightSpace.Global_AmbientLight; | 2073 | dColor = LightSpace.Global_AmbientLight; |
2074 | dColor.add ( Material.EmissiveColor ); | 2074 | dColor.add ( Material.EmissiveColor ); |
2075 | 2075 | ||
2076 | if ( Lights.size () == 0 ) | 2076 | if ( Lights.size () == 0 ) |
2077 | { | 2077 | { |
2078 | dColor.saturate( dest->Color[0], vertexargb); | 2078 | dColor.saturate( dest->Color[0], vertexargb); |
2079 | return; | 2079 | return; |
2080 | } | 2080 | } |
2081 | 2081 | ||
2082 | sVec3 ambient; | 2082 | sVec3 ambient; |
2083 | sVec3 diffuse; | 2083 | sVec3 diffuse; |
2084 | sVec3 specular; | 2084 | sVec3 specular; |
2085 | 2085 | ||
2086 | 2086 | ||
2087 | // the universe started in darkness.. | 2087 | // the universe started in darkness.. |
2088 | ambient.set ( 0.f, 0.f, 0.f ); | 2088 | ambient.set ( 0.f, 0.f, 0.f ); |
2089 | diffuse.set ( 0.f, 0.f, 0.f ); | 2089 | diffuse.set ( 0.f, 0.f, 0.f ); |
2090 | specular.set ( 0.f, 0.f, 0.f ); | 2090 | specular.set ( 0.f, 0.f, 0.f ); |
2091 | 2091 | ||
2092 | 2092 | ||
2093 | u32 i; | 2093 | u32 i; |
2094 | f32 dot; | 2094 | f32 dot; |
2095 | f32 len; | 2095 | f32 len; |
2096 | f32 attenuation; | 2096 | f32 attenuation; |
2097 | sVec4 vp; // unit vector vertex to light | 2097 | sVec4 vp; // unit vector vertex to light |
2098 | sVec4 lightHalf; // blinn-phong reflection | 2098 | sVec4 lightHalf; // blinn-phong reflection |
2099 | 2099 | ||
2100 | for ( i = 0; i!= LightSpace.Light.size (); ++i ) | 2100 | for ( i = 0; i!= LightSpace.Light.size (); ++i ) |
2101 | { | 2101 | { |
2102 | const SBurningShaderLight &light = LightSpace.Light[i]; | 2102 | const SBurningShaderLight &light = LightSpace.Light[i]; |
2103 | 2103 | ||
2104 | if ( !light.LightIsOn ) | 2104 | if ( !light.LightIsOn ) |
2105 | continue; | 2105 | continue; |
2106 | 2106 | ||
2107 | // accumulate ambient | 2107 | // accumulate ambient |
2108 | ambient.add ( light.AmbientColor ); | 2108 | ambient.add ( light.AmbientColor ); |
2109 | 2109 | ||
2110 | switch ( light.Type ) | 2110 | switch ( light.Type ) |
2111 | { | 2111 | { |
2112 | case video::ELT_SPOT: | 2112 | case video::ELT_SPOT: |
2113 | case video::ELT_POINT: | 2113 | case video::ELT_POINT: |
2114 | // surface to light | 2114 | // surface to light |
2115 | vp.x = light.pos.x - LightSpace.vertex.x; | 2115 | vp.x = light.pos.x - LightSpace.vertex.x; |
2116 | vp.y = light.pos.y - LightSpace.vertex.y; | 2116 | vp.y = light.pos.y - LightSpace.vertex.y; |
2117 | vp.z = light.pos.z - LightSpace.vertex.z; | 2117 | vp.z = light.pos.z - LightSpace.vertex.z; |
2118 | //vp.x = light.pos_objectspace.x - LightSpace.vertex.x; | 2118 | //vp.x = light.pos_objectspace.x - LightSpace.vertex.x; |
2119 | //vp.y = light.pos_objectspace.y - LightSpace.vertex.x; | 2119 | //vp.y = light.pos_objectspace.y - LightSpace.vertex.x; |
2120 | //vp.z = light.pos_objectspace.z - LightSpace.vertex.x; | 2120 | //vp.z = light.pos_objectspace.z - LightSpace.vertex.x; |
2121 | 2121 | ||
2122 | len = vp.get_length_xyz_square(); | 2122 | len = vp.get_length_xyz_square(); |
2123 | if ( light.radius < len ) | 2123 | if ( light.radius < len ) |
2124 | continue; | 2124 | continue; |
2125 | 2125 | ||
2126 | len = core::reciprocal_squareroot ( len ); | 2126 | len = core::reciprocal_squareroot ( len ); |
2127 | 2127 | ||
2128 | // build diffuse reflection | 2128 | // build diffuse reflection |
2129 | 2129 | ||
2130 | //angle between normal and light vector | 2130 | //angle between normal and light vector |
2131 | vp.mul ( len ); | 2131 | vp.mul ( len ); |
2132 | dot = LightSpace.normal.dot_xyz ( vp ); | 2132 | dot = LightSpace.normal.dot_xyz ( vp ); |
2133 | if ( dot < 0.f ) | 2133 | if ( dot < 0.f ) |
2134 | continue; | 2134 | continue; |
2135 | 2135 | ||
2136 | attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) ); | 2136 | attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) ); |
2137 | 2137 | ||
2138 | // diffuse component | 2138 | // diffuse component |
2139 | diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation ); | 2139 | diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation ); |
2140 | 2140 | ||
2141 | if ( !(LightSpace.Flags & SPECULAR) ) | 2141 | if ( !(LightSpace.Flags & SPECULAR) ) |
2142 | continue; | 2142 | continue; |
2143 | 2143 | ||
2144 | // build specular | 2144 | // build specular |
2145 | // surface to view | 2145 | // surface to view |
2146 | lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x; | 2146 | lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x; |
2147 | lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y; | 2147 | lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y; |
2148 | lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z; | 2148 | lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z; |
2149 | lightHalf.normalize_xyz(); | 2149 | lightHalf.normalize_xyz(); |
2150 | lightHalf += vp; | 2150 | lightHalf += vp; |
2151 | lightHalf.normalize_xyz(); | 2151 | lightHalf.normalize_xyz(); |
2152 | 2152 | ||
2153 | // specular | 2153 | // specular |
2154 | dot = LightSpace.normal.dot_xyz ( lightHalf ); | 2154 | dot = LightSpace.normal.dot_xyz ( lightHalf ); |
2155 | if ( dot < 0.f ) | 2155 | if ( dot < 0.f ) |
2156 | continue; | 2156 | continue; |
2157 | 2157 | ||
2158 | //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation ); | 2158 | //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation ); |
2159 | specular.mulAdd ( light.SpecularColor, dot * attenuation ); | 2159 | specular.mulAdd ( light.SpecularColor, dot * attenuation ); |
2160 | break; | 2160 | break; |
2161 | 2161 | ||
2162 | case video::ELT_DIRECTIONAL: | 2162 | case video::ELT_DIRECTIONAL: |
2163 | 2163 | ||
2164 | //angle between normal and light vector | 2164 | //angle between normal and light vector |
2165 | dot = LightSpace.normal.dot_xyz ( light.pos ); | 2165 | dot = LightSpace.normal.dot_xyz ( light.pos ); |
2166 | if ( dot < 0.f ) | 2166 | if ( dot < 0.f ) |
2167 | continue; | 2167 | continue; |
2168 | 2168 | ||
2169 | // diffuse component | 2169 | // diffuse component |
2170 | diffuse.mulAdd ( light.DiffuseColor, dot ); | 2170 | diffuse.mulAdd ( light.DiffuseColor, dot ); |
2171 | break; | 2171 | break; |
2172 | default: | 2172 | default: |
2173 | break; | 2173 | break; |
2174 | } | 2174 | } |
2175 | 2175 | ||
2176 | } | 2176 | } |
2177 | 2177 | ||
2178 | // sum up lights | 2178 | // sum up lights |
2179 | dColor.mulAdd (ambient, Material.AmbientColor ); | 2179 | dColor.mulAdd (ambient, Material.AmbientColor ); |
2180 | dColor.mulAdd (diffuse, Material.DiffuseColor); | 2180 | dColor.mulAdd (diffuse, Material.DiffuseColor); |
2181 | dColor.mulAdd (specular, Material.SpecularColor); | 2181 | dColor.mulAdd (specular, Material.SpecularColor); |
2182 | 2182 | ||
2183 | dColor.saturate ( dest->Color[0], vertexargb ); | 2183 | dColor.saturate ( dest->Color[0], vertexargb ); |
2184 | } | 2184 | } |
2185 | 2185 | ||
2186 | #endif | 2186 | #endif |
2187 | 2187 | ||
2188 | 2188 | ||
2189 | //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. | 2189 | //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. |
2190 | void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, | 2190 | void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, |
2191 | const core::rect<s32>& sourceRect, | 2191 | const core::rect<s32>& sourceRect, |
2192 | const core::rect<s32>* clipRect, SColor color, | 2192 | const core::rect<s32>* clipRect, SColor color, |
2193 | bool useAlphaChannelOfTexture) | 2193 | bool useAlphaChannelOfTexture) |
2194 | { | 2194 | { |
2195 | if (texture) | 2195 | if (texture) |
2196 | { | 2196 | { |
2197 | if (texture->getDriverType() != EDT_BURNINGSVIDEO) | 2197 | if (texture->getDriverType() != EDT_BURNINGSVIDEO) |
2198 | { | 2198 | { |
2199 | os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); | 2199 | os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); |
2200 | return; | 2200 | return; |
2201 | } | 2201 | } |
2202 | 2202 | ||
2203 | #if 0 | 2203 | #if 0 |
2204 | // 2d methods don't use viewPort | 2204 | // 2d methods don't use viewPort |
2205 | core::position2di dest = destPos; | 2205 | core::position2di dest = destPos; |
2206 | core::recti clip=ViewPort; | 2206 | core::recti clip=ViewPort; |
2207 | if (ViewPort.getSize().Width != ScreenSize.Width) | 2207 | if (ViewPort.getSize().Width != ScreenSize.Width) |
2208 | { | 2208 | { |
2209 | dest.X=ViewPort.UpperLeftCorner.X+core::round32(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width); | 2209 | dest.X=ViewPort.UpperLeftCorner.X+core::round32(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width); |
2210 | dest.Y=ViewPort.UpperLeftCorner.Y+core::round32(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height); | 2210 | dest.Y=ViewPort.UpperLeftCorner.Y+core::round32(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height); |
2211 | if (clipRect) | 2211 | if (clipRect) |
2212 | { | 2212 | { |
2213 | clip.constrainTo(*clipRect); | 2213 | clip.constrainTo(*clipRect); |
2214 | } | 2214 | } |
2215 | clipRect = &clip; | 2215 | clipRect = &clip; |
2216 | } | 2216 | } |
2217 | #endif | 2217 | #endif |
2218 | if (useAlphaChannelOfTexture) | 2218 | if (useAlphaChannelOfTexture) |
2219 | ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha( | 2219 | ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha( |
2220 | RenderTargetSurface, destPos, sourceRect, color, clipRect); | 2220 | RenderTargetSurface, destPos, sourceRect, color, clipRect); |
2221 | else | 2221 | else |
2222 | ((CSoftwareTexture2*)texture)->getImage()->copyTo( | 2222 | ((CSoftwareTexture2*)texture)->getImage()->copyTo( |
2223 | RenderTargetSurface, destPos, sourceRect, clipRect); | 2223 | RenderTargetSurface, destPos, sourceRect, clipRect); |
2224 | } | 2224 | } |
2225 | } | 2225 | } |
2226 | 2226 | ||
2227 | 2227 | ||
2228 | //! Draws a part of the texture into the rectangle. | 2228 | //! Draws a part of the texture into the rectangle. |
2229 | void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, | 2229 | void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect, |
2230 | const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, | 2230 | const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, |
2231 | const video::SColor* const colors, bool useAlphaChannelOfTexture) | 2231 | const video::SColor* const colors, bool useAlphaChannelOfTexture) |
2232 | { | 2232 | { |
2233 | if (texture) | 2233 | if (texture) |
2234 | { | 2234 | { |
2235 | if (texture->getDriverType() != EDT_BURNINGSVIDEO) | 2235 | if (texture->getDriverType() != EDT_BURNINGSVIDEO) |
2236 | { | 2236 | { |
2237 | os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); | 2237 | os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); |
2238 | return; | 2238 | return; |
2239 | } | 2239 | } |
2240 | 2240 | ||
2241 | if (useAlphaChannelOfTexture) | 2241 | if (useAlphaChannelOfTexture) |
2242 | StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect, | 2242 | StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect, |
2243 | ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); | 2243 | ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); |
2244 | else | 2244 | else |
2245 | StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect, | 2245 | StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect, |
2246 | ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); | 2246 | ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); |
2247 | } | 2247 | } |
2248 | } | 2248 | } |
2249 | 2249 | ||
2250 | //! Draws a 2d line. | 2250 | //! Draws a 2d line. |
2251 | void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start, | 2251 | void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start, |
2252 | const core::position2d<s32>& end, | 2252 | const core::position2d<s32>& end, |
2253 | SColor color) | 2253 | SColor color) |
2254 | { | 2254 | { |
2255 | drawLine(BackBuffer, start, end, color ); | 2255 | drawLine(BackBuffer, start, end, color ); |
2256 | } | 2256 | } |
2257 | 2257 | ||
2258 | 2258 | ||
2259 | //! Draws a pixel | 2259 | //! Draws a pixel |
2260 | void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color) | 2260 | void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color) |
2261 | { | 2261 | { |
2262 | BackBuffer->setPixel(x, y, color, true); | 2262 | BackBuffer->setPixel(x, y, color, true); |
2263 | } | 2263 | } |
2264 | 2264 | ||
2265 | 2265 | ||
2266 | //! draw an 2d rectangle | 2266 | //! draw an 2d rectangle |
2267 | void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, | 2267 | void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, |
2268 | const core::rect<s32>* clip) | 2268 | const core::rect<s32>* clip) |
2269 | { | 2269 | { |
2270 | if (clip) | 2270 | if (clip) |
2271 | { | 2271 | { |
2272 | core::rect<s32> p(pos); | 2272 | core::rect<s32> p(pos); |
2273 | 2273 | ||
2274 | p.clipAgainst(*clip); | 2274 | p.clipAgainst(*clip); |
2275 | 2275 | ||
2276 | if(!p.isValid()) | 2276 | if(!p.isValid()) |
2277 | return; | 2277 | return; |
2278 | 2278 | ||
2279 | drawRectangle(BackBuffer, p, color); | 2279 | drawRectangle(BackBuffer, p, color); |
2280 | } | 2280 | } |
2281 | else | 2281 | else |
2282 | { | 2282 | { |
2283 | if(!pos.isValid()) | 2283 | if(!pos.isValid()) |
2284 | return; | 2284 | return; |
2285 | 2285 | ||
2286 | drawRectangle(BackBuffer, pos, color); | 2286 | drawRectangle(BackBuffer, pos, color); |
2287 | } | 2287 | } |
2288 | } | 2288 | } |
2289 | 2289 | ||
2290 | 2290 | ||
2291 | //! Only used by the internal engine. Used to notify the driver that | 2291 | //! Only used by the internal engine. Used to notify the driver that |
2292 | //! the window was resized. | 2292 | //! the window was resized. |
2293 | void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size) | 2293 | void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size) |
2294 | { | 2294 | { |
2295 | // make sure width and height are multiples of 2 | 2295 | // make sure width and height are multiples of 2 |
2296 | core::dimension2d<u32> realSize(size); | 2296 | core::dimension2d<u32> realSize(size); |
2297 | 2297 | ||
2298 | if (realSize.Width % 2) | 2298 | if (realSize.Width % 2) |
2299 | realSize.Width += 1; | 2299 | realSize.Width += 1; |
2300 | 2300 | ||
2301 | if (realSize.Height % 2) | 2301 | if (realSize.Height % 2) |
2302 | realSize.Height += 1; | 2302 | realSize.Height += 1; |
2303 | 2303 | ||
2304 | if (ScreenSize != realSize) | 2304 | if (ScreenSize != realSize) |
2305 | { | 2305 | { |
2306 | if (ViewPort.getWidth() == (s32)ScreenSize.Width && | 2306 | if (ViewPort.getWidth() == (s32)ScreenSize.Width && |
2307 | ViewPort.getHeight() == (s32)ScreenSize.Height) | 2307 | ViewPort.getHeight() == (s32)ScreenSize.Height) |
2308 | { | 2308 | { |
2309 | ViewPort.UpperLeftCorner.X = 0; | 2309 | ViewPort.UpperLeftCorner.X = 0; |
2310 | ViewPort.UpperLeftCorner.Y = 0; | 2310 | ViewPort.UpperLeftCorner.Y = 0; |
2311 | ViewPort.LowerRightCorner.X = realSize.Width; | 2311 | ViewPort.LowerRightCorner.X = realSize.Width; |
2312 | ViewPort.LowerRightCorner.X = realSize.Height; | 2312 | ViewPort.LowerRightCorner.X = realSize.Height; |
2313 | } | 2313 | } |
2314 | 2314 | ||
2315 | ScreenSize = realSize; | 2315 | ScreenSize = realSize; |
2316 | 2316 | ||
2317 | bool resetRT = (RenderTargetSurface == BackBuffer); | 2317 | bool resetRT = (RenderTargetSurface == BackBuffer); |
2318 | 2318 | ||
2319 | if (BackBuffer) | 2319 | if (BackBuffer) |
2320 | BackBuffer->drop(); | 2320 | BackBuffer->drop(); |
2321 | BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, realSize); | 2321 | BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, realSize); |
2322 | 2322 | ||
2323 | if (resetRT) | 2323 | if (resetRT) |
2324 | setRenderTarget(BackBuffer); | 2324 | setRenderTarget(BackBuffer); |
2325 | } | 2325 | } |
2326 | } | 2326 | } |
2327 | 2327 | ||
2328 | 2328 | ||
2329 | //! returns the current render target size | 2329 | //! returns the current render target size |
2330 | const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize() const | 2330 | const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize() const |
2331 | { | 2331 | { |
2332 | return RenderTargetSize; | 2332 | return RenderTargetSize; |
2333 | } | 2333 | } |
2334 | 2334 | ||
2335 | 2335 | ||
2336 | //!Draws an 2d rectangle with a gradient. | 2336 | //!Draws an 2d rectangle with a gradient. |
2337 | void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position, | 2337 | void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position, |
2338 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, | 2338 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, |
2339 | const core::rect<s32>* clip) | 2339 | const core::rect<s32>* clip) |
2340 | { | 2340 | { |
2341 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR | 2341 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR |
2342 | 2342 | ||
2343 | core::rect<s32> pos = position; | 2343 | core::rect<s32> pos = position; |
2344 | 2344 | ||
2345 | if (clip) | 2345 | if (clip) |
2346 | pos.clipAgainst(*clip); | 2346 | pos.clipAgainst(*clip); |
2347 | 2347 | ||
2348 | if (!pos.isValid()) | 2348 | if (!pos.isValid()) |
2349 | return; | 2349 | return; |
2350 | 2350 | ||
2351 | const core::dimension2d<s32> renderTargetSize ( ViewPort.getSize() ); | 2351 | const core::dimension2d<s32> renderTargetSize ( ViewPort.getSize() ); |
2352 | 2352 | ||
2353 | const s32 xPlus = -(renderTargetSize.Width>>1); | 2353 | const s32 xPlus = -(renderTargetSize.Width>>1); |
2354 | const f32 xFact = 1.0f / (renderTargetSize.Width>>1); | 2354 | const f32 xFact = 1.0f / (renderTargetSize.Width>>1); |
2355 | 2355 | ||
2356 | const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); | 2356 | const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); |
2357 | const f32 yFact = 1.0f / (renderTargetSize.Height>>1); | 2357 | const f32 yFact = 1.0f / (renderTargetSize.Height>>1); |
2358 | 2358 | ||
2359 | // fill VertexCache direct | 2359 | // fill VertexCache direct |
2360 | s4DVertex *v; | 2360 | s4DVertex *v; |
2361 | 2361 | ||
2362 | VertexCache.vertexCount = 4; | 2362 | VertexCache.vertexCount = 4; |
2363 | 2363 | ||
2364 | VertexCache.info[0].index = 0; | 2364 | VertexCache.info[0].index = 0; |
2365 | VertexCache.info[1].index = 1; | 2365 | VertexCache.info[1].index = 1; |
2366 | VertexCache.info[2].index = 2; | 2366 | VertexCache.info[2].index = 2; |
2367 | VertexCache.info[3].index = 3; | 2367 | VertexCache.info[3].index = 3; |
2368 | 2368 | ||
2369 | v = &VertexCache.mem.data [ 0 ]; | 2369 | v = &VertexCache.mem.data [ 0 ]; |
2370 | 2370 | ||
2371 | v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); | 2371 | v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); |
2372 | v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color ); | 2372 | v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color ); |
2373 | 2373 | ||
2374 | v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); | 2374 | v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); |
2375 | v[2].Color[0].setA8R8G8B8 ( colorRightUp.color ); | 2375 | v[2].Color[0].setA8R8G8B8 ( colorRightUp.color ); |
2376 | 2376 | ||
2377 | v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f ); | 2377 | v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f ); |
2378 | v[4].Color[0].setA8R8G8B8 ( colorRightDown.color ); | 2378 | v[4].Color[0].setA8R8G8B8 ( colorRightDown.color ); |
2379 | 2379 | ||
2380 | v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f ); | 2380 | v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f ); |
2381 | v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color ); | 2381 | v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color ); |
2382 | 2382 | ||
2383 | s32 i; | 2383 | s32 i; |
2384 | u32 g; | 2384 | u32 g; |
2385 | 2385 | ||
2386 | for ( i = 0; i!= 8; i += 2 ) | 2386 | for ( i = 0; i!= 8; i += 2 ) |
2387 | { | 2387 | { |
2388 | v[i + 0].flag = clipToFrustumTest ( v + i ); | 2388 | v[i + 0].flag = clipToFrustumTest ( v + i ); |
2389 | v[i + 1].flag = 0; | 2389 | v[i + 1].flag = 0; |
2390 | if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE ) | 2390 | if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE ) |
2391 | { | 2391 | { |
2392 | ndc_2_dc_and_project ( v + i + 1, v + i, 2 ); | 2392 | ndc_2_dc_and_project ( v + i + 1, v + i, 2 ); |
2393 | } | 2393 | } |
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | 2396 | ||
2397 | IBurningShader * render; | 2397 | IBurningShader * render; |
2398 | 2398 | ||
2399 | render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ]; | 2399 | render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ]; |
2400 | render->setRenderTarget(RenderTargetSurface, ViewPort); | 2400 | render->setRenderTarget(RenderTargetSurface, ViewPort); |
2401 | 2401 | ||
2402 | static const s16 indexList[6] = {0,1,2,0,2,3}; | 2402 | static const s16 indexList[6] = {0,1,2,0,2,3}; |
2403 | 2403 | ||
2404 | s4DVertex * face[3]; | 2404 | s4DVertex * face[3]; |
2405 | 2405 | ||
2406 | for ( i = 0; i!= 6; i += 3 ) | 2406 | for ( i = 0; i!= 6; i += 3 ) |
2407 | { | 2407 | { |
2408 | face[0] = VertexCache_getVertex ( indexList [ i + 0 ] ); | 2408 | face[0] = VertexCache_getVertex ( indexList [ i + 0 ] ); |
2409 | face[1] = VertexCache_getVertex ( indexList [ i + 1 ] ); | 2409 | face[1] = VertexCache_getVertex ( indexList [ i + 1 ] ); |
2410 | face[2] = VertexCache_getVertex ( indexList [ i + 2 ] ); | 2410 | face[2] = VertexCache_getVertex ( indexList [ i + 2 ] ); |
2411 | 2411 | ||
2412 | // test clipping | 2412 | // test clipping |
2413 | u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE; | 2413 | u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE; |
2414 | 2414 | ||
2415 | if ( test == VERTEX4D_INSIDE ) | 2415 | if ( test == VERTEX4D_INSIDE ) |
2416 | { | 2416 | { |
2417 | render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); | 2417 | render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); |
2418 | continue; | 2418 | continue; |
2419 | } | 2419 | } |
2420 | // Todo: all vertices are clipped in 2d.. | 2420 | // Todo: all vertices are clipped in 2d.. |
2421 | // is this true ? | 2421 | // is this true ? |
2422 | u32 vOut = 6; | 2422 | u32 vOut = 6; |
2423 | memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 ); | 2423 | memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 ); |
2424 | memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 ); | 2424 | memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 ); |
2425 | memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 ); | 2425 | memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 ); |
2426 | 2426 | ||
2427 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); | 2427 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); |
2428 | if ( vOut < 3 ) | 2428 | if ( vOut < 3 ) |
2429 | continue; | 2429 | continue; |
2430 | 2430 | ||
2431 | vOut <<= 1; | 2431 | vOut <<= 1; |
2432 | // to DC Space, project homogenous vertex | 2432 | // to DC Space, project homogenous vertex |
2433 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); | 2433 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); |
2434 | 2434 | ||
2435 | // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) | 2435 | // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) |
2436 | for ( g = 0; g <= vOut - 6; g += 2 ) | 2436 | for ( g = 0; g <= vOut - 6; g += 2 ) |
2437 | { | 2437 | { |
2438 | // rasterize | 2438 | // rasterize |
2439 | render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] ); | 2439 | render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] ); |
2440 | } | 2440 | } |
2441 | 2441 | ||
2442 | } | 2442 | } |
2443 | #else | 2443 | #else |
2444 | draw2DRectangle ( colorLeftUp, position, clip ); | 2444 | draw2DRectangle ( colorLeftUp, position, clip ); |
2445 | #endif | 2445 | #endif |
2446 | } | 2446 | } |
2447 | 2447 | ||
2448 | 2448 | ||
2449 | //! Draws a 3d line. | 2449 | //! Draws a 3d line. |
2450 | void CBurningVideoDriver::draw3DLine(const core::vector3df& start, | 2450 | void CBurningVideoDriver::draw3DLine(const core::vector3df& start, |
2451 | const core::vector3df& end, SColor color) | 2451 | const core::vector3df& end, SColor color) |
2452 | { | 2452 | { |
2453 | Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start ); | 2453 | Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start ); |
2454 | Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end ); | 2454 | Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end ); |
2455 | 2455 | ||
2456 | u32 g; | 2456 | u32 g; |
2457 | u32 vOut; | 2457 | u32 vOut; |
2458 | 2458 | ||
2459 | // no clipping flags | 2459 | // no clipping flags |
2460 | for ( g = 0; g != CurrentOut.ElementSize; ++g ) | 2460 | for ( g = 0; g != CurrentOut.ElementSize; ++g ) |
2461 | { | 2461 | { |
2462 | CurrentOut.data[g].flag = 0; | 2462 | CurrentOut.data[g].flag = 0; |
2463 | Temp.data[g].flag = 0; | 2463 | Temp.data[g].flag = 0; |
2464 | } | 2464 | } |
2465 | 2465 | ||
2466 | // vertices count per line | 2466 | // vertices count per line |
2467 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 ); | 2467 | vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 ); |
2468 | if ( vOut < 2 ) | 2468 | if ( vOut < 2 ) |
2469 | return; | 2469 | return; |
2470 | 2470 | ||
2471 | vOut <<= 1; | 2471 | vOut <<= 1; |
2472 | 2472 | ||
2473 | IBurningShader * line; | 2473 | IBurningShader * line; |
2474 | line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ]; | 2474 | line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ]; |
2475 | line->setRenderTarget(RenderTargetSurface, ViewPort); | 2475 | line->setRenderTarget(RenderTargetSurface, ViewPort); |
2476 | 2476 | ||
2477 | // to DC Space, project homogenous vertex | 2477 | // to DC Space, project homogenous vertex |
2478 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); | 2478 | ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); |
2479 | 2479 | ||
2480 | // unproject vertex color | 2480 | // unproject vertex color |
2481 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR | 2481 | #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR |
2482 | for ( g = 0; g != vOut; g+= 2 ) | 2482 | for ( g = 0; g != vOut; g+= 2 ) |
2483 | { | 2483 | { |
2484 | CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color ); | 2484 | CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color ); |
2485 | } | 2485 | } |
2486 | #endif | 2486 | #endif |
2487 | 2487 | ||
2488 | 2488 | ||
2489 | for ( g = 0; g <= vOut - 4; g += 2 ) | 2489 | for ( g = 0; g <= vOut - 4; g += 2 ) |
2490 | { | 2490 | { |
2491 | // rasterize | 2491 | // rasterize |
2492 | line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 ); | 2492 | line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 ); |
2493 | } | 2493 | } |
2494 | } | 2494 | } |
2495 | 2495 | ||
2496 | 2496 | ||
2497 | //! \return Returns the name of the video driver. Example: In case of the DirectX8 | 2497 | //! \return Returns the name of the video driver. Example: In case of the DirectX8 |
2498 | //! driver, it would return "Direct3D8.1". | 2498 | //! driver, it would return "Direct3D8.1". |
2499 | const wchar_t* CBurningVideoDriver::getName() const | 2499 | const wchar_t* CBurningVideoDriver::getName() const |
2500 | { | 2500 | { |
2501 | #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL | 2501 | #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL |
2502 | return L"Burning's Video 0.47 beautiful"; | 2502 | return L"Burning's Video 0.47 beautiful"; |
2503 | #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) | 2503 | #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) |
2504 | return L"Burning's Video 0.47 ultra fast"; | 2504 | return L"Burning's Video 0.47 ultra fast"; |
2505 | #elif defined ( BURNINGVIDEO_RENDERER_FAST ) | 2505 | #elif defined ( BURNINGVIDEO_RENDERER_FAST ) |
2506 | return L"Burning's Video 0.47 fast"; | 2506 | return L"Burning's Video 0.47 fast"; |
2507 | #else | 2507 | #else |
2508 | return L"Burning's Video 0.47"; | 2508 | return L"Burning's Video 0.47"; |
2509 | #endif | 2509 | #endif |
2510 | } | 2510 | } |
2511 | 2511 | ||
2512 | //! Returns the graphics card vendor name. | 2512 | //! Returns the graphics card vendor name. |
2513 | core::stringc CBurningVideoDriver::getVendorInfo() | 2513 | core::stringc CBurningVideoDriver::getVendorInfo() |
2514 | { | 2514 | { |
2515 | return "Burning's Video: Ing. Thomas Alten (c) 2006-2012"; | 2515 | return "Burning's Video: Ing. Thomas Alten (c) 2006-2012"; |
2516 | } | 2516 | } |
2517 | 2517 | ||
2518 | 2518 | ||
2519 | //! Returns type of video driver | 2519 | //! Returns type of video driver |
2520 | E_DRIVER_TYPE CBurningVideoDriver::getDriverType() const | 2520 | E_DRIVER_TYPE CBurningVideoDriver::getDriverType() const |
2521 | { | 2521 | { |
2522 | return EDT_BURNINGSVIDEO; | 2522 | return EDT_BURNINGSVIDEO; |
2523 | } | 2523 | } |
2524 | 2524 | ||
2525 | 2525 | ||
2526 | //! returns color format | 2526 | //! returns color format |
2527 | ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const | 2527 | ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const |
2528 | { | 2528 | { |
2529 | return BURNINGSHADER_COLOR_FORMAT; | 2529 | return BURNINGSHADER_COLOR_FORMAT; |
2530 | } | 2530 | } |
2531 | 2531 | ||
2532 | 2532 | ||
2533 | //! Returns the transformation set by setTransform | 2533 | //! Returns the transformation set by setTransform |
2534 | const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const | 2534 | const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const |
2535 | { | 2535 | { |
2536 | return Transformation[state]; | 2536 | return Transformation[state]; |
2537 | } | 2537 | } |
2538 | 2538 | ||
2539 | 2539 | ||
2540 | //! Creates a render target texture. | 2540 | //! Creates a render target texture. |
2541 | ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, | 2541 | ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, |
2542 | const io::path& name, const ECOLOR_FORMAT format) | 2542 | const io::path& name, const ECOLOR_FORMAT format) |
2543 | { | 2543 | { |
2544 | IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size); | 2544 | IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size); |
2545 | ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET ); | 2545 | ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET ); |
2546 | img->drop(); | 2546 | img->drop(); |
2547 | addTexture(tex); | 2547 | addTexture(tex); |
2548 | tex->drop(); | 2548 | tex->drop(); |
2549 | return tex; | 2549 | return tex; |
2550 | } | 2550 | } |
2551 | 2551 | ||
2552 | 2552 | ||
2553 | //! Clears the DepthBuffer. | 2553 | //! Clears the DepthBuffer. |
2554 | void CBurningVideoDriver::clearZBuffer() | 2554 | void CBurningVideoDriver::clearZBuffer() |
2555 | { | 2555 | { |
2556 | if (DepthBuffer) | 2556 | if (DepthBuffer) |
2557 | DepthBuffer->clear(); | 2557 | DepthBuffer->clear(); |
2558 | } | 2558 | } |
2559 | 2559 | ||
2560 | 2560 | ||
2561 | //! Returns an image created from the last rendered frame. | 2561 | //! Returns an image created from the last rendered frame. |
2562 | IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) | 2562 | IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) |
2563 | { | 2563 | { |
2564 | if (target != video::ERT_FRAME_BUFFER) | 2564 | if (target != video::ERT_FRAME_BUFFER) |
2565 | return 0; | 2565 | return 0; |
2566 | 2566 | ||
2567 | if (BackBuffer) | 2567 | if (BackBuffer) |
2568 | { | 2568 | { |
2569 | IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension()); | 2569 | IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension()); |
2570 | BackBuffer->copyTo(tmp); | 2570 | BackBuffer->copyTo(tmp); |
2571 | return tmp; | 2571 | return tmp; |
2572 | } | 2572 | } |
2573 | else | 2573 | else |
2574 | return 0; | 2574 | return 0; |
2575 | } | 2575 | } |
2576 | 2576 | ||
2577 | 2577 | ||
2578 | //! returns a device dependent texture from a software surface (IImage) | 2578 | //! returns a device dependent texture from a software surface (IImage) |
2579 | //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES | 2579 | //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES |
2580 | ITexture* CBurningVideoDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) | 2580 | ITexture* CBurningVideoDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) |
2581 | { | 2581 | { |
2582 | return new CSoftwareTexture2( | 2582 | return new CSoftwareTexture2( |
2583 | surface, name, | 2583 | surface, name, |
2584 | (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0 ) | | 2584 | (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0 ) | |
2585 | (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE ), mipmapData); | 2585 | (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE ), mipmapData); |
2586 | 2586 | ||
2587 | } | 2587 | } |
2588 | 2588 | ||
2589 | 2589 | ||
2590 | //! Returns the maximum amount of primitives (mostly vertices) which | 2590 | //! Returns the maximum amount of primitives (mostly vertices) which |
2591 | //! the device is able to render with one drawIndexedTriangleList | 2591 | //! the device is able to render with one drawIndexedTriangleList |
2592 | //! call. | 2592 | //! call. |
2593 | u32 CBurningVideoDriver::getMaximalPrimitiveCount() const | 2593 | u32 CBurningVideoDriver::getMaximalPrimitiveCount() const |
2594 | { | 2594 | { |
2595 | return 0xFFFFFFFF; | 2595 | return 0xFFFFFFFF; |
2596 | } | 2596 | } |
2597 | 2597 | ||
2598 | 2598 | ||
2599 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do | 2599 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do |
2600 | //! this: First, draw all geometry. Then use this method, to draw the shadow | 2600 | //! this: First, draw all geometry. Then use this method, to draw the shadow |
2601 | //! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. | 2601 | //! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. |
2602 | void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) | 2602 | void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) |
2603 | { | 2603 | { |
2604 | const u32 count = triangles.size(); | 2604 | const u32 count = triangles.size(); |
2605 | IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ]; | 2605 | IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ]; |
2606 | 2606 | ||
2607 | CurrentShader = shader; | 2607 | CurrentShader = shader; |
2608 | shader->setRenderTarget(RenderTargetSurface, ViewPort); | 2608 | shader->setRenderTarget(RenderTargetSurface, ViewPort); |
2609 | 2609 | ||
2610 | Material.org.MaterialType = video::EMT_SOLID; | 2610 | Material.org.MaterialType = video::EMT_SOLID; |
2611 | Material.org.Lighting = false; | 2611 | Material.org.Lighting = false; |
2612 | Material.org.ZWriteEnable = false; | 2612 | Material.org.ZWriteEnable = false; |
2613 | Material.org.ZBuffer = ECFN_LESSEQUAL; | 2613 | Material.org.ZBuffer = ECFN_LESSEQUAL; |
2614 | LightSpace.Flags &= ~VERTEXTRANSFORM; | 2614 | LightSpace.Flags &= ~VERTEXTRANSFORM; |
2615 | 2615 | ||
2616 | //glStencilMask(~0); | 2616 | //glStencilMask(~0); |
2617 | //glStencilFunc(GL_ALWAYS, 0, ~0); | 2617 | //glStencilFunc(GL_ALWAYS, 0, ~0); |
2618 | 2618 | ||
2619 | if (true)// zpass does not work yet | 2619 | if (true)// zpass does not work yet |
2620 | { | 2620 | { |
2621 | Material.org.BackfaceCulling = true; | 2621 | Material.org.BackfaceCulling = true; |
2622 | Material.org.FrontfaceCulling = false; | 2622 | Material.org.FrontfaceCulling = false; |
2623 | shader->setParam ( 0, 0 ); | 2623 | shader->setParam ( 0, 0 ); |
2624 | shader->setParam ( 1, 1 ); | 2624 | shader->setParam ( 1, 1 ); |
2625 | shader->setParam ( 2, 0 ); | 2625 | shader->setParam ( 2, 0 ); |
2626 | drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); | 2626 | drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); |
2627 | //glStencilOp(GL_KEEP, incr, GL_KEEP); | 2627 | //glStencilOp(GL_KEEP, incr, GL_KEEP); |
2628 | //glDrawArrays(GL_TRIANGLES,0,count); | 2628 | //glDrawArrays(GL_TRIANGLES,0,count); |
2629 | 2629 | ||
2630 | Material.org.BackfaceCulling = false; | 2630 | Material.org.BackfaceCulling = false; |
2631 | Material.org.FrontfaceCulling = true; | 2631 | Material.org.FrontfaceCulling = true; |
2632 | shader->setParam ( 0, 0 ); | 2632 | shader->setParam ( 0, 0 ); |
2633 | shader->setParam ( 1, 2 ); | 2633 | shader->setParam ( 1, 2 ); |
2634 | shader->setParam ( 2, 0 ); | 2634 | shader->setParam ( 2, 0 ); |
2635 | drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); | 2635 | drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); |
2636 | //glStencilOp(GL_KEEP, decr, GL_KEEP); | 2636 | //glStencilOp(GL_KEEP, decr, GL_KEEP); |
2637 | //glDrawArrays(GL_TRIANGLES,0,count); | 2637 | //glDrawArrays(GL_TRIANGLES,0,count); |
2638 | } | 2638 | } |
2639 | else // zpass | 2639 | else // zpass |
2640 | { | 2640 | { |
2641 | Material.org.BackfaceCulling = true; | 2641 | Material.org.BackfaceCulling = true; |
2642 | Material.org.FrontfaceCulling = false; | 2642 | Material.org.FrontfaceCulling = false; |
2643 | shader->setParam ( 0, 0 ); | 2643 | shader->setParam ( 0, 0 ); |
2644 | shader->setParam ( 1, 0 ); | 2644 | shader->setParam ( 1, 0 ); |
2645 | shader->setParam ( 2, 1 ); | 2645 | shader->setParam ( 2, 1 ); |
2646 | //glStencilOp(GL_KEEP, GL_KEEP, incr); | 2646 | //glStencilOp(GL_KEEP, GL_KEEP, incr); |
2647 | //glDrawArrays(GL_TRIANGLES,0,count); | 2647 | //glDrawArrays(GL_TRIANGLES,0,count); |
2648 | 2648 | ||
2649 | Material.org.BackfaceCulling = false; | 2649 | Material.org.BackfaceCulling = false; |
2650 | Material.org.FrontfaceCulling = true; | 2650 | Material.org.FrontfaceCulling = true; |
2651 | shader->setParam ( 0, 0 ); | 2651 | shader->setParam ( 0, 0 ); |
2652 | shader->setParam ( 1, 0 ); | 2652 | shader->setParam ( 1, 0 ); |
2653 | shader->setParam ( 2, 2 ); | 2653 | shader->setParam ( 2, 2 ); |
2654 | //glStencilOp(GL_KEEP, GL_KEEP, decr); | 2654 | //glStencilOp(GL_KEEP, GL_KEEP, decr); |
2655 | //glDrawArrays(GL_TRIANGLES,0,count); | 2655 | //glDrawArrays(GL_TRIANGLES,0,count); |
2656 | } | 2656 | } |
2657 | } | 2657 | } |
2658 | 2658 | ||
2659 | //! Fills the stencil shadow with color. After the shadow volume has been drawn | 2659 | //! Fills the stencil shadow with color. After the shadow volume has been drawn |
2660 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this | 2660 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this |
2661 | //! to draw the color of the shadow. | 2661 | //! to draw the color of the shadow. |
2662 | void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, | 2662 | void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, |
2663 | video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) | 2663 | video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) |
2664 | { | 2664 | { |
2665 | if (!StencilBuffer) | 2665 | if (!StencilBuffer) |
2666 | return; | 2666 | return; |
2667 | // draw a shadow rectangle covering the entire screen using stencil buffer | 2667 | // draw a shadow rectangle covering the entire screen using stencil buffer |
2668 | const u32 h = RenderTargetSurface->getDimension().Height; | 2668 | const u32 h = RenderTargetSurface->getDimension().Height; |
2669 | const u32 w = RenderTargetSurface->getDimension().Width; | 2669 | const u32 w = RenderTargetSurface->getDimension().Width; |
2670 | tVideoSample *dst; | 2670 | tVideoSample *dst; |
2671 | u32 *stencil; | 2671 | u32 *stencil; |
2672 | u32* const stencilBase=(u32*) StencilBuffer->lock(); | 2672 | u32* const stencilBase=(u32*) StencilBuffer->lock(); |
2673 | 2673 | ||
2674 | for ( u32 y = 0; y < h; ++y ) | 2674 | for ( u32 y = 0; y < h; ++y ) |
2675 | { | 2675 | { |
2676 | dst = (tVideoSample*)RenderTargetSurface->lock() + ( y * w ); | 2676 | dst = (tVideoSample*)RenderTargetSurface->lock() + ( y * w ); |
2677 | stencil = stencilBase + ( y * w ); | 2677 | stencil = stencilBase + ( y * w ); |
2678 | 2678 | ||
2679 | for ( u32 x = 0; x < w; ++x ) | 2679 | for ( u32 x = 0; x < w; ++x ) |
2680 | { | 2680 | { |
2681 | if ( stencil[x] > 1 ) | 2681 | if ( stencil[x] > 1 ) |
2682 | { | 2682 | { |
2683 | dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color ); | 2683 | dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color ); |
2684 | } | 2684 | } |
2685 | } | 2685 | } |
2686 | } | 2686 | } |
2687 | 2687 | ||
2688 | StencilBuffer->clear(); | 2688 | StencilBuffer->clear(); |
2689 | } | 2689 | } |
2690 | 2690 | ||
2691 | 2691 | ||
2692 | core::dimension2du CBurningVideoDriver::getMaxTextureSize() const | 2692 | core::dimension2du CBurningVideoDriver::getMaxTextureSize() const |
2693 | { | 2693 | { |
2694 | return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE); | 2694 | return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE); |
2695 | } | 2695 | } |
2696 | 2696 | ||
2697 | 2697 | ||
2698 | } // end namespace video | 2698 | } // end namespace video |
2699 | } // end namespace irr | 2699 | } // end namespace irr |
2700 | 2700 | ||
2701 | #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ | 2701 | #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ |
2702 | 2702 | ||
2703 | namespace irr | 2703 | namespace irr |
2704 | { | 2704 | { |
2705 | namespace video | 2705 | namespace video |
2706 | { | 2706 | { |
2707 | 2707 | ||
2708 | //! creates a video driver | 2708 | //! creates a video driver |
2709 | IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) | 2709 | IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) |
2710 | { | 2710 | { |
2711 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ | 2711 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ |
2712 | return new CBurningVideoDriver(params, io, presenter); | 2712 | return new CBurningVideoDriver(params, io, presenter); |
2713 | #else | 2713 | #else |
2714 | return 0; | 2714 | return 0; |
2715 | #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ | 2715 | #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ |
2716 | } | 2716 | } |
2717 | 2717 | ||
2718 | 2718 | ||
2719 | 2719 | ||
2720 | } // end namespace video | 2720 | } // end namespace video |
2721 | } // end namespace irr | 2721 | } // end namespace irr |
2722 | 2722 | ||