02b928430644f05c74d877db07e2c98bb80ff08b
[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 struct GPUTexture *globals_weight_ramp; /* draw_common.c */
50
51 extern char datatoc_paint_weight_vert_glsl[];
52 extern char datatoc_paint_weight_frag_glsl[];
53
54 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
55 extern char datatoc_edit_mesh_overlay_frag_glsl[];
56 extern char datatoc_edit_mesh_overlay_vert_glsl[];
57 extern char datatoc_edit_mesh_overlay_geom_tri_glsl[];
58 extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
59 extern char datatoc_edit_mesh_overlay_points_vert_glsl[];
60 extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
61 extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
62 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
63 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
64 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
65 extern char datatoc_edit_normals_vert_glsl[];
66 extern char datatoc_edit_normals_geom_glsl[];
67 extern char datatoc_common_globals_lib_glsl[];
68
69 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
70 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
71 extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
72 extern char datatoc_gpu_shader_depth_only_frag_glsl[];
73
74 /* *********** LISTS *********** */
75 typedef struct EDIT_MESH_PassList {
76         struct DRWPass *weight_faces;
77         struct DRWPass *depth_hidden_wire;
78         struct DRWPass *ghost_clear_depth;
79         struct DRWPass *edit_face_overlay;
80         struct DRWPass *edit_face_occluded;
81         struct DRWPass *mix_occlude;
82         struct DRWPass *facefill_occlude;
83         struct DRWPass *normals;
84 } EDIT_MESH_PassList;
85
86 typedef struct EDIT_MESH_FramebufferList {
87         struct GPUFrameBuffer *occlude_wire_fb;
88         struct GPUFrameBuffer *ghost_wire_fb;
89 } EDIT_MESH_FramebufferList;
90
91 typedef struct EDIT_MESH_StorageList {
92         struct EDIT_MESH_PrivateData *g_data;
93 } EDIT_MESH_StorageList;
94
95 typedef struct EDIT_MESH_Data {
96         void *engine_type;
97         EDIT_MESH_FramebufferList *fbl;
98         DRWViewportEmptyList *txl;
99         EDIT_MESH_PassList *psl;
100         EDIT_MESH_StorageList *stl;
101 } EDIT_MESH_Data;
102
103 /* *********** STATIC *********** */
104 #define MAX_SHADERS 16
105
106 static struct {
107         /* weight */
108         GPUShader *weight_face_shader;
109
110         /* Geometry */
111         GPUShader *overlay_tri_sh_cache[MAX_SHADERS];
112         GPUShader *overlay_loose_edge_sh_cache[MAX_SHADERS];
113
114         GPUShader *overlay_vert_sh;
115         GPUShader *overlay_lvert_sh;
116         GPUShader *overlay_facedot_sh;
117         GPUShader *overlay_mix_sh;
118         GPUShader *overlay_facefill_sh;
119         GPUShader *normals_face_sh;
120         GPUShader *normals_loop_sh;
121         GPUShader *normals_sh;
122         GPUShader *depth_sh;
123         GPUShader *ghost_clear_depth_sh;
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
134         DRWShadingGroup *fnormals_shgrp;
135         DRWShadingGroup *vnormals_shgrp;
136         DRWShadingGroup *lnormals_shgrp;
137
138         DRWShadingGroup *face_overlay_shgrp;
139         DRWShadingGroup *verts_overlay_shgrp;
140         DRWShadingGroup *ledges_overlay_shgrp;
141         DRWShadingGroup *lverts_overlay_shgrp;
142         DRWShadingGroup *facedot_overlay_shgrp;
143
144         DRWShadingGroup *face_occluded_shgrp;
145         DRWShadingGroup *verts_occluded_shgrp;
146         DRWShadingGroup *ledges_occluded_shgrp;
147         DRWShadingGroup *lverts_occluded_shgrp;
148         DRWShadingGroup *facedot_occluded_shgrp;
149         DRWShadingGroup *facefill_occluded_shgrp;
150
151         int data_mask[4];
152         int ghost_ob;
153         int edit_ob;
154         bool do_zbufclip;
155         bool do_faces;
156         bool do_edges;
157         float edge_width_scale;
158 } EDIT_MESH_PrivateData; /* Transient data */
159
160 /* *********** FUNCTIONS *********** */
161 static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode)
162 {
163         int result = tsettings->selectmode << 1;
164         if (supports_fast_mode) {
165                 SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0);
166         }
167         return result;
168 }
169
170 static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias, bool looseedge)
171 {
172         const int selectmode = tsettings->selectmode;
173         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
174
175         char *str = NULL;
176         DynStr *ds = BLI_dynstr_new();
177
178         if (selectmode & SCE_SELECT_VERTEX) {
179                 BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n");
180         }
181
182         if (selectmode & SCE_SELECT_EDGE) {
183                 BLI_dynstr_append(ds, "#define EDGE_SELECTION\n");
184         }
185
186         if (selectmode & SCE_SELECT_FACE) {
187                 BLI_dynstr_append(ds, "#define FACE_SELECTION\n");
188         }
189
190         if (!fast_mode || looseedge) {
191                 BLI_dynstr_append(ds, "#define EDGE_FIX\n");
192         }
193
194         if (anti_alias) {
195                 BLI_dynstr_append(ds, "#define ANTI_ALIASING\n");
196         }
197
198         if (!looseedge) {
199                 BLI_dynstr_append(ds, "#define VERTEX_FACING\n");
200         }
201
202         str = BLI_dynstr_get_cstring(ds);
203         BLI_dynstr_free(ds);
204         return str;
205 }
206 static char *EDIT_MESH_sh_lib(void)
207 {
208         char *str = NULL;
209         DynStr *ds = BLI_dynstr_new();
210
211         BLI_dynstr_append(ds, datatoc_common_globals_lib_glsl);
212         BLI_dynstr_append(ds, datatoc_edit_mesh_overlay_common_lib_glsl);
213
214         str = BLI_dynstr_get_cstring(ds);
215         BLI_dynstr_free(ds);
216         return str;
217 }
218
219 static GPUShader *EDIT_MESH_ensure_shader(
220         ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode, bool looseedge)
221 {
222         const int index = EDIT_MESH_sh_index(tsettings, rv3d, supports_fast_mode);
223         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
224         if (looseedge) {
225                 if (!e_data.overlay_loose_edge_sh_cache[index]) {
226                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, true);
227                         char *lib = EDIT_MESH_sh_lib();
228                         e_data.overlay_loose_edge_sh_cache[index] = DRW_shader_create_with_lib(
229                                 datatoc_edit_mesh_overlay_vert_glsl,
230                                 datatoc_edit_mesh_overlay_geom_edge_glsl,
231                                 datatoc_edit_mesh_overlay_frag_glsl,
232                                 lib,
233                                 defines);
234                         MEM_freeN(lib);
235                         MEM_freeN(defines);
236                 }
237                 return e_data.overlay_loose_edge_sh_cache[index];
238         }
239         else {
240                 if (!e_data.overlay_tri_sh_cache[index]) {
241                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, false);
242                         char *lib = EDIT_MESH_sh_lib();
243                         e_data.overlay_tri_sh_cache[index] = DRW_shader_create_with_lib(
244                                 datatoc_edit_mesh_overlay_vert_glsl,
245                                 fast_mode ? NULL : datatoc_edit_mesh_overlay_geom_tri_glsl,
246                                 datatoc_edit_mesh_overlay_frag_glsl,
247                                 lib,
248                                 defines);
249                         MEM_freeN(lib);
250                         MEM_freeN(defines);
251                 }
252                 return e_data.overlay_tri_sh_cache[index];
253         }
254 }
255
256 static void EDIT_MESH_engine_init(void *vedata)
257 {
258         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
259
260         const float *viewport_size = DRW_viewport_size_get();
261         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
262
263         e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
264                                                                  &draw_engine_edit_mesh_type);
265         e_data.occlude_wire_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
266                                                                  &draw_engine_edit_mesh_type);
267
268         GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb, {
269                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
270                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)
271         });
272
273         if (!e_data.weight_face_shader) {
274                 e_data.weight_face_shader = DRW_shader_create_with_lib(
275                         datatoc_paint_weight_vert_glsl, NULL,
276                         datatoc_paint_weight_frag_glsl,
277                         datatoc_common_globals_lib_glsl, NULL);
278         }
279
280         if (!e_data.overlay_vert_sh) {
281                 char *lib = EDIT_MESH_sh_lib();
282                 e_data.overlay_vert_sh = DRW_shader_create_with_lib(
283                         datatoc_edit_mesh_overlay_points_vert_glsl, NULL,
284                         datatoc_gpu_shader_point_varying_color_frag_glsl, lib,
285                         "#define VERTEX_FACING\n");
286                 e_data.overlay_lvert_sh = DRW_shader_create_with_lib(
287                         datatoc_edit_mesh_overlay_points_vert_glsl, NULL,
288                         datatoc_gpu_shader_point_varying_color_frag_glsl, lib,
289                         NULL);
290                 MEM_freeN(lib);
291         }
292         if (!e_data.overlay_facedot_sh) {
293                 e_data.overlay_facedot_sh = DRW_shader_create_with_lib(
294                         datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL,
295                         datatoc_edit_mesh_overlay_facedot_frag_glsl,
296                         datatoc_common_globals_lib_glsl,
297                         "#define VERTEX_FACING\n");
298         }
299         if (!e_data.overlay_mix_sh) {
300                 e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
301         }
302         if (!e_data.overlay_facefill_sh) {
303                 e_data.overlay_facefill_sh = DRW_shader_create_with_lib(
304                         datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL,
305                         datatoc_edit_mesh_overlay_facefill_frag_glsl,
306                         datatoc_common_globals_lib_glsl, NULL);
307         }
308         if (!e_data.normals_face_sh) {
309                 e_data.normals_face_sh = DRW_shader_create(
310                         datatoc_edit_normals_vert_glsl,
311                         datatoc_edit_normals_geom_glsl,
312                         datatoc_gpu_shader_uniform_color_frag_glsl,
313                         "#define FACE_NORMALS\n");
314         }
315         if (!e_data.normals_loop_sh) {
316                 e_data.normals_loop_sh = DRW_shader_create(
317                         datatoc_edit_normals_vert_glsl,
318                         datatoc_edit_normals_geom_glsl,
319                         datatoc_gpu_shader_uniform_color_frag_glsl,
320                         "#define LOOP_NORMALS\n");
321         }
322         if (!e_data.normals_sh) {
323                 e_data.normals_sh = DRW_shader_create(
324                         datatoc_edit_normals_vert_glsl,
325                         datatoc_edit_normals_geom_glsl,
326                         datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
327         }
328         if (!e_data.depth_sh) {
329                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
330         }
331         if (!e_data.ghost_clear_depth_sh) {
332                 e_data.ghost_clear_depth_sh = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL);
333         }
334
335 }
336
337 static DRWPass *edit_mesh_create_overlay_pass(
338         float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool xray,
339         DRWState statemod,
340         DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_verts_shgrp, DRWShadingGroup **r_ledges_shgrp,
341         DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp)
342 {
343         GPUShader *tri_sh, *ledge_sh;
344         const DRWContextState *draw_ctx = DRW_context_state_get();
345         RegionView3D *rv3d = draw_ctx->rv3d;
346         Scene *scene = draw_ctx->scene;
347         ToolSettings *tsettings = scene->toolsettings;
348         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
349
350         ledge_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, false, true);
351         tri_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, true, false);
352
353         DRWPass *pass = DRW_pass_create(
354                 "Edit Mesh Face Overlay Pass",
355                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
356
357         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
358                 *r_lverts_shgrp = DRW_shgroup_create(e_data.overlay_lvert_sh, pass);
359                 DRW_shgroup_uniform_block(*r_lverts_shgrp, "globalsBlock", globals_ubo);
360                 DRW_shgroup_uniform_vec2(*r_lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
361                 DRW_shgroup_uniform_float(*r_lverts_shgrp, "edgeScale", edge_width_scale, 1);
362                 DRW_shgroup_state_enable(*r_lverts_shgrp, DRW_STATE_WRITE_DEPTH);
363
364                 *r_verts_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, pass);
365                 DRW_shgroup_uniform_block(*r_verts_shgrp, "globalsBlock", globals_ubo);
366                 DRW_shgroup_uniform_vec2(*r_verts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
367                 DRW_shgroup_uniform_float(*r_verts_shgrp, "edgeScale", edge_width_scale, 1);
368                 DRW_shgroup_state_enable(*r_verts_shgrp, DRW_STATE_WRITE_DEPTH);
369         }
370
371         if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
372                 *r_facedot_shgrp = DRW_shgroup_create(e_data.overlay_facedot_sh, pass);
373                 DRW_shgroup_uniform_block(*r_facedot_shgrp, "globalsBlock", globals_ubo);
374                 DRW_shgroup_uniform_float(*r_facedot_shgrp, "edgeScale", edge_width_scale, 1);
375                 DRW_shgroup_state_enable(*r_facedot_shgrp, DRW_STATE_WRITE_DEPTH);
376         }
377
378         *r_face_shgrp = DRW_shgroup_create(tri_sh, pass);
379         DRW_shgroup_uniform_block(*r_face_shgrp, "globalsBlock", globals_ubo);
380         DRW_shgroup_uniform_vec2(*r_face_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
381         DRW_shgroup_uniform_float(*r_face_shgrp, "faceAlphaMod", face_alpha, 1);
382         DRW_shgroup_uniform_float(*r_face_shgrp, "edgeScale", edge_width_scale, 1);
383         DRW_shgroup_uniform_ivec4(*r_face_shgrp, "dataMask", data_mask, 1);
384         DRW_shgroup_uniform_bool_copy(*r_face_shgrp, "doEdges", do_edges);
385         if (!fast_mode) {
386                 DRW_shgroup_uniform_bool_copy(*r_face_shgrp, "isXray", xray);
387         }
388
389         *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
390         DRW_shgroup_uniform_block(*r_ledges_shgrp, "globalsBlock", globals_ubo);
391         DRW_shgroup_uniform_vec2(*r_ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
392         DRW_shgroup_uniform_float(*r_ledges_shgrp, "edgeScale", edge_width_scale, 1);
393         DRW_shgroup_uniform_ivec4(*r_ledges_shgrp, "dataMask", data_mask, 1);
394         DRW_shgroup_uniform_bool_copy(*r_ledges_shgrp, "doEdges", do_edges);
395
396         return pass;
397 }
398
399 static float backwire_opacity;
400 static float face_mod;
401 static float size_normal;
402
403 static void EDIT_MESH_cache_init(void *vedata)
404 {
405         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
406         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
407         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
408
409         const DRWContextState *draw_ctx = DRW_context_state_get();
410         View3D *v3d = draw_ctx->v3d;
411         Scene *scene = draw_ctx->scene;
412         ToolSettings *tsettings = scene->toolsettings;
413
414         static float zero = 0.0f;
415
416         if (!stl->g_data) {
417                 /* Alloc transient pointers */
418                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
419         }
420         stl->g_data->ghost_ob = 0;
421         stl->g_data->edit_ob = 0;
422         stl->g_data->do_faces = true;
423         stl->g_data->do_edges = true;
424
425         stl->g_data->do_zbufclip = ((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0;
426
427         /* Applies on top of the theme edge width, so edge-mode can have thick edges. */
428         stl->g_data->edge_width_scale = (tsettings->selectmode & (SCE_SELECT_EDGE)) ? 1.75f : 1.0f;
429
430         stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
431         stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
432         stl->g_data->data_mask[2] = 0xFF; /* Crease */
433         stl->g_data->data_mask[3] = 0xFF; /* BWeight */
434
435         if (draw_ctx->object_edit->type == OB_MESH) {
436                 if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
437                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE) == 0) {
438                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
439                         }
440                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACES) == 0) {
441                                 stl->g_data->data_mask[0] &= ~(VFLAG_FACE_SELECTED & VFLAG_FACE_FREESTYLE);
442                                 stl->g_data->do_faces = false;
443                         }
444                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
445                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
446                         }
447                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SHARP) == 0) {
448                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
449                         }
450                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE) == 0) {
451                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
452                         }
453                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
454                                 if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
455                                         stl->g_data->data_mask[1] &= ~(VFLAG_EDGE_ACTIVE & VFLAG_EDGE_SELECTED);
456                                         stl->g_data->do_edges = false;
457                                 }
458                         }
459                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CREASES) == 0) {
460                                 stl->g_data->data_mask[2] = 0x0;
461                         }
462                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_BWEIGHTS) == 0) {
463                                 stl->g_data->data_mask[3] = 0x0;
464                         }
465                 }
466         }
467
468         {
469                 psl->weight_faces = DRW_pass_create(
470                         "Weight Pass",
471                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
472
473                 stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
474
475                 static float alpha = 1.0f;
476                 DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &alpha, 1);
477                 DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", globals_weight_ramp);
478                 DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", globals_ubo);
479         }
480
481         {
482                 /* Complementary Depth Pass */
483                 psl->depth_hidden_wire = DRW_pass_create(
484                         "Depth Pass Hidden Wire",
485                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
486                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
487         }
488
489         {
490                 /* Depth clearing for ghosting. */
491                 psl->ghost_clear_depth = DRW_pass_create(
492                         "Ghost Depth Clear",
493                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
494
495                 DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.ghost_clear_depth_sh, psl->ghost_clear_depth);
496                 DRW_shgroup_stencil_mask(shgrp, 0x00);
497                 DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
498         }
499
500         {
501                 /* Normals */
502                 psl->normals = DRW_pass_create(
503                         "Edit Mesh Normals Pass",
504                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
505
506                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
507                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
508                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
509
510                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
511                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
512                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
513
514                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_loop_sh, psl->normals);
515                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
516                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
517         }
518
519         if (!stl->g_data->do_zbufclip) {
520                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
521                         &face_mod, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, false,
522                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
523                         &stl->g_data->face_overlay_shgrp,
524                         &stl->g_data->verts_overlay_shgrp,
525                         &stl->g_data->ledges_overlay_shgrp,
526                         &stl->g_data->lverts_overlay_shgrp,
527                         &stl->g_data->facedot_overlay_shgrp);
528         }
529         else {
530                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
531                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
532                         &zero, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, true,
533                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
534                         &stl->g_data->face_occluded_shgrp,
535                         &stl->g_data->verts_occluded_shgrp,
536                         &stl->g_data->ledges_occluded_shgrp,
537                         &stl->g_data->lverts_occluded_shgrp,
538                         &stl->g_data->facedot_occluded_shgrp);
539
540                 /* however we loose the front faces value (because we need the depth of occluded wires and
541                  * faces are alpha blended ) so we recover them in a new pass. */
542                 psl->facefill_occlude = DRW_pass_create(
543                         "Front Face Color",
544                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
545                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
546                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo);
547                 DRW_shgroup_uniform_ivec4(stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
548
549                 /* we need a full screen pass to combine the result */
550                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
551
552                 psl->mix_occlude = DRW_pass_create(
553                         "Mix Occluded Wires",
554                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
555                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
556                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
557                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
558                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
559                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
560                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
561         }
562 }
563
564 static void edit_mesh_add_ob_to_pass(
565         Scene *scene, Object *ob,
566         DRWShadingGroup *face_shgrp,
567         DRWShadingGroup *verts_shgrp,
568         DRWShadingGroup *ledges_shgrp,
569         DRWShadingGroup *lverts_shgrp,
570         DRWShadingGroup *facedot_shgrp,
571         DRWShadingGroup *facefill_shgrp)
572 {
573         struct GPUBatch *geo_ovl_tris, *geo_ovl_verts, *geo_ovl_lnor, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
574         struct GPUTexture *data_texture;
575         ToolSettings *tsettings = scene->toolsettings;
576
577         DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts, &data_texture);
578
579         face_shgrp = DRW_shgroup_create_sub(face_shgrp);
580         DRW_shgroup_uniform_texture(face_shgrp, "dataBuffer", data_texture);
581         DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
582
583         DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
584
585         if (facefill_shgrp) {
586                 DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
587         }
588
589         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
590                 /* Thoses are point batches. */
591                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_verts, &geo_ovl_lnor, &geo_ovl_ledges, &geo_ovl_lverts);
592                 DRW_shgroup_call_add(verts_shgrp, geo_ovl_verts, ob->obmat);
593                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_ledges, ob->obmat);
594                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
595         }
596
597         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) {
598                 geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
599                 DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
600         }
601 }
602
603 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
604 {
605         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
606         const DRWContextState *draw_ctx = DRW_context_state_get();
607         View3D *v3d = draw_ctx->v3d;
608         Scene *scene = draw_ctx->scene;
609         ToolSettings *tsettings = scene->toolsettings;
610         struct GPUBatch *geom;
611
612         if (ob->type == OB_MESH) {
613                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
614                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
615                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
616                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
617                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
618                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
619
620                         bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0;
621
622                         if (stl->g_data->do_faces == false &&
623                             stl->g_data->do_edges == false &&
624                             (tsettings->selectmode & SCE_SELECT_FACE))
625                         {
626                                 /* Force display of face centers in this case because that's
627                                  * the only way to see if a face is selected. */
628                                 show_face_dots = true;
629                         }
630
631                         /* Updating uniform */
632                         backwire_opacity = v3d->overlay.backwire_opacity;
633                         size_normal = v3d->overlay.normals_length;
634
635                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
636
637                         if (!stl->g_data->do_faces) {
638                                 face_mod = 0.0f;
639                         }
640
641                         if (do_show_weight) {
642                                 geom = DRW_cache_mesh_surface_weights_get(ob, tsettings, false);
643                                 DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
644                         }
645
646                         if (do_occlude_wire) {
647                                 geom = DRW_cache_mesh_surface_get(ob, false);
648                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
649                         }
650
651                         if (fnormals_do) {
652                                 geom = DRW_cache_face_centers_get(ob);
653                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
654                         }
655
656                         if (vnormals_do || lnormals_do) {
657                                 struct GPUBatch *geo_ovl_tris, *geo_ovl_lnor, *geo_ovl_ledges, *geo_ovl_lverts;
658                                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_lnor, &geo_ovl_ledges, &geo_ovl_lverts);
659
660                                 if (vnormals_do) {
661                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_tris, ob->obmat);
662                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_ledges, ob->obmat);
663                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_lverts, ob->obmat);
664                                 }
665
666                                 if (lnormals_do) {
667                                         DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geo_ovl_lnor, ob->obmat);
668                                 }
669                         }
670
671                         if (stl->g_data->do_zbufclip) {
672                                 edit_mesh_add_ob_to_pass(
673                                         scene, ob,
674                                         stl->g_data->face_occluded_shgrp,
675                                         stl->g_data->verts_occluded_shgrp,
676                                         stl->g_data->ledges_occluded_shgrp,
677                                         stl->g_data->lverts_occluded_shgrp,
678                                         stl->g_data->facedot_occluded_shgrp,
679                                         (stl->g_data->do_faces) ? stl->g_data->facefill_occluded_shgrp : NULL);
680                         }
681                         else {
682                                 edit_mesh_add_ob_to_pass(
683                                         scene, ob,
684                                         stl->g_data->face_overlay_shgrp,
685                                         stl->g_data->verts_overlay_shgrp,
686                                         stl->g_data->ledges_overlay_shgrp,
687                                         stl->g_data->lverts_overlay_shgrp,
688                                         (show_face_dots) ? stl->g_data->facedot_overlay_shgrp : NULL,
689                                         NULL);
690                         }
691
692                         stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
693                         stl->g_data->edit_ob += 1;
694
695                         /* 3D text overlay */
696                         if (v3d->overlay.edit_flag & (V3D_OVERLAY_EDIT_EDGE_LEN |
697                                                       V3D_OVERLAY_EDIT_FACE_AREA |
698                                                       V3D_OVERLAY_EDIT_FACE_ANG |
699                                                       V3D_OVERLAY_EDIT_EDGE_ANG |
700                                                       V3D_OVERLAY_EDIT_INDICES))
701                         {
702                                 if (DRW_state_show_text()) {
703                                         DRW_edit_mesh_mode_text_measure_stats(
704                                                draw_ctx->ar, v3d, ob, &scene->unit);
705                                 }
706                         }
707                 }
708         }
709 }
710
711 static void EDIT_MESH_draw_scene(void *vedata)
712 {
713         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
714         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
715         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
716         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
717         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
718
719         DRW_draw_pass(psl->weight_faces);
720
721         DRW_draw_pass(psl->depth_hidden_wire);
722
723         if (stl->g_data->do_zbufclip) {
724                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
725                 /* render facefill */
726                 DRW_draw_pass(psl->facefill_occlude);
727
728                 /* Render wires on a separate framebuffer */
729                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
730                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
731                 DRW_draw_pass(psl->normals);
732                 DRW_draw_pass(psl->edit_face_occluded);
733
734                 /* Combine with scene buffer */
735                 GPU_framebuffer_bind(dfbl->color_only_fb);
736                 DRW_draw_pass(psl->mix_occlude);
737         }
738         else {
739                 DRW_draw_pass(psl->normals);
740
741                 const DRWContextState *draw_ctx = DRW_context_state_get();
742                 View3D *v3d = draw_ctx->v3d;
743
744                 if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0) {
745                         if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
746                                 /* In the case of single ghost object edit (common case for retopology):
747                                  * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
748                                  * the stencil buffer is no 0x00. */
749                                 const float *viewport_size = DRW_viewport_size_get();
750                                 const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
751                                 struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
752                                 GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
753                                         GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
754                                         GPU_ATTACHMENT_TEXTURE(dtxl->color),
755                                 });
756
757                                 GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
758                                 GPU_framebuffer_bind(fbl->ghost_wire_fb);
759
760                                 DRW_draw_pass(psl->ghost_clear_depth);
761                         }
762                 }
763
764                 DRW_draw_pass(psl->edit_face_overlay);
765         }
766 }
767
768 static void EDIT_MESH_engine_free(void)
769 {
770         DRW_SHADER_FREE_SAFE(e_data.weight_face_shader);
771
772         DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
773         DRW_SHADER_FREE_SAFE(e_data.overlay_lvert_sh);
774         DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh);
775         DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh);
776         DRW_SHADER_FREE_SAFE(e_data.overlay_facefill_sh);
777         DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh);
778         DRW_SHADER_FREE_SAFE(e_data.normals_face_sh);
779         DRW_SHADER_FREE_SAFE(e_data.normals_sh);
780         DRW_SHADER_FREE_SAFE(e_data.ghost_clear_depth_sh);
781
782         for (int i = 0; i < MAX_SHADERS; i++) {
783                 DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh_cache[i]);
784                 DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh_cache[i]);
785         }
786 }
787
788 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
789
790 DrawEngineType draw_engine_edit_mesh_type = {
791         NULL, NULL,
792         N_("EditMeshMode"),
793         &EDIT_MESH_data_size,
794         &EDIT_MESH_engine_init,
795         &EDIT_MESH_engine_free,
796         &EDIT_MESH_cache_init,
797         &EDIT_MESH_cache_populate,
798         NULL,
799         NULL,
800         &EDIT_MESH_draw_scene,
801         NULL,
802         NULL,
803 };