diff options
author | mano-wii <germano.costa@ig.com.br> | 2019-03-15 22:02:55 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2019-03-15 23:02:48 +0300 |
commit | 681661dbed121c7b81e9129c57df5eadb03c1009 (patch) | |
tree | 8802195c72af13e1bb7324131024cc98fb5971a7 /source/blender/editors | |
parent | 4510f88d00a721a3d4ad3aa675050723eec2292c (diff) |
GPU: Simplify select shaders.
The shaders are: `GPU_SHADER_3D_FLAT_SELECT_ID` and `GPU_SHADER_3D_UNIFORM_SELECT_ID`.
This commit allows the drawing of the mesh select ids to be done on a 32UI format texture.
This simplifies the shader that previously acted on the backbuffer and had to do an uint to rgba conversion.
Differential Revision: https://developer.blender.org/D4350
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 12 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 26 | ||||
-rw-r--r-- | source/blender/editors/mesh/editface.c | 30 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 67 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 29 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_utils.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 50 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw_legacy.c | 255 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 32 |
13 files changed, 257 insertions, 271 deletions
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 7318df8adab..e8c5e0dd789 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -237,7 +237,7 @@ void EDBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEd /* editface.c */ void paintface_flush_flags(struct bContext *C, struct Object *ob, short flag); bool paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], bool extend, bool deselect, bool toggle); -int do_paintface_box_select(struct ViewContext *vc, struct rcti *rect, int sel_op); +int do_paintface_box_select(struct ViewContext *vc, const struct rcti *rect, int sel_op); void paintface_deselect_all_visible(struct bContext *C, struct Object *ob, int action, bool flush_flags); void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], const bool select); bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]); @@ -365,9 +365,9 @@ int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct Me int ED_mesh_mirror_get_vert(struct Object *ob, int index); -bool ED_mesh_pick_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size, bool use_zbuf); -bool ED_mesh_pick_face(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size); -bool ED_mesh_pick_face_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size); +bool ED_mesh_pick_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int dist_px, bool use_zbuf); +bool ED_mesh_pick_face(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int dist_px); +bool ED_mesh_pick_face_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int dist_px); struct MDeformVert *ED_mesh_active_dvert_get_em(struct Object *ob, struct BMVert **r_eve); @@ -377,8 +377,8 @@ struct MDeformVert *ED_mesh_active_dvert_get_only(struct Object *ob); void EDBM_mesh_stats_multi(struct Object **objects, const uint objects_len, int totelem[3], int totelem_sel[3]); void EDBM_mesh_elem_index_ensure_multi(struct Object **objects, const uint objects_len, const char htype); -#define ED_MESH_PICK_DEFAULT_VERT_SIZE 50 -#define ED_MESH_PICK_DEFAULT_FACE_SIZE 3 +#define ED_MESH_PICK_DEFAULT_VERT_DIST 25 +#define ED_MESH_PICK_DEFAULT_FACE_DIST 1 #define USE_LOOPSLIDE_HACK diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 131069bfb5f..e8cd6ebf5f3 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -348,16 +348,24 @@ float ED_view3d_radius_to_dist( void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos); /* backbuffer select and draw support */ -void ED_view3d_backbuf_validate_with_select_mode(struct ViewContext *vc, short select_mode); -void ED_view3d_backbuf_validate(struct ViewContext *vc); -struct ImBuf *ED_view3d_backbuf_read( - struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax); -unsigned int ED_view3d_backbuf_sample_rect( - struct ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, float *r_dist); -int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist); -unsigned int ED_view3d_backbuf_sample( +void ED_view3d_backbuf_depth_validate(struct ViewContext *vc); +int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist); + +void ED_view3d_select_id_validate(struct ViewContext *vc); +void ED_view3d_select_id_validate_with_select_mode( + struct ViewContext *vc, short select_mode); + +uint ED_view3d_select_id_sample( struct ViewContext *vc, int x, int y); +uint *ED_view3d_select_id_read( + struct ViewContext *vc, + int xmin, int ymin, int xmax, int ymax, + uint *r_buf_len); +uint *ED_view3d_select_id_read_rect( + struct ViewContext *vc, const struct rcti *rect, uint *r_buf_len); +uint ED_view3d_select_id_read_nearest( + struct ViewContext *vc, const int mval[2], + const uint min, const uint max, uint *r_dist); bool ED_view3d_autodist( struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d, diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 5afde1b3ba1..e226985300c 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -272,7 +272,7 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b if (me == NULL || me->totpoly == 0) return; if (mval) { - if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_DIST)) { return; } } @@ -374,7 +374,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b /* Get the face under the cursor */ me = BKE_mesh_from_object(ob); - if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) + if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_DIST)) return false; if (index >= me->totpoly) @@ -418,22 +418,17 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b return true; } -int do_paintface_box_select(ViewContext *vc, rcti *rect, int sel_op) +int do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op) { Object *ob = vc->obact; Mesh *me; MPoly *mpoly; - struct ImBuf *ibuf; - unsigned int *rt; + uint *rt; char *selar; int a, index; - const int size[2] = { - BLI_rcti_size_x(rect) + 1, - BLI_rcti_size_y(rect) + 1}; me = BKE_mesh_from_object(ob); - - if ((me == NULL) || (me->totpoly == 0) || (size[0] * size[1] <= 0)) { + if ((me == NULL) || (me->totpoly == 0) || BLI_rcti_is_empty(rect)) { return OPERATOR_CANCELLED; } @@ -443,17 +438,12 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int sel_op) paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false); } - ED_view3d_backbuf_validate(vc); + uint buf_len; + uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len); - ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); - rt = ibuf->rect; - view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - if (ENDIAN_ORDER == B_ENDIAN) { - IMB_convert_rgba_to_abgr(ibuf); - } - GPU_select_to_index_array(ibuf->rect, size[0] * size[1]); + rt = buf; - a = size[0] * size[1]; + a = buf_len; while (a--) { if (*rt) { index = *rt; @@ -476,7 +466,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int sel_op) } } - IMB_freeImBuf(ibuf); + MEM_freeN(buf); MEM_freeN(selar); #ifdef __APPLE__ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 80d23f37e71..991e0f94383 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -213,32 +213,29 @@ bool EDBM_backbuf_border_init( ViewContext *vc, short xmin, short ymin, short xmax, short ymax) { - struct ImBuf *buf; - unsigned int *dr; - int a; + uint *buf, *dr, buf_len; if (vc->obedit == NULL || !V3D_IS_ZBUF(vc->v3d)) { return false; } - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } - dr = buf->rect; + dr = buf; /* build selection lookup */ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); - a = (xmax - xmin + 1) * (ymax - ymin + 1); - while (a--) { + while (buf_len--) { if (*dr > 0 && *dr <= bm_vertoffs) { BLI_BITMAP_ENABLE(selbuf, *dr); } dr++; } - IMB_freeImBuf(buf); + MEM_freeN(buf); return true; } @@ -286,9 +283,7 @@ static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data) */ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { - unsigned int *dr, *dr_mask, *dr_mask_arr; - struct ImBuf *buf; - int a; + uint *buf, *dr, *dr_mask, *dr_mask_arr, buf_len; struct LassoMaskData lasso_mask_data; /* method in use for face selecting too */ @@ -301,14 +296,14 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short return false; } - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } - dr = buf->rect; + dr = buf; - dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf->x * buf->y, __func__); + dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf_len, __func__); lasso_mask_data.px = dr_mask; lasso_mask_data.width = (xmax - xmin) + 1; @@ -320,14 +315,13 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short /* build selection lookup */ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); - a = (xmax - xmin + 1) * (ymax - ymin + 1); - while (a--) { + while (buf_len--) { if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) { BLI_BITMAP_ENABLE(selbuf, *dr); } dr++; dr_mask++; } - IMB_freeImBuf(buf); + MEM_freeN(buf); MEM_freeN(dr_mask_arr); return true; @@ -338,8 +332,7 @@ bool EDBM_backbuf_circle_init( ViewContext *vc, short xs, short ys, short rads) { - struct ImBuf *buf; - unsigned int *dr; + uint *buf, *dr; short xmin, ymin, xmax, ymax, xc, yc; int radsq; @@ -355,12 +348,12 @@ bool EDBM_backbuf_circle_init( xmin = xs - rads; xmax = xs + rads; ymin = ys - rads; ymax = ys + rads; - buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); + buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL); if ((buf == NULL) || (bm_vertoffs == 0)) { return false; } - dr = buf->rect; + dr = buf; /* build selection lookup */ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); @@ -375,7 +368,7 @@ bool EDBM_backbuf_circle_init( } } - IMB_freeImBuf(buf); + MEM_freeN(buf); return true; } @@ -472,26 +465,24 @@ BMVert *EDBM_vert_find_nearest_ex( BMesh *bm = vc->em->bm; if (V3D_IS_ZBUF(vc->v3d)) { - const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); - float dist_test; + uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); unsigned int index; BMVert *eve; /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX); - ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); + ED_view3d_select_id_validate_with_select_mode(vc, select_mode); - index = ED_view3d_backbuf_sample_rect( - vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test); + index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_wireoffs, 0xFFFFFF, &dist_px); eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL; FAKE_SELECT_MODE_END(vc, fake_select_mode); } if (eve) { - if (dist_test < *r_dist) { - *r_dist = dist_test; + if (dist_px < *r_dist) { + *r_dist = dist_px; return eve; } } @@ -665,17 +656,16 @@ BMEdge *EDBM_edge_find_nearest_ex( BMesh *bm = vc->em->bm; if (V3D_IS_ZBUF(vc->v3d)) { - const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); - float dist_test = 0.0f; + uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); unsigned int index; BMEdge *eed; /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE); - ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); + ED_view3d_select_id_validate_with_select_mode(vc, select_mode); - index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test); + index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_solidoffs, bm_wireoffs, &dist_px); eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL; FAKE_SELECT_MODE_END(vc, fake_select_mode); @@ -703,8 +693,8 @@ BMEdge *EDBM_edge_find_nearest_ex( /* end exception */ if (eed) { - if (dist_test < *r_dist) { - *r_dist = dist_test; + if (dist_px < *r_dist) { + *r_dist = dist_px; return eed; } } @@ -842,9 +832,9 @@ BMFace *EDBM_face_find_nearest_ex( { FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE); - ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); + ED_view3d_select_id_validate_with_select_mode(vc, select_mode); - index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]); + index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]); efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL; FAKE_SELECT_MODE_END(vc, fake_select_mode); @@ -974,7 +964,6 @@ static bool unified_findnearest( Object *obedit = base_iter->object; ED_view3d_viewcontext_init_object(vc, obedit); BLI_assert(vc->em->selectmode == em->selectmode); - ED_view3d_backbuf_validate(vc); BMFace *efa_zbuf = NULL; BMFace *efa_test = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf); if (efa_test && dist_center_p) { @@ -999,7 +988,6 @@ static bool unified_findnearest( Base *base_iter = bases[base_index]; Object *obedit = base_iter->object; ED_view3d_viewcontext_init_object(vc, obedit); - ED_view3d_backbuf_validate(vc); BMEdge *eed_zbuf = NULL; BMEdge *eed_test = EDBM_edge_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf); if (eed_test && dist_center_p) { @@ -1021,7 +1009,6 @@ static bool unified_findnearest( Base *base_iter = bases[base_index]; Object *obedit = base_iter->object; ED_view3d_viewcontext_init_object(vc, obedit); - ED_view3d_backbuf_validate(vc); BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle); if (eve_test) { hit.v.base_index = base_index; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 2b8535f868b..952690775b7 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1014,7 +1014,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) * * \return boolean true == Found */ -bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) +bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int dist_px) { ViewContext vc; Mesh *me = ob->data; @@ -1026,16 +1026,18 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int ED_view3d_viewcontext_init(C, &vc); - if (size) { + if (dist_px) { /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist); + ED_view3d_select_id_validate(&vc); + + *index = ED_view3d_select_id_read_nearest( + &vc, mval, 1, me->totpoly + 1, &dist_px); } else { /* sample only on the exact position */ - *index = ED_view3d_backbuf_sample(&vc, mval[0], mval[1]); + *index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]); } if ((*index) == 0 || (*index) > (unsigned int)me->totpoly) @@ -1045,6 +1047,7 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int return true; } + static void ed_mesh_pick_face_vert__mpoly_find( /* context */ struct ARegion *ar, const float mval[2], @@ -1073,7 +1076,7 @@ static void ed_mesh_pick_face_vert__mpoly_find( * Use when the back buffer stores face index values. but we want a vert. * This gets the face then finds the closest vertex to mval. */ -bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) +bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int dist_px) { Depsgraph *depsgraph = CTX_data_depsgraph(C); unsigned int poly_index; @@ -1081,7 +1084,7 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned BLI_assert(me && GS(me->id.name) == ID_ME); - if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) { + if (ED_mesh_pick_face(C, ob, mval, &poly_index, dist_px)) { Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); struct ARegion *ar = CTX_wm_region(C); @@ -1181,7 +1184,7 @@ static void ed_mesh_pick_vert__mapFunc(void *userData, int index, const float co } } } -bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, bool use_zbuf) +bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int dist_px, bool use_zbuf) { ViewContext vc; Mesh *me = ob->data; @@ -1194,16 +1197,18 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int ED_view3d_viewcontext_init(C, &vc); if (use_zbuf) { - if (size > 0) { + if (dist_px > 0) { /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - float dummy_dist; - *index = ED_view3d_backbuf_sample_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist); + ED_view3d_select_id_validate(&vc); + + *index = ED_view3d_select_id_read_nearest( + &vc, mval, 1, me->totvert + 1, &dist_px); } else { /* sample only on the exact position */ - *index = ED_view3d_backbuf_sample(&vc, mval[0], mval[1]); + *index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]); } if ((*index) == 0 || (*index) > (unsigned int)me->totvert) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 0b63d7455f2..97f191a217a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -451,7 +451,7 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - ED_view3d_backbuf_validate(&data->vc); + ED_view3d_backbuf_depth_validate(&data->vc); /* we may need to force an update here by setting the rv3d as dirty * for now it seems ok, but take care!: * rv3d->depths->dirty = 1; */ diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index b8c067d61e7..7de8e6bb07f 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -362,7 +362,7 @@ static int imapaint_pick_face( return 0; /* sample only on the exact position */ - *r_index = ED_view3d_backbuf_sample(vc, mval[0], mval[1]); + *r_index = ED_view3d_select_id_sample(vc, mval[0], mval[1]); if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) { return 0; diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c index aa3f424f816..24a26676df3 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -188,15 +188,15 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d); if (use_vert_sel) { - if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, true)) { + if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_DIST, true)) { v_idx_best = index; } } else { - if (ED_mesh_pick_face_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + if (ED_mesh_pick_face_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_DIST)) { v_idx_best = index; } - else if (ED_mesh_pick_face(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + else if (ED_mesh_pick_face(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_DIST)) { /* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */ BKE_report(op->reports, RPT_WARNING, "The modifier used does not support deformed locations"); } @@ -312,13 +312,13 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf( ED_view3d_init_mats_rv3d(vc.obact, vc.rv3d); if (use_vert_sel) { - if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, true)) { + if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_DIST, true)) { MDeformVert *dvert = &me->dvert[index]; found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups); } } else { - if (ED_mesh_pick_face(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + if (ED_mesh_pick_face(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_FACE_DIST)) { const MPoly *mp = &me->mpoly[index]; uint fidx = mp->totloop - 1; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index e6e0438164c..b976c231841 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -47,6 +47,8 @@ #include "UI_resources.h" +#include "DRW_engine.h" + #include "view3d_intern.h" /* bad level include */ #include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */ @@ -281,7 +283,7 @@ static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob, const float w bbs_mesh_face(geom_faces, true, world_clip_planes); } -void draw_object_backbufsel( +void draw_object_select_id( Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, short select_mode) { @@ -380,6 +382,52 @@ void draw_object_backbufsel( GPU_matrix_set(rv3d->viewmat); } +void draw_object_depth(RegionView3D *rv3d, Object *ob) +{ + GPU_matrix_mul(ob->obmat); + GPU_depth_test(true); + + const float (*world_clip_planes)[4] = NULL; + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_local(rv3d, ob->obmat); + world_clip_planes = rv3d->clip_local; + } + + switch (ob->type) { + case OB_MESH: + { + GPUBatch *batch; + + Mesh *me = ob->data; + + if (ob->mode & OB_MODE_EDIT) { + batch = DRW_mesh_batch_cache_get_edit_triangles(me); + } + else { + batch = DRW_mesh_batch_cache_get_surface(me); + } + + DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true); + + DRW_opengl_context_enable(); + const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED : GPU_SHADER_CFG_DEFAULT; + GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg); + if (world_clip_planes != NULL) { + bbs_world_clip_planes_from_rv3d(batch, world_clip_planes); + } + + GPU_batch_draw(batch); + DRW_opengl_context_disable(); + } + break; + case OB_CURVE: + case OB_SURF: + break; + } + + GPU_matrix_set(rv3d->viewmat); +} + void ED_draw_object_facemap( Depsgraph *depsgraph, Object *ob, const float col[4], const int facemap) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index ca18a96c253..25cc8854607 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -536,11 +536,6 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar) RegionView3D *rv3d = ar->regiondata; ED_view3d_stop_render_preview(wm, ar); - - if (rv3d->gpuoffscreen) { - GPU_offscreen_free(rv3d->gpuoffscreen); - rv3d->gpuoffscreen = NULL; - } } static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) @@ -729,9 +724,6 @@ static void view3d_main_region_free(ARegion *ar) if (rv3d->sms) { MEM_freeN(rv3d->sms); } - if (rv3d->gpuoffscreen) { - GPU_offscreen_free(rv3d->gpuoffscreen); - } MEM_freeN(rv3d); ar->regiondata = NULL; @@ -751,7 +743,6 @@ static void *view3d_main_region_duplicate(void *poin) new->clipbb = MEM_dupallocN(rv3d->clipbb); new->depths = NULL; - new->gpuoffscreen = NULL; new->render_engine = NULL; new->sms = NULL; new->smooth_timer = NULL; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index a52fd89d284..eed6fc31235 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -149,7 +149,7 @@ void ED_view3d_clipping_enable(void) /* *********************** backdraw for selection *************** */ -static void backdrawview3d( +static void validate_object_select_id( struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact, Object *obedit, @@ -203,81 +203,24 @@ static void backdrawview3d( if (v3d->shading.type > OB_WIRE) v3d->zbuf = true; #endif - /* dithering and AA break color coding, so disable */ - glDisable(GL_DITHER); - - if (false) { - /* for multisample we use an offscreen FBO. multisample drawing can fail - * with color coded selection drawing, and reading back depths from such - * a buffer can also cause a few seconds freeze on OS X / NVidia. - * - * NOTE: code is no longer used now, but offscreen drawing is likely - * what we will always want to do for the new viewport. */ - int w = BLI_rcti_size_x(&ar->winrct); - int h = BLI_rcti_size_y(&ar->winrct); - char error[256]; - - if (rv3d->gpuoffscreen) { - if (GPU_offscreen_width(rv3d->gpuoffscreen) != w || - GPU_offscreen_height(rv3d->gpuoffscreen) != h) - { - GPU_offscreen_free(rv3d->gpuoffscreen); - rv3d->gpuoffscreen = NULL; - } - } - - if (!rv3d->gpuoffscreen) { - rv3d->gpuoffscreen = GPU_offscreen_create(w, h, 0, true, false, error); - - if (!rv3d->gpuoffscreen) - fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error); - } - } - - if (rv3d->gpuoffscreen) - GPU_offscreen_bind(rv3d->gpuoffscreen, true); - else - GPU_scissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); - - GPU_clear_color(0.0, 0.0, 0.0, 0.0); - GPU_depth_test(true); - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_set(rv3d); - G.f |= G_FLAG_BACKBUFSEL; if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { - draw_object_backbufsel(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode); + DRW_framebuffer_select_id_setup(ar, true); + draw_object_select_id(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode); + DRW_framebuffer_select_id_release(ar); } - if (rv3d->gpuoffscreen) - GPU_offscreen_unbind(rv3d->gpuoffscreen, true); - + /* TODO: Create a flag in `DRW_manager` because the drawing is no longer + * made on the backbuffer in this case. */ v3d->flag &= ~V3D_INVALID_BACKBUF; G.f &= ~G_FLAG_BACKBUFSEL; - GPU_depth_test(false); - glEnable(GL_DITHER); - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_disable(); } void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data) { - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->gpuoffscreen) { - GPU_offscreen_bind(rv3d->gpuoffscreen, true); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glReadPixels(x, y, w, h, format, type, data); - GPU_offscreen_unbind(rv3d->gpuoffscreen, true); - } - else { - glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); - } + glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); } /* XXX depth reading exception, for code not using gpu offscreen */ @@ -286,16 +229,70 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); } -void ED_view3d_backbuf_validate_with_select_mode(ViewContext *vc, short select_mode) +void ED_view3d_select_id_validate_with_select_mode(ViewContext *vc, short select_mode) { + /* TODO: Create a flag in `DRW_manager` because the drawing is no longer + * made on the backbuffer in this case. */ if (vc->v3d->flag & V3D_INVALID_BACKBUF) { - backdrawview3d(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact, vc->obedit, select_mode); + validate_object_select_id( + vc->depsgraph, vc->scene, vc->ar, vc->v3d, + vc->obact, vc->obedit, select_mode); + } +} + +void ED_view3d_select_id_validate(ViewContext *vc) +{ + ED_view3d_select_id_validate_with_select_mode(vc, -1); +} + +void ED_view3d_backbuf_depth_validate(ViewContext *vc) +{ + if (vc->v3d->flag & V3D_INVALID_BACKBUF) { + ARegion *ar = vc->ar; + RegionView3D *rv3d = ar->regiondata; + Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact); + + if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) { + GPU_scissor(ar->winrct.xmin, ar->winrct.ymin, + BLI_rcti_size_x(&ar->winrct), + BLI_rcti_size_y(&ar->winrct)); + + GPU_depth_test(true); + GPU_clear(GPU_DEPTH_BIT); + + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_set(rv3d); + } + + draw_object_depth(rv3d, obact_eval); + + if (rv3d->rflag & RV3D_CLIPPING) { + ED_view3d_clipping_disable(rv3d); + } + + GPU_depth_test(false); + } + + vc->v3d->flag &= ~V3D_INVALID_BACKBUF; } } -void ED_view3d_backbuf_validate(ViewContext *vc) +uint *ED_view3d_select_id_read_rect(ViewContext *vc, const rcti *clip, uint *r_buf_len) { - ED_view3d_backbuf_validate_with_select_mode(vc, -1); + ED_view3d_select_id_validate(vc); + + uint width = BLI_rcti_size_x(clip); + uint height = BLI_rcti_size_y(clip); + uint buf_len = width * height; + uint *buf = MEM_mallocN(buf_len * sizeof(*buf), __func__); + + DRW_framebuffer_select_id_read(clip, buf); + + if (r_buf_len) { + *r_buf_len = buf_len; + } + + return buf; } /** @@ -308,111 +305,81 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist) } /* samples a single pixel (copied from vpaint) */ -uint ED_view3d_backbuf_sample( +uint ED_view3d_select_id_sample( ViewContext *vc, int x, int y) { if (x >= vc->ar->winx || y >= vc->ar->winy) { return 0; } - ED_view3d_backbuf_validate(vc); - - uint col; - view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); - glReadBuffer(GL_BACK); + uint buf_len; + uint *buf = ED_view3d_select_id_read(vc, x, y, x, y, &buf_len); + BLI_assert(0 != buf_len); + uint ret = buf[0]; + MEM_freeN(buf); - if (ENDIAN_ORDER == B_ENDIAN) { - BLI_endian_switch_uint32(&col); - } - - return GPU_select_to_index(col); + return ret; } /* reads full rect, converts indices */ -ImBuf *ED_view3d_backbuf_read( - ViewContext *vc, int xmin, int ymin, int xmax, int ymax) +uint *ED_view3d_select_id_read( + ViewContext *vc, int xmin, int ymin, int xmax, int ymax, uint *r_buf_len) { - /* clip */ - const rcti clip = { - max_ii(xmin, 0), min_ii(xmax, vc->ar->winx - 1), - max_ii(ymin, 0), min_ii(ymax, vc->ar->winy - 1)}; - const int size_clip[2] = { - BLI_rcti_size_x(&clip) + 1, - BLI_rcti_size_y(&clip) + 1}; - - if (UNLIKELY((clip.xmin > clip.xmax) || - (clip.ymin > clip.ymax))) - { + if (UNLIKELY((xmin > xmax) || (ymin > ymax))) { return NULL; } - ImBuf *ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect); - - ED_view3d_backbuf_validate(vc); - - view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect); + const rcti rect = { + .xmin = xmin, .xmax = xmax + 1, + .ymin = ymin, .ymax = ymax + 1, + }; - glReadBuffer(GL_BACK); + uint buf_len; + uint *buf = ED_view3d_select_id_read_rect(vc, &rect, &buf_len); - if (ENDIAN_ORDER == B_ENDIAN) { - IMB_convert_rgba_to_abgr(ibuf_clip); + if (r_buf_len) { + *r_buf_len = buf_len; } - GPU_select_to_index_array(ibuf_clip->rect, size_clip[0] * size_clip[1]); - - if ((clip.xmin == xmin) && - (clip.xmax == xmax) && - (clip.ymin == ymin) && - (clip.ymax == ymax)) - { - return ibuf_clip; - } - else { - /* put clipped result into a non-clipped buffer */ - const int size[2] = { - (xmax - xmin + 1), - (ymax - ymin + 1)}; - - ImBuf *ibuf_full = IMB_allocImBuf(size[0], size[1], 32, IB_rect); - - IMB_rectcpy( - ibuf_full, ibuf_clip, - clip.xmin - xmin, clip.ymin - ymin, - 0, 0, - size_clip[0], size_clip[1]); - IMB_freeImBuf(ibuf_clip); - return ibuf_full; - } + return buf; } /* smart function to sample a rect spiralling outside, nice for backbuf selection */ -uint ED_view3d_backbuf_sample_rect( - ViewContext *vc, const int mval[2], int size, - uint min, uint max, float *r_dist) +uint ED_view3d_select_id_read_nearest( + struct ViewContext *vc, const int mval[2], + const uint min, const uint max, uint *r_dist) { + uint index = 0; + int dirvec[4][2]; - const int amount = (size - 1) / 2; + rcti rect; + BLI_rcti_init_pt_radius(&rect, mval, *r_dist); + rect.xmax += 1; + rect.ymax += 1; + + uint width, height; + width = height = BLI_rcti_size_x(&rect); + + uint buf_len = width * height; + uint *buf = MEM_mallocN(buf_len * sizeof(*buf), __func__); + + DRW_framebuffer_select_id_read(&rect, buf); - const int minx = mval[0] - (amount + 1); - const int miny = mval[1] - (amount + 1); - ImBuf *buf = ED_view3d_backbuf_read(vc, minx, miny, minx + size - 1, miny + size - 1); - if (!buf) return 0; + BLI_assert(width == height); /* This algorithm doesn't work well with rectangles */ - unsigned index = 0; int rc = 0; dirvec[0][0] = 1; dirvec[0][1] = 0; - dirvec[1][0] = 0; dirvec[1][1] = -size; + dirvec[1][0] = 0; dirvec[1][1] = -height; dirvec[2][0] = -1; dirvec[2][1] = 0; - dirvec[3][0] = 0; dirvec[3][1] = size; + dirvec[3][0] = 0; dirvec[3][1] = height; - const unsigned *bufmin = buf->rect; - const unsigned *tbuf = buf->rect; - const unsigned *bufmax = buf->rect + size * size; - tbuf += amount * size + amount; + const uint *bufmin = buf; + const uint *bufmax = buf + buf_len; + const uint *tbuf = buf + (height * (int)(width / 2) + height / 2 - 1); - for (int nr = 1; nr <= size; nr++) { + for (int nr = 1; nr <= height; nr++) { for (int a = 0; a < 2; a++) { for (int b = 0; b < nr; b++) { if (*tbuf && *tbuf >= min && *tbuf < max) { @@ -421,8 +388,8 @@ uint ED_view3d_backbuf_sample_rect( /* get x,y pixel coords from the offset * (manhatten distance in keeping with other screen-based selection) */ *r_dist = (float)( - abs(((int)(tbuf - buf->rect) % size) - (size / 2)) + - abs(((int)(tbuf - buf->rect) / size) - (size / 2))); + abs(((int)(tbuf - buf) % height) - (height / 2)) + + abs(((int)(tbuf - buf) / height) - (height / 2))); /* indices start at 1 here */ index = (*tbuf - min) + 1; @@ -441,7 +408,7 @@ uint ED_view3d_backbuf_sample_rect( } exit: - IMB_freeImBuf(buf); + MEM_freeN(buf); return index; } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index bb6b96b96d5..e85558765b6 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -123,11 +123,13 @@ void VIEW3D_OT_fly(struct wmOperatorType *ot); void VIEW3D_OT_walk(struct wmOperatorType *ot); /* drawobject.c */ -void draw_object_backbufsel( +void draw_object_select_id( struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, short select_mode); +void draw_object_depth(RegionView3D *rv3d, struct Object *ob); + int view3d_effective_drawtype(const struct View3D *v3d); /* view3d_draw.c */ diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index fc13968def7..02d469bfa73 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1924,7 +1924,7 @@ static bool ed_wpaint_vertex_select_pick( uint index = 0; MVert *mv; - if (ED_mesh_pick_vert(C, obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, use_zbuf)) { + if (ED_mesh_pick_vert(C, obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf)) { mv = &me->mvert[index]; if (extend) { mv->flag |= SELECT; @@ -2112,22 +2112,17 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con } } static int do_paintvert_box_select( - ViewContext *vc, rcti *rect, const eSelectOp sel_op) + ViewContext *vc, const rcti *rect, const eSelectOp sel_op) { const bool use_zbuf = V3D_IS_ZBUF(vc->v3d); Mesh *me; MVert *mvert; - struct ImBuf *ibuf; - uint *rt; + unsigned int *rt; int a, index; char *selar; - const int size[2] = { - BLI_rcti_size_x(rect) + 1, - BLI_rcti_size_y(rect) + 1}; me = vc->obact->data; - - if ((me == NULL) || (me->totvert == 0) || (size[0] * size[1] <= 0)) { + if ((me == NULL) || (me->totvert == 0) || BLI_rcti_is_empty(rect)) { return OPERATOR_CANCELLED; } @@ -2137,20 +2132,13 @@ static int do_paintvert_box_select( if (use_zbuf) { selar = MEM_callocN(me->totvert + 1, "selar"); - ED_view3d_backbuf_validate(vc); - ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect); - rt = ibuf->rect; - glReadPixels( - rect->xmin + vc->ar->winrct.xmin, - rect->ymin + vc->ar->winrct.ymin, - size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - if (ENDIAN_ORDER == B_ENDIAN) { - IMB_convert_rgba_to_abgr(ibuf); - } - GPU_select_to_index_array(ibuf->rect, size[0] * size[1]); + uint buf_len; + uint *buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len); + + rt = buf; - a = size[0] * size[1]; + a = buf_len; while (a--) { if (*rt) { index = *rt; @@ -2173,7 +2161,7 @@ static int do_paintvert_box_select( } } - IMB_freeImBuf(ibuf); + MEM_freeN(buf); MEM_freeN(selar); #ifdef __APPLE__ |