diff options
Diffstat (limited to 'source/blender/src/drawview.c')
-rw-r--r-- | source/blender/src/drawview.c | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 79c94124499..4871562e1e5 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -2928,67 +2928,83 @@ void draw_depth(ScrArea *sa, void *spacedata, int (* func)(void *)) static void draw_viewport_fps(ScrArea *sa); -static void gpu_render_lamp_update(View3D *v3d, Object *ob) -{ - Lamp *la; - float viewmat[4][4], winmat[4][4]; - int drawtype, lay, winsize, flag2; - - la= ob->data; - GPU_lamp_from_blender(ob, la); +typedef struct View3DShadow{ + struct View3DShadow*next, *prev; + GPULamp *lamp; +} View3DShadow; - if(ob->gpulamp) { - GPU_lamp_update(ob->gpulamp, ob->obmat); - - if(GPU_lamp_has_shadow_buffer(ob->gpulamp)) { - /* this needs to be done better .. */ - drawtype= v3d->drawtype; - lay= v3d->lay; - flag2= v3d->flag2 & V3D_SOLID_TEX; +static void gpu_render_lamp_update(View3D *v3d, Object *ob, Object *par, float obmat[][4], ListBase *shadows) +{ + GPULamp *lamp; + View3DShadow *shadow; - v3d->drawtype = OB_SOLID; - v3d->lay &= GPU_lamp_shadow_layer(ob->gpulamp); - v3d->flag2 &= ~V3D_SOLID_TEX; + lamp = GPU_lamp_from_blender(ob, par); - GPU_lamp_shadow_buffer_bind(ob->gpulamp, viewmat, &winsize, winmat); - drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1); - GPU_lamp_shadow_buffer_unbind(ob->gpulamp); + if(lamp) { + GPU_lamp_update(lamp, obmat); - v3d->drawtype= drawtype; - v3d->lay= lay; - v3d->flag2 |= flag2; + if(GPU_lamp_has_shadow_buffer(lamp)) { + shadow= MEM_callocN(sizeof(View3DShadow), "View3DShadow"); + shadow->lamp = lamp; + BLI_addtail(shadows, shadow); } } } -static void gpu_render_shadow_buffers(Scene *scene, View3D *v3d) +static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) { + ListBase shadows; + View3DShadow *shadow; Scene *sce; Base *base; Object *ob; + shadows.first= shadows.last= NULL; + + /* update lamp transform and gather shadow lamps */ for(SETLOOPER(G.scene, base)) { ob= base->object; if(ob->type == OB_LAMP) - gpu_render_lamp_update(v3d, ob); + gpu_render_lamp_update(v3d, ob, NULL, ob->obmat, &shadows); if (ob->transflag & OB_DUPLI) { DupliObject *dob; ListBase *lb = object_duplilist(G.scene, ob); - for(dob=lb->first; dob; dob=dob->next) { - Object *ob = dob->ob; - - if(ob->type==OB_LAMP) { - Mat4CpyMat4(ob->obmat, dob->mat); - gpu_render_lamp_update(v3d, ob); - } - } + for(dob=lb->first; dob; dob=dob->next) + if(dob->ob->type==OB_LAMP) + gpu_render_lamp_update(v3d, dob->ob, ob, dob->mat, &shadows); free_object_duplilist(lb); } } + + /* render shadows after updating all lamps, nested object_duplilist + * don't work correct since it's replacing object matrices */ + for(shadow=shadows.first; shadow; shadow=shadow->next) { + /* this needs to be done better .. */ + float viewmat[4][4], winmat[4][4]; + int drawtype, lay, winsize, flag2; + + drawtype= v3d->drawtype; + lay= v3d->lay; + flag2= v3d->flag2 & V3D_SOLID_TEX; + + v3d->drawtype = OB_SOLID; + v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp); + v3d->flag2 &= ~V3D_SOLID_TEX; + + GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); + drawview3d_render(v3d, viewmat, winsize, winsize, winmat, 1); + GPU_lamp_shadow_buffer_unbind(shadow->lamp); + + v3d->drawtype= drawtype; + v3d->lay= lay; + v3d->flag2 |= flag2; + } + + BLI_freelistN(&shadows); } void drawview3dspace(ScrArea *sa, void *spacedata) @@ -3016,7 +3032,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) /* shadow buffers, before we setup matrices */ if(draw_glsl_material(NULL, v3d->drawtype)) - gpu_render_shadow_buffers(G.scene, v3d); + gpu_update_lamps_shadows(G.scene, v3d); setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */ setviewmatrixview3d(); /* note: calls where_is_object for camera... */ @@ -3295,7 +3311,7 @@ void drawview3d_render(struct View3D *v3d, float viewmat[][4], int winx, int win /* shadow buffers, before we setup matrices */ if(!shadow && draw_glsl_material(NULL, v3d->drawtype)) - gpu_render_shadow_buffers(G.scene, v3d); + gpu_update_lamps_shadows(G.scene, v3d); if(!winmat) setwinmatrixview3d(winx, winy, NULL); |