LEFT | RIGHT |
1 /* | 1 /* |
2 * $Id$ | |
3 * | |
4 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
5 * | 3 * |
6 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
8 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
9 * of the License, or (at your option) any later version.· | 7 * of the License, or (at your option) any later version.· |
10 * | 8 * |
11 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 GPUPass *pass; | 87 GPUPass *pass; |
90 GPUVertexAttribs attribs; | 88 GPUVertexAttribs attribs; |
91 int bound; | 89 int bound; |
92 int builtins; | 90 int builtins; |
93 int alpha, obcolalpha; | 91 int alpha, obcolalpha; |
94 int dynproperty; | 92 int dynproperty; |
95 | 93 |
96 /* for passing uniforms */ | 94 /* for passing uniforms */ |
97 int viewmatloc, invviewmatloc; | 95 int viewmatloc, invviewmatloc; |
98 int obmatloc, invobmatloc; | 96 int obmatloc, invobmatloc; |
99 » int obcolloc; | 97 » int obcolloc, obautobumpscaleloc; |
100 | 98 |
101 ListBase lamps; | 99 ListBase lamps; |
102 }; | 100 }; |
103 | 101 |
104 struct GPULamp { | 102 struct GPULamp { |
105 Scene *scene; | 103 Scene *scene; |
106 Object *ob; | 104 Object *ob; |
107 Object *par; | 105 Object *par; |
108 Lamp *la; | 106 Lamp *la; |
109 | 107 |
110 int type, mode, lay, hide; | 108 int type, mode, lay, hide; |
111 | 109 |
112 float dynenergy, dyncol[3]; | 110 float dynenergy, dyncol[3]; |
113 float energy, col[3]; | 111 float energy, col[3]; |
114 | 112 |
115 float co[3], vec[3]; | 113 float co[3], vec[3]; |
116 float dynco[3], dynvec[3]; | 114 float dynco[3], dynvec[3]; |
117 float obmat[4][4]; | 115 float obmat[4][4]; |
118 float imat[4][4]; | 116 float imat[4][4]; |
119 float dynimat[4][4]; | 117 float dynimat[4][4]; |
120 | 118 |
121 float spotsi, spotbl, k; | 119 float spotsi, spotbl, k; |
| 120 float dyndist, dynatt1, dynatt2; |
122 float dist, att1, att2; | 121 float dist, att1, att2; |
| 122 float shadow_color[3]; |
123 | 123 |
124 float bias, d, clipend; | 124 float bias, d, clipend; |
125 int size; | 125 int size; |
126 | 126 |
127 int falloff_type; | 127 int falloff_type; |
128 struct CurveMapping *curfalloff; | 128 struct CurveMapping *curfalloff; |
129 | 129 |
130 float winmat[4][4]; | 130 float winmat[4][4]; |
131 float viewmat[4][4]; | 131 float viewmat[4][4]; |
132 float persmat[4][4]; | 132 float persmat[4][4]; |
133 float dynpersmat[4][4]; | 133 float dynpersmat[4][4]; |
134 | 134 |
135 GPUFrameBuffer *fb; | 135 GPUFrameBuffer *fb; |
| 136 GPUFrameBuffer *blurfb; |
136 GPUTexture *tex; | 137 GPUTexture *tex; |
| 138 GPUTexture *depthtex; |
| 139 GPUTexture *blurtex; |
137 | 140 |
138 ListBase materials; | 141 ListBase materials; |
139 }; | 142 }; |
| 143 |
| 144 /* Forward declaration so shade_light_textures() can use this, while still keepi
ng the code somewhat organized */ |
| 145 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *o
ut, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in); |
140 | 146 |
141 /* Functions */ | 147 /* Functions */ |
142 | 148 |
143 static GPUMaterial *GPU_material_construct_begin(Material *ma) | 149 static GPUMaterial *GPU_material_construct_begin(Material *ma) |
144 { | 150 { |
145 GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); | 151 GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); |
146 | 152 |
147 material->ma= ma; | 153 material->ma= ma; |
148 | 154 |
149 return material; | 155 return material; |
150 } | 156 } |
151 | 157 |
152 static void gpu_material_set_attrib_id(GPUMaterial *material) | 158 static void gpu_material_set_attrib_id(GPUMaterial *material) |
153 { | 159 { |
154 GPUVertexAttribs *attribs; | 160 GPUVertexAttribs *attribs; |
155 GPUShader *shader; | 161 GPUShader *shader; |
156 GPUPass *pass; | 162 GPUPass *pass; |
157 char name[32]; | 163 char name[32]; |
158 int a, b; | 164 int a, b; |
159 | 165 |
160 attribs= &material->attribs; | 166 attribs= &material->attribs; |
161 pass= material->pass; | 167 pass= material->pass; |
162 » if(!pass) { | 168 » if (!pass) { |
163 attribs->totlayer = 0; | 169 attribs->totlayer = 0; |
164 return; | 170 return; |
165 } | 171 } |
166 ········ | 172 ········ |
167 shader= GPU_pass_shader(pass); | 173 shader= GPU_pass_shader(pass); |
168 » if(!shader) { | 174 » if (!shader) { |
169 attribs->totlayer = 0; | 175 attribs->totlayer = 0; |
170 return; | 176 return; |
171 } | 177 } |
172 | 178 |
173 /* convert from attribute number to the actual id assigned by opengl, | 179 /* convert from attribute number to the actual id assigned by opengl, |
174 * in case the attrib does not get a valid index back, it was probably | 180 * in case the attrib does not get a valid index back, it was probably |
175 * removed by the glsl compiler by dead code elimination */ | 181 * removed by the glsl compiler by dead code elimination */ |
176 | 182 |
177 » for(a=0, b=0; a<attribs->totlayer; a++) { | 183 » for (a=0, b=0; a<attribs->totlayer; a++) { |
178 » » sprintf(name, "att%d", attribs->layer[a].attribid); | 184 » » BLI_snprintf(name, sizeof(name), "att%d", attribs->layer[a].attr
ibid); |
179 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, nam
e); | 185 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, nam
e); |
180 | 186 |
181 » » if(attribs->layer[a].glindex >= 0) { | 187 » » if (attribs->layer[a].glindex >= 0) { |
182 attribs->layer[b] = attribs->layer[a]; | 188 attribs->layer[b] = attribs->layer[a]; |
183 b++; | 189 b++; |
184 } | 190 } |
185 } | 191 } |
186 | 192 |
187 attribs->totlayer = b; | 193 attribs->totlayer = b; |
188 } | 194 } |
189 | 195 |
190 static int GPU_material_construct_end(GPUMaterial *material) | 196 static int GPU_material_construct_end(GPUMaterial *material) |
191 { | 197 { |
192 if (material->outlink) { | 198 if (material->outlink) { |
193 GPUNodeLink *outlink; | 199 GPUNodeLink *outlink; |
194 GPUShader *shader; | 200 GPUShader *shader; |
195 | 201 |
196 outlink = material->outlink; | 202 outlink = material->outlink; |
197 material->pass = GPU_generate_pass(&material->nodes, outlink, | 203 material->pass = GPU_generate_pass(&material->nodes, outlink, |
198 &material->attribs, &material->builtins, material->ma->i
d.name); | 204 &material->attribs, &material->builtins, material->ma->i
d.name); |
199 | 205 |
200 » » if(!material->pass) | 206 » » if (!material->pass) |
201 return 0; | 207 return 0; |
202 | 208 |
203 gpu_material_set_attrib_id(material); | 209 gpu_material_set_attrib_id(material); |
204 ················ | 210 ················ |
205 shader = GPU_pass_shader(material->pass); | 211 shader = GPU_pass_shader(material->pass); |
206 | 212 |
207 » » if(material->builtins & GPU_VIEW_MATRIX) | 213 » » if (material->builtins & GPU_VIEW_MATRIX) |
208 material->viewmatloc = GPU_shader_get_uniform(shader, GP
U_builtin_name(GPU_VIEW_MATRIX)); | 214 material->viewmatloc = GPU_shader_get_uniform(shader, GP
U_builtin_name(GPU_VIEW_MATRIX)); |
209 » » if(material->builtins & GPU_INVERSE_VIEW_MATRIX) | 215 » » if (material->builtins & GPU_INVERSE_VIEW_MATRIX) |
210 material->invviewmatloc = GPU_shader_get_uniform(shader,
GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX)); | 216 material->invviewmatloc = GPU_shader_get_uniform(shader,
GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX)); |
211 » » if(material->builtins & GPU_OBJECT_MATRIX) | 217 » » if (material->builtins & GPU_OBJECT_MATRIX) |
212 material->obmatloc = GPU_shader_get_uniform(shader, GPU_
builtin_name(GPU_OBJECT_MATRIX)); | 218 material->obmatloc = GPU_shader_get_uniform(shader, GPU_
builtin_name(GPU_OBJECT_MATRIX)); |
213 » » if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) | 219 » » if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) |
214 material->invobmatloc = GPU_shader_get_uniform(shader, G
PU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); | 220 material->invobmatloc = GPU_shader_get_uniform(shader, G
PU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); |
215 » » if(material->builtins & GPU_OBCOLOR) | 221 » » if (material->builtins & GPU_OBCOLOR) |
216 material->obcolloc = GPU_shader_get_uniform(shader, GPU_
builtin_name(GPU_OBCOLOR)); | 222 material->obcolloc = GPU_shader_get_uniform(shader, GPU_
builtin_name(GPU_OBCOLOR)); |
217 | 223 » » if (material->builtins & GPU_AUTO_BUMPSCALE) |
| 224 » » » material->obautobumpscaleloc = GPU_shader_get_uniform(sh
ader, GPU_builtin_name(GPU_AUTO_BUMPSCALE)); |
218 return 1; | 225 return 1; |
219 } | 226 } |
220 | 227 |
221 return 0; | 228 return 0; |
222 } | 229 } |
223 | 230 |
224 void GPU_material_free(Material *ma) | 231 void GPU_material_free(Material *ma) |
225 { | 232 { |
226 LinkData *link; | 233 LinkData *link; |
227 LinkData *nlink, *mlink, *next; | 234 LinkData *nlink, *mlink, *next; |
228 | 235 |
229 » for(link=ma->gpumaterial.first; link; link=link->next) { | 236 » for (link=ma->gpumaterial.first; link; link=link->next) { |
230 GPUMaterial *material = link->data; | 237 GPUMaterial *material = link->data; |
231 | 238 |
232 » » if(material->pass) | 239 » » if (material->pass) |
233 GPU_pass_free(material->pass); | 240 GPU_pass_free(material->pass); |
234 | 241 |
235 » » for(nlink=material->lamps.first; nlink; nlink=nlink->next) { | 242 » » for (nlink=material->lamps.first; nlink; nlink=nlink->next) { |
236 GPULamp *lamp = nlink->data; | 243 GPULamp *lamp = nlink->data; |
237 | 244 |
238 » » » for(mlink=lamp->materials.first; mlink; mlink=next) { | 245 » » » for (mlink=lamp->materials.first; mlink; mlink=next) { |
239 next = mlink->next; | 246 next = mlink->next; |
240 » » » » if(mlink->data == ma) | 247 » » » » if (mlink->data == ma) |
241 BLI_freelinkN(&lamp->materials, mlink); | 248 BLI_freelinkN(&lamp->materials, mlink); |
242 } | 249 } |
243 } | 250 } |
244 | 251 |
245 BLI_freelistN(&material->lamps); | 252 BLI_freelistN(&material->lamps); |
246 | 253 |
247 MEM_freeN(material); | 254 MEM_freeN(material); |
248 } | 255 } |
249 | 256 |
250 BLI_freelistN(&ma->gpumaterial); | 257 BLI_freelistN(&ma->gpumaterial); |
251 } | 258 } |
252 | 259 |
253 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
e, int mipmap) | 260 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
e, int mipmap, float viewmat[4][4], float viewinv[4][4]) |
254 { | 261 { |
255 » if(material->pass) { | 262 » if (material->pass) { |
256 LinkData *nlink; | 263 LinkData *nlink; |
257 GPULamp *lamp; | 264 GPULamp *lamp; |
| 265 GPUShader *shader = GPU_pass_shader(material->pass); |
258 | 266 |
259 /* handle layer lamps */ | 267 /* handle layer lamps */ |
260 » » for(nlink=material->lamps.first; nlink; nlink=nlink->next) { | 268 » » for (nlink=material->lamps.first; nlink; nlink=nlink->next) { |
261 lamp= nlink->data; | 269 lamp= nlink->data; |
262 | 270 |
263 » » » if(!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode
& LA_LAYER) || (lamp->lay & oblay))) { | 271 » » » if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mod
e & LA_LAYER) || (lamp->lay & oblay))) { |
264 lamp->dynenergy = lamp->energy; | 272 lamp->dynenergy = lamp->energy; |
265 » » » » VECCOPY(lamp->dyncol, lamp->col); | 273 » » » » copy_v3_v3(lamp->dyncol, lamp->col); |
266 } | 274 } |
267 else { | 275 else { |
268 lamp->dynenergy = 0.0f; | 276 lamp->dynenergy = 0.0f; |
269 lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2
] = 0.0f; | 277 lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2
] = 0.0f; |
270 } | 278 } |
271 » » } | 279 |
272 | 280 » » » if (material->dynproperty & DYN_LAMP_VEC) { |
273 » » GPU_pass_bind(material->pass, time, mipmap); | 281 » » » » copy_v3_v3(lamp->dynvec, lamp->vec); |
274 » » material->bound = 1; | |
275 » } | |
276 } | |
277 | |
278 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v
iewmat[][4], float viewinv[][4], float obcol[4]) | |
279 { | |
280 » if(material->pass) { | |
281 » » GPUShader *shader = GPU_pass_shader(material->pass); | |
282 » » LinkData *nlink; | |
283 » » GPULamp *lamp; | |
284 » » float invmat[4][4], col[4]; | |
285 | |
286 » » /* handle builtins */ | |
287 » » if(material->builtins & GPU_VIEW_MATRIX) { | |
288 » » » GPU_shader_uniform_vector(shader, material->viewmatloc,
16, 1, (float*)viewmat); | |
289 » » } | |
290 » » if(material->builtins & GPU_INVERSE_VIEW_MATRIX) { | |
291 » » » GPU_shader_uniform_vector(shader, material->invviewmatlo
c, 16, 1, (float*)viewinv); | |
292 » » } | |
293 » » if(material->builtins & GPU_OBJECT_MATRIX) { | |
294 » » » GPU_shader_uniform_vector(shader, material->obmatloc, 16
, 1, (float*)obmat); | |
295 » » } | |
296 » » if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) { | |
297 » » » invert_m4_m4(invmat, obmat); | |
298 » » » GPU_shader_uniform_vector(shader, material->invobmatloc,
16, 1, (float*)invmat); | |
299 » » } | |
300 » » if(material->builtins & GPU_OBCOLOR) { | |
301 » » » QUATCOPY(col, obcol); | |
302 » » » CLAMP(col[3], 0.0f, 1.0f); | |
303 » » » GPU_shader_uniform_vector(shader, material->obcolloc, 4,
1, col); | |
304 » » } | |
305 | |
306 » » /* update lamps */ | |
307 » » for(nlink=material->lamps.first; nlink; nlink=nlink->next) { | |
308 » » » lamp= nlink->data; | |
309 | |
310 » » » if(material->dynproperty & DYN_LAMP_VEC) { | |
311 » » » » VECCOPY(lamp->dynvec, lamp->vec); | |
312 normalize_v3(lamp->dynvec); | 282 normalize_v3(lamp->dynvec); |
313 negate_v3(lamp->dynvec); | 283 negate_v3(lamp->dynvec); |
314 mul_mat3_m4_v3(viewmat, lamp->dynvec); | 284 mul_mat3_m4_v3(viewmat, lamp->dynvec); |
315 } | 285 } |
316 | 286 |
317 » » » if(material->dynproperty & DYN_LAMP_CO) { | 287 » » » if (material->dynproperty & DYN_LAMP_CO) { |
318 » » » » VECCOPY(lamp->dynco, lamp->co); | 288 » » » » copy_v3_v3(lamp->dynco, lamp->co); |
319 mul_m4_v3(viewmat, lamp->dynco); | 289 mul_m4_v3(viewmat, lamp->dynco); |
320 } | 290 } |
321 | 291 |
322 » » » if(material->dynproperty & DYN_LAMP_IMAT) | 292 » » » if (material->dynproperty & DYN_LAMP_IMAT) { |
323 » » » » mul_m4_m4m4(lamp->dynimat, viewinv, lamp->imat); | 293 » » » » mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv); |
324 » » » if(material->dynproperty & DYN_LAMP_PERSMAT) | 294 » » » } |
325 » » » » mul_m4_m4m4(lamp->dynpersmat, viewinv, lamp->per
smat); | 295 |
| 296 » » » if (material->dynproperty & DYN_LAMP_PERSMAT) { |
| 297 » » » » if (!GPU_lamp_has_shadow_buffer(lamp)) /* The la
mp matrices are already updated if we're using shadow buffers */ |
| 298 » » » » » GPU_lamp_update_buffer_mats(lamp); |
| 299 » » » » mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, vie
winv); |
| 300 » » » } |
| 301 » » } |
| 302 |
| 303 » » /* note material must be bound before setting uniforms */ |
| 304 » » GPU_pass_bind(material->pass, time, mipmap); |
| 305 |
| 306 » » /* handle per material built-ins */ |
| 307 » » if (material->builtins & GPU_VIEW_MATRIX) { |
| 308 » » » GPU_shader_uniform_vector(shader, material->viewmatloc,
16, 1, (float*)viewmat); |
| 309 » » } |
| 310 » » if (material->builtins & GPU_INVERSE_VIEW_MATRIX) { |
| 311 » » » GPU_shader_uniform_vector(shader, material->invviewmatlo
c, 16, 1, (float*)viewinv); |
326 } | 312 } |
327 | 313 |
328 GPU_pass_update_uniforms(material->pass); | 314 GPU_pass_update_uniforms(material->pass); |
| 315 |
| 316 material->bound = 1; |
| 317 } |
| 318 } |
| 319 |
| 320 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float
obcol[4], float autobumpscale) |
| 321 { |
| 322 if (material->pass) { |
| 323 GPUShader *shader = GPU_pass_shader(material->pass); |
| 324 float invmat[4][4], col[4]; |
| 325 |
| 326 /* handle per object builtins */ |
| 327 if (material->builtins & GPU_OBJECT_MATRIX) { |
| 328 GPU_shader_uniform_vector(shader, material->obmatloc, 16
, 1, (float*)obmat); |
| 329 } |
| 330 if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) { |
| 331 invert_m4_m4(invmat, obmat); |
| 332 GPU_shader_uniform_vector(shader, material->invobmatloc,
16, 1, (float*)invmat); |
| 333 } |
| 334 if (material->builtins & GPU_OBCOLOR) { |
| 335 copy_v4_v4(col, obcol); |
| 336 CLAMP(col[3], 0.0f, 1.0f); |
| 337 GPU_shader_uniform_vector(shader, material->obcolloc, 4,
1, col); |
| 338 } |
| 339 if (material->builtins & GPU_AUTO_BUMPSCALE) { |
| 340 GPU_shader_uniform_vector(shader, material->obautobumpsc
aleloc, 1, 1, &autobumpscale); |
| 341 } |
329 } | 342 } |
330 } | 343 } |
331 | 344 |
332 void GPU_material_unbind(GPUMaterial *material) | 345 void GPU_material_unbind(GPUMaterial *material) |
333 { | 346 { |
334 if (material->pass) { | 347 if (material->pass) { |
335 material->bound = 0; | 348 material->bound = 0; |
336 GPU_pass_unbind(material->pass); | 349 GPU_pass_unbind(material->pass); |
337 } | 350 } |
338 } | 351 } |
339 | 352 |
340 int GPU_material_bound(GPUMaterial *material) | 353 int GPU_material_bound(GPUMaterial *material) |
341 { | 354 { |
342 return material->bound; | 355 return material->bound; |
343 } | 356 } |
344 | 357 |
345 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *att
ribs) | |
346 { | |
347 *attribs = material->attribs; | |
348 } | |
349 | |
350 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) | |
351 { | |
352 if(!material->outlink) | |
353 material->outlink= link; | |
354 } | |
355 | |
356 void GPU_material_enable_alpha(GPUMaterial *material) | |
357 { | |
358 material->alpha= 1; | 358 material->alpha= 1; |
359 } | 359 } |
360 | 360 |
361 GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]) | 361 GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]) |
362 { | 362 { |
363 if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f)) | 363 if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f)) |
364 return GPU_BLEND_ALPHA; | 364 return GPU_BLEND_ALPHA; |
365 else | |
366 return GPU_BLEND_SOLID; | |
367 } | |
368 | |
369 void gpu_material_add_node(GPUMaterial *material, GPUNode *node) | |
370 { | |
371 BLI_addtail(&material->nodes, node); | |
372 } | |
373 | |
374 /* Code generation */ | |
375 | |
376 static int gpu_do_color_management(GPUMaterial *mat) | |
377 { | |
378 return ((mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) && | |
379 !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT))); | |
380 } | |
381 | |
382 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNode
Link **lv, GPUNodeLink **dist) | |
383 { | |
384 GPUNodeLink *visifac, *inpr; | |
385 | |
386 /* from get_lamp_visibility */ | |
387 if(lamp->type==LA_SUN || lamp->type==LA_HEMI) { | |
388 mat->dynproperty |= DYN_LAMP_VEC; | |
389 GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(la
mp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), lv, dist, &visifac); | |
390 return visifac; | |
391 } | |
392 else { | |
393 mat->dynproperty |= DYN_LAMP_CO; | |
394 GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSI
TION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), lv, d
ist, &visifac); | |
395 | |
396 if(lamp->type==LA_AREA) | |
397 return visifac; | |
398 | |
399 switch(lamp->falloff_type) | |
400 { | |
401 case LA_FALLOFF_CONSTANT: | |
402 break; | |
403 case LA_FALLOFF_INVLINEAR: | |
404 GPU_link(mat, "lamp_falloff_invlinear", GPU_unif
orm(&lamp->dist), *dist, &visifac); | |
405 break; | |
406 case LA_FALLOFF_INVSQUARE: | |
407 GPU_link(mat, "lamp_falloff_invsquare", GPU_unif
orm(&lamp->dist), *dist, &visifac); | |
408 break; | |
409 case LA_FALLOFF_SLIDERS: | |
410 GPU_link(mat, "lamp_falloff_sliders", GPU_unifor
m(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visi
fac); | |
411 break; | |
412 case LA_FALLOFF_CURVE: | |
413 { | |
414 float *array; | |
415 int size; | |
416 | |
417 curvemapping_table_RGBA(lamp->curfalloff
, &array, &size); | |
418 GPU_link(mat, "lamp_falloff_curve", GPU_
uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac); | |
419 } | |
420 break; | |
421 } | |
422 | |
423 if(lamp->mode & LA_SPHERE) | |
424 GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lam
p->dist), *dist, visifac, &visifac); | |
425 | |
426 if(lamp->type == LA_SPOT) { | |
427 if(lamp->mode & LA_SQUARE) { | |
428 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT; | |
429 GPU_link(mat, "lamp_visibility_spot_square", GPU
_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), GPU_dynamic_u
niform((float*)lamp->dynimat, GPU_DYNAMIC_LAMP_DYNIMAT, lamp->ob), *lv, &inpr); | |
430 } | |
431 else { | |
432 mat->dynproperty |= DYN_LAMP_VEC; | |
433 GPU_link(mat, "lamp_visibility_spot_circle", GPU
_dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), *lv, &inpr); | |
434 } | |
435 ························ | |
436 GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp-
>spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac); | |
437 } | |
438 | |
439 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac); | |
440 | |
441 return visifac; | |
442 } | |
443 } | |
444 | |
445 #if 0 | |
446 static void area_lamp_vectors(LampRen *lar) | |
447 { | |
448 float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac; | |
449 | |
450 /* make it smaller, so area light can be multisampled */ | |
451 multifac= 1.0f/sqrt((float)lar->ray_totsamp); | |
452 xsize *= multifac; | |
453 ysize *= multifac; | |
454 | |
455 /* corner vectors */ | |
456 lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0
]; | |
457 lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1
]; | |
458 lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2
]; | |
459 | |
460 /* corner vectors */ | |
461 lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0
]; | |
462 lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1
]; | |
463 lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2
]; | |
464 | |
465 /* corner vectors */ | |
466 lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0
]; | |
467 lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1
]; | |
468 lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2
]; | |
469 | |
470 /* corner vectors */ | |
471 lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0
]; | |
472 lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1
]; | |
473 lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2
]; | |
474 /* only for correction button size, matrix size works on energy */ | |
475 lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize); | |
476 } | |
477 #endif | |
478 | |
479 static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GP
UNodeLink *col2, int type, GPUNodeLink **outcol) | |
480 { | |
481 static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_s
ub", | |
482 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light", | |
483 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat", | |
484 "mix_val", "mix_color", "mix_soft", "mix_linear"}; | |
485 | |
486 GPU_link(mat, names[type], fac, col1, col2, outcol); | |
487 } | |
488 | |
489 static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *f
ac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol) | |
490 { | |
491 GPUNodeLink *tmp, *alpha, *col; | |
492 float *array; | |
493 int size; | |
494 | |
495 /* do colorband */ | |
496 colorband_table_RGBA(coba, &array, &size); | |
497 GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp); | |
498 | |
499 /* use alpha in fac */ | |
500 GPU_link(mat, "mtex_alpha_from_col", col, &alpha); | |
501 GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac); | |
502 | |
503 /* blending method */ | |
504 ramp_blend(mat, fac, incol, col, type, outcol); | |
505 } | |
506 | |
507 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff) | |
508 { | |
509 Material *ma= shi->mat; | |
510 GPUMaterial *mat= shi->gpumat; | |
511 GPUNodeLink *fac; | |
512 | |
513 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) { | |
514 if(ma->ramp_col) { | |
515 if(ma->rampin_col==MA_RAMP_IN_RESULT) { | |
516 GPU_link(mat, "ramp_rgbtobw", *diff, &fac); | |
517 ································ | |
518 /* colorband + blend */ | |
519 do_colorband_blend(mat, ma->ramp_col, fac, ma->r
ampfac_col, ma->rampblend_col, *diff, diff); | |
520 } | |
521 } | |
522 } | |
523 } | |
524 | |
525 static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, G
PUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff) | |
526 { | |
527 GPUNodeLink *fac, *tmp, *addcol; | |
528 ········ | |
529 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) && | |
530 ma->ramp_col && (ma->mode & MA_RAMP_COL)) { | |
531 /* MA_RAMP_IN_RESULT is exceptional */ | |
532 if(ma->rampin_col==MA_RAMP_IN_RESULT) { | |
533 addcol = shi->rgb; | |
534 } | |
535 else { | |
536 /* input */ | |
537 switch(ma->rampin_col) { | |
538 case MA_RAMP_IN_ENERGY: | |
539 GPU_link(mat, "ramp_rgbtobw", rgb, &fac); | |
540 break; | |
541 case MA_RAMP_IN_SHADER: | |
542 fac= is; | |
543 break; | |
544 case MA_RAMP_IN_NOR: | |
545 GPU_link(mat, "vec_math_dot", shi->view, shi->vn
, &tmp, &fac); | |
546 break; | |
547 default: | |
548 GPU_link(mat, "set_value_zero", &fac); | |
549 break; | |
550 } | |
551 | |
552 /* colorband + blend */ | |
553 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_c
ol, ma->rampblend_col, shi->rgb, &addcol); | |
554 } | |
555 } | |
556 else | |
557 addcol = shi->rgb; | |
558 | |
559 /* output to */ | |
560 GPU_link(mat, "shade_madd_clamped", *diff, rgb, addcol, diff); | |
561 } | |
562 | |
563 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec) | |
564 { | |
565 Material *ma= shi->mat; | |
566 GPUMaterial *mat= shi->gpumat; | |
567 GPUNodeLink *fac; | |
568 | |
569 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) && | |
570 ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT) { | |
571 GPU_link(mat, "ramp_rgbtobw", *spec, &fac); | |
572 ················ | |
573 /* colorband + blend */ | |
574 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma
->rampblend_spec, *spec, spec); | |
575 } | |
576 } | |
577 | |
578 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t
, GPUNodeLink **spec) | |
579 { | |
580 Material *ma= shi->mat; | |
581 GPUMaterial *mat= shi->gpumat; | |
582 GPUNodeLink *fac, *tmp; | |
583 | |
584 *spec = shi->specrgb; | |
585 | |
586 /* MA_RAMP_IN_RESULT is exception */ | |
587 if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) { | |
588 ················ | |
589 /* input */ | |
590 switch(ma->rampin_spec) { | |
591 case MA_RAMP_IN_ENERGY: | |
592 fac = t; | |
593 break; | |
594 case MA_RAMP_IN_SHADER: | |
595 fac = is; | |
596 break; | |
597 case MA_RAMP_IN_NOR: | |
598 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp,
&fac); | |
599 break; | |
600 default: | |
601 GPU_link(mat, "set_value_zero", &fac); | |
602 break; | |
603 } | |
604 ················ | |
605 /* colorband + blend */ | |
606 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma
->rampblend_spec, *spec, spec); | |
607 } | |
608 } | |
609 | |
610 static void add_user_list(ListBase *list, void *data) | |
611 { | |
612 LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData"); | |
613 link->data = data; | |
614 BLI_addtail(list, link); | |
615 } | |
616 | |
617 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
mp) | |
618 { | |
619 Material *ma= shi->mat; | |
620 GPUMaterial *mat= shi->gpumat; | |
621 GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view; | |
622 GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL; | |
623 float one = 1.0f; | |
624 | |
625 if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW)) | |
626 return; | |
627 ········ | |
628 vn= shi->vn; | |
629 view= shi->view; | |
630 | |
631 visifac= lamp_get_visibility(mat, lamp, &lv, &dist); | |
632 | |
633 /*if(ma->mode & MA_TANGENT_V) | |
634 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, "
"), &vn);*/ | |
635 ········ | |
636 GPU_link(mat, "shade_inp", vn, lv, &inp); | |
637 | |
638 if(lamp->mode & LA_NO_DIFF) { | |
639 GPU_link(mat, "shade_is_no_diffuse", &is); | |
640 } | |
641 else if(lamp->type == LA_HEMI) { | |
642 GPU_link(mat, "shade_is_hemi", inp, &is); | |
643 } | |
644 else { | |
645 if(lamp->type == LA_AREA) { | |
646 float area[4][4]= {{0.0f}}, areasize= 0.0f; | |
647 | |
648 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO; | |
649 GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POS
ITION), GPU_dynamic_uniform(lamp->dynco, GPU_DYNAMIC_LAMP_DYNCO, lamp->ob), GPU_
dynamic_uniform(lamp->dynvec, GPU_DYNAMIC_LAMP_DYNVEC, lamp->ob), vn, GPU_unifor
m((float*)area), | |
650 GPU_uniform(&areasize), GPU_uniform(&lamp->k), &
inp); | |
651 } | |
652 | |
653 is= inp; /* Lambert */ | |
654 | |
655 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) { | |
656 if(ma->diff_shader==MA_DIFF_ORENNAYAR) | |
657 GPU_link(mat, "shade_diffuse_oren_nayer", inp, v
n, lv, view, GPU_uniform(&ma->roughness), &is); | |
658 else if(ma->diff_shader==MA_DIFF_TOON) | |
659 GPU_link(mat, "shade_diffuse_toon", vn, lv, view
, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); | |
660 else if(ma->diff_shader==MA_DIFF_MINNAERT) | |
661 GPU_link(mat, "shade_diffuse_minnaert", inp, vn,
view, GPU_uniform(&ma->darkness), &is); | |
662 else if(ma->diff_shader==MA_DIFF_FRESNEL) | |
663 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, v
iew, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); | |
664 } | |
665 } | |
666 | |
667 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) | |
668 if(ma->shade_flag & MA_CUBIC) | |
669 GPU_link(mat, "shade_cubic", is, &is); | |
670 ········ | |
671 i = is; | |
672 GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i); | |
673 | |
674 | |
675 /*if(ma->mode & MA_TANGENT_VN) | |
676 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT,
""), &vn);*/ | |
677 | |
678 /* this replaces if(i > 0.0) conditional until that is supported */ | |
679 // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive",
i, &i); | |
680 | |
681 if((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) { | |
682 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) { | |
683 mat->dynproperty |= DYN_LAMP_PERSMAT; | |
684 | |
685 GPU_link(mat, "test_shadowbuf", | |
686 GPU_builtin(GPU_VIEW_POSITION), | |
687 GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPL
ER_2DSHADOW, lamp->ob), | |
688 GPU_dynamic_uniform((float*)lamp->dynpersmat, GP
U_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), | |
689 GPU_uniform(&lamp->bias), inp, &shadfac); | |
690 ························ | |
691 if(lamp->mode & LA_ONLYSHADOW) { | |
692 GPU_link(mat, "shade_only_shadow", i, shadfac, | |
693 GPU_dynamic_uniform(&lamp->dynenergy, GP
U_DYNAMIC_LAMP_DYNENERGY, lamp->ob), &shadfac); | |
694 ································ | |
695 if(!(lamp->mode & LA_NO_DIFF)) | |
696 GPU_link(mat, "shade_only_shadow_diffuse
", shadfac, shi->rgb, | |
697 shr->diff, &shr->diff); | |
698 | |
699 if(!(lamp->mode & LA_NO_SPEC)) | |
700 GPU_link(mat, "shade_only_shadow_specula
r", shadfac, shi->specrgb, | |
701 shr->spec, &shr->spec); | |
702 ································ | |
703 add_user_list(&mat->lamps, lamp); | |
704 add_user_list(&lamp->materials, shi->gpumat->ma)
; | |
705 return; | |
706 } | |
707 ························ | |
708 GPU_link(mat, "math_multiply", i, shadfac, &i); | |
709 } | |
710 } | |
711 else if((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA
_ONLYSHADOW)) { | |
712 add_user_list(&mat->lamps, lamp); | |
713 add_user_list(&lamp->materials, shi->gpumat->ma); | |
714 return; | |
715 } | |
716 else | |
717 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac); | |
718 | |
719 if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) { | |
720 if(!(lamp->mode & LA_NO_DIFF)) { | |
721 GPUNodeLink *rgb; | |
722 GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(
lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &rgb); | |
723 add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); | |
724 } | |
725 } | |
726 | |
727 if(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS); | |
728 else if(!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && | |
729 (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { | |
730 if(lamp->type == LA_HEMI) { | |
731 GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_unifo
rm(&ma->spec), shi->har, visifac, &t); | |
732 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(l
amp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol); | |
733 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &s
hr->spec); | |
734 } | |
735 else { | |
736 if(ma->spec_shader==MA_SPEC_PHONG) | |
737 GPU_link(mat, "shade_phong_spec", vn, lv, view,
shi->har, &specfac); | |
738 else if(ma->spec_shader==MA_SPEC_COOKTORR) | |
739 GPU_link(mat, "shade_cooktorr_spec", vn, lv, vie
w, shi->har, &specfac); | |
740 else if(ma->spec_shader==MA_SPEC_BLINN) | |
741 GPU_link(mat, "shade_blinn_spec", vn, lv, view,
GPU_uniform(&ma->refrac), shi->har, &specfac); | |
742 else if(ma->spec_shader==MA_SPEC_WARDISO) | |
743 GPU_link(mat, "shade_wardiso_spec", vn, lv, view
, GPU_uniform(&ma->rms), &specfac); | |
744 else | |
745 GPU_link(mat, "shade_toon_spec", vn, lv, view, G
PU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac); | |
746 | |
747 if(lamp->type==LA_AREA) | |
748 GPU_link(mat, "shade_spec_area_inp", specfac, in
p, &specfac); | |
749 | |
750 GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifa
c, specfac, &t); | |
751 | |
752 if(ma->mode & MA_RAMP_SPEC) { | |
753 GPUNodeLink *spec; | |
754 do_specular_ramp(shi, specfac, t, &spec); | |
755 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_u
niform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), spec, &outcol); | |
756 GPU_link(mat, "shade_add_clamped", shr->spec, ou
tcol, &shr->spec); | |
757 } | |
758 else { | |
759 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_u
niform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), shi->specrgb, &outcol); | |
760 GPU_link(mat, "shade_add_clamped", shr->spec, ou
tcol, &shr->spec); | |
761 } | |
762 } | |
763 } | |
764 | |
765 add_user_list(&mat->lamps, lamp); | |
766 add_user_list(&lamp->materials, shi->gpumat->ma); | |
767 } | |
768 | |
769 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) | |
770 { | |
771 Base *base; | |
772 Object *ob; | |
773 Scene *sce_iter; | |
774 GPULamp *lamp; | |
775 ········ | |
776 for(SETLOOPER(shi->gpumat->scene, sce_iter, base)) { | |
777 ob= base->object; | |
778 | |
779 if(ob->type==OB_LAMP) { | |
780 lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NUL
L); | |
781 if(lamp) | |
782 shade_one_light(shi, shr, lamp); | |
783 } | |
784 | |
785 if (ob->transflag & OB_DUPLI) { | |
786 DupliObject *dob; | |
787 ListBase *lb = object_duplilist(shi->gpumat->scene, ob); | |
788 ························ | |
789 for(dob=lb->first; dob; dob=dob->next) { | |
790 Object *ob_iter = dob->ob; | |
791 | |
792 if(ob_iter->type==OB_LAMP) { | |
793 copy_m4_m4(ob_iter->obmat, dob->mat); | |
794 | |
795 lamp = GPU_lamp_from_blender(shi->gpumat
->scene, ob_iter, ob); | |
796 if(lamp) | |
797 shade_one_light(shi, shr, lamp); | |
798 } | |
799 } | |
800 ························ | |
801 free_object_duplilist(lb); | |
802 } | |
803 } | |
804 } | |
805 | |
806 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *o
ut, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in) | |
807 { | |
808 switch(blendtype) { | |
809 case MTEX_BLEND: | |
810 GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in); | |
811 break; | |
812 case MTEX_MUL: | |
813 GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in); | |
814 break; | |
815 case MTEX_SCREEN: | |
816 GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in); | |
817 break; | |
818 case MTEX_OVERLAY: | |
819 GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in); | |
820 break; | |
821 case MTEX_SUB: | |
822 GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in); | |
823 break; | |
824 case MTEX_ADD: | |
825 GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in); | |
826 break; | |
827 case MTEX_DIV: | |
828 GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in); | |
829 break; | |
830 case MTEX_DIFF: | |
831 GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in); | |
832 break; | |
833 case MTEX_DARK: | |
834 GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in); | |
835 break; | |
836 case MTEX_LIGHT: | |
837 GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in); | |
838 break; | |
839 case MTEX_BLEND_HUE: | |
840 GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in); | |
841 break; | |
842 case MTEX_BLEND_SAT: | |
843 GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in); | |
844 break; | |
845 case MTEX_BLEND_VAL: | |
846 GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in); | |
847 break; | |
848 case MTEX_BLEND_COLOR: | |
849 GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in); | |
850 break; | |
851 default: | |
852 GPU_link(mat, "set_rgb_zero", &in); | |
853 break; | |
854 } | |
855 } | |
856 | |
857 static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink
*out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in) | |
858 { | |
859 switch(blendtype) { | |
860 case MTEX_BLEND: | |
861 GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in); | |
862 break; | |
863 case MTEX_MUL: | |
864 GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in); | |
865 break; | |
866 case MTEX_SCREEN: | |
867 GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in); | |
868 break; | |
869 case MTEX_SUB: | |
870 GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in); | |
871 break; | |
872 case MTEX_ADD: | |
873 GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in); | |
874 break; | |
875 case MTEX_DIV: | |
876 GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in); | |
877 break; | |
878 case MTEX_DIFF: | |
879 GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in); | |
880 break; | |
881 case MTEX_DARK: | |
882 GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in); | |
883 break; | |
884 case MTEX_LIGHT: | |
885 GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in); | |
886 break; | |
887 default: | |
888 GPU_link(mat, "set_value_zero", &in); | |
889 break; | |
890 } | |
891 } | |
892 | |
893 static void do_material_tex(GPUShadeInput *shi) | |
894 { | |
895 Material *ma= shi->mat; | |
896 GPUMaterial *mat= shi->gpumat; | |
897 MTex *mtex; | |
898 Tex *tex; | |
899 GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac; | |
900 GPUNodeLink *texco_norm, *texco_orco, *texco_object; | |
901 GPUNodeLink *texco_global, *texco_uv = NULL; | |
902 GPUNodeLink *newnor, *orn; | |
903 /*char *lastuvname = NULL;*/ /*UNUSED*/ | |
904 float one = 1.0f, norfac, ofs[3]; | |
905 int tex_nr, rgbnor, talpha; | |
906 int init_done = 0, iBumpSpacePrev; | |
907 GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; | |
908 int iFirstTimeNMap=1; | |
909 int found_deriv_map = 0; | |
910 | |
911 GPU_link(mat, "set_value", GPU_uniform(&one), &stencil); | |
912 | |
913 GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm); | |
914 GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco); | |
915 GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | |
916 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), | |
917 GPU_builtin(GPU_VIEW_POSITION), &texco_object); | |
918 //GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_t
angent); | |
919 GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), | |
920 GPU_builtin(GPU_VIEW_POSITION), &texco_global); | |
921 | |
922 orn= texco_norm; | |
923 | |
924 /* go over texture slots */ | |
925 for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { | |
926 /* separate tex switching */ | |
927 if(ma->septex & (1<<tex_nr)) continue; | |
928 ················ | |
929 if(ma->mtex[tex_nr]) { | |
930 mtex= ma->mtex[tex_nr]; | |
931 ························ | |
932 tex= mtex->tex; | |
933 if(tex == NULL) continue; | |
934 | |
935 /* which coords */ | |
936 if(mtex->texco==TEXCO_ORCO) | |
937 texco= texco_orco; | |
938 else if(mtex->texco==TEXCO_OBJECT) | |
939 texco= texco_object; | |
940 else if(mtex->texco==TEXCO_NORM) | |
941 texco= orn; | |
942 else if(mtex->texco==TEXCO_TANGENT) | |
943 texco= texco_object; | |
944 else if(mtex->texco==TEXCO_GLOB) | |
945 texco= texco_global; | |
946 else if(mtex->texco==TEXCO_REFL) { | |
947 GPU_link(mat, "texco_refl", shi->vn, shi->view,
&shi->ref); | |
948 texco= shi->ref; | |
949 } | |
950 else if(mtex->texco==TEXCO_UV) { | |
951 if(1) { //!(texco_uv && strcmp(mtex->uvname, las
tuvname) == 0)) { | |
952 GPU_link(mat, "texco_uv", GPU_attribute(
CD_MTFACE, mtex->uvname), &texco_uv); | |
953 /*lastuvname = mtex->uvname;*/ /*UNUSED*
/ | |
954 } | |
955 texco= texco_uv; | |
956 } | |
957 else | |
958 continue; | |
959 | |
960 /* in case of uv, this would just undo a multiplication
in texco_uv */ | |
961 if(mtex->texco != TEXCO_UV) | |
962 GPU_link(mat, "mtex_2d_mapping", texco, &texco); | |
963 | |
964 if(mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mte
x->size[2] != 1.0f) | |
965 GPU_link(mat, "mtex_mapping_size", texco, GPU_un
iform(mtex->size), &texco); | |
966 | |
967 ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0]; | |
968 ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1]; | |
969 ofs[2] = 0.0f; | |
970 if(ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) | |
971 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uni
form(ofs), &texco); | |
972 | |
973 talpha = 0; | |
974 rgbnor = 0; | |
975 | |
976 if(tex && tex->type == TEX_IMAGE && tex->ima) { | |
977 GPU_link(mat, "mtex_image", texco, GPU_image(tex
->ima, &tex->iuser), &tin, &trgb); | |
978 rgbnor= TEX_RGB; | |
979 | |
980 if(tex->imaflag & TEX_USEALPHA) | |
981 talpha= 1; | |
982 } | |
983 else continue; | |
984 | |
985 /* texture output */ | |
986 if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)
) { | |
987 GPU_link(mat, "mtex_rgbtoint", trgb, &tin); | |
988 rgbnor -= TEX_RGB; | |
989 } | |
990 | |
991 if(mtex->texflag & MTEX_NEGATIVE) { | |
992 if(rgbnor & TEX_RGB) | |
993 GPU_link(mat, "mtex_rgb_invert", trgb, &
trgb); | |
994 else | |
995 GPU_link(mat, "mtex_value_invert", tin,
&tin); | |
996 } | |
997 | |
998 if(mtex->texflag & MTEX_STENCIL) { | |
999 if(rgbnor & TEX_RGB) | |
1000 GPU_link(mat, "mtex_rgb_stencil", stenci
l, trgb, &stencil, &trgb); | |
1001 else | |
1002 GPU_link(mat, "mtex_value_stencil", sten
cil, tin, &stencil, &tin); | |
1003 } | |
1004 | |
1005 /* mapping */ | |
1006 if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) { | |
1007 /* stencil maps on the texture control slider, n
ot texture intensity value */ | |
1008 if((rgbnor & TEX_RGB)==0) { | |
1009 GPU_link(mat, "set_rgb", GPU_uniform(&mt
ex->r), &tcol); | |
1010 } | |
1011 else { | |
1012 GPU_link(mat, "set_rgba", trgb, &tcol); | |
1013 | |
1014 if(mtex->mapto & MAP_ALPHA) | |
1015 GPU_link(mat, "set_value", stenc
il, &tin); | |
1016 else if(talpha) | |
1017 GPU_link(mat, "mtex_alpha_from_c
ol", trgb, &tin); | |
1018 else | |
1019 GPU_link(mat, "set_value_one", &
tin); | |
1020 } | |
1021 | |
1022 if(tex->type==TEX_IMAGE) | |
1023 if(gpu_do_color_management(mat)) | |
1024 GPU_link(mat, "srgb_to_linearrgb
", tcol, &tcol); | |
1025 ································ | |
1026 if(mtex->mapto & MAP_COL) { | |
1027 GPUNodeLink *colfac; | |
1028 | |
1029 if(mtex->colfac == 1.0f) colfac = stenci
l; | |
1030 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->colfac), stencil, &colfac); | |
1031 | |
1032 texture_rgb_blend(mat, tcol, shi->rgb, t
in, colfac, mtex->blendtype, &shi->rgb); | |
1033 } | |
1034 ································ | |
1035 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && (mtex->mapto & MAP_COLSPEC)) { | |
1036 GPUNodeLink *colspecfac; | |
1037 | |
1038 if(mtex->colspecfac == 1.0f) colspecfac
= stencil; | |
1039 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->colspecfac), stencil, &colspecfac); | |
1040 | |
1041 texture_rgb_blend(mat, tcol, shi->specrg
b, tin, colspecfac, mtex->blendtype, &shi->specrgb); | |
1042 } | |
1043 } | |
1044 | |
1045 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (m
tex->mapto & MAP_NORM)) { | |
1046 if(tex->type==TEX_IMAGE) { | |
1047 found_deriv_map = tex->imaflag & TEX_DER
IVATIVEMAP; | |
1048 | |
1049 if(tex->imaflag & TEX_NORMALMAP) { | |
1050 /* normalmap image */ | |
1051 GPU_link(mat, "mtex_normal", tex
co, GPU_image(tex->ima, &tex->iuser), &tnor ); | |
1052 ················································ | |
1053 if(mtex->norfac < 0.0f) | |
1054 GPU_link(mat, "mtex_nega
te_texnormal", tnor, &tnor); | |
1055 | |
1056 if(mtex->normapspace == MTEX_NSP
ACE_TANGENT) | |
1057 { | |
1058 if(iFirstTimeNMap!=0) | |
1059 { | |
1060 // use unnormali
zed normal (this is how we bake it - closer to gamedev) | |
1061 GPUNodeLink *vNe
gNorm; | |
1062 GPU_link(mat, "v
ec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm); | |
1063 GPU_link(mat, "m
tex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor); | |
1064 iFirstTimeNMap =
0; | |
1065 } | |
1066 else // otherwise use
accumulated perturbations | |
1067 { | |
1068 GPU_link(mat, "m
tex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor); | |
1069 } | |
1070 } | |
1071 else | |
1072 newnor = tnor; | |
1073 ················································ | |
1074 norfac = MIN2(fabsf(mtex->norfac
), 1.0f); | |
1075 ················································ | |
1076 if(norfac == 1.0f && !GPU_link_c
hanged(stencil)) { | |
1077 shi->vn = newnor; | |
1078 } | |
1079 else { | |
1080 tnorfac = GPU_uniform(&n
orfac); | |
1081 ········ | |
1082 if(GPU_link_changed(sten
cil)) | |
1083 GPU_link(mat, "m
ath_multiply", tnorfac, stencil, &tnorfac); | |
1084 ········ | |
1085 GPU_link(mat, "mtex_blen
d_normal", tnorfac, shi->vn, newnor, &shi->vn); | |
1086 } | |
1087 ················································ | |
1088 } else if( (mtex->texflag & (MTEX_3TAP_B
UMP|MTEX_5TAP_BUMP)) || found_deriv_map) { | |
1089 /* ntap bumpmap image */ | |
1090 int iBumpSpace; | |
1091 float ima_x, ima_y; | |
1092 float hScale = 0.1f; // compatib
ility adjustment factor for all bumpspace types | |
1093 float hScaleTex = 13.0f; // fact
or for scaling texspace bumps | |
1094 ················································ | |
1095 GPUNodeLink *surf_pos = GPU_buil
tin(GPU_VIEW_POSITION); | |
1096 GPUNodeLink *vR1, *vR2; | |
1097 GPUNodeLink *dBs, *dBt, *fDet; | |
1098 ················································ | |
1099 if( mtex->texflag & MTEX_BUMP_TE
XTURESPACE ) | |
1100 hScale = hScaleTex; | |
1101 norfac = hScale * mtex->norfac; | |
1102 tnorfac = GPU_uniform(&norfac); | |
1103 ················································ | |
1104 if(GPU_link_changed(stencil)) | |
1105 GPU_link(mat, "math_mult
iply", tnorfac, stencil, &tnorfac); | |
1106 ················································ | |
1107 if( !init_done ) { | |
1108 // copy shi->vn to vNorg
and vNacc, set magnitude to 1 | |
1109 GPU_link(mat, "mtex_bump
_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude); | |
1110 iBumpSpacePrev = 0; | |
1111 init_done = 1; | |
1112 } | |
1113 ················································ | |
1114 // find current bump space | |
1115 if( mtex->texflag & MTEX_BUMP_OB
JECTSPACE ) | |
1116 iBumpSpace = 1; | |
1117 else if( mtex->texflag & MTEX_BU
MP_TEXTURESPACE ) | |
1118 iBumpSpace = 2; | |
1119 else | |
1120 iBumpSpace = 4; // ViewS
pace | |
1121 ················································ | |
1122 // re-initialize if bump space c
hanged | |
1123 if( iBumpSpacePrev != iBumpSpace
) { | |
1124 ························································ | |
1125 if( mtex->texflag & MTEX
_BUMP_OBJECTSPACE )· | |
1126 GPU_link( mat, "
mtex_bump_init_objspace", | |
1127
surf_pos, vNorg,· | |
1128 GPU_bu
iltin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OB
JECT_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),· | |
1129 fPrevM
agnitude, vNacc, | |
1130
&fPrevMagnitude, &vNacc,· | |
1131 &vR1,
&vR2, &fDet ); | |
1132 ································································ | |
1133 else if( mtex->texflag &
MTEX_BUMP_TEXTURESPACE ) | |
1134 GPU_link( mat, "
mtex_bump_init_texturespace", | |
1135
surf_pos, vNorg,· | |
1136 fPrevM
agnitude, vNacc, | |
1137
&fPrevMagnitude, &vNacc,· | |
1138 &vR1,
&vR2, &fDet ); | |
1139 ································································ | |
1140 else | |
1141 GPU_link( mat, "
mtex_bump_init_viewspace", | |
1142
surf_pos, vNorg,· | |
1143 fPrevM
agnitude, vNacc, | |
1144
&fPrevMagnitude, &vNacc,· | |
1145 &vR1,
&vR2, &fDet ); | |
1146 ························································ | |
1147 iBumpSpacePrev = iBumpSp
ace; | |
1148 } | |
1149 | |
1150 // resolve texture resolution | |
1151 if( (mtex->texflag & MTEX_BUMP_T
EXTURESPACE) || found_deriv_map ) { | |
1152 ImBuf *ibuf= BKE_image_g
et_ibuf(tex->ima, &tex->iuser); | |
1153 ima_x= 512.0f; ima_y= 51
2.f; // prevent calling textureSize, glsl 1.3 only | |
1154 if(ibuf) { | |
1155 ima_x= ibuf->x; | |
1156 ima_y= ibuf->y; | |
1157 } | |
1158 } | |
1159 ················································ | |
1160 ················································ | |
1161 if(found_deriv_map) { | |
1162 GPU_link( mat, "mtex_bum
p_deriv",· | |
1163 texco, GPU_ima
ge(tex->ima, &tex->iuser), GPU_uniform(&ima_x), GPU_uniform(&ima_y), tnorfac, | |
1164 &dBs, &dBt ); | |
1165 } | |
1166 else if( mtex->texflag & MTEX_3T
AP_BUMP ) | |
1167 GPU_link( mat, "mtex_bum
p_tap3",· | |
1168 texco, GPU_ima
ge(tex->ima, &tex->iuser), tnorfac, | |
1169 &dBs, &dBt ); | |
1170 else | |
1171 GPU_link( mat, "mtex_bum
p_tap5",· | |
1172 texco, GPU_ima
ge(tex->ima, &tex->iuser), tnorfac, | |
1173 &dBs, &dBt ); | |
1174 ················································ | |
1175 ················································ | |
1176 if( mtex->texflag & MTEX_BUMP_TE
XTURESPACE ) { | |
1177 ························································ | |
1178 GPU_link( mat, "mtex_bum
p_apply_texspace", | |
1179 fDet, dBs, dBt
, vR1, vR2,· | |
1180 GPU_image(tex-
>ima, &tex->iuser), texco, GPU_uniform(&ima_x), GPU_uniform(&ima_y), vNacc, | |
1181 &vNacc, &shi->
vn ); | |
1182 } else | |
1183 GPU_link( mat, "mtex_bum
p_apply", | |
1184 fDet, dBs, dBt
, vR1, vR2, vNacc, | |
1185 &vNacc, &shi->
vn ); | |
1186 ················································ | |
1187 } | |
1188 } | |
1189 ································ | |
1190 GPU_link(mat, "vec_math_negate", shi->vn, &orn); | |
1191 } | |
1192 | |
1193 if((mtex->mapto & MAP_VARS)) { | |
1194 if(rgbnor & TEX_RGB) { | |
1195 if(talpha) | |
1196 GPU_link(mat, "mtex_alpha_from_c
ol", trgb, &tin); | |
1197 else | |
1198 GPU_link(mat, "mtex_rgbtoint", t
rgb, &tin); | |
1199 } | |
1200 | |
1201 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && mtex->mapto & MAP_REF) { | |
1202 GPUNodeLink *difffac; | |
1203 | |
1204 if(mtex->difffac == 1.0f) difffac = sten
cil; | |
1205 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->difffac), stencil, &difffac); | |
1206 | |
1207 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl); | |
1208 GPU_link(mat, "mtex_value_clamp_positive
", shi->refl, &shi->refl); | |
1209 } | |
1210 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && mtex->mapto & MAP_SPEC) { | |
1211 GPUNodeLink *specfac; | |
1212 | |
1213 if(mtex->specfac == 1.0f) specfac = sten
cil; | |
1214 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->specfac), stencil, &specfac); | |
1215 | |
1216 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec); | |
1217 GPU_link(mat, "mtex_value_clamp_positive
", shi->spec, &shi->spec); | |
1218 } | |
1219 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && mtex->mapto & MAP_EMIT) { | |
1220 GPUNodeLink *emitfac; | |
1221 | |
1222 if(mtex->emitfac == 1.0f) emitfac = sten
cil; | |
1223 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->emitfac), stencil, &emitfac); | |
1224 | |
1225 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit); | |
1226 GPU_link(mat, "mtex_value_clamp_positive
", shi->emit, &shi->emit); | |
1227 } | |
1228 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && mtex->mapto & MAP_HAR) { | |
1229 GPUNodeLink *hardfac; | |
1230 | |
1231 if(mtex->hardfac == 1.0f) hardfac = sten
cil; | |
1232 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->hardfac), stencil, &hardfac); | |
1233 | |
1234 GPU_link(mat, "mtex_har_divide", shi->ha
r, &shi->har); | |
1235 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har); | |
1236 GPU_link(mat, "mtex_har_multiply_clamp",
shi->har, &shi->har); | |
1237 } | |
1238 if(mtex->mapto & MAP_ALPHA) { | |
1239 GPUNodeLink *alphafac; | |
1240 | |
1241 if(mtex->alphafac == 1.0f) alphafac = st
encil; | |
1242 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->alphafac), stencil, &alphafac); | |
1243 | |
1244 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha); | |
1245 GPU_link(mat, "mtex_value_clamp", shi->a
lpha, &shi->alpha); | |
1246 } | |
1247 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TE
X) && mtex->mapto & MAP_AMB) { | |
1248 GPUNodeLink *ambfac; | |
1249 | |
1250 if(mtex->ambfac == 1.0f) ambfac = stenci
l; | |
1251 else GPU_link(mat, "math_multiply", GPU_
uniform(&mtex->ambfac), stencil, &ambfac); | |
1252 | |
1253 texture_value_blend(mat, GPU_uniform(&mt
ex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb); | |
1254 GPU_link(mat, "mtex_value_clamp", shi->a
mb, &shi->amb); | |
1255 } | |
1256 } | |
1257 } | |
1258 } | |
1259 } | |
1260 | |
1261 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) | |
1262 { | |
1263 float hard = ma->har; | |
1264 | |
1265 memset(shi, 0, sizeof(*shi)); | |
1266 | |
1267 shi->gpumat = mat; | |
1268 shi->mat = ma; | |
1269 | |
1270 GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb); | |
1271 GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb); | |
1272 GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); | |
1273 GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha); | |
1274 GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl); | |
1275 GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec); | |
1276 GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit); | |
1277 GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har); | |
1278 GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb); | |
1279 GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); | |
1280 GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); | |
1281 if(gpu_do_color_management(mat)) | |
1282 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol); | |
1283 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); | |
1284 } | |
1285 | |
1286 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) | |
1287 { | |
1288 GPUMaterial *mat= shi->gpumat; | |
1289 GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac; | |
1290 Material *ma= shi->mat; | |
1291 World *world= mat->scene->world; | |
1292 float linfac, logfac, misttype; | |
1293 | |
1294 memset(shr, 0, sizeof(*shr)); | |
1295 | |
1296 if(ma->mode & MA_VERTEXCOLP) | |
1297 shi->rgb = shi->vcol; | |
1298 | |
1299 do_material_tex(shi); | |
1300 | |
1301 if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) | |
1302 GPU_material_enable_alpha(mat); | |
1303 | |
1304 if((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)
) { | |
1305 shr->combined = shi->rgb; | |
1306 shr->alpha = shi->alpha; | |
1307 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff); | |
1308 GPU_link(mat, "set_rgb_zero", &shr->spec); | |
1309 } | |
1310 else { | |
1311 if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) { | |
1312 if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEX
COL) { | |
1313 GPU_link(mat, "shade_add", shi->emit, shi->vcol,
&emit); | |
1314 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr-
>diff); | |
1315 } | |
1316 else | |
1317 GPU_link(mat, "shade_mul_value", shi->emit, shi-
>rgb, &shr->diff); | |
1318 } | |
1319 else | |
1320 GPU_link(mat, "set_rgb_zero", &shr->diff); | |
1321 | |
1322 GPU_link(mat, "set_rgb_zero", &shr->spec); | |
1323 | |
1324 material_lights(shi, shr); | |
1325 | |
1326 shr->combined = shr->diff; | |
1327 shr->alpha = shi->alpha; | |
1328 | |
1329 if(world) { | |
1330 /* exposure correction */ | |
1331 if(world->exp!=0.0f || world->range!=1.0f) { | |
1332 linfac= 1.0 + pow((2.0*world->exp + 0.5), -10); | |
1333 logfac= log((linfac-1.0f)/linfac)/world->range; | |
1334 | |
1335 GPU_link(mat, "set_value", GPU_uniform(&linfac),
&ulinfac); | |
1336 GPU_link(mat, "set_value", GPU_uniform(&logfac),
&ulogfac); | |
1337 | |
1338 GPU_link(mat, "shade_exposure_correct", shr->com
bined, | |
1339 ulinfac, ulogfac, &shr->combined); | |
1340 GPU_link(mat, "shade_exposure_correct", shr->spe
c, | |
1341 ulinfac, ulogfac, &shr->spec); | |
1342 } | |
1343 | |
1344 /* ambient color */ | |
1345 if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb
!=0.0f) { | |
1346 if(GPU_link_changed(shi->amb) || ma->amb != 0.0f
) | |
1347 GPU_link(mat, "shade_maddf", shr->combin
ed, GPU_uniform(&ma->amb), | |
1348 GPU_uniform(&world->ambr), &shr-
>combined); | |
1349 } | |
1350 } | |
1351 | |
1352 if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combin
ed); | |
1353 if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec); | |
1354 | |
1355 if(GPU_link_changed(shi->spec) || ma->spec != 0.0f) | |
1356 GPU_link(mat, "shade_add", shr->combined, shr->spec, &sh
r->combined); | |
1357 } | |
1358 | |
1359 GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->comb
ined); | |
1360 | |
1361 if(ma->shade_flag & MA_OBCOLOR) | |
1362 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OB
COLOR), &shr->combined); | |
1363 | |
1364 if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) { | |
1365 misttype = world->mistype; | |
1366 | |
1367 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION
), | |
1368 GPU_uniform(&world->miststa), GPU_uniform(&world->mistdi
st), | |
1369 GPU_uniform(&misttype), GPU_uniform(&world->misi), &mist
fac); | |
1370 | |
1371 GPU_link(mat, "mix_blend", mistfac, shr->combined, | |
1372 GPU_uniform(&world->horr), &shr->combined); | |
1373 } | |
1374 | |
1375 if(!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) { | |
1376 if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) | |
1377 GPU_link(mat, "shade_world_mix", GPU_uniform(&world->hor
r), | |
1378 shr->combined, &shr->combined); | |
1379 | |
1380 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combine
d); | |
1381 } | |
1382 | |
1383 if(ma->shade_flag & MA_OBCOLOR) { | |
1384 mat->obcolalpha = 1; | |
1385 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(
GPU_OBCOLOR), &shr->combined); | |
1386 } | |
1387 } | |
1388 | |
1389 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma) | |
1390 { | |
1391 GPUShadeInput shi; | |
1392 GPUShadeResult shr; | |
1393 | |
1394 GPU_shadeinput_set(mat, ma, &shi); | |
1395 GPU_shaderesult_set(&shi, &shr); | |
1396 | |
1397 return shr.combined; | |
1398 } | |
1399 | |
1400 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) | |
1401 { | |
1402 GPUMaterial *mat; | |
1403 GPUNodeLink *outlink; | |
1404 LinkData *link; | |
1405 | |
1406 for(link=ma->gpumaterial.first; link; link=link->next) | |
1407 if(((GPUMaterial*)link->data)->scene == scene) | |
1408 return link->data; | |
1409 | |
1410 mat = GPU_material_construct_begin(ma); | |
1411 mat->scene = scene; | |
1412 | |
1413 if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nod
es) { | |
1414 ntreeGPUMaterialNodes(ma->nodetree, mat); | |
1415 } | |
1416 else { | |
1417 outlink = GPU_blender_material(mat, ma); | |
1418 GPU_material_output_link(mat, outlink); | |
1419 } | |
1420 | |
1421 if(gpu_do_color_management(mat)) | |
1422 if(mat->outlink) | |
1423 GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->o
utlink); | |
1424 | |
1425 /*if(!GPU_material_construct_end(mat)) { | |
1426 GPU_material_free(mat); | |
1427 mat= NULL; | |
1428 return 0; | |
1429 }*/ | |
1430 | |
1431 GPU_material_construct_end(mat); | |
1432 | |
1433 link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); | |
1434 link->data = mat; | |
1435 BLI_addtail(&ma->gpumaterial, link); | |
1436 | |
1437 return mat; | |
1438 } | |
1439 | |
1440 void GPU_materials_free(void) | |
1441 { | |
1442 Object *ob; | |
1443 Material *ma; | |
1444 extern Material defmaterial; | |
1445 | |
1446 for(ma=G.main->mat.first; ma; ma=ma->id.next) | |
1447 GPU_material_free(ma); | |
1448 | |
1449 GPU_material_free(&defmaterial); | |
1450 | |
1451 for(ob=G.main->object.first; ob; ob=ob->id.next) | |
1452 GPU_lamp_free(ob); | |
1453 } | |
1454 | |
1455 /* Lamps and shadow buffers */ | |
1456 | |
1457 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]) | |
1458 { | |
1459 float mat[4][4]; | |
1460 | |
1461 lamp->lay = lay; | |
1462 lamp->hide = hide; | |
1463 | |
1464 copy_m4_m4(mat, obmat); | |
1465 normalize_m4(mat); | |
1466 | |
1467 VECCOPY(lamp->vec, mat[2]); | |
1468 VECCOPY(lamp->co, mat[3]); | |
1469 copy_m4_m4(lamp->obmat, mat); | |
1470 invert_m4_m4(lamp->imat, mat); | |
1471 } | |
1472 | |
1473 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener
gy) | |
1474 { | |
1475 lamp->energy = energy; | |
1476 if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; | |
1477 | |
1478 lamp->col[0]= r* lamp->energy; | |
1479 lamp->col[1]= g* lamp->energy; | |
1480 lamp->col[2]= b* lamp->energy; | |
1481 } | |
1482 | |
1483 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
a, GPULamp *lamp) | |
1484 { | |
1485 float temp, angle, pixsize, wsize; | |
1486 | |
1487 lamp->scene = scene; | |
1488 lamp->ob = ob; | |
1489 lamp->par = par; | |
1490 lamp->la = la; | |
1491 | |
1492 /* add_render_lamp */ | |
1493 lamp->mode = la->mode; | |
1494 lamp->type = la->type; | |
1495 | |
1496 lamp->energy = la->energy; | |
1497 if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; | |
1498 | |
1499 lamp->col[0]= la->r*lamp->energy; | |
1500 lamp->col[1]= la->g*lamp->energy; | |
1501 lamp->col[2]= la->b*lamp->energy; | |
1502 | |
1503 GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER),
ob->obmat); | |
1504 | |
1505 lamp->spotsi= la->spotsize; | |
1506 if(lamp->mode & LA_HALO) | |
1507 if(lamp->spotsi > 170.0f) | |
1508 lamp->spotsi = 170.0f; | |
1509 lamp->spotsi= cos(M_PI*lamp->spotsi/360.0); | |
1510 lamp->spotbl= (1.0f - lamp->spotsi)*la->spotblend; | |
1511 lamp->k= la->k; | |
1512 | |
1513 lamp->dist= la->dist; | |
1514 lamp->falloff_type= la->falloff_type; | |
1515 lamp->att1= la->att1; | |
1516 lamp->att2= la->att2; | |
1517 lamp->curfalloff= la->curfalloff; | |
1518 | |
1519 /* initshadowbuf */ | |
1520 lamp->bias = 0.02f*la->bias; | |
1521 lamp->size = la->bufsize; | |
1522 lamp->d= la->clipsta; | |
1523 lamp->clipend= la->clipend; | |
1524 | |
1525 /* arbitrary correction for the fact we do no soft transition */ | |
1526 lamp->bias *= 0.25f; | |
1527 | |
1528 /* makeshadowbuf */ | |
1529 angle= saacos(lamp->spotsi); | |
1530 temp= 0.5f*lamp->size*cos(angle)/sin(angle); | |
1531 pixsize= (lamp->d)/temp; | |
1532 wsize= pixsize*0.5f*lamp->size; | |
1533 ················ | |
1534 perspective_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp
->clipend); | |
1535 } | |
1536 | |
1537 static void gpu_lamp_shadow_free(GPULamp *lamp) | |
1538 { | |
1539 if(lamp->tex) { | |
1540 GPU_texture_free(lamp->tex); | |
1541 lamp->tex= NULL; | |
1542 } | |
1543 if(lamp->fb) { | |
1544 GPU_framebuffer_free(lamp->fb); | |
1545 lamp->fb= NULL; | |
1546 } | |
1547 } | |
1548 | |
1549 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) | |
1550 { | |
1551 Lamp *la; | |
1552 GPULamp *lamp; | |
1553 LinkData *link; | |
1554 | |
1555 for(link=ob->gpulamp.first; link; link=link->next) { | |
1556 lamp = (GPULamp*)link->data; | |
1557 | |
1558 if(lamp->par == par && lamp->scene == scene) | |
1559 return link->data; | |
1560 } | |
1561 | |
1562 lamp = MEM_callocN(sizeof(GPULamp), "GPULamp"); | |
1563 | |
1564 link = MEM_callocN(sizeof(LinkData), "GPULampLink"); | |
1565 link->data = lamp; | |
1566 BLI_addtail(&ob->gpulamp, link); | |
1567 | |
1568 la = ob->data; | |
1569 gpu_lamp_from_blender(scene, ob, par, la, lamp); | |
1570 | |
1571 if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) { | |
1572 /* opengl */ | |
1573 lamp->fb = GPU_framebuffer_create(); | |
1574 if(!lamp->fb) { | |
1575 gpu_lamp_shadow_free(lamp); | |
1576 return lamp; | |
1577 } | |
1578 | |
1579 lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NUL
L); | |
1580 if(!lamp->tex) { | |
1581 gpu_lamp_shadow_free(lamp); | |
1582 return lamp; | |
1583 } | |
1584 | |
1585 if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) { | |
1586 gpu_lamp_shadow_free(lamp); | |
1587 return lamp; | |
1588 } | |
1589 | |
1590 GPU_framebuffer_restore(); | |
1591 } | |
1592 | |
1593 return lamp; | |
1594 } | |
1595 | |
1596 void GPU_lamp_free(Object *ob) | |
1597 { | |
1598 GPULamp *lamp; | |
1599 LinkData *link; | |
1600 LinkData *nlink; | |
1601 Material *ma; | |
1602 | |
1603 for(link=ob->gpulamp.first; link; link=link->next) { | |
1604 lamp = link->data; | |
1605 | |
1606 while(lamp->materials.first) { | |
1607 nlink = lamp->materials.first; | |
1608 ma = nlink->data; | |
1609 BLI_freelinkN(&lamp->materials, nlink); | |
1610 | |
1611 if(ma->gpumaterial.first) | |
1612 GPU_material_free(ma); | |
1613 } | |
1614 | |
1615 gpu_lamp_shadow_free(lamp); | |
1616 | |
1617 MEM_freeN(lamp); | |
1618 } | |
1619 | |
1620 BLI_freelistN(&ob->gpulamp); | |
1621 } | |
1622 | |
1623 int GPU_lamp_has_shadow_buffer(GPULamp *lamp) | |
1624 { | |
1625 return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && | |
1626 !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) && | |
1627 lamp->tex && lamp->fb); | |
1628 } | |
1629 | |
1630 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize
, float winmat[][4]) | |
1631 { | |
1632 float rangemat[4][4], persmat[4][4]; | |
1633 | |
1634 /* initshadowbuf */ | |
1635 invert_m4_m4(lamp->viewmat, lamp->obmat); | |
1636 normalize_v3(lamp->viewmat[0]); | |
1637 normalize_v3(lamp->viewmat[1]); | |
1638 normalize_v3(lamp->viewmat[2]); | |
1639 | |
1640 /* makeshadowbuf */ | |
1641 mul_m4_m4m4(persmat, lamp->viewmat, lamp->winmat); | |
1642 | |
1643 /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender
*/ | |
1644 unit_m4(rangemat); | |
1645 rangemat[0][0] = 0.5f; | |
1646 rangemat[1][1] = 0.5f; | |
1647 rangemat[2][2] = 0.5f; | |
1648 rangemat[3][0] = 0.5f; | |
1649 rangemat[3][1] = 0.5f; | |
1650 rangemat[3][2] = 0.5f; | |
1651 | |
1652 mul_m4_m4m4(lamp->persmat, persmat, rangemat); | |
1653 | |
1654 /* opengl */ | |
1655 glDisable(GL_SCISSOR_TEST); | |
1656 GPU_framebuffer_texture_bind(lamp->fb, lamp->tex); | |
1657 | |
1658 /* set matrices */ | |
1659 copy_m4_m4(viewmat, lamp->viewmat); | |
1660 copy_m4_m4(winmat, lamp->winmat); | |
1661 *winsize = lamp->size; | |
1662 } | |
1663 | |
1664 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp) | |
1665 { | |
1666 GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex); | |
1667 GPU_framebuffer_restore(); | |
1668 glEnable(GL_SCISSOR_TEST); | |
1669 } | |
1670 | |
1671 int GPU_lamp_shadow_layer(GPULamp *lamp) | |
1672 { | |
1673 if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW))) | |
1674 return lamp->lay; | |
1675 else | |
1676 return -1; | |
1677 } | |
1678 | |
1679 /* export the GLSL shader */ | |
1680 | |
1681 GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) | |
1682 { | |
1683 static struct { | |
1684 GPUBuiltin gputype; | |
1685 GPUDynamicType dynamictype; | |
1686 GPUDataType datatype; | |
1687 } builtins[] = {· | |
1688 { GPU_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWMAT, GPU_DATA_16F }, | |
1689 { GPU_INVERSE_VIEW_MATRIX, GPU_DYNAMIC_OBJECT_VIEWIMAT, GPU_DATA
_16F }, | |
1690 { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F }, | |
1691 { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_1
6F }, | |
1692 { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F }, | |
1693 { 0 } | |
1694 }; | |
1695 | |
1696 GPUShaderExport *shader = NULL; | |
1697 GPUPass *pass; | |
1698 GPUInput *input; | |
1699 GPUMaterial *mat; | |
1700 GPUInputUniform *uniform; | |
1701 GPUInputAttribute *attribute; | |
1702 GLint lastbindcode; | |
1703 int i, liblen, fraglen; | |
1704 | |
1705 if(!GPU_glsl_support()) | |
1706 return NULL; | |
1707 | |
1708 mat = GPU_material_from_blender(scene, ma); | |
1709 pass = (mat)? mat->pass: NULL; | |
1710 | |
1711 if(pass && pass->fragmentcode && pass->vertexcode) { | |
1712 shader = MEM_callocN(sizeof(GPUShaderExport), "GPUShaderExport")
; | |
1713 | |
1714 for(input = pass->inputs.first; input; input = input->next) { | |
1715 uniform = MEM_callocN(sizeof(GPUInputUniform), "GPUInput
Uniform"); | |
1716 | |
1717 if(input->ima) { | |
1718 /* image sampler uniform */ | |
1719 uniform->type = GPU_DYNAMIC_SAMPLER_2DIMAGE; | |
1720 uniform->datatype = GPU_DATA_1I; | |
1721 uniform->image = input->ima; | |
1722 uniform->texnumber = input->texid; | |
1723 BLI_strncpy(uniform->varname, input->shadername,
sizeof(uniform->varname)); | |
1724 } | |
1725 else if(input->tex) { | |
1726 /* generated buffer */ | |
1727 uniform->texnumber = input->texid; | |
1728 uniform->datatype = GPU_DATA_1I; | |
1729 BLI_strncpy(uniform->varname, input->shadername,
sizeof(uniform->varname)); | |
1730 | |
1731 switch(input->textype) { | |
1732 case GPU_SHADOW2D: | |
1733 uniform->type = GPU_DYNAMIC_SAMPLER_2DSH
ADOW; | |
1734 uniform->lamp = input->dynamicdata; | |
1735 break; | |
1736 case GPU_TEX2D: | |
1737 if(GPU_texture_opengl_bindcode(input->te
x)) { | |
1738 uniform->type = GPU_DYNAMIC_SAMP
LER_2DBUFFER; | |
1739 glGetIntegerv(GL_TEXTURE_BINDING
_2D, &lastbindcode); | |
1740 glBindTexture(GL_TEXTURE_2D, GPU
_texture_opengl_bindcode(input->tex)); | |
1741 uniform->texsize = GPU_texture_o
pengl_width(input->tex) * GPU_texture_opengl_height(input->tex); | |
1742 uniform->texpixels = MEM_mallocN
(uniform->texsize*4, "RGBApixels"); | |
1743 glGetTexImage(GL_TEXTURE_2D, 0,
GL_RGBA, GL_UNSIGNED_BYTE, uniform->texpixels);· | |
1744 glBindTexture(GL_TEXTURE_2D, las
tbindcode); | |
1745 } | |
1746 break; | |
1747 } | |
1748 } | |
1749 else { | |
1750 uniform->type = input->dynamictype; | |
1751 BLI_strncpy(uniform->varname, input->shadername,
sizeof(uniform->varname)); | |
1752 switch(input->type) { | |
1753 case 1: | |
1754 uniform->datatype = GPU_DATA_1F; | |
1755 break; | |
1756 case 2: | |
1757 uniform->datatype = GPU_DATA_2F; | |
1758 break; | |
1759 case 3: | |
1760 uniform->datatype = GPU_DATA_3F; | |
1761 break; | |
1762 case 4: | |
1763 uniform->datatype = GPU_DATA_4F; | |
1764 break; | |
1765 case 9: | |
1766 uniform->datatype = GPU_DATA_9F; | |
1767 break; | |
1768 case 16: | |
1769 uniform->datatype = GPU_DATA_16F; | |
1770 break; | |
1771 } | |
1772 | |
1773 if(uniform->type >= GPU_DYNAMIC_LAMP_FIRST && un
iform->type <= GPU_DYNAMIC_LAMP_LAST) | |
1774 uniform->lamp = input->dynamicdata; | |
1775 } | |
1776 | |
1777 if(uniform->type != GPU_DYNAMIC_NONE) | |
1778 BLI_addtail(&shader->uniforms, uniform); | |
1779 else | |
1780 MEM_freeN(uniform); | |
1781 } | |
1782 | |
1783 /* process builtin uniform */ | |
1784 for(i=0; builtins[i].gputype; i++) { | |
1785 if(mat->builtins & builtins[i].gputype) { | |
1786 uniform = MEM_callocN(sizeof(GPUInputUniform), "
GPUInputUniform"); | |
1787 uniform->type = builtins[i].dynamictype; | |
1788 uniform->datatype = builtins[i].datatype; | |
1789 BLI_strncpy(uniform->varname, GPU_builtin_name(b
uiltins[i].gputype), sizeof(uniform->varname)); | |
1790 BLI_addtail(&shader->uniforms, uniform); | |
1791 } | |
1792 } | |
1793 | |
1794 // now link fragement shader with library shader | |
1795 // TBD: remove the function that are not used in the main functi
on | |
1796 liblen = (pass->libcode) ? strlen(pass->libcode) : 0; | |
1797 fraglen = strlen(pass->fragmentcode); | |
1798 shader->fragment = (char *)MEM_mallocN(liblen+fraglen+1, "GPUFra
gShader"); | |
1799 if(pass->libcode) | |
1800 memcpy(shader->fragment, pass->libcode, liblen); | |
1801 memcpy(&shader->fragment[liblen], pass->fragmentcode, fraglen); | |
1802 shader->fragment[liblen+fraglen] = 0; | |
1803 | |
1804 // export the attribute | |
1805 for(i=0; i<mat->attribs.totlayer; i++) { | |
1806 attribute = MEM_callocN(sizeof(GPUInputAttribute), "GPUI
nputAttribute"); | |
1807 attribute->type = mat->attribs.layer[i].type; | |
1808 attribute->number = mat->attribs.layer[i].glindex; | |
1809 BLI_snprintf(attribute->varname, sizeof(attribute->varna
me), "att%d", mat->attribs.layer[i].attribid); | |
1810 | |
1811 switch(attribute->type) { | |
1812 case CD_TANGENT: | |
1813 attribute->datatype = GPU_DATA_4F; | |
1814 break; | |
1815 case CD_MTFACE: | |
1816 attribute->datatype = GPU_DATA_2F; | |
1817 attribute->name = mat->attribs.layer[i].name; | |
1818 break; | |
1819 case CD_MCOL: | |
1820 attribute->datatype = GPU_DATA_4UB; | |
1821 attribute->name = mat->attribs.layer[i].name; | |
1822 break; | |
1823 case CD_ORCO: | |
1824 attribute->datatype = GPU_DATA_3F; | |
1825 break; | |
1826 } | |
1827 | |
1828 if(attribute->datatype != GPU_DATA_NONE) | |
1829 BLI_addtail(&shader->attributes, attribute); | |
1830 else | |
1831 MEM_freeN(attribute); | |
1832 } | |
1833 | |
1834 // export the vertex shader | |
1835 shader->vertex = BLI_strdup(pass->vertexcode); | |
1836 } | |
1837 | |
1838 return shader; | |
1839 } | |
1840 | |
1841 void GPU_free_shader_export(GPUShaderExport *shader) | |
1842 { | |
1843 GPUInputUniform *uniform; | |
1844 | |
1845 if(shader == NULL) | |
1846 return; | |
1847 | |
1848 for(uniform = shader->uniforms.first; uniform; uniform=uniform->next) | |
1849 if(uniform->texpixels) | |
1850 MEM_freeN(uniform->texpixels); | |
1851 | |
1852 BLI_freelistN(&shader->uniforms); | |
1853 BLI_freelistN(&shader->attributes); | |
1854 | |
1855 if(shader->vertex) | |
1856 MEM_freeN(shader->vertex); | |
1857 if(shader->fragment) | |
1858 MEM_freeN(shader->fragment); | |
1859 | |
1860 MEM_freeN(shader); | |
1861 } | |
1862 | |
LEFT | RIGHT |