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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user