b94848cdd98fd24d513679cfc2975b61365913e6
[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
20  * \ingroup draw
21  */
22
23 #include "DRW_engine.h"
24 #include "DRW_render.h"
25
26 #include "GPU_extensions.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 "BIF_glutil.h"
42
43 #include "BLI_dynstr.h"
44 #include "BLI_string_utils.h"
45
46 #include "ED_view3d.h"
47
48 extern char datatoc_paint_weight_vert_glsl[];
49 extern char datatoc_paint_weight_frag_glsl[];
50
51 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
52 extern char datatoc_edit_mesh_overlay_frag_glsl[];
53 extern char datatoc_edit_mesh_overlay_vert_glsl[];
54 extern char datatoc_edit_mesh_overlay_geom_glsl[];
55 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
56 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
57 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
58 extern char datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl[];
59 extern char datatoc_edit_mesh_overlay_mesh_analysis_vert_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 extern char datatoc_common_view_lib_glsl[];
64
65 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
66 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
67 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
68 extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
69
70 /* *********** LISTS *********** */
71 typedef struct EDIT_MESH_PassList {
72   struct DRWPass *weight_faces;
73   struct DRWPass *depth_hidden_wire;
74   struct DRWPass *depth_hidden_wire_in_front;
75   struct DRWPass *edit_face_overlay;
76   struct DRWPass *edit_face_overlay_in_front;
77   struct DRWPass *edit_face_in_front;
78   struct DRWPass *edit_face_occluded;
79   struct DRWPass *mix_occlude;
80   struct DRWPass *facefill_occlude;
81   struct DRWPass *mesh_analysis_pass;
82   struct DRWPass *normals;
83 } EDIT_MESH_PassList;
84
85 typedef struct EDIT_MESH_FramebufferList {
86   struct GPUFrameBuffer *occlude_wire_fb;
87   struct GPUFrameBuffer *ghost_wire_fb;
88 } EDIT_MESH_FramebufferList;
89
90 typedef struct EDIT_MESH_StorageList {
91   struct EDIT_MESH_PrivateData *g_data;
92 } EDIT_MESH_StorageList;
93
94 typedef struct EDIT_MESH_Data {
95   void *engine_type;
96   EDIT_MESH_FramebufferList *fbl;
97   DRWViewportEmptyList *txl;
98   EDIT_MESH_PassList *psl;
99   EDIT_MESH_StorageList *stl;
100 } EDIT_MESH_Data;
101
102 #define MAX_SHADERS 16
103
104 /** Can only contain shaders (freed as array). */
105 typedef struct EDIT_MESH_Shaders {
106   /* weight */
107   GPUShader *weight_face;
108
109   /* Geometry */
110   GPUShader *overlay_vert;
111   GPUShader *overlay_edge;
112   GPUShader *overlay_edge_flat;
113   GPUShader *overlay_face;
114   GPUShader *overlay_facedot;
115
116   GPUShader *overlay_mix;
117   GPUShader *overlay_facefill;
118   GPUShader *normals_face;
119   GPUShader *normals_loop;
120   GPUShader *normals;
121   GPUShader *depth;
122
123   /* Mesh analysis shader */
124   GPUShader *mesh_analysis_face;
125   GPUShader *mesh_analysis_vertex;
126 } EDIT_MESH_Shaders;
127
128 /* *********** STATIC *********** */
129 static struct {
130   EDIT_MESH_Shaders sh_data[GPU_SHADER_CFG_LEN];
131
132   /* temp buffer texture */
133   struct GPUTexture *occlude_wire_depth_tx;
134   struct GPUTexture *occlude_wire_color_tx;
135 } e_data = {{{NULL}}}; /* Engine data */
136
137 typedef struct EDIT_MESH_PrivateData {
138   /* weight */
139   DRWShadingGroup *fweights_shgrp;
140   DRWShadingGroup *depth_shgrp_hidden_wire;
141   DRWShadingGroup *depth_shgrp_hidden_wire_in_front;
142
143   DRWShadingGroup *fnormals_shgrp;
144   DRWShadingGroup *vnormals_shgrp;
145   DRWShadingGroup *lnormals_shgrp;
146
147   DRWShadingGroup *vert_shgrp;
148   DRWShadingGroup *edge_shgrp;
149   DRWShadingGroup *face_shgrp;
150   DRWShadingGroup *face_cage_shgrp;
151   DRWShadingGroup *facedot_shgrp;
152
153   DRWShadingGroup *vert_shgrp_in_front;
154   DRWShadingGroup *edge_shgrp_in_front;
155   DRWShadingGroup *face_shgrp_in_front;
156   DRWShadingGroup *face_cage_shgrp_in_front;
157   DRWShadingGroup *facedot_shgrp_in_front;
158
159   DRWShadingGroup *facefill_occluded_shgrp;
160   DRWShadingGroup *mesh_analysis_shgrp;
161
162   int data_mask[4];
163   int ghost_ob;
164   int edit_ob;
165   bool do_zbufclip;
166   bool do_faces;
167   bool do_edges;
168 } EDIT_MESH_PrivateData; /* Transient data */
169
170 /* *********** FUNCTIONS *********** */
171
172 static void EDIT_MESH_engine_init(void *vedata)
173 {
174   EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
175
176   const DRWContextState *draw_ctx = DRW_context_state_get();
177   EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
178
179   const float *viewport_size = DRW_viewport_size_get();
180   const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
181
182   e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2d(
183       size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_edit_mesh_type);
184   e_data.occlude_wire_color_tx = DRW_texture_pool_query_2d(
185       size[0], size[1], GPU_RGBA8, &draw_engine_edit_mesh_type);
186
187   GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb,
188                                 {GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
189                                  GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)});
190
191   if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
192     DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
193   }
194
195   const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
196
197   if (!sh_data->weight_face) {
198     sh_data->weight_face = GPU_shader_create_from_arrays({
199         .vert = (const char *[]){sh_cfg_data->lib,
200                                  datatoc_common_globals_lib_glsl,
201                                  datatoc_common_view_lib_glsl,
202                                  datatoc_paint_weight_vert_glsl,
203                                  NULL},
204         .frag = (const char *[]){datatoc_common_globals_lib_glsl,
205                                  datatoc_paint_weight_frag_glsl,
206                                  NULL},
207         .defs = (const char *[]){sh_cfg_data->def, NULL},
208     });
209
210     char *lib = BLI_string_joinN(sh_cfg_data->lib,
211                                  datatoc_common_globals_lib_glsl,
212                                  datatoc_common_view_lib_glsl,
213                                  datatoc_edit_mesh_overlay_common_lib_glsl);
214     /* Use geometry shader to draw edge wireframe. This ensure us
215      * the same result accross platforms and more flexibility. But
216      * we pay the cost of running a geometry shader.
217      * In the future we might consider using only the vertex shader
218      * and loading data manually with buffer textures. */
219     const bool use_geom_shader = true;
220     const char *geom_sh_code[] = {lib, datatoc_edit_mesh_overlay_geom_glsl, NULL};
221     if (!use_geom_shader) {
222       geom_sh_code[0] = NULL;
223     }
224     const char *use_geom_def = use_geom_shader ? "#define USE_GEOM_SHADER\n" : "";
225     const char *use_smooth_def = (U.gpu_flag & USER_GPU_FLAG_NO_EDIT_MODE_SMOOTH_WIRE) ?
226                                      "" :
227                                      "#define USE_SMOOTH_WIRE\n";
228     sh_data->overlay_face = GPU_shader_create_from_arrays({
229         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
230         .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL},
231         .defs = (const char *[]){sh_cfg_data->def, "#define FACE\n", NULL},
232     });
233     sh_data->overlay_edge = GPU_shader_create_from_arrays({
234         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
235         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
236         .defs = (const char
237                      *[]){sh_cfg_data->def, use_geom_def, use_smooth_def, "#define EDGE\n", NULL},
238         .geom = (use_geom_shader) ? geom_sh_code : NULL,
239     });
240     sh_data->overlay_edge_flat = GPU_shader_create_from_arrays({
241         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
242         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
243         .defs = (const char *[]){sh_cfg_data->def,
244                                  use_geom_def,
245                                  use_smooth_def,
246                                  "#define EDGE\n",
247                                  "#define FLAT\n",
248                                  NULL},
249         .geom = (use_geom_shader) ? geom_sh_code : NULL,
250     });
251     sh_data->overlay_vert = GPU_shader_create_from_arrays({
252         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
253         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
254         .defs = (const char *[]){sh_cfg_data->def, "#define VERT\n", NULL},
255     });
256     sh_data->overlay_facedot = GPU_shader_create_from_arrays({
257         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
258         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
259         .defs = (const char *[]){sh_cfg_data->def, "#define FACEDOT\n", NULL},
260     });
261     sh_data->overlay_facefill = GPU_shader_create_from_arrays({
262         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL},
263         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL},
264         .defs = (const char *[]){sh_cfg_data->def, NULL},
265     });
266     MEM_freeN(lib);
267
268     sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl,
269                                                         NULL);
270
271     lib = BLI_string_joinN(sh_cfg_data->lib, datatoc_common_view_lib_glsl);
272
273     sh_data->normals_face = GPU_shader_create_from_arrays({
274         .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
275         .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
276         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
277         .defs = (const char *[]){sh_cfg_data->def, "#define FACE_NORMALS\n", NULL},
278     });
279
280     sh_data->normals_loop = GPU_shader_create_from_arrays({
281         .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
282         .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
283         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
284         .defs = (const char *[]){sh_cfg_data->def, "#define LOOP_NORMALS\n", NULL},
285     });
286
287     sh_data->normals = GPU_shader_create_from_arrays({
288         .vert = (const char *[]){lib, datatoc_edit_normals_vert_glsl, NULL},
289         .geom = (const char *[]){lib, datatoc_edit_normals_geom_glsl, NULL},
290         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
291         .defs = (const char *[]){sh_cfg_data->def, NULL},
292     });
293
294     /* Mesh Analysis */
295     sh_data->mesh_analysis_face = GPU_shader_create_from_arrays({
296         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, NULL},
297         .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
298         .defs = (const char *[]){sh_cfg_data->def, "#define FACE_COLOR\n", NULL},
299     });
300     sh_data->mesh_analysis_vertex = GPU_shader_create_from_arrays({
301         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl, NULL},
302         .frag = (const char *[]){datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl, NULL},
303         .defs = (const char *[]){sh_cfg_data->def, "#define VERTEX_COLOR\n", NULL},
304     });
305
306     MEM_freeN(lib);
307
308     sh_data->depth = DRW_shader_create_3d_depth_only(draw_ctx->sh_cfg);
309   }
310 }
311
312 static DRWPass *edit_mesh_create_overlay_pass(float *face_alpha,
313                                               int *data_mask,
314                                               bool do_edges,
315                                               DRWState statemod,
316                                               DRWShadingGroup **r_face_shgrp,
317                                               DRWShadingGroup **r_face_cage_shgrp,
318                                               DRWShadingGroup **r_facedot_shgrp,
319                                               DRWShadingGroup **r_edge_shgrp,
320                                               DRWShadingGroup **r_vert_shgrp)
321 {
322   const DRWContextState *draw_ctx = DRW_context_state_get();
323   RegionView3D *rv3d = draw_ctx->rv3d;
324   Scene *scene = draw_ctx->scene;
325   ToolSettings *tsettings = scene->toolsettings;
326   EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
327   const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
328   const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
329   const bool select_edge = (tsettings->selectmode & SCE_SELECT_EDGE) != 0;
330
331   float winmat[4][4];
332   float viewdist = rv3d->dist;
333   DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
334   /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
335   if (rv3d->persp == RV3D_CAMOB && rv3d->is_persp == false) {
336     viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
337   }
338   const float depth_ofs = bglPolygonOffsetCalc((float *)winmat, viewdist, 1.0f);
339
340   DRWPass *pass = DRW_pass_create("Edit Mesh Face Overlay Pass",
341                                   DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
342
343   DRWShadingGroup *grp;
344
345   GPUShader *vert_sh = sh_data->overlay_vert;
346   GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat;
347   GPUShader *face_sh = sh_data->overlay_face;
348   GPUShader *facedot_sh = sh_data->overlay_facedot;
349
350   /* Faces */
351   if (select_face) {
352     grp = *r_facedot_shgrp = DRW_shgroup_create(facedot_sh, pass);
353     DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
354     DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
355     if (rv3d->rflag & RV3D_CLIPPING) {
356       DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
357     }
358   }
359
360   grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass);
361   DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
362   DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
363   DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
364   DRW_shgroup_uniform_float_copy(grp, "ofs", 0.0f);
365   DRW_shgroup_uniform_bool_copy(grp, "selectFaces", select_face);
366   if (rv3d->rflag & RV3D_CLIPPING) {
367     DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
368   }
369
370   /* Cage geom needs to be offseted to avoid Z-fighting. */
371   grp = *r_face_cage_shgrp = DRW_shgroup_create_sub(*r_face_shgrp);
372   DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
373
374   /* Edges */
375   grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass);
376   DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
377   DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
378   DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
379   DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
380   DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
381   DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
382   DRW_shgroup_uniform_bool_copy(grp, "selectEdges", select_edge);
383
384   DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
385   /* To match blender loop structure. */
386   DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
387   if (rv3d->rflag & RV3D_CLIPPING) {
388     DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
389   }
390
391   /* Verts */
392   if (select_vert) {
393     grp = *r_vert_shgrp = DRW_shgroup_create(vert_sh, pass);
394     DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
395     DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
396     DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs * 1.5f);
397     DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE | DRW_STATE_WRITE_DEPTH);
398     DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
399     if (rv3d->rflag & RV3D_CLIPPING) {
400       DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
401     }
402   }
403
404   return pass;
405 }
406
407 static float backwire_opacity;
408 static float face_mod;
409 static float size_normal;
410
411 static void EDIT_MESH_cache_init(void *vedata)
412 {
413   EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
414   EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
415   DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
416
417   const DRWContextState *draw_ctx = DRW_context_state_get();
418   View3D *v3d = draw_ctx->v3d;
419   RegionView3D *rv3d = draw_ctx->rv3d;
420   Scene *scene = draw_ctx->scene;
421   ToolSettings *tsettings = scene->toolsettings;
422   EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
423   static float zero = 0.0f;
424
425   if (!stl->g_data) {
426     /* Alloc transient pointers */
427     stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
428   }
429   stl->g_data->ghost_ob = 0;
430   stl->g_data->edit_ob = 0;
431   stl->g_data->do_faces = true;
432   stl->g_data->do_edges = true;
433
434   stl->g_data->do_zbufclip = XRAY_FLAG_ENABLED(v3d);
435
436   stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
437   stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
438   stl->g_data->data_mask[2] = 0xFF; /* Crease */
439   stl->g_data->data_mask[3] = 0xFF; /* BWeight */
440
441   if (draw_ctx->object_edit->type == OB_MESH) {
442     if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
443       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE) == 0) {
444         stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
445       }
446       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACES) == 0) {
447         stl->g_data->data_mask[0] &= ~(VFLAG_FACE_SELECTED & VFLAG_FACE_FREESTYLE);
448         stl->g_data->do_faces = false;
449         stl->g_data->do_zbufclip = false;
450       }
451       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
452         stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
453       }
454       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SHARP) == 0) {
455         stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
456       }
457       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE) == 0) {
458         stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
459       }
460       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
461         if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
462           stl->g_data->data_mask[1] &= ~(VFLAG_EDGE_ACTIVE & VFLAG_EDGE_SELECTED);
463           stl->g_data->do_edges = false;
464         }
465       }
466       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CREASES) == 0) {
467         stl->g_data->data_mask[2] = 0x0;
468       }
469       if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_BWEIGHTS) == 0) {
470         stl->g_data->data_mask[3] = 0x0;
471       }
472     }
473   }
474
475   {
476     psl->weight_faces = DRW_pass_create(
477         "Weight Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
478
479     stl->g_data->fweights_shgrp = DRW_shgroup_create(sh_data->weight_face, psl->weight_faces);
480
481     static float alpha = 1.0f;
482     DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &alpha, 1);
483     DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", G_draw.weight_ramp);
484     DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", G_draw.block_ubo);
485     if (rv3d->rflag & RV3D_CLIPPING) {
486       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
487     }
488   }
489
490   {
491     /* Complementary Depth Pass */
492     psl->depth_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire",
493                                              DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
494                                                  DRW_STATE_CULL_BACK);
495     stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(sh_data->depth,
496                                                               psl->depth_hidden_wire);
497     if (rv3d->rflag & RV3D_CLIPPING) {
498       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->depth_shgrp_hidden_wire, rv3d);
499     }
500
501     psl->depth_hidden_wire_in_front = DRW_pass_create(
502         "Depth Pass Hidden Wire In Front",
503         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
504     stl->g_data->depth_shgrp_hidden_wire_in_front = DRW_shgroup_create(
505         sh_data->depth, psl->depth_hidden_wire_in_front);
506     if (rv3d->rflag & RV3D_CLIPPING) {
507       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->depth_shgrp_hidden_wire_in_front, rv3d);
508     }
509   }
510
511   {
512     /* Normals */
513     psl->normals = DRW_pass_create("Edit Mesh Normals Pass",
514                                    DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR |
515                                        DRW_STATE_DEPTH_LESS_EQUAL);
516
517     stl->g_data->fnormals_shgrp = DRW_shgroup_create(sh_data->normals_face, psl->normals);
518     DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
519     DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", G_draw.block.colorNormal, 1);
520     if (rv3d->rflag & RV3D_CLIPPING) {
521       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fnormals_shgrp, rv3d);
522     }
523
524     stl->g_data->vnormals_shgrp = DRW_shgroup_create(sh_data->normals, psl->normals);
525     DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
526     DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", G_draw.block.colorVNormal, 1);
527     if (rv3d->rflag & RV3D_CLIPPING) {
528       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vnormals_shgrp, rv3d);
529     }
530
531     stl->g_data->lnormals_shgrp = DRW_shgroup_create(sh_data->normals_loop, psl->normals);
532     DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
533     DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", G_draw.block.colorLNormal, 1);
534     if (rv3d->rflag & RV3D_CLIPPING) {
535       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lnormals_shgrp, rv3d);
536     }
537   }
538
539   {
540     /* Mesh Analysis Pass */
541     DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
542     psl->mesh_analysis_pass = DRW_pass_create("Mesh Analysis", state);
543     const bool is_vertex_color = scene->toolsettings->statvis.type == SCE_STATVIS_SHARP;
544     stl->g_data->mesh_analysis_shgrp = DRW_shgroup_create(
545         is_vertex_color ? sh_data->mesh_analysis_vertex : sh_data->mesh_analysis_face,
546         psl->mesh_analysis_pass);
547     if (rv3d->rflag & RV3D_CLIPPING) {
548       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->mesh_analysis_shgrp, rv3d);
549     }
550   }
551   /* For in front option */
552   psl->edit_face_overlay_in_front = edit_mesh_create_overlay_pass(
553       &face_mod,
554       stl->g_data->data_mask,
555       stl->g_data->do_edges,
556       DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
557       &stl->g_data->face_shgrp_in_front,
558       &stl->g_data->face_cage_shgrp_in_front,
559       &stl->g_data->facedot_shgrp_in_front,
560       &stl->g_data->edge_shgrp_in_front,
561       &stl->g_data->vert_shgrp_in_front);
562
563   if (!stl->g_data->do_zbufclip) {
564     psl->edit_face_overlay = edit_mesh_create_overlay_pass(&face_mod,
565                                                            stl->g_data->data_mask,
566                                                            stl->g_data->do_edges,
567                                                            DRW_STATE_DEPTH_LESS_EQUAL |
568                                                                DRW_STATE_BLEND,
569                                                            &stl->g_data->face_shgrp,
570                                                            &stl->g_data->face_cage_shgrp,
571                                                            &stl->g_data->facedot_shgrp,
572                                                            &stl->g_data->edge_shgrp,
573                                                            &stl->g_data->vert_shgrp);
574   }
575   else {
576     /* We render all wires with depth and opaque to a new fbo and blend the result based on depth
577      * values */
578     psl->edit_face_occluded = edit_mesh_create_overlay_pass(&zero,
579                                                             stl->g_data->data_mask,
580                                                             stl->g_data->do_edges,
581                                                             DRW_STATE_DEPTH_LESS_EQUAL |
582                                                                 DRW_STATE_WRITE_DEPTH,
583                                                             &stl->g_data->face_shgrp,
584                                                             &stl->g_data->face_cage_shgrp,
585                                                             &stl->g_data->facedot_shgrp,
586                                                             &stl->g_data->edge_shgrp,
587                                                             &stl->g_data->vert_shgrp);
588
589     /* however we loose the front faces value (because we need the depth of occluded wires and
590      * faces are alpha blended ) so we recover them in a new pass. */
591     psl->facefill_occlude = DRW_pass_create(
592         "Front Face Color", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
593     stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(sh_data->overlay_facefill,
594                                                               psl->facefill_occlude);
595     DRW_shgroup_uniform_block(
596         stl->g_data->facefill_occluded_shgrp, "globalsBlock", G_draw.block_ubo);
597     DRW_shgroup_uniform_ivec4(
598         stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
599     if (rv3d->rflag & RV3D_CLIPPING) {
600       DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->facefill_occluded_shgrp, rv3d);
601     }
602
603     /* we need a full screen pass to combine the result */
604     struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
605
606     psl->mix_occlude = DRW_pass_create("Mix Occluded Wires",
607                                        DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
608     DRWShadingGroup *mix_shgrp = DRW_shgroup_create(sh_data->overlay_mix, psl->mix_occlude);
609     DRW_shgroup_call(mix_shgrp, quad, NULL);
610     DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
611     DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
612     DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
613     DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
614   }
615 }
616
617 static void edit_mesh_add_ob_to_pass(Scene *scene,
618                                      Object *ob,
619                                      DRWShadingGroup *vert_shgrp,
620                                      DRWShadingGroup *edge_shgrp,
621                                      DRWShadingGroup *face_shgrp,
622                                      DRWShadingGroup *face_cage_shgrp,
623                                      DRWShadingGroup *facedot_shgrp,
624                                      DRWShadingGroup *facefill_shgrp)
625 {
626   struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter;
627   ToolSettings *tsettings = scene->toolsettings;
628
629   bool has_edit_mesh_cage = false;
630   /* TODO: Should be its own function. */
631   Mesh *me = (Mesh *)ob->data;
632   BMEditMesh *embm = me->edit_mesh;
633   if (embm) {
634     has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
635   }
636
637   face_shgrp = (has_edit_mesh_cage) ? face_cage_shgrp : face_shgrp;
638   face_shgrp = (facefill_shgrp != NULL) ? facefill_shgrp : face_shgrp;
639
640   geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
641   geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
642   DRW_shgroup_call(edge_shgrp, geom_edges, ob->obmat);
643   DRW_shgroup_call(face_shgrp, geom_tris, ob->obmat);
644
645   if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
646     geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
647     DRW_shgroup_call(vert_shgrp, geom_verts, ob->obmat);
648   }
649
650   if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) {
651     geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
652     DRW_shgroup_call(facedot_shgrp, geom_fcenter, ob->obmat);
653   }
654 }
655
656 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
657 {
658   EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
659   EDIT_MESH_PrivateData *g_data = stl->g_data;
660   const DRWContextState *draw_ctx = DRW_context_state_get();
661   View3D *v3d = draw_ctx->v3d;
662   Scene *scene = draw_ctx->scene;
663   ToolSettings *tsettings = scene->toolsettings;
664   struct GPUBatch *geom;
665
666   if (ob->type == OB_MESH) {
667     if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
668       bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
669       bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
670       bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
671       bool do_show_mesh_analysis = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_STATVIS) != 0;
672       bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
673       bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
674       bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
675
676       bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0;
677
678       if (g_data->do_faces == false && g_data->do_edges == false &&
679           (tsettings->selectmode & SCE_SELECT_FACE)) {
680         /* Force display of face centers in this case because that's
681          * the only way to see if a face is selected. */
682         show_face_dots = true;
683       }
684
685       /* Updating uniform */
686       backwire_opacity = v3d->overlay.backwire_opacity;
687       size_normal = v3d->overlay.normals_length;
688
689       face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
690
691       if (!g_data->do_faces) {
692         face_mod = 0.0f;
693       }
694
695       if (do_show_weight) {
696         geom = DRW_cache_mesh_surface_weights_get(ob);
697         DRW_shgroup_call(g_data->fweights_shgrp, geom, ob->obmat);
698       }
699
700       if (do_show_mesh_analysis) {
701         Mesh *me = (Mesh *)ob->data;
702         BMEditMesh *embm = me->edit_mesh;
703         const bool is_original = embm->mesh_eval_final &&
704                                  (embm->mesh_eval_final->runtime.is_original == true);
705         if (is_original) {
706           geom = DRW_cache_mesh_surface_mesh_analysis_get(ob);
707           if (geom) {
708             DRW_shgroup_call(g_data->mesh_analysis_shgrp, geom, ob->obmat);
709           }
710         }
711       }
712
713       if (do_occlude_wire || do_in_front) {
714         geom = DRW_cache_mesh_surface_get(ob);
715         DRW_shgroup_call(do_in_front ? g_data->depth_shgrp_hidden_wire_in_front :
716                                            g_data->depth_shgrp_hidden_wire,
717                              geom,
718                              ob->obmat);
719       }
720
721       if (vnormals_do) {
722         geom = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
723         DRW_shgroup_call(g_data->vnormals_shgrp, geom, ob->obmat);
724       }
725       if (lnormals_do) {
726         geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
727         DRW_shgroup_call(g_data->lnormals_shgrp, geom, ob->obmat);
728       }
729       if (fnormals_do) {
730         geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
731         DRW_shgroup_call(g_data->fnormals_shgrp, geom, ob->obmat);
732       }
733
734       if (g_data->do_zbufclip) {
735         edit_mesh_add_ob_to_pass(scene,
736                                  ob,
737                                  g_data->vert_shgrp,
738                                  g_data->edge_shgrp,
739                                  g_data->face_shgrp,
740                                  g_data->face_cage_shgrp,
741                                  g_data->facedot_shgrp,
742                                  (g_data->do_faces) ? g_data->facefill_occluded_shgrp : NULL);
743       }
744       else if (do_in_front) {
745         edit_mesh_add_ob_to_pass(scene,
746                                  ob,
747                                  g_data->vert_shgrp_in_front,
748                                  g_data->edge_shgrp_in_front,
749                                  g_data->face_shgrp_in_front,
750                                  g_data->face_cage_shgrp_in_front,
751                                  (show_face_dots) ? g_data->facedot_shgrp_in_front : NULL,
752                                  NULL);
753       }
754       else {
755         edit_mesh_add_ob_to_pass(scene,
756                                  ob,
757                                  g_data->vert_shgrp,
758                                  g_data->edge_shgrp,
759                                  g_data->face_shgrp,
760                                  g_data->face_cage_shgrp,
761                                  (show_face_dots) ? g_data->facedot_shgrp : NULL,
762                                  NULL);
763       }
764
765       g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
766       g_data->edit_ob += 1;
767
768       /* 3D text overlay */
769       if (v3d->overlay.edit_flag &
770           (V3D_OVERLAY_EDIT_EDGE_LEN | V3D_OVERLAY_EDIT_FACE_AREA | V3D_OVERLAY_EDIT_FACE_ANG |
771            V3D_OVERLAY_EDIT_EDGE_ANG | V3D_OVERLAY_EDIT_INDICES)) {
772         if (DRW_state_show_text()) {
773           DRW_edit_mesh_mode_text_measure_stats(draw_ctx->ar, v3d, ob, &scene->unit);
774         }
775       }
776     }
777   }
778 }
779
780 static void EDIT_MESH_draw_scene(void *vedata)
781 {
782   EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
783   EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
784   EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
785   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
786
787   DRW_draw_pass(psl->weight_faces);
788   DRW_draw_pass(psl->mesh_analysis_pass);
789
790   DRW_draw_pass(psl->depth_hidden_wire);
791
792   if (stl->g_data->do_zbufclip) {
793     float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
794
795     DRW_draw_pass(psl->depth_hidden_wire_in_front);
796
797     /* render facefill */
798     DRW_draw_pass(psl->facefill_occlude);
799
800     /* Render wires on a separate framebuffer */
801     GPU_framebuffer_bind(fbl->occlude_wire_fb);
802     GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
803     DRW_draw_pass(psl->normals);
804     DRW_draw_pass(psl->edit_face_occluded);
805
806     /* Combine with scene buffer */
807     GPU_framebuffer_bind(dfbl->color_only_fb);
808     DRW_draw_pass(psl->mix_occlude);
809   }
810   else {
811     const DRWContextState *draw_ctx = DRW_context_state_get();
812     View3D *v3d = draw_ctx->v3d;
813
814     DRW_draw_pass(psl->normals);
815     DRW_draw_pass(psl->edit_face_overlay);
816
817     if (v3d->shading.type == OB_SOLID && !XRAY_FLAG_ENABLED(v3d) && stl->g_data->ghost_ob == 1 &&
818         stl->g_data->edit_ob == 1) {
819       /* In the case of single ghost object edit (common case for retopology):
820        * we clear the depth buffer so that only the depth of the retopo mesh
821        * is occluding the edit cage. */
822       GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
823     }
824
825     DRW_draw_pass(psl->depth_hidden_wire_in_front);
826     DRW_draw_pass(psl->edit_face_overlay_in_front);
827   }
828
829   DRW_state_clip_planes_reset();
830 }
831
832 static void EDIT_MESH_engine_free(void)
833 {
834   for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
835     EDIT_MESH_Shaders *sh_data = &e_data.sh_data[sh_data_index];
836     /* Don't free builtins. */
837     sh_data->depth = NULL;
838     GPUShader **sh_data_as_array = (GPUShader **)sh_data;
839     for (int i = 0; i < (sizeof(EDIT_MESH_Shaders) / sizeof(GPUShader *)); i++) {
840       DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
841     }
842   }
843 }
844
845 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
846
847 DrawEngineType draw_engine_edit_mesh_type = {
848     NULL,
849     NULL,
850     N_("EditMeshMode"),
851     &EDIT_MESH_data_size,
852     &EDIT_MESH_engine_init,
853     &EDIT_MESH_engine_free,
854     &EDIT_MESH_cache_init,
855     &EDIT_MESH_cache_populate,
856     NULL,
857     NULL,
858     &EDIT_MESH_draw_scene,
859     NULL,
860     NULL,
861 };