Merge branch 'blender2.7'
[blender.git] / source / blender / draw / modes / edit_mesh_mode.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file blender/draw/modes/edit_mesh_mode.c
20  *  \ingroup draw
21  */
22
23 #include "DRW_engine.h"
24 #include "DRW_render.h"
25
26 #include "GPU_shader.h"
27
28 #include "DNA_mesh_types.h"
29 #include "DNA_view3d_types.h"
30
31 #include "draw_common.h"
32
33 #include "draw_cache_impl.h"
34 #include "draw_mode_engines.h"
35
36 #include "edit_mesh_mode_intern.h" /* own include */
37
38 #include "BKE_editmesh.h"
39 #include "BKE_object.h"
40
41 #include "BLI_dynstr.h"
42 #include "BLI_string_utils.h"
43
44 extern char datatoc_common_world_clip_lib_glsl[];
45
46 extern char datatoc_paint_weight_vert_glsl[];
47 extern char datatoc_paint_weight_frag_glsl[];
48
49 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
50 extern char datatoc_edit_mesh_overlay_frag_glsl[];
51 extern char datatoc_edit_mesh_overlay_vert_glsl[];
52 extern char datatoc_edit_mesh_overlay_geom_tri_glsl[];
53 extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
54 extern char datatoc_edit_mesh_overlay_points_vert_glsl[];
55 extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
56 extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
57 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
58 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
59 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
60 extern char datatoc_edit_normals_vert_glsl[];
61 extern char datatoc_edit_normals_geom_glsl[];
62 extern char datatoc_common_globals_lib_glsl[];
63
64 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
65 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
66 extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
67 extern char datatoc_gpu_shader_depth_only_frag_glsl[];
68
69 /* *********** LISTS *********** */
70 typedef struct EDIT_MESH_PassList {
71         struct DRWPass *weight_faces;
72         struct DRWPass *depth_hidden_wire;
73         struct DRWPass *ghost_clear_depth;
74         struct DRWPass *edit_face_overlay;
75         struct DRWPass *edit_face_occluded;
76         struct DRWPass *mix_occlude;
77         struct DRWPass *facefill_occlude;
78         struct DRWPass *normals;
79 } EDIT_MESH_PassList;
80
81 typedef struct EDIT_MESH_FramebufferList {
82         struct GPUFrameBuffer *occlude_wire_fb;
83         struct GPUFrameBuffer *ghost_wire_fb;
84 } EDIT_MESH_FramebufferList;
85
86 typedef struct EDIT_MESH_StorageList {
87         struct EDIT_MESH_PrivateData *g_data;
88 } EDIT_MESH_StorageList;
89
90 typedef struct EDIT_MESH_Data {
91         void *engine_type;
92         EDIT_MESH_FramebufferList *fbl;
93         DRWViewportEmptyList *txl;
94         EDIT_MESH_PassList *psl;
95         EDIT_MESH_StorageList *stl;
96 } EDIT_MESH_Data;
97
98 #define MAX_SHADERS 16
99
100 /** Can only contain shaders (freed as array). */
101 typedef struct EDIT_MESH_Shaders {
102         /* weight */
103         GPUShader *weight_face;
104
105         /* Geometry */
106         GPUShader *overlay_tri_cache[MAX_SHADERS];
107         GPUShader *overlay_loose_edge_cache[MAX_SHADERS];
108
109         GPUShader *overlay_vert;
110         GPUShader *overlay_lvert;
111         GPUShader *overlay_facedot;
112         GPUShader *overlay_mix;
113         GPUShader *overlay_facefill;
114         GPUShader *normals_face;
115         GPUShader *normals_loop;
116         GPUShader *normals;
117         GPUShader *depth;
118         GPUShader *ghost_clear_depth;
119 } EDIT_MESH_Shaders;
120
121 /* *********** STATIC *********** */
122 static struct {
123         EDIT_MESH_Shaders sh_data[DRW_SHADER_SLOT_LEN];
124
125         /* temp buffer texture */
126         struct GPUTexture *occlude_wire_depth_tx;
127         struct GPUTexture *occlude_wire_color_tx;
128 } e_data = {NULL}; /* Engine data */
129
130 typedef struct EDIT_MESH_PrivateData {
131         /* weight */
132         DRWShadingGroup *fweights_shgrp;
133         DRWShadingGroup *depth_shgrp_hidden_wire;
134
135         DRWShadingGroup *fnormals_shgrp;
136         DRWShadingGroup *vnormals_shgrp;
137         DRWShadingGroup *lnormals_shgrp;
138
139         DRWShadingGroup *face_shgrp;
140         DRWShadingGroup *face_cage_shgrp;
141
142         DRWShadingGroup *verts_shgrp;
143         DRWShadingGroup *ledges_shgrp;
144         DRWShadingGroup *lverts_shgrp;
145         DRWShadingGroup *facedot_shgrp;
146
147         DRWShadingGroup *facefill_occluded_shgrp;
148
149         int data_mask[4];
150         int ghost_ob;
151         int edit_ob;
152         bool do_zbufclip;
153         bool do_faces;
154         bool do_edges;
155         float edge_width_scale;
156 } EDIT_MESH_PrivateData; /* Transient data */
157
158 /* *********** FUNCTIONS *********** */
159
160 static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode)
161 {
162         int result = tsettings->selectmode << 1;
163         if (supports_fast_mode) {
164                 SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0);
165         }
166         return result;
167 }
168
169 static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias, bool looseedge)
170 {
171         const int selectmode = tsettings->selectmode;
172         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
173
174         char *str = NULL;
175         DynStr *ds = BLI_dynstr_new();
176
177         if (selectmode & SCE_SELECT_VERTEX) {
178                 BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n");
179         }
180
181         if (selectmode & SCE_SELECT_EDGE) {
182                 BLI_dynstr_append(ds, "#define EDGE_SELECTION\n");
183         }
184
185         if (selectmode & SCE_SELECT_FACE) {
186                 BLI_dynstr_append(ds, "#define FACE_SELECTION\n");
187         }
188
189         if (!fast_mode || looseedge) {
190                 BLI_dynstr_append(ds, "#define EDGE_FIX\n");
191         }
192
193         if (anti_alias) {
194                 BLI_dynstr_append(ds, "#define ANTI_ALIASING\n");
195         }
196
197         if (!looseedge) {
198                 BLI_dynstr_append(ds, "#define VERTEX_FACING\n");
199         }
200         str = BLI_dynstr_get_cstring(ds);
201         BLI_dynstr_free(ds);
202         return str;
203 }
204 static GPUShader *EDIT_MESH_ensure_shader(
205         EDIT_MESH_Shaders *sh_data,
206         ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode, bool looseedge)
207 {
208         const int index = EDIT_MESH_sh_index(tsettings, rv3d, supports_fast_mode);
209         const bool fast_mode = (rv3d->rflag & RV3D_NAVIGATING) != 0;
210         const bool is_clip = (rv3d->rflag & RV3D_CLIPPING) != 0;
211         const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
212         const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
213
214         if (looseedge) {
215                 if (!sh_data->overlay_loose_edge_cache[index]) {
216                         char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
217                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, true);
218                         sh_data->overlay_loose_edge_cache[index] = DRW_shader_create_from_arrays({
219                                 .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
220                                 .geom = (const char *[]){lib, datatoc_edit_mesh_overlay_geom_edge_glsl, NULL},
221                                 .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
222                                 .defs = (const char *[]){world_clip_def_or_empty, defines, NULL},
223                         });
224                         MEM_freeN(lib);
225                         MEM_freeN(defines);
226                 }
227                 return sh_data->overlay_loose_edge_cache[index];
228         }
229         else {
230                 if (!sh_data->overlay_tri_cache[index]) {
231                         char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
232                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, false);
233                         sh_data->overlay_tri_cache[index] = DRW_shader_create_from_arrays({
234                                 .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
235                                 .geom = fast_mode ? NULL : (const char *[]){lib, datatoc_edit_mesh_overlay_geom_tri_glsl, NULL},
236                                 .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
237                                 .defs = (const char *[]){world_clip_def_or_empty, defines, NULL},
238                         });
239                         MEM_freeN(lib);
240                         MEM_freeN(defines);
241                 }
242                 return sh_data->overlay_tri_cache[index];
243         }
244 }
245
246 static void EDIT_MESH_engine_init(void *vedata)
247 {
248         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
249
250         const DRWContextState *draw_ctx = DRW_context_state_get();
251         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
252         const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
253
254         const float *viewport_size = DRW_viewport_size_get();
255         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
256
257         e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
258                                                                  &draw_engine_edit_mesh_type);
259         e_data.occlude_wire_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
260                                                                  &draw_engine_edit_mesh_type);
261
262         GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb, {
263                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
264                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)
265         });
266
267         if (is_clip) {
268                 DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
269         }
270
271         const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
272         const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
273
274         if (!sh_data->weight_face) {
275                 sh_data->weight_face = DRW_shader_create_from_arrays({
276                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
277                         .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
278                         .defs = (const char *[]){world_clip_def_or_empty, NULL},
279                 });
280         }
281
282         if (!sh_data->overlay_vert) {
283                 char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
284                 sh_data->overlay_vert = DRW_shader_create_from_arrays({
285                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL},
286                         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
287                         .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL},
288                 });
289
290                 sh_data->overlay_lvert = DRW_shader_create_from_arrays({
291                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL},
292                         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
293                         .defs = (const char *[]){world_clip_def_or_empty, NULL},
294                 });
295                 MEM_freeN(lib);
296         }
297         if (!sh_data->overlay_facedot) {
298                 sh_data->overlay_facedot = DRW_shader_create_from_arrays({
299                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL},
300                         .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_frag_glsl, NULL},
301                         .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL},
302                 });
303         }
304         if (!sh_data->overlay_mix) {
305                 sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
306         }
307         if (!sh_data->overlay_facefill) {
308                 sh_data->overlay_facefill = DRW_shader_create_from_arrays({
309                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL},
310                         .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL},
311                         .defs = (const char *[]){world_clip_def_or_empty, NULL},
312                 });
313         }
314         if (!sh_data->normals_face) {
315                 sh_data->normals_face = DRW_shader_create_from_arrays({
316                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
317                         .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
318                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
319                         .defs = (const char *[]){world_clip_def_or_empty, "#define FACE_NORMALS\n", NULL},
320                 });
321         }
322         if (!sh_data->normals_loop) {
323                 sh_data->normals_loop = DRW_shader_create_from_arrays({
324                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
325                         .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
326                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
327                         .defs = (const char *[]){world_clip_def_or_empty, "#define LOOP_NORMALS\n", NULL},
328                 });
329         }
330         if (!sh_data->normals) {
331                 sh_data->normals = DRW_shader_create_from_arrays({
332                         .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL},
333                         .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL},
334                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
335                         .defs = (const char *[]){world_clip_def_or_empty, NULL},
336                 });
337         }
338         if (!sh_data->depth) {
339                 sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_slot);
340         }
341         if (!sh_data->ghost_clear_depth) {
342                 sh_data->ghost_clear_depth = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL);
343         }
344
345 }
346
347 static DRWPass *edit_mesh_create_overlay_pass(
348         float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool xray,
349         DRWState statemod,
350         DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp,
351         DRWShadingGroup **r_verts_shgrp, DRWShadingGroup **r_ledges_shgrp,
352         DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp)
353 {
354         GPUShader *tri_sh, *ledge_sh;
355         const DRWContextState *draw_ctx = DRW_context_state_get();
356         RegionView3D *rv3d = draw_ctx->rv3d;
357         Scene *scene = draw_ctx->scene;
358         ToolSettings *tsettings = scene->toolsettings;
359         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
360         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
361
362         ledge_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, false, true);
363         tri_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, true, false);
364
365         DRWPass *pass = DRW_pass_create(
366                 "Edit Mesh Face Overlay Pass",
367                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
368
369         DRWShadingGroup *grp;
370
371         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
372                 grp = *r_lverts_shgrp = DRW_shgroup_create(sh_data->overlay_lvert, pass);
373                 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
374                 DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
375                 DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
376                 DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
377                 DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
378                 if (rv3d->rflag & RV3D_CLIPPING) {
379                         DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
380                 }
381
382                 grp = *r_verts_shgrp = DRW_shgroup_create(sh_data->overlay_vert, pass);
383                 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
384                 DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
385                 DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
386                 DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
387                 DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
388                 if (rv3d->rflag & RV3D_CLIPPING) {
389                         DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
390                 }
391         }
392
393         if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
394                 grp = *r_facedot_shgrp = DRW_shgroup_create(sh_data->overlay_facedot, pass);
395                 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
396                 DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
397                 DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
398                 if (rv3d->rflag & RV3D_CLIPPING) {
399                         DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
400                 }
401         }
402
403         grp = *r_face_shgrp = DRW_shgroup_create(tri_sh, pass);
404         DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
405         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
406         DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
407         DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
408         DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
409         DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
410         if (!fast_mode) {
411                 DRW_shgroup_uniform_bool_copy(grp, "isXray", xray);
412         }
413         else {
414                 /* To be able to use triple load. */
415                 DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
416         }
417         if (rv3d->rflag & RV3D_CLIPPING) {
418                 DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
419         }
420
421         /* Cage geom needs to be offseted to avoid Z-fighting. */
422         grp = *r_face_cage_shgrp = DRW_shgroup_create_sub(*r_face_shgrp);
423         DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
424
425         grp = *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
426         DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
427         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
428         DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1);
429         DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
430         DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
431         if (rv3d->rflag & RV3D_CLIPPING) {
432                 DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
433         }
434
435         return pass;
436 }
437
438 static float backwire_opacity;
439 static float face_mod;
440 static float size_normal;
441
442 static void EDIT_MESH_cache_init(void *vedata)
443 {
444         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
445         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
446         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
447
448         const DRWContextState *draw_ctx = DRW_context_state_get();
449         View3D *v3d = draw_ctx->v3d;
450         RegionView3D *rv3d = draw_ctx->rv3d;
451         Scene *scene = draw_ctx->scene;
452         ToolSettings *tsettings = scene->toolsettings;
453         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot];
454         static float zero = 0.0f;
455
456         if (!stl->g_data) {
457                 /* Alloc transient pointers */
458                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
459         }
460         stl->g_data->ghost_ob = 0;
461         stl->g_data->edit_ob = 0;
462         stl->g_data->do_faces = true;
463         stl->g_data->do_edges = true;
464
465         stl->g_data->do_zbufclip = ((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0;
466
467         /* Applies on top of the theme edge width, so edge-mode can have thick edges. */
468         stl->g_data->edge_width_scale = (tsettings->selectmode & (SCE_SELECT_EDGE)) ? 1.75f : 1.0f;
469
470         stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
471         stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
472         stl->g_data->data_mask[2] = 0xFF; /* Crease */
473         stl->g_data->data_mask[3] = 0xFF; /* BWeight */
474
475         if (draw_ctx->object_edit->type == OB_MESH) {
476                 if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
477                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE) == 0) {
478                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
479                         }
480                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACES) == 0) {
481                                 stl->g_data->data_mask[0] &= ~(VFLAG_FACE_SELECTED & VFLAG_FACE_FREESTYLE);
482                                 stl->g_data->do_faces = false;
483                         }
484                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
485                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
486                         }
487                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SHARP) == 0) {
488                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
489                         }
490                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE) == 0) {
491                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
492                         }
493                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
494                                 if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
495                                         stl->g_data->data_mask[1] &= ~(VFLAG_EDGE_ACTIVE & VFLAG_EDGE_SELECTED);
496                                         stl->g_data->do_edges = false;
497                                 }
498                         }
499                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CREASES) == 0) {
500                                 stl->g_data->data_mask[2] = 0x0;
501                         }
502                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_BWEIGHTS) == 0) {
503                                 stl->g_data->data_mask[3] = 0x0;
504                         }
505                 }
506         }
507
508         {
509                 psl->weight_faces = DRW_pass_create(
510                         "Weight Pass",
511                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
512
513                 stl->g_data->fweights_shgrp = DRW_shgroup_create(sh_data->weight_face, psl->weight_faces);
514
515                 static float alpha = 1.0f;
516                 DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &alpha, 1);
517                 DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", G_draw.weight_ramp);
518                 DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", G_draw.block_ubo);
519                 if (rv3d->rflag & RV3D_CLIPPING) {
520                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
521                 }
522         }
523
524         {
525                 /* Complementary Depth Pass */
526                 psl->depth_hidden_wire = DRW_pass_create(
527                         "Depth Pass Hidden Wire",
528                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
529                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(sh_data->depth, psl->depth_hidden_wire);
530                 if (rv3d->rflag & RV3D_CLIPPING) {
531                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
532                 }
533         }
534
535         {
536                 /* Depth clearing for ghosting. */
537                 psl->ghost_clear_depth = DRW_pass_create(
538                         "Ghost Depth Clear",
539                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
540
541                 DRWShadingGroup *shgrp = DRW_shgroup_create(sh_data->ghost_clear_depth, psl->ghost_clear_depth);
542                 DRW_shgroup_stencil_mask(shgrp, 0x00);
543                 DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
544         }
545
546         {
547                 /* Normals */
548                 psl->normals = DRW_pass_create(
549                         "Edit Mesh Normals Pass",
550                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
551
552                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(sh_data->normals_face, psl->normals);
553                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
554                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", G_draw.block.colorNormal, 1);
555                 if (rv3d->rflag & RV3D_CLIPPING) {
556                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fnormals_shgrp, rv3d);
557                 }
558
559                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(sh_data->normals, psl->normals);
560                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
561                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", G_draw.block.colorVNormal, 1);
562                 if (rv3d->rflag & RV3D_CLIPPING) {
563                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vnormals_shgrp, rv3d);
564                 }
565
566                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(sh_data->normals_loop, psl->normals);
567                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
568                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", G_draw.block.colorLNormal, 1);
569                 if (rv3d->rflag & RV3D_CLIPPING) {
570                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lnormals_shgrp, rv3d);
571                 }
572         }
573
574         if (!stl->g_data->do_zbufclip) {
575                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
576                         &face_mod, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, false,
577                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
578                         &stl->g_data->face_shgrp,
579                         &stl->g_data->face_cage_shgrp,
580                         &stl->g_data->verts_shgrp,
581                         &stl->g_data->ledges_shgrp,
582                         &stl->g_data->lverts_shgrp,
583                         &stl->g_data->facedot_shgrp);
584         }
585         else {
586                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
587                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
588                         &zero, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, true,
589                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
590                         &stl->g_data->face_shgrp,
591                         &stl->g_data->face_cage_shgrp,
592                         &stl->g_data->verts_shgrp,
593                         &stl->g_data->ledges_shgrp,
594                         &stl->g_data->lverts_shgrp,
595                         &stl->g_data->facedot_shgrp);
596
597                 /* however we loose the front faces value (because we need the depth of occluded wires and
598                  * faces are alpha blended ) so we recover them in a new pass. */
599                 psl->facefill_occlude = DRW_pass_create(
600                         "Front Face Color",
601                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
602                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(sh_data->overlay_facefill, psl->facefill_occlude);
603                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", G_draw.block_ubo);
604                 DRW_shgroup_uniform_ivec4(stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
605                 if (rv3d->rflag & RV3D_CLIPPING) {
606                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->facefill_occluded_shgrp, rv3d);
607                 }
608
609                 /* we need a full screen pass to combine the result */
610                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
611
612                 psl->mix_occlude = DRW_pass_create(
613                         "Mix Occluded Wires",
614                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
615                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(sh_data->overlay_mix, psl->mix_occlude);
616                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
617                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
618                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
619                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
620                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
621         }
622 }
623
624 static void edit_mesh_add_ob_to_pass(
625         Scene *scene, Object *ob,
626         EDIT_MESH_PrivateData *g_data,
627         DRWShadingGroup *facedot_shgrp,
628         DRWShadingGroup *facefill_shgrp)
629 {
630         struct GPUBatch *geom_tris, *geom_verts, *geom_ledges, *geom_ledges_nor, *geom_lverts, *geom_fcenter;
631         ToolSettings *tsettings = scene->toolsettings;
632
633         bool has_edit_mesh_cage = false;
634         /* TODO: Should be its own function. */
635         Mesh *me = (Mesh *)ob->data;
636         BMEditMesh *embm = me->edit_btmesh;
637         if (embm) {
638                 has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
639         }
640
641         DRWShadingGroup *face_shgrp = (has_edit_mesh_cage) ? g_data->face_cage_shgrp : g_data->face_shgrp;
642         DRWShadingGroup *verts_shgrp = g_data->verts_shgrp;
643         DRWShadingGroup *ledges_shgrp = g_data->ledges_shgrp;
644         DRWShadingGroup *lverts_shgrp = g_data->lverts_shgrp;
645
646         geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
647         geom_ledges = DRW_mesh_batch_cache_get_edit_loose_edges(ob->data);
648         DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat);
649         DRW_shgroup_call_add(ledges_shgrp, geom_ledges, ob->obmat);
650
651         if (facefill_shgrp) {
652                 DRW_shgroup_call_add(facefill_shgrp, geom_tris, ob->obmat);
653         }
654
655         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
656                 /* Thoses are point batches. */
657                 geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
658                 geom_ledges_nor = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data);
659                 geom_lverts = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data);
660                 DRW_shgroup_call_add(verts_shgrp, geom_verts, ob->obmat);
661                 DRW_shgroup_call_add(lverts_shgrp, geom_ledges_nor, ob->obmat);
662                 DRW_shgroup_call_add(lverts_shgrp, geom_lverts, ob->obmat);
663         }
664
665         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) {
666                 geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
667                 DRW_shgroup_call_add(facedot_shgrp, geom_fcenter, ob->obmat);
668         }
669 }
670
671 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
672 {
673         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
674         const DRWContextState *draw_ctx = DRW_context_state_get();
675         View3D *v3d = draw_ctx->v3d;
676         Scene *scene = draw_ctx->scene;
677         ToolSettings *tsettings = scene->toolsettings;
678         struct GPUBatch *geom;
679
680         if (ob->type == OB_MESH) {
681                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
682                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
683                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
684                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
685                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
686                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
687
688                         bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0;
689
690                         if (stl->g_data->do_faces == false &&
691                             stl->g_data->do_edges == false &&
692                             (tsettings->selectmode & SCE_SELECT_FACE))
693                         {
694                                 /* Force display of face centers in this case because that's
695                                  * the only way to see if a face is selected. */
696                                 show_face_dots = true;
697                         }
698
699                         /* Updating uniform */
700                         backwire_opacity = v3d->overlay.backwire_opacity;
701                         size_normal = v3d->overlay.normals_length;
702
703                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
704
705                         if (!stl->g_data->do_faces) {
706                                 face_mod = 0.0f;
707                         }
708
709                         if (do_show_weight) {
710                                 geom = DRW_cache_mesh_surface_weights_get(ob);
711                                 DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
712                         }
713
714                         if (do_occlude_wire) {
715                                 geom = DRW_cache_mesh_surface_get(ob);
716                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
717                         }
718
719                         if (vnormals_do) {
720                                 geom = DRW_mesh_batch_cache_get_edit_triangles_nor(ob->data);
721                                 DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat);
722                                 geom = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data);
723                                 DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat);
724                                 geom = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data);
725                                 DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat);
726                         }
727                         if (lnormals_do) {
728                                 geom = DRW_mesh_batch_cache_get_edit_triangles_lnor(ob->data);
729                                 DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geom, ob->obmat);
730                         }
731                         if (fnormals_do) {
732                                 geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
733                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
734                         }
735
736                         if (stl->g_data->do_zbufclip) {
737                                 edit_mesh_add_ob_to_pass(
738                                         scene, ob, stl->g_data,
739                                         stl->g_data->facedot_shgrp,
740                                         (stl->g_data->do_faces) ? stl->g_data->facefill_occluded_shgrp : NULL);
741                         }
742                         else {
743                                 edit_mesh_add_ob_to_pass(
744                                         scene, ob, stl->g_data,
745                                         (show_face_dots) ? stl->g_data->facedot_shgrp : NULL,
746                                         NULL);
747                         }
748
749                         stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
750                         stl->g_data->edit_ob += 1;
751
752                         /* 3D text overlay */
753                         if (v3d->overlay.edit_flag & (V3D_OVERLAY_EDIT_EDGE_LEN |
754                                                       V3D_OVERLAY_EDIT_FACE_AREA |
755                                                       V3D_OVERLAY_EDIT_FACE_ANG |
756                                                       V3D_OVERLAY_EDIT_EDGE_ANG |
757                                                       V3D_OVERLAY_EDIT_INDICES))
758                         {
759                                 if (DRW_state_show_text()) {
760                                         DRW_edit_mesh_mode_text_measure_stats(
761                                                draw_ctx->ar, v3d, ob, &scene->unit);
762                                 }
763                         }
764                 }
765         }
766 }
767
768 static void EDIT_MESH_draw_scene(void *vedata)
769 {
770         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
771         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
772         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
773         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
774         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
775
776         DRW_draw_pass(psl->weight_faces);
777
778         DRW_draw_pass(psl->depth_hidden_wire);
779
780         if (stl->g_data->do_zbufclip) {
781                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
782                 /* render facefill */
783                 DRW_draw_pass(psl->facefill_occlude);
784
785                 /* Render wires on a separate framebuffer */
786                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
787                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
788                 DRW_draw_pass(psl->normals);
789                 DRW_draw_pass(psl->edit_face_occluded);
790
791                 /* Combine with scene buffer */
792                 GPU_framebuffer_bind(dfbl->color_only_fb);
793                 DRW_draw_pass(psl->mix_occlude);
794         }
795         else {
796                 DRW_draw_pass(psl->normals);
797
798                 const DRWContextState *draw_ctx = DRW_context_state_get();
799                 View3D *v3d = draw_ctx->v3d;
800
801                 if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0) {
802                         if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
803                                 /* In the case of single ghost object edit (common case for retopology):
804                                  * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
805                                  * the stencil buffer is no 0x00. */
806                                 const float *viewport_size = DRW_viewport_size_get();
807                                 const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
808                                 struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
809                                 GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
810                                         GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
811                                         GPU_ATTACHMENT_TEXTURE(dtxl->color),
812                                 });
813
814                                 GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
815                                 GPU_framebuffer_bind(fbl->ghost_wire_fb);
816
817                                 DRW_draw_pass(psl->ghost_clear_depth);
818                         }
819                 }
820
821                 DRW_draw_pass(psl->edit_face_overlay);
822         }
823
824         DRW_state_clip_planes_reset();
825 }
826
827 static void EDIT_MESH_engine_free(void)
828 {
829         for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
830                 EDIT_MESH_Shaders *sh_data = &e_data.sh_data[sh_data_index];
831                 /* Don't free builtins. */
832                 sh_data->depth = NULL;
833                 GPUShader **sh_data_as_array = (GPUShader **)sh_data;
834                 for (int i = 0; i < (sizeof(EDIT_MESH_Shaders) / sizeof(GPUShader *)); i++) {
835                         DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
836                 }
837         }
838 }
839
840 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
841
842 DrawEngineType draw_engine_edit_mesh_type = {
843         NULL, NULL,
844         N_("EditMeshMode"),
845         &EDIT_MESH_data_size,
846         &EDIT_MESH_engine_init,
847         &EDIT_MESH_engine_free,
848         &EDIT_MESH_cache_init,
849         &EDIT_MESH_cache_populate,
850         NULL,
851         NULL,
852         &EDIT_MESH_draw_scene,
853         NULL,
854         NULL,
855 };