diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_draw.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 130 |
1 files changed, 66 insertions, 64 deletions
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index d14070a4c24..e1ca64388ae 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -35,6 +35,7 @@ #include "GL/glew.h" #include "BLI_math.h" +#include "BLI_utildefines.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -58,7 +59,7 @@ #include "BKE_material.h" #include "BKE_node.h" #include "BKE_object.h" -#include "BKE_utildefines.h" + #include "BLI_threads.h" #include "BLI_blenlib.h" @@ -307,7 +308,7 @@ static void gpu_make_repbind(Image *ima) ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind"); } -static void gpu_clear_tpage() +static void gpu_clear_tpage(void) { if(GTS.lasttface==0) return; @@ -394,7 +395,7 @@ static void gpu_verify_reflection(Image *ima) } } -int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int tfmode, int compare, int mipmap) +int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int mipmap) { ImBuf *ibuf = NULL; unsigned int *bind = NULL; @@ -593,7 +594,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap) gpu_verify_alpha_mode(tface); gpu_verify_reflection(ima); - if(GPU_verify_image(ima, NULL, tface->tile, tface->mode, 1, mipmap)) { + if(GPU_verify_image(ima, NULL, tface->tile, 1, mipmap)) { GTS.curtile= GTS.tile; GTS.curima= GTS.ima; GTS.curtilemode= GTS.tilemode; @@ -775,9 +776,9 @@ void GPU_free_smoke(SmokeModifierData *smd) void GPU_create_smoke(SmokeModifierData *smd, int highres) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && !highres) + if(smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && !highres) smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid)); - else if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex && highres) + else if(smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && highres) smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt)); smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow); @@ -810,7 +811,8 @@ void GPU_free_unused_buffers(void) BLI_freelistN(&image_free_queue); /* vbo buffers */ - GPU_buffer_pool_free_unused(0); + /* it's probably not necessary to free all buffers every frame */ + /* GPU_buffer_pool_free_unused(0); */ BLI_unlock_thread(LOCK_OPENGL); } @@ -871,9 +873,15 @@ void GPU_free_images_anim(void) /* OpenGL state caching for materials */ +typedef struct GPUMaterialFixed { + float diff[4]; + float spec[4]; + int hard; +} GPUMaterialFixed; + static struct GPUMaterialState { - float (*matbuf)[2][4]; - float matbuf_fixed[FIXEDMAT][2][4]; + GPUMaterialFixed (*matbuf); + GPUMaterialFixed matbuf_fixed[FIXEDMAT]; int totmat; Material **gmatbuf; @@ -893,7 +901,36 @@ static struct GPUMaterialState { GPUBlendMode lastblendmode; } GMS = {NULL}; -Material *gpu_active_node_material(Material *ma) +/* fixed function material, alpha handed by caller */ +static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob) +{ + if (bmat->mode & MA_SHLESS) { + copy_v3_v3(smat->diff, &bmat->r); + smat->diff[3]= 1.0; + + if(gamma) { + linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); + } + } + else { + mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); + smat->diff[3]= 1.0; /* caller may set this to bmat->alpha */ + + if(bmat->shade_flag & MA_OBCOLOR) + mul_v3_v3(smat->diff, ob->col); + + mul_v3_v3fl(smat->spec, &bmat->specr, bmat->spec); + smat->spec[3]= 1.0; /* always 1 */ + smat->hard= CLAMPIS(bmat->har, 0, 128); + + if(gamma) { + linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); + linearrgb_to_srgb_v3_v3(smat->spec, smat->spec); + } + } +} + +static Material *gpu_active_node_material(Material *ma) { if(ma && ma->use_nodes && ma->nodetree) { bNode *node= nodeGetActiveID(ma->nodetree, ID_MA); @@ -934,7 +971,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O *do_alpha_pass = 0; if(GMS.totmat > FIXEDMAT) { - GMS.matbuf= MEM_callocN(sizeof(*GMS.matbuf)*GMS.totmat, "GMS.matbuf"); + GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf"); GMS.gmatbuf= MEM_callocN(sizeof(*GMS.gmatbuf)*GMS.totmat, "GMS.matbuf"); GMS.blendmode= MEM_callocN(sizeof(*GMS.blendmode)*GMS.totmat, "GMS.matbuf"); } @@ -946,19 +983,10 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O /* no materials assigned? */ if(ob->totcol==0) { - GMS.matbuf[0][0][0]= (defmaterial.ref+defmaterial.emit)*defmaterial.r; - GMS.matbuf[0][0][1]= (defmaterial.ref+defmaterial.emit)*defmaterial.g; - GMS.matbuf[0][0][2]= (defmaterial.ref+defmaterial.emit)*defmaterial.b; - GMS.matbuf[0][0][3]= 1.0; - - GMS.matbuf[0][1][0]= defmaterial.spec*defmaterial.specr; - GMS.matbuf[0][1][1]= defmaterial.spec*defmaterial.specg; - GMS.matbuf[0][1][2]= defmaterial.spec*defmaterial.specb; - GMS.matbuf[0][1][3]= 1.0; - + gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob); + /* do material 1 too, for displists! */ - QUATCOPY(GMS.matbuf[1][0], GMS.matbuf[0][0]); - QUATCOPY(GMS.matbuf[1][1], GMS.matbuf[0][1]); + memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); if(glsl) { GMS.gmatbuf[0]= &defmaterial; @@ -985,32 +1013,13 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O } else { /* fixed function opengl materials */ - if (ma->mode & MA_SHLESS) { - GMS.matbuf[a][0][0]= ma->r; - GMS.matbuf[a][0][1]= ma->g; - GMS.matbuf[a][0][2]= ma->b; - if(gamma) linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]); - } else { - GMS.matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r; - GMS.matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g; - GMS.matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b; - - GMS.matbuf[a][1][0]= ma->spec*ma->specr; - GMS.matbuf[a][1][1]= ma->spec*ma->specg; - GMS.matbuf[a][1][2]= ma->spec*ma->specb; - GMS.matbuf[a][1][3]= 1.0; - - if(gamma) { - linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]); - linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][1][0], &GMS.matbuf[a][1][0]); - } - } + gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob); blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; if(do_alpha_pass && GMS.alphapass) - GMS.matbuf[a][0][3]= ma->alpha; + GMS.matbuf[a].diff[3]= ma->alpha; else - GMS.matbuf[a][0][3]= 1.0f; + GMS.matbuf[a].diff[3]= 1.0f; } /* setting do_alpha_pass = 1 indicates this object needs to be @@ -1039,18 +1048,15 @@ int GPU_enable_material(int nr, void *attribs) memset(&GMS, 0, sizeof(GMS)); - diff[0]= (defmaterial.ref+defmaterial.emit)*defmaterial.r; - diff[1]= (defmaterial.ref+defmaterial.emit)*defmaterial.g; - diff[2]= (defmaterial.ref+defmaterial.emit)*defmaterial.b; + mul_v3_v3fl(diff, &defmaterial.r, defmaterial.ref + defmaterial.emit); diff[3]= 1.0; - spec[0]= defmaterial.spec*defmaterial.specr; - spec[1]= defmaterial.spec*defmaterial.specg; - spec[2]= defmaterial.spec*defmaterial.specb; + mul_v3_v3fl(spec, &defmaterial.specr, defmaterial.spec); spec[3]= 1.0; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 35); /* blender default */ return 0; } @@ -1094,8 +1100,9 @@ int GPU_enable_material(int nr, void *attribs) } else { /* or do fixed function opengl material */ - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr][0]); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr][1]); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr].diff); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr].spec); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, GMS.matbuf[nr].hard); } /* set (alpha) blending mode */ @@ -1257,14 +1264,14 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4 if(la->type==LA_SUN) { /* sun lamp */ - VECCOPY(direction, base->object->obmat[2]); + copy_v3_v3(direction, base->object->obmat[2]); direction[3]= 0.0; glLightfv(GL_LIGHT0+count, GL_POSITION, direction); } else { /* other lamps with attenuation */ - VECCOPY(position, base->object->obmat[3]); + copy_v3_v3(position, base->object->obmat[3]); position[3]= 1.0f; glLightfv(GL_LIGHT0+count, GL_POSITION, position); @@ -1274,9 +1281,7 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4 if(la->type==LA_SPOT) { /* spot lamp */ - direction[0]= -base->object->obmat[2][0]; - direction[1]= -base->object->obmat[2][1]; - direction[2]= -base->object->obmat[2][2]; + negate_v3_v3(direction, base->object->obmat[2]); glLightfv(GL_LIGHT0+count, GL_SPOT_DIRECTION, direction); glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, la->spotsize/2.0); glLightf(GL_LIGHT0+count, GL_SPOT_EXPONENT, 128.0*la->spotblend); @@ -1288,9 +1293,7 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4 power= (ELEM(la->type, LA_SUN, LA_HEMI))? la->energy*M_PI: la->energy*M_PI; //XXX la->power /* setup energy */ - energy[0]= power*la->r; - energy[1]= power*la->g; - energy[2]= power*la->b; + mul_v3_v3fl(energy, &la->r, la->energy); energy[3]= 1.0; glLightfv(GL_LIGHT0+count, GL_DIFFUSE, energy); @@ -1314,7 +1317,6 @@ void GPU_state_init(void) /* also called when doing opengl rendering and in the game engine */ float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 }; float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 }; - float mat_shininess[] = { 35.0 }; int a, x, y; GLubyte pat[32*32]; const GLubyte *patc= pat; @@ -1322,7 +1324,7 @@ void GPU_state_init(void) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 35); GPU_default_lights(); |