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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-08-16 18:38:07 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-08-16 23:34:02 +0300
commit7c96f613e4d05f67f5cd9bf0cec29ca7ce51a3e4 (patch)
tree5d366b09edc069803d67c875e9ef65314eff87a9 /source
parenta4068d008304f2c609df0b2d8db5f987c86c1509 (diff)
DwM: Use Batch's for drawing selection
Use mesh batch cache for mesh selection. Note that we could create the batches and free immediately so they don't take up memory. This resolves a problem where selection was limited to immediate-mode buffer size.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h7
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c464
-rw-r--r--source/blender/editors/space_view3d/drawobject.c61
-rw-r--r--source/blender/gpu/GPU_shader.h1
-rw-r--r--source/blender/gpu/intern/gpu_shader.c2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl12
6 files changed, 503 insertions, 44 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index f8feeb37b82..82972b9f75b 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -85,7 +85,8 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
-struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide);
struct Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
@@ -95,6 +96,10 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me);
+/* edit-mesh selection (use generic function for faces) */
+struct Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset);
void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 721db9f5f72..eddf2dc2fa4 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1427,13 +1427,32 @@ typedef struct MeshBatchCache {
Gwn_VertBuf *pos_with_normals;
Gwn_VertBuf *tri_aligned_uv; /* Active UV layer (mloopuv) */
+
+ /**
+ * Other uses are all positions or loose elements.
+ * This stores all visible elements, needed for selection.
+ */
+ Gwn_VertBuf *ed_fcenter_pos_with_nor_and_sel;
+ Gwn_VertBuf *ed_edge_pos;
+ Gwn_VertBuf *ed_vert_pos;
+
Gwn_Batch *triangles_with_normals;
/* Skip hidden (depending on paint select mode) */
Gwn_Batch *triangles_with_weights;
Gwn_Batch *triangles_with_vert_colors;
/* Always skip hidden */
+ Gwn_Batch *triangles_with_select_mask;
Gwn_Batch *triangles_with_select_id;
+ uint triangles_with_select_id_offset;
+
+ Gwn_Batch *facedot_with_select_id; /* shares vbo with 'overlay_facedots' */
+ Gwn_Batch *edges_with_select_id;
+ Gwn_Batch *verts_with_select_id;
+
+ uint facedot_with_select_id_offset;
+ uint edges_with_select_id_offset;
+ uint verts_with_select_id_offset;
Gwn_Batch *points_with_normals;
Gwn_Batch *fancy_edges; /* owns its vertex buffer (not shared) */
@@ -1463,9 +1482,6 @@ typedef struct MeshBatchCache {
Gwn_VertBuf *ed_lvert_nor; /* VertNor */
Gwn_VertBuf *ed_lvert_data;
- Gwn_VertBuf *ed_fcenter_pos;
- Gwn_VertBuf *ed_fcenter_nor;
-
Gwn_Batch *overlay_triangles;
Gwn_Batch *overlay_triangles_nor; /* GWN_PRIM_POINTS */
Gwn_Batch *overlay_loose_edges;
@@ -1583,11 +1599,18 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode)
GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_data);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_nor); /* Contains select flag */
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
+
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
GWN_BATCH_DISCARD_SAFE(cache->overlay_facedots);
+ /* Edit mode selection. */
+ GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
break;
case BKE_MESH_BATCH_DIRTY_NOCHECK:
cache->is_really_dirty = true;
@@ -1629,8 +1652,6 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_nor);
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles);
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
@@ -1648,7 +1669,14 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
+ GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
GWN_BATCH_DISCARD_SAFE(cache->fancy_edges);
@@ -2054,6 +2082,286 @@ static Gwn_VertBuf *mesh_create_tri_pos_and_normals_visible_only(
&vbo_dummy);
}
+static Gwn_VertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (cache->ed_fcenter_pos_with_nor_and_sel == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ attr_id.data = GWN_vertformat_attr_add(&format, "norAndFlag", GWN_COMP_I10, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
+ int vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ for (int i = 0; i < vbo_len_capacity; ++i) {
+ float pcenter[3], pnor[3];
+ bool selected = false;
+
+ if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
+
+ Gwn_PackedNormal nor = { .x = 0, .y = 0, .z = -511 };
+ nor = GWN_normal_convert_i10_v3(pnor);
+ nor.w = selected ? 1 : 0;
+ GWN_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor);
+
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter);
+
+ vidx += 1;
+ }
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ BLI_assert(vbo_len_capacity == vbo_len_used);
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_fcenter_pos_with_nor_and_sel;
+}
+
+static Gwn_VertBuf *mesh_batch_cache_get_edges_visible(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
+
+ if (cache->ed_edge_pos == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
+ int vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_edge_pos = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co);
+ vidx += 1;
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co);
+ vidx += 1;
+ }
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_edge_pos;
+}
+
+static Gwn_VertBuf *mesh_batch_cache_get_verts_visible(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_vert_pos == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
+ uint vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_vert_pos = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co);
+ vidx += 1;
+ }
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const uint vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_vert_pos;
+}
+
+static Gwn_VertBuf *mesh_create_facedot_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *efa;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
+}
+
+static Gwn_VertBuf *mesh_create_edges_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
+}
+
+static Gwn_VertBuf *mesh_create_verts_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
+}
+
static Gwn_VertBuf *mesh_create_tri_weights(
MeshRenderData *rdata, bool use_hide, int defgroup)
{
@@ -2071,10 +2379,9 @@ static Gwn_VertBuf *mesh_create_tri_weights(
attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
}
- const int tri_len = mesh_render_data_looptri_len_get(rdata);
-
vbo = GWN_vertbuf_create_with_format(&format);
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
const int vbo_len_capacity = tri_len * 3;
int vbo_len_used = 0;
GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
@@ -2176,7 +2483,7 @@ static Gwn_VertBuf *mesh_create_tri_vert_colors(
}
static Gwn_VertBuf *mesh_create_tri_select_id(
- MeshRenderData *rdata, bool use_hide)
+ MeshRenderData *rdata, bool use_hide, uint select_id_offset)
{
BLI_assert(
rdata->types &
@@ -2207,7 +2514,7 @@ static Gwn_VertBuf *mesh_create_tri_select_id(
if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
const int poly_index = BM_elem_index_get(ltri[0]->f);
int select_id;
- GPU_select_index_get(poly_index + 1, &select_id);
+ GPU_select_index_get(poly_index + select_id_offset, &select_id);
for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
}
@@ -2220,7 +2527,7 @@ static Gwn_VertBuf *mesh_create_tri_select_id(
const int poly_index = mlt->poly;
if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) {
int select_id;
- GPU_select_index_get(poly_index + 1, &select_id);
+ GPU_select_index_get(poly_index + select_id_offset, &select_id);
for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
}
@@ -3006,17 +3313,23 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh
}
-struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide)
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(
+ struct Mesh *me, bool use_hide, uint select_id_offset)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ if (cache->triangles_with_select_id_offset != select_id_offset) {
+ cache->triangles_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
+ }
+
if (cache->triangles_with_select_id == NULL) {
const int datatype =
MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
cache->triangles_with_select_id = GWN_batch_create_ex(
- GWN_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide), NULL, GWN_BATCH_OWNS_VBO);
+ GWN_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GWN_BATCH_OWNS_VBO);
Gwn_VertBuf *vbo_tris = use_hide ?
mesh_create_tri_pos_and_normals_visible_only(rdata) :
@@ -3029,6 +3342,31 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh
return cache->triangles_with_select_id;
}
+/**
+ * Same as #DRW_mesh_batch_cache_get_triangles_with_select_id
+ * without the ID's, use to mask out geometry, eg - dont select face-dots behind other faces.
+ */
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ if (cache->triangles_with_select_mask == NULL) {
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ Gwn_VertBuf *vbo_tris = use_hide ?
+ mesh_create_tri_pos_and_normals_visible_only(rdata) :
+ mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+
+ cache->triangles_with_select_mask = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo_tris, NULL, use_hide ? GWN_BATCH_OWNS_VBO : 0);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_select_mask;
+}
+
Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -3238,46 +3576,90 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me)
if (cache->overlay_facedots == NULL) {
MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- static Gwn_VertFormat format = { 0 };
- static struct { uint pos, data; } attr_id;
- if (format.attrib_ct == 0) {
- attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- attr_id.data = GWN_vertformat_attr_add(&format, "norAndFlag", GWN_COMP_I10, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- }
+ cache->overlay_facedots = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL);
- const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
- int vidx = 0;
+ mesh_render_data_free(rdata);
+ }
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
- for (int i = 0; i < vbo_len_capacity; ++i) {
- float pcenter[3], pnor[3];
- bool selected = false;
+ return cache->overlay_facedots;
+}
- if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
+Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
- Gwn_PackedNormal nor = { .x = 0, .y = 0, .z = -511 };
- nor = GWN_normal_convert_i10_v3(pnor);
- nor.w = selected ? 1 : 0;
- GWN_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor);
+ if (cache->facedot_with_select_id_offset != select_id_offset) {
+ cache->facedot_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ }
- GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter);
+ if (cache->facedot_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- vidx += 1;
+ /* We only want the 'pos', not the normals or flag.
+ * Use since this is almost certainly already created. */
+ cache->facedot_with_select_id = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL);
- }
- }
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GWN_vertbuf_data_resize(vbo, vbo_len_used);
- }
+ GWN_batch_vertbuf_add_ex(
+ cache->facedot_with_select_id,
+ mesh_create_facedot_select_id(rdata, select_id_offset), true);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->facedot_with_select_id;
+}
+
+Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->edges_with_select_id_offset != select_id_offset) {
+ cache->edges_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ }
- cache->overlay_facedots = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ if (cache->edges_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
+
+ cache->edges_with_select_id = GWN_batch_create(
+ GWN_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL);
+
+ GWN_batch_vertbuf_add_ex(
+ cache->edges_with_select_id,
+ mesh_create_edges_select_id(rdata, select_id_offset), true);
mesh_render_data_free(rdata);
}
- return cache->overlay_facedots;
+ return cache->edges_with_select_id;
+}
+
+Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->verts_with_select_id_offset != select_id_offset) {
+ cache->verts_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
+ }
+
+ if (cache->verts_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
+
+ cache->verts_with_select_id = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL);
+
+ GWN_batch_vertbuf_add_ex(
+ cache->verts_with_select_id,
+ mesh_create_verts_select_id(rdata, select_id_offset), true);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->verts_with_select_id;
}
Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded(
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 2acc7241f86..5698b2fe08a 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -118,6 +118,8 @@
/* prototypes */
static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos);
+// #define USE_MESH_DM_SELECT
+
/* Workaround for sequencer scene render mode.
*
* Strips doesn't use DAG to update objects or so, which
@@ -9369,6 +9371,7 @@ void draw_object_select(
/* ***************** BACKBUF SEL (BBS) ********* */
+
static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -9410,6 +9413,7 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -9442,7 +9446,17 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#else
+static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_wire__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
{
drawBMOffset_userData *data = userData;
@@ -9482,7 +9496,19 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#else
+static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select)
{
UNUSED_VARS(dm);
@@ -9535,7 +9561,29 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select
immUnbindProgram();
}
+#else
+static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select)
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch;
+ if (use_select) {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+ }
+ else {
+ int selcol;
+ GPU_select_index_get(0, &selcol);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GWN_batch_uniform_1i(batch, "color", selcol);
+ GWN_batch_draw(batch);
+ }
+}
+#endif
+
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
{
drawBMOffset_userData *data = (drawBMOffset_userData *)userData;
@@ -9567,6 +9615,15 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
immUnbindProgram();
}
+#else
+static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm))
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
/* two options, facecolors or black */
static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
@@ -9641,10 +9698,10 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts);
Gwn_Batch *batch;
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
}
else {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
}
GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
GWN_batch_draw(batch);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 7c8ee07eb88..5b62bafd402 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -118,6 +118,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */
GPU_SHADER_3D_UNIFORM_COLOR,
+ GPU_SHADER_3D_UNIFORM_COLOR_U32,
GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
GPU_SHADER_3D_FLAT_COLOR,
GPU_SHADER_3D_FLAT_COLOR_U32, /* use for select-id's */
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index e67e5bc933d..5d5be2ec4ef 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -663,6 +663,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR_U32] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR_U32] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
@@ -767,6 +768,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
defines = "#define USE_INSTANCE_COLOR;\n";
break;
case GPU_SHADER_3D_FLAT_COLOR_U32:
+ case GPU_SHADER_3D_UNIFORM_COLOR_U32:
defines = "#define USE_COLOR_U32;\n";
break;
case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
diff --git a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
index 5dd1352adc5..118a661863d 100644
--- a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
@@ -1,9 +1,21 @@
+#if defined(USE_COLOR_U32)
+uniform uint color;
+#else
uniform vec4 color;
+#endif
out vec4 fragColor;
void main()
{
+#if defined(USE_COLOR_U32)
+ fragColor = vec4(
+ ((color ) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 8) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 16) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 24) ) * (1.0f / 255.0f));
+#else
fragColor = color;
+#endif
}