Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-03-15 22:02:55 +0300
committermano-wii <germano.costa@ig.com.br>2019-03-15 23:02:48 +0300
commit681661dbed121c7b81e9129c57df5eadb03c1009 (patch)
tree8802195c72af13e1bb7324131024cc98fb5971a7 /source/blender/editors
parent4510f88d00a721a3d4ad3aa675050723eec2292c (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.h12
-rw-r--r--source/blender/editors/include/ED_view3d.h26
-rw-r--r--source/blender/editors/mesh/editface.c30
-rw-r--r--source/blender/editors/mesh/editmesh_select.c67
-rw-r--r--source/blender/editors/mesh/meshtools.c29
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c10
-rw-r--r--source/blender/editors/space_view3d/drawobject.c50
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c255
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h4
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c32
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__