diff options
18 files changed, 869 insertions, 1409 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index d6d244c81d0..ee91245fb1a 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -114,12 +114,9 @@ struct GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_surface_weights(struct Mesh *me); /* edit-mesh drawing */ struct GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_triangles_nor(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_triangles_lnor(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_loose_edges(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_loose_edges_nor(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_loose_verts(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_edges(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(struct Mesh *me); /* edit-mesh selection */ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me); @@ -142,25 +139,27 @@ struct GPUBatch *DRW_mesh_batch_cache_get_uv_edges(struct Mesh *me); void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me); /* Edit mesh bitflags (is this the right place?) */ - enum { - VFLAG_VERTEX_ACTIVE = 1 << 0, - VFLAG_VERTEX_SELECTED = 1 << 1, - VFLAG_VERTEX_EXISTS = 1 << 2, - VFLAG_FACE_ACTIVE = 1 << 3, - VFLAG_FACE_SELECTED = 1 << 4, - VFLAG_FACE_FREESTYLE = 1 << 5, + VFLAG_VERT_ACTIVE = 1 << 0, + VFLAG_VERT_SELECTED = 1 << 1, + VFLAG_EDGE_ACTIVE = 1 << 2, + VFLAG_EDGE_SELECTED = 1 << 3, + VFLAG_EDGE_SEAM = 1 << 4, + VFLAG_EDGE_SHARP = 1 << 5, + VFLAG_EDGE_FREESTYLE = 1 << 6, /* Beware to not go over 1 << 7 (it's a byte flag) * (see gpu_shader_edit_mesh_overlay_geom.glsl) */ }; enum { - VFLAG_EDGE_EXISTS = 1 << 0, - VFLAG_EDGE_ACTIVE = 1 << 1, - VFLAG_EDGE_SELECTED = 1 << 2, - VFLAG_EDGE_SEAM = 1 << 3, - VFLAG_EDGE_SHARP = 1 << 4, - VFLAG_EDGE_FREESTYLE = 1 << 5, + VFLAG_FACE_ACTIVE = 1 << 0, + VFLAG_FACE_SELECTED = 1 << 1, + VFLAG_FACE_FREESTYLE = 1 << 2, + VFLAG_VERT_UV_SELECT = 1 << 3, + VFLAG_VERT_UV_PINNED = 1 << 4, + VFLAG_EDGE_UV_SELECT = 1 << 5, + VFLAG_FACE_UV_ACTIVE = 1 << 6, + VFLAG_FACE_UV_SELECT = 1 << 7, /* Beware to not go over 1 << 7 (it's a byte flag) * (see gpu_shader_edit_mesh_overlay_geom.glsl) */ }; diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index 510cc790be2..54c1c924f87 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -679,8 +679,8 @@ static void curve_create_edit_curves_nor(CurveRenderData *rdata, GPUVertBuf *vbo static char beztriple_vflag_get(CurveRenderData *rdata, char flag, char col_id, int v_idx, int nu_id) { char vflag = 0; - SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERTEX_SELECTED); - SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERTEX_ACTIVE); + SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERT_SELECTED); + SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERT_ACTIVE); SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB); /* handle color id */ vflag |= col_id << 4; /* << 4 because of EVEN_U_BIT */ @@ -690,8 +690,8 @@ static char beztriple_vflag_get(CurveRenderData *rdata, char flag, char col_id, static char bpoint_vflag_get(CurveRenderData *rdata, char flag, int v_idx, int nu_id, int u) { char vflag = 0; - SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERTEX_SELECTED); - SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERTEX_ACTIVE); + SET_FLAG_FROM_TEST(vflag, (flag & SELECT), VFLAG_VERT_SELECTED); + SET_FLAG_FROM_TEST(vflag, (v_idx == rdata->actvert), VFLAG_VERT_ACTIVE); SET_FLAG_FROM_TEST(vflag, (nu_id == rdata->actnu), ACTIVE_NURB); SET_FLAG_FROM_TEST(vflag, ((u % 2) == 0), EVEN_U_BIT); vflag |= COLOR_NURB_ULINE_ID << 4; /* << 4 because of EVEN_U_BIT */ diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c index 53ce55bae71..d1abd19c2ff 100644 --- a/source/blender/draw/intern/draw_cache_impl_lattice.c +++ b/source/blender/draw/intern/draw_cache_impl_lattice.c @@ -513,10 +513,10 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt) char vflag = 0; if (bp->f1 & SELECT) { if (i == rdata->actbp) { - vflag |= VFLAG_VERTEX_ACTIVE; + vflag |= VFLAG_VERT_ACTIVE; } else { - vflag |= VFLAG_VERTEX_SELECTED; + vflag |= VFLAG_VERT_SELECTED; } } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 0d79ce3025a..016631e84d0 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -181,6 +181,7 @@ typedef struct MeshRenderData { BMEditMesh *edit_bmesh; struct EditMeshData *edit_data; + const ToolSettings *toolsettings; Mesh *me; @@ -243,6 +244,7 @@ typedef struct MeshRenderData { BMVert *eve_act; BMEdge *eed_act; BMFace *efa_act; + BMFace *efa_act_uv; /* Data created on-demand (usually not for bmesh-based data). */ EdgeAdjacentPolys *edges_adjacent_polys; @@ -549,10 +551,12 @@ static void mesh_cd_extract_auto_layers_names_and_srgb( * Although this only impacts the data that's generated, not the materials that display. */ static MeshRenderData *mesh_render_data_create_ex( - Mesh *me, const int types, const uchar cd_vused[CD_NUMTYPES], const ushort cd_lused[CD_NUMTYPES]) + Mesh *me, const int types, const uchar cd_vused[CD_NUMTYPES], const ushort cd_lused[CD_NUMTYPES], + const ToolSettings *ts) { MeshRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__); rdata->types = types; + rdata->toolsettings = ts; rdata->mat_len = mesh_render_mat_len_get(me); CustomData_reset(&rdata->cd.output.ldata); @@ -586,6 +590,9 @@ static MeshRenderData *mesh_render_data_create_ex( if (types & MR_DATATYPE_LOOPTRI) { rdata->mapped.tri_len = poly_to_tri_count(me_cage->totpoly, me_cage->totloop); } + if (types & MR_DATATYPE_LOOPUV) { + rdata->mloopuv = CustomData_get_layer(&me_cage->ldata, CD_MLOOPUV); + } rdata->mapped.v_origindex = CustomData_get_layer(&me_cage->vdata, CD_ORIGINDEX); rdata->mapped.e_origindex = CustomData_get_layer(&me_cage->edata, CD_ORIGINDEX); @@ -626,6 +633,7 @@ static MeshRenderData *mesh_render_data_create_ex( bm_ensure_types |= BM_FACE; } if (types & MR_DATATYPE_OVERLAY) { + rdata->efa_act_uv = EDBM_uv_active_face_get(embm, false, false); rdata->efa_act = BM_mesh_active_face_get(bm, false, true); rdata->eed_act = BM_mesh_active_edge_get(bm); rdata->eve_act = BM_mesh_active_vert_get(bm); @@ -1110,11 +1118,6 @@ static void mesh_render_data_free(MeshRenderData *rdata) MEM_freeN(rdata); } -static MeshRenderData *mesh_render_data_create(Mesh *me, const int types) -{ - return mesh_render_data_create_ex(me, types, NULL, NULL); -} - /** \} */ /* ---------------------------------------------------------------------- */ @@ -1241,7 +1244,7 @@ static int mesh_render_data_polys_len_get_maybe_mapped(const MeshRenderData *rda /* ---------------------------------------------------------------------- */ /* TODO remove prototype. */ -static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor_data_facedots); +static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_facedots_pos_nor_data); /** \name Internal Cache (Lazy Initialization) * \{ */ @@ -1468,18 +1471,24 @@ fallback: /** \name Internal Cache Generation * \{ */ -static uchar mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace *efa) +static uchar mesh_render_data_face_flag(MeshRenderData *rdata, const BMFace *efa, const int cd_ofs) { uchar fflag = 0; if (efa == rdata->efa_act) { fflag |= VFLAG_FACE_ACTIVE; } - if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { fflag |= VFLAG_FACE_SELECTED; } + if (efa == rdata->efa_act_uv) { + fflag |= VFLAG_FACE_UV_ACTIVE; + } + if ((cd_ofs != -1) && uvedit_face_select_test_ex(rdata->toolsettings, (BMFace *)efa, cd_ofs)) { + fflag |= VFLAG_FACE_UV_SELECT; + } + #ifdef WITH_FREESTYLE if (rdata->cd.offset.freestyle_face != -1) { const FreestyleFace *ffa = BM_ELEM_CD_GET_VOID_P(efa, rdata->cd.offset.freestyle_face); @@ -1496,24 +1505,29 @@ static void mesh_render_data_edge_flag( const MeshRenderData *rdata, const BMEdge *eed, EdgeDrawAttr *eattr) { - eattr->e_flag |= VFLAG_EDGE_EXISTS; + const ToolSettings *ts = rdata->toolsettings; + const bool is_vertex_select_mode = (ts != NULL) && (ts->selectmode & SCE_SELECT_VERTEX) != 0; if (eed == rdata->eed_act) { eattr->e_flag |= VFLAG_EDGE_ACTIVE; } - - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (!is_vertex_select_mode && + BM_elem_flag_test(eed, BM_ELEM_SELECT)) + { + eattr->e_flag |= VFLAG_EDGE_SELECTED; + } + if (is_vertex_select_mode && + BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) && + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) + { eattr->e_flag |= VFLAG_EDGE_SELECTED; } - if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) { eattr->e_flag |= VFLAG_EDGE_SEAM; } - if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) { eattr->e_flag |= VFLAG_EDGE_SHARP; } - /* Use a byte for value range */ if (rdata->cd.offset.crease != -1) { float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease); @@ -1521,7 +1535,6 @@ static void mesh_render_data_edge_flag( eattr->crease = (uchar)(crease * 255.0f); } } - /* Use a byte for value range */ if (rdata->cd.offset.bweight != -1) { float bweight = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.bweight); @@ -1529,7 +1542,6 @@ static void mesh_render_data_edge_flag( eattr->bweight = (uchar)(bweight * 255.0f); } } - #ifdef WITH_FREESTYLE if (rdata->cd.offset.freestyle_edge != -1) { const FreestyleEdge *fed = BM_ELEM_CD_GET_VOID_P(eed, rdata->cd.offset.freestyle_edge); @@ -1540,288 +1552,30 @@ static void mesh_render_data_edge_flag( #endif } -static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve) -{ - uchar vflag = VFLAG_VERTEX_EXISTS; - - /* Current vertex */ - if (eve == rdata->eve_act) { - vflag |= VFLAG_VERTEX_ACTIVE; - } - - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - vflag |= VFLAG_VERTEX_SELECTED; - } - - return vflag; -} - -static void add_edit_tri( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb, - const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id, - const BMLoop **bm_looptri, const int base_vert_idx) +static void mesh_render_data_loop_flag(MeshRenderData *rdata, BMLoop *loop, const int cd_ofs, EdgeDrawAttr *eattr) { - uchar fflag; - uchar vflag; - - /* Only draw vertices once. */ - if (elb) { - for (int i = 0; i < 3; ++i) { - if (!BM_elem_flag_test(bm_looptri[i]->v, BM_ELEM_TAG)) { - BM_elem_flag_enable(bm_looptri[i]->v, BM_ELEM_TAG); - GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i); - } - } - } - - if (vbo_pos_nor) { - /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */ - if (rdata->edit_data && rdata->edit_data->vertexCos) { - for (uint i = 0; i < 3; i++) { - int vidx = BM_elem_index_get(bm_looptri[i]->v); - const float *pos = rdata->edit_data->vertexCos[vidx]; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - } - } - else { - for (uint i = 0; i < 3; i++) { - const float *pos = bm_looptri[i]->v->co; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - } - } - - for (uint i = 0; i < 3; i++) { - GPUPackedNormal vnor = GPU_normal_convert_i10_v3(bm_looptri[i]->v->no); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor); - } - } - - if (vbo_lnor) { - float (*lnors)[3] = rdata->loop_normals; - for (uint i = 0; i < 3; i++) { - const float *nor = (lnors) ? lnors[BM_elem_index_get(bm_looptri[i])] : bm_looptri[0]->f->no; - GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor); - GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor); - } - } - - if (vbo_data) { - fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f); - for (uint i = 0; i < 3; i++) { - const int i_next = (i + 1) % 3; - const int i_prev = (i + 2) % 3; - vflag = mesh_render_data_vertex_flag(rdata, bm_looptri[i]->v); - /* Opposite edge to the vertex at 'i'. */ - EdgeDrawAttr eattr = {0}; - const bool is_edge_real = (bm_looptri[i_next] == bm_looptri[i_prev]->prev); - if (is_edge_real) { - mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr); - } - eattr.v_flag = fflag | vflag; - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); - } - } -} -static bool add_edit_tri_mapped( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUVertBuf *vbo_data, GPUIndexBufBuilder *elb, - const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id, - BMFace *efa, const MLoopTri *mlt, const float (*poly_normals)[3], const float (*loop_normals)[3], const int base_vert_idx) -{ - if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - return false; - } - - BMEditMesh *embm = rdata->edit_bmesh; - BMesh *bm = embm->bm; - Mesh *me_cage = embm->mesh_eval_cage; - - const MVert *mvert = me_cage->mvert; - const MEdge *medge = me_cage->medge; - const MLoop *mloop = me_cage->mloop; - - const int *v_origindex = rdata->mapped.v_origindex; - const int *e_origindex = rdata->mapped.e_origindex; - - if (elb) { - for (int i = 0; i < 3; ++i) { - const int v_orig = v_origindex[mloop[mlt->tri[i]].v]; - if (v_orig == ORIGINDEX_NONE) { - continue; - } - BMVert *v = BM_vert_at_index(bm, v_orig); - if (!BM_elem_flag_test(v, BM_ELEM_TAG)) { - BM_elem_flag_enable(v, BM_ELEM_TAG); - GPU_indexbuf_add_generic_vert(elb, base_vert_idx + i); - } - } - } - - if (vbo_pos_nor) { - for (uint i = 0; i < 3; i++) { - const float *pos = mvert[mloop[mlt->tri[i]].v].co; - GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[mloop[mlt->tri[i]].v].no); - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor); - } - } - - if (vbo_lnor) { - for (uint i = 0; i < 3; i++) { - const float *nor = loop_normals ? loop_normals[mlt->tri[i]] : poly_normals[mlt->poly]; - GPUPackedNormal lnor = GPU_normal_convert_i10_v3(nor); - GPU_vertbuf_attr_set(vbo_lnor, lnor_id, base_vert_idx + i, &lnor); - } - } - - if (vbo_data) { - EdgeDrawAttr eattr[3] = {{0}}; /* Importantly VFLAG_VERTEX_EXISTS is not set. */ - uchar fflag = mesh_render_data_looptri_flag(rdata, efa); - for (uint i = 0; i < 3; i++) { - const int i_next = (i + 1) % 3; - const int i_prev = (i + 2) % 3; - const int v_orig = v_origindex[mloop[mlt->tri[i]].v]; - if (v_orig != ORIGINDEX_NONE) { - BMVert *v = BM_vert_at_index(bm, v_orig); - eattr[i].v_flag |= mesh_render_data_vertex_flag(rdata, v); - } - /* Opposite edge to the vertex at 'i'. */ - const int e_idx = mloop[mlt->tri[i_next]].e; - const int e_orig = e_origindex[e_idx]; - if (e_orig != ORIGINDEX_NONE) { - const MEdge *ed = &medge[e_idx]; - const uint tri_edge[2] = {mloop[mlt->tri[i_prev]].v, mloop[mlt->tri[i_next]].v}; - const bool is_edge_real = ( - ((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) || - ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0]))); - if (is_edge_real) { - BMEdge *eed = BM_edge_at_index(bm, e_orig); - mesh_render_data_edge_flag(rdata, eed, &eattr[i]); - /* Set vertex selected if both original verts are selected. */ - if (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) && - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) - { - eattr[i_next].v_flag |= VFLAG_VERTEX_SELECTED; - eattr[i_prev].v_flag |= VFLAG_VERTEX_SELECTED; - } - } - } - } - for (uint i = 0; i < 3; i++) { - eattr[i].v_flag |= fflag; - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr[i]); - } - } - - return true; -} - -static void add_edit_loose_edge( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data, - const uint pos_id, const uint vnor_id, const uint data_id, - const BMEdge *eed, const int base_vert_idx) -{ - if (vbo_pos_nor) { - /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */ - if (rdata->edit_data && rdata->edit_data->vertexCos) { - for (uint i = 0; i < 2; i++) { - int vidx = BM_elem_index_get((&eed->v1)[i]); - const float *pos = rdata->edit_data->vertexCos[vidx]; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - } - } - else { - for (int i = 0; i < 2; i++) { - const float *pos = (&eed->v1)[i]->co; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - } - } - - for (int i = 0; i < 2; i++) { - GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor); - } + if (cd_ofs == -1) { + return; } - - if (vbo_data) { - EdgeDrawAttr eattr = {0}; - mesh_render_data_edge_flag(rdata, eed, &eattr); - for (int i = 0; i < 2; i++) { - eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]); - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); - } + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, cd_ofs); + if (luv != NULL && (luv->flag & MLOOPUV_PINNED)) { + eattr->v_flag |= VFLAG_VERT_UV_PINNED; } -} -static void add_edit_loose_edge_mapped( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data, - const uint pos_id, const uint vnor_id, const uint data_id, - BMEdge *eed, const MVert *mvert, const MEdge *ed, const int base_vert_idx) -{ - if (vbo_pos_nor) { - /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */ - for (int i = 0; i < 2; i++) { - const float *pos = mvert[*(&ed->v1 + i)].co; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx + i, pos); - - GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[*(&ed->v1 + i)].no); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx + i, &vnor); - } + if (uvedit_uv_select_test_ex(rdata->toolsettings, loop, cd_ofs)) { + eattr->v_flag |= VFLAG_VERT_UV_SELECT; } - - if (vbo_data) { - EdgeDrawAttr eattr = {0}; - mesh_render_data_edge_flag(rdata, eed, &eattr); - for (int i = 0; i < 2; i++) { - const int v_orig = rdata->mapped.v_origindex[*(&ed->v1 + i)]; - eattr.v_flag = (v_orig != ORIGINDEX_NONE) ? mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]) : 0; - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); - } + if (uvedit_edge_select_test_ex(rdata->toolsettings, loop, cd_ofs)) { + eattr->v_flag |= VFLAG_EDGE_UV_SELECT; } } -static void add_edit_loose_vert( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data, - const uint pos_id, const uint vnor_id, const uint data_id, - const BMVert *eve, const int base_vert_idx) -{ - if (vbo_pos_nor) { - /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */ - if (rdata->edit_data && rdata->edit_data->vertexCos) { - int vidx = BM_elem_index_get(eve); - const float *pos = rdata->edit_data->vertexCos[vidx]; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos); - } - else { - const float *pos = eve->co; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos); - } - - GPUPackedNormal vnor = GPU_normal_convert_i10_v3(eve->no); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor); - } - - if (vbo_data) { - uchar vflag[4] = {0, 0, 0, 0}; - vflag[0] = mesh_render_data_vertex_flag(rdata, eve); - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag); - } -} -static void add_edit_loose_vert_mapped( - MeshRenderData *rdata, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_data, - const uint pos_id, const uint vnor_id, const uint data_id, - const BMVert *eve, const MVert *mv, const int base_vert_idx) +static void mesh_render_data_vert_flag(MeshRenderData *rdata, const BMVert *eve, EdgeDrawAttr *eattr) { - if (vbo_pos_nor) { - const float *pos = mv->co; - GPU_vertbuf_attr_set(vbo_pos_nor, pos_id, base_vert_idx, pos); - - GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mv->no); - GPU_vertbuf_attr_set(vbo_pos_nor, vnor_id, base_vert_idx, &vnor); + if (eve == rdata->eve_act) { + eattr->e_flag |= VFLAG_VERT_ACTIVE; } - - if (vbo_data) { - uchar vflag[4] = {0, 0, 0, 0}; - vflag[0] = mesh_render_data_vertex_flag(rdata, eve); - GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag); + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + eattr->e_flag |= VFLAG_VERT_SELECTED; } } @@ -2005,35 +1759,30 @@ typedef struct MeshBatchCache { } tess; /* Edit Mesh Data: - * Data is also tesselated because of barycentric wireframe rendering. */ + * Edit cage can be different from final mesh so vertex count + * might differ. */ struct { - GPUVertBuf *pos_nor; - GPUVertBuf *pos_nor_ledges; - GPUVertBuf *pos_nor_lverts; - GPUVertBuf *pos_nor_data_facedots; - GPUVertBuf *data; - GPUVertBuf *data_ledges; - GPUVertBuf *data_lverts; - GPUVertBuf *lnor; + /* TODO(fclem): Reuse ordered.loop_pos_nor and maybe even + * ordered.loop_uv_tan when cage match final mesh. */ + GPUVertBuf *loop_pos_nor; + GPUVertBuf *loop_data; + GPUVertBuf *loop_lnor; + GPUVertBuf *facedots_pos_nor_data; + /* UV data without modifier applied. + * Vertex count is always the one of the cage. */ + GPUVertBuf *loop_uv; + GPUVertBuf *loop_uv_data; + GPUVertBuf *loop_stretch_angle; + GPUVertBuf *loop_stretch_area; + GPUVertBuf *facedots_uv; + GPUVertBuf *facedots_uv_data; /* Selection */ - GPUVertBuf *loop_pos; GPUVertBuf *loop_vert_idx; GPUVertBuf *loop_edge_idx; GPUVertBuf *loop_face_idx; GPUVertBuf *facedots_idx; } edit; - /* Edit UVs: - * We need different flags and vertex count form edit mesh. */ - struct { - GPUVertBuf *loop_stretch_angle; - GPUVertBuf *loop_stretch_area; - GPUVertBuf *loop_uv; - GPUVertBuf *loop_data; - GPUVertBuf *facedots_uv; - GPUVertBuf *facedots_data; - } edituv; - /* Index Buffers: * Only need to be updated when topology changes. */ struct { @@ -2045,15 +1794,14 @@ typedef struct MeshBatchCache { /* Indices to vloops. */ GPUIndexBuf *loops_tris; GPUIndexBuf *loops_lines; - /* Contains indices to unique edit vertices to not - * draw the same vert multiple times (because of tesselation). */ - GPUIndexBuf *edit_verts_points; - /* Edit mode selection. */ + /* Edit mode. */ GPUIndexBuf *edit_loops_points; /* verts */ GPUIndexBuf *edit_loops_lines; /* edges */ GPUIndexBuf *edit_loops_tris; /* faces */ /* Edit UVs */ - GPUIndexBuf *edituv_loops_lines; /* edges & faces */ + GPUIndexBuf *edituv_loops_points; /* verts */ + GPUIndexBuf *edituv_loops_lines; /* edges */ + GPUIndexBuf *edituv_loops_tri_fans; /* faces */ } ibo; struct { @@ -2063,11 +1811,8 @@ typedef struct MeshBatchCache { /* Edit mode */ GPUBatch *edit_triangles; GPUBatch *edit_vertices; - GPUBatch *edit_loose_edges; - GPUBatch *edit_loose_verts; - GPUBatch *edit_triangles_nor; - GPUBatch *edit_triangles_lnor; - GPUBatch *edit_loose_edges_nor; + GPUBatch *edit_edges; + GPUBatch *edit_lnor; GPUBatch *edit_facedots; /* Edit UVs */ GPUBatch *edituv_faces_strech_area; @@ -2245,12 +1990,15 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache) { - for (int i = 0; i < sizeof(cache->edituv) / sizeof(void *); ++i) { - GPUVertBuf **vbo = (GPUVertBuf **)&cache->edituv; - GPU_VERTBUF_DISCARD_SAFE(vbo[i]); - } - + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_angle); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_area); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv_data); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv_data); + GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans); GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines); + GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces); @@ -2270,15 +2018,11 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode) cache->is_maybe_dirty = true; break; case BKE_MESH_BATCH_DIRTY_SELECT: - GPU_VERTBUF_DISCARD_SAFE(cache->edit.data); - GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_ledges); - GPU_VERTBUF_DISCARD_SAFE(cache->edit.data_lverts); - GPU_VERTBUF_DISCARD_SAFE(cache->edit.pos_nor_data_facedots); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_data); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_pos_nor_data); GPU_BATCH_DISCARD_SAFE(cache->batch.edit_triangles); GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices); - GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_verts); - GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_edges); - GPU_BATCH_DISCARD_SAFE(cache->batch.edit_loose_edges_nor); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_edges); GPU_BATCH_DISCARD_SAFE(cache->batch.edit_facedots); /* Paint mode selection */ /* TODO only do that in paint mode. */ @@ -2307,8 +2051,8 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode) mesh_batch_cache_discard_uvedit(cache); break; case BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT: - GPU_VERTBUF_DISCARD_SAFE(cache->edituv.loop_data); - GPU_VERTBUF_DISCARD_SAFE(cache->edituv.facedots_data); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv_data); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv_data); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_area); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_strech_angle); GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces); @@ -2583,9 +2327,15 @@ BLI_INLINE void mesh_edit_add_select_index(GPUVertBufRaw *buf, GPUVertCompType c #define SELECT_COMP_FORMAT(el_len) (el_len > 0xFF ? (el_len > 0xFFFF ? GPU_COMP_U32 : GPU_COMP_U16) : GPU_COMP_U8) -static void mesh_create_edit_select_id( +static void mesh_create_edit_vertex_loops( MeshRenderData *rdata, - GPUVertBuf *vbo_pos, GPUVertBuf *vbo_verts, GPUVertBuf *vbo_edges, GPUVertBuf *vbo_faces) + GPUVertBuf *vbo_pos_nor, + GPUVertBuf *vbo_lnor, + GPUVertBuf *vbo_uv, + GPUVertBuf *vbo_data, + GPUVertBuf *vbo_verts, + GPUVertBuf *vbo_edges, + GPUVertBuf *vbo_faces) { const int vert_len = mesh_render_data_verts_len_get_maybe_mapped(rdata); const int edge_len = mesh_render_data_edges_len_get_maybe_mapped(rdata); @@ -2594,37 +2344,67 @@ static void mesh_create_edit_select_id( const int ledge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata); const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata); const int tot_loop_len = loop_len + ledge_len * 2 + lvert_len; + static struct { uint vert, edge, face, pos, nor, lnor, data, uvs; } attr_id; + float (*lnors)[3] = rdata->loop_normals; + uchar fflag; /* Choose the most compact vertex format. */ GPUVertCompType vert_comp = SELECT_COMP_FORMAT(vert_len); GPUVertCompType edge_comp = SELECT_COMP_FORMAT(edge_len); GPUVertCompType face_comp = SELECT_COMP_FORMAT(poly_len); - GPUVertFormat format_vert = { 0 }, format_edge = { 0 }, format_face = { 0 }, format_pos = { 0 }; - struct { uint vert, edge, face, pos; } attr_id; - attr_id.vert = GPU_vertformat_attr_add(&format_vert, "color", vert_comp, 1, GPU_FETCH_INT); - attr_id.edge = GPU_vertformat_attr_add(&format_edge, "color", edge_comp, 1, GPU_FETCH_INT); - attr_id.face = GPU_vertformat_attr_add(&format_face, "color", face_comp, 1, GPU_FETCH_INT); - attr_id.pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPUVertFormat format_vert_idx = { 0 }, format_edge_idx = { 0 }, format_face_idx = { 0 }; + attr_id.vert = GPU_vertformat_attr_add(&format_vert_idx, "color", vert_comp, 1, GPU_FETCH_INT); + attr_id.edge = GPU_vertformat_attr_add(&format_edge_idx, "color", edge_comp, 1, GPU_FETCH_INT); + attr_id.face = GPU_vertformat_attr_add(&format_face_idx, "color", face_comp, 1, GPU_FETCH_INT); + + /* Static formats */ + static GPUVertFormat format_pos_nor = { 0 }, format_lnor = { 0 }, format_flag = { 0 }, format_uv = { 0 }; + if (format_pos_nor.attr_len == 0) { + attr_id.pos = GPU_vertformat_attr_add(&format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format_pos_nor, "vnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.lnor = GPU_vertformat_attr_add(&format_lnor, "lnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.data = GPU_vertformat_attr_add(&format_flag, "data", GPU_COMP_U8, 4, GPU_FETCH_INT); + attr_id.uvs = GPU_vertformat_attr_add(&format_uv, "u", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_vertformat_alias_add(&format_uv, "pos"); + GPU_vertformat_alias_add(&format_flag, "flag"); + } - GPUVertBufRaw raw_verts, raw_edges, raw_faces, raw_pos; - if (DRW_TEST_ASSIGN_VBO(vbo_pos)) { - GPU_vertbuf_init_with_format(vbo_pos, &format_pos); - GPU_vertbuf_data_alloc(vbo_pos, tot_loop_len); - GPU_vertbuf_attr_get_raw_data(vbo_pos, attr_id.pos, &raw_pos); + GPUVertBufRaw raw_verts, raw_edges, raw_faces, raw_pos, raw_nor, raw_lnor, raw_uv, raw_data; + if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor)) { + GPU_vertbuf_init_with_format(vbo_pos_nor, &format_pos_nor); + GPU_vertbuf_data_alloc(vbo_pos_nor, tot_loop_len); + GPU_vertbuf_attr_get_raw_data(vbo_pos_nor, attr_id.pos, &raw_pos); + GPU_vertbuf_attr_get_raw_data(vbo_pos_nor, attr_id.nor, &raw_nor); + } + if (DRW_TEST_ASSIGN_VBO(vbo_lnor)) { + GPU_vertbuf_init_with_format(vbo_lnor, &format_lnor); + GPU_vertbuf_data_alloc(vbo_lnor, tot_loop_len); + GPU_vertbuf_attr_get_raw_data(vbo_lnor, attr_id.lnor, &raw_lnor); } + if (DRW_TEST_ASSIGN_VBO(vbo_data)) { + GPU_vertbuf_init_with_format(vbo_data, &format_flag); + GPU_vertbuf_data_alloc(vbo_data, tot_loop_len); + GPU_vertbuf_attr_get_raw_data(vbo_data, attr_id.data, &raw_data); + } + if (DRW_TEST_ASSIGN_VBO(vbo_uv)) { + GPU_vertbuf_init_with_format(vbo_uv, &format_uv); + GPU_vertbuf_data_alloc(vbo_uv, tot_loop_len); + GPU_vertbuf_attr_get_raw_data(vbo_uv, attr_id.uvs, &raw_uv); + } + /* Select Idx */ if (DRW_TEST_ASSIGN_VBO(vbo_verts)) { - GPU_vertbuf_init_with_format(vbo_verts, &format_vert); + GPU_vertbuf_init_with_format(vbo_verts, &format_vert_idx); GPU_vertbuf_data_alloc(vbo_verts, tot_loop_len); GPU_vertbuf_attr_get_raw_data(vbo_verts, attr_id.vert, &raw_verts); } if (DRW_TEST_ASSIGN_VBO(vbo_edges)) { - GPU_vertbuf_init_with_format(vbo_edges, &format_edge); + GPU_vertbuf_init_with_format(vbo_edges, &format_edge_idx); GPU_vertbuf_data_alloc(vbo_edges, tot_loop_len); GPU_vertbuf_attr_get_raw_data(vbo_edges, attr_id.edge, &raw_edges); } if (DRW_TEST_ASSIGN_VBO(vbo_faces)) { - GPU_vertbuf_init_with_format(vbo_faces, &format_face); + GPU_vertbuf_init_with_format(vbo_faces, &format_face_idx); GPU_vertbuf_data_alloc(vbo_faces, tot_loop_len); GPU_vertbuf_attr_get_raw_data(vbo_faces, attr_id.face, &raw_faces); } @@ -2636,14 +2416,37 @@ static void mesh_create_edit_select_id( BMEdge *eed; BMVert *eve; BMLoop *loop; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); /* Face Loops */ BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) { int fidx = BM_elem_index_get(efa); + if (vbo_data) { + fflag = mesh_render_data_face_flag(rdata, efa, cd_loop_uv_offset); + } BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) { - if (vbo_pos) { + if (vbo_pos_nor) { + GPUPackedNormal *vnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor); + *vnor = GPU_normal_convert_i10_v3(loop->v->no); copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), loop->v->co); } + if (vbo_lnor) { + const float *nor = (lnors) ? lnors[BM_elem_index_get(loop)] : efa->no; + GPUPackedNormal *lnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_lnor); + *lnor = GPU_normal_convert_i10_v3(nor); + } + if (vbo_data) { + EdgeDrawAttr eattr = { .v_flag = fflag }; + mesh_render_data_edge_flag(rdata, loop->e, &eattr); + mesh_render_data_vert_flag(rdata, loop->v, &eattr); + mesh_render_data_loop_flag(rdata, loop, cd_loop_uv_offset, &eattr); + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + if (vbo_uv) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, cd_loop_uv_offset); + copy_v2_v2(GPU_vertbuf_raw_step(&raw_uv), luv->uv); + } + /* Select Idx */ if (vbo_verts) { int vidx = BM_elem_index_get(loop->v); mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2661,9 +2464,18 @@ static void mesh_create_edit_select_id( for (int e = 0; e < ledge_len; e++) { eed = BM_edge_at_index(bm, rdata->loose_edges[e]); BM_ITER_ELEM (eve, &iter_vert, eed, BM_VERTS_OF_EDGE) { - if (vbo_pos) { + if (vbo_pos_nor) { + GPUPackedNormal *vnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor); + *vnor = GPU_normal_convert_i10_v3(eve->no); copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co); } + if (vbo_data) { + EdgeDrawAttr eattr = { 0 }; + mesh_render_data_edge_flag(rdata, eed, &eattr); + mesh_render_data_vert_flag(rdata, eve, &eattr); + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + /* Select Idx */ if (vbo_verts) { int vidx = BM_elem_index_get(eve); mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2677,9 +2489,17 @@ static void mesh_create_edit_select_id( /* Loose verts */ for (int e = 0; e < lvert_len; e++) { eve = BM_vert_at_index(bm, rdata->loose_verts[e]); - if (vbo_pos) { + if (vbo_pos_nor) { + GPUPackedNormal *vnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor); + *vnor = GPU_normal_convert_i10_v3(eve->no); copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), eve->co); } + if (vbo_data) { + EdgeDrawAttr eattr = { 0 }; + mesh_render_data_vert_flag(rdata, eve, &eattr); + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + /* Select Idx */ if (vbo_verts) { int vidx = BM_elem_index_get(eve); mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2687,6 +2507,9 @@ static void mesh_create_edit_select_id( } } else if (rdata->mapped.use == true) { + BMesh *bm = rdata->edit_bmesh->bm; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const MPoly *mpoly = rdata->mapped.me_cage->mpoly; const MEdge *medge = rdata->mapped.me_cage->medge; const MVert *mvert = rdata->mapped.me_cage->mvert; @@ -2700,10 +2523,56 @@ static void mesh_create_edit_select_id( for (int poly = 0; poly < poly_len; poly++, mpoly++) { const MLoop *l = &mloop[mpoly->loopstart]; int fidx = p_origindex[poly]; + BMFace *efa = NULL; + if (vbo_data) { + fflag = 0; + if (fidx != ORIGINDEX_NONE) { + efa = BM_face_at_index(bm, fidx); + fflag = mesh_render_data_face_flag(rdata, efa, cd_loop_uv_offset); + } + } for (int i = 0; i < mpoly->totloop; i++, l++) { - if (vbo_pos) { + if (vbo_pos_nor) { copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co); } + if (vbo_lnor || vbo_pos_nor) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[l->v].no); + if (vbo_pos_nor) { + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor) = vnor; + } + if (vbo_lnor) { + /* Mapped does not support lnors yet. */ + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_lnor) = vnor; + } + } + if (vbo_data) { + EdgeDrawAttr eattr = { .v_flag = fflag }; + int vidx = v_origindex[l->v]; + int eidx = e_origindex[l->e]; + if (vidx != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, vidx); + mesh_render_data_vert_flag(rdata, eve, &eattr); + } + if (eidx != ORIGINDEX_NONE) { + BMEdge *eed = BM_edge_at_index(bm, eidx); + mesh_render_data_edge_flag(rdata, eed, &eattr); + /* TODO find a more efficient way to do that. */ + BMLoop *loop; + BMIter iter_loop; + BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) { + if (loop->e == eed) { + mesh_render_data_loop_flag(rdata, loop, cd_loop_uv_offset, &eattr); + break; + } + } + } + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + if (vbo_uv) { + MLoopUV *luv = &rdata->mloopuv[mpoly->loopstart + i]; + copy_v2_v2(GPU_vertbuf_raw_step(&raw_uv), luv->uv); + } + /* Select Idx */ if (vbo_verts) { int vidx = v_origindex[l->v]; mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2722,9 +2591,26 @@ static void mesh_create_edit_select_id( const int e = rdata->mapped.loose_edges[j]; for (int i = 0; i < 2; ++i) { int v = (i == 0) ? medge[e].v1 : medge[e].v2; - if (vbo_pos) { + if (vbo_pos_nor) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[v].no); + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor) = vnor; copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[v].co); } + if (vbo_data) { + EdgeDrawAttr eattr = { 0 }; + int vidx = v_origindex[v]; + int eidx = e_origindex[e]; + if (vidx != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, vidx); + mesh_render_data_vert_flag(rdata, eve, &eattr); + } + if (eidx != ORIGINDEX_NONE) { + BMEdge *eed = BM_edge_at_index(bm, eidx); + mesh_render_data_edge_flag(rdata, eed, &eattr); + } + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + /* Select Idx */ if (vbo_verts) { int vidx = v_origindex[v]; mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2738,9 +2624,21 @@ static void mesh_create_edit_select_id( /* Loose verts */ for (int i = 0; i < lvert_len; i++) { const int v = rdata->mapped.loose_verts[i]; - if (vbo_pos) { + if (vbo_pos_nor) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[v].no); + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor) = vnor; copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[v].co); } + if (vbo_data) { + EdgeDrawAttr eattr = { 0 }; + int vidx = v_origindex[v]; + if (vidx != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, vidx); + mesh_render_data_vert_flag(rdata, eve, &eattr); + } + memcpy(GPU_vertbuf_raw_step(&raw_data), &eattr, sizeof(EdgeDrawAttr)); + } + /* Select Idx */ if (vbo_verts) { int vidx = v_origindex[v]; mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -2761,9 +2659,24 @@ static void mesh_create_edit_select_id( const MLoop *l = &mloop[mpoly->loopstart]; int fidx = p_origindex ? p_origindex[poly] : poly; for (int i = 0; i < mpoly->totloop; i++, l++) { - if (vbo_pos) { + if (vbo_pos_nor) { copy_v3_v3(GPU_vertbuf_raw_step(&raw_pos), mvert[l->v].co); } + if (vbo_lnor || vbo_pos_nor) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[l->v].no); + if (vbo_pos_nor) { + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_nor) = vnor; + } + if (vbo_lnor) { + /* Mapped does not support lnors yet. */ + *(GPUPackedNormal *)GPU_vertbuf_raw_step(&raw_lnor) = vnor; + } + } + if (vbo_uv) { + MLoopUV *luv = &rdata->mloopuv[mpoly->loopstart + i]; + copy_v2_v2(GPU_vertbuf_raw_step(&raw_uv), luv->uv); + } + /* Select Idx */ if (vbo_verts) { int vidx = v_origindex ? v_origindex[l->v] : l->v; mesh_edit_add_select_index(&raw_verts, vert_comp, vidx); @@ -3270,268 +3183,24 @@ static void mesh_create_loop_vcol(MeshRenderData *rdata, GPUVertBuf *vbo) #undef USE_COMP_MESH_DATA } -static GPUVertFormat *edit_mesh_pos_nor_format(uint *r_pos_id, uint *r_nor_id) -{ - static GPUVertFormat format_pos_nor = { 0 }; - static uint pos_id, nor_id; - if (format_pos_nor.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - nor_id = GPU_vertformat_attr_add(&format_pos_nor, "vnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - *r_pos_id = pos_id; - *r_nor_id = nor_id; - return &format_pos_nor; -} - -static GPUVertFormat *edit_mesh_lnor_format(uint *r_lnor_id) -{ - static GPUVertFormat format_lnor = { 0 }; - static uint lnor_id; - if (format_lnor.attr_len == 0) { - lnor_id = GPU_vertformat_attr_add(&format_lnor, "lnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - *r_lnor_id = lnor_id; - return &format_lnor; -} - -static GPUVertFormat *edit_mesh_data_format(uint *r_data_id) -{ - static GPUVertFormat format_flag = { 0 }; - static uint data_id; - if (format_flag.attr_len == 0) { - data_id = GPU_vertformat_attr_add(&format_flag, "data", GPU_COMP_U8, 4, GPU_FETCH_INT); - GPU_vertformat_triple_load(&format_flag); - } - *r_data_id = data_id; - return &format_flag; -} - -static GPUVertFormat *edit_mesh_facedot_format(uint *r_pos_id, uint *r_nor_flag_id) -{ - static GPUVertFormat format_facedots = { 0 }; - static uint pos_id, nor_flag_id; - if (format_facedots.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format_facedots, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - nor_flag_id = GPU_vertformat_attr_add(&format_facedots, "norAndFlag", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - } - *r_pos_id = pos_id; - *r_nor_flag_id = nor_flag_id; - return &format_facedots; -} - -static void mesh_create_edit_tris_and_verts( - MeshRenderData *rdata, - GPUVertBuf *vbo_data, GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_lnor, GPUIndexBuf *ibo_verts) -{ - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMVert *ev; - const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata); - int tri_len_used = 0; - int points_len = bm->totvert; - int verts_tri_len = tri_len * 3; - struct { uint pos, vnor, lnor, data; } attr_id; - GPUVertFormat *pos_nor_format = edit_mesh_pos_nor_format(&attr_id.pos, &attr_id.vnor); - GPUVertFormat *data_format = edit_mesh_data_format(&attr_id.data); - GPUVertFormat *lnor_format = edit_mesh_lnor_format(&attr_id.lnor); - - /* Positions & Vert Normals */ - if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor)) { - GPU_vertbuf_init_with_format(vbo_pos_nor, pos_nor_format); - GPU_vertbuf_data_alloc(vbo_pos_nor, verts_tri_len); - } - /* Overlay data */ - if (DRW_TEST_ASSIGN_VBO(vbo_data)) { - GPU_vertbuf_init_with_format(vbo_data, data_format); - GPU_vertbuf_data_alloc(vbo_data, verts_tri_len); - } - /* Loop Normals */ - if (DRW_TEST_ASSIGN_VBO(vbo_lnor)) { - GPU_vertbuf_init_with_format(vbo_lnor, lnor_format); - GPU_vertbuf_data_alloc(vbo_lnor, verts_tri_len); - } - /* Verts IBO */ - GPUIndexBufBuilder elb, *elbp = NULL; - if (DRW_TEST_ASSIGN_IBO(ibo_verts)) { - elbp = &elb; - GPU_indexbuf_init(elbp, GPU_PRIM_POINTS, points_len, verts_tri_len); - /* Clear tag */ - BM_ITER_MESH(ev, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_flag_disable(ev, BM_ELEM_TAG); - } - } - - if (rdata->mapped.use == false) { - for (int i = 0; i < tri_len; i++) { - const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; - if (!BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) { - add_edit_tri(rdata, vbo_pos_nor, vbo_lnor, vbo_data, elbp, - attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data, - bm_looptri, tri_len_used); - tri_len_used += 3; - } - } - } - else { - Mesh *me_cage = rdata->mapped.me_cage; - - /* TODO(fclem): Maybe move data generation to mesh_render_data_create() */ - const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage); - if (vbo_lnor && !CustomData_has_layer(&me_cage->pdata, CD_NORMAL)) { - BKE_mesh_ensure_normals_for_display(me_cage); - } - const float (*polynors)[3] = CustomData_get_layer(&me_cage->pdata, CD_NORMAL); - const float (*loopnors)[3] = CustomData_get_layer(&me_cage->ldata, CD_NORMAL); - - for (int i = 0; i < tri_len; i++) { - const MLoopTri *mlt = &mlooptri[i]; - const int p_orig = rdata->mapped.p_origindex[mlt->poly]; - if (p_orig != ORIGINDEX_NONE) { - BMFace *efa = BM_face_at_index(bm, p_orig); - if (add_edit_tri_mapped(rdata, vbo_pos_nor, vbo_lnor, vbo_data, elbp, - attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data, - efa, mlt, polynors, loopnors, tri_len_used)) - { - tri_len_used += 3; - } - } - } - } - - /* Resize & Finish */ - if (elbp != NULL) { - GPU_indexbuf_build_in_place(elbp, ibo_verts); - } - if (tri_len_used != verts_tri_len) { - if (vbo_pos_nor != NULL) { - GPU_vertbuf_data_resize(vbo_pos_nor, tri_len_used); - } - if (vbo_lnor != NULL) { - GPU_vertbuf_data_resize(vbo_lnor, tri_len_used); - } - if (vbo_data != NULL) { - GPU_vertbuf_data_resize(vbo_data, tri_len_used); - } - } -} - -static void mesh_create_edit_loose_edges( - MeshRenderData *rdata, - GPUVertBuf *vbo_data_ledges, GPUVertBuf *vbo_pos_nor_ledges) -{ - BMesh *bm = rdata->edit_bmesh->bm; - const int loose_edge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata); - const int verts_ledges_len = loose_edge_len * 2; - int ledges_len_used = 0; - - struct { uint pos, vnor, data; } attr_id; - GPUVertFormat *pos_nor_format = edit_mesh_pos_nor_format(&attr_id.pos, &attr_id.vnor); - GPUVertFormat *data_format = edit_mesh_data_format(&attr_id.data); - - /* Positions & Vert Normals */ - if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_ledges)) { - GPU_vertbuf_init_with_format(vbo_pos_nor_ledges, pos_nor_format); - GPU_vertbuf_data_alloc(vbo_pos_nor_ledges, verts_ledges_len); - } - /* Overlay data */ - if (DRW_TEST_ASSIGN_VBO(vbo_data_ledges)) { - GPU_vertbuf_init_with_format(vbo_data_ledges, data_format); - GPU_vertbuf_data_alloc(vbo_data_ledges, verts_ledges_len); - } - - if (rdata->mapped.use == false) { - for (uint i = 0; i < loose_edge_len; i++) { - const BMEdge *eed = BM_edge_at_index(bm, rdata->loose_edges[i]); - add_edit_loose_edge(rdata, vbo_pos_nor_ledges, vbo_data_ledges, - attr_id.pos, attr_id.vnor, attr_id.data, - eed, ledges_len_used); - ledges_len_used += 2; - } - } - else { - Mesh *me_cage = rdata->mapped.me_cage; - const MVert *mvert = me_cage->mvert; - const MEdge *medge = me_cage->medge; - const int *e_origindex = rdata->mapped.e_origindex; - - for (uint i_iter = 0; i_iter < loose_edge_len; i_iter++) { - const int i = rdata->mapped.loose_edges[i_iter]; - const int e_orig = e_origindex[i]; - BMEdge *eed = BM_edge_at_index(bm, e_orig); - add_edit_loose_edge_mapped(rdata, vbo_pos_nor_ledges, vbo_data_ledges, - attr_id.pos, attr_id.vnor, attr_id.data, - eed, mvert, &medge[i], ledges_len_used); - ledges_len_used += 2; - } - } - BLI_assert(ledges_len_used == verts_ledges_len); -} - -static void mesh_create_edit_loose_verts( - MeshRenderData *rdata, - GPUVertBuf *vbo_data_lverts, GPUVertBuf *vbo_pos_nor_lverts) -{ - BMesh *bm = rdata->edit_bmesh->bm; - const int loose_verts_len = mesh_render_data_loose_verts_len_get_maybe_mapped(rdata); - const int verts_lverts_len = loose_verts_len; - int lverts_len_used = 0; - - struct { uint pos, vnor, data; } attr_id; - GPUVertFormat *pos_nor_format = edit_mesh_pos_nor_format(&attr_id.pos, &attr_id.vnor); - GPUVertFormat *data_format = edit_mesh_data_format(&attr_id.data); - - /* Positions & Vert Normals */ - if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_lverts)) { - GPU_vertbuf_init_with_format(vbo_pos_nor_lverts, pos_nor_format); - GPU_vertbuf_data_alloc(vbo_pos_nor_lverts, verts_lverts_len); - } - /* Overlay data */ - if (DRW_TEST_ASSIGN_VBO(vbo_data_lverts)) { - GPU_vertbuf_init_with_format(vbo_data_lverts, data_format); - GPU_vertbuf_data_alloc(vbo_data_lverts, verts_lverts_len); - } - - if (rdata->mapped.use == false) { - for (uint i = 0; i < loose_verts_len; i++) { - BMVert *eve = BM_vert_at_index(bm, rdata->loose_verts[i]); - add_edit_loose_vert(rdata, vbo_pos_nor_lverts, vbo_data_lverts, - attr_id.pos, attr_id.vnor, attr_id.data, - eve, lverts_len_used); - lverts_len_used += 1; - } - } - else { - Mesh *me_cage = rdata->mapped.me_cage; - const MVert *mvert = me_cage->mvert; - const int *v_origindex = rdata->mapped.v_origindex; - - for (uint i_iter = 0; i_iter < loose_verts_len; i_iter++) { - const int i = rdata->mapped.loose_verts[i_iter]; - const int v_orig = v_origindex[i]; - BMVert *eve = BM_vert_at_index(bm, v_orig); - add_edit_loose_vert_mapped(rdata, vbo_pos_nor_lverts, vbo_data_lverts, - attr_id.pos, attr_id.vnor, attr_id.data, - eve, &mvert[i], lverts_len_used); - lverts_len_used += 1; - } - } - BLI_assert(lverts_len_used == verts_lverts_len); -} - static void mesh_create_edit_facedots( MeshRenderData *rdata, - GPUVertBuf *vbo_pos_nor_data_facedots) + GPUVertBuf *vbo_facedots_pos_nor_data) { const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata); const int verts_facedot_len = poly_len; int facedot_len_used = 0; - struct { uint fdot_pos, fdot_nor_flag; } attr_id; - GPUVertFormat *facedot_format = edit_mesh_facedot_format(&attr_id.fdot_pos, &attr_id.fdot_nor_flag); + static struct { uint fdot_pos, fdot_nor_flag; } attr_id; + static GPUVertFormat facedot_format = { 0 }; + if (facedot_format.attr_len == 0) { + attr_id.fdot_pos = GPU_vertformat_attr_add(&facedot_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.fdot_nor_flag = GPU_vertformat_attr_add(&facedot_format, "norAndFlag", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + } - if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor_data_facedots)) { - GPU_vertbuf_init_with_format(vbo_pos_nor_data_facedots, facedot_format); - GPU_vertbuf_data_alloc(vbo_pos_nor_data_facedots, verts_facedot_len); + if (DRW_TEST_ASSIGN_VBO(vbo_facedots_pos_nor_data)) { + GPU_vertbuf_init_with_format(vbo_facedots_pos_nor_data, &facedot_format); + GPU_vertbuf_data_alloc(vbo_facedots_pos_nor_data, verts_facedot_len); /* TODO(fclem): Maybe move data generation to mesh_render_data_create() */ if (rdata->edit_bmesh) { if (rdata->edit_data && rdata->edit_data->vertexCos != NULL) { @@ -3543,7 +3212,7 @@ static void mesh_create_edit_facedots( if (rdata->mapped.use == false) { for (int i = 0; i < poly_len; i++) { - if (add_edit_facedot(rdata, vbo_pos_nor_data_facedots, + if (add_edit_facedot(rdata, vbo_facedots_pos_nor_data, attr_id.fdot_pos, attr_id.fdot_nor_flag, i, facedot_len_used)) { @@ -3560,7 +3229,7 @@ static void mesh_create_edit_facedots( const int *v_origindex = rdata->mapped.v_origindex; #endif for (int i = 0; i < poly_len; i++) { - if (add_edit_facedot_mapped(rdata, vbo_pos_nor_data_facedots, + if (add_edit_facedot_mapped(rdata, vbo_facedots_pos_nor_data, attr_id.fdot_pos, attr_id.fdot_nor_flag, i, facedot_len_used)) { @@ -3571,8 +3240,8 @@ static void mesh_create_edit_facedots( /* Resize & Finish */ if (facedot_len_used != verts_facedot_len) { - if (vbo_pos_nor_data_facedots != NULL) { - GPU_vertbuf_data_resize(vbo_pos_nor_data_facedots, facedot_len_used); + if (vbo_facedots_pos_nor_data != NULL) { + GPU_vertbuf_data_resize(vbo_facedots_pos_nor_data, facedot_len_used); } } } @@ -4446,54 +4115,6 @@ GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me) return DRW_batch_request(&cache->batch.wire_triangles); } -GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_triangles); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_vertices); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_loose_edges(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_loose_edges); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_loose_verts(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_loose_verts); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_triangles_nor(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_triangles_nor); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_triangles_lnor(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_triangles_lnor); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_loose_edges_nor(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_loose_edges_nor); -} - -GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me) -{ - MeshBatchCache *cache = mesh_batch_cache_get(me); - return DRW_batch_request(&cache->batch.edit_facedots); -} - GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count) @@ -4556,6 +4177,42 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Mesh *me) /** \} */ /* ---------------------------------------------------------------------- */ +/** \name Edit Mode API + * \{ */ + +GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_triangles); +} + +GPUBatch *DRW_mesh_batch_cache_get_edit_edges(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_edges); +} + +GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_vertices); +} + +GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_lnor); +} + +GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + return DRW_batch_request(&cache->batch.edit_facedots); +} + +/** \} */ + +/* ---------------------------------------------------------------------- */ /** \name Edit Mode selection API * \{ */ @@ -4712,53 +4369,26 @@ BLI_INLINE float edit_uv_get_loop_stretch_angle( } #endif -#define VERTEX_SELECT (1 << 0) -#define VERTEX_PINNED (1 << 1) -#define FACE_SELECT (1 << 2) -#define FACE_ACTIVE (1 << 3) -#define EDGE_SELECT (1 << 4) - -BLI_INLINE uchar edit_uv_get_face_flag(BMFace *efa, BMFace *efa_act, const int cd_loop_uv_offset, Scene *scene) -{ - uchar flag = 0; - flag |= uvedit_face_select_test(scene, efa, cd_loop_uv_offset) ? FACE_SELECT : 0; - flag |= (efa == efa_act) ? FACE_ACTIVE : 0; - return flag; -} - -BLI_INLINE uchar edit_uv_get_loop_flag(BMLoop *l, const int cd_loop_uv_offset, Scene *scene) -{ - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uchar flag = 0; - flag |= uvedit_uv_select_test(scene, l, cd_loop_uv_offset) ? VERTEX_SELECT : 0; - flag |= uvedit_edge_select_test(scene, l, cd_loop_uv_offset) ? EDGE_SELECT : 0; - flag |= (luv->flag & MLOOPUV_PINNED) ? VERTEX_PINNED : 0; - return flag; -} - static struct EditUVFormatIndex { - uint uvs, area, angle, uv_adj, flag, fdots_uvs, fdots_flag; + uint area, angle, uv_adj, flag, fdots_uvs, fdots_flag; } uv_attr_id = {0}; static void uvedit_fill_buffer_data( - Mesh *me, const ToolSettings *ts, - GPUVertBuf *vbo_pos, GPUVertBuf *vbo_data, GPUVertBuf *vbo_area, GPUVertBuf *vbo_angle, + MeshRenderData *rdata, + GPUVertBuf *vbo_area, GPUVertBuf *vbo_angle, GPUVertBuf *vbo_fdots_pos, GPUVertBuf *vbo_fdots_data, - GPUIndexBufBuilder *elb) + GPUIndexBufBuilder *elb_vert, + GPUIndexBufBuilder *elb_edge, + GPUIndexBufBuilder *elb_face) { - BMEditMesh *embm = me->edit_btmesh; - BMesh *bm = embm->bm; + BMesh *bm = rdata->edit_bmesh->bm; BMIter iter, liter; BMFace *efa; - BMLoop *l; - MLoopUV *luv; - uint vidx, fidx, i; + uint vidx, fidx, fdot_idx, i; + const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata); float (*faces_areas)[2] = NULL; float totarea = 0.0f, totuvarea = 0.0f; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - BMFace *efa_act = EDBM_uv_active_face_get(embm, false, false); /* will be set to NULL if hidden */ - /* Hack to avoid passing the scene here. */ - Scene scene = { .toolsettings = (ToolSettings *)ts }; BLI_buffer_declare_static(vec3f, vec3_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); BLI_buffer_declare_static(vec2f, vec2_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); @@ -4771,7 +4401,7 @@ static void uvedit_fill_buffer_data( fidx = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { /* Tag hidden faces */ - BM_elem_flag_set(efa, BM_ELEM_TAG, uvedit_face_visible_nolocal(&scene, efa)); + BM_elem_flag_set(efa, BM_ELEM_TAG, uvedit_face_visible_nolocal_ex(rdata->toolsettings, efa)); if (vbo_area && BM_elem_flag_test(efa, BM_ELEM_TAG)) { edit_uv_preprocess_stretch_area(efa, cd_loop_uv_offset, fidx++, @@ -4781,72 +4411,124 @@ static void uvedit_fill_buffer_data( vidx = 0; fidx = 0; - BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { - const int efa_len = efa->len; - float fdot[2] = {0.0f, 0.0f}; - float (*av)[3], (*auv)[2]; - ushort area_stretch; - /* Skip hidden faces. */ - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) { - continue; - } - - uchar face_flag = edit_uv_get_face_flag(efa, efa_act, cd_loop_uv_offset, &scene); - /* Face preprocess */ - if (vbo_area) { - area_stretch = edit_uv_get_stretch_area(faces_areas[fidx][0] / totarea, - faces_areas[fidx][1] / totuvarea) * 65534.0f; - } - if (vbo_angle) { - av = (float (*)[3])BLI_buffer_reinit_data(&vec3_buf, vec3f, efa_len); - auv = (float (*)[2])BLI_buffer_reinit_data(&vec2_buf, vec2f, efa_len); - edit_uv_preprocess_stretch_angle(auv, av, cd_loop_uv_offset, efa); - } - - BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + fdot_idx = 0; + if (rdata->mapped.use == false && rdata->edit_bmesh) { + BMLoop *l; + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + const bool face_visible = BM_elem_flag_test(efa, BM_ELEM_TAG); + const int efa_len = efa->len; + float fdot[2] = {0.0f, 0.0f}; + float (*av)[3], (*auv)[2]; + ushort area_stretch; + + /* Face preprocess */ if (vbo_area) { - GPU_vertbuf_attr_set(vbo_area, uv_attr_id.area, vidx, &area_stretch); + area_stretch = edit_uv_get_stretch_area(faces_areas[fidx][0] / totarea, + faces_areas[fidx][1] / totuvarea) * 65534.0f; } if (vbo_angle) { - int i_next = (i + 1) % efa_len; - short suv[4]; - /* Send uvs to the shader and let it compute the aspect corrected angle. */ - normal_float_to_short_v2(&suv[0], auv[i]); - normal_float_to_short_v2(&suv[2], auv[i_next]); - GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.uv_adj, vidx, suv); - /* Compute 3D angle here */ - short angle = 32767.0f * angle_normalized_v3v3(av[i], av[i_next]) / (float)M_PI; - GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.angle, vidx, &angle); - } - if (vbo_pos) { - GPU_vertbuf_attr_set(vbo_pos, uv_attr_id.uvs, vidx, luv->uv); + av = (float (*)[3])BLI_buffer_reinit_data(&vec3_buf, vec3f, efa_len); + auv = (float (*)[2])BLI_buffer_reinit_data(&vec2_buf, vec2f, efa_len); + edit_uv_preprocess_stretch_angle(auv, av, cd_loop_uv_offset, efa); } - if (vbo_data) { - uchar flag = face_flag | edit_uv_get_loop_flag(l, cd_loop_uv_offset, &scene); - GPU_vertbuf_attr_set(vbo_data, uv_attr_id.flag, vidx, &flag); + + /* Skip hidden faces. */ + if (elb_face && face_visible) { + for (i = 0; i < efa->len; ++i) { + GPU_indexbuf_add_generic_vert(elb_face, vidx + i); + GPU_indexbuf_add_generic_vert(elb_vert, vidx + i); + GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % efa->len); + } + } + + BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (vbo_area) { + GPU_vertbuf_attr_set(vbo_area, uv_attr_id.area, vidx, &area_stretch); + } + if (vbo_angle) { + int i_next = (i + 1) % efa_len; + short suv[4]; + /* Send uvs to the shader and let it compute the aspect corrected angle. */ + normal_float_to_short_v2(&suv[0], auv[i]); + normal_float_to_short_v2(&suv[2], auv[i_next]); + GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.uv_adj, vidx, suv); + /* Compute 3D angle here */ + short angle = 32767.0f * angle_normalized_v3v3(av[i], av[i_next]) / (float)M_PI; + GPU_vertbuf_attr_set(vbo_angle, uv_attr_id.angle, vidx, &angle); + } + if (vbo_fdots_pos) { + add_v2_v2(fdot, luv->uv); + } + vidx++; } - if (elb) { - GPU_indexbuf_add_generic_vert(elb, vidx); + + if (elb_face && face_visible) { + GPU_indexbuf_add_generic_vert(elb_face, vidx - efa->len); + GPU_indexbuf_add_primitive_restart(elb_face); + } + if (vbo_fdots_pos && face_visible) { + mul_v2_fl(fdot, 1.0f / (float)efa->len); + GPU_vertbuf_attr_set(vbo_fdots_pos, uv_attr_id.fdots_uvs, fdot_idx, fdot); } - if (vbo_fdots_pos) { - add_v2_v2(fdot, luv->uv); + if (vbo_fdots_data && face_visible) { + uchar face_flag = mesh_render_data_face_flag(rdata, efa, cd_loop_uv_offset); + GPU_vertbuf_attr_set(vbo_fdots_data, uv_attr_id.fdots_flag, fdot_idx, &face_flag); } - vidx++; + fdot_idx += face_visible ? 1 : 0; + fidx++; } + } + else { + const MPoly *mpoly = rdata->mapped.me_cage->mpoly; + // const MEdge *medge = rdata->mapped.me_cage->medge; + // const MVert *mvert = rdata->mapped.me_cage->mvert; + const MLoop *mloop = rdata->mapped.me_cage->mloop; - if (elb) { - GPU_indexbuf_add_generic_vert(elb, vidx - efa->len); - GPU_indexbuf_add_primitive_restart(elb); - } - if (vbo_fdots_pos) { - mul_v2_fl(fdot, 1.0f / (float)efa->len); - GPU_vertbuf_attr_set(vbo_fdots_pos, uv_attr_id.fdots_uvs, fidx, fdot); - } - if (vbo_fdots_data) { - GPU_vertbuf_attr_set(vbo_fdots_data, uv_attr_id.fdots_flag, fidx, &face_flag); + const int *v_origindex = rdata->mapped.v_origindex; + const int *e_origindex = rdata->mapped.e_origindex; + const int *p_origindex = rdata->mapped.p_origindex; + + /* Face Loops */ + for (int poly = 0; poly < poly_len; poly++, mpoly++) { + float fdot[2] = {0.0f, 0.0f}; + const MLoop *l = &mloop[mpoly->loopstart]; + int fidx_ori = p_origindex[poly]; + efa = (fidx_ori != ORIGINDEX_NONE) ? BM_face_at_index(bm, fidx_ori) : NULL; + const bool face_visible = efa != NULL && BM_elem_flag_test(efa, BM_ELEM_TAG); + if (efa && vbo_fdots_data) { + uchar face_flag = mesh_render_data_face_flag(rdata, efa, cd_loop_uv_offset); + GPU_vertbuf_attr_set(vbo_fdots_data, uv_attr_id.fdots_flag, fdot_idx, &face_flag); + } + /* Skip hidden faces. */ + if (elb_face && face_visible) { + for (i = 0; i < mpoly->totloop; ++i) { + GPU_indexbuf_add_generic_vert(elb_face, vidx + i); + if (e_origindex[l[i].e] != ORIGINDEX_NONE) { + GPU_indexbuf_add_line_verts(elb_edge, vidx + i, vidx + (i + 1) % mpoly->totloop); + } + if (v_origindex[l[i].v] != ORIGINDEX_NONE) { + GPU_indexbuf_add_generic_vert(elb_vert, vidx + i); + } + } + GPU_indexbuf_add_generic_vert(elb_face, vidx); + GPU_indexbuf_add_primitive_restart(elb_face); + } + for (i = 0; i < mpoly->totloop; i++, l++) { + /* TODO support stretch. */ + if (vbo_fdots_pos) { + MLoopUV *luv = &rdata->mloopuv[mpoly->loopstart + i]; + add_v2_v2(fdot, luv->uv); + } + vidx++; + } + if (vbo_fdots_pos && face_visible) { + mul_v2_fl(fdot, 1.0f / mpoly->totloop); + GPU_vertbuf_attr_set(vbo_fdots_pos, uv_attr_id.fdots_uvs, fdot_idx, fdot); + } + fidx++; + fdot_idx += face_visible ? 1 : 0; } - fidx++; } if (faces_areas) { @@ -4856,76 +4538,48 @@ static void uvedit_fill_buffer_data( BLI_buffer_free(&vec3_buf); BLI_buffer_free(&vec2_buf); - if (vidx < bm->totloop) { - if (vbo_area) { - GPU_vertbuf_data_resize(vbo_area, vidx); - } - if (vbo_angle) { - GPU_vertbuf_data_resize(vbo_angle, vidx); - } - if (vbo_pos) { - GPU_vertbuf_data_resize(vbo_pos, vidx); - } - if (vbo_data) { - GPU_vertbuf_data_resize(vbo_data, vidx); - } - } - if (fidx < bm->totface) { + if (fdot_idx < poly_len) { if (vbo_fdots_pos) { - GPU_vertbuf_data_resize(vbo_fdots_pos, fidx); + GPU_vertbuf_data_resize(vbo_fdots_pos, fdot_idx); } if (vbo_fdots_data) { - GPU_vertbuf_data_resize(vbo_fdots_data, fidx); + GPU_vertbuf_data_resize(vbo_fdots_data, fdot_idx); } } } static void mesh_create_uvedit_buffers( - Mesh *me, const ToolSettings *ts, - GPUVertBuf *vbo_pos, GPUVertBuf *vbo_data, GPUVertBuf *vbo_area, GPUVertBuf *vbo_angle, - GPUVertBuf *vbo_fdots_pos, GPUVertBuf *vbo_fdots_data, GPUIndexBuf *ibo_face) + MeshRenderData *rdata, + GPUVertBuf *vbo_area, GPUVertBuf *vbo_angle, + GPUVertBuf *vbo_fdots_pos, GPUVertBuf *vbo_fdots_data, + GPUIndexBuf *ibo_vert, GPUIndexBuf *ibo_edge, GPUIndexBuf *ibo_face) { - BMesh *bm = me->edit_btmesh->bm; - - static GPUVertFormat format_pos = { 0 }; static GPUVertFormat format_area = { 0 }; static GPUVertFormat format_angle = { 0 }; - static GPUVertFormat format_flag = { 0 }; static GPUVertFormat format_fdots_pos = { 0 }; static GPUVertFormat format_fdots_flag = { 0 }; - if (format_pos.attr_len == 0) { + if (format_area.attr_len == 0) { uv_attr_id.area = GPU_vertformat_attr_add(&format_area, "stretch", GPU_COMP_U16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); uv_attr_id.angle = GPU_vertformat_attr_add(&format_angle, "angle", GPU_COMP_I16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); uv_attr_id.uv_adj = GPU_vertformat_attr_add(&format_angle, "uv_adj", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - uv_attr_id.flag = GPU_vertformat_attr_add(&format_flag, "flag", GPU_COMP_U8, 1, GPU_FETCH_INT); - uv_attr_id.uvs = GPU_vertformat_attr_add(&format_pos, "u", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_vertformat_alias_add(&format_pos, "pos"); uv_attr_id.fdots_flag = GPU_vertformat_attr_add(&format_fdots_flag, "flag", GPU_COMP_U8, 1, GPU_FETCH_INT); uv_attr_id.fdots_uvs = GPU_vertformat_attr_add(&format_fdots_pos, "u", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_vertformat_alias_add(&format_fdots_pos, "pos"); } - const uint vert_len = bm->totloop; - const uint idx_len = bm->totloop + bm->totface * 2; - const uint face_len = bm->totface; + const int loop_len = mesh_render_data_loops_len_get_maybe_mapped(rdata); + const int face_len = mesh_render_data_polys_len_get_maybe_mapped(rdata); + const int idx_len = loop_len + face_len * 2; - if (DRW_TEST_ASSIGN_VBO(vbo_pos)) { - GPU_vertbuf_init_with_format(vbo_pos, &format_pos); - GPU_vertbuf_data_alloc(vbo_pos, vert_len); - } - if (DRW_TEST_ASSIGN_VBO(vbo_data)) { - GPU_vertbuf_init_with_format(vbo_data, &format_flag); - GPU_vertbuf_data_alloc(vbo_data, vert_len); - } if (DRW_TEST_ASSIGN_VBO(vbo_area)) { GPU_vertbuf_init_with_format(vbo_area, &format_area); - GPU_vertbuf_data_alloc(vbo_area, vert_len); + GPU_vertbuf_data_alloc(vbo_area, loop_len); } if (DRW_TEST_ASSIGN_VBO(vbo_angle)) { GPU_vertbuf_init_with_format(vbo_angle, &format_angle); - GPU_vertbuf_data_alloc(vbo_angle, vert_len); + GPU_vertbuf_data_alloc(vbo_angle, loop_len); } if (DRW_TEST_ASSIGN_VBO(vbo_fdots_pos)) { GPU_vertbuf_init_with_format(vbo_fdots_pos, &format_fdots_pos); @@ -4936,17 +4590,33 @@ static void mesh_create_uvedit_buffers( GPU_vertbuf_data_alloc(vbo_fdots_data, face_len); } - GPUIndexBufBuilder elb; + GPUIndexBufBuilder elb_vert, elb_edge, elb_face; + if (DRW_TEST_ASSIGN_IBO(ibo_vert)) { + GPU_indexbuf_init_ex(&elb_vert, GPU_PRIM_POINTS, loop_len, loop_len, false); + } + if (DRW_TEST_ASSIGN_IBO(ibo_edge)) { + GPU_indexbuf_init_ex(&elb_edge, GPU_PRIM_LINES, loop_len * 2, loop_len, false); + } if (DRW_TEST_ASSIGN_IBO(ibo_face)) { - GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, idx_len, vert_len, true); + GPU_indexbuf_init_ex(&elb_face, GPU_PRIM_TRI_FAN, idx_len, loop_len, true); + } + + uvedit_fill_buffer_data(rdata, + vbo_area, vbo_angle, vbo_fdots_pos, vbo_fdots_data, + ibo_vert ? &elb_vert : NULL, + ibo_edge ? &elb_edge : NULL, + ibo_face ? &elb_face : NULL); + + if (ibo_vert) { + GPU_indexbuf_build_in_place(&elb_vert, ibo_vert); } - uvedit_fill_buffer_data(me, ts, - vbo_pos, vbo_data, vbo_area, vbo_angle, vbo_fdots_pos, vbo_fdots_data, - ibo_face ? &elb : NULL); + if (ibo_edge) { + GPU_indexbuf_build_in_place(&elb_edge, ibo_edge); + } if (ibo_face) { - GPU_indexbuf_build_in_place(&elb, ibo_face); + GPU_indexbuf_build_in_place(&elb_face, ibo_face); } } @@ -5016,11 +4686,14 @@ void DRW_mesh_batch_cache_create_requested( const bool is_uvsyncsel = (ts->uv_flag & UV_SYNC_SELECTION); if (cache->is_uvsyncsel != is_uvsyncsel) { cache->is_uvsyncsel = is_uvsyncsel; - for (int i = 0; i < sizeof(cache->edituv) / sizeof(void *); ++i) { - GPUVertBuf **vbo = (GPUVertBuf **)&cache->edituv; - GPU_VERTBUF_DISCARD_SAFE(vbo[i]); - } + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv_data); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_angle); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_stretch_area); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.loop_uv); + GPU_VERTBUF_DISCARD_SAFE(cache->edit.facedots_uv); + GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_tri_fans); GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_lines); + GPU_INDEXBUF_DISCARD_SAFE(cache->ibo.edituv_loops_points); /* We only clear the batches as they may already have been referenced. */ GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_area); GPU_BATCH_CLEAR_SAFE(cache->batch.edituv_faces_strech_angle); @@ -5081,93 +4754,82 @@ void DRW_mesh_batch_cache_create_requested( /* Edit Mesh */ if (DRW_batch_requested(cache->batch.edit_triangles, GPU_PRIM_TRIS)) { - DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.pos_nor); - DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.data); + DRW_ibo_request(cache->batch.edit_triangles, &cache->ibo.edit_loops_tris); + DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_pos_nor); + DRW_vbo_request(cache->batch.edit_triangles, &cache->edit.loop_data); } if (DRW_batch_requested(cache->batch.edit_vertices, GPU_PRIM_POINTS)) { - DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_verts_points); - DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.pos_nor); - DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.data); - } - if (DRW_batch_requested(cache->batch.edit_loose_edges, GPU_PRIM_LINES)) { - DRW_vbo_request(cache->batch.edit_loose_edges, &cache->edit.pos_nor_ledges); - DRW_vbo_request(cache->batch.edit_loose_edges, &cache->edit.data_ledges); + DRW_ibo_request(cache->batch.edit_vertices, &cache->ibo.edit_loops_points); + DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_pos_nor); + DRW_vbo_request(cache->batch.edit_vertices, &cache->edit.loop_data); } - if (DRW_batch_requested(cache->batch.edit_loose_verts, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edit_loose_verts, &cache->edit.pos_nor_lverts); - DRW_vbo_request(cache->batch.edit_loose_verts, &cache->edit.data_lverts); + if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) { + DRW_ibo_request(cache->batch.edit_edges, &cache->ibo.edit_loops_lines); + DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_pos_nor); + DRW_vbo_request(cache->batch.edit_edges, &cache->edit.loop_data); } - if (DRW_batch_requested(cache->batch.edit_triangles_nor, GPU_PRIM_POINTS)) { - DRW_ibo_request(cache->batch.edit_triangles_nor, &cache->ibo.edit_verts_points); - DRW_vbo_request(cache->batch.edit_triangles_nor, &cache->edit.pos_nor); - } - if (DRW_batch_requested(cache->batch.edit_triangles_lnor, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edit_triangles_lnor, &cache->edit.pos_nor); - DRW_vbo_request(cache->batch.edit_triangles_lnor, &cache->edit.lnor); - } - if (DRW_batch_requested(cache->batch.edit_loose_edges_nor, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edit_loose_edges_nor, &cache->edit.pos_nor_ledges); - DRW_vbo_request(cache->batch.edit_loose_edges_nor, &cache->edit.data_ledges); + if (DRW_batch_requested(cache->batch.edit_lnor, GPU_PRIM_POINTS)) { + /* TODO use a range of loops line, before drawing the loose edges. */ + DRW_ibo_request(cache->batch.edit_lnor, &cache->ibo.edit_loops_lines); + DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_pos_nor); + DRW_vbo_request(cache->batch.edit_lnor, &cache->edit.loop_lnor); } if (DRW_batch_requested(cache->batch.edit_facedots, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.pos_nor_data_facedots); - } - if (DRW_batch_requested(cache->batch.edit_triangles_nor, GPU_PRIM_POINTS)) { - DRW_ibo_request(cache->batch.edit_triangles_nor, &cache->ibo.edit_verts_points); - DRW_vbo_request(cache->batch.edit_triangles_nor, &cache->edit.pos_nor); + DRW_vbo_request(cache->batch.edit_facedots, &cache->edit.facedots_pos_nor_data); } /* Edit UV */ if (DRW_batch_requested(cache->batch.edituv_faces, GPU_PRIM_TRI_FAN)) { - DRW_ibo_request(cache->batch.edituv_faces, &cache->ibo.edituv_loops_lines); /* reuse linestrip as fan */ - DRW_vbo_request(cache->batch.edituv_faces, &cache->edituv.loop_uv); - DRW_vbo_request(cache->batch.edituv_faces, &cache->edituv.loop_data); + DRW_ibo_request(cache->batch.edituv_faces, &cache->ibo.edituv_loops_tri_fans); + DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv); + DRW_vbo_request(cache->batch.edituv_faces, &cache->edit.loop_uv_data); } if (DRW_batch_requested(cache->batch.edituv_faces_strech_area, GPU_PRIM_TRI_FAN)) { - DRW_ibo_request(cache->batch.edituv_faces_strech_area, &cache->ibo.edituv_loops_lines); /* reuse linestrip as fan */ - DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edituv.loop_uv); - DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edituv.loop_data); - DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edituv.loop_stretch_area); + DRW_ibo_request(cache->batch.edituv_faces_strech_area, &cache->ibo.edituv_loops_tri_fans); + DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv); + DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_uv_data); + DRW_vbo_request(cache->batch.edituv_faces_strech_area, &cache->edit.loop_stretch_area); } if (DRW_batch_requested(cache->batch.edituv_faces_strech_angle, GPU_PRIM_TRI_FAN)) { - DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &cache->ibo.edituv_loops_lines); /* reuse linestrip as fan */ - DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edituv.loop_uv); - DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edituv.loop_data); - DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edituv.loop_stretch_angle); + DRW_ibo_request(cache->batch.edituv_faces_strech_angle, &cache->ibo.edituv_loops_tri_fans); + DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv); + DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_uv_data); + DRW_vbo_request(cache->batch.edituv_faces_strech_angle, &cache->edit.loop_stretch_angle); } - if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINE_STRIP)) { + if (DRW_batch_requested(cache->batch.edituv_edges, GPU_PRIM_LINES)) { DRW_ibo_request(cache->batch.edituv_edges, &cache->ibo.edituv_loops_lines); - DRW_vbo_request(cache->batch.edituv_edges, &cache->edituv.loop_uv); - DRW_vbo_request(cache->batch.edituv_edges, &cache->edituv.loop_data); + DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv); + DRW_vbo_request(cache->batch.edituv_edges, &cache->edit.loop_uv_data); } if (DRW_batch_requested(cache->batch.edituv_verts, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edituv_verts, &cache->edituv.loop_uv); - DRW_vbo_request(cache->batch.edituv_verts, &cache->edituv.loop_data); + DRW_ibo_request(cache->batch.edituv_verts, &cache->ibo.edituv_loops_points); + DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv); + DRW_vbo_request(cache->batch.edituv_verts, &cache->edit.loop_uv_data); } if (DRW_batch_requested(cache->batch.edituv_facedots, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edituv_facedots, &cache->edituv.facedots_uv); - DRW_vbo_request(cache->batch.edituv_facedots, &cache->edituv.facedots_data); + DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv); + DRW_vbo_request(cache->batch.edituv_facedots, &cache->edit.facedots_uv_data); } /* Selection */ /* TODO reuse ordered.loop_pos_nor if possible. */ if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) { DRW_ibo_request(cache->batch.edit_selection_verts, &cache->ibo.edit_loops_points); - DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_pos); + DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_pos_nor); DRW_vbo_request(cache->batch.edit_selection_verts, &cache->edit.loop_vert_idx); } if (DRW_batch_requested(cache->batch.edit_selection_edges, GPU_PRIM_LINES)) { DRW_ibo_request(cache->batch.edit_selection_edges, &cache->ibo.edit_loops_lines); - DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_pos); + DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_pos_nor); DRW_vbo_request(cache->batch.edit_selection_edges, &cache->edit.loop_edge_idx); } if (DRW_batch_requested(cache->batch.edit_selection_faces, GPU_PRIM_TRIS)) { DRW_ibo_request(cache->batch.edit_selection_faces, &cache->ibo.edit_loops_tris); - DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_pos); + DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_pos_nor); DRW_vbo_request(cache->batch.edit_selection_faces, &cache->edit.loop_face_idx); } if (DRW_batch_requested(cache->batch.edit_selection_facedots, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.pos_nor_data_facedots); + DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_pos_nor_data); DRW_vbo_request(cache->batch.edit_selection_facedots, &cache->edit.facedots_idx); } @@ -5215,34 +4877,30 @@ void DRW_mesh_batch_cache_create_requested( DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->surf_per_mat_tris[i], MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI); } - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.data_ledges, MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.data_lverts, MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_ledges, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_lverts, MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.pos_nor_data_facedots, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.lnor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_OVERLAY); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_pos, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP); + int combined_edit_flag = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | + MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_OVERLAY; + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_pos_nor, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_lnor, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_data, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_uv_data, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_uv, combined_edit_flag | MR_DATATYPE_LOOPUV); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_vert_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_edge_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_face_idx, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP); DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_idx, MR_DATATYPE_POLY); - DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_verts_points, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_pos_nor_data, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_OVERLAY); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_angle, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.loop_stretch_area, combined_edit_flag); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv, combined_edit_flag | MR_DATATYPE_LOOPUV); + DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edit.facedots_uv_data, combined_edit_flag); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_points, combined_edit_flag); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_lines, combined_edit_flag); + DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_tri_fans, combined_edit_flag); /* TODO: Some of the flags here may not be needed. */ DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_points, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI); DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_lines, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI); DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edit_loops_tris, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_VERT | MR_DATATYPE_LOOSE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI); - /* Thoses read bmesh directly. */ - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.loop_stretch_angle, 0); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.loop_stretch_area, 0); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.loop_uv, 0); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.loop_data, 0); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.facedots_uv, 0); - DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_edit_flag, cache->edituv.facedots_data, 0); - DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_edit_flag, cache->ibo.edituv_loops_lines, 0); - Mesh *me_original = me; MBC_GET_FINAL_MESH(me); @@ -5253,7 +4911,7 @@ void DRW_mesh_batch_cache_create_requested( MeshRenderData *rdata = NULL; if (mr_flag != 0) { - rdata = mesh_render_data_create_ex(me, mr_flag, cache->cd_vused, cache->cd_lused); + rdata = mesh_render_data_create_ex(me, mr_flag, cache->cd_vused, cache->cd_lused, ts); } /* Generate VBOs */ @@ -5305,39 +4963,32 @@ void DRW_mesh_batch_cache_create_requested( if (rdata) { mesh_render_data_free(rdata); } - rdata = mesh_render_data_create(me_original, mr_edit_flag); + rdata = mesh_render_data_create_ex(me_original, mr_edit_flag, NULL, NULL, ts); } if (rdata && rdata->mapped.supported) { rdata->mapped.use = true; } - if (DRW_vbo_requested(cache->edit.data) || - DRW_vbo_requested(cache->edit.pos_nor) || - DRW_vbo_requested(cache->edit.lnor) || - DRW_ibo_requested(cache->ibo.edit_verts_points)) - { - mesh_create_edit_tris_and_verts( - rdata, - cache->edit.data, cache->edit.pos_nor, - cache->edit.lnor, cache->ibo.edit_verts_points); - } - if (DRW_vbo_requested(cache->edit.data_ledges) || DRW_vbo_requested(cache->edit.pos_nor_ledges)) { - mesh_create_edit_loose_edges(rdata, cache->edit.data_ledges, cache->edit.pos_nor_ledges); - } - if (DRW_vbo_requested(cache->edit.data_lverts) || DRW_vbo_requested(cache->edit.pos_nor_lverts)) { - mesh_create_edit_loose_verts(rdata, cache->edit.data_lverts, cache->edit.pos_nor_lverts); - } - if (DRW_vbo_requested(cache->edit.pos_nor_data_facedots)) { - mesh_create_edit_facedots(rdata, cache->edit.pos_nor_data_facedots); - } - if (DRW_vbo_requested(cache->edit.loop_pos) || + if (DRW_vbo_requested(cache->edit.loop_pos_nor) || + DRW_vbo_requested(cache->edit.loop_lnor) || + DRW_vbo_requested(cache->edit.loop_data) || DRW_vbo_requested(cache->edit.loop_vert_idx) || DRW_vbo_requested(cache->edit.loop_edge_idx) || DRW_vbo_requested(cache->edit.loop_face_idx)) { - mesh_create_edit_select_id(rdata, cache->edit.loop_pos, cache->edit.loop_vert_idx, - cache->edit.loop_edge_idx, cache->edit.loop_face_idx); + mesh_create_edit_vertex_loops( + rdata, + cache->edit.loop_pos_nor, + cache->edit.loop_lnor, + NULL, + cache->edit.loop_data, + cache->edit.loop_vert_idx, + cache->edit.loop_edge_idx, + cache->edit.loop_face_idx); + } + if (DRW_vbo_requested(cache->edit.facedots_pos_nor_data)) { + mesh_create_edit_facedots(rdata, cache->edit.facedots_pos_nor_data); } if (DRW_vbo_requested(cache->edit.facedots_idx)) { mesh_create_edit_facedots_select_id(rdata, cache->edit.facedots_idx); @@ -5351,19 +5002,43 @@ void DRW_mesh_batch_cache_create_requested( mesh_create_edit_loops_tris(rdata, cache->ibo.edit_loops_tris); } - if (DRW_vbo_requested(cache->edituv.loop_stretch_angle) || - DRW_vbo_requested(cache->edituv.loop_stretch_area) || - DRW_vbo_requested(cache->edituv.loop_uv) || - DRW_vbo_requested(cache->edituv.loop_data) || - DRW_vbo_requested(cache->edituv.facedots_uv) || - DRW_vbo_requested(cache->edituv.facedots_data) || - DRW_ibo_requested(cache->ibo.edituv_loops_lines)) + /* UV editor */ + /** + * TODO: The code and data structure is ready to support modified UV display + * but the selection code for UVs needs to support it first. So for now, only + * display the cage in all cases. + **/ + if (rdata && rdata->mapped.supported) { + rdata->mapped.use = false; + } + + if (DRW_vbo_requested(cache->edit.loop_uv_data) || + DRW_vbo_requested(cache->edit.loop_uv)) + { + mesh_create_edit_vertex_loops( + rdata, + NULL, + NULL, + cache->edit.loop_uv, + cache->edit.loop_uv_data, + NULL, + NULL, + NULL); + } + if (DRW_vbo_requested(cache->edit.loop_stretch_angle) || + DRW_vbo_requested(cache->edit.loop_stretch_area) || + DRW_vbo_requested(cache->edit.facedots_uv) || + DRW_vbo_requested(cache->edit.facedots_uv_data) || + DRW_ibo_requested(cache->ibo.edituv_loops_points) || + DRW_ibo_requested(cache->ibo.edituv_loops_lines) || + DRW_ibo_requested(cache->ibo.edituv_loops_tri_fans)) { - mesh_create_uvedit_buffers(me_original, ts, - cache->edituv.loop_uv, cache->edituv.loop_data, - cache->edituv.loop_stretch_area, cache->edituv.loop_stretch_angle, - cache->edituv.facedots_uv, cache->edituv.facedots_data, - cache->ibo.edituv_loops_lines); + mesh_create_uvedit_buffers(rdata, + cache->edit.loop_stretch_area, cache->edit.loop_stretch_angle, + cache->edit.facedots_uv, cache->edit.facedots_uv_data, + cache->ibo.edituv_loops_points, + cache->ibo.edituv_loops_lines, + cache->ibo.edituv_loops_tri_fans); } if (rdata) { diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index f76e0f4a18c..e981b305dfb 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -62,6 +62,7 @@ extern char datatoc_edit_normals_geom_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; +extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_flat_color_frag_glsl[]; extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; extern char datatoc_gpu_shader_depth_only_frag_glsl[]; @@ -103,12 +104,12 @@ typedef struct EDIT_MESH_Shaders { GPUShader *weight_face; /* Geometry */ - GPUShader *overlay_tri_cache[MAX_SHADERS]; - GPUShader *overlay_loose_edge_cache[MAX_SHADERS]; - GPUShader *overlay_vert; - GPUShader *overlay_lvert; + GPUShader *overlay_edge; + GPUShader *overlay_edge_flat; + GPUShader *overlay_face; GPUShader *overlay_facedot; + GPUShader *overlay_mix; GPUShader *overlay_facefill; GPUShader *normals_face; @@ -136,12 +137,10 @@ typedef struct EDIT_MESH_PrivateData { DRWShadingGroup *vnormals_shgrp; DRWShadingGroup *lnormals_shgrp; + DRWShadingGroup *vert_shgrp; + DRWShadingGroup *edge_shgrp; DRWShadingGroup *face_shgrp; DRWShadingGroup *face_cage_shgrp; - - DRWShadingGroup *verts_shgrp; - DRWShadingGroup *ledges_shgrp; - DRWShadingGroup *lverts_shgrp; DRWShadingGroup *facedot_shgrp; DRWShadingGroup *facefill_occluded_shgrp; @@ -157,91 +156,6 @@ typedef struct EDIT_MESH_PrivateData { /* *********** FUNCTIONS *********** */ -static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode) -{ - int result = tsettings->selectmode << 1; - if (supports_fast_mode) { - SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0); - } - return result; -} - -static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias, bool looseedge) -{ - const int selectmode = tsettings->selectmode; - const int fast_mode = rv3d->rflag & RV3D_NAVIGATING; - - char *str = NULL; - DynStr *ds = BLI_dynstr_new(); - - if (selectmode & SCE_SELECT_VERTEX) { - BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n"); - } - - if (selectmode & SCE_SELECT_EDGE) { - BLI_dynstr_append(ds, "#define EDGE_SELECTION\n"); - } - - if (selectmode & SCE_SELECT_FACE) { - BLI_dynstr_append(ds, "#define FACE_SELECTION\n"); - } - - if (!fast_mode || looseedge) { - BLI_dynstr_append(ds, "#define EDGE_FIX\n"); - } - - if (anti_alias) { - BLI_dynstr_append(ds, "#define ANTI_ALIASING\n"); - } - - if (!looseedge) { - BLI_dynstr_append(ds, "#define VERTEX_FACING\n"); - } - str = BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - return str; -} -static GPUShader *EDIT_MESH_ensure_shader( - EDIT_MESH_Shaders *sh_data, - ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode, bool looseedge) -{ - const int index = EDIT_MESH_sh_index(tsettings, rv3d, supports_fast_mode); - const bool fast_mode = (rv3d->rflag & RV3D_NAVIGATING) != 0; - const bool is_clip = (rv3d->rflag & RV3D_CLIPPING) != 0; - const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : ""; - const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : ""; - - if (looseedge) { - if (!sh_data->overlay_loose_edge_cache[index]) { - char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); - char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, true); - sh_data->overlay_loose_edge_cache[index] = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, - .geom = (const char *[]){lib, datatoc_edit_mesh_overlay_geom_edge_glsl, NULL}, - .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, defines, NULL}, - }); - MEM_freeN(lib); - MEM_freeN(defines); - } - return sh_data->overlay_loose_edge_cache[index]; - } - else { - if (!sh_data->overlay_tri_cache[index]) { - char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); - char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, false); - sh_data->overlay_tri_cache[index] = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, - .geom = fast_mode ? NULL : (const char *[]){lib, datatoc_edit_mesh_overlay_geom_tri_glsl, NULL}, - .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, defines, NULL}, - }); - MEM_freeN(lib); - MEM_freeN(defines); - } - return sh_data->overlay_tri_cache[index]; - } -} static void EDIT_MESH_engine_init(void *vedata) { @@ -277,90 +191,83 @@ static void EDIT_MESH_engine_init(void *vedata) .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->overlay_vert) { char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); + sh_data->overlay_face = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define FACE\n", NULL}, + }); + sh_data->overlay_edge = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", NULL}, + }); + sh_data->overlay_edge_flat = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_edit_mesh_overlay_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", "#define FLAT\n", NULL}, + }); sh_data->overlay_vert = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL}, + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define VERT\n", NULL}, }); - - sh_data->overlay_lvert = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL}, + sh_data->overlay_facedot = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define FACEDOT\n", NULL}, }); MEM_freeN(lib); - } - if (!sh_data->overlay_facedot) { - sh_data->overlay_facedot = DRW_shader_create_from_arrays({ - .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL}, - }); - } - if (!sh_data->overlay_mix) { + sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL); - } - if (!sh_data->overlay_facefill) { + sh_data->overlay_facefill = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL}, .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->normals_face) { + sh_data->normals_face = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, "#define FACE_NORMALS\n", NULL}, }); - } - if (!sh_data->normals_loop) { + sh_data->normals_loop = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, "#define LOOP_NORMALS\n", NULL}, }); - } - if (!sh_data->normals) { + sh_data->normals = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->depth) { + sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_slot); - } - if (!sh_data->ghost_clear_depth) { + sh_data->ghost_clear_depth = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL); } - } static DRWPass *edit_mesh_create_overlay_pass( - float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool xray, + float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool UNUSED(xray), DRWState statemod, - DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, - DRWShadingGroup **r_verts_shgrp, DRWShadingGroup **r_ledges_shgrp, - DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp) + DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, DRWShadingGroup **r_facedot_shgrp, + DRWShadingGroup **r_edge_shgrp, DRWShadingGroup **r_vert_shgrp) { - GPUShader *tri_sh, *ledge_sh; const DRWContextState *draw_ctx = DRW_context_state_get(); RegionView3D *rv3d = draw_ctx->rv3d; Scene *scene = draw_ctx->scene; ToolSettings *tsettings = scene->toolsettings; - const int fast_mode = rv3d->rflag & RV3D_NAVIGATING; EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot]; - - ledge_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, false, true); - tri_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, true, false); + const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0; + const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0; DRWPass *pass = DRW_pass_create( "Edit Mesh Face Overlay Pass", @@ -368,30 +275,14 @@ static DRWPass *edit_mesh_create_overlay_pass( DRWShadingGroup *grp; - if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { - grp = *r_lverts_shgrp = DRW_shgroup_create(sh_data->overlay_lvert, pass); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); - DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); - DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); - if (rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); - } - - grp = *r_verts_shgrp = DRW_shgroup_create(sh_data->overlay_vert, pass); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); - DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); - DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); - if (rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); - } - } - - if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) { - grp = *r_facedot_shgrp = DRW_shgroup_create(sh_data->overlay_facedot, pass); + /* TEST */ + GPUShader *vert_sh = sh_data->overlay_vert; + GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat; + GPUShader *face_sh = sh_data->overlay_face; + GPUShader *facedot_sh = sh_data->overlay_facedot; + /* Faces */ + if (select_face) { + grp = *r_facedot_shgrp = DRW_shgroup_create(facedot_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); @@ -400,20 +291,13 @@ static DRWPass *edit_mesh_create_overlay_pass( } } - grp = *r_face_shgrp = DRW_shgroup_create(tri_sh, pass); + grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1); DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges); - if (!fast_mode) { - DRW_shgroup_uniform_bool_copy(grp, "isXray", xray); - } - else { - /* To be able to use triple load. */ - DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION); - } if (rv3d->rflag & RV3D_CLIPPING) { DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); } @@ -422,16 +306,32 @@ static DRWPass *edit_mesh_create_overlay_pass( grp = *r_face_cage_shgrp = DRW_shgroup_create_sub(*r_face_shgrp); DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE); - grp = *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass); + /* Edges */ + grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1); DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges); + DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE); + /* To match blender loop structure. */ + DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION); if (rv3d->rflag & RV3D_CLIPPING) { DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); } + /* Verts */ + if (select_vert) { + grp = *r_vert_shgrp = DRW_shgroup_create(vert_sh, pass); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); + DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); + DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE | DRW_STATE_WRITE_DEPTH); + DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); + if (rv3d->rflag & RV3D_CLIPPING) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); + } + } return pass; } @@ -577,10 +477,9 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND, &stl->g_data->face_shgrp, &stl->g_data->face_cage_shgrp, - &stl->g_data->verts_shgrp, - &stl->g_data->ledges_shgrp, - &stl->g_data->lverts_shgrp, - &stl->g_data->facedot_shgrp); + &stl->g_data->facedot_shgrp, + &stl->g_data->edge_shgrp, + &stl->g_data->vert_shgrp); } else { /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */ @@ -589,10 +488,9 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH, &stl->g_data->face_shgrp, &stl->g_data->face_cage_shgrp, - &stl->g_data->verts_shgrp, - &stl->g_data->ledges_shgrp, - &stl->g_data->lverts_shgrp, - &stl->g_data->facedot_shgrp); + &stl->g_data->facedot_shgrp, + &stl->g_data->edge_shgrp, + &stl->g_data->vert_shgrp); /* however we loose the front faces value (because we need the depth of occluded wires and * faces are alpha blended ) so we recover them in a new pass. */ @@ -627,7 +525,7 @@ static void edit_mesh_add_ob_to_pass( DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp) { - struct GPUBatch *geom_tris, *geom_verts, *geom_ledges, *geom_ledges_nor, *geom_lverts, *geom_fcenter; + struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter; ToolSettings *tsettings = scene->toolsettings; bool has_edit_mesh_cage = false; @@ -639,30 +537,24 @@ static void edit_mesh_add_ob_to_pass( } DRWShadingGroup *face_shgrp = (has_edit_mesh_cage) ? g_data->face_cage_shgrp : g_data->face_shgrp; - DRWShadingGroup *verts_shgrp = g_data->verts_shgrp; - DRWShadingGroup *ledges_shgrp = g_data->ledges_shgrp; - DRWShadingGroup *lverts_shgrp = g_data->lverts_shgrp; + DRWShadingGroup *vert_shgrp = g_data->vert_shgrp; + DRWShadingGroup *edge_shgrp = g_data->edge_shgrp; geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data); - geom_ledges = DRW_mesh_batch_cache_get_edit_loose_edges(ob->data); + geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data); DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat); - DRW_shgroup_call_add(ledges_shgrp, geom_ledges, ob->obmat); + DRW_shgroup_call_add(edge_shgrp, geom_edges, ob->obmat); if (facefill_shgrp) { DRW_shgroup_call_add(facefill_shgrp, geom_tris, ob->obmat); } if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { - /* Thoses are point batches. */ geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data); - geom_ledges_nor = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data); - geom_lverts = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data); - DRW_shgroup_call_add(verts_shgrp, geom_verts, ob->obmat); - DRW_shgroup_call_add(lverts_shgrp, geom_ledges_nor, ob->obmat); - DRW_shgroup_call_add(lverts_shgrp, geom_lverts, ob->obmat); + DRW_shgroup_call_add(vert_shgrp, geom_verts, ob->obmat); } - if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) { + if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) { geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data); DRW_shgroup_call_add(facedot_shgrp, geom_fcenter, ob->obmat); } @@ -717,15 +609,11 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) } if (vnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_triangles_nor(ob->data); - DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); - geom = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data); - DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); - geom = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data); + geom = DRW_mesh_batch_cache_get_edit_vertices(ob->data); DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); } if (lnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_triangles_lnor(ob->data); + geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data); DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geom, ob->obmat); } if (fnormals_do) { diff --git a/source/blender/draw/modes/shaders/common_globals_lib.glsl b/source/blender/draw/modes/shaders/common_globals_lib.glsl index 7b0c48a76e5..1cb8a440469 100644 --- a/source/blender/draw/modes/shaders/common_globals_lib.glsl +++ b/source/blender/draw/modes/shaders/common_globals_lib.glsl @@ -81,3 +81,21 @@ layout(std140) uniform globalsBlock { float pad_globalsBlock; }; + +/* data[0] (1nd byte flags) */ +#define FACE_ACTIVE (1 << 0) +#define FACE_SELECTED (1 << 1) +#define FACE_FREESTYLE (1 << 2) +#define VERT_UV_SELECT (1 << 3) +#define VERT_UV_PINNED (1 << 4) +#define EDGE_UV_SELECT (1 << 5) +#define FACE_UV_ACTIVE (1 << 6) +#define FACE_UV_SELECT (1 << 7) +/* data[1] (2st byte flags) */ +#define VERT_ACTIVE (1 << 0) +#define VERT_SELECTED (1 << 1) +#define EDGE_ACTIVE (1 << 2) +#define EDGE_SELECTED (1 << 3) +#define EDGE_SEAM (1 << 4) +#define EDGE_SHARP (1 << 5) +#define EDGE_FREESTYLE (1 << 6) diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl index 24df1923a66..9000fd7247b 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl @@ -1,6 +1,4 @@ -#define VERTEX_ACTIVE 1 << 0 -#define VERTEX_SELECTED 1 << 1 /* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */ #define ACTIVE_NURB 1 << 2 #define EVEN_U_BIT 1 << 3 @@ -41,7 +39,7 @@ void main() return; } - bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERTEX_SELECTED) != 0); + bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERT_SELECTED) != 0); vec4 inner_color; if (color_id == 0) inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree; @@ -50,7 +48,7 @@ void main() else if (color_id == 3) inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign; else if (color_id == 4) inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp; else { - bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERTEX_SELECTED) != 0); + bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERT_SELECTED) != 0); bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0); if (is_u_segment) { inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline; diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl index 85e38ba3b43..eb0de41a320 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl @@ -9,13 +9,10 @@ in int data; out vec4 finalColor; -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) - void main() { - if ((data & VERTEX_SELECTED) != 0) { - if ((data & VERTEX_ACTIVE) != 0) { + if ((data & VERT_SELECTED) != 0) { + if ((data & VERT_ACTIVE) != 0) { finalColor = colorEditMeshActive; } else { diff --git a/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl index b2720704dcc..92caa4620d7 100644 --- a/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl @@ -1,19 +1,16 @@ flat in int vertFlag; -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) - out vec4 FragColor; void main() { /* TODO: vertex size */ - if ((vertFlag & VERTEX_SELECTED) != 0) { + if ((vertFlag & VERT_SELECTED) != 0) { FragColor = colorVertexSelect; } - else if ((vertFlag & VERTEX_ACTIVE) != 0) { + else if ((vertFlag & VERT_ACTIVE) != 0) { FragColor = colorEditMeshActive; } else { diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl index b37862f2037..59dcf602d43 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl @@ -1,24 +1,7 @@ -#define EDGE_EXISTS (1 << 0) -#define EDGE_ACTIVE (1 << 1) -#define EDGE_SELECTED (1 << 2) -#define EDGE_SEAM (1 << 3) -#define EDGE_SHARP (1 << 4) -#define EDGE_FREESTYLE (1 << 5) -#define EDGE_VERTEX_ACTIVE (1 << (0 + 8)) -#define EDGE_VERTEX_SELECTED (1 << (1 + 8)) -#define EDGE_VERTEX_EXISTS (1 << (2 + 8)) - -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) -#define VERTEX_EXISTS (1 << 2) - -#define FACE_ACTIVE (1 << 3) -#define FACE_SELECTED (1 << 4) -#define FACE_FREESTYLE (1 << 5) uniform bool doEdges = true; -vec4 EDIT_MESH_edge_color_outer(int edge_flag, bool face_active, float crease, float bweight) +vec4 EDIT_MESH_edge_color_outer(int edge_flag, int face_flag, float crease, float bweight) { vec4 color = vec4(0.0); color = ((edge_flag & EDGE_FREESTYLE) != 0) ? colorEdgeFreestyle : color; @@ -27,13 +10,13 @@ vec4 EDIT_MESH_edge_color_outer(int edge_flag, bool face_active, float crease, f color = (bweight > 0.0) ? vec4(colorEdgeBWeight.rgb, bweight) : color; color = ((edge_flag & EDGE_SEAM) != 0) ? colorEdgeSeam : color; - if (face_active) { + if ((face_flag & FACE_ACTIVE) != 0) { color = colorEditMeshActive; } return color; } -vec4 EDIT_MESH_edge_color_inner(int edge_flag, bool face_active) +vec4 EDIT_MESH_edge_color_inner(int edge_flag) { vec4 color = colorWireEdit; #ifdef EDGE_SELECTION @@ -45,9 +28,48 @@ vec4 EDIT_MESH_edge_color_inner(int edge_flag, bool face_active) return color; } -vec4 EDIT_MESH_vertex_color(int vertex_flag) +vec4 EDIT_MESH_edge_vertex_color(int vertex_flag) { vec4 color = colorWireEdit; - color = (doEdges && (vertex_flag & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0) ? colorEdgeSelect : color; + color = (doEdges && (vertex_flag & (VERT_ACTIVE | VERT_SELECTED)) != 0) ? colorEdgeSelect : color; return color; } + +vec4 EDIT_MESH_vertex_color(int vertex_flag) +{ + if ((vertex_flag & VERT_ACTIVE) != 0) { + return vec4(colorEditMeshActive.xyz, 1.0); + } + else if ((vertex_flag & VERT_SELECTED) != 0) { + return colorVertexSelect; + } + else { + return colorVertex; + } +} + +vec4 EDIT_MESH_face_color(int face_flag) +{ + if ((face_flag & FACE_ACTIVE) != 0) { + return colorFaceSelect; + } + else if ((face_flag & FACE_SELECTED) != 0) { + return colorFaceSelect; + } + else if ((face_flag & FACE_FREESTYLE) != 0) { + return colorFaceFreestyle; + } + else { + return colorFace; + } +} + +vec4 EDIT_MESH_facedot_color(float facedot_flag) +{ + if (facedot_flag != 0.0) { + return colorFaceDot; + } + else { + return colorVertex; + } +} diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl index bc46b3fe0f4..d6e1943980a 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl @@ -8,10 +8,6 @@ in ivec4 data; flat out vec4 faceColor; -#define FACE_ACTIVE (1 << 3) -#define FACE_SELECTED (1 << 4) -#define FACE_FREESTYLE (1 << 5) - void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl index c6cbd712d40..248d9de7aee 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl @@ -1,154 +1,36 @@ -/* Solid Wirefram implementation - * Mike Erwin, Clément Foucault */ - -uniform float faceAlphaMod; uniform float edgeScale; uniform bool isXray = false; -flat in vec3 edgesCrease; -flat in vec3 edgesBweight; -flat in vec4 faceColor; -flat in ivec3 flag; -#ifdef VERTEX_SELECTION -in vec3 vertexColor; -#endif +flat in vec4 finalColorStipple; +in float dist; +flat in float base_dist; -#ifdef EDGE_FIX -flat in vec2 ssPos[3]; +#ifdef FLAT +flat in vec4 finalColor; #else -in vec3 barycentric; -#endif - -#ifdef VERTEX_FACING -in float facing; +in vec4 finalColor; +# ifdef EDGE +flat in int selectOveride; +# endif #endif out vec4 FragColor; -/* Vertex flag is shifted and combined with the edge flag */ -#define FACE_ACTIVE_ (FACE_ACTIVE << 8) - -#define LARGE_EDGE_SIZE 2.15 - -/* Enough to visually fill gaps and not enough to mess the AA gradient too much. */ -#define EDGE_FIX_ALPHA 0.67 - -void distToEdgesAndPoints(out vec3 edges, out vec3 points) -{ -#ifdef EDGE_FIX - vec2 e0 = normalize(ssPos[1] - ssPos[0] + 1e-8); - vec2 e1 = normalize(ssPos[2] - ssPos[1] + 1e-8); - vec2 e2 = normalize(ssPos[0] - ssPos[2] + 1e-8); - e0 = vec2(-e0.y, e0.x); - e1 = vec2(-e1.y, e1.x); - e2 = vec2(-e2.y, e2.x); - vec2 p0 = gl_FragCoord.xy - ssPos[0]; - vec2 p1 = gl_FragCoord.xy - ssPos[1]; - vec2 p2 = gl_FragCoord.xy - ssPos[2]; - edges.z = abs(dot(e0, p0)); - edges.x = abs(dot(e1, p1)); - edges.y = abs(dot(e2, p2)); -#else - vec3 dx = dFdx(barycentric); - vec3 dy = dFdy(barycentric); - /* per component derivative */ - vec2 d0 = vec2(dx.x, dy.x); - vec2 d1 = vec2(dx.y, dy.y); - vec2 d2 = vec2(dx.z, dy.z); - vec3 d = vec3(length(d0), length(d1), length(d2)); - - edges = abs(vec3(barycentric / d)); -#endif - -#if defined(VERTEX_SELECTION) && defined(EDGE_FIX) - points.x = dot(p0, p0); - points.y = dot(p1, p1); - points.z = dot(p2, p2); - points = sqrt(points); -#else - points = vec3(1e10); -#endif -} - -void colorDist(vec4 color, float dist) -{ - FragColor = (dist < 0) ? color : FragColor; -} - -#ifdef ANTI_ALIASING -void colorDistEdge(vec4 color, float dist) -{ - FragColor.rgb *= FragColor.a; - FragColor = mix(color, FragColor, clamp(dist, 0.0, 1.0)); - FragColor.rgb /= max(1e-8, FragColor.a); -} -#else -#define colorDistEdge colorDist -#endif - void main() { - vec3 e, p; - distToEdgesAndPoints(e, p); - - /* Face */ - FragColor = faceColor; - FragColor.a *= faceAlphaMod; - - /* Edges */ - float sizeEdgeFinal = sizeEdge * edgeScale; - - for (int v = 0; v < 3; ++v) { - if ((flag[v] & EDGE_EXISTS) != 0) { - /* Outer large edge */ - float largeEdge = e[v] - sizeEdgeFinal * LARGE_EDGE_SIZE; - - vec4 large_edge_color = EDIT_MESH_edge_color_outer(flag[v], (flag[0] & FACE_ACTIVE_) != 0, edgesCrease[v], edgesBweight[v]); -#ifdef EDGE_FIX - large_edge_color *= isXray ? 1.0 : EDGE_FIX_ALPHA; -#endif - if (large_edge_color.a != 0.0) { - colorDistEdge(large_edge_color, largeEdge); - } - - /* Inner thin edge */ - float innerEdge = e[v] - sizeEdgeFinal; -#ifdef ANTI_ALIASING - innerEdge += 0.4; -#endif - -#ifdef VERTEX_SELECTION - vec4 inner_edge_color = vec4(vertexColor, 1.0); -#else - vec4 inner_edge_color = EDIT_MESH_edge_color_inner(flag[v], (flag[0] & FACE_ACTIVE_) != 0); -#endif -#ifdef EDGE_FIX - inner_edge_color *= isXray ? 1.0 : EDGE_FIX_ALPHA; -#endif - colorDistEdge(inner_edge_color, innerEdge); - } - } - -#if defined(VERTEX_SELECTION) && defined(EDGE_FIX) - /* Points */ - for (int v = 0; v < 3; ++v) { - if ((flag[v] & EDGE_VERTEX_EXISTS) != 0) { - float size = p[v] - sizeVertex; - vec4 point_color = colorVertex; - point_color = ((flag[v] & EDGE_VERTEX_SELECTED) != 0) ? colorVertexSelect : point_color; - point_color = ((flag[v] & EDGE_VERTEX_ACTIVE) != 0) ? vec4(colorEditMeshActive.xyz, 1.0) : point_color; - colorDist(point_color, size); - } + float dist_px = dist - base_dist; + dist_px /= fwidth(dist_px); + float mix_fac = step(0.5, fract(abs(dist_px) * (1.0 / 20.0))); + if (finalColorStipple.a == 0.0) { + mix_fac = 1.0; } +#if defined(EDGE) && !defined(FLAT) + vec4 prim_col = mix(colorEditMeshMiddle, colorEdgeSelect, finalColor.a); + prim_col = (selectOveride != 0) ? prim_col : finalColor; + prim_col.a = 1.0; +#else +# define prim_col finalColor #endif - -#ifdef VERTEX_FACING - FragColor.rgb = mix(colorEditMeshMiddle.rgb, FragColor.rgb, 1.0 - abs(facing) * 0.4); -#endif - - /* don't write depth if not opaque */ - if (FragColor.a == 0.0) { - discard; - } + FragColor = mix(finalColorStipple, prim_col, mix_fac); } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl index 8b9bcb33fae..2c906412ed2 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl @@ -1,115 +1,99 @@ -/* Solid Wirefram implementation - * Mike Erwin, Clément Foucault */ - uniform mat3 NormalMatrix; uniform mat4 ProjectionMatrix; uniform mat4 ModelViewMatrix; uniform mat4 ModelViewProjectionMatrix; uniform mat4 ModelMatrix; +uniform float faceAlphaMod; uniform ivec4 dataMask = ivec4(0xFF); +in ivec4 data; in vec3 pos; -#ifdef VERTEX_FACING +#ifndef FACEDOT in vec3 vnor; +#else +in vec4 norAndFlag; +# define vnor norAndFlag.xyz #endif -#ifdef EDGE_FIX -in ivec4 data; +#ifdef EDGE +flat out vec4 finalColorStipple; +flat out float base_dist; +out float dist; +#endif -out vec4 pPos; -out ivec4 vData; -# ifdef VERTEX_FACING -out float vFacing; +#ifdef FLAT +flat out vec4 finalColor; +#else +out vec4 finalColor; +# ifdef EDGE +flat out int selectOveride; # endif +#endif void main() { - pPos = ModelViewProjectionMatrix * vec4(pos, 1.0); - vData = data & dataMask; -# ifdef VERTEX_FACING - vec4 vpos = ModelViewMatrix * vec4(pos, 1.0); - vec3 view_normal = normalize(NormalMatrix * vnor); - vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) - ? normalize(vpos.xyz) - : vec3(0.0, 0.0, 1.0); - vFacing = dot(view_vec, view_normal); -# endif + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); -# ifdef USE_WORLD_CLIP_PLANES - world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); -# endif -} + ivec4 m_data = data & dataMask; -#else /* EDGE_FIX */ - -/* Consecutive data of the nth vertex. - * Only valid for first vertex in the triangle. - * Assuming GL_FRIST_VERTEX_CONVENTION. */ -in ivec4 data0; -in ivec4 data1; -in ivec4 data2; - -flat out vec3 edgesCrease; -flat out vec3 edgesBweight; -flat out vec4 faceColor; -flat out ivec3 flag; -# ifdef VERTEX_SELECTION -out vec3 vertexColor; -# endif -# ifdef VERTEX_FACING -out float facing; +#if defined(VERT) + finalColor = EDIT_MESH_vertex_color(m_data.y); + gl_PointSize = sizeVertex * 2.0; + gl_Position.z -= 3e-5 * ((ProjectionMatrix[3][3] == 0.0) ? 1.0 : 0.0); + /* Make selected and active vertex always on top. */ + if ((data.x & VERT_SELECTED) != 0) { + gl_Position.z -= 1e-7; + } + if ((data.x & VERT_ACTIVE) != 0) { + gl_Position.z -= 1e-7; + } + +#elif defined(EDGE) +# ifdef FLAT + finalColor = EDIT_MESH_edge_color_inner(m_data.y); +# else + finalColor = EDIT_MESH_edge_vertex_color(m_data.y); + selectOveride = (m_data.y & EDGE_SELECTED); # endif -out vec3 barycentric; + float crease = float(m_data.z) / 255.0; + float bweight = float(m_data.w) / 255.0; + finalColorStipple = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight); + base_dist = dist = float(gl_VertexID % 128); -void main() -{ - gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +#elif defined(FACE) + finalColor = EDIT_MESH_face_color(m_data.x); + finalColor.a *= faceAlphaMod; - int v_0 = (gl_VertexID / 3) * 3; - int vidx = gl_VertexID % 3; - barycentric = vec3(equal(ivec3(0, 1, 2), ivec3(vidx))); - - /* Edge */ - ivec4 vData[3] = ivec4[3](data0, data1, data2); - ivec3 eflag; - for (int v = 0; v < 3; ++v) { - vData[v] = vData[v] & dataMask; - flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8); - edgesCrease[v] = vData[v].z / 255.0; - edgesBweight[v] = vData[v].w / 255.0; - } +#elif defined(FACEDOT) + finalColor = EDIT_MESH_facedot_color(norAndFlag.w); + /* Bias Facedot Z position in clipspace. */ + gl_Position.z -= 0.00035; + gl_PointSize = sizeFaceDot; - /* Face */ - if ((vData[0].x & FACE_ACTIVE) != 0) { - faceColor = colorFaceSelect; - } - else if ((vData[0].x & FACE_SELECTED) != 0) { - faceColor = colorFaceSelect; - } - else if ((vData[0].x & FACE_FREESTYLE) != 0) { - faceColor = colorFaceFreestyle; - } - else { - faceColor = colorFace; - } +#endif -# ifdef VERTEX_SELECTION - vertexColor = EDIT_MESH_vertex_color(data0.x).rgb; -# endif -# ifdef VERTEX_FACING - vec4 vPos = ModelViewMatrix * vec4(pos, 1.0); +#ifndef FACE + vec4 vpos = ModelViewMatrix * vec4(pos, 1.0); vec3 view_normal = normalize(NormalMatrix * vnor); vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) - ? normalize(vPos.xyz) + ? normalize(vpos.xyz) : vec3(0.0, 0.0, 1.0); - facing = dot(view_vec, view_normal); -# endif + float facing = dot(view_vec, view_normal); + facing = 1.0 - abs(facing) * 0.3; -# ifdef USE_WORLD_CLIP_PLANES - world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); + finalColor = mix(colorEditMeshMiddle, finalColor, facing); + finalColor.a = 1.0; + +# if defined(EDGE) && !defined(FLAT) + /* Hack to blend color in pixel shader in case of overide. */ + finalColor.a = facing; # endif -} #endif + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); +#endif +} diff --git a/source/blender/draw/modes/shaders/paint_vert_frag.glsl b/source/blender/draw/modes/shaders/paint_vert_frag.glsl index 2e83362b90f..3042ddf9770 100644 --- a/source/blender/draw/modes/shaders/paint_vert_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_vert_frag.glsl @@ -2,15 +2,11 @@ flat in vec4 finalColor; out vec4 fragColor; -#define VERTEX_SELECTED (1 << 0) - void main() { vec2 centered = gl_PointCoord - vec2(0.5); float dist_squared = dot(centered, centered); const float rad_squared = 0.25; - const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0); - const vec4 colUnsel = vec4(0.0, 0.0, 0.0, 1.0); // round point with jaggy edges if (dist_squared > rad_squared) { diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl index 76e9c066103..0fddbddddc5 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_edges_vert.glsl @@ -12,17 +12,19 @@ noperspective out vec4 finalColor; flat out vec4 finalColor; #endif -#define VERTEX_SELECT (1 << 0) -#define EDGE_SELECT (1 << 4) +/* TODO: Port drawing to draw manager and + * remove constants duplications. */ +#define VERT_UV_SELECT (1 << 3) +#define EDGE_UV_SELECT (1 << 5) void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); #ifdef SMOOTH_COLOR - bool is_select = (flag & VERTEX_SELECT) != 0; + bool is_select = (flag & VERT_UV_SELECT) != 0; #else - bool is_select = (flag & EDGE_SELECT) != 0; + bool is_select = (flag & EDGE_UV_SELECT) != 0; #endif finalColor = (is_select) ? selectColor : edgeColor; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl index c5f84b976c5..e0d168e8095 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_facedots_vert.glsl @@ -8,10 +8,12 @@ in int flag; out vec4 finalColor; -#define FACE_SELECT (1 << 2) +/* TODO: Port drawing to draw manager and + * remove constants duplications. */ +#define FACE_UV_SELECT (1 << 7) void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); - finalColor = ((flag & FACE_SELECT) != 0) ? selectColor : vertColor; + finalColor = ((flag & FACE_UV_SELECT) != 0) ? selectColor : vertColor; } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl index 82c8d3f0c4a..1d25c8fe345 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_faces_vert.glsl @@ -9,15 +9,17 @@ in int flag; flat out vec4 finalColor; -#define FACE_SELECT (1 << 2) -#define FACE_ACTIVE (1 << 3) +/* TODO: Port drawing to draw manager and + * remove constants duplications. */ +#define FACE_UV_ACTIVE (1 << 6) +#define FACE_UV_SELECT (1 << 7) void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); - bool is_selected = (flag & FACE_SELECT) != 0; - bool is_active = (flag & FACE_ACTIVE) != 0; + bool is_selected = (flag & FACE_UV_SELECT) != 0; + bool is_active = (flag & FACE_UV_ACTIVE) != 0; finalColor = (is_selected) ? selectColor : faceColor; finalColor = (is_active) ? activeColor : finalColor; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl index 46dd1e066c8..50166bc4e95 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_points_vert.glsl @@ -13,16 +13,18 @@ out vec4 fillColor; out vec4 outlineColor; out vec4 radii; -#define VERTEX_SELECT (1 << 0) -#define VERTEX_PINNED (1 << 1) +/* TODO: Port drawing to draw manager and + * remove constants duplications. */ +#define VERT_UV_SELECT (1 << 3) +#define VERT_UV_PINNED (1 << 4) void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); gl_PointSize = pointSize; - bool is_selected = (flag & VERTEX_SELECT) != 0; - bool is_pinned = (flag & VERTEX_PINNED) != 0; + bool is_selected = (flag & VERT_UV_SELECT) != 0; + bool is_pinned = (flag & VERT_UV_PINNED) != 0; vec4 deselect_col = (is_pinned) ? pinnedColor : vertColor; fillColor = (is_selected) ? selectColor : deselect_col; |