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