Edit Mesh: Fix buggy occlusion when in xray mode.
[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_mode_engines.h"
37
38 #include "edit_mesh_mode_intern.h" /* own include */
39
40 #include "BKE_object.h"
41
42 #include "BLI_dynstr.h"
43
44
45 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
46 extern struct GlobalsUboStorage ts; /* draw_common.c */
47
48 extern char datatoc_edit_mesh_overlay_common_lib_glsl[];
49 extern char datatoc_edit_mesh_overlay_frag_glsl[];
50 extern char datatoc_edit_mesh_overlay_vert_glsl[];
51 extern char datatoc_edit_mesh_overlay_geom_tri_glsl[];
52 extern char datatoc_edit_mesh_overlay_geom_edge_glsl[];
53 extern char datatoc_edit_mesh_overlay_loosevert_vert_glsl[];
54 extern char datatoc_edit_mesh_overlay_facedot_frag_glsl[];
55 extern char datatoc_edit_mesh_overlay_facedot_vert_glsl[];
56 extern char datatoc_edit_mesh_overlay_mix_vert_glsl[];
57 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
58 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
59 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
60 extern char datatoc_edit_normals_vert_glsl[];
61 extern char datatoc_edit_normals_geom_glsl[];
62 extern char datatoc_common_globals_lib_glsl[];
63
64 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
65
66 /* *********** LISTS *********** */
67 typedef struct EDIT_MESH_PassList {
68         struct DRWPass *vcolor_faces;
69         struct DRWPass *depth_hidden_wire;
70         struct DRWPass *edit_face_overlay;
71         struct DRWPass *edit_face_occluded;
72         struct DRWPass *mix_occlude;
73         struct DRWPass *facefill_occlude;
74         struct DRWPass *normals;
75 } EDIT_MESH_PassList;
76
77 typedef struct EDIT_MESH_FramebufferList {
78         struct GPUFrameBuffer *occlude_wire_fb;
79 } EDIT_MESH_FramebufferList;
80
81 typedef struct EDIT_MESH_StorageList {
82         struct EDIT_MESH_PrivateData *g_data;
83 } EDIT_MESH_StorageList;
84
85 typedef struct EDIT_MESH_Data {
86         void *engine_type;
87         EDIT_MESH_FramebufferList *fbl;
88         DRWViewportEmptyList *txl;
89         EDIT_MESH_PassList *psl;
90         EDIT_MESH_StorageList *stl;
91 } EDIT_MESH_Data;
92
93 /* *********** STATIC *********** */
94 #define MAX_SHADERS 16
95
96 static struct {
97         /* weight/vert-color */
98         GPUShader *vcolor_face_shader;
99
100         /* Geometry */
101         GPUShader *overlay_tri_sh_cache[MAX_SHADERS];
102         GPUShader *overlay_loose_edge_sh_cache[MAX_SHADERS];
103
104         GPUShader *overlay_vert_sh;
105         GPUShader *overlay_facedot_sh;
106         GPUShader *overlay_mix_sh;
107         GPUShader *overlay_facefill_sh;
108         GPUShader *normals_face_sh;
109         GPUShader *normals_loop_sh;
110         GPUShader *normals_sh;
111         GPUShader *depth_sh;
112         /* temp buffer texture */
113         struct GPUTexture *occlude_wire_depth_tx;
114         struct GPUTexture *occlude_wire_color_tx;
115 } e_data = {NULL}; /* Engine data */
116
117 typedef struct EDIT_MESH_PrivateData {
118         /* weight/vert-color */
119         DRWShadingGroup *fvcolor_shgrp;
120         DRWShadingGroup *depth_shgrp_hidden_wire;
121
122         DRWShadingGroup *fnormals_shgrp;
123         DRWShadingGroup *vnormals_shgrp;
124         DRWShadingGroup *lnormals_shgrp;
125
126         DRWShadingGroup *face_overlay_shgrp;
127         DRWShadingGroup *ledges_overlay_shgrp;
128         DRWShadingGroup *lverts_overlay_shgrp;
129         DRWShadingGroup *facedot_overlay_shgrp;
130
131         DRWShadingGroup *face_occluded_shgrp;
132         DRWShadingGroup *ledges_occluded_shgrp;
133         DRWShadingGroup *lverts_occluded_shgrp;
134         DRWShadingGroup *facedot_occluded_shgrp;
135         DRWShadingGroup *facefill_occluded_shgrp;
136
137         bool do_zbufclip;
138 } EDIT_MESH_PrivateData; /* Transient data */
139
140 /* *********** FUNCTIONS *********** */
141 static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode)
142 {
143         int result = tsettings->selectmode << 1;
144         if (supports_fast_mode) {
145                 SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0);
146         }
147         return result;
148 }
149
150 static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias)
151 {
152         const int selectmode = tsettings->selectmode;
153         const int fast_mode = rv3d->rflag & RV3D_NAVIGATING;
154
155         char *str = NULL;
156         DynStr *ds = BLI_dynstr_new();
157
158         if (selectmode & SCE_SELECT_VERTEX) {
159                 BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n");
160         }
161
162         if (selectmode & SCE_SELECT_EDGE) {
163                 BLI_dynstr_append(ds, "#define EDGE_SELECTION\n");
164         }
165
166         if (selectmode & SCE_SELECT_FACE) {
167                 BLI_dynstr_append(ds, "#define FACE_SELECTION\n");
168         }
169
170         if (!fast_mode) {
171                 BLI_dynstr_append(ds, "#define EDGE_FIX\n");
172         }
173
174         if (anti_alias) {
175                 BLI_dynstr_append(ds, "#define ANTI_ALIASING\n");
176         }
177         BLI_dynstr_append(ds, "#define VERTEX_FACING\n");
178
179         str = BLI_dynstr_get_cstring(ds);
180         BLI_dynstr_free(ds);
181         return str;
182 }
183 static char *EDIT_MESH_sh_lib(void)
184 {
185         char *str = NULL;
186         DynStr *ds = BLI_dynstr_new();
187
188         BLI_dynstr_append(ds, datatoc_common_globals_lib_glsl);
189         BLI_dynstr_append(ds, datatoc_edit_mesh_overlay_common_lib_glsl);
190
191         str = BLI_dynstr_get_cstring(ds);
192         BLI_dynstr_free(ds);
193         return str;
194 }
195
196 static GPUShader *EDIT_MESH_ensure_shader(ToolSettings *tsettings, RegionView3D *rv3d, bool fast_mode, bool looseedge)
197 {
198         const int index = EDIT_MESH_sh_index(tsettings, rv3d, fast_mode);
199         if (looseedge) {
200                 if (!e_data.overlay_loose_edge_sh_cache[index]) {
201                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true);
202                         char *lib = EDIT_MESH_sh_lib();
203                         e_data.overlay_loose_edge_sh_cache[index] = DRW_shader_create_with_lib(
204                                 datatoc_edit_mesh_overlay_vert_glsl,
205                                 datatoc_edit_mesh_overlay_geom_edge_glsl,
206                                 datatoc_edit_mesh_overlay_frag_glsl,
207                                 lib,
208                                 defines);
209                         MEM_freeN(lib);
210                         MEM_freeN(defines);
211                 }
212                 return e_data.overlay_loose_edge_sh_cache[index];
213         }
214         else {
215                 if (!e_data.overlay_tri_sh_cache[index]) {
216                         char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true);
217                         char *lib = EDIT_MESH_sh_lib();
218                         e_data.overlay_tri_sh_cache[index] = DRW_shader_create_with_lib(
219                                 datatoc_edit_mesh_overlay_vert_glsl,
220                                 datatoc_edit_mesh_overlay_geom_tri_glsl,
221                                 datatoc_edit_mesh_overlay_frag_glsl,
222                                 lib,
223                                 defines);
224                         MEM_freeN(lib);
225                         MEM_freeN(defines);
226                 }
227                 return e_data.overlay_tri_sh_cache[index];
228         }
229 }
230
231 static void EDIT_MESH_engine_init(void *vedata)
232 {
233         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
234
235         const float *viewport_size = DRW_viewport_size_get();
236         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
237
238         e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
239                                                                  &draw_engine_edit_mesh_type);
240         e_data.occlude_wire_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
241                                                                  &draw_engine_edit_mesh_type);
242
243         GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb, {
244                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
245                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)
246         });
247
248         if (!e_data.vcolor_face_shader) {
249                 e_data.vcolor_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
250         }
251
252         if (!e_data.overlay_vert_sh) {
253                 char *lib = EDIT_MESH_sh_lib();
254                 e_data.overlay_vert_sh = DRW_shader_create_with_lib(
255                         datatoc_edit_mesh_overlay_loosevert_vert_glsl, NULL,
256                         datatoc_edit_mesh_overlay_frag_glsl,
257                         lib,
258                         "#define VERTEX_SELECTION\n");
259                 MEM_freeN(lib);
260         }
261         if (!e_data.overlay_facedot_sh) {
262                 e_data.overlay_facedot_sh = DRW_shader_create_with_lib(
263                         datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL,
264                         datatoc_edit_mesh_overlay_facedot_frag_glsl,
265                         datatoc_common_globals_lib_glsl,
266                         "#define VERTEX_FACING\n");
267         }
268         if (!e_data.overlay_mix_sh) {
269                 e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
270         }
271         if (!e_data.overlay_facefill_sh) {
272                 e_data.overlay_facefill_sh = DRW_shader_create_with_lib(
273                         datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL,
274                         datatoc_edit_mesh_overlay_facefill_frag_glsl,
275                         datatoc_common_globals_lib_glsl, NULL);
276         }
277         if (!e_data.normals_face_sh) {
278                 e_data.normals_face_sh = DRW_shader_create(
279                         datatoc_edit_normals_vert_glsl,
280                         datatoc_edit_normals_geom_glsl,
281                         datatoc_gpu_shader_uniform_color_frag_glsl,
282                         "#define FACE_NORMALS\n");
283         }
284         if (!e_data.normals_loop_sh) {
285                 e_data.normals_loop_sh = DRW_shader_create(
286                         datatoc_edit_normals_vert_glsl,
287                         datatoc_edit_normals_geom_glsl,
288                         datatoc_gpu_shader_uniform_color_frag_glsl,
289                         "#define LOOP_NORMALS\n");
290         }
291         if (!e_data.normals_sh) {
292                 e_data.normals_sh = DRW_shader_create(
293                         datatoc_edit_normals_vert_glsl,
294                         datatoc_edit_normals_geom_glsl,
295                         datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
296         }
297         if (!e_data.depth_sh) {
298                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
299         }
300 }
301
302 static DRWPass *edit_mesh_create_overlay_pass(
303         float *faceAlpha, DRWState statemod,
304         DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_ledges_shgrp,
305         DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp)
306 {
307         GPUShader *tri_sh, *ledge_sh;
308         const DRWContextState *draw_ctx = DRW_context_state_get();
309         RegionView3D *rv3d = draw_ctx->rv3d;
310         Scene *scene = draw_ctx->scene;
311         ToolSettings *tsettings = scene->toolsettings;
312
313         ledge_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, false, true);
314         tri_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, true, false);
315
316         DRWPass *pass = DRW_pass_create(
317                 "Edit Mesh Face Overlay Pass",
318                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
319
320         *r_face_shgrp = DRW_shgroup_create(tri_sh, pass);
321         DRW_shgroup_uniform_block(*r_face_shgrp, "globalsBlock", globals_ubo);
322         DRW_shgroup_uniform_vec2(*r_face_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
323         DRW_shgroup_uniform_float(*r_face_shgrp, "faceAlphaMod", faceAlpha, 1);
324
325         *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
326         DRW_shgroup_uniform_block(*r_ledges_shgrp, "globalsBlock", globals_ubo);
327         DRW_shgroup_uniform_vec2(*r_ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
328
329         if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
330                 *r_lverts_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, pass);
331                 DRW_shgroup_uniform_block(*r_lverts_shgrp, "globalsBlock", globals_ubo);
332                 DRW_shgroup_uniform_vec2(*r_lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
333         }
334
335         if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
336                 *r_facedot_shgrp = DRW_shgroup_create(e_data.overlay_facedot_sh, pass);
337                 DRW_shgroup_uniform_block(*r_facedot_shgrp, "globalsBlock", globals_ubo);
338         }
339
340         return pass;
341 }
342
343 static float backwire_opacity;
344 static float face_mod;
345 static float size_normal;
346
347 static void EDIT_MESH_cache_init(void *vedata)
348 {
349         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
350         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
351         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
352
353         const DRWContextState *draw_ctx = DRW_context_state_get();
354         View3D *v3d = draw_ctx->v3d;
355
356         static float zero = 0.0f;
357
358         if (!stl->g_data) {
359                 /* Alloc transient pointers */
360                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
361         }
362
363
364         const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
365                                    (draw_ctx->v3d->drawtype < OB_MATERIAL);
366         stl->g_data->do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0) || xray_enabled;
367
368         {
369                 psl->vcolor_faces = DRW_pass_create(
370                         "Vert Color Pass",
371                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
372
373                 stl->g_data->fvcolor_shgrp = DRW_shgroup_create(e_data.vcolor_face_shader, psl->vcolor_faces);
374
375                 static float light[3] = {-0.3f, 0.5f, 1.0f};
376                 static float alpha = 1.0f;
377                 static float world_light = 1.0f;  /* XXX, see: paint_vertex_mode.c */
378                 DRW_shgroup_uniform_vec3(stl->g_data->fvcolor_shgrp, "light", light, 1);
379                 DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "alpha", &alpha, 1);
380                 DRW_shgroup_uniform_float(stl->g_data->fvcolor_shgrp, "global", &world_light, 1);
381         }
382
383         {
384                 /* Complementary Depth Pass */
385                 psl->depth_hidden_wire = DRW_pass_create(
386                         "Depth Pass Hidden Wire",
387                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
388                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
389         }
390
391         {
392                 /* Normals */
393                 psl->normals = DRW_pass_create(
394                         "Edit Mesh Normals Pass",
395                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
396
397                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
398                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
399                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
400
401                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
402                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
403                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
404
405                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_loop_sh, psl->normals);
406                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
407                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
408         }
409
410         if (!stl->g_data->do_zbufclip) {
411                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
412                         &face_mod, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND,
413                         &stl->g_data->face_overlay_shgrp, &stl->g_data->ledges_overlay_shgrp,
414                         &stl->g_data->lverts_overlay_shgrp, &stl->g_data->facedot_overlay_shgrp);
415         }
416         else {
417                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
418                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
419                         &zero, DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
420                         &stl->g_data->face_occluded_shgrp, &stl->g_data->ledges_occluded_shgrp,
421                         &stl->g_data->lverts_occluded_shgrp, &stl->g_data->facedot_occluded_shgrp);
422
423                 /* however we loose the front faces value (because we need the depth of occluded wires and
424                  * faces are alpha blended ) so we recover them in a new pass. */
425                 psl->facefill_occlude = DRW_pass_create(
426                         "Front Face Color",
427                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
428                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
429                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo);
430
431                 /* we need a full screen pass to combine the result */
432                 struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
433
434                 psl->mix_occlude = DRW_pass_create(
435                         "Mix Occluded Wires",
436                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
437                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
438                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
439                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
440                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
441                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
442                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
443         }
444 }
445
446 static void edit_mesh_add_ob_to_pass(
447         Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp,
448         DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
449 {
450         struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
451         ToolSettings *tsettings = scene->toolsettings;
452
453         DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
454         DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
455         DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
456
457         if (facefill_shgrp) {
458                 DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
459         }
460
461         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
462                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
463         }
464
465         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) {
466                 geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
467                 DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
468         }
469 }
470
471 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
472 {
473         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
474         const DRWContextState *draw_ctx = DRW_context_state_get();
475         View3D *v3d = draw_ctx->v3d;
476         Scene *scene = draw_ctx->scene;
477         struct Gwn_Batch *geom;
478
479         if (ob->type == OB_MESH) {
480                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
481                         const Mesh *me = ob->data;
482                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
483                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
484
485                         /* Updating uniform */
486                         backwire_opacity = v3d->overlay.backwire_opacity;
487
488                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
489                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
490                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
491                         /* Updating uniform */
492                         size_normal = v3d->overlay.normals_length;
493
494                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
495
496                         if (do_show_weight) {
497                                 geom = DRW_cache_mesh_surface_weights_get(ob);
498                                 DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
499                         }
500
501                         if (do_occlude_wire) {
502                                 geom = DRW_cache_mesh_surface_get(ob);
503                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
504                         }
505
506                         if (fnormals_do) {
507                                 geom = DRW_cache_face_centers_get(ob);
508                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
509                         }
510
511                         if (vnormals_do || lnormals_do) {
512                                 struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts;
513                                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
514
515                                 if (vnormals_do) {
516                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_tris, ob->obmat);
517                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_ledges, ob->obmat);
518                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_lverts, ob->obmat);
519                                 }
520
521                                 if (lnormals_do) {
522                                         DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geo_ovl_tris, ob->obmat);
523                                 }
524                         }
525
526                         if (stl->g_data->do_zbufclip) {
527                                 edit_mesh_add_ob_to_pass(
528                                         scene, ob, stl->g_data->face_occluded_shgrp, stl->g_data->ledges_occluded_shgrp,
529                                         stl->g_data->lverts_occluded_shgrp, stl->g_data->facedot_occluded_shgrp,
530                                         stl->g_data->facefill_occluded_shgrp);
531                         }
532                         else {
533                                 edit_mesh_add_ob_to_pass(
534                                         scene, ob, stl->g_data->face_overlay_shgrp, stl->g_data->ledges_overlay_shgrp,
535                                         stl->g_data->lverts_overlay_shgrp, NULL, NULL);
536                         }
537
538                         /* 3D text overlay */
539                         if (me->drawflag & (ME_DRAWEXTRA_EDGELEN |
540                                             ME_DRAWEXTRA_FACEAREA |
541                                             ME_DRAWEXTRA_FACEANG |
542                                             ME_DRAWEXTRA_EDGEANG |
543                                             ME_DRAWEXTRA_INDICES))
544                         {
545                                 if (DRW_state_show_text()) {
546                                         DRW_edit_mesh_mode_text_measure_stats(
547                                                draw_ctx->ar, v3d, ob, &scene->unit);
548                                 }
549                         }
550                 }
551         }
552 }
553
554 static void EDIT_MESH_draw_scene(void *vedata)
555 {
556         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
557         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
558         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
559         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
560
561         DRW_draw_pass(psl->vcolor_faces);
562
563         DRW_draw_pass(psl->depth_hidden_wire);
564
565         if (stl->g_data->do_zbufclip) {
566                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
567                 /* render facefill */
568                 DRW_draw_pass(psl->facefill_occlude);
569
570                 /* Render wires on a separate framebuffer */
571                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
572                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
573                 DRW_draw_pass(psl->normals);
574                 DRW_draw_pass(psl->edit_face_occluded);
575
576                 /* Combine with scene buffer */
577                 GPU_framebuffer_bind(dfbl->color_only_fb);
578                 DRW_draw_pass(psl->mix_occlude);
579         }
580         else {
581                 DRW_draw_pass(psl->normals);
582                 DRW_draw_pass(psl->edit_face_overlay);
583         }
584 }
585
586 static void EDIT_MESH_engine_free(void)
587 {
588         DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
589         DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh);
590         DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh);
591         DRW_SHADER_FREE_SAFE(e_data.overlay_facefill_sh);
592         DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh);
593         DRW_SHADER_FREE_SAFE(e_data.normals_face_sh);
594         DRW_SHADER_FREE_SAFE(e_data.normals_sh);
595
596         for (int i = 0; i < MAX_SHADERS; i++) {
597                 DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh_cache[i]);
598                 DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh_cache[i]);
599         }
600 }
601
602 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
603
604 DrawEngineType draw_engine_edit_mesh_type = {
605         NULL, NULL,
606         N_("EditMeshMode"),
607         &EDIT_MESH_data_size,
608         &EDIT_MESH_engine_init,
609         &EDIT_MESH_engine_free,
610         &EDIT_MESH_cache_init,
611         &EDIT_MESH_cache_populate,
612         NULL,
613         NULL,
614         &EDIT_MESH_draw_scene,
615         NULL,
616         NULL,
617 };