diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-08-25 18:23:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-08-25 18:23:02 +0400 |
commit | 7d0e4ac889af1fcd35f0398651d7fbcf67eaf32c (patch) | |
tree | 11e7a9d54d348c06f29d1e1e7f3612d9f4e2b4fc /source/blender | |
parent | 967154497dea50b75771b5ae3df630d8f739ac13 (diff) |
simplify pass drawing, give each pass its own list, avoids some context switching.
- also fixes a problem where xray+transp+alpha1.0 objects wouldnt draw at all.
- the patch worked by adding twice but this leaked memory.
- solve by adding the xraytransp object to the xray list if the alpha is 1.0
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 26 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 160 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 4 |
6 files changed, 116 insertions, 81 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c37585faed9..cbc4c8890a6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5079,7 +5079,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc) direct_link_gpencil(fd, v3d->gpd); } v3d->localvd= newdataadr(fd, v3d->localvd); - v3d->afterdraw.first= v3d->afterdraw.last= NULL; + v3d->afterdraw_transp.first= v3d->afterdraw_transp.last= NULL; + v3d->afterdraw_xray.first= v3d->afterdraw_xray.last= NULL; + v3d->afterdraw_xraytransp.first= v3d->afterdraw_xraytransp.last= NULL; v3d->properties_storage= NULL; view3d_split_250(v3d, &sl->regionbase); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index df3bc3d479d..d3162c44463 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -901,7 +901,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if(drawcone && !v3d->transp) { /* in this case we need to draw delayed */ - add_view3d_after(v3d, base, V3D_TRANSP, flag); + add_view3d_after(&v3d->afterdraw_transp, base, flag); return; } @@ -2769,7 +2769,20 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } /* GPU_begin_object_materials checked if this is needed */ - if(do_alpha_pass) add_view3d_after(v3d, base, V3D_TRANSP, flag); + if(do_alpha_pass) { + if(ob->dtx & OB_DRAWXRAY) { + add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); + } + else { + add_view3d_after(&v3d->afterdraw_transp, base, flag); + } + } + else if(ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { + /* special case xray+transp when alpha is 1.0, without this the object vanishes */ + if(v3d->xray == 0 && v3d->transp == 0) { + add_view3d_after(&v3d->afterdraw_xray, base, flag); + } + } return retval; } @@ -5537,13 +5550,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* don't do xray in particle mode, need the z-buffer */ if(!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ - if(!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY)) { - if(ob->dtx & OB_DRAWTRANSP) { - add_view3d_after(v3d, base, V3D_XRAYTRANSP, flag); - } - else { - add_view3d_after(v3d, base, V3D_XRAY, flag); - } + if(!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { + add_view3d_after(&v3d->afterdraw_xray, base, flag); return; } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index ac845ec7ea3..c49f4f48e10 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -270,7 +270,6 @@ static void view3d_free(SpaceLink *sl) if(vd->localvd) MEM_freeN(vd->localvd); if(vd->properties_storage) MEM_freeN(vd->properties_storage); - } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index db6127210f7..5f88a1b8b62 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1419,52 +1419,18 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) typedef struct View3DAfter { struct View3DAfter *next, *prev; struct Base *base; - int type, flag; + int flag; } View3DAfter; /* temp storage of Objects that need to be drawn as last */ -void add_view3d_after(View3D *v3d, Base *base, int type, int flag) +void add_view3d_after(ListBase *lb, Base *base, int flag) { View3DAfter *v3da= MEM_callocN(sizeof(View3DAfter), "View 3d after"); - - BLI_addtail(&v3d->afterdraw, v3da); + BLI_addtail(lb, v3da); v3da->base= base; - v3da->type= type; v3da->flag= flag; } -/* clears zbuffer and draws it over */ -static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) -{ - View3DAfter *v3da, *next; - int doit= 0; - - for(v3da= v3d->afterdraw.first; v3da; v3da= v3da->next) - if(v3da->type==V3D_XRAY || v3da->type==V3D_XRAYTRANSP) doit= 1; - - if(doit) { - if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); - v3d->xray= TRUE; - - for(v3da= v3d->afterdraw.first; v3da; v3da= next) { - next= v3da->next; - if(v3da->type==V3D_XRAY) { - draw_object(scene, ar, v3d, v3da->base, v3da->flag); - BLI_remlink(&v3d->afterdraw, v3da); - MEM_freeN(v3da); - } - else if(v3da->type==V3D_XRAYTRANSP){ - v3d->transp= TRUE; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); - BLI_remlink(&v3d->afterdraw, v3da); - MEM_freeN(v3da); - v3d->transp= FALSE; - } - } - v3d->xray= FALSE; - } -} - /* disables write in zbuffer and draws it over */ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) { @@ -1473,13 +1439,11 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) glDepthMask(0); v3d->transp= TRUE; - for(v3da= v3d->afterdraw.first; v3da; v3da= next) { + for(v3da= v3d->afterdraw_transp.first; v3da; v3da= next) { next= v3da->next; - if(v3da->type==V3D_TRANSP) { - draw_object(scene, ar, v3d, v3da->base, v3da->flag); - BLI_remlink(&v3d->afterdraw, v3da); - MEM_freeN(v3da); - } + draw_object(scene, ar, v3d, v3da->base, v3da->flag); + BLI_remlink(&v3d->afterdraw_transp, v3da); + MEM_freeN(v3da); } v3d->transp= FALSE; @@ -1487,6 +1451,48 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) } +/* clears zbuffer and draws it over */ +static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) +{ + View3DAfter *v3da, *next; + + if(clear && v3d->zbuf) + glClear(GL_DEPTH_BUFFER_BIT); + + v3d->xray= TRUE; + for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, v3da->flag); + BLI_remlink(&v3d->afterdraw_xray, v3da); + MEM_freeN(v3da); + } + v3d->xray= FALSE; +} + + +/* clears zbuffer and draws it over */ +static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int clear) +{ + View3DAfter *v3da, *next; + + if(clear && v3d->zbuf) + glClear(GL_DEPTH_BUFFER_BIT); + + v3d->xray= TRUE; + v3d->transp= TRUE; + + for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, v3da->flag); + BLI_remlink(&v3d->afterdraw_xraytransp, v3da); + MEM_freeN(v3da); + } + + v3d->transp= FALSE; + v3d->xray= FALSE; + +} + /* *********************** */ /* @@ -1747,41 +1753,57 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) } /* this isnt that nice, draw xray objects as if they are normal */ - if (v3d->afterdraw.first) { + if ( v3d->afterdraw_transp.first || + v3d->afterdraw_xray.first || + v3d->afterdraw_xraytransp.first + ) { View3DAfter *v3da, *next; - int num = 0; int mask_orig; + v3d->xray= TRUE; /* transp materials can change the depth mask, see #21388 */ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); - glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ - for(v3da= v3d->afterdraw.first; v3da; v3da= next) { - next= v3da->next; - if(v3da->type==V3D_XRAY) { + + if(v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { + glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ + for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { + next= v3da->next; draw_object(scene, ar, v3d, v3da->base, 0); - num++; } - /* dont remove this time */ + glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ } + + /* draw 3 passes, transp/xray/xraytransp */ v3d->xray= FALSE; - - glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ - for(v3da= v3d->afterdraw.first; v3da; v3da= next) { + v3d->transp= TRUE; + for(v3da= v3d->afterdraw_transp.first; v3da; v3da= next) { next= v3da->next; - if(v3da->type==V3D_XRAY) { - v3d->xray= TRUE; v3d->transp= FALSE; - } else if (v3da->type==V3D_TRANSP) { - v3d->xray= FALSE; v3d->transp= TRUE; - } else if (v3da->type == V3D_XRAYTRANSP) { - v3d->xray= TRUE; v3d->transp= TRUE; - } - - draw_object(scene, ar, v3d, v3da->base, 0); /* Draw Xray or Transp objects normally */ - BLI_remlink(&v3d->afterdraw, v3da); + draw_object(scene, ar, v3d, v3da->base, 0); + BLI_remlink(&v3d->afterdraw_transp, v3da); + MEM_freeN(v3da); + } + + v3d->xray= TRUE; + v3d->transp= FALSE; + for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, 0); + BLI_remlink(&v3d->afterdraw_xray, v3da); + MEM_freeN(v3da); + } + + v3d->xray= TRUE; + v3d->transp= TRUE; + for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, 0); + BLI_remlink(&v3d->afterdraw_xraytransp, v3da); MEM_freeN(v3da); } + + v3d->xray= FALSE; v3d->transp= FALSE; @@ -2059,8 +2081,9 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, } /* transp and X-ray afterdraw stuff */ - view3d_draw_transp(scene, ar, v3d); - view3d_draw_xray(scene, ar, v3d, 1); // clears zbuffer if it is used! + if(v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); + if(v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); // clears zbuffer if it is used! + if(v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); /* cleanup */ if(v3d->zbuf) { @@ -2378,8 +2401,9 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) // REEB_draw(); /* Transp and X-ray afterdraw stuff */ - view3d_draw_transp(scene, ar, v3d); - view3d_draw_xray(scene, ar, v3d, 1); // clears zbuffer if it is used! + if(v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); + if(v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, 1); // clears zbuffer if it is used! + if(v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5042411183f..7a45a43ddd4 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -126,7 +126,7 @@ void draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, int (* func)(void void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); void view3d_clr_clipping(void); void view3d_set_clipping(RegionView3D *rv3d); -void add_view3d_after(View3D *v3d, Base *base, int type, int flag); +void add_view3d_after(ListBase *lb, Base *base, int flag); void circf(float x, float y, float rad); void circ(float x, float y, float rad); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index c5516a3bff5..520fc56162c 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -185,7 +185,9 @@ typedef struct View3D { unsigned int customdata_mask; /* afterdraw, for xray & transparent */ - struct ListBase afterdraw; + struct ListBase afterdraw_transp; + struct ListBase afterdraw_xray; + struct ListBase afterdraw_xraytransp; /* drawflags, denoting state */ short zbuf, transp, xray; |