diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index f23e587e55d..3fb2761d40e 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -100,6 +100,7 @@ #include "GPU_material.h" #include "GPU_compositing.h" #include "GPU_extensions.h" +#include "GPU_select.h" #include "view3d_intern.h" /* own include */ @@ -2023,6 +2024,35 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const glDepthMask(GL_TRUE); } +/* clears zbuffer and draws it over, + * note that in the select version we don't care about transparent flag as with regular drawing */ +static void view3d_draw_xray_select(Scene *scene, ARegion *ar, View3D *v3d, bool *clear) +{ + /* Not ideal, but we need to read from the previous depths before clearing + * otherwise we could have a function to load the depths after drawing. + * + * Clearing the depth buffer isn't all that common between drawing objects so accept this for now. + */ + if (U.gpu_select_pick_deph) { + GPU_select_load_id(-1); + } + + View3DAfter *v3da; + if (*clear && v3d->zbuf) { + glClear(GL_DEPTH_BUFFER_BIT); + *clear = false; + } + + v3d->xray = true; + while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { + if (GPU_select_load_id(v3da->base->selcol)) { + draw_object_select(scene, ar, v3d, v3da->base, v3da->dflag); + } + MEM_freeN(v3da); + } + v3d->xray = false; +} + /* *********************** */ /* @@ -2487,6 +2517,58 @@ void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaover U.obcenter_dia = obcenter_dia; } +void ED_view3d_draw_select_loop( + ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, + bool use_obedit_skip, bool use_nearest) +{ + short code = 1; + const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR; + + if (vc->obedit && vc->obedit->type == OB_MBALL) { + draw_object(scene, ar, v3d, BASACT, dflag); + } + else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) { + /* if not drawing sketch, draw bones */ + if (!BDR_drawSketchNames(vc)) { + draw_object(scene, ar, v3d, BASACT, dflag); + } + } + else { + Base *base; + + for (base = scene->base.first; base; base = base->next) { + if (base->lay & v3d->lay) { + + if ((base->object->restrictflag & OB_RESTRICT_SELECT) || + (use_obedit_skip && (scene->obedit->data == base->object->data))) + { + base->selcol = 0; + } + else { + base->selcol = code; + + if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) { + ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); + } + else { + if (GPU_select_load_id(code)) { + draw_object_select(scene, ar, v3d, base, dflag); + } + } + code++; + } + } + } + + if (use_nearest) { + bool xrayclear = true; + if (v3d->afterdraw_xray.first) { + view3d_draw_xray_select(scene, ar, v3d, &xrayclear); + } + } + } +} + typedef struct View3DShadow { struct View3DShadow *next, *prev; GPULamp *lamp; @@ -2955,7 +3037,7 @@ struct RV3DMatrixStore { float pixsize; }; -void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) +struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) { struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__); copy_m4_m4(rv3dmat->winmat, rv3d->winmat); @@ -2968,9 +3050,8 @@ void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) return (void *)rv3dmat; } -void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt) +void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat) { - struct RV3DMatrixStore *rv3dmat = rv3dmat_pt; copy_m4_m4(rv3d->winmat, rv3dmat->winmat); copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat); copy_m4_m4(rv3d->persmat, rv3dmat->persmat); |