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 9f4162195bf314a297d615ce937b728cc59706a9..63af602873d29c027e12474bb271b997746728db 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 0bac64df5673dea8b3a21deff427a27ca5e118fc..92131a2e74c2caed92167b77b54b473c8676ddde 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 46c62c4a086ebd93454a37cd211df0a710c86ce2..356f24e0758d6aa83ad340d672cca68e6bb985e4 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 71536523caf81737debd94843344559a8ede6f41..4803c6c07925ca4a3562aaf0cf153dd4c503401a 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 8a3581c54dff085b7d9af31818d5660c8deaf477..8a141eaa2b240db2bc6be7fa4cdf67d156d406d3 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 89e3c52f9f8c31296a3162bb0466e9d6ac2a845b..b3b897da3c6b33c0a929350ef11c55879318788a 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()
 {