|
Blender
V2.59
|
00001 /* 00002 * $Id: gpu_material.c 38790 2011-07-28 14:28:27Z blendix $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Brecht Van Lommel. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <math.h> 00036 #include <string.h> 00037 00038 #include "GL/glew.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "DNA_lamp_types.h" 00043 #include "DNA_material_types.h" 00044 #include "DNA_object_types.h" 00045 #include "DNA_scene_types.h" 00046 #include "DNA_world_types.h" 00047 00048 #include "BLI_math.h" 00049 #include "BLI_blenlib.h" 00050 #include "BLI_utildefines.h" 00051 00052 #include "BKE_anim.h" 00053 #include "BKE_colortools.h" 00054 #include "BKE_DerivedMesh.h" 00055 #include "BKE_global.h" 00056 #include "BKE_image.h" 00057 #include "BKE_main.h" 00058 #include "BKE_node.h" 00059 #include "BKE_scene.h" 00060 #include "BKE_texture.h" 00061 00062 #include "IMB_imbuf_types.h" 00063 00064 #include "GPU_extensions.h" 00065 #include "GPU_material.h" 00066 00067 #include "gpu_codegen.h" 00068 00069 #include <string.h> 00070 00071 /* Structs */ 00072 00073 typedef enum DynMatProperty { 00074 DYN_LAMP_CO = 1, 00075 DYN_LAMP_VEC = 2, 00076 DYN_LAMP_IMAT = 4, 00077 DYN_LAMP_PERSMAT = 8, 00078 } DynMatProperty; 00079 00080 struct GPUMaterial { 00081 Scene *scene; 00082 Material *ma; 00083 00084 /* for creating the material */ 00085 ListBase nodes; 00086 GPUNodeLink *outlink; 00087 00088 /* for binding the material */ 00089 GPUPass *pass; 00090 GPUVertexAttribs attribs; 00091 int bound; 00092 int builtins; 00093 int alpha, obcolalpha; 00094 int dynproperty; 00095 00096 /* for passing uniforms */ 00097 int viewmatloc, invviewmatloc; 00098 int obmatloc, invobmatloc; 00099 int obcolloc; 00100 00101 ListBase lamps; 00102 }; 00103 00104 struct GPULamp { 00105 Scene *scene; 00106 Object *ob; 00107 Object *par; 00108 Lamp *la; 00109 00110 int type, mode, lay, hide; 00111 00112 float dynenergy, dyncol[3]; 00113 float energy, col[3]; 00114 00115 float co[3], vec[3]; 00116 float dynco[3], dynvec[3]; 00117 float obmat[4][4]; 00118 float imat[4][4]; 00119 float dynimat[4][4]; 00120 00121 float spotsi, spotbl, k; 00122 float dist, att1, att2; 00123 00124 float bias, d, clipend; 00125 int size; 00126 00127 int falloff_type; 00128 struct CurveMapping *curfalloff; 00129 00130 float winmat[4][4]; 00131 float viewmat[4][4]; 00132 float persmat[4][4]; 00133 float dynpersmat[4][4]; 00134 00135 GPUFrameBuffer *fb; 00136 GPUTexture *tex; 00137 00138 ListBase materials; 00139 }; 00140 00141 /* Functions */ 00142 00143 static GPUMaterial *GPU_material_construct_begin(Material *ma) 00144 { 00145 GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial"); 00146 00147 material->ma= ma; 00148 00149 return material; 00150 } 00151 00152 static void gpu_material_set_attrib_id(GPUMaterial *material) 00153 { 00154 GPUVertexAttribs *attribs; 00155 GPUShader *shader; 00156 GPUPass *pass; 00157 char name[32]; 00158 int a, b; 00159 00160 attribs= &material->attribs; 00161 pass= material->pass; 00162 if(!pass) { 00163 attribs->totlayer = 0; 00164 return; 00165 } 00166 00167 shader= GPU_pass_shader(pass); 00168 if(!shader) { 00169 attribs->totlayer = 0; 00170 return; 00171 } 00172 00173 /* convert from attribute number to the actual id assigned by opengl, 00174 * in case the attrib does not get a valid index back, it was probably 00175 * removed by the glsl compiler by dead code elimination */ 00176 00177 for(a=0, b=0; a<attribs->totlayer; a++) { 00178 sprintf(name, "att%d", attribs->layer[a].glindex); 00179 attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name); 00180 00181 if(attribs->layer[a].glindex >= 0) { 00182 attribs->layer[b] = attribs->layer[a]; 00183 b++; 00184 } 00185 } 00186 00187 attribs->totlayer = b; 00188 } 00189 00190 static int GPU_material_construct_end(GPUMaterial *material) 00191 { 00192 if (material->outlink) { 00193 GPUNodeLink *outlink; 00194 GPUShader *shader; 00195 00196 outlink = material->outlink; 00197 material->pass = GPU_generate_pass(&material->nodes, outlink, 00198 &material->attribs, &material->builtins, material->ma->id.name); 00199 00200 if(!material->pass) 00201 return 0; 00202 00203 gpu_material_set_attrib_id(material); 00204 00205 shader = GPU_pass_shader(material->pass); 00206 00207 if(material->builtins & GPU_VIEW_MATRIX) 00208 material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX)); 00209 if(material->builtins & GPU_INVERSE_VIEW_MATRIX) 00210 material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX)); 00211 if(material->builtins & GPU_OBJECT_MATRIX) 00212 material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX)); 00213 if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) 00214 material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); 00215 if(material->builtins & GPU_OBCOLOR) 00216 material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); 00217 00218 return 1; 00219 } 00220 00221 return 0; 00222 } 00223 00224 void GPU_material_free(Material *ma) 00225 { 00226 LinkData *link; 00227 LinkData *nlink, *mlink, *next; 00228 00229 for(link=ma->gpumaterial.first; link; link=link->next) { 00230 GPUMaterial *material = link->data; 00231 00232 if(material->pass) 00233 GPU_pass_free(material->pass); 00234 00235 for(nlink=material->lamps.first; nlink; nlink=nlink->next) { 00236 GPULamp *lamp = nlink->data; 00237 00238 for(mlink=lamp->materials.first; mlink; mlink=next) { 00239 next = mlink->next; 00240 if(mlink->data == ma) 00241 BLI_freelinkN(&lamp->materials, mlink); 00242 } 00243 } 00244 00245 BLI_freelistN(&material->lamps); 00246 00247 MEM_freeN(material); 00248 } 00249 00250 BLI_freelistN(&ma->gpumaterial); 00251 } 00252 00253 void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap) 00254 { 00255 if(material->pass) { 00256 LinkData *nlink; 00257 GPULamp *lamp; 00258 00259 /* handle layer lamps */ 00260 for(nlink=material->lamps.first; nlink; nlink=nlink->next) { 00261 lamp= nlink->data; 00262 00263 if(!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) { 00264 lamp->dynenergy = lamp->energy; 00265 VECCOPY(lamp->dyncol, lamp->col); 00266 } 00267 else { 00268 lamp->dynenergy = 0.0f; 00269 lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f; 00270 } 00271 } 00272 00273 GPU_pass_bind(material->pass, time, mipmap); 00274 material->bound = 1; 00275 } 00276 } 00277 00278 void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]) 00279 { 00280 if(material->pass) { 00281 GPUShader *shader = GPU_pass_shader(material->pass); 00282 LinkData *nlink; 00283 GPULamp *lamp; 00284 float invmat[4][4], col[4]; 00285 00286 /* handle builtins */ 00287 if(material->builtins & GPU_VIEW_MATRIX) { 00288 GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat); 00289 } 00290 if(material->builtins & GPU_INVERSE_VIEW_MATRIX) { 00291 GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv); 00292 } 00293 if(material->builtins & GPU_OBJECT_MATRIX) { 00294 GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat); 00295 } 00296 if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) { 00297 invert_m4_m4(invmat, obmat); 00298 GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat); 00299 } 00300 if(material->builtins & GPU_OBCOLOR) { 00301 QUATCOPY(col, obcol); 00302 CLAMP(col[3], 0.0f, 1.0f); 00303 GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col); 00304 } 00305 00306 /* update lamps */ 00307 for(nlink=material->lamps.first; nlink; nlink=nlink->next) { 00308 lamp= nlink->data; 00309 00310 if(material->dynproperty & DYN_LAMP_VEC) { 00311 VECCOPY(lamp->dynvec, lamp->vec); 00312 normalize_v3(lamp->dynvec); 00313 negate_v3(lamp->dynvec); 00314 mul_mat3_m4_v3(viewmat, lamp->dynvec); 00315 } 00316 00317 if(material->dynproperty & DYN_LAMP_CO) { 00318 VECCOPY(lamp->dynco, lamp->co); 00319 mul_m4_v3(viewmat, lamp->dynco); 00320 } 00321 00322 if(material->dynproperty & DYN_LAMP_IMAT) 00323 mul_m4_m4m4(lamp->dynimat, viewinv, lamp->imat); 00324 if(material->dynproperty & DYN_LAMP_PERSMAT) 00325 mul_m4_m4m4(lamp->dynpersmat, viewinv, lamp->persmat); 00326 } 00327 00328 GPU_pass_update_uniforms(material->pass); 00329 } 00330 } 00331 00332 void GPU_material_unbind(GPUMaterial *material) 00333 { 00334 if (material->pass) { 00335 material->bound = 0; 00336 GPU_pass_unbind(material->pass); 00337 } 00338 } 00339 00340 int GPU_material_bound(GPUMaterial *material) 00341 { 00342 return material->bound; 00343 } 00344 00345 void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) 00346 { 00347 *attribs = material->attribs; 00348 } 00349 00350 void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) 00351 { 00352 if(!material->outlink) 00353 material->outlink= link; 00354 } 00355 00356 void GPU_material_enable_alpha(GPUMaterial *material) 00357 { 00358 material->alpha= 1; 00359 } 00360 00361 GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[3]) 00362 { 00363 if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f)) 00364 return GPU_BLEND_ALPHA; 00365 else 00366 return GPU_BLEND_SOLID; 00367 } 00368 00369 void gpu_material_add_node(GPUMaterial *material, GPUNode *node) 00370 { 00371 BLI_addtail(&material->nodes, node); 00372 } 00373 00374 /* Code generation */ 00375 00376 static int gpu_do_color_management(GPUMaterial *mat) 00377 { 00378 return ((mat->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) && 00379 !((mat->scene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT))); 00380 } 00381 00382 static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist) 00383 { 00384 GPUNodeLink *visifac, *inpr; 00385 00386 /* from get_lamp_visibility */ 00387 if(lamp->type==LA_SUN || lamp->type==LA_HEMI) { 00388 mat->dynproperty |= DYN_LAMP_VEC; 00389 GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec), lv, dist, &visifac); 00390 return visifac; 00391 } 00392 else { 00393 mat->dynproperty |= DYN_LAMP_CO; 00394 GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), lv, dist, &visifac); 00395 00396 if(lamp->type==LA_AREA) 00397 return visifac; 00398 00399 switch(lamp->falloff_type) 00400 { 00401 case LA_FALLOFF_CONSTANT: 00402 break; 00403 case LA_FALLOFF_INVLINEAR: 00404 GPU_link(mat, "lamp_falloff_invlinear", GPU_uniform(&lamp->dist), *dist, &visifac); 00405 break; 00406 case LA_FALLOFF_INVSQUARE: 00407 GPU_link(mat, "lamp_falloff_invsquare", GPU_uniform(&lamp->dist), *dist, &visifac); 00408 break; 00409 case LA_FALLOFF_SLIDERS: 00410 GPU_link(mat, "lamp_falloff_sliders", GPU_uniform(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visifac); 00411 break; 00412 case LA_FALLOFF_CURVE: 00413 { 00414 float *array; 00415 int size; 00416 00417 curvemapping_table_RGBA(lamp->curfalloff, &array, &size); 00418 GPU_link(mat, "lamp_falloff_curve", GPU_uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac); 00419 } 00420 break; 00421 } 00422 00423 if(lamp->mode & LA_SPHERE) 00424 GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lamp->dist), *dist, visifac, &visifac); 00425 00426 if(lamp->type == LA_SPOT) { 00427 if(lamp->mode & LA_SQUARE) { 00428 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT; 00429 GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec), GPU_dynamic_uniform((float*)lamp->dynimat), *lv, &inpr); 00430 } 00431 else { 00432 mat->dynproperty |= DYN_LAMP_VEC; 00433 GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec), *lv, &inpr); 00434 } 00435 00436 GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac); 00437 } 00438 00439 GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac); 00440 00441 return visifac; 00442 } 00443 } 00444 00445 #if 0 00446 static void area_lamp_vectors(LampRen *lar) 00447 { 00448 float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac; 00449 00450 /* make it smaller, so area light can be multisampled */ 00451 multifac= 1.0f/sqrt((float)lar->ray_totsamp); 00452 xsize *= multifac; 00453 ysize *= multifac; 00454 00455 /* corner vectors */ 00456 lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; 00457 lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; 00458 lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; 00459 00460 /* corner vectors */ 00461 lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; 00462 lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; 00463 lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; 00464 00465 /* corner vectors */ 00466 lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; 00467 lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; 00468 lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; 00469 00470 /* corner vectors */ 00471 lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; 00472 lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; 00473 lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; 00474 /* only for correction button size, matrix size works on energy */ 00475 lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize); 00476 } 00477 #endif 00478 00479 static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol) 00480 { 00481 static const char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub", 00482 "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light", 00483 "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat", 00484 "mix_val", "mix_color", "mix_soft", "mix_linear"}; 00485 00486 GPU_link(mat, names[type], fac, col1, col2, outcol); 00487 } 00488 00489 static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol) 00490 { 00491 GPUNodeLink *tmp, *alpha, *col; 00492 float *array; 00493 int size; 00494 00495 /* do colorband */ 00496 colorband_table_RGBA(coba, &array, &size); 00497 GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp); 00498 00499 /* use alpha in fac */ 00500 GPU_link(mat, "mtex_alpha_from_col", col, &alpha); 00501 GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac); 00502 00503 /* blending method */ 00504 ramp_blend(mat, fac, incol, col, type, outcol); 00505 } 00506 00507 static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff) 00508 { 00509 Material *ma= shi->mat; 00510 GPUMaterial *mat= shi->gpumat; 00511 GPUNodeLink *fac; 00512 00513 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS)) { 00514 if(ma->ramp_col) { 00515 if(ma->rampin_col==MA_RAMP_IN_RESULT) { 00516 GPU_link(mat, "ramp_rgbtobw", *diff, &fac); 00517 00518 /* colorband + blend */ 00519 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff); 00520 } 00521 } 00522 } 00523 } 00524 00525 static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff) 00526 { 00527 GPUNodeLink *fac, *tmp, *addcol; 00528 00529 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) && 00530 ma->ramp_col && (ma->mode & MA_RAMP_COL)) { 00531 /* MA_RAMP_IN_RESULT is exceptional */ 00532 if(ma->rampin_col==MA_RAMP_IN_RESULT) { 00533 addcol = shi->rgb; 00534 } 00535 else { 00536 /* input */ 00537 switch(ma->rampin_col) { 00538 case MA_RAMP_IN_ENERGY: 00539 GPU_link(mat, "ramp_rgbtobw", rgb, &fac); 00540 break; 00541 case MA_RAMP_IN_SHADER: 00542 fac= is; 00543 break; 00544 case MA_RAMP_IN_NOR: 00545 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac); 00546 break; 00547 default: 00548 GPU_link(mat, "set_value_zero", &fac); 00549 break; 00550 } 00551 00552 /* colorband + blend */ 00553 do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol); 00554 } 00555 } 00556 else 00557 addcol = shi->rgb; 00558 00559 /* output to */ 00560 GPU_link(mat, "shade_madd_clamped", *diff, rgb, addcol, diff); 00561 } 00562 00563 static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec) 00564 { 00565 Material *ma= shi->mat; 00566 GPUMaterial *mat= shi->gpumat; 00567 GPUNodeLink *fac; 00568 00569 if(!(mat->scene->gm.flag & GAME_GLSL_NO_RAMPS) && 00570 ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT) { 00571 GPU_link(mat, "ramp_rgbtobw", *spec, &fac); 00572 00573 /* colorband + blend */ 00574 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec); 00575 } 00576 } 00577 00578 static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec) 00579 { 00580 Material *ma= shi->mat; 00581 GPUMaterial *mat= shi->gpumat; 00582 GPUNodeLink *fac, *tmp; 00583 00584 *spec = shi->specrgb; 00585 00586 /* MA_RAMP_IN_RESULT is exception */ 00587 if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) { 00588 00589 /* input */ 00590 switch(ma->rampin_spec) { 00591 case MA_RAMP_IN_ENERGY: 00592 fac = t; 00593 break; 00594 case MA_RAMP_IN_SHADER: 00595 fac = is; 00596 break; 00597 case MA_RAMP_IN_NOR: 00598 GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac); 00599 break; 00600 default: 00601 GPU_link(mat, "set_value_zero", &fac); 00602 break; 00603 } 00604 00605 /* colorband + blend */ 00606 do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec); 00607 } 00608 } 00609 00610 static void add_user_list(ListBase *list, void *data) 00611 { 00612 LinkData *link = MEM_callocN(sizeof(LinkData), "GPULinkData"); 00613 link->data = data; 00614 BLI_addtail(list, link); 00615 } 00616 00617 static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp) 00618 { 00619 Material *ma= shi->mat; 00620 GPUMaterial *mat= shi->gpumat; 00621 GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view; 00622 GPUNodeLink *outcol, *specfac, *t, *shadfac= NULL; 00623 float one = 1.0f; 00624 00625 if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW)) 00626 return; 00627 00628 vn= shi->vn; 00629 view= shi->view; 00630 00631 visifac= lamp_get_visibility(mat, lamp, &lv, &dist); 00632 00633 /*if(ma->mode & MA_TANGENT_V) 00634 GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);*/ 00635 00636 GPU_link(mat, "shade_inp", vn, lv, &inp); 00637 00638 if(lamp->mode & LA_NO_DIFF) { 00639 GPU_link(mat, "shade_is_no_diffuse", &is); 00640 } 00641 else if(lamp->type == LA_HEMI) { 00642 GPU_link(mat, "shade_is_hemi", inp, &is); 00643 } 00644 else { 00645 if(lamp->type == LA_AREA) { 00646 float area[4][4]= {{0.0f}}, areasize= 0.0f; 00647 00648 mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO; 00649 GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), GPU_dynamic_uniform(lamp->dynvec), vn, GPU_uniform((float*)area), 00650 GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp); 00651 } 00652 00653 is= inp; /* Lambert */ 00654 00655 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) { 00656 if(ma->diff_shader==MA_DIFF_ORENNAYAR) 00657 GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, GPU_uniform(&ma->roughness), &is); 00658 else if(ma->diff_shader==MA_DIFF_TOON) 00659 GPU_link(mat, "shade_diffuse_toon", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); 00660 else if(ma->diff_shader==MA_DIFF_MINNAERT) 00661 GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, GPU_uniform(&ma->darkness), &is); 00662 else if(ma->diff_shader==MA_DIFF_FRESNEL) 00663 GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is); 00664 } 00665 } 00666 00667 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS)) 00668 if(ma->shade_flag & MA_CUBIC) 00669 GPU_link(mat, "shade_cubic", is, &is); 00670 00671 i = is; 00672 GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i); 00673 00674 00675 /*if(ma->mode & MA_TANGENT_VN) 00676 GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/ 00677 00678 /* this replaces if(i > 0.0) conditional until that is supported */ 00679 // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i); 00680 00681 if((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) { 00682 if(!(mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS)) { 00683 mat->dynproperty |= DYN_LAMP_PERSMAT; 00684 00685 GPU_link(mat, "test_shadowbuf", 00686 GPU_builtin(GPU_VIEW_POSITION), 00687 GPU_dynamic_texture(lamp->tex), 00688 GPU_dynamic_uniform((float*)lamp->dynpersmat), 00689 GPU_uniform(&lamp->bias), inp, &shadfac); 00690 00691 if(lamp->mode & LA_ONLYSHADOW) { 00692 GPU_link(mat, "shade_only_shadow", i, shadfac, 00693 GPU_dynamic_uniform(&lamp->dynenergy), &shadfac); 00694 00695 if(!(lamp->mode & LA_NO_DIFF)) 00696 GPU_link(mat, "shade_only_shadow_diffuse", shadfac, shi->rgb, 00697 shr->diff, &shr->diff); 00698 00699 if(!(lamp->mode & LA_NO_SPEC)) 00700 GPU_link(mat, "shade_only_shadow_specular", shadfac, shi->specrgb, 00701 shr->spec, &shr->spec); 00702 00703 add_user_list(&mat->lamps, lamp); 00704 add_user_list(&lamp->materials, shi->gpumat->ma); 00705 return; 00706 } 00707 00708 GPU_link(mat, "math_multiply", i, shadfac, &i); 00709 } 00710 } 00711 else if((mat->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) { 00712 add_user_list(&mat->lamps, lamp); 00713 add_user_list(&lamp->materials, shi->gpumat->ma); 00714 return; 00715 } 00716 else 00717 GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac); 00718 00719 if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) { 00720 if(!(lamp->mode & LA_NO_DIFF)) { 00721 GPUNodeLink *rgb; 00722 GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol), &rgb); 00723 add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff); 00724 } 00725 } 00726 00727 if(mat->scene->gm.flag & GAME_GLSL_NO_SHADERS); 00728 else if(!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && 00729 (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { 00730 if(lamp->type == LA_HEMI) { 00731 GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t); 00732 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol); 00733 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); 00734 } 00735 else { 00736 if(ma->spec_shader==MA_SPEC_PHONG) 00737 GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac); 00738 else if(ma->spec_shader==MA_SPEC_COOKTORR) 00739 GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac); 00740 else if(ma->spec_shader==MA_SPEC_BLINN) 00741 GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac); 00742 else if(ma->spec_shader==MA_SPEC_WARDISO) 00743 GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac); 00744 else 00745 GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac); 00746 00747 if(lamp->type==LA_AREA) 00748 GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac); 00749 00750 GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t); 00751 00752 if(ma->mode & MA_RAMP_SPEC) { 00753 GPUNodeLink *spec; 00754 do_specular_ramp(shi, specfac, t, &spec); 00755 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), spec, &outcol); 00756 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); 00757 } 00758 else { 00759 GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol); 00760 GPU_link(mat, "shade_add_clamped", shr->spec, outcol, &shr->spec); 00761 } 00762 } 00763 } 00764 00765 add_user_list(&mat->lamps, lamp); 00766 add_user_list(&lamp->materials, shi->gpumat->ma); 00767 } 00768 00769 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr) 00770 { 00771 Base *base; 00772 Object *ob; 00773 Scene *sce_iter; 00774 GPULamp *lamp; 00775 00776 for(SETLOOPER(shi->gpumat->scene, sce_iter, base)) { 00777 ob= base->object; 00778 00779 if(ob->type==OB_LAMP) { 00780 lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL); 00781 if(lamp) 00782 shade_one_light(shi, shr, lamp); 00783 } 00784 00785 if (ob->transflag & OB_DUPLI) { 00786 DupliObject *dob; 00787 ListBase *lb = object_duplilist(shi->gpumat->scene, ob); 00788 00789 for(dob=lb->first; dob; dob=dob->next) { 00790 Object *ob_iter = dob->ob; 00791 00792 if(ob_iter->type==OB_LAMP) { 00793 copy_m4_m4(ob_iter->obmat, dob->mat); 00794 00795 lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob); 00796 if(lamp) 00797 shade_one_light(shi, shr, lamp); 00798 } 00799 } 00800 00801 free_object_duplilist(lb); 00802 } 00803 } 00804 } 00805 00806 static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in) 00807 { 00808 switch(blendtype) { 00809 case MTEX_BLEND: 00810 GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in); 00811 break; 00812 case MTEX_MUL: 00813 GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in); 00814 break; 00815 case MTEX_SCREEN: 00816 GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in); 00817 break; 00818 case MTEX_OVERLAY: 00819 GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in); 00820 break; 00821 case MTEX_SUB: 00822 GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in); 00823 break; 00824 case MTEX_ADD: 00825 GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in); 00826 break; 00827 case MTEX_DIV: 00828 GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in); 00829 break; 00830 case MTEX_DIFF: 00831 GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in); 00832 break; 00833 case MTEX_DARK: 00834 GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in); 00835 break; 00836 case MTEX_LIGHT: 00837 GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in); 00838 break; 00839 case MTEX_BLEND_HUE: 00840 GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in); 00841 break; 00842 case MTEX_BLEND_SAT: 00843 GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in); 00844 break; 00845 case MTEX_BLEND_VAL: 00846 GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in); 00847 break; 00848 case MTEX_BLEND_COLOR: 00849 GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in); 00850 break; 00851 default: 00852 GPU_link(mat, "set_rgb_zero", &in); 00853 break; 00854 } 00855 } 00856 00857 static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in) 00858 { 00859 switch(blendtype) { 00860 case MTEX_BLEND: 00861 GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, in); 00862 break; 00863 case MTEX_MUL: 00864 GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, in); 00865 break; 00866 case MTEX_SCREEN: 00867 GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, in); 00868 break; 00869 case MTEX_SUB: 00870 GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, in); 00871 break; 00872 case MTEX_ADD: 00873 GPU_link(mat, "mtex_value_add", out, tex, fact, facg, in); 00874 break; 00875 case MTEX_DIV: 00876 GPU_link(mat, "mtex_value_div", out, tex, fact, facg, in); 00877 break; 00878 case MTEX_DIFF: 00879 GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, in); 00880 break; 00881 case MTEX_DARK: 00882 GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, in); 00883 break; 00884 case MTEX_LIGHT: 00885 GPU_link(mat, "mtex_value_light", out, tex, fact, facg, in); 00886 break; 00887 default: 00888 GPU_link(mat, "set_value_zero", &in); 00889 break; 00890 } 00891 } 00892 00893 static void do_material_tex(GPUShadeInput *shi) 00894 { 00895 Material *ma= shi->mat; 00896 GPUMaterial *mat= shi->gpumat; 00897 MTex *mtex; 00898 Tex *tex; 00899 GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac; 00900 GPUNodeLink *texco_norm, *texco_orco, *texco_object; 00901 GPUNodeLink *texco_global, *texco_uv = NULL; 00902 GPUNodeLink *newnor, *orn; 00903 /*char *lastuvname = NULL;*/ /*UNUSED*/ 00904 float one = 1.0f, norfac, ofs[3]; 00905 int tex_nr, rgbnor, talpha; 00906 int init_done = 0, iBumpSpacePrev; 00907 GPUNodeLink *vNorg, *vNacc, *fPrevMagnitude; 00908 int iFirstTimeNMap=1; 00909 00910 GPU_link(mat, "set_value", GPU_uniform(&one), &stencil); 00911 00912 GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm); 00913 GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco); 00914 GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), 00915 GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 00916 GPU_builtin(GPU_VIEW_POSITION), &texco_object); 00917 //GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent); 00918 GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX), 00919 GPU_builtin(GPU_VIEW_POSITION), &texco_global); 00920 00921 orn= texco_norm; 00922 00923 /* go over texture slots */ 00924 for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { 00925 /* separate tex switching */ 00926 if(ma->septex & (1<<tex_nr)) continue; 00927 00928 if(ma->mtex[tex_nr]) { 00929 mtex= ma->mtex[tex_nr]; 00930 00931 tex= mtex->tex; 00932 if(tex == NULL) continue; 00933 00934 /* which coords */ 00935 if(mtex->texco==TEXCO_ORCO) 00936 texco= texco_orco; 00937 else if(mtex->texco==TEXCO_OBJECT) 00938 texco= texco_object; 00939 else if(mtex->texco==TEXCO_NORM) 00940 texco= orn; 00941 else if(mtex->texco==TEXCO_TANGENT) 00942 texco= texco_object; 00943 else if(mtex->texco==TEXCO_GLOB) 00944 texco= texco_global; 00945 else if(mtex->texco==TEXCO_REFL) { 00946 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); 00947 texco= shi->ref; 00948 } 00949 else if(mtex->texco==TEXCO_UV) { 00950 if(1) { 00951 GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv); 00952 /*lastuvname = mtex->uvname;*/ /*UNUSED*/ 00953 } 00954 texco= texco_uv; 00955 } 00956 else 00957 continue; 00958 00959 /* in case of uv, this would just undo a multiplication in texco_uv */ 00960 if(mtex->texco != TEXCO_UV) 00961 GPU_link(mat, "mtex_2d_mapping", texco, &texco); 00962 00963 if(mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f) 00964 GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco); 00965 00966 ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0]; 00967 ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1]; 00968 ofs[2] = 0.0f; 00969 if(ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f) 00970 GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco); 00971 00972 talpha = 0; 00973 rgbnor = 0; 00974 00975 if(tex && tex->type == TEX_IMAGE && tex->ima) { 00976 GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser), &tin, &trgb); 00977 rgbnor= TEX_RGB; 00978 00979 if(tex->imaflag & TEX_USEALPHA) 00980 talpha= 1; 00981 } 00982 else continue; 00983 00984 /* texture output */ 00985 if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { 00986 GPU_link(mat, "mtex_rgbtoint", trgb, &tin); 00987 rgbnor -= TEX_RGB; 00988 } 00989 00990 if(mtex->texflag & MTEX_NEGATIVE) { 00991 if(rgbnor & TEX_RGB) 00992 GPU_link(mat, "mtex_rgb_invert", trgb, &trgb); 00993 else 00994 GPU_link(mat, "mtex_value_invert", tin, &tin); 00995 } 00996 00997 if(mtex->texflag & MTEX_STENCIL) { 00998 if(rgbnor & TEX_RGB) 00999 GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb); 01000 else 01001 GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin); 01002 } 01003 01004 /* mapping */ 01005 if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) { 01006 /* stencil maps on the texture control slider, not texture intensity value */ 01007 if((rgbnor & TEX_RGB)==0) { 01008 GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol); 01009 } 01010 else { 01011 GPU_link(mat, "set_rgba", trgb, &tcol); 01012 01013 if(mtex->mapto & MAP_ALPHA) 01014 GPU_link(mat, "set_value", stencil, &tin); 01015 else if(talpha) 01016 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); 01017 else 01018 GPU_link(mat, "set_value_one", &tin); 01019 } 01020 01021 if(tex->type==TEX_IMAGE) 01022 if(gpu_do_color_management(mat)) 01023 GPU_link(mat, "srgb_to_linearrgb", tcol, &tcol); 01024 01025 if(mtex->mapto & MAP_COL) { 01026 GPUNodeLink *colfac; 01027 01028 if(mtex->colfac == 1.0f) colfac = stencil; 01029 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac); 01030 01031 texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb); 01032 } 01033 01034 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC)) { 01035 GPUNodeLink *colspecfac; 01036 01037 if(mtex->colspecfac == 1.0f) colspecfac = stencil; 01038 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colspecfac), stencil, &colspecfac); 01039 01040 texture_rgb_blend(mat, tcol, shi->specrgb, tin, colspecfac, mtex->blendtype, &shi->specrgb); 01041 } 01042 } 01043 01044 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) { 01045 if(tex->type==TEX_IMAGE) { 01046 if(tex->imaflag & TEX_NORMALMAP) { 01047 /* normalmap image */ 01048 GPU_link(mat, "mtex_normal", texco, GPU_image(tex->ima, &tex->iuser), &tnor ); 01049 01050 if(mtex->norfac < 0.0f) 01051 GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor); 01052 01053 if(mtex->normapspace == MTEX_NSPACE_TANGENT) 01054 { 01055 if(iFirstTimeNMap!=0) 01056 { 01057 // use unnormalized normal (this is how we bake it - closer to gamedev) 01058 GPUNodeLink *vNegNorm; 01059 GPU_link(mat, "vec_math_negate", GPU_builtin(GPU_VIEW_NORMAL), &vNegNorm); 01060 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), vNegNorm, tnor, &newnor); 01061 iFirstTimeNMap = 0; 01062 } 01063 else // otherwise use accumulated perturbations 01064 { 01065 GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor); 01066 } 01067 } 01068 else 01069 newnor = tnor; 01070 01071 norfac = MIN2(fabsf(mtex->norfac), 1.0f); 01072 01073 if(norfac == 1.0f && !GPU_link_changed(stencil)) { 01074 shi->vn = newnor; 01075 } 01076 else { 01077 tnorfac = GPU_uniform(&norfac); 01078 01079 if(GPU_link_changed(stencil)) 01080 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); 01081 01082 GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn); 01083 } 01084 01085 } else if( mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)) { 01086 /* ntap bumpmap image */ 01087 int iBumpSpace; 01088 float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types 01089 float hScaleTex = 13.0f; // factor for scaling texspace bumps 01090 01091 GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION); 01092 GPUNodeLink *vR1, *vR2; 01093 GPUNodeLink *dBs, *dBt, *fDet; 01094 01095 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) 01096 hScale = hScaleTex; 01097 norfac = hScale * mtex->norfac; 01098 tnorfac = GPU_uniform(&norfac); 01099 01100 if(GPU_link_changed(stencil)) 01101 GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); 01102 01103 if( !init_done ) { 01104 // copy shi->vn to vNorg and vNacc, set magnitude to 1 01105 GPU_link(mat, "mtex_bump_normals_init", shi->vn, &vNorg, &vNacc, &fPrevMagnitude); 01106 iBumpSpacePrev = 0; 01107 init_done = 1; 01108 } 01109 01110 // find current bump space 01111 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) 01112 iBumpSpace = 1; 01113 else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) 01114 iBumpSpace = 2; 01115 else 01116 iBumpSpace = 4; // ViewSpace 01117 01118 // re-initialize if bump space changed 01119 if( iBumpSpacePrev != iBumpSpace ) { 01120 01121 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) 01122 GPU_link( mat, "mtex_bump_init_objspace", 01123 surf_pos, vNorg, 01124 GPU_builtin(GPU_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), 01125 fPrevMagnitude, vNacc, 01126 &fPrevMagnitude, &vNacc, 01127 &vR1, &vR2, &fDet ); 01128 01129 else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) 01130 GPU_link( mat, "mtex_bump_init_texturespace", 01131 surf_pos, vNorg, 01132 fPrevMagnitude, vNacc, 01133 &fPrevMagnitude, &vNacc, 01134 &vR1, &vR2, &fDet ); 01135 01136 else 01137 GPU_link( mat, "mtex_bump_init_viewspace", 01138 surf_pos, vNorg, 01139 fPrevMagnitude, vNacc, 01140 &fPrevMagnitude, &vNacc, 01141 &vR1, &vR2, &fDet ); 01142 01143 iBumpSpacePrev = iBumpSpace; 01144 } 01145 01146 01147 if( mtex->texflag & MTEX_3TAP_BUMP ) 01148 GPU_link( mat, "mtex_bump_tap3", 01149 texco, GPU_image(tex->ima, &tex->iuser), tnorfac, 01150 &dBs, &dBt ); 01151 else 01152 GPU_link( mat, "mtex_bump_tap5", 01153 texco, GPU_image(tex->ima, &tex->iuser), tnorfac, 01154 &dBs, &dBt ); 01155 01156 01157 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { 01158 float ima_x= 512.0f, ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only 01159 ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser); 01160 if(ibuf) { 01161 ima_x= ibuf->x; 01162 ima_y= ibuf->y; 01163 } 01164 01165 GPU_link( mat, "mtex_bump_apply_texspace", 01166 fDet, dBs, dBt, vR1, vR2, 01167 GPU_image(tex->ima, &tex->iuser), texco, GPU_uniform(&ima_x), GPU_uniform(&ima_y), vNacc, 01168 &vNacc, &shi->vn ); 01169 } else 01170 GPU_link( mat, "mtex_bump_apply", 01171 fDet, dBs, dBt, vR1, vR2, vNacc, 01172 &vNacc, &shi->vn ); 01173 01174 } 01175 } 01176 01177 GPU_link(mat, "vec_math_negate", shi->vn, &orn); 01178 } 01179 01180 if((mtex->mapto & MAP_VARS)) { 01181 if(rgbnor & TEX_RGB) { 01182 if(talpha) 01183 GPU_link(mat, "mtex_alpha_from_col", trgb, &tin); 01184 else 01185 GPU_link(mat, "mtex_rgbtoint", trgb, &tin); 01186 } 01187 01188 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) { 01189 GPUNodeLink *difffac; 01190 01191 if(mtex->difffac == 1.0f) difffac = stencil; 01192 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->difffac), stencil, &difffac); 01193 01194 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, difffac, mtex->blendtype, &shi->refl); 01195 GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl); 01196 } 01197 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) { 01198 GPUNodeLink *specfac; 01199 01200 if(mtex->specfac == 1.0f) specfac = stencil; 01201 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->specfac), stencil, &specfac); 01202 01203 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, specfac, mtex->blendtype, &shi->spec); 01204 GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec); 01205 } 01206 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) { 01207 GPUNodeLink *emitfac; 01208 01209 if(mtex->emitfac == 1.0f) emitfac = stencil; 01210 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->emitfac), stencil, &emitfac); 01211 01212 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, emitfac, mtex->blendtype, &shi->emit); 01213 GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit); 01214 } 01215 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) { 01216 GPUNodeLink *hardfac; 01217 01218 if(mtex->hardfac == 1.0f) hardfac = stencil; 01219 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->hardfac), stencil, &hardfac); 01220 01221 GPU_link(mat, "mtex_har_divide", shi->har, &shi->har); 01222 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, hardfac, mtex->blendtype, &shi->har); 01223 GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har); 01224 } 01225 if(mtex->mapto & MAP_ALPHA) { 01226 GPUNodeLink *alphafac; 01227 01228 if(mtex->alphafac == 1.0f) alphafac = stencil; 01229 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->alphafac), stencil, &alphafac); 01230 01231 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, alphafac, mtex->blendtype, &shi->alpha); 01232 GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha); 01233 } 01234 if(!(mat->scene->gm.flag & GAME_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) { 01235 GPUNodeLink *ambfac; 01236 01237 if(mtex->ambfac == 1.0f) ambfac = stencil; 01238 else GPU_link(mat, "math_multiply", GPU_uniform(&mtex->ambfac), stencil, &ambfac); 01239 01240 texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, ambfac, mtex->blendtype, &shi->amb); 01241 GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb); 01242 } 01243 } 01244 } 01245 } 01246 } 01247 01248 void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi) 01249 { 01250 float hard = ma->har; 01251 01252 memset(shi, 0, sizeof(*shi)); 01253 01254 shi->gpumat = mat; 01255 shi->mat = ma; 01256 01257 GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb); 01258 GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb); 01259 GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn); 01260 GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha); 01261 GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl); 01262 GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec); 01263 GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit); 01264 GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har); 01265 GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb); 01266 GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view); 01267 GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol); 01268 if(gpu_do_color_management(mat)) 01269 GPU_link(mat, "srgb_to_linearrgb", shi->vcol, &shi->vcol); 01270 GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref); 01271 } 01272 01273 void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr) 01274 { 01275 GPUMaterial *mat= shi->gpumat; 01276 GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac; 01277 Material *ma= shi->mat; 01278 World *world= mat->scene->world; 01279 float linfac, logfac, misttype; 01280 01281 memset(shr, 0, sizeof(*shr)); 01282 01283 if(ma->mode & MA_VERTEXCOLP) 01284 shi->rgb = shi->vcol; 01285 01286 do_material_tex(shi); 01287 01288 if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) 01289 GPU_material_enable_alpha(mat); 01290 01291 if((mat->scene->gm.flag & GAME_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) { 01292 shr->combined = shi->rgb; 01293 shr->alpha = shi->alpha; 01294 GPU_link(mat, "set_rgb", shi->rgb, &shr->diff); 01295 GPU_link(mat, "set_rgb_zero", &shr->spec); 01296 } 01297 else { 01298 if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) { 01299 if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) { 01300 GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit); 01301 GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff); 01302 } 01303 else 01304 GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff); 01305 } 01306 else 01307 GPU_link(mat, "set_rgb_zero", &shr->diff); 01308 01309 GPU_link(mat, "set_rgb_zero", &shr->spec); 01310 01311 material_lights(shi, shr); 01312 01313 shr->combined = shr->diff; 01314 shr->alpha = shi->alpha; 01315 01316 if(world) { 01317 /* exposure correction */ 01318 if(world->exp!=0.0f || world->range!=1.0f) { 01319 linfac= 1.0 + pow((2.0*world->exp + 0.5), -10); 01320 logfac= log((linfac-1.0f)/linfac)/world->range; 01321 01322 GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac); 01323 GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac); 01324 01325 GPU_link(mat, "shade_exposure_correct", shr->combined, 01326 ulinfac, ulogfac, &shr->combined); 01327 GPU_link(mat, "shade_exposure_correct", shr->spec, 01328 ulinfac, ulogfac, &shr->spec); 01329 } 01330 01331 /* ambient color */ 01332 if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) { 01333 if(GPU_link_changed(shi->amb) || ma->amb != 0.0f) 01334 GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb), 01335 GPU_uniform(&world->ambr), &shr->combined); 01336 } 01337 } 01338 01339 if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined); 01340 if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec); 01341 01342 if(GPU_link_changed(shi->spec) || ma->spec != 0.0f) 01343 GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined); 01344 } 01345 01346 GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined); 01347 01348 if(ma->shade_flag & MA_OBCOLOR) 01349 GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); 01350 01351 if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) { 01352 misttype = world->mistype; 01353 01354 GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION), 01355 GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist), 01356 GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac); 01357 01358 GPU_link(mat, "mix_blend", mistfac, shr->combined, 01359 GPU_uniform(&world->horr), &shr->combined); 01360 } 01361 01362 if(!((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))) { 01363 if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f)) 01364 GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr), 01365 shr->combined, &shr->combined); 01366 01367 GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined); 01368 } 01369 01370 if(ma->shade_flag & MA_OBCOLOR) { 01371 mat->obcolalpha = 1; 01372 GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined); 01373 } 01374 } 01375 01376 static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma) 01377 { 01378 GPUShadeInput shi; 01379 GPUShadeResult shr; 01380 01381 GPU_shadeinput_set(mat, ma, &shi); 01382 GPU_shaderesult_set(&shi, &shr); 01383 01384 return shr.combined; 01385 } 01386 01387 GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) 01388 { 01389 GPUMaterial *mat; 01390 GPUNodeLink *outlink; 01391 LinkData *link; 01392 01393 for(link=ma->gpumaterial.first; link; link=link->next) 01394 if(((GPUMaterial*)link->data)->scene == scene) 01395 return link->data; 01396 01397 mat = GPU_material_construct_begin(ma); 01398 mat->scene = scene; 01399 01400 if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) { 01401 ntreeGPUMaterialNodes(ma->nodetree, mat); 01402 } 01403 else { 01404 outlink = GPU_blender_material(mat, ma); 01405 GPU_material_output_link(mat, outlink); 01406 } 01407 01408 if(gpu_do_color_management(mat)) 01409 if(mat->outlink) 01410 GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); 01411 01412 /*if(!GPU_material_construct_end(mat)) { 01413 GPU_material_free(mat); 01414 mat= NULL; 01415 return 0; 01416 }*/ 01417 01418 GPU_material_construct_end(mat); 01419 01420 link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink"); 01421 link->data = mat; 01422 BLI_addtail(&ma->gpumaterial, link); 01423 01424 return mat; 01425 } 01426 01427 void GPU_materials_free(void) 01428 { 01429 Object *ob; 01430 Material *ma; 01431 extern Material defmaterial; 01432 01433 for(ma=G.main->mat.first; ma; ma=ma->id.next) 01434 GPU_material_free(ma); 01435 01436 GPU_material_free(&defmaterial); 01437 01438 for(ob=G.main->object.first; ob; ob=ob->id.next) 01439 GPU_lamp_free(ob); 01440 } 01441 01442 /* Lamps and shadow buffers */ 01443 01444 void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]) 01445 { 01446 float mat[4][4]; 01447 01448 lamp->lay = lay; 01449 lamp->hide = hide; 01450 01451 copy_m4_m4(mat, obmat); 01452 normalize_m4(mat); 01453 01454 VECCOPY(lamp->vec, mat[2]); 01455 VECCOPY(lamp->co, mat[3]); 01456 copy_m4_m4(lamp->obmat, mat); 01457 invert_m4_m4(lamp->imat, mat); 01458 } 01459 01460 void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy) 01461 { 01462 lamp->energy = energy; 01463 if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; 01464 01465 lamp->col[0]= r* lamp->energy; 01466 lamp->col[1]= g* lamp->energy; 01467 lamp->col[2]= b* lamp->energy; 01468 } 01469 01470 static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) 01471 { 01472 float temp, angle, pixsize, wsize; 01473 01474 lamp->scene = scene; 01475 lamp->ob = ob; 01476 lamp->par = par; 01477 lamp->la = la; 01478 01479 /* add_render_lamp */ 01480 lamp->mode = la->mode; 01481 lamp->type = la->type; 01482 01483 lamp->energy = la->energy; 01484 if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy; 01485 01486 lamp->col[0]= la->r*lamp->energy; 01487 lamp->col[1]= la->g*lamp->energy; 01488 lamp->col[2]= la->b*lamp->energy; 01489 01490 GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat); 01491 01492 lamp->spotsi= la->spotsize; 01493 if(lamp->mode & LA_HALO) 01494 if(lamp->spotsi > 170.0f) 01495 lamp->spotsi = 170.0f; 01496 lamp->spotsi= cos(M_PI*lamp->spotsi/360.0); 01497 lamp->spotbl= (1.0f - lamp->spotsi)*la->spotblend; 01498 lamp->k= la->k; 01499 01500 lamp->dist= la->dist; 01501 lamp->falloff_type= la->falloff_type; 01502 lamp->att1= la->att1; 01503 lamp->att2= la->att2; 01504 lamp->curfalloff= la->curfalloff; 01505 01506 /* initshadowbuf */ 01507 lamp->bias = 0.02f*la->bias; 01508 lamp->size = la->bufsize; 01509 lamp->d= la->clipsta; 01510 lamp->clipend= la->clipend; 01511 01512 /* arbitrary correction for the fact we do no soft transition */ 01513 lamp->bias *= 0.25f; 01514 01515 /* makeshadowbuf */ 01516 angle= saacos(lamp->spotsi); 01517 temp= 0.5f*lamp->size*cos(angle)/sin(angle); 01518 pixsize= (lamp->d)/temp; 01519 wsize= pixsize*0.5f*lamp->size; 01520 01521 perspective_m4( lamp->winmat,-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend); 01522 } 01523 01524 static void gpu_lamp_shadow_free(GPULamp *lamp) 01525 { 01526 if(lamp->tex) { 01527 GPU_texture_free(lamp->tex); 01528 lamp->tex= NULL; 01529 } 01530 if(lamp->fb) { 01531 GPU_framebuffer_free(lamp->fb); 01532 lamp->fb= NULL; 01533 } 01534 } 01535 01536 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par) 01537 { 01538 Lamp *la; 01539 GPULamp *lamp; 01540 LinkData *link; 01541 01542 for(link=ob->gpulamp.first; link; link=link->next) { 01543 lamp = (GPULamp*)link->data; 01544 01545 if(lamp->par == par && lamp->scene == scene) 01546 return link->data; 01547 } 01548 01549 lamp = MEM_callocN(sizeof(GPULamp), "GPULamp"); 01550 01551 link = MEM_callocN(sizeof(LinkData), "GPULampLink"); 01552 link->data = lamp; 01553 BLI_addtail(&ob->gpulamp, link); 01554 01555 la = ob->data; 01556 gpu_lamp_from_blender(scene, ob, par, la, lamp); 01557 01558 if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) { 01559 /* opengl */ 01560 lamp->fb = GPU_framebuffer_create(); 01561 if(!lamp->fb) { 01562 gpu_lamp_shadow_free(lamp); 01563 return lamp; 01564 } 01565 01566 lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL); 01567 if(!lamp->tex) { 01568 gpu_lamp_shadow_free(lamp); 01569 return lamp; 01570 } 01571 01572 if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) { 01573 gpu_lamp_shadow_free(lamp); 01574 return lamp; 01575 } 01576 01577 GPU_framebuffer_restore(); 01578 } 01579 01580 return lamp; 01581 } 01582 01583 void GPU_lamp_free(Object *ob) 01584 { 01585 GPULamp *lamp; 01586 LinkData *link; 01587 LinkData *nlink; 01588 Material *ma; 01589 01590 for(link=ob->gpulamp.first; link; link=link->next) { 01591 lamp = link->data; 01592 01593 while(lamp->materials.first) { 01594 nlink = lamp->materials.first; 01595 ma = nlink->data; 01596 BLI_freelinkN(&lamp->materials, nlink); 01597 01598 if(ma->gpumaterial.first) 01599 GPU_material_free(ma); 01600 } 01601 01602 gpu_lamp_shadow_free(lamp); 01603 01604 MEM_freeN(lamp); 01605 } 01606 01607 BLI_freelistN(&ob->gpulamp); 01608 } 01609 01610 int GPU_lamp_has_shadow_buffer(GPULamp *lamp) 01611 { 01612 return (!(lamp->scene->gm.flag & GAME_GLSL_NO_SHADOWS) && 01613 !(lamp->scene->gm.flag & GAME_GLSL_NO_LIGHTS) && 01614 lamp->tex && lamp->fb); 01615 } 01616 01617 void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]) 01618 { 01619 float rangemat[4][4], persmat[4][4]; 01620 01621 /* initshadowbuf */ 01622 invert_m4_m4(lamp->viewmat, lamp->obmat); 01623 normalize_v3(lamp->viewmat[0]); 01624 normalize_v3(lamp->viewmat[1]); 01625 normalize_v3(lamp->viewmat[2]); 01626 01627 /* makeshadowbuf */ 01628 mul_m4_m4m4(persmat, lamp->viewmat, lamp->winmat); 01629 01630 /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */ 01631 unit_m4(rangemat); 01632 rangemat[0][0] = 0.5f; 01633 rangemat[1][1] = 0.5f; 01634 rangemat[2][2] = 0.5f; 01635 rangemat[3][0] = 0.5f; 01636 rangemat[3][1] = 0.5f; 01637 rangemat[3][2] = 0.5f; 01638 01639 mul_m4_m4m4(lamp->persmat, persmat, rangemat); 01640 01641 /* opengl */ 01642 glDisable(GL_SCISSOR_TEST); 01643 GPU_framebuffer_texture_bind(lamp->fb, lamp->tex); 01644 01645 /* set matrices */ 01646 copy_m4_m4(viewmat, lamp->viewmat); 01647 copy_m4_m4(winmat, lamp->winmat); 01648 *winsize = lamp->size; 01649 } 01650 01651 void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp) 01652 { 01653 GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex); 01654 GPU_framebuffer_restore(); 01655 glEnable(GL_SCISSOR_TEST); 01656 } 01657 01658 int GPU_lamp_shadow_layer(GPULamp *lamp) 01659 { 01660 if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW))) 01661 return lamp->lay; 01662 else 01663 return -1; 01664 } 01665