Mesh Batch Cache: Port Texture paint wires to new batch request
authorClément Foucault <foucault.clem@gmail.com>
Mon, 17 Dec 2018 16:01:06 +0000 (17:01 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 17 Dec 2018 16:11:45 +0000 (17:11 +0100)
source/blender/draw/CMakeLists.txt
source/blender/draw/engines/eevee/eevee_materials.c
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache.h
source/blender/draw/intern/draw_cache_impl.h
source/blender/draw/intern/draw_cache_impl_mesh.c
source/blender/draw/modes/paint_texture_mode.c
source/blender/draw/modes/paint_vertex_mode.c
source/blender/draw/modes/paint_weight_mode.c
source/blender/draw/modes/shaders/paint_face_vert.glsl [new file with mode: 0644]

index 4fcd43d..8ba9058 100644 (file)
@@ -314,6 +314,7 @@ data_to_c_simple(modes/shaders/paint_vertex_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vertex_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_weight_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_weight_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vertex_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_weight_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_weight_vert.glsl SRC)
+data_to_c_simple(modes/shaders/paint_face_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
 data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
index 642dbed..f26920c 100644 (file)
@@ -1446,7 +1446,6 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
        const bool is_sculpt_mode_draw =
                is_sculpt_mode &&
                ((ob->sculpt && ob->sculpt->pbvh) && (BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES));
        const bool is_sculpt_mode_draw =
                is_sculpt_mode &&
                ((ob->sculpt && ob->sculpt->pbvh) && (BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES));
-       const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
        const bool is_default_mode_shader = is_sculpt_mode;
 
        /* First get materials for this mesh. */
        const bool is_default_mode_shader = is_sculpt_mode;
 
        /* First get materials for this mesh. */
index 468d56f..d5c99e1 100644 (file)
@@ -3032,6 +3032,14 @@ GPUBatch *DRW_cache_mesh_surface_get(Object *ob)
        return DRW_mesh_batch_cache_get_triangles_with_normals(me);
 }
 
        return DRW_mesh_batch_cache_get_triangles_with_normals(me);
 }
 
+GPUBatch *DRW_cache_mesh_wire_get(Object *ob)
+{
+       BLI_assert(ob->type == OB_MESH);
+
+       Mesh *me = ob->data;
+       return DRW_mesh_batch_cache_get_wire_loops(me);
+}
+
 GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
 {
        BLI_assert(ob->type == OB_MESH);
 GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
 {
        BLI_assert(ob->type == OB_MESH);
@@ -3152,14 +3160,6 @@ GPUBatch *DRW_cache_mesh_verts_get(Object *ob)
        return DRW_mesh_batch_cache_get_all_verts(me);
 }
 
        return DRW_mesh_batch_cache_get_all_verts(me);
 }
 
-GPUBatch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel)
-{
-       BLI_assert(ob->type == OB_MESH);
-
-       Mesh *me = ob->data;
-       return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel, use_sel);
-}
-
 GPUBatch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob)
 {
        BLI_assert(ob->type == OB_MESH);
 GPUBatch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob)
 {
        BLI_assert(ob->type == OB_MESH);
index b5c7c96..f503c0d 100644 (file)
@@ -129,6 +129,7 @@ struct GPUBatch *DRW_cache_face_centers_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold);
 struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold);
 struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob);
+struct GPUBatch *DRW_cache_mesh_wire_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_loose_edges_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob, struct ToolSettings *ts, bool paint_mode);
 struct GPUBatch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_loose_edges_get(struct Object *ob);
 struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob, struct ToolSettings *ts, bool paint_mode);
 struct GPUBatch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
index b225083..ffaa99b 100644 (file)
@@ -126,7 +126,7 @@ struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
         char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
 struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
         char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
 struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me);
-struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel, bool use_hide);
+struct GPUBatch *DRW_mesh_batch_cache_get_wire_loops(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
index 1aa7a85..ab9c13e 100644 (file)
@@ -56,6 +56,8 @@
 #include "BKE_colorband.h"
 #include "BKE_cdderivedmesh.h"
 
 #include "BKE_colorband.h"
 #include "BKE_cdderivedmesh.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include "bmesh.h"
 
 #include "GPU_batch.h"
 #include "bmesh.h"
 
 #include "GPU_batch.h"
@@ -1435,94 +1437,6 @@ fallback:
        }
 }
 
        }
 }
 
-
-/** Ensure #MeshRenderData.edge_select_bool */
-static void mesh_render_data_ensure_edge_select_bool(MeshRenderData *rdata, bool use_wire)
-{
-       bool *edge_select_bool = rdata->edge_select_bool;
-       if (edge_select_bool == NULL) {
-               edge_select_bool = rdata->edge_select_bool =
-                       MEM_callocN(sizeof(*edge_select_bool) * rdata->edge_len, __func__);
-
-               for (int i = 0; i < rdata->poly_len; i++) {
-                       const MPoly *poly = &rdata->mpoly[i];
-
-                       if (poly->flag & ME_FACE_SEL) {
-                               for (int j = 0; j < poly->totloop; j++) {
-                                       const MLoop *loop = &rdata->mloop[poly->loopstart + j];
-                                       if (use_wire) {
-                                               edge_select_bool[loop->e] = true;
-                                       }
-                                       else {
-                                               /* Not totally correct, will cause problems for edges with 3x faces. */
-                                               edge_select_bool[loop->e] = !edge_select_bool[loop->e];
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-/** Ensure #MeshRenderData.edge_visible_bool */
-static void mesh_render_data_ensure_edge_visible_bool(MeshRenderData *rdata)
-{
-       bool *edge_visible_bool = rdata->edge_visible_bool;
-       if (edge_visible_bool == NULL) {
-               edge_visible_bool = rdata->edge_visible_bool =
-                       MEM_callocN(sizeof(*edge_visible_bool) * rdata->edge_len, __func__);
-
-               /* If original index is available, hide edges within the same original poly. */
-               const int *p_origindex = NULL;
-               int *index_table = NULL;
-
-               if (rdata->me != NULL) {
-                       p_origindex = CustomData_get_layer(&rdata->me->pdata, CD_ORIGINDEX);
-                       if (p_origindex != NULL) {
-                               index_table = MEM_malloc_arrayN(sizeof(int), rdata->edge_len, __func__);
-                               memset(index_table, -1, sizeof(int) * rdata->edge_len);
-                       }
-               }
-
-               for (int i = 0; i < rdata->poly_len; i++) {
-                       const MPoly *poly = &rdata->mpoly[i];
-                       int p_orig = p_origindex ? p_origindex[i] : ORIGINDEX_NONE;
-
-                       if (!(poly->flag & ME_HIDE)) {
-                               for (int j = 0; j < poly->totloop; j++) {
-                                       const MLoop *loop = &rdata->mloop[poly->loopstart + j];
-
-                                       if (p_orig != ORIGINDEX_NONE) {
-                                               /* Boundary edge is visible. */
-                                               if (index_table[loop->e] == -1) {
-                                                       index_table[loop->e] = p_orig;
-                                                       edge_visible_bool[loop->e] = true;
-                                               }
-                                               /* Edge between two faces with the same original is hidden. */
-                                               else if (index_table[loop->e] == p_orig) {
-                                                       edge_visible_bool[loop->e] = false;
-                                               }
-                                               /* Edge between two different original faces is visible. */
-                                               else {
-                                                       index_table[loop->e] = -2;
-                                                       edge_visible_bool[loop->e] = true;
-                                               }
-                                       }
-                                       else {
-                                               if (index_table != NULL) {
-                                                       index_table[loop->e] = -2;
-                                               }
-                                               edge_visible_bool[loop->e] = true;
-                                       }
-                               }
-                       }
-               }
-
-               if (index_table != NULL) {
-                       MEM_freeN(index_table);
-               }
-       }
-}
-
 /** \} */
 
 /* ---------------------------------------------------------------------- */
 /** \} */
 
 /* ---------------------------------------------------------------------- */
@@ -2150,6 +2064,7 @@ typedef struct MeshBatchCache {
        struct {
                /* Indices to vloops. */
                GPUIndexBuf *surface_tris;
        struct {
                /* Indices to vloops. */
                GPUIndexBuf *surface_tris;
+               GPUIndexBuf *loops_lines;
                /* Contains indices to unique edit vertices to not
                 * draw the same vert multiple times (because of tesselation). */
                GPUIndexBuf *edit_verts_points;
                /* Contains indices to unique edit vertices to not
                 * draw the same vert multiple times (because of tesselation). */
                GPUIndexBuf *edit_verts_points;
@@ -2169,6 +2084,7 @@ typedef struct MeshBatchCache {
                GPUBatch *edit_facedots;
                /* Common display / Other */
                GPUBatch *all_verts;
                GPUBatch *edit_facedots;
                /* Common display / Other */
                GPUBatch *all_verts;
+               GPUBatch *wire_loops; /* Loops around faces. */
                GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
        } batch;
 
                GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
        } batch;
 
@@ -2478,6 +2394,15 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
                        GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
                        GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
                        /* Paint mode selection */
                        GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
                        GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
                        /* Paint mode selection */
+                       /* TODO only do that in paint mode. */
+                       GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
+                       GPU_BATCH_DISCARD_SAFE(cache->batch.surface);
+                       GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops);
+                       if (cache->surf_per_mat) {
+                               for (int i = 0; i < cache->mat_len; i++) {
+                                       GPU_BATCH_DISCARD_SAFE(cache->surf_per_mat[i]);
+                               }
+                       }
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
                        GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
@@ -2623,8 +2548,6 @@ static void mesh_batch_cache_clear(Mesh *me)
        }
        MEM_SAFE_FREE(cache->texpaint_triangles);
 
        }
        MEM_SAFE_FREE(cache->texpaint_triangles);
 
-       GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
-
        DRW_mesh_weight_state_clear(&cache->weight_state);
 }
 
        DRW_mesh_weight_state_clear(&cache->weight_state);
 }
 
@@ -3466,14 +3389,14 @@ static void mesh_create_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
        }
 }
 
        }
 }
 
-static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
+static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo, const bool use_face_sel)
 {
        /* TODO deduplicate format creation*/
        static GPUVertFormat format = { 0 };
        static struct { uint pos, nor; } attr_id;
        if (format.attr_len == 0) {
                attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
 {
        /* TODO deduplicate format creation*/
        static GPUVertFormat format = { 0 };
        static struct { uint pos, nor; } attr_id;
        if (format.attr_len == 0) {
                attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-               attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+               attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
        }
        const int poly_len = mesh_render_data_polys_len_get(rdata);
        const int loop_len = mesh_render_data_loops_len_get(rdata);
        }
        const int poly_len = mesh_render_data_polys_len_get(rdata);
        const int loop_len = mesh_render_data_loops_len_get(rdata);
@@ -3537,14 +3460,18 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
                                const GPUPackedNormal *fnor = (mpoly->flag & ME_SMOOTH) ? NULL : &rdata->poly_normals_pack[a];
                                for (int b = 0; b < mpoly->totloop; b++, mloop++) {
                                        copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop->v].co);
                                const GPUPackedNormal *fnor = (mpoly->flag & ME_SMOOTH) ? NULL : &rdata->poly_normals_pack[a];
                                for (int b = 0; b < mpoly->totloop; b++, mloop++) {
                                        copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop->v].co);
+                                       GPUPackedNormal *pnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step);
                                        if (lnors) {
                                        if (lnors) {
-                                               *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(lnors);
+                                               *pnor = GPU_normal_convert_i10_v3(lnors);
                                        }
                                        else if (fnor) {
                                        }
                                        else if (fnor) {
-                                               *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *fnor;
+                                               *pnor = *fnor;
                                        }
                                        else {
                                        }
                                        else {
-                                               *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mvert[mloop->v].no);
+                                               *pnor = GPU_normal_convert_i10_s3(mvert[mloop->v].no);
+                                       }
+                                       if (use_face_sel) {
+                                               pnor->w = (mpoly->flag & ME_FACE_SEL) ? 1 : 0;
                                        }
                                }
                        }
                                        }
                                }
                        }
@@ -3570,14 +3497,15 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
                        }
                        for (int b = 0; b < mpoly->totloop; b++, mloop++) {
                                copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop->v].co);
                        }
                        for (int b = 0; b < mpoly->totloop; b++, mloop++) {
                                copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop->v].co);
+                               GPUPackedNormal *pnor = (GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step);
                                if (lnors) {
                                if (lnors) {
-                                       *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(lnors);
+                                       *pnor = GPU_normal_convert_i10_v3(lnors);
                                }
                                else if (fnor) {
                                }
                                else if (fnor) {
-                                       *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *fnor;
+                                       *pnor = *fnor;
                                }
                                else {
                                }
                                else {
-                                       *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mvert[mloop->v].no);
+                                       *pnor = GPU_normal_convert_i10_s3(mvert[mloop->v].no);
                                }
                        }
                }
                                }
                        }
                }
@@ -4456,6 +4384,59 @@ static GPUIndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, Mesh
        return cache->ledges_in_order;
 }
 
        return cache->ledges_in_order;
 }
 
+static void mesh_create_loops_lines(
+        MeshRenderData *rdata, GPUIndexBuf *ibo, const bool use_hide)
+{
+       const int loop_len = mesh_render_data_loops_len_get(rdata);
+       const int poly_len = mesh_render_data_polys_len_get(rdata);
+
+       GPUIndexBufBuilder elb;
+       GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, loop_len + poly_len * 2, loop_len, true);
+
+       uint v_index = 0;
+       if (rdata->mapped.use == false) {
+               if (rdata->edit_bmesh) {
+                       BMesh *bm = rdata->edit_bmesh->bm;
+                       BMIter iter;
+                       BMFace *bm_face;
+
+                       BM_ITER_MESH (bm_face, &iter, bm, BM_FACES_OF_MESH) {
+                               /* use_hide always for edit-mode */
+                               if (!BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
+                                       for (int i; i < bm_face->len; i++) {
+                                               GPU_indexbuf_add_generic_vert(&elb, v_index + i);
+                                       }
+                                       /* Finish loop and restart primitive. */
+                                       GPU_indexbuf_add_generic_vert(&elb, v_index);
+                                       GPU_indexbuf_add_primitive_restart(&elb);
+                               }
+                               v_index += bm_face->len;
+                       }
+               }
+               else {
+                       for (int poly = 0; poly < poly_len; poly++) {
+                               const MPoly *mp = &rdata->mpoly[poly];
+                               if (!(use_hide && (mp->flag & ME_HIDE))) {
+                                       const int loopend = mp->loopstart + mp->totloop;
+                                       for (int j = mp->loopstart; j < loopend; j++) {
+                                               GPU_indexbuf_add_generic_vert(&elb, j);
+                                       }
+                                       /* Finish loop and restart primitive. */
+                                       GPU_indexbuf_add_generic_vert(&elb, mp->loopstart);
+                                       GPU_indexbuf_add_primitive_restart(&elb);
+                               }
+                               v_index += mp->totloop;
+                       }
+               }
+       }
+       else {
+               /* Implement ... eventually if needed. */
+               BLI_assert(0);
+       }
+
+       GPU_indexbuf_build_in_place(&elb, ibo);
+}
+
 static void mesh_create_surface_tris(
         MeshRenderData *rdata, GPUIndexBuf **ibo, int ibo_len, const bool use_hide)
 {
 static void mesh_create_surface_tris(
         MeshRenderData *rdata, GPUIndexBuf **ibo, int ibo_len, const bool use_hide)
 {
@@ -4521,74 +4502,6 @@ static void mesh_create_surface_tris(
        }
 }
 
        }
 }
 
-static GPUVertBuf *mesh_create_edge_pos_with_sel(
-        MeshRenderData *rdata, bool use_wire, bool use_select_bool, bool use_visible_bool)
-{
-       BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
-       BLI_assert(rdata->edit_bmesh == NULL);
-
-       GPUVertBuf *vbo;
-       {
-               uint vidx = 0, cidx = 0;
-
-               static GPUVertFormat format = { 0 };
-               static struct { uint pos, sel; } attr_id;
-               if (format.attr_len == 0) {
-                       attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-                       attr_id.sel = GPU_vertformat_attr_add(&format, "select", GPU_COMP_U8, 1, GPU_FETCH_INT);
-               }
-
-               const int edge_len = mesh_render_data_edges_len_get(rdata);
-
-               vbo = GPU_vertbuf_create_with_format(&format);
-
-               const int vbo_len_capacity = edge_len * 2;
-               int vbo_len_used = 0;
-               GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
-
-               if (use_select_bool) {
-                       mesh_render_data_ensure_edge_select_bool(rdata, use_wire);
-               }
-               bool *edge_select_bool = use_select_bool ? rdata->edge_select_bool : NULL;
-               if (use_visible_bool) {
-                       mesh_render_data_ensure_edge_visible_bool(rdata);
-               }
-               bool *edge_visible_bool = use_visible_bool ? rdata->edge_visible_bool : NULL;
-
-               for (int i = 0; i < edge_len; i++) {
-                       const MEdge *ed = &rdata->medge[i];
-
-                       if (use_visible_bool && !edge_visible_bool[i]) {
-                               continue;
-                       }
-
-                       uchar edge_vert_sel;
-                       if (use_select_bool && edge_select_bool[i]) {
-                               edge_vert_sel = true;
-                       }
-                       else if (use_wire) {
-                               edge_vert_sel = false;
-                       }
-                       else {
-                               continue;
-                       }
-
-                       GPU_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel);
-                       GPU_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel);
-
-                       GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v1].co);
-                       GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v2].co);
-               }
-               vbo_len_used = vidx;
-
-               if (vbo_len_capacity != vbo_len_used) {
-                       GPU_vertbuf_data_resize(vbo, vbo_len_used);
-               }
-       }
-
-       return vbo;
-}
-
 static GPUIndexBuf *mesh_create_tri_overlay_weight_faces(
         MeshRenderData *rdata)
 {
 static GPUIndexBuf *mesh_create_tri_overlay_weight_faces(
         MeshRenderData *rdata)
 {
@@ -5153,6 +5066,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
        return DRW_batch_request(&cache->batch.surface);
 }
 
        return DRW_batch_request(&cache->batch.surface);
 }
 
+/* TODO port to batch request. Is basically batch.wire_loops. */
 GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me)
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
 GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me)
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -5204,22 +5118,10 @@ GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me)
        return cache->texpaint_uv_loops;
 }
 
        return cache->texpaint_uv_loops;
 }
 
-GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel, bool use_hide)
+GPUBatch *DRW_mesh_batch_cache_get_wire_loops(Mesh *me)
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
-
-       if (cache->overlay_paint_edges == NULL) {
-               /* create batch from Mesh */
-               const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP;
-               MeshRenderData *rdata = mesh_render_data_create(me, datatype);
-
-               cache->overlay_paint_edges = GPU_batch_create_ex(
-                       GPU_PRIM_LINES, mesh_create_edge_pos_with_sel(rdata, use_wire, use_sel, use_hide), NULL, GPU_BATCH_OWNS_VBO);
-
-               mesh_render_data_free(rdata);
-       }
-
-       return cache->overlay_paint_edges;
+       return DRW_batch_request(&cache->batch.wire_loops);
 }
 
 GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)
 }
 
 GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)
@@ -5705,9 +5607,18 @@ void DRW_mesh_cache_uvedit(
  * \{ */
 
 /* Can be called for any surface type. Mesh *me is the final mesh. */
  * \{ */
 
 /* Can be called for any surface type. Mesh *me is the final mesh. */
-void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me)
+void DRW_mesh_batch_cache_create_requested(Object *ob, Mesh *me)
 {
 {
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+       const int mode = CTX_data_mode_enum_ex(draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
        const bool use_hide = false; /* TODO */
        const bool use_hide = false; /* TODO */
+       bool use_face_sel;
+
+       /* Tex paint face select */
+       if ((mode == CTX_MODE_PAINT_TEXTURE) && (ob->type == OB_MESH) && (draw_ctx->obact == ob)) {
+               const Mesh *me_orig = DEG_get_original_object(ob)->data;
+               use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
+       }
 
        MeshBatchCache *cache = mesh_batch_cache_get(me);
 
 
        MeshBatchCache *cache = mesh_batch_cache_get(me);
 
@@ -5760,6 +5671,10 @@ void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me)
        if (DRW_batch_requested(cache->batch.all_verts, GPU_PRIM_POINTS)) {
                DRW_vbo_request(cache->batch.all_verts, &cache->ordered.pos_nor);
        }
        if (DRW_batch_requested(cache->batch.all_verts, GPU_PRIM_POINTS)) {
                DRW_vbo_request(cache->batch.all_verts, &cache->ordered.pos_nor);
        }
+       if (DRW_batch_requested(cache->batch.wire_loops, GPU_PRIM_LINE_STRIP)) {
+               DRW_ibo_request(cache->batch.wire_loops, &cache->ibo.loops_lines);
+               DRW_vbo_request(cache->batch.wire_loops, &cache->ordered.loop_pos_nor);
+       }
        if (DRW_batch_requested(cache->batch.wire_triangles, GPU_PRIM_TRIS)) {
                DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.pos_nor);
                DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.wireframe_data);
        if (DRW_batch_requested(cache->batch.wire_triangles, GPU_PRIM_TRIS)) {
                DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.pos_nor);
                DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.wireframe_data);
@@ -5830,6 +5745,7 @@ void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me)
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surface_tris, MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI | MR_DATATYPE_POLY);
        DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surface_tris, MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
+       DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_lines, MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
        for (int i = 0; i < cache->mat_len; ++i) {
                DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->surf_per_mat_tris[i], MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        }
        for (int i = 0; i < cache->mat_len; ++i) {
                DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->surf_per_mat_tris[i], MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
        }
@@ -5858,7 +5774,7 @@ void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me)
                mesh_create_pos_and_nor(rdata, cache->ordered.pos_nor);
        }
        if (DRW_vbo_requested(cache->ordered.loop_pos_nor)) {
                mesh_create_pos_and_nor(rdata, cache->ordered.pos_nor);
        }
        if (DRW_vbo_requested(cache->ordered.loop_pos_nor)) {
-               mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor);
+               mesh_create_loop_pos_and_nor(rdata, cache->ordered.loop_pos_nor, use_face_sel);
        }
        if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
                mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
        }
        if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
                mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
@@ -5872,6 +5788,9 @@ void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me)
        if (DRW_vbo_requested(cache->tess.pos_nor)) {
                mesh_create_pos_and_nor_tess(rdata, cache->tess.pos_nor, use_hide);
        }
        if (DRW_vbo_requested(cache->tess.pos_nor)) {
                mesh_create_pos_and_nor_tess(rdata, cache->tess.pos_nor, use_hide);
        }
+       if (DRW_ibo_requested(cache->ibo.loops_lines)) {
+               mesh_create_loops_lines(rdata, cache->ibo.loops_lines, use_hide);
+       }
        if (DRW_ibo_requested(cache->ibo.surface_tris)) {
                mesh_create_surface_tris(rdata, &cache->ibo.surface_tris, 1, use_hide);
        }
        if (DRW_ibo_requested(cache->ibo.surface_tris)) {
                mesh_create_surface_tris(rdata, &cache->ibo.surface_tris, 1, use_hide);
        }
index 8e78d2f..8fb854e 100644 (file)
@@ -45,6 +45,9 @@ extern char datatoc_paint_texture_vert_glsl[];
 extern char datatoc_paint_texture_frag_glsl[];
 extern char datatoc_paint_wire_vert_glsl[];
 extern char datatoc_paint_wire_frag_glsl[];
 extern char datatoc_paint_texture_frag_glsl[];
 extern char datatoc_paint_wire_vert_glsl[];
 extern char datatoc_paint_wire_frag_glsl[];
+extern char datatoc_paint_face_vert_glsl[];
+
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
 
 /* If needed, contains all global/Theme colors
  * Add needed theme colors / values to DRW_globals_update() and update UBO
 
 /* If needed, contains all global/Theme colors
  * Add needed theme colors / values to DRW_globals_update() and update UBO
@@ -130,35 +133,12 @@ typedef struct PAINT_TEXTURE_PrivateData {
 /* *********** FUNCTIONS *********** */
 
 /* Init Textures, Framebuffers, Storage and Shaders.
 /* *********** FUNCTIONS *********** */
 
 /* Init Textures, Framebuffers, Storage and Shaders.
- * It is called for every frames.
- * (Optional) */
-static void PAINT_TEXTURE_engine_init(void *vedata)
+ * It is called for every frames. */
+static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata))
 {
 {
-       PAINT_TEXTURE_TextureList *txl = ((PAINT_TEXTURE_Data *)vedata)->txl;
-       PAINT_TEXTURE_FramebufferList *fbl = ((PAINT_TEXTURE_Data *)vedata)->fbl;
-       PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl;
-
-       UNUSED_VARS(txl, fbl, stl);
-
-       /* Init Framebuffers like this: order is attachment order (for color texs) */
-       /*
-        * DRWFboTexture tex[2] = {{&txl->depth, GPU_DEPTH_COMPONENT24, 0},
-        *                         {&txl->color, GPU_RGBA8, DRW_TEX_FILTER}};
-        */
-
-       /* DRW_framebuffer_init takes care of checking if
-        * the framebuffer is valid and has the right size*/
-       /*
-        * float *viewport_size = DRW_viewport_size_get();
-        * DRW_framebuffer_init(&fbl->occlude_wire_fb,
-        *                     (int)viewport_size[0], (int)viewport_size[1],
-        *                     tex, 2);
-        */
-
        if (!e_data.fallback_sh) {
                e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
        if (!e_data.fallback_sh) {
                e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
-       }
-       if (!e_data.image_sh) {
+
                e_data.image_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
 
                e_data.image_sh = DRW_shader_create_with_lib(
                e_data.image_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
 
                e_data.image_sh = DRW_shader_create_with_lib(
@@ -166,18 +146,15 @@ static void PAINT_TEXTURE_engine_init(void *vedata)
                        datatoc_paint_texture_frag_glsl,
                        datatoc_common_globals_lib_glsl, NULL);
 
                        datatoc_paint_texture_frag_glsl,
                        datatoc_common_globals_lib_glsl, NULL);
 
-       }
-
-       if (!e_data.wire_overlay_shader) {
                e_data.wire_overlay_shader = DRW_shader_create_with_lib(
                        datatoc_paint_wire_vert_glsl, NULL,
                        datatoc_paint_wire_frag_glsl,
                        datatoc_common_globals_lib_glsl,
                        "#define VERTEX_MODE\n");
                e_data.wire_overlay_shader = DRW_shader_create_with_lib(
                        datatoc_paint_wire_vert_glsl, NULL,
                        datatoc_paint_wire_frag_glsl,
                        datatoc_common_globals_lib_glsl,
                        "#define VERTEX_MODE\n");
-       }
 
 
-       if (!e_data.face_overlay_shader) {
-               e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+               e_data.face_overlay_shader = DRW_shader_create(
+                       datatoc_paint_face_vert_glsl, NULL,
+                       datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
        }
 }
 
        }
 }
 
@@ -328,12 +305,10 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob)
                /* Face Mask */
                if (use_face_sel) {
                        struct GPUBatch *geom;
                /* Face Mask */
                if (use_face_sel) {
                        struct GPUBatch *geom;
-                       /* Note: ideally selected faces wouldn't show interior wire. */
-                       const bool use_wire = true;
-                       geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+                       geom = DRW_cache_mesh_wire_get(ob);
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
 
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
 
-                       geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+                       geom = DRW_cache_mesh_surface_get(ob);
                        DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
                }
        }
                        DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
                }
        }
index d026e7a..50aeece 100644 (file)
@@ -163,12 +163,12 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob)
                }
 
                if (use_face_sel || use_wire) {
                }
 
                if (use_face_sel || use_wire) {
-                       geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+                       geom = DRW_cache_mesh_wire_get(ob);
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
                }
 
                if (use_face_sel) {
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
                }
 
                if (use_face_sel) {
-                       geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+                       geom = DRW_cache_mesh_surface_get(ob);
                        DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
                }
        }
                        DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
                }
        }
index 935c236..c050df4 100644 (file)
@@ -197,7 +197,7 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
                }
 
                if (use_face_sel || use_wire) {
                }
 
                if (use_face_sel || use_wire) {
-                       geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel);
+                       geom = DRW_cache_mesh_wire_get(ob);
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
                }
 
                        DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
                }
 
diff --git a/source/blender/draw/modes/shaders/paint_face_vert.glsl b/source/blender/draw/modes/shaders/paint_face_vert.glsl
new file mode 100644 (file)
index 0000000..437eeb2
--- /dev/null
@@ -0,0 +1,14 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 nor; /* select flag on the 4th component */
+
+void main()
+{
+       gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+       /* Don't draw faces that are selected. */
+       if (nor.w > 0.0) {
+               gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+       }
+}