Edit Mesh: Add support for draw option parameters
[blender.git] / source / blender / draw / modes / edit_mesh_mode.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file blender/draw/modes/edit_mesh_mode.c
23  *  \ingroup draw
24  */
25
26 #include "DRW_engine.h"
27 #include "DRW_render.h"
28
29 #include "GPU_shader.h"
30
31 #include "DNA_mesh_types.h"
32 #include "DNA_view3d_types.h"
33
34 #include "draw_common.h"
35
36 #include "draw_cache_impl.h"
37 #include "draw_mode_engines.h"
38
39 #include "edit_mesh_mode_intern.h" /* own include */
40
41 #include "BKE_object.h"
42
43 #include "BLI_dynstr.h"
44
45
46 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
47 extern struct GlobalsUboStorage ts; /* draw_common.c */
48
49 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
50 extern char datatoc_edit_mesh_overlay_frag_glsl[];
51 extern char datatoc_edit_mesh_overlay_vert_glsl[];
52 extern char datatoc_edit_mesh_overlay_geom_tri_glsl[];
53 extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
54 extern char datatoc_edit_mesh_overlay_loosevert_vert_glsl[];
55 extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
56 extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
57 extern char datatoc_edit_mesh_overlay_ghost_clear_vert_glsl[];
58 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
59 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
60 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
61 extern char datatoc_edit_normals_vert_glsl[];
62 extern char datatoc_edit_normals_geom_glsl[];
63 extern char datatoc_common_globals_lib_glsl[];
64
65 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
66
67 /* *********** LISTS *********** */
68 typedef struct EDIT_MESH_PassList {
69         struct DRWPass *vcolor_faces;
70         struct DRWPass *depth_hidden_wire;
71         struct DRWPass *ghost_clear_depth;
72         struct DRWPass *edit_face_overlay;
73         struct DRWPass *edit_face_occluded;
74         struct DRWPass *mix_occlude;
75         struct DRWPass *facefill_occlude;
76         struct DRWPass *normals;
77 } EDIT_MESH_PassList;
78
79 typedef struct EDIT_MESH_FramebufferList {
80         struct GPUFrameBuffer *occlude_wire_fb;
81         struct GPUFrameBuffer *ghost_wire_fb;
82 } EDIT_MESH_FramebufferList;
83
84 typedef struct EDIT_MESH_StorageList {
85         struct EDIT_MESH_PrivateData *g_data;
86 } EDIT_MESH_StorageList;
87
88 typedef struct EDIT_MESH_Data {
89         void *engine_type;
90         EDIT_MESH_FramebufferList *fbl;
91         DRWViewportEmptyList *txl;
92         EDIT_MESH_PassList *psl;
93         EDIT_MESH_StorageList *stl;
94 } EDIT_MESH_Data;
95
96 /* *********** STATIC *********** */
97 #define MAX_SHADERS 16
98
99 static struct {
100         /* weight/vert-color */
101         GPUShader *vcolor_face_shader;
102
103         /* Geometry */
104         GPUShader *overlay_tri_sh_cache[MAX_SHADERS];
105         GPUShader *overlay_loose_edge_sh_cache[MAX_SHADERS];
106
107         GPUShader *overlay_vert_sh;
108         GPUShader *overlay_facedot_sh;
109         GPUShader *overlay_mix_sh;
110         GPUShader *overlay_facefill_sh;
111         GPUShader *normals_face_sh;
112         GPUShader *normals_loop_sh;
113         GPUShader *normals_sh;
114         GPUShader *depth_sh;
115         GPUShader *ghost_clear_depth_sh;
116         /* temp buffer texture */
117         struct GPUTexture *occlude_wire_depth_tx;
118         struct GPUTexture *occlude_wire_color_tx;
119 } e_data = {NULL}; /* Engine data */
120
121 typedef struct EDIT_MESH_PrivateData {
122         /* weight/vert-color */
123         DRWShadingGroup *fvcolor_shgrp;
124         DRWShadingGroup *depth_shgrp_hidden_wire;
125
126         DRWShadingGroup *fnormals_shgrp;
127         DRWShadingGroup *vnormals_shgrp;
128         DRWShadingGroup *lnormals_shgrp;
129
130         DRWShadingGroup *face_overlay_shgrp;
131         DRWShadingGroup *ledges_overlay_shgrp;
132         DRWShadingGroup *lverts_overlay_shgrp;
133         DRWShadingGroup *facedot_overlay_shgrp;
134
135         DRWShadingGroup *face_occluded_shgrp;
136         DRWShadingGroup *ledges_occluded_shgrp;
137         DRWShadingGroup *lverts_occluded_shgrp;
138         DRWShadingGroup *facedot_occluded_shgrp;
139         DRWShadingGroup *facefill_occluded_shgrp;
140
141         int data_mask[4];
142         int ghost_ob;
143         int edit_ob;
144         bool do_zbufclip;
145         float edge_width_scale;
146 } EDIT_MESH_PrivateData; /* Transient data */
147
148 /* *********** FUNCTIONS *********** */
149 static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode)
150 {
151         int result = tsettings->selectmode << 1;
152         if (supports_fast_mode) {
153                 SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0);
154         }
155         return result;
156 }
157
158 static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias, bool looseedge)
159 {
160         const int selectmode = tsettings->selectmode;
161         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
162
163         char *str = NULL;
164         DynStr *ds = BLI_dynstr_new();
165
166         if (selectmode & SCE_SELECT_VERTEX) {
167                 BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n");
168         }
169
170         if (selectmode & SCE_SELECT_EDGE) {
171                 BLI_dynstr_append(ds, "#define EDGE_SELECTION\n");
172         }
173
174         if (selectmode & SCE_SELECT_FACE) {
175                 BLI_dynstr_append(ds, "#define FACE_SELECTION\n");
176         }
177
178         if (!fast_mode) {
179                 BLI_dynstr_append(ds, "#define EDGE_FIX\n");
180         }
181
182         if (anti_alias) {
183                 BLI_dynstr_append(ds, "#define ANTI_ALIASING\n");
184         }
185
186         if (!looseedge) {
187                 BLI_dynstr_append(ds, "#define VERTEX_FACING\n");
188         }
189
190         str = BLI_dynstr_get_cstring(ds);
191         BLI_dynstr_free(ds);
192         return str;
193 }
194 static char *EDIT_MESH_sh_lib(void)
195 {
196         char *str = NULL;
197         DynStr *ds = BLI_dynstr_new();
198
199         BLI_dynstr_append(ds, datatoc_common_globals_lib_glsl);
200         BLI_dynstr_append(ds, datatoc_edit_mesh_overlay_common_lib_glsl);
201
202         str = BLI_dynstr_get_cstring(ds);
203         BLI_dynstr_free(ds);
204         return str;
205 }
206
207 static GPUShader *EDIT_MESH_ensure_shader(ToolSettings *tsettings, RegionView3D *rv3d, bool fast_mode, bool looseedge)
208 {
209         const int index = EDIT_MESH_sh_index(tsettings, rv3d, fast_mode);
210         if (looseedge) {
211                 if (!e_data.overlay_loose_edge_sh_cache[index]) {
212                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, true);
213                         char *lib = EDIT_MESH_sh_lib();
214                         e_data.overlay_loose_edge_sh_cache[index] = DRW_shader_create_with_lib(
215                                 datatoc_edit_mesh_overlay_vert_glsl,
216                                 datatoc_edit_mesh_overlay_geom_edge_glsl,
217                                 datatoc_edit_mesh_overlay_frag_glsl,
218                                 lib,
219                                 defines);
220                         MEM_freeN(lib);
221                         MEM_freeN(defines);
222                 }
223                 return e_data.overlay_loose_edge_sh_cache[index];
224         }
225         else {
226                 if (!e_data.overlay_tri_sh_cache[index]) {
227                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, false);
228                         char *lib = EDIT_MESH_sh_lib();
229                         e_data.overlay_tri_sh_cache[index] = DRW_shader_create_with_lib(
230                                 datatoc_edit_mesh_overlay_vert_glsl,
231                                 datatoc_edit_mesh_overlay_geom_tri_glsl,
232                                 datatoc_edit_mesh_overlay_frag_glsl,
233                                 lib,
234                                 defines);
235                         MEM_freeN(lib);
236                         MEM_freeN(defines);
237                 }
238                 return e_data.overlay_tri_sh_cache[index];
239         }
240 }
241
242 static void EDIT_MESH_engine_init(void *vedata)
243 {
244         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
245
246         const float *viewport_size = DRW_viewport_size_get();
247         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
248
249         e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
250                                                                  &draw_engine_edit_mesh_type);
251         e_data.occlude_wire_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
252                                                                  &draw_engine_edit_mesh_type);
253
254         GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb, {
255                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
256                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)
257         });
258
259         if (!e_data.vcolor_face_shader) {
260                 e_data.vcolor_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
261         }
262
263         if (!e_data.overlay_vert_sh) {
264                 char *lib = EDIT_MESH_sh_lib();
265                 e_data.overlay_vert_sh = DRW_shader_create_with_lib(
266                         datatoc_edit_mesh_overlay_loosevert_vert_glsl, NULL,
267                         datatoc_edit_mesh_overlay_frag_glsl,
268                         lib,
269                         "#define VERTEX_SELECTION\n");
270                 MEM_freeN(lib);
271         }
272         if (!e_data.overlay_facedot_sh) {
273                 e_data.overlay_facedot_sh = DRW_shader_create_with_lib(
274                         datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL,
275                         datatoc_edit_mesh_overlay_facedot_frag_glsl,
276                         datatoc_common_globals_lib_glsl,
277                         "#define VERTEX_FACING\n");
278         }
279         if (!e_data.overlay_mix_sh) {
280                 e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
281         }
282         if (!e_data.overlay_facefill_sh) {
283                 e_data.overlay_facefill_sh = DRW_shader_create_with_lib(
284                         datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL,
285                         datatoc_edit_mesh_overlay_facefill_frag_glsl,
286                         datatoc_common_globals_lib_glsl, NULL);
287         }
288         if (!e_data.normals_face_sh) {
289                 e_data.normals_face_sh = DRW_shader_create(
290                         datatoc_edit_normals_vert_glsl,
291                         datatoc_edit_normals_geom_glsl,
292                         datatoc_gpu_shader_uniform_color_frag_glsl,
293                         "#define FACE_NORMALS\n");
294         }
295         if (!e_data.normals_loop_sh) {
296                 e_data.normals_loop_sh = DRW_shader_create(
297                         datatoc_edit_normals_vert_glsl,
298                         datatoc_edit_normals_geom_glsl,
299                         datatoc_gpu_shader_uniform_color_frag_glsl,
300                         "#define LOOP_NORMALS\n");
301         }
302         if (!e_data.normals_sh) {
303                 e_data.normals_sh = DRW_shader_create(
304                         datatoc_edit_normals_vert_glsl,
305                         datatoc_edit_normals_geom_glsl,
306                         datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
307         }
308         if (!e_data.depth_sh) {
309                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
310         }
311         if (!e_data.ghost_clear_depth_sh) {
312                 e_data.ghost_clear_depth_sh = DRW_shader_create(datatoc_edit_mesh_overlay_ghost_clear_vert_glsl,
313                                                                 NULL, NULL, NULL);
314         }
315
316 }
317
318 static DRWPass *edit_mesh_create_overlay_pass(
319         float *face_alpha, float *edge_width_scale, int *data_mask,
320         DRWState statemod,
321         DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_ledges_shgrp,
322         DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp)
323 {
324         GPUShader *tri_sh, *ledge_sh;
325         const DRWContextState *draw_ctx = DRW_context_state_get();
326         RegionView3D *rv3d = draw_ctx->rv3d;
327         Scene *scene = draw_ctx->scene;
328         ToolSettings *tsettings = scene->toolsettings;
329
330         ledge_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, false, true);
331         tri_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, true, false);
332
333         DRWPass *pass = DRW_pass_create(
334                 "Edit Mesh Face Overlay Pass",
335                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
336
337         *r_face_shgrp = DRW_shgroup_create(tri_sh, pass);
338         DRW_shgroup_uniform_block(*r_face_shgrp, "globalsBlock", globals_ubo);
339         DRW_shgroup_uniform_vec2(*r_face_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
340         DRW_shgroup_uniform_float(*r_face_shgrp, "faceAlphaMod", face_alpha, 1);
341         DRW_shgroup_uniform_float(*r_face_shgrp, "edgeScale", edge_width_scale, 1);
342         DRW_shgroup_uniform_ivec4(*r_face_shgrp, "dataMask", data_mask, 1);
343
344         *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
345         DRW_shgroup_uniform_block(*r_ledges_shgrp, "globalsBlock", globals_ubo);
346         DRW_shgroup_uniform_vec2(*r_ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
347         DRW_shgroup_uniform_float(*r_ledges_shgrp, "edgeScale", edge_width_scale, 1);
348         DRW_shgroup_uniform_ivec4(*r_ledges_shgrp, "dataMask", data_mask, 1);
349
350         if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
351                 *r_lverts_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, pass);
352                 DRW_shgroup_uniform_block(*r_lverts_shgrp, "globalsBlock", globals_ubo);
353                 DRW_shgroup_uniform_vec2(*r_lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
354                 DRW_shgroup_uniform_float(*r_lverts_shgrp, "edgeScale", edge_width_scale, 1);
355         }
356
357         if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
358                 *r_facedot_shgrp = DRW_shgroup_create(e_data.overlay_facedot_sh, pass);
359                 DRW_shgroup_uniform_block(*r_facedot_shgrp, "globalsBlock", globals_ubo);
360                 DRW_shgroup_uniform_float(*r_facedot_shgrp, "edgeScale", edge_width_scale, 1);
361         }
362
363         return pass;
364 }
365
366 static float backwire_opacity;
367 static float face_mod;
368 static float size_normal;
369
370 static void EDIT_MESH_cache_init(void *vedata)
371 {
372         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
373         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
374         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
375
376         const DRWContextState *draw_ctx = DRW_context_state_get();
377         View3D *v3d = draw_ctx->v3d;
378         Scene *scene = draw_ctx->scene;
379         ToolSettings *tsettings = scene->toolsettings;
380
381         static float zero = 0.0f;
382
383         if (!stl->g_data) {
384                 /* Alloc transient pointers */
385                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
386         }
387         stl->g_data->ghost_ob = 0;
388         stl->g_data->edit_ob = 0;
389
390         const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
391                                    (draw_ctx->v3d->shading.type < OB_MATERIAL);
392         stl->g_data->do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0) || xray_enabled;
393
394         /* Applies on top of the theme edge width, so edge-mode can have thick edges. */
395         stl->g_data->edge_width_scale = (tsettings->selectmode & (SCE_SELECT_EDGE)) ? 1.75f : 1.0f;
396
397         stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
398         stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
399         stl->g_data->data_mask[2] = 0xFF; /* Crease */
400         stl->g_data->data_mask[3] = 0xFF; /* BWeight */
401
402         if (draw_ctx->object_edit->type == OB_MESH) {
403                 if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
404                         const Mesh *me = draw_ctx->object_edit->data;
405                         if ((me->drawflag & ME_DRAW_FREESTYLE_FACE) == 0) {
406                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
407                         }
408                         if ((me->drawflag & ME_DRAWSEAMS) == 0) {
409                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
410                         }
411                         if ((me->drawflag & ME_DRAWSHARP) == 0) {
412                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
413                         }
414                         if ((me->drawflag & ME_DRAW_FREESTYLE_EDGE) == 0) {
415                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
416                         }
417                         if ((me->drawflag & ME_DRAWCREASES) == 0) {
418                                 stl->g_data->data_mask[2] = 0x0;
419                         }
420                         if ((me->drawflag & ME_DRAWBWEIGHTS) == 0) {
421                                 stl->g_data->data_mask[3] = 0x0;
422                         }
423                 }
424         }
425
426         {
427                 psl->vcolor_faces = DRW_pass_create(
428                         "Vert Color Pass",
429                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
430
431                 stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces);
432
433                 static float light[3] = {-0.3f, 0.5f, 1.0f};
434                 static float alpha = 1.0f;
435                 static float world_light = 1.0f;  /* XXX, see: paint_vertex_mode.c */
436                 DRW_shgroup_uniform_vec3(stl->g_data->fvcolor_shgrp, "light", light, 1);
437                 DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "alpha", &alpha, 1);
438                 DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "global", &world_light, 1);
439         }
440
441         {
442                 /* Complementary Depth Pass */
443                 psl->depth_hidden_wire = DRW_pass_create(
444                         "Depth Pass Hidden Wire",
445                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
446                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
447         }
448
449         {
450                 /* Depth clearing for ghosting. */
451                 psl->ghost_clear_depth = DRW_pass_create(
452                         "Ghost Depth Clear",
453                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
454
455                 DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.ghost_clear_depth_sh, psl->ghost_clear_depth);
456                 DRW_shgroup_stencil_mask(shgrp, 0x00);
457                 DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
458         }
459
460         {
461                 /* Normals */
462                 psl->normals = DRW_pass_create(
463                         "Edit Mesh Normals Pass",
464                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
465
466                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
467                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
468                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
469
470                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
471                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
472                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
473
474                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_loop_sh, psl->normals);
475                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
476                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
477         }
478
479         if (!stl->g_data->do_zbufclip) {
480                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
481                         &face_mod, &stl->g_data->edge_width_scale, stl->g_data->data_mask,
482                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
483                         &stl->g_data->face_overlay_shgrp, &stl->g_data->ledges_overlay_shgrp,
484                         &stl->g_data->lverts_overlay_shgrp, &stl->g_data->facedot_overlay_shgrp);
485         }
486         else {
487                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
488                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
489                         &zero, &stl->g_data->edge_width_scale, stl->g_data->data_mask,
490                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
491                         &stl->g_data->face_occluded_shgrp, &stl->g_data->ledges_occluded_shgrp,
492                         &stl->g_data->lverts_occluded_shgrp, &stl->g_data->facedot_occluded_shgrp);
493
494                 /* however we loose the front faces value (because we need the depth of occluded wires and
495                  * faces are alpha blended ) so we recover them in a new pass. */
496                 psl->facefill_occlude = DRW_pass_create(
497                         "Front Face Color",
498                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
499                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
500                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo);
501                 DRW_shgroup_uniform_ivec4(stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
502
503                 /* we need a full screen pass to combine the result */
504                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
505
506                 psl->mix_occlude = DRW_pass_create(
507                         "Mix Occluded Wires",
508                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
509                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
510                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
511                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
512                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
513                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
514                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
515         }
516 }
517
518 static void edit_mesh_add_ob_to_pass(
519         Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp,
520         DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
521 {
522         struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
523         ToolSettings *tsettings = scene->toolsettings;
524
525         DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
526         DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
527         DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
528
529         if (facefill_shgrp) {
530                 DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
531         }
532
533         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
534                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
535         }
536
537         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) {
538                 geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
539                 DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
540         }
541 }
542
543 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
544 {
545         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
546         const DRWContextState *draw_ctx = DRW_context_state_get();
547         View3D *v3d = draw_ctx->v3d;
548         Scene *scene = draw_ctx->scene;
549         struct GPUBatch *geom;
550
551         if (ob->type == OB_MESH) {
552                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
553                         const Mesh *me = ob->data;
554                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
555                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
556
557                         /* Updating uniform */
558                         backwire_opacity = v3d->overlay.backwire_opacity;
559
560                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
561                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
562                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
563                         /* Updating uniform */
564                         size_normal = v3d->overlay.normals_length;
565
566                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
567
568                         if (do_show_weight) {
569                                 geom = DRW_cache_mesh_surface_weights_get(ob);
570                                 DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
571                         }
572
573                         if (do_occlude_wire) {
574                                 geom = DRW_cache_mesh_surface_get(ob);
575                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
576                         }
577
578                         if (fnormals_do) {
579                                 geom = DRW_cache_face_centers_get(ob);
580                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
581                         }
582
583                         if (vnormals_do || lnormals_do) {
584                                 struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts;
585                                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
586
587                                 if (vnormals_do) {
588                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_tris, ob->obmat);
589                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_ledges, ob->obmat);
590                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_lverts, ob->obmat);
591                                 }
592
593                                 if (lnormals_do) {
594                                         DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geo_ovl_tris, ob->obmat);
595                                 }
596                         }
597
598                         if (stl->g_data->do_zbufclip) {
599                                 edit_mesh_add_ob_to_pass(
600                                         scene, ob,
601                                         stl->g_data->face_occluded_shgrp,
602                                         stl->g_data->ledges_occluded_shgrp,
603                                         stl->g_data->lverts_occluded_shgrp,
604                                         stl->g_data->facedot_occluded_shgrp,
605                                         stl->g_data->facefill_occluded_shgrp);
606                         }
607                         else {
608                                 edit_mesh_add_ob_to_pass(
609                                         scene, ob,
610                                         stl->g_data->face_overlay_shgrp,
611                                         stl->g_data->ledges_overlay_shgrp,
612                                         stl->g_data->lverts_overlay_shgrp,
613                                         (me->drawflag & ME_DRAW_FACE_DOT) ? stl->g_data->facedot_overlay_shgrp : NULL,
614                                         NULL);
615                         }
616
617                         stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
618                         stl->g_data->edit_ob += 1;
619
620                         /* 3D text overlay */
621                         if (me->drawflag & (ME_DRAWEXTRA_EDGELEN |
622                                             ME_DRAWEXTRA_FACEAREA |
623                                             ME_DRAWEXTRA_FACEANG |
624                                             ME_DRAWEXTRA_EDGEANG |
625                                             ME_DRAWEXTRA_INDICES))
626                         {
627                                 if (DRW_state_show_text()) {
628                                         DRW_edit_mesh_mode_text_measure_stats(
629                                                draw_ctx->ar, v3d, ob, &scene->unit);
630                                 }
631                         }
632                 }
633         }
634 }
635
636 static void EDIT_MESH_draw_scene(void *vedata)
637 {
638         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
639         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
640         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
641         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
642         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
643
644         DRW_draw_pass(psl->vcolor_faces);
645
646         DRW_draw_pass(psl->depth_hidden_wire);
647
648         if (stl->g_data->do_zbufclip) {
649                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
650                 /* render facefill */
651                 DRW_draw_pass(psl->facefill_occlude);
652
653                 /* Render wires on a separate framebuffer */
654                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
655                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
656                 DRW_draw_pass(psl->normals);
657                 DRW_draw_pass(psl->edit_face_occluded);
658
659                 /* Combine with scene buffer */
660                 GPU_framebuffer_bind(dfbl->color_only_fb);
661                 DRW_draw_pass(psl->mix_occlude);
662         }
663         else {
664                 DRW_draw_pass(psl->normals);
665
666                 const DRWContextState *draw_ctx = DRW_context_state_get();
667                 View3D *v3d = draw_ctx->v3d;
668
669                 if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & V3D_SHADING_XRAY) == 0) {
670                         if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
671                                 /* In the case of single ghost object edit (common case for retopology):
672                                  * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
673                                  * the stencil buffer is no 0x00. */
674                                 const float *viewport_size = DRW_viewport_size_get();
675                                 const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
676                                 struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
677                                 GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
678                                         GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
679                                         GPU_ATTACHMENT_TEXTURE(dtxl->color),
680                                 });
681
682                                 GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
683                                 GPU_framebuffer_bind(fbl->ghost_wire_fb);
684
685                                 DRW_draw_pass(psl->ghost_clear_depth);
686                         }
687                 }
688
689                 DRW_draw_pass(psl->edit_face_overlay);
690         }
691 }
692
693 static void EDIT_MESH_engine_free(void)
694 {
695         DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
696         DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh);
697         DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh);
698         DRW_SHADER_FREE_SAFE(e_data.overlay_facefill_sh);
699         DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh);
700         DRW_SHADER_FREE_SAFE(e_data.normals_face_sh);
701         DRW_SHADER_FREE_SAFE(e_data.normals_sh);
702         DRW_SHADER_FREE_SAFE(e_data.ghost_clear_depth_sh);
703
704         for (int i = 0; i < MAX_SHADERS; i++) {
705                 DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh_cache[i]);
706                 DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh_cache[i]);
707         }
708 }
709
710 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
711
712 DrawEngineType draw_engine_edit_mesh_type = {
713         NULL, NULL,
714         N_("EditMeshMode"),
715         &EDIT_MESH_data_size,
716         &EDIT_MESH_engine_init,
717         &EDIT_MESH_engine_free,
718         &EDIT_MESH_cache_init,
719         &EDIT_MESH_cache_populate,
720         NULL,
721         NULL,
722         &EDIT_MESH_draw_scene,
723         NULL,
724         NULL,
725 };