diff options
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 16 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 9 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 1379 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_debug.c | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 31 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.h | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 46 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 14 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.c | 4 |
11 files changed, 1153 insertions, 365 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 193c2416215..17304dde802 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -325,6 +325,7 @@ struct GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribF } while (0) DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass); +DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup); DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass); DRWShadingGroup *DRW_shgroup_material_instance_create( struct GPUMaterial *material, DRWPass *pass, struct GPUBatch *geom, struct Object *ob, @@ -363,11 +364,12 @@ void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, uint point void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, uint line_count, float (*obmat)[4]); void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tria_count, float (*obmat)[4]); void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *shgroup, uint tria_count, struct Object *ob); -void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, bool bypass_culling); -#define DRW_shgroup_call_object_add(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, false) -#define DRW_shgroup_call_object_add_no_cull(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, true) +void DRW_shgroup_call_object_add_ex( + DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, struct Material *ma, bool bypass_culling); +#define DRW_shgroup_call_object_add(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, NULL, false) +#define DRW_shgroup_call_object_add_no_cull(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, NULL, true) void DRW_shgroup_call_object_add_with_callback( - DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, + DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, struct Material *ma, DRWCallVisibilityFn *callback, void *user_data); /* Used for drawing a batch with instancing without instance attribs. */ void DRW_shgroup_call_instances_add( @@ -507,11 +509,11 @@ DrawData *DRW_drawdata_ensure( DrawDataFreeCb free_cb); /* Settings */ -bool DRW_object_is_renderable(struct Object *ob); -bool DRW_check_object_visible_within_active_context(struct Object *ob); +bool DRW_object_is_renderable(const struct Object *ob); +bool DRW_object_is_visible_in_active_context(const struct Object *ob); bool DRW_object_is_flat_normal(const struct Object *ob); -bool DRW_check_psys_visible_within_active_context(struct Object *object, struct ParticleSystem *psys); +bool DRW_object_is_visible_psys_in_active_context(const struct Object *object, const struct ParticleSystem *psys); /* Draw commands */ void DRW_draw_pass(DRWPass *pass); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 9f0306f32a3..20ead73e0f5 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2986,7 +2986,8 @@ GPUBatch *DRW_cache_mesh_surface_overlay_get(Object *ob) void DRW_cache_mesh_wire_overlay_get( Object *ob, - GPUBatch **r_tris, GPUBatch **r_ledges, GPUBatch **r_lverts) + GPUBatch **r_tris, GPUBatch **r_ledges, GPUBatch **r_lverts, + struct GPUTexture **r_data_tex) { BLI_assert(ob->type == OB_MESH); @@ -2995,6 +2996,7 @@ void DRW_cache_mesh_wire_overlay_get( *r_tris = DRW_mesh_batch_cache_get_overlay_triangles(me); *r_ledges = DRW_mesh_batch_cache_get_overlay_loose_edges(me); *r_lverts = DRW_mesh_batch_cache_get_overlay_loose_verts(me); + *r_data_tex = DRW_mesh_batch_cache_get_overlay_data_tex(me); } void DRW_cache_mesh_normals_overlay_get( diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 5999dc25338..4860b438bb1 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -128,7 +128,8 @@ struct GPUBatch *DRW_cache_bone_dof_lines_get(void); struct GPUBatch *DRW_cache_mesh_surface_overlay_get(struct Object *ob); void DRW_cache_mesh_wire_overlay_get( struct Object *ob, - struct GPUBatch **r_tris, struct GPUBatch **r_ledges, struct GPUBatch **r_lverts); + struct GPUBatch **r_tris, struct GPUBatch **r_ledges, struct GPUBatch **r_lverts, + struct GPUTexture **r_data_tex); void DRW_cache_mesh_normals_overlay_get( struct Object *ob, struct GPUBatch **r_tris, struct GPUBatch **r_ledges, struct GPUBatch **r_lverts); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 1aaedd39c85..575670319d8 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -143,10 +143,12 @@ struct GPUBatch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me, bool *r_is_manifold); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles_nor(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_verts(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me); +struct GPUTexture *DRW_mesh_batch_cache_get_overlay_data_tex(struct Mesh *me); /* edit-mesh selection (use generic function for faces) */ struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset); struct GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset); @@ -178,9 +180,10 @@ void DRW_mesh_cache_uvedit( enum { VFLAG_VERTEX_ACTIVE = 1 << 0, VFLAG_VERTEX_SELECTED = 1 << 1, - VFLAG_FACE_ACTIVE = 1 << 2, - VFLAG_FACE_SELECTED = 1 << 3, - VFLAG_FACE_FREESTYLE = 1 << 4, + VFLAG_VERTEX_EXISTS = 1 << 2, + VFLAG_FACE_ACTIVE = 1 << 3, + VFLAG_FACE_SELECTED = 1 << 4, + VFLAG_FACE_FREESTYLE = 1 << 5, /* 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_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index b2ec0632db2..6013c8eef91 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -48,10 +48,13 @@ #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" #include "BKE_editmesh_tangent.h" #include "BKE_mesh.h" #include "BKE_mesh_tangent.h" +#include "BKE_mesh_runtime.h" #include "BKE_colorband.h" +#include "BKE_cdderivedmesh.h" #include "bmesh.h" @@ -142,13 +145,40 @@ typedef struct MeshRenderData { int loose_vert_len; int loose_edge_len; + /* Support for mapped mesh data. */ + struct { + /* Must be set if we want to get mapped data. */ + bool use; + bool supported; + + Mesh *me_cage; + + int vert_len; + int edge_len; + int tri_len; + int loop_len; + int poly_len; + + int *loose_verts; + int loose_vert_len; + + int *loose_edges; + int loose_edge_len; + + /* origindex layers */ + int *v_origindex; + int *e_origindex; + int *l_origindex; + int *p_origindex; + } mapped; + BMEditMesh *edit_bmesh; struct EditMeshData *edit_data; MVert *mvert; - MEdge *medge; - MLoop *mloop; - MPoly *mpoly; + const MEdge *medge; + const MLoop *mloop; + const MPoly *mpoly; float (*orco)[3]; /* vertex coordinates normalized to bounding box */ bool is_orco_allocated; MDeformVert *dvert; @@ -180,6 +210,10 @@ typedef struct MeshRenderData { int bweight; int *uv; int *vcol; +#ifdef WITH_FREESTYLE + int freestyle_edge; + int freestyle_face; +#endif } offset; struct { @@ -409,6 +443,36 @@ static MeshRenderData *mesh_render_data_create_ex( rdata->edit_bmesh = embm; rdata->edit_data = me->runtime.edit_data; + if (embm->mesh_eval_cage && (embm->mesh_eval_cage->runtime.is_original == false)) { + Mesh *me_cage = embm->mesh_eval_cage; + + rdata->mapped.me_cage = me_cage; + if (types & MR_DATATYPE_VERT) { + rdata->mapped.vert_len = me_cage->totvert; + } + if (types & MR_DATATYPE_EDGE) { + rdata->mapped.edge_len = me_cage->totedge; + } + if (types & MR_DATATYPE_LOOP) { + rdata->mapped.loop_len = me_cage->totloop; + } + if (types & MR_DATATYPE_POLY) { + rdata->mapped.poly_len = me_cage->totpoly; + } + if (types & MR_DATATYPE_LOOPTRI) { + rdata->mapped.tri_len = poly_to_tri_count(me_cage->totpoly, me_cage->totloop); + } + + rdata->mapped.v_origindex = CustomData_get_layer(&me_cage->vdata, CD_ORIGINDEX); + rdata->mapped.e_origindex = CustomData_get_layer(&me_cage->edata, CD_ORIGINDEX); + rdata->mapped.l_origindex = CustomData_get_layer(&me_cage->ldata, CD_ORIGINDEX); + rdata->mapped.p_origindex = CustomData_get_layer(&me_cage->pdata, CD_ORIGINDEX); + rdata->mapped.supported = ( + rdata->mapped.v_origindex && + rdata->mapped.e_origindex && + rdata->mapped.p_origindex); + } + int bm_ensure_types = 0; if (types & MR_DATATYPE_VERT) { rdata->vert_len = bm->totvert; @@ -419,17 +483,7 @@ static MeshRenderData *mesh_render_data_create_ex( bm_ensure_types |= BM_EDGE; } if (types & MR_DATATYPE_LOOPTRI) { - BKE_editmesh_tessface_calc(embm); - int tottri = embm->tottri; - rdata->mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * embm->tottri, __func__); - for (int index = 0; index < tottri ; index ++ ) { - BMLoop **bmtri = embm->looptris[index]; - MLoopTri *mtri = &rdata->mlooptri[index]; - mtri->tri[0] = BM_elem_index_get(bmtri[0]); - mtri->tri[1] = BM_elem_index_get(bmtri[1]); - mtri->tri[2] = BM_elem_index_get(bmtri[2]); - } - rdata->tri_len = tottri; + bm_ensure_types |= BM_LOOP; } if (types & MR_DATATYPE_LOOP) { int totloop = bm->totloop; @@ -453,6 +507,11 @@ static MeshRenderData *mesh_render_data_create_ex( rdata->eve_act = BM_mesh_active_vert_get(bm); rdata->cd.offset.crease = CustomData_get_offset(&bm->edata, CD_CREASE); rdata->cd.offset.bweight = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + +#ifdef WITH_FREESTYLE + rdata->cd.offset.freestyle_edge = CustomData_get_offset(&bm->edata, CD_FREESTYLE_EDGE); + rdata->cd.offset.freestyle_face = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE); +#endif } if (types & (MR_DATATYPE_DVERT)) { bm_ensure_types |= BM_VERT; @@ -463,13 +522,28 @@ static MeshRenderData *mesh_render_data_create_ex( BM_mesh_elem_index_ensure(bm, bm_ensure_types); BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP); + + if (types & MR_DATATYPE_LOOPTRI) { + /* Edit mode ensures this is valid, no need to calculate. */ + BLI_assert((bm->totloop == 0) || (embm->looptris != NULL)); + int tottri = embm->tottri; + MLoopTri *mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * embm->tottri, __func__); + for (int index = 0; index < tottri ; index ++ ) { + BMLoop **bmtri = embm->looptris[index]; + MLoopTri *mtri = &mlooptri[index]; + mtri->tri[0] = BM_elem_index_get(bmtri[0]); + mtri->tri[1] = BM_elem_index_get(bmtri[1]); + mtri->tri[2] = BM_elem_index_get(bmtri[2]); + } + rdata->mlooptri = mlooptri; + rdata->tri_len = tottri; + } + if (types & MR_DATATYPE_OVERLAY) { rdata->loose_vert_len = rdata->loose_edge_len = 0; - int *lverts = rdata->loose_verts = MEM_mallocN(rdata->vert_len * sizeof(int), "Loose Vert"); - int *ledges = rdata->loose_edges = MEM_mallocN(rdata->edge_len * sizeof(int), "Loose Edges"); - { + int *lverts = MEM_mallocN(rdata->vert_len * sizeof(int), __func__); BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); BMVert **vtable = bm->vtable; for (int i = 0; i < bm->totvert; i++) { @@ -481,9 +555,11 @@ static MeshRenderData *mesh_render_data_create_ex( } } } + rdata->loose_verts = MEM_reallocN(lverts, rdata->loose_vert_len * sizeof(int)); } { + int *ledges = MEM_mallocN(rdata->edge_len * sizeof(int), __func__); BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); BMEdge **etable = bm->etable; for (int i = 0; i < bm->totedge; i++) { @@ -495,10 +571,49 @@ static MeshRenderData *mesh_render_data_create_ex( } } } + rdata->loose_edges = MEM_reallocN(ledges, rdata->loose_edge_len * sizeof(int)); } - rdata->loose_verts = MEM_reallocN(rdata->loose_verts, rdata->loose_vert_len * sizeof(int)); - rdata->loose_edges = MEM_reallocN(rdata->loose_edges, rdata->loose_edge_len * sizeof(int)); + if (rdata->mapped.supported) { + Mesh *me_cage = embm->mesh_eval_cage; + rdata->mapped.loose_vert_len = rdata->mapped.loose_edge_len = 0; + + if (rdata->loose_vert_len) { + int *lverts = MEM_mallocN(me_cage->totvert * sizeof(int), __func__); + const int *v_origindex = rdata->mapped.v_origindex; + for (int i = 0; i < me_cage->totvert; i++) { + const int v_orig = v_origindex[i]; + if (v_orig != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, v_orig); + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + /* Loose vert */ + if (eve->e == NULL || !bm_vert_has_visible_edge(eve)) { + lverts[rdata->mapped.loose_vert_len++] = i; + } + } + } + } + rdata->mapped.loose_verts = MEM_reallocN(lverts, rdata->mapped.loose_vert_len * sizeof(int)); + } + + if (rdata->loose_edge_len) { + int *ledges = MEM_mallocN(me_cage->totedge * sizeof(int), __func__); + const int *e_origindex = rdata->mapped.e_origindex; + for (int i = 0; i < me_cage->totedge; i++) { + const int e_orig = e_origindex[i]; + if (e_orig != ORIGINDEX_NONE) { + BMEdge *eed = BM_edge_at_index(bm, e_orig); + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + /* Loose edge */ + if (eed->l == NULL || !bm_edge_has_visible_face(eed)) { + ledges[rdata->mapped.loose_edge_len++] = i; + } + } + } + } + rdata->mapped.loose_edges = MEM_reallocN(ledges, rdata->mapped.loose_edge_len * sizeof(int)); + } + } } } else { @@ -512,8 +627,9 @@ static MeshRenderData *mesh_render_data_create_ex( } if (types & MR_DATATYPE_LOOPTRI) { const int tri_len = rdata->tri_len = poly_to_tri_count(me->totpoly, me->totloop); - rdata->mlooptri = MEM_mallocN(sizeof(*rdata->mlooptri) * tri_len, __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, rdata->mlooptri); + MLoopTri *mlooptri = MEM_mallocN(sizeof(*mlooptri) * tri_len, __func__); + BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri); + rdata->mlooptri = mlooptri; } if (types & MR_DATATYPE_LOOP) { rdata->loop_len = me->totloop; @@ -856,6 +972,9 @@ static void mesh_render_data_free(MeshRenderData *rdata) MEM_SAFE_FREE(rdata->edge_select_bool); MEM_SAFE_FREE(rdata->vert_color); + MEM_SAFE_FREE(rdata->mapped.loose_verts); + MEM_SAFE_FREE(rdata->mapped.loose_edges); + CustomData_free(&rdata->cd.output.ldata, rdata->loop_len); MEM_freeN(rdata); @@ -909,30 +1028,55 @@ static int mesh_render_data_verts_len_get(const MeshRenderData *rdata) BLI_assert(rdata->types & MR_DATATYPE_VERT); return rdata->vert_len; } +static int mesh_render_data_verts_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_VERT); + return ((rdata->mapped.use == false) ? rdata->vert_len : rdata->mapped.vert_len); +} -static int mesh_render_data_loose_verts_len_get(const MeshRenderData *rdata) +static int UNUSED_FUNCTION(mesh_render_data_loose_verts_len_get)(const MeshRenderData *rdata) { BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); return rdata->loose_vert_len; } +static int mesh_render_data_loose_verts_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); + return ((rdata->mapped.use == false) ? rdata->loose_vert_len : rdata->mapped.loose_vert_len); +} static int mesh_render_data_edges_len_get(const MeshRenderData *rdata) { BLI_assert(rdata->types & MR_DATATYPE_EDGE); return rdata->edge_len; } +static int mesh_render_data_edges_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_EDGE); + return ((rdata->mapped.use == false) ? rdata->edge_len : rdata->mapped.edge_len); +} -static int mesh_render_data_loose_edges_len_get(const MeshRenderData *rdata) +static int UNUSED_FUNCTION(mesh_render_data_loose_edges_len_get)(const MeshRenderData *rdata) { BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); return rdata->loose_edge_len; } +static int mesh_render_data_loose_edges_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_OVERLAY); + return ((rdata->mapped.use == false) ? rdata->loose_edge_len : rdata->mapped.loose_edge_len); +} static int mesh_render_data_looptri_len_get(const MeshRenderData *rdata) { BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI); return rdata->tri_len; } +static int mesh_render_data_looptri_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI); + return ((rdata->mapped.use == false) ? rdata->tri_len : rdata->mapped.tri_len); +} static int mesh_render_data_mat_len_get(const MeshRenderData *rdata) { @@ -951,6 +1095,11 @@ static int mesh_render_data_polys_len_get(const MeshRenderData *rdata) BLI_assert(rdata->types & MR_DATATYPE_POLY); return rdata->poly_len; } +static int mesh_render_data_polys_len_get_maybe_mapped(const MeshRenderData *rdata) +{ + BLI_assert(rdata->types & MR_DATATYPE_POLY); + return ((rdata->mapped.use == false) ? rdata->poly_len : rdata->mapped.poly_len); +} /** \} */ @@ -972,8 +1121,17 @@ static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata) int i; pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__); - BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) { - pnors_pack[i] = GPU_normal_convert_i10_v3(efa->no); + if (rdata->edit_data && rdata->edit_data->vertexCos != NULL) { + BKE_editmesh_cache_ensure_poly_normals(rdata->edit_bmesh, rdata->edit_data); + const float (*pnors)[3] = rdata->edit_data->polyNos; + for (i = 0; i < bm->totface; i++) { + pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]); + } + } + else { + BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) { + pnors_pack[i] = GPU_normal_convert_i10_v3(efa->no); + } } } else { @@ -1177,11 +1335,11 @@ static void mesh_render_data_ensure_edge_select_bool(MeshRenderData *rdata, bool MEM_callocN(sizeof(*edge_select_bool) * rdata->edge_len, __func__); for (int i = 0; i < rdata->poly_len; i++) { - MPoly *poly = &rdata->mpoly[i]; + const MPoly *poly = &rdata->mpoly[i]; if (poly->flag & ME_FACE_SEL) { for (int j = 0; j < poly->totloop; j++) { - MLoop *loop = &rdata->mloop[poly->loopstart + j]; + const MLoop *loop = &rdata->mloop[poly->loopstart + j]; if (use_wire) { edge_select_bool[loop->e] = true; } @@ -1213,8 +1371,14 @@ static bool mesh_render_data_pnors_pcenter_select_get( if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return false; } - BM_face_calc_center_mean(efa, r_center); - copy_v3_v3(r_pnors, efa->no); + if (rdata->edit_data && rdata->edit_data->vertexCos) { + copy_v3_v3(r_center, rdata->edit_data->polyCos[poly]); + copy_v3_v3(r_pnors, rdata->edit_data->polyNos[poly]); + } + else { + BM_face_calc_center_mean(efa, r_center); + copy_v3_v3(r_pnors, efa->no); + } *r_selected = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? true : false; } else { @@ -1230,6 +1394,40 @@ static bool mesh_render_data_pnors_pcenter_select_get( return true; } +static bool mesh_render_data_pnors_pcenter_select_get_mapped( + MeshRenderData *rdata, const int poly, + float r_pnors[3], float r_center[3], bool *r_selected) +{ + BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); + const int *p_origindex = rdata->mapped.p_origindex; + const int p_orig = p_origindex[poly]; + if (p_orig == ORIGINDEX_NONE) { + return false; + } + BMEditMesh *em = rdata->edit_bmesh; + const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig); + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + return false; + } + + Mesh *me_cage = em->mesh_eval_cage; + const MVert *mvert = me_cage->mvert; +#if 0 + const MEdge *medge = me_cage->medge; +#endif + const MLoop *mloop = me_cage->mloop; + const MPoly *mpoly = me_cage->mpoly; + + const MPoly *mp = mpoly + poly; + const MLoop *ml = mloop + mp->loopstart; + + BKE_mesh_calc_poly_center(mp, ml, mvert, r_center); + BKE_mesh_calc_poly_normal(mp, ml, mvert, r_pnors); + + *r_selected = (BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0) ? true : false; + + return true; +} static bool mesh_render_data_edge_vcos_manifold_pnors( MeshRenderData *rdata, const int edge_index, @@ -1263,7 +1461,7 @@ static bool mesh_render_data_edge_vcos_manifold_pnors( } else { MVert *mvert = rdata->mvert; - MEdge *medge = rdata->medge; + const MEdge *medge = rdata->medge; EdgeAdjacentPolys *eap = rdata->edges_adjacent_polys; float (*pnors)[3] = rdata->poly_normals; @@ -1349,12 +1547,11 @@ static uchar mesh_render_data_looptri_flag(MeshRenderData *rdata, const BMFace * fflag |= VFLAG_FACE_SELECTED; #ifdef WITH_FREESTYLE - BMesh *bm = rdata->edit_bmesh->bm; - if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { - FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE); - - if (ffa->flag & FREESTYLE_FACE_MARK) + if (rdata->cd.offset.freestyle_face != -1) { + const FreestyleFace *ffa = BM_ELEM_CD_GET_VOID_P(efa, rdata->cd.offset.freestyle_face); + if (ffa->flag & FREESTYLE_FACE_MARK) { fflag |= VFLAG_FACE_FREESTYLE; + } } #endif @@ -1379,16 +1576,6 @@ static void mesh_render_data_edge_flag( if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) eattr->e_flag |= VFLAG_EDGE_SHARP; -#ifdef WITH_FREESTYLE - BMesh *bm = rdata->edit_bmesh->bm; - if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { - FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE); - - if (fed->flag & FREESTYLE_EDGE_MARK) - eattr->e_flag |= VFLAG_EDGE_FREESTYLE; - } -#endif - /* Use a byte for value range */ if (rdata->cd.offset.crease != -1) { float crease = BM_ELEM_CD_GET_FLOAT(eed, rdata->cd.offset.crease); @@ -1404,11 +1591,20 @@ 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); + if (fed->flag & FREESTYLE_EDGE_MARK) { + eattr->e_flag |= VFLAG_EDGE_FREESTYLE; + } + } +#endif } static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *eve) { - uchar vflag = 0; + uchar vflag = VFLAG_VERTEX_EXISTS; /* Current vertex */ if (eve == rdata->eve_act) @@ -1421,13 +1617,20 @@ static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *e } static void add_overlay_tri( - MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data, + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, 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) { uchar fflag; uchar vflag; + 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) { /* TODO(sybren): deduplicate this and all the other places it's pasted to in this file. */ if (rdata->edit_data && rdata->edit_data->vertexCos) { @@ -1457,18 +1660,109 @@ static void add_overlay_tri( if (vbo_data) { fflag = mesh_render_data_looptri_flag(rdata, bm_looptri[0]->f); - uint i_prev = 1, i = 2; - for (uint i_next = 0; i_next < 3; i_next++) { + 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}; - if (bm_looptri[i_next] == bm_looptri[i_prev]->prev) { + 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 void add_overlay_tri_mapped( + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, 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_normal[3], const int base_vert_idx) +{ + 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; +#if 0 + const MPoly *mpoly = me_cage->mpoly; +#endif - i_prev = i; - i = i_next; + const int *v_origindex = rdata->mapped.v_origindex; + const int *e_origindex = rdata->mapped.e_origindex; +#if 0 + const int *l_origindex = rdata->mapped.l_origindex; + const int *p_origindex = rdata->mapped.p_origindex; +#endif + + uchar fflag; + uchar vflag; + + 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) { + for (uint i = 0; i < 3; i++) { + const float *pos = mvert[mloop[mlt->tri[i]].v].co; + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); + } + } + + if (vbo_nor) { + /* TODO real loop normal */ + GPUPackedNormal lnor = GPU_normal_convert_i10_v3(poly_normal); + for (uint i = 0; i < 3; i++) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[mloop[mlt->tri[i]].v].no); + GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); + GPU_vertbuf_attr_set(vbo_nor, lnor_id, base_vert_idx + i, &lnor); + } + } + + if (vbo_data) { + 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); + vflag = mesh_render_data_vertex_flag(rdata, v); + } + else { + /* Importantly VFLAG_VERTEX_EXISTS is not set. */ + vflag = 0; + } + /* Opposite edge to the vertex at 'i'. */ + EdgeDrawAttr eattr = {0}; + 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); + } + } + eattr.v_flag = fflag | vflag; + GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); } } } @@ -1488,7 +1782,7 @@ static void add_overlay_loose_edge( } } else { - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; i++) { const float *pos = (&eed->v1)[i]->co; GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); } @@ -1496,7 +1790,7 @@ static void add_overlay_loose_edge( } if (vbo_nor) { - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; i++) { GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no); GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); } @@ -1505,12 +1799,42 @@ static void add_overlay_loose_edge( if (vbo_data) { EdgeDrawAttr eattr = {0}; mesh_render_data_edge_flag(rdata, eed, &eattr); - for (int i = 0; i < 2; ++i) { + 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); } } } +static void add_overlay_loose_edge_mapped( + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_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) { + /* 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, pos_id, base_vert_idx + i, pos); + } + } + + if (vbo_nor) { + for (int i = 0; i < 2; i++) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mvert[*(&ed->v1 + i)].no); + GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); + } + } + + 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); + } + } +} static void add_overlay_loose_vert( MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data, @@ -1541,6 +1865,27 @@ static void add_overlay_loose_vert( GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag); } } +static void add_overlay_loose_vert_mapped( + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_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) +{ + if (vbo_pos) { + const float *pos = mv->co; + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos); + } + + if (vbo_nor) { + GPUPackedNormal vnor = GPU_normal_convert_i10_s3(mv->no); + GPU_vertbuf_attr_set(vbo_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); + } +} /** \} */ @@ -1659,6 +2004,8 @@ typedef struct MeshBatchCache { GPUVertBuf *ed_tri_pos; GPUVertBuf *ed_tri_nor; /* LoopNor, VertNor */ GPUVertBuf *ed_tri_data; + GPUTexture *ed_tri_data_tx; + GPUIndexBuf *ed_tri_verts; GPUVertBuf *ed_ledge_pos; GPUVertBuf *ed_ledge_nor; /* VertNor */ @@ -1817,18 +2164,24 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) { GPU_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data); if (cache->shaded_triangles_in_order) { - for (int i = 0; i < cache->mat_len; ++i) { + for (int i = 0; i < cache->mat_len; i++) { GPU_INDEXBUF_DISCARD_SAFE(cache->shaded_triangles_in_order[i]); } } if (cache->shaded_triangles) { - for (int i = 0; i < cache->mat_len; ++i) { + for (int i = 0; i < cache->mat_len; i++) { GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); } } - + if (cache->texpaint_triangles) { + for (int i = 0; i < cache->mat_len; i++) { + /* They use shaded_triangles_in_order */ + GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); + } + } MEM_SAFE_FREE(cache->shaded_triangles_in_order); MEM_SAFE_FREE(cache->shaded_triangles); + MEM_SAFE_FREE(cache->texpaint_triangles); MEM_SAFE_FREE(cache->auto_layer_names); MEM_SAFE_FREE(cache->auto_layer_is_srgb); @@ -1882,11 +2235,15 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode) GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */ GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos); GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos); + GPU_INDEXBUF_DISCARD_SAFE(cache->ed_tri_verts); + DRW_TEXTURE_FREE_SAFE(cache->ed_tri_data_tx); GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles); GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); GPU_BATCH_DISCARD_SAFE(cache->overlay_facedots); + GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor); /* Edit mode selection. */ GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id); GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id); @@ -1937,13 +2294,13 @@ static void mesh_batch_cache_clear_selective(Mesh *me, GPUVertBuf *vert) GPU_BATCH_DISCARD_SAFE(cache->points_with_normals); GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals); if (cache->shaded_triangles) { - for (int i = 0; i < cache->mat_len; ++i) { + for (int i = 0; i < cache->mat_len; i++) { GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); } } MEM_SAFE_FREE(cache->shaded_triangles); if (cache->texpaint_triangles) { - for (int i = 0; i < cache->mat_len; ++i) { + for (int i = 0; i < cache->mat_len; i++) { GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); } } @@ -1983,11 +2340,13 @@ static void mesh_batch_cache_clear(Mesh *me) GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos); GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor); GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data); + GPU_INDEXBUF_DISCARD_SAFE(cache->ed_tri_verts); GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles); GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor); GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor); + DRW_TEXTURE_FREE_SAFE(cache->ed_tri_data_tx); GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces); GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts); @@ -2023,7 +2382,7 @@ static void mesh_batch_cache_clear(Mesh *me) mesh_batch_cache_discard_uvedit(cache); if (cache->texpaint_triangles) { - for (int i = 0; i < cache->mat_len; ++i) { + for (int i = 0; i < cache->mat_len; i++) { GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); } } @@ -2356,7 +2715,7 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } - const int tri_len = mesh_render_data_looptri_len_get(rdata); + const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata); GPUVertBuf *vbo = *r_vbo = GPU_vertbuf_create_with_format(&format); @@ -2368,103 +2727,170 @@ static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); GPU_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step); - float (*lnors)[3] = rdata->loop_normals; - - if (rdata->edit_bmesh) { - GPUPackedNormal *pnors_pack, *vnors_pack; + if (rdata->mapped.use == false) { + float (*lnors)[3] = rdata->loop_normals; + if (rdata->edit_bmesh) { + GPUPackedNormal *pnors_pack, *vnors_pack; - if (lnors == NULL) { - mesh_render_data_ensure_poly_normals_pack(rdata); - mesh_render_data_ensure_vert_normals_pack(rdata); + if (lnors == NULL) { + mesh_render_data_ensure_poly_normals_pack(rdata); + mesh_render_data_ensure_vert_normals_pack(rdata); - pnors_pack = rdata->poly_normals_pack; - vnors_pack = rdata->vert_normals_pack; - } + pnors_pack = rdata->poly_normals_pack; + vnors_pack = rdata->vert_normals_pack; + } - for (int i = 0; i < tri_len; i++) { - const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; - const BMFace *bm_face = bm_looptri[0]->f; + for (int i = 0; i < tri_len; i++) { + const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; + const BMFace *bm_face = bm_looptri[0]->f; - /* use_hide always for edit-mode */ - if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) { - continue; - } + /* use_hide always for edit-mode */ + if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) { + continue; + } - if (lnors) { - for (uint t = 0; t < 3; t++) { - const float *nor = lnors[BM_elem_index_get(bm_looptri[t])]; - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); + if (lnors) { + for (uint t = 0; t < 3; t++) { + const float *nor = lnors[BM_elem_index_get(bm_looptri[t])]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); + } } - } - else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) { - for (uint t = 0; t < 3; t++) { - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)]; + else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) { + for (uint t = 0; t < 3; t++) { + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)]; + } } - } - else { - const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)]; - for (uint t = 0; t < 3; t++) { - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack; + else { + const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)]; + for (uint t = 0; t < 3; t++) { + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack; + } } - } - /* 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 t = 0; t < 3; t++) { - int vidx = BM_elem_index_get(bm_looptri[t]->v); - const float *pos = rdata->edit_data->vertexCos[vidx]; - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos); + /* 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 t = 0; t < 3; t++) { + int vidx = BM_elem_index_get(bm_looptri[t]->v); + const float *pos = rdata->edit_data->vertexCos[vidx]; + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos); + } } - } - else { - for (uint t = 0; t < 3; t++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co); + else { + for (uint t = 0; t < 3; t++) { + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co); + } } } } - } - else { - if (lnors == NULL) { - /* Use normals from vertex. */ - mesh_render_data_ensure_poly_normals_pack(rdata); - } + else { + if (lnors == NULL) { + /* Use normals from vertex. */ + mesh_render_data_ensure_poly_normals_pack(rdata); + } - for (int i = 0; i < tri_len; i++) { - const MLoopTri *mlt = &rdata->mlooptri[i]; - const MPoly *mp = &rdata->mpoly[mlt->poly]; + for (int i = 0; i < tri_len; i++) { + const MLoopTri *mlt = &rdata->mlooptri[i]; + const MPoly *mp = &rdata->mpoly[mlt->poly]; - if (use_hide && (mp->flag & ME_HIDE)) { - continue; - } + if (use_hide && (mp->flag & ME_HIDE)) { + continue; + } - const uint vtri[3] = { - rdata->mloop[mlt->tri[0]].v, - rdata->mloop[mlt->tri[1]].v, - rdata->mloop[mlt->tri[2]].v, - }; + const uint vtri[3] = { + rdata->mloop[mlt->tri[0]].v, + rdata->mloop[mlt->tri[1]].v, + rdata->mloop[mlt->tri[2]].v, + }; - if (lnors) { - for (uint t = 0; t < 3; t++) { - const float *nor = lnors[mlt->tri[t]]; - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); + if (lnors) { + for (uint t = 0; t < 3; t++) { + const float *nor = lnors[mlt->tri[t]]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); + } } - } - else if (mp->flag & ME_SMOOTH) { - for (uint t = 0; t < 3; t++) { - const MVert *mv = &rdata->mvert[vtri[t]]; - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no); + else if (mp->flag & ME_SMOOTH) { + for (uint t = 0; t < 3; t++) { + const MVert *mv = &rdata->mvert[vtri[t]]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no); + } } - } - else { - const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly]; + else { + const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly]; + for (uint t = 0; t < 3; t++) { + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack; + } + } + for (uint t = 0; t < 3; t++) { - *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack; + const MVert *mv = &rdata->mvert[vtri[t]]; + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co); } } + } + } + else { + /* Note: mapped doesn't support lnors yet. */ + BMesh *bm = rdata->edit_bmesh->bm; + Mesh *me_cage = rdata->mapped.me_cage; + + /* TODO(campbell): unlike non-mapped modes we don't generate these on demand, just use if they exist. + * this seems like a low priority TODO since mapped meshes typically + * use the final mesh evaluated mesh for showing faces. */ + const float (*lnors)[3] = CustomData_get_layer(&me_cage->ldata, CD_NORMAL); + + /* TODO(campbell): this is quite an expensive operation for something + * that's not used unless 'normal' display option is enabled. */ + if (!CustomData_has_layer(&me_cage->pdata, CD_NORMAL)) { + /* TODO(campbell): this is quite an expensive operation for something + * that's not used unless 'normal' display option is enabled. */ + BKE_mesh_ensure_normals_for_display(me_cage); + } + const float (*polynors)[3] = CustomData_get_layer(&me_cage->pdata, CD_NORMAL); - for (uint t = 0; t < 3; t++) { - const MVert *mv = &rdata->mvert[vtri[t]]; - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co); + const MVert *mvert = rdata->mapped.me_cage->mvert; + const MLoop *mloop = rdata->mapped.me_cage->mloop; + const MPoly *mpoly = rdata->mapped.me_cage->mpoly; + + const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage); + 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) { + /* Assume 'use_hide' */ + BMFace *efa = BM_face_at_index(bm, p_orig); + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + const MPoly *mp = &mpoly[mlt->poly]; + const uint vtri[3] = { + mloop[mlt->tri[0]].v, + mloop[mlt->tri[1]].v, + mloop[mlt->tri[2]].v, + }; + + if (lnors) { + for (uint t = 0; t < 3; t++) { + const float *nor = lnors[mlt->tri[t]]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); + } + } + else if (mp->flag & ME_SMOOTH) { + for (uint t = 0; t < 3; t++) { + const MVert *mv = &mvert[vtri[t]]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no); + } + } + else { + /* we don't have cached 'rdata->poly_normals_pack'. */ + const GPUPackedNormal pnor = GPU_normal_convert_i10_v3(polynors[mlt->poly]); + for (uint t = 0; t < 3; t++) { + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = pnor; + } + } + + for (uint t = 0; t < 3; t++) { + const MVert *mv = &mvert[vtri[t]]; + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co); + } + } } } } @@ -2507,26 +2933,43 @@ static GPUVertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag( attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); attr_id.data = GPU_vertformat_attr_add(&format, "norAndFlag", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } - - const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata); + const int vbo_len_capacity = mesh_render_data_polys_len_get_maybe_mapped(rdata); int vidx = 0; GPUVertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - for (int i = 0; i < vbo_len_capacity; ++i) { - float pcenter[3], pnor[3]; - bool selected = false; - - if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) { - - GPUPackedNormal nor = { .x = 0, .y = 0, .z = -511 }; - nor = GPU_normal_convert_i10_v3(pnor); - nor.w = selected ? 1 : 0; - GPU_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor); - GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter); + if (rdata->edit_bmesh) { + if (rdata->edit_data && rdata->edit_data->vertexCos != NULL) { + BKE_editmesh_cache_ensure_poly_normals(rdata->edit_bmesh, rdata->edit_data); + BKE_editmesh_cache_ensure_poly_centers(rdata->edit_bmesh, rdata->edit_data); + } + } - vidx += 1; + if (rdata->mapped.use == false) { + for (int i = 0; i < vbo_len_capacity; i++) { + float pcenter[3], pnor[3]; + bool selected = false; + if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) { + GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor); + nor.w = selected ? 1 : 0; + GPU_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter); + vidx += 1; + } + } + } + else { + for (int i = 0; i < vbo_len_capacity; i++) { + float pcenter[3], pnor[3]; + bool selected = false; + if (mesh_render_data_pnors_pcenter_select_get_mapped(rdata, i, pnor, pcenter, &selected)) { + GPUPackedNormal nor = GPU_normal_convert_i10_v3(pnor); + nor.w = selected ? 1 : 0; + GPU_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter); + vidx += 1; + } } } const int vbo_len_used = vidx; @@ -2551,28 +2994,50 @@ static GPUVertBuf *mesh_batch_cache_get_edges_visible( attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2; + const int vbo_len_capacity = mesh_render_data_edges_len_get_maybe_mapped(rdata) * 2; int vidx = 0; GPUVertBuf *vbo = cache->ed_edge_pos = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMEdge *eed; - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co); - vidx += 1; - GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co); - vidx += 1; + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMEdge *eed; + + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co); + vidx += 1; + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co); + vidx += 1; + } } } + else { + /* not yet done! */ + BLI_assert(0); + } } else { - /* not yet done! */ - BLI_assert(0); + BMesh *bm = rdata->edit_bmesh->bm; + const MVert *mvert = rdata->mapped.me_cage->mvert; + const MEdge *medge = rdata->mapped.me_cage->medge; + const int *e_origindex = rdata->mapped.e_origindex; + for (int i = 0; i < rdata->mapped.edge_len; i++) { + const int e_orig = e_origindex[i]; + if (e_orig != ORIGINDEX_NONE) { + BMEdge *eed = BM_edge_at_index(bm, e_orig); + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + const MEdge *ed = &medge[i]; + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v1].co); + vidx += 1; + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mvert[ed->v2].co); + vidx += 1; + } + } + } } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { @@ -2596,29 +3061,47 @@ static GPUVertBuf *mesh_batch_cache_get_verts_visible( attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); + const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata); uint vidx = 0; GPUVertBuf *vbo = cache->ed_vert_pos = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMVert *eve; + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMVert *eve; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co); - vidx += 1; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co); + vidx += 1; + } + } + } + else { + for (int i = 0; i < vbo_len_capacity; i++) { + const MVert *mv = &rdata->mvert[i]; + if (!(mv->flag & ME_HIDE)) { + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co); + vidx += 1; + } } } } else { + BMesh *bm = rdata->edit_bmesh->bm; + const MVert *mvert = rdata->mapped.me_cage->mvert; + const int *v_origindex = rdata->mapped.v_origindex; for (int i = 0; i < vbo_len_capacity; i++) { - const MVert *mv = &rdata->mvert[i]; - if (!(mv->flag & ME_HIDE)) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co); - vidx += 1; + const int v_orig = v_origindex[i]; + if (v_orig != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, v_orig); + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + const MVert *mv = &mvert[i]; + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co); + vidx += 1; + } } } } @@ -2694,33 +3177,54 @@ static GPUVertBuf *mesh_create_edges_select_id( attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } - const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2; + const int vbo_len_capacity = mesh_render_data_edges_len_get_maybe_mapped(rdata) * 2; int vidx = 0; vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - uint select_index = select_id_offset; - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMEdge *eed; + if (rdata->mapped.use == false) { + uint select_index = select_id_offset; + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMEdge *eed; - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int select_id; - GPU_select_index_get(select_index, &select_id); - GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); - vidx += 1; - GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); - vidx += 1; + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + int select_id; + GPU_select_index_get(select_index, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + } + select_index += 1; } - select_index += 1; + } + else { + /* not yet done! */ + BLI_assert(0); } } else { - /* not yet done! */ - BLI_assert(0); + BMesh *bm = rdata->edit_bmesh->bm; + const int *e_origindex = rdata->mapped.e_origindex; + for (int i = 0; i < rdata->mapped.edge_len; i++) { + const int e_orig = e_origindex[i]; + if (e_orig != ORIGINDEX_NONE) { + BMEdge *eed = BM_edge_at_index(bm, e_orig); + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + uint select_index = select_id_offset + e_orig; + int select_id; + GPU_select_index_get(select_index, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + } + } + } } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { @@ -2744,38 +3248,57 @@ static GPUVertBuf *mesh_create_verts_select_id( attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } - const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); + const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata); int vidx = 0; vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - uint select_index = select_id_offset; - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMVert *eve; + if (rdata->mapped.use == false) { + uint select_index = select_id_offset; + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMVert *eve; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - int select_id; - GPU_select_index_get(select_index, &select_id); - GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); - vidx += 1; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + int select_id; + GPU_select_index_get(select_index, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + } + select_index += 1; + } + } + else { + for (int i = 0; i < vbo_len_capacity; i++) { + const MVert *mv = &rdata->mvert[i]; + if (!(mv->flag & ME_HIDE)) { + int select_id; + GPU_select_index_get(select_index, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + } + select_index += 1; } - select_index += 1; } } else { + BMesh *bm = rdata->edit_bmesh->bm; + const int *v_origindex = rdata->mapped.v_origindex; for (int i = 0; i < vbo_len_capacity; i++) { - const MVert *mv = &rdata->mvert[i]; - if (!(mv->flag & ME_HIDE)) { - int select_id; - GPU_select_index_get(select_index, &select_id); - GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); - vidx += 1; + const int v_orig = v_origindex[i]; + if (v_orig != ORIGINDEX_NONE) { + BMVert *eve = BM_vert_at_index(bm, v_orig); + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + uint select_index = select_id_offset + v_orig; + int select_id; + GPU_select_index_get(select_index, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + vidx += 1; + } } - select_index += 1; } } const int vbo_len_used = vidx; @@ -2924,7 +3447,7 @@ static GPUVertBuf *mesh_create_tri_select_id( attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } - const int tri_len = mesh_render_data_looptri_len_get(rdata); + const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata); vbo = GPU_vertbuf_create_with_format(&format); @@ -2932,29 +3455,52 @@ static GPUVertBuf *mesh_create_tri_select_id( int vbo_len_used = 0; GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - if (rdata->edit_bmesh) { - for (int i = 0; i < tri_len; i++) { - const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; - /* Assume 'use_hide' */ - if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { - const int poly_index = BM_elem_index_get(ltri[0]->f); - int select_id; - GPU_select_index_get(poly_index + select_id_offset, &select_id); - for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + for (int i = 0; i < tri_len; i++) { + const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; + /* Assume 'use_hide' */ + if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { + const int poly_index = BM_elem_index_get(ltri[0]->f); + int select_id; + GPU_select_index_get(poly_index + select_id_offset, &select_id); + for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + } + } + } + } + else { + for (int i = 0; i < tri_len; i++) { + const MLoopTri *mlt = &rdata->mlooptri[i]; + const int poly_index = mlt->poly; + if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) { + int select_id; + GPU_select_index_get(poly_index + select_id_offset, &select_id); + for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + } } } } } else { + BMesh *bm = rdata->edit_bmesh->bm; + Mesh *me_cage = rdata->mapped.me_cage; + const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage); for (int i = 0; i < tri_len; i++) { - const MLoopTri *mlt = &rdata->mlooptri[i]; - const int poly_index = mlt->poly; - if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) { - int select_id; - GPU_select_index_get(poly_index + select_id_offset, &select_id); - for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + const MLoopTri *mlt = &mlooptri[i]; + const int p_orig = rdata->mapped.p_origindex[mlt->poly]; + if (p_orig != ORIGINDEX_NONE) { + /* Assume 'use_hide' */ + BMFace *efa = BM_face_at_index(bm, p_orig); + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + int select_id; + GPU_select_index_get(select_id_offset + p_orig, &select_id); + for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + } } } } @@ -2983,28 +3529,42 @@ static GPUVertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order( } GPUVertBuf *vbo = cache->pos_in_order = GPU_vertbuf_create_with_format(&format); - const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); + const int vbo_len_capacity = mesh_render_data_verts_len_get_maybe_mapped(rdata); GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - BMIter iter; - BMVert *eve; - uint i; + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMVert *eve; + uint i; - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - static short no_short[4]; - normal_float_to_short_v3(no_short, eve->no); + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { + static short no_short[4]; + normal_float_to_short_v3(no_short, eve->no); - GPU_vertbuf_attr_set(vbo, attr_id.pos, i, eve->co); - GPU_vertbuf_attr_set(vbo, attr_id.nor, i, no_short); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, eve->co); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, no_short); + } + BLI_assert(i == vbo_len_capacity); + } + else { + for (int i = 0; i < vbo_len_capacity; i++) { + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->mvert[i].co); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, rdata->mvert[i].no); /* XXX actually reading 4 shorts */ + } } - BLI_assert(i == vbo_len_capacity); } else { - for (int i = 0; i < vbo_len_capacity; ++i) { - GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->mvert[i].co); - GPU_vertbuf_attr_set(vbo, attr_id.nor, i, rdata->mvert[i].no); /* XXX actually reading 4 shorts */ + const MVert *mvert = rdata->mapped.me_cage->mvert; + const int *v_origindex = rdata->mapped.v_origindex; + for (int i = 0; i < vbo_len_capacity; i++) { + const int v_orig = v_origindex[i]; + if (v_orig != ORIGINDEX_NONE) { + const MVert *mv = &mvert[i]; + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, mv->co); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, mv->no); /* XXX actually reading 4 shorts */ + } } } } @@ -3059,11 +3619,14 @@ static void mesh_batch_cache_create_overlay_tri_buffers( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); - - const int tri_len = mesh_render_data_looptri_len_get(rdata); + BMesh *bm = rdata->edit_bmesh->bm; + BMIter iter; + BMVert *ev; + const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; + int points_len = bm->totvert; /* Positions */ GPUVertBuf *vbo_pos = NULL; @@ -3090,18 +3653,59 @@ static void mesh_batch_cache_create_overlay_tri_buffers( GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } - 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_overlay_tri( - rdata, vbo_pos, vbo_nor, vbo_data, - attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data, - bm_looptri, vbo_len_used); + /* Verts IBO */ + GPUIndexBufBuilder elb, *elbp = NULL; + if (cache->ed_tri_verts == NULL) { + elbp = &elb; + GPU_indexbuf_init(elbp, GPU_PRIM_POINTS, points_len, vbo_len_capacity); + } - vbo_len_used += 3; + /* 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_overlay_tri( + rdata, vbo_pos, vbo_nor, vbo_data, elbp, + attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data, + bm_looptri, vbo_len_used); + vbo_len_used += 3; + } + } + } + else { + Mesh *me_cage = rdata->mapped.me_cage; + const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage); + if (!CustomData_has_layer(&me_cage->pdata, CD_NORMAL)) { + /* TODO(campbell): this is quite an expensive operation for something + * that's not used unless 'normal' display option is enabled. */ + BKE_mesh_ensure_normals_for_display(me_cage); + } + const float (*polynors)[3] = CustomData_get_layer(&me_cage->pdata, 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 (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + add_overlay_tri_mapped( + rdata, vbo_pos, vbo_nor, vbo_data, elbp, + attr_id.pos, attr_id.vnor, attr_id.lnor, attr_id.data, + efa, mlt, polynors[mlt->poly], vbo_len_used); + vbo_len_used += 3; + } + } } } + if (elbp != NULL) { + cache->ed_tri_verts = GPU_indexbuf_build(elbp); + } + /* Finish */ if (vbo_len_used != vbo_len_capacity) { if (vbo_pos != NULL) { @@ -3114,6 +3718,10 @@ static void mesh_batch_cache_create_overlay_tri_buffers( GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } } + + /* Upload data early because we need to create the texture for it. */ + GPU_vertbuf_use(vbo_data); + cache->ed_tri_data_tx = GPU_texture_create_from_vertbuf(vbo_data); } static void mesh_batch_cache_create_overlay_ledge_buffers( @@ -3121,7 +3729,7 @@ static void mesh_batch_cache_create_overlay_ledge_buffers( { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); - const int ledge_len = mesh_render_data_loose_edges_len_get(rdata); + const int ledge_len = mesh_render_data_loose_edges_len_get_maybe_mapped(rdata); const int vbo_len_capacity = ledge_len * 2; int vbo_len_used = 0; @@ -3151,19 +3759,39 @@ static void mesh_batch_cache_create_overlay_ledge_buffers( GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } - if (rdata->edit_bmesh) { - BMesh *bm = rdata->edit_bmesh->bm; - for (uint i = 0; i < ledge_len; i++) { - const BMEdge *eed = BM_edge_at_index(bm, rdata->loose_edges[i]); - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - add_overlay_loose_edge( - rdata, vbo_pos, vbo_nor, vbo_data, - attr_id.pos, attr_id.vnor, attr_id.data, - eed, vbo_len_used); - vbo_len_used += 2; + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + BMesh *bm = rdata->edit_bmesh->bm; + for (uint i = 0; i < ledge_len; i++) { + const BMEdge *eed = BM_edge_at_index(bm, rdata->loose_edges[i]); + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + add_overlay_loose_edge( + rdata, vbo_pos, vbo_nor, vbo_data, + attr_id.pos, attr_id.vnor, attr_id.data, + eed, vbo_len_used); + vbo_len_used += 2; + } } } } + else { + BMesh *bm = rdata->edit_bmesh->bm; + 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 < ledge_len; i_iter++) { + const int i = rdata->mapped.loose_edges[i_iter]; + const int e_orig = e_origindex[i]; + const MEdge *ed = &medge[i]; + BMEdge *eed = BM_edge_at_index(bm, e_orig); + add_overlay_loose_edge_mapped( + rdata, vbo_pos, vbo_nor, vbo_data, + attr_id.pos, attr_id.vnor, attr_id.data, + eed, mvert, ed, vbo_len_used); + vbo_len_used += 2; + } + } /* Finish */ if (vbo_len_used != vbo_len_capacity) { @@ -3185,7 +3813,7 @@ static void mesh_batch_cache_create_overlay_lvert_buffers( BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); BMesh *bm = rdata->edit_bmesh->bm; - const int lvert_len = mesh_render_data_loose_verts_len_get(rdata); + const int lvert_len = mesh_render_data_loose_verts_len_get_maybe_mapped(rdata); const int vbo_len_capacity = lvert_len; int vbo_len_used = 0; @@ -3216,13 +3844,31 @@ static void mesh_batch_cache_create_overlay_lvert_buffers( GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } - for (uint i = 0; i < lvert_len; i++) { - BMVert *eve = BM_vert_at_index(bm, rdata->loose_verts[i]); - add_overlay_loose_vert( - rdata, vbo_pos, vbo_nor, vbo_data, - attr_id.pos, attr_id.vnor, attr_id.data, - eve, vbo_len_used); - vbo_len_used += 1; + if (rdata->mapped.use == false) { + for (uint i = 0; i < lvert_len; i++) { + BMVert *eve = BM_vert_at_index(bm, rdata->loose_verts[i]); + add_overlay_loose_vert( + rdata, vbo_pos, vbo_nor, vbo_data, + attr_id.pos, attr_id.vnor, attr_id.data, + eve, vbo_len_used); + vbo_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 < lvert_len; i_iter++) { + const int i = rdata->mapped.loose_verts[i_iter]; + const int v_orig = v_origindex[i]; + const MVert *mv = &mvert[i]; + BMVert *eve = BM_vert_at_index(bm, v_orig); + add_overlay_loose_vert_mapped( + rdata, vbo_pos, vbo_nor, vbo_data, + attr_id.pos, attr_id.vnor, attr_id.data, + eve, mv, vbo_len_used); + vbo_len_used += 1; + } } /* Finish */ @@ -3258,6 +3904,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_ledge_pos( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_ledge_pos == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache); } @@ -3270,12 +3919,28 @@ static GPUVertBuf *mesh_batch_cache_get_edit_lvert_pos( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_lvert_pos == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache); } return cache->ed_lvert_pos; } +/* Indices */ +static GPUIndexBuf *mesh_batch_cache_get_edit_tri_indices( + MeshRenderData *rdata, MeshBatchCache *cache) +{ + BLI_assert(rdata->types & MR_DATATYPE_VERT); + + if (cache->ed_tri_verts == NULL) { + mesh_batch_cache_create_overlay_tri_buffers(rdata, cache); + } + + return cache->ed_tri_verts; +} + /* Normal */ static GPUVertBuf *mesh_batch_cache_get_edit_tri_nor( MeshRenderData *rdata, MeshBatchCache *cache) @@ -3283,6 +3948,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_tri_nor( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_tri_nor == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_tri_buffers(rdata, cache); } @@ -3295,6 +3963,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_ledge_nor( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_ledge_nor == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache); } @@ -3307,6 +3978,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_lvert_nor( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_lvert_nor == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache); } @@ -3332,6 +4006,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_ledge_data( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_ledge_data == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_ledge_buffers(rdata, cache); } @@ -3344,6 +4021,9 @@ static GPUVertBuf *mesh_batch_cache_get_edit_lvert_data( BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_lvert_data == NULL) { + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } mesh_batch_cache_create_overlay_lvert_buffers(rdata, cache); } @@ -3403,7 +4083,7 @@ static GPUIndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3); /* Create edges for each pair of triangles sharing an edge. */ for (int i = 0; i < tri_len; i++) { - for (int e = 0; e < 3; ++e) { + for (int e = 0; e < 3; e++) { uint v0, v1, v2; if (rdata->edit_bmesh) { const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; @@ -3415,8 +4095,8 @@ static GPUIndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, v2 = BM_elem_index_get(bm_looptri[(e + 2) % 3]->v); } else { - MLoop *mloop = rdata->mloop; - MLoopTri *mlt = rdata->mlooptri + i; + const MLoop *mloop = rdata->mloop; + const MLoopTri *mlt = rdata->mlooptri + i; v0 = mloop[mlt->tri[e]].v; v1 = mloop[mlt->tri[(e + 1) % 3]].v; v2 = mloop[mlt->tri[(e + 2) % 3]].v; @@ -3485,7 +4165,7 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata) EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3); /* Create edges for each pair of triangles sharing an edge. */ for (int i = 0; i < tri_len; i++) { - for (int e = 0; e < 3; ++e) { + for (int e = 0; e < 3; e++) { uint v0, v1, v2; if (rdata->edit_bmesh) { const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; @@ -3497,8 +4177,8 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata) v2 = BM_elem_index_get(bm_looptri[(e + 2) % 3]->v); } else { - MLoop *mloop = rdata->mloop; - MLoopTri *mlt = rdata->mlooptri + i; + const MLoop *mloop = rdata->mloop; + const MLoopTri *mlt = rdata->mlooptri + i; v0 = mloop[mlt->tri[e]].v; v1 = mloop[mlt->tri[(e + 1) % 3]].v; v2 = mloop[mlt->tri[(e + 2) % 3]].v; @@ -3540,25 +4220,23 @@ static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderD eh = create_looptri_edge_adjacency_hash(rdata); for (int i = 0; i < tri_len; i++) { - bool edge_is_real[3] = {false, false, false}; + bool edge_is_real[3]; - MEdge *medge = rdata->medge; - MLoop *mloop = rdata->mloop; - MLoopTri *mlt = rdata->mlooptri + i; + const MEdge *medge = rdata->medge; + const MLoop *mloop = rdata->mloop; + const MLoopTri *mlt = rdata->mlooptri + i; int j, j_next; for (j = 2, j_next = 0; j_next < 3; j = j_next++) { - MEdge *ed = &medge[mloop[mlt->tri[j]].e]; - uint tri_edge[2] = {mloop[mlt->tri[j]].v, mloop[mlt->tri[j_next]].v}; - - if (((ed->v1 == tri_edge[0]) && (ed->v2 == tri_edge[1])) || - ((ed->v1 == tri_edge[1]) && (ed->v2 == tri_edge[0]))) - { - edge_is_real[j] = true; - } + const MEdge *ed = &medge[mloop[mlt->tri[j]].e]; + const uint tri_edge[2] = {mloop[mlt->tri[j]].v, mloop[mlt->tri[j_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]))); + edge_is_real[j] = is_edge_real; } - for (int e = 0; e < 3; ++e) { + for (int e = 0; e < 3; e++) { int v0 = mloop[mlt->tri[e]].v; int v1 = mloop[mlt->tri[(e + 1) % 3]].v; EdgeAdjacentVerts *eav = BLI_edgehash_lookup(eh, v0, v1); @@ -3569,7 +4247,7 @@ static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderD } /* Non-manifold edge */ if (eav->vert_index[1] == -1) { - value |= (1 << 31); + value |= (1u << 31); } GPU_vertbuf_attr_set(vbo, index_id, vidx++, &value); } @@ -3631,7 +4309,7 @@ static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdat GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); if (rdata->edit_bmesh) { - for (int i = 0; i < tri_len; ++i) { + for (int i = 0; i < tri_len; i++) { const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { @@ -3641,7 +4319,7 @@ static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdat } } else { - for (int i = 0; i < tri_len; ++i) { + for (int i = 0; i < tri_len; i++) { const MLoopTri *mlt = &rdata->mlooptri[i]; for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { GPU_indexbuf_add_generic_vert(&elb, mlt->tri[tri_corner]); @@ -3660,31 +4338,42 @@ static GPUIndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, Mesh BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); if (cache->ledges_in_order == NULL) { - const int vert_len = mesh_render_data_verts_len_get(rdata); - const int edge_len = mesh_render_data_edges_len_get(rdata); + 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); /* Alloc max (edge_len) and upload only needed range. */ GPUIndexBufBuilder elb; GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); - if (rdata->edit_bmesh) { - /* No need to support since edit mesh already draw them. - * But some engines may want them ... */ - BMesh *bm = rdata->edit_bmesh->bm; - BMIter eiter; - BMEdge *eed; - BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) { - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_edge_is_wire(eed)) { - GPU_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); + if (rdata->mapped.use == false) { + if (rdata->edit_bmesh) { + /* No need to support since edit mesh already draw them. + * But some engines may want them ... */ + BMesh *bm = rdata->edit_bmesh->bm; + BMIter eiter; + BMEdge *eed; + BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !bm_edge_has_visible_face(eed)) { + GPU_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); + } + } + } + else { + for (int i = 0; i < edge_len; i++) { + const MEdge *medge = &rdata->medge[i]; + if (medge->flag & ME_LOOSEEDGE) { + GPU_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); + } } } } else { - for (int i = 0; i < edge_len; ++i) { - const MEdge *medge = &rdata->medge[i]; - if (medge->flag & ME_LOOSEEDGE) { - GPU_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); - } + /* Hidden checks are already done when creating the loose edge list. */ + Mesh *me_cage = rdata->mapped.me_cage; + for (int i_iter = 0; i_iter < rdata->mapped.loose_edge_len; i_iter++) { + const int i = rdata->mapped.loose_edges[i_iter]; + const MEdge *medge = &me_cage->medge[i]; + GPU_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); } } cache->ledges_in_order = GPU_indexbuf_build(&elb); @@ -3730,7 +4419,7 @@ static GPUIndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( } /* Init ELBs. */ - for (int i = 0; i < mat_len; ++i) { + for (int i = 0; i < mat_len; i++) { GPU_indexbuf_init(&elb[i], GPU_PRIM_TRIS, mat_tri_len[i], tri_len * 3); } @@ -3763,7 +4452,7 @@ static GPUIndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( } /* Build ELBs. */ - for (int i = 0; i < mat_len; ++i) { + for (int i = 0; i < mat_len; i++) { cache->shaded_triangles_in_order[i] = GPU_indexbuf_build(&elb[i]); } @@ -3846,7 +4535,7 @@ static GPUIndexBuf *mesh_create_tri_overlay_weight_faces( GPUIndexBufBuilder elb; GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); - for (int i = 0; i < tri_len; ++i) { + for (int i = 0; i < tri_len; i++) { const MLoopTri *mlt = &rdata->mlooptri[i]; if (!(rdata->mpoly[mlt->poly].flag & (ME_FACE_SEL | ME_HIDE))) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { @@ -3969,6 +4658,9 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) if (cache->ledges_with_normals == NULL) { const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } cache->ledges_with_normals = GPU_batch_create( GPU_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), @@ -4049,6 +4741,9 @@ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id( const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } cache->triangles_with_select_id = GPU_batch_create_ex( GPU_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GPU_BATCH_OWNS_VBO); @@ -4075,6 +4770,9 @@ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } GPUVertBuf *vbo_tris = use_hide ? mesh_create_tri_pos_and_normals_visible_only(rdata) : @@ -4147,7 +4845,7 @@ GPUBatch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) const int vbo_len_capacity = edge_len * 2; /* these are PRIM_LINE verts, not mesh verts */ int vbo_len_used = 0; GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - for (int i = 0; i < edge_len; ++i) { + for (int i = 0; i < edge_len; i++) { float *vcos1, *vcos2; float *pnor1 = NULL, *pnor2 = NULL; bool is_manifold; @@ -4244,6 +4942,10 @@ static void mesh_batch_cache_create_overlay_batches(Mesh *me) MeshBatchCache *cache = mesh_batch_cache_get(me); MeshRenderData *rdata = mesh_render_data_create(me, options); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } + if (cache->overlay_triangles == NULL) { cache->overlay_triangles = GPU_batch_create( GPU_PRIM_TRIS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); @@ -4265,16 +4967,20 @@ static void mesh_batch_cache_create_overlay_batches(Mesh *me) GPU_batch_vertbuf_add(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_data(rdata, cache)); } + /* Also used for vertices display */ if (cache->overlay_triangles_nor == NULL) { cache->overlay_triangles_nor = GPU_batch_create( - GPU_PRIM_POINTS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); + GPU_PRIM_POINTS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), + mesh_batch_cache_get_edit_tri_indices(rdata, cache)); GPU_batch_vertbuf_add(cache->overlay_triangles_nor, mesh_batch_cache_get_edit_tri_nor(rdata, cache)); + GPU_batch_vertbuf_add(cache->overlay_triangles_nor, mesh_batch_cache_get_edit_tri_data(rdata, cache)); } if (cache->overlay_loose_edges_nor == NULL) { cache->overlay_loose_edges_nor = GPU_batch_create( GPU_PRIM_POINTS, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL); GPU_batch_vertbuf_add(cache->overlay_loose_edges_nor, mesh_batch_cache_get_edit_ledge_nor(rdata, cache)); + GPU_batch_vertbuf_add(cache->overlay_loose_edges_nor, mesh_batch_cache_get_edit_ledge_data(rdata, cache)); } mesh_render_data_free(rdata); @@ -4291,6 +4997,17 @@ GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles(Mesh *me) return cache->overlay_triangles; } +GPUTexture *DRW_mesh_batch_cache_get_overlay_data_tex(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + if (cache->ed_tri_data_tx == NULL) { + mesh_batch_cache_create_overlay_batches(me); + } + + return cache->ed_tri_data_tx; +} + GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4389,6 +5106,9 @@ GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id if (cache->edges_with_select_id == NULL) { MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } cache->edges_with_select_id = GPU_batch_create( GPU_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL); @@ -4414,6 +5134,9 @@ GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id if (cache->verts_with_select_id == NULL) { MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT); + if (rdata->mapped.supported) { + rdata->mapped.use = true; + } cache->verts_with_select_id = GPU_batch_create( GPU_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL); @@ -4435,6 +5158,20 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->shaded_triangles == NULL) { + + /* Hack to show the final result. */ + const bool use_em_final = ( + me->edit_btmesh && + me->edit_btmesh->mesh_eval_final && + (me->edit_btmesh->mesh_eval_final->runtime.is_original == false)); + Mesh me_fake; + if (use_em_final) { + me_fake = *me->edit_btmesh->mesh_eval_final; + me_fake.mat = me->mat; + me_fake.totcol = me->totcol; + me = &me_fake; + } + /* create batch from DM */ const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | @@ -4450,7 +5187,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); GPUVertBuf *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache); - for (int i = 0; i < mat_len; ++i) { + for (int i = 0; i < mat_len; i++) { cache->shaded_triangles[i] = GPU_batch_create( GPU_PRIM_TRIS, vbo, el[i]); if (vbo_shading) { @@ -4487,7 +5224,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) GPUIndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache); GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - for (int i = 0; i < mat_len; ++i) { + for (int i = 0; i < mat_len; i++) { cache->texpaint_triangles[i] = GPU_batch_create( GPU_PRIM_TRIS, vbo, el[i]); GPUVertBuf *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); @@ -4556,7 +5293,7 @@ GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me) GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, vert_len); - MPoly *mpoly = rdata->mpoly; + const MPoly *mpoly = rdata->mpoly; for (int a = 0; a < poly_len; a++, mpoly++) { const MLoopUV *mloopuv = mloopuv_base + mpoly->loopstart; for (int b = 0; b < mpoly->totloop; b++, mloopuv++) { diff --git a/source/blender/draw/intern/draw_debug.c b/source/blender/draw/intern/draw_debug.c index 053d266ec34..366da92cf50 100644 --- a/source/blender/draw/intern/draw_debug.c +++ b/source/blender/draw/intern/draw_debug.c @@ -161,10 +161,10 @@ static void drw_debug_draw_lines(void) while (DST.debug.lines) { void *next = DST.debug.lines->next; - immAttrib4fv(col, DST.debug.lines->color); + immAttr4fv(col, DST.debug.lines->color); immVertex3fv(pos, DST.debug.lines->pos[0]); - immAttrib4fv(col, DST.debug.lines->color); + immAttr4fv(col, DST.debug.lines->color); immVertex3fv(pos, DST.debug.lines->pos[1]); MEM_freeN(DST.debug.lines); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 0566abd3436..512100d3ded 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -148,13 +148,10 @@ struct DRWTextStore *DRW_text_cache_ensure(void) /** \name Settings * \{ */ -bool DRW_object_is_renderable(Object *ob) +bool DRW_object_is_renderable(const Object *ob) { BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE)); - if (ob->dt < OB_SOLID) - return false; - if (ob->type == OB_MESH) { if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) { View3D *v3d = DST.draw_ctx.v3d; @@ -173,7 +170,7 @@ bool DRW_object_is_renderable(Object *ob) * Return whether this object is visible depending if * we are rendering or drawing in the viewport. */ -bool DRW_check_object_visible_within_active_context(Object *ob) +bool DRW_object_is_visible_in_active_context(const Object *ob) { const eObjectVisibilityCheck mode = DRW_state_is_scene_render() ? OB_VISIBILITY_CHECK_FOR_RENDER : @@ -192,9 +189,9 @@ bool DRW_object_is_flat_normal(const Object *ob) return true; } -bool DRW_check_psys_visible_within_active_context( - Object *object, - struct ParticleSystem *psys) +bool DRW_object_is_visible_psys_in_active_context( + const Object *object, + const ParticleSystem *psys) { const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene = draw_ctx->scene; @@ -270,13 +267,13 @@ void DRW_transform_to_display(GPUTexture *tex, bool use_view_settings) /* Full screen triangle */ immBegin(GPU_PRIM_TRIS, 3); - immAttrib2f(texco, 0.0f, 0.0f); + immAttr2f(texco, 0.0f, 0.0f); immVertex2f(pos, -1.0f, -1.0f); - immAttrib2f(texco, 2.0f, 0.0f); + immAttr2f(texco, 2.0f, 0.0f); immVertex2f(pos, 3.0f, -1.0f); - immAttrib2f(texco, 0.0f, 2.0f); + immAttr2f(texco, 0.0f, 2.0f); immVertex2f(pos, -1.0f, 3.0f); immEnd(); @@ -1284,7 +1281,7 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t { Object *obact = OBACT(view_layer); const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode); - View3D * v3d = DST.draw_ctx.v3d; + View3D *v3d = DST.draw_ctx.v3d; const int drawtype = v3d->shading.type; const bool use_xray = XRAY_ENABLED(v3d); @@ -1660,7 +1657,7 @@ static bool DRW_render_check_grease_pencil(Depsgraph *depsgraph) { DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) { - if ((ob->type == OB_GPENCIL) && (DRW_check_object_visible_within_active_context(ob))) { + if ((ob->type == OB_GPENCIL) && (DRW_object_is_visible_in_active_context(ob))) { return true; } } @@ -2201,16 +2198,16 @@ static void draw_depth_texture_to_screen(GPUTexture *texture) immBegin(GPU_PRIM_TRI_STRIP, 4); - immAttrib2f(texcoord, 0.0f, 0.0f); + immAttr2f(texcoord, 0.0f, 0.0f); immVertex2f(pos, 0.0f, 0.0f); - immAttrib2f(texcoord, 1.0f, 0.0f); + immAttr2f(texcoord, 1.0f, 0.0f); immVertex2f(pos, w, 0.0f); - immAttrib2f(texcoord, 0.0f, 1.0f); + immAttr2f(texcoord, 0.0f, 1.0f); immVertex2f(pos, 0.0f, h); - immAttrib2f(texcoord, 1.0f, 1.0f); + immAttr2f(texcoord, 1.0f, 1.0f); immVertex2f(pos, w, h); immEnd(); diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 5916b45aa27..c8a7816c402 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -101,6 +101,7 @@ enum { DRW_CALL_NORMALWORLD = (1 << 5), DRW_CALL_ORCOTEXFAC = (1 << 6), DRW_CALL_EYEVEC = (1 << 7), + DRW_CALL_OBJECTINFO = (1 << 8), }; typedef struct DRWCallState { @@ -122,6 +123,7 @@ typedef struct DRWCallState { float normalview[3][3]; float normalworld[3][3]; /* Not view dependent */ float orcotexfac[2][3]; /* Not view dependent */ + float objectinfo[2]; float eyevec[3]; } DRWCallState; @@ -140,6 +142,7 @@ typedef struct DRWCall { union { struct { /* type == DRW_CALL_SINGLE */ GPUBatch *geometry; + short ma_index; } single; struct { /* type == DRW_CALL_RANGE */ GPUBatch *geometry; @@ -257,14 +260,13 @@ struct DRWShadingGroup { int orcotexfac; int eye; int callid; + int objectinfo; uint16_t matflag; /* Matrices needed, same as DRWCall.flag */ + DRWPass *pass_parent; /* backlink to pass we're in */ #ifndef NDEBUG char attribs_count; #endif -#if !defined(NDEBUG) || defined(USE_GPU_SELECT) - DRWPass *pass_parent; /* backlink to pass we're in */ -#endif #ifdef USE_GPU_SELECT GPUVertBuf *inst_selectid; int override_selectid; /* Override for single object instances. */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 371bd9dd189..3823d081adc 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -36,6 +36,7 @@ #include "DNA_mesh_types.h" #include "DNA_meta_types.h" +#include "BLI_hash.h" #include "BLI_link_utils.h" #include "BLI_mempool.h" @@ -344,6 +345,22 @@ static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obm state->matflag &= ~DRW_CALL_ORCOTEXFAC; } + if ((state->matflag & DRW_CALL_OBJECTINFO) != 0) { + state->objectinfo[0] = ob ? ob->index : 0; + unsigned int random; +#if 0 /* TODO(fclem) handle dupli objects */ + if (GMS.dob) { + random = GMS.dob->random_id; + } + else +#endif + { + random = BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0); + } + state->objectinfo[1] = random * (1.0f / (float)0xFFFFFFFF); + state->matflag &= ~DRW_CALL_OBJECTINFO; + } + return state; } @@ -440,7 +457,7 @@ void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *sh } /* These calls can be culled and are optimized for redraw */ -void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, bool bypass_culling) +void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, Material *ma, bool bypass_culling) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -449,6 +466,7 @@ void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, GPUBatch *geom, Ob call->state = drw_call_state_object(shgroup, ob->obmat, ob); call->type = DRW_CALL_SINGLE; call->single.geometry = geom; + call->single.ma_index = ma ? ma->index : 0; #ifdef USE_GPU_SELECT call->select_id = DST.select_id; #endif @@ -460,7 +478,7 @@ void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, GPUBatch *geom, Ob } void DRW_shgroup_call_object_add_with_callback( - DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, + DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, Material *ma, DRWCallVisibilityFn *callback, void *user_data) { BLI_assert(geom != NULL); @@ -472,6 +490,7 @@ void DRW_shgroup_call_object_add_with_callback( call->state->user_data = user_data; call->type = DRW_CALL_SINGLE; call->single.geometry = geom; + call->single.ma_index = ma ? ma->index : 0; #ifdef USE_GPU_SELECT call->select_id = DST.select_id; #endif @@ -635,6 +654,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) shgroup->normalview = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL); shgroup->normalworld = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_WORLDNORMAL); shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_ORCO); + shgroup->objectinfo = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_OBJECT_INFO); shgroup->eye = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_EYE); shgroup->callid = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_CALLID); @@ -653,6 +673,8 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) shgroup->matflag |= DRW_CALL_NORMALWORLD; if (shgroup->orcotexfac > -1) shgroup->matflag |= DRW_CALL_ORCOTEXFAC; + if (shgroup->objectinfo > -1) + shgroup->matflag |= DRW_CALL_OBJECTINFO; if (shgroup->eye > -1) shgroup->matflag |= DRW_CALL_EYEVEC; } @@ -746,10 +768,7 @@ static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass shgroup->instance_geom = NULL; shgroup->instance_vbo = NULL; #endif - -#if !defined(NDEBUG) || defined(USE_GPU_SELECT) shgroup->pass_parent = pass; -#endif return shgroup; } @@ -1013,6 +1032,23 @@ bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup) return true; } +DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup) +{ + /* Remove this assertion if needed but implement the other cases first! */ + BLI_assert(shgroup->type == DRW_SHG_NORMAL); + + DRWShadingGroup *shgroup_new = BLI_mempool_alloc(DST.vmempool->shgroups); + + *shgroup_new = *shgroup; + shgroup_new->uniforms = NULL; /* Not sure about that.. Should we copy them instead? */ + shgroup_new->calls.first = NULL; + shgroup_new->calls.last = NULL; + + BLI_LINKS_INSERT_AFTER(&shgroup->pass_parent->shgroups, shgroup, shgroup_new); + + return shgroup; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 938dda2eec9..7a4edc4e7fe 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -801,10 +801,16 @@ static void draw_matrices_model_prepare(DRWCallState *st) } } -static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCallState *state) +static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call) { /* step 1 : bind object dependent matrices */ - if (state != NULL) { + if (call != NULL) { + DRWCallState *state = call->state; + float objectinfo[3]; + objectinfo[0] = state->objectinfo[0]; + objectinfo[1] = call->single.ma_index; /* WATCH this is only valid for single drawcalls. */ + objectinfo[2] = state->objectinfo[1]; + GPU_shader_uniform_vector(shgroup->shader, shgroup->model, 16, 1, (float *)state->model); GPU_shader_uniform_vector(shgroup->shader, shgroup->modelinverse, 16, 1, (float *)state->modelinverse); GPU_shader_uniform_vector(shgroup->shader, shgroup->modelview, 16, 1, (float *)state->modelview); @@ -812,6 +818,7 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCallState *state) GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)state->modelviewprojection); GPU_shader_uniform_vector(shgroup->shader, shgroup->normalview, 9, 1, (float *)state->normalview); GPU_shader_uniform_vector(shgroup->shader, shgroup->normalworld, 9, 1, (float *)state->normalworld); + GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 3, 1, (float *)objectinfo); GPU_shader_uniform_vector(shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac); GPU_shader_uniform_vector(shgroup->shader, shgroup->eye, 3, 1, (float *)state->eyevec); } @@ -825,6 +832,7 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCallState *state) GPU_shader_uniform_vector(shgroup->shader, shgroup->modelview, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_VIEW]); GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewinverse, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_VIEWINV]); GPU_shader_uniform_vector(shgroup->shader, shgroup->modelviewprojection, 16, 1, (float *)DST.view_data.matstate.mat[DRW_MAT_PERS]); + GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 3, 1, (float *)unitmat); GPU_shader_uniform_vector(shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)shgroup->instance_orcofac); } } @@ -1205,7 +1213,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) } GPU_SELECT_LOAD_IF_PICKSEL_CALL(call); - draw_geometry_prepare(shgroup, call->state); + draw_geometry_prepare(shgroup, call); switch (call->type) { case DRW_CALL_SINGLE: diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index d77620bc47b..545c4af878c 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -108,11 +108,11 @@ void DRW_draw_background(void) UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi); immBegin(GPU_PRIM_TRI_FAN, 4); - immAttrib3ubv(color, col_lo); + immAttr3ubv(color, col_lo); immVertex2f(pos, -1.0f, -1.0f); immVertex2f(pos, 1.0f, -1.0f); - immAttrib3ubv(color, col_hi); + immAttr3ubv(color, col_hi); immVertex2f(pos, 1.0f, 1.0f); immVertex2f(pos, -1.0f, 1.0f); immEnd(); |