UVEdit: Port texpaint_loop_wire to batch request
authorClément Foucault <foucault.clem@gmail.com>
Thu, 10 Jan 2019 21:22:42 +0000 (22:22 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Fri, 11 Jan 2019 15:00:23 +0000 (16:00 +0100)
This removes code duplication and put an end to the old "create at request"
batch creation.

Also it uses the same vbo as the uv layer used for shading. Reducing VRAM
usage.

Also fixes the modified uv display in uv edit mode.

source/blender/draw/intern/draw_cache_impl.h
source/blender/draw/intern/draw_cache_impl_mesh.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/shaders/gpu_shader_2D_vert.glsl

index 9f41621..63af602 100644 (file)
@@ -139,12 +139,11 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edituv_faces(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_edituv_edges(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_edituv_verts(struct Mesh *me);
 struct GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(struct Mesh *me);
+/* For Image UV editor. */
+struct GPUBatch *DRW_mesh_batch_cache_get_uv_edges(struct Mesh *me);
 
 void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
 
-/* For Image UV editor. */
-struct GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(struct Mesh *me);
-
 /* Edit mesh bitflags (is this the right place?) */
 
 enum {
index 0bac64d..92131a2 100644 (file)
@@ -2100,15 +2100,13 @@ typedef struct MeshBatchCache {
                GPUBatch *loose_edges;
                GPUBatch *edge_detection;
                GPUBatch *wire_loops; /* Loops around faces. */
+               GPUBatch *wire_loops_uvs; /* Same as wire_loops but only has uvs. */
                GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
        } batch;
 
        GPUIndexBuf **surf_per_mat_tris;
        GPUBatch **surf_per_mat;
 
-       /* OLD BATCH METHOD, thoses needs to be ported and added in the structs above. */
-       GPUBatch *texpaint_uv_loops;
-
        /* arrays of bool uniform names (and value) that will be use to
         * set srgb conversion for auto attribs.*/
        char *auto_layer_names;
@@ -2272,10 +2270,6 @@ static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
        GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges);
        GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts);
        GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_facedots);
-
-       gpu_batch_presets_unregister(cache->texpaint_uv_loops);
-
-       GPU_BATCH_DISCARD_SAFE(cache->texpaint_uv_loops);
 }
 
 void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
@@ -4667,56 +4661,11 @@ GPUBatch *DRW_mesh_batch_cache_get_edituv_facedots(Mesh *me)
        return DRW_batch_request(&cache->batch.edituv_facedots);
 }
 
-/* TODO port to batch request. Is basically batch.wire_loops. */
-GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me)
+GPUBatch *DRW_mesh_batch_cache_get_uv_edges(Mesh *me)
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
-
-       if (cache->texpaint_uv_loops == NULL) {
-               /* create batch from DM */
-               const int datatype = MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPUV;
-               MeshRenderData *rdata = mesh_render_data_create(me, datatype);
-
-               const MLoopUV *mloopuv_base = rdata->mloopuv;
-               if (mloopuv_base == NULL) {
-                       return NULL;
-               }
-
-               uint vidx = 0;
-
-               static GPUVertFormat format = { 0 };
-               static struct { uint uv; } attr_id;
-               if (format.attr_len == 0) {
-                       attr_id.uv = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-               }
-
-               const uint vert_len = mesh_render_data_loops_len_get(rdata);
-               const uint poly_len = mesh_render_data_polys_len_get(rdata);
-               const uint idx_len = vert_len + poly_len;
-
-               GPUIndexBufBuilder elb;
-               GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_LOOP, idx_len, vert_len, true);
-
-               GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
-               GPU_vertbuf_data_alloc(vbo, vert_len);
-
-               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++) {
-                               GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx, mloopuv->uv);
-                               GPU_indexbuf_add_generic_vert(&elb, vidx++);
-                       }
-                       GPU_indexbuf_add_primitive_restart(&elb);
-               }
-
-               cache->texpaint_uv_loops = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP,
-                                                              vbo, GPU_indexbuf_build(&elb),
-                                                              GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
-               gpu_batch_presets_register(cache->texpaint_uv_loops);
-               mesh_render_data_free(rdata);
-       }
-       return cache->texpaint_uv_loops;
+       texpaint_request_active_uv(cache, me);
+       return DRW_batch_request(&cache->batch.wire_loops_uvs);
 }
 
 GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Mesh *me)
@@ -5154,6 +5103,13 @@ void DRW_mesh_batch_cache_create_requested(
                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_loops_uvs, GPU_PRIM_LINE_STRIP)) {
+               DRW_ibo_request(cache->batch.wire_loops_uvs, &cache->ibo.loops_lines);
+               /* For paint overlay. Active layer should have been queried. */
+               if (cache->cd_lused[CD_MLOOPUV] != 0) {
+                       DRW_vbo_request(cache->batch.wire_loops_uvs, &cache->ordered.loop_uv_tan);
+               }
+       }
        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);
index 46c62c4..356f24e 100644 (file)
@@ -199,16 +199,15 @@ static void uvedit_get_batches(
 static void draw_uvs_shadow(SpaceImage *UNUSED(sima), Scene *scene, Object *obedit, Depsgraph *depsgraph)
 {
        Object *eval_ob = DEG_get_evaluated_object(depsgraph, obedit);
+       Mesh *me = eval_ob->data;
        float col[4];
        UI_GetThemeColor4fv(TH_UV_SHADOW, col);
 
-       /* TODO get real modified edges. */
-       GPUBatch *edges = DRW_mesh_batch_cache_get_edituv_edges(eval_ob->data);
-
-       DRW_mesh_batch_cache_create_requested(eval_ob, eval_ob->data, scene->toolsettings, false, false);
+       GPUBatch *edges = DRW_mesh_batch_cache_get_uv_edges(me);
+       DRW_mesh_batch_cache_create_requested(eval_ob, me, scene->toolsettings, false, false);
 
        if (edges) {
-               GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_UNIFORM_COLOR);
+               GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_UV_UNIFORM_COLOR);
                GPU_batch_uniform_4fv(edges, "color", col);
                GPU_batch_draw(edges);
        }
@@ -219,14 +218,17 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
        Object *eval_ob = DEG_get_evaluated_object(depsgraph, ob);
        Mesh *me = eval_ob->data;
        ToolSettings *ts = scene->toolsettings;
-       GPUBatch *geom = DRW_mesh_batch_cache_get_texpaint_loop_wire(me);
        float col[4];
        UI_GetThemeColor4fv(TH_UV_SHADOW, col);
 
-       if (!geom)
+       if (me->mloopuv == NULL) {
                return;
+       }
+
+       GPUBatch *geom = DRW_mesh_batch_cache_get_uv_edges(me);
+       DRW_mesh_batch_cache_create_requested(eval_ob, me, scene->toolsettings, false, false);
 
-       GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_UNIFORM_COLOR);
+       GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_UV_UNIFORM_COLOR);
        GPU_batch_uniform_4fv(geom, "color", col);
 
        const bool do_material_masking = (ts->uv_flag & UV_SHOW_SAME_IMAGE);
@@ -275,8 +277,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
        float col1[4], col2[4], col3[4], transparent[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 
        if (sima->flag & SI_DRAWSHADOW) {
-               /* XXX TODO: Need to check if shadow mesh is different than original mesh. */
-               bool is_cage_like_final_meshes = true;
+               bool is_cage_like_final_meshes = false;
+               Mesh *me = (Mesh *)eval_ob->data;
+               BMEditMesh *embm = me->edit_btmesh;
+               is_cage_like_final_meshes = embm &&
+                                           embm->mesh_eval_final &&
+                                           embm->mesh_eval_final->runtime.is_original;
 
                /* When sync selection is enabled, all faces are drawn (except for hidden)
                 * so if cage is the same as the final, there is no point in drawing this. */
index 7153652..4803c6c 100644 (file)
@@ -344,6 +344,7 @@ typedef enum GPUBuiltinShader {
        GPU_SHADER_2D_NODELINK,
        GPU_SHADER_2D_NODELINK_INST,
        /* specialized for edituv drawing */
+       GPU_SHADER_2D_UV_UNIFORM_COLOR,
        GPU_SHADER_2D_UV_VERTS,
        GPU_SHADER_2D_UV_FACEDOTS,
        GPU_SHADER_2D_UV_EDGES,
index 8a3581c..8a141ea 100644 (file)
@@ -918,6 +918,9 @@ static const GPUShaderStages builtin_shader_stages[GPU_NUM_BUILTIN_SHADERS] = {
                { datatoc_gpu_shader_2D_nodelink_vert_glsl,
                  datatoc_gpu_shader_2D_nodelink_frag_glsl },
 
+       [GPU_SHADER_2D_UV_UNIFORM_COLOR] =
+               { datatoc_gpu_shader_2D_vert_glsl,
+                 datatoc_gpu_shader_uniform_color_frag_glsl },
        [GPU_SHADER_2D_UV_VERTS] =
                { datatoc_gpu_shader_2D_edituvs_points_vert_glsl,
                  datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl },
@@ -1007,6 +1010,9 @@ static const char *gpu_shader_get_builtin_shader_defines(
                case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
                        return "#define USE_FLAT_NORMAL\n";
 
+               case GPU_SHADER_2D_UV_UNIFORM_COLOR:
+                       return "#define UV_POS\n";
+
                case GPU_SHADER_2D_UV_EDGES_SMOOTH:
                        return "#define SMOOTH_COLOR\n";
 
index 89e3c52..b3b897d 100644 (file)
@@ -1,7 +1,12 @@
 
 uniform mat4 ModelViewProjectionMatrix;
 
+#ifdef UV_POS
+in vec2 u;
+#  define pos u
+#else
 in vec2 pos;
+#endif
 
 void main()
 {