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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/DRW_render.h16
-rw-r--r--source/blender/draw/intern/draw_cache.c4
-rw-r--r--source/blender/draw/intern/draw_cache.h3
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h9
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c1379
-rw-r--r--source/blender/draw/intern/draw_debug.c4
-rw-r--r--source/blender/draw/intern/draw_manager.c31
-rw-r--r--source/blender/draw/intern/draw_manager.h8
-rw-r--r--source/blender/draw/intern/draw_manager_data.c46
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c14
-rw-r--r--source/blender/draw/intern/draw_view.c4
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();