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