Cleanup: use DRW_cache_mesh prefix w/ mesh objects
[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 #include "DNA_view3d_types.h"
31
32 #include "draw_common.h"
33
34 #include "draw_mode_engines.h"
35
36 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
37 extern struct GlobalsUboStorage ts; /* draw_common.c */
38
39 extern char datatoc_edit_overlay_frag_glsl[];
40 extern char datatoc_edit_overlay_vert_glsl[];
41 extern char datatoc_edit_overlay_geom_tri_glsl[];
42 extern char datatoc_edit_overlay_geom_edge_glsl[];
43 extern char datatoc_edit_overlay_loosevert_vert_glsl[];
44 extern char datatoc_edit_overlay_facedot_frag_glsl[];
45 extern char datatoc_edit_overlay_facedot_vert_glsl[];
46 extern char datatoc_edit_overlay_mix_vert_glsl[];
47 extern char datatoc_edit_overlay_mix_frag_glsl[];
48 extern char datatoc_edit_overlay_facefill_vert_glsl[];
49 extern char datatoc_edit_overlay_facefill_frag_glsl[];
50 extern char datatoc_edit_normals_vert_glsl[];
51 extern char datatoc_edit_normals_geom_glsl[];
52 extern char datatoc_common_globals_lib_glsl[];
53
54 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
55
56 /* *********** LISTS *********** */
57 /* keep it under MAX_PASSES */
58 typedef struct EDIT_MESH_PassList {
59         struct DRWPass *depth_hidden_wire;
60         struct DRWPass *edit_face_overlay;
61         struct DRWPass *edit_face_occluded;
62         struct DRWPass *mix_occlude;
63         struct DRWPass *facefill_occlude;
64         struct DRWPass *normals;
65 } EDIT_MESH_PassList;
66
67 /* keep it under MAX_BUFFERS */
68 typedef struct EDIT_MESH_FramebufferList {
69         struct GPUFrameBuffer *occlude_wire_fb;
70 } EDIT_MESH_FramebufferList;
71
72 /* keep it under MAX_TEXTURES */
73 typedef struct EDIT_MESH_TextureList {
74         struct GPUTexture *occlude_wire_depth_tx;
75         struct GPUTexture *occlude_wire_color_tx;
76 } EDIT_MESH_TextureList;
77
78 /* keep it under MAX_STORAGE */
79 typedef struct EDIT_MESH_StorageList {
80         struct g_data *g_data;
81 } EDIT_MESH_StorageList;
82
83 typedef struct EDIT_MESH_Data {
84         void *engine_type;
85         EDIT_MESH_FramebufferList *fbl;
86         EDIT_MESH_TextureList *txl;
87         EDIT_MESH_PassList *psl;
88         void *stl;
89 } EDIT_MESH_Data;
90
91 /* *********** STATIC *********** */
92
93 static struct {
94         struct GPUShader *overlay_tri_sh;
95         struct GPUShader *overlay_tri_fast_sh;
96         struct GPUShader *overlay_tri_vcol_sh;
97         struct GPUShader *overlay_tri_vcol_fast_sh;
98         struct GPUShader *overlay_edge_sh;
99         struct GPUShader *overlay_edge_vcol_sh;
100         struct GPUShader *overlay_vert_sh;
101         struct GPUShader *overlay_facedot_sh;
102         struct GPUShader *overlay_mix_sh;
103         struct GPUShader *overlay_facefill_sh;
104         struct GPUShader *normals_face_sh;
105         struct GPUShader *normals_sh;
106         struct GPUShader *depth_sh;
107 } e_data = {NULL}; /* Engine data */
108
109 typedef struct g_data {
110         DRWShadingGroup *depth_shgrp_hidden_wire;
111
112         DRWShadingGroup *fnormals_shgrp;
113         DRWShadingGroup *vnormals_shgrp;
114         DRWShadingGroup *lnormals_shgrp;
115
116         DRWShadingGroup *face_overlay_shgrp;
117         DRWShadingGroup *ledges_overlay_shgrp;
118         DRWShadingGroup *lverts_overlay_shgrp;
119         DRWShadingGroup *facedot_overlay_shgrp;
120
121         DRWShadingGroup *face_occluded_shgrp;
122         DRWShadingGroup *ledges_occluded_shgrp;
123         DRWShadingGroup *lverts_occluded_shgrp;
124         DRWShadingGroup *facedot_occluded_shgrp;
125         DRWShadingGroup *facefill_occluded_shgrp;
126
127 } g_data; /* Transient data */
128
129 /* *********** FUNCTIONS *********** */
130
131 static void EDIT_MESH_engine_init(void *vedata)
132 {
133         EDIT_MESH_TextureList *txl = ((EDIT_MESH_Data *)vedata)->txl;
134         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
135
136         const float *viewport_size = DRW_viewport_size_get();
137
138         DRWFboTexture tex[2] = {{
139             &txl->occlude_wire_depth_tx, DRW_BUF_DEPTH_24, 0},
140             {&txl->occlude_wire_color_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER}
141         };
142         DRW_framebuffer_init(
143                 &fbl->occlude_wire_fb,
144                 (int)viewport_size[0], (int)viewport_size[1],
145                 tex, ARRAY_SIZE(tex));
146
147         if (!e_data.overlay_tri_sh) {
148                 e_data.overlay_tri_sh = DRW_shader_create_with_lib(
149                         datatoc_edit_overlay_vert_glsl,
150                         datatoc_edit_overlay_geom_tri_glsl,
151                         datatoc_edit_overlay_frag_glsl,
152                         datatoc_common_globals_lib_glsl, "#define EDGE_FIX\n");
153         }
154         if (!e_data.overlay_tri_fast_sh) {
155                 e_data.overlay_tri_fast_sh = DRW_shader_create_with_lib(
156                         datatoc_edit_overlay_vert_glsl,
157                         datatoc_edit_overlay_geom_tri_glsl,
158                         datatoc_edit_overlay_frag_glsl,
159                         datatoc_common_globals_lib_glsl, NULL);
160         }
161         if (!e_data.overlay_tri_vcol_sh) {
162                 e_data.overlay_tri_vcol_sh = DRW_shader_create_with_lib(
163                         datatoc_edit_overlay_vert_glsl,
164                         datatoc_edit_overlay_geom_tri_glsl,
165                         datatoc_edit_overlay_frag_glsl,
166                         datatoc_common_globals_lib_glsl,
167                         "#define EDGE_FIX\n"
168                         "#define VERTEX_SELECTION\n");
169         }
170         if (!e_data.overlay_tri_vcol_fast_sh) {
171                 e_data.overlay_tri_vcol_fast_sh = DRW_shader_create_with_lib(
172                         datatoc_edit_overlay_vert_glsl,
173                         datatoc_edit_overlay_geom_tri_glsl,
174                         datatoc_edit_overlay_frag_glsl,
175                         datatoc_common_globals_lib_glsl,
176                         "#define VERTEX_SELECTION\n");
177         }
178         if (!e_data.overlay_edge_sh) {
179                 e_data.overlay_edge_sh = DRW_shader_create_with_lib(
180                         datatoc_edit_overlay_vert_glsl,
181                         datatoc_edit_overlay_geom_edge_glsl,
182                         datatoc_edit_overlay_frag_glsl,
183                         datatoc_common_globals_lib_glsl, NULL);
184         }
185         if (!e_data.overlay_edge_vcol_sh) {
186                 e_data.overlay_edge_vcol_sh = DRW_shader_create_with_lib(
187                         datatoc_edit_overlay_vert_glsl,
188                         datatoc_edit_overlay_geom_edge_glsl,
189                         datatoc_edit_overlay_frag_glsl,
190                         datatoc_common_globals_lib_glsl,
191                         "#define VERTEX_SELECTION\n");
192         }
193         if (!e_data.overlay_vert_sh) {
194                 e_data.overlay_vert_sh = DRW_shader_create_with_lib(
195                         datatoc_edit_overlay_loosevert_vert_glsl, NULL,
196                         datatoc_edit_overlay_frag_glsl,
197                         datatoc_common_globals_lib_glsl,
198                         "#define VERTEX_SELECTION\n");
199         }
200         if (!e_data.overlay_facedot_sh) {
201                 e_data.overlay_facedot_sh = DRW_shader_create_with_lib(
202                         datatoc_edit_overlay_facedot_vert_glsl, NULL,
203                         datatoc_edit_overlay_facedot_frag_glsl,
204                         datatoc_common_globals_lib_glsl, NULL);
205         }
206         if (!e_data.overlay_mix_sh) {
207                 e_data.overlay_mix_sh = DRW_shader_create_fullscreen(datatoc_edit_overlay_mix_frag_glsl, NULL);
208         }
209         if (!e_data.overlay_facefill_sh) {
210                 e_data.overlay_facefill_sh = DRW_shader_create_with_lib(
211                         datatoc_edit_overlay_facefill_vert_glsl, NULL,
212                         datatoc_edit_overlay_facefill_frag_glsl,
213                         datatoc_common_globals_lib_glsl, NULL);
214         }
215         if (!e_data.normals_face_sh) {
216                 e_data.normals_face_sh = DRW_shader_create(
217                         datatoc_edit_normals_vert_glsl,
218                         datatoc_edit_normals_geom_glsl,
219                         datatoc_gpu_shader_uniform_color_frag_glsl,
220                         "#define FACE_NORMALS\n");
221         }
222         if (!e_data.normals_sh) {
223                 e_data.normals_sh = DRW_shader_create(
224                         datatoc_edit_normals_vert_glsl,
225                         datatoc_edit_normals_geom_glsl,
226                         datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
227         }
228         if (!e_data.depth_sh) {
229                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
230         }
231 }
232
233 static DRWPass *edit_mesh_create_overlay_pass(
234         DRWShadingGroup **face_shgrp, DRWShadingGroup **ledges_shgrp,
235         DRWShadingGroup **lverts_shgrp, DRWShadingGroup **facedot_shgrp,
236         float *faceAlpha, DRWState statemod)
237 {
238         static struct GPUShader *tri_sh, *ledge_sh;
239         const struct bContext *C = DRW_get_context();
240         RegionView3D *rv3d = CTX_wm_region_view3d(C);
241         Scene *scene = CTX_data_scene(C);
242         ToolSettings *tsettings = scene->toolsettings;
243
244         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
245                 ledge_sh = e_data.overlay_edge_vcol_sh;
246
247                 if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
248                         tri_sh = e_data.overlay_tri_vcol_fast_sh;
249                 else
250                         tri_sh = e_data.overlay_tri_vcol_sh;
251         }
252         else {
253                 ledge_sh = e_data.overlay_edge_sh;
254
255                 if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
256                         tri_sh = e_data.overlay_tri_fast_sh;
257                 else
258                         tri_sh = e_data.overlay_tri_sh;
259         }
260
261         DRWPass *pass = DRW_pass_create(
262                 "Edit Mesh Face Overlay Pass",
263                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
264
265         *face_shgrp = DRW_shgroup_create(tri_sh, pass);
266         DRW_shgroup_uniform_block(*face_shgrp, "globalsBlock", globals_ubo, 0);
267         DRW_shgroup_uniform_vec2(*face_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
268         DRW_shgroup_uniform_float(*face_shgrp, "faceAlphaMod", faceAlpha, 1);
269
270         *ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
271         DRW_shgroup_uniform_vec2(*ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
272
273         if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
274                 *lverts_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, pass);
275                 DRW_shgroup_uniform_vec2(*lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
276         }
277
278         if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
279                 *facedot_shgrp = DRW_shgroup_create(e_data.overlay_facedot_sh, pass);
280         }
281
282         return pass;
283 }
284
285 static float backwire_opacity;
286 static float face_mod;
287 static float size_normal;
288
289 static void EDIT_MESH_cache_init(void *vedata)
290 {
291         EDIT_MESH_TextureList *txl = ((EDIT_MESH_Data *)vedata)->txl;
292         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
293         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
294         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
295
296         const struct bContext *C = DRW_get_context();
297         View3D *v3d = CTX_wm_view3d(C);
298
299         bool do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0);
300
301         static float zero = 0.0f;
302
303         if (!stl->g_data) {
304                 /* Alloc transient pointers */
305                 stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
306         }
307
308         {
309                 /* Complementary Depth Pass */
310                 psl->depth_hidden_wire = DRW_pass_create(
311                         "Depth Pass Hidden Wire",
312                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
313                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
314         }
315
316         {
317                 /* Normals */
318                 psl->normals = DRW_pass_create(
319                         "Edit Mesh Normals Pass",
320                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
321
322                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
323                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
324                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
325
326                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
327                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
328                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
329
330                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
331                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
332                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
333         }
334
335         if (!do_zbufclip) {
336                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
337                         &stl->g_data->face_overlay_shgrp, &stl->g_data->ledges_overlay_shgrp,
338                         &stl->g_data->lverts_overlay_shgrp, &stl->g_data->facedot_overlay_shgrp, &face_mod,
339                         DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND);
340         }
341         else {
342                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
343                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
344                         &stl->g_data->face_occluded_shgrp, &stl->g_data->ledges_occluded_shgrp,
345                         &stl->g_data->lverts_occluded_shgrp, &stl->g_data->facedot_occluded_shgrp, &zero,
346                         DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH);
347
348                 /* however we loose the front faces value (because we need the depth of occluded wires and
349                  * faces are alpha blended ) so we recover them in a new pass. */
350                 psl->facefill_occlude = DRW_pass_create(
351                         "Front Face Color",
352                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
353                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
354                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo, 0);
355
356                 /* we need a full screen pass to combine the result */
357                 struct Batch *quad = DRW_cache_fullscreen_quad_get();
358
359                 psl->mix_occlude = DRW_pass_create(
360                         "Mix Occluded Wires",
361                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
362                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
363                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
364                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
365                 DRW_shgroup_uniform_buffer(mix_shgrp, "wireColor", &txl->occlude_wire_color_tx, 0);
366                 DRW_shgroup_uniform_buffer(mix_shgrp, "wireDepth", &txl->occlude_wire_depth_tx, 2);
367                 DRW_shgroup_uniform_buffer(mix_shgrp, "sceneDepth", &dtxl->depth, 3);
368         }
369 }
370
371 static void edit_mesh_add_ob_to_pass(
372         Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp,
373         DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
374 {
375         struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
376         ToolSettings *tsettings = scene->toolsettings;
377
378         DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
379         DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
380         DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
381
382         if (facefill_shgrp) {
383                 DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
384         }
385
386         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
387                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
388         }
389
390         if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
391                 geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
392                 DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
393         }
394 }
395
396 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
397 {
398         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
399         const struct bContext *C = DRW_get_context();
400         View3D *v3d = CTX_wm_view3d(C);
401         Scene *scene = CTX_data_scene(C);
402         Object *obedit = scene->obedit;
403         struct Batch *geom;
404
405         if (ob->type == OB_MESH) {
406                 if (ob == obedit) {
407                         IDProperty *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
408                         bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
409                         /* Updating uniform */
410                         backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity");
411
412                         bool fnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "face_normals_show");
413                         bool vnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "vert_normals_show");
414                         bool lnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "loop_normals_show");
415                         /* Updating uniform */
416                         size_normal = BKE_collection_engine_property_value_get_float(ces_mode_ed, "normals_length");
417
418                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
419
420                         if (do_occlude_wire) {
421                                 geom = DRW_cache_mesh_surface_get(ob);
422                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
423                         }
424
425                         if (fnormals_do) {
426                                 geom = DRW_cache_face_centers_get(ob);
427                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
428                         }
429
430                         if (vnormals_do) {
431                                 geom = DRW_cache_mesh_verts_get(ob);
432                                 DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat);
433                         }
434
435                         if (lnormals_do) {
436                                 geom = DRW_cache_mesh_surface_verts_get(ob);
437                                 DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geom, ob->obmat);
438                         }
439
440                         if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
441                                 edit_mesh_add_ob_to_pass(
442                                         scene, ob, stl->g_data->face_occluded_shgrp, stl->g_data->ledges_occluded_shgrp,
443                                         stl->g_data->lverts_occluded_shgrp, stl->g_data->facedot_occluded_shgrp,
444                                         stl->g_data->facefill_occluded_shgrp);
445                         }
446                         else {
447                                 edit_mesh_add_ob_to_pass(
448                                         scene, ob, stl->g_data->face_overlay_shgrp, stl->g_data->ledges_overlay_shgrp,
449                                         stl->g_data->lverts_overlay_shgrp, stl->g_data->facedot_overlay_shgrp, NULL);
450                         }
451                 }
452         }
453 }
454
455 static void EDIT_MESH_draw_scene(void *vedata)
456 {
457         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
458         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
459         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
460         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
461
462         DRW_draw_pass(psl->depth_hidden_wire);
463
464         if (psl->edit_face_occluded) {
465                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
466                 /* render facefill */
467                 DRW_draw_pass(psl->facefill_occlude);
468                 
469                 /* Render wires on a separate framebuffer */
470                 DRW_framebuffer_bind(fbl->occlude_wire_fb);
471                 DRW_framebuffer_clear(true, true, false, clearcol, 1.0f);
472                 DRW_draw_pass(psl->normals);
473                 DRW_draw_pass(psl->edit_face_occluded);
474
475                 /* detach textures */
476                 DRW_framebuffer_texture_detach(dtxl->depth);
477
478                 /* Combine with scene buffer */
479                 DRW_framebuffer_bind(dfbl->default_fb);
480                 DRW_draw_pass(psl->mix_occlude);
481
482                 /* reattach */
483                 DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0);
484         }
485         else {
486                 DRW_draw_pass(psl->normals);
487                 DRW_draw_pass(psl->edit_face_overlay);
488         }
489 }
490
491 void EDIT_MESH_collection_settings_create(IDProperty *properties)
492 {
493         BLI_assert(properties &&
494                    properties->type == IDP_GROUP &&
495                    properties->subtype == IDP_GROUP_SUB_MODE_EDIT);
496         BKE_collection_engine_property_add_int(properties, "show_occlude_wire", false);
497         BKE_collection_engine_property_add_int(properties, "face_normals_show", false);
498         BKE_collection_engine_property_add_int(properties, "vert_normals_show", false);
499         BKE_collection_engine_property_add_int(properties, "loop_normals_show", false);
500         BKE_collection_engine_property_add_float(properties, "normals_length", 0.1);
501         BKE_collection_engine_property_add_float(properties, "backwire_opacity", 0.5);
502 }
503
504 static void EDIT_MESH_engine_free(void)
505 {
506         if (e_data.overlay_tri_sh)
507                 DRW_shader_free(e_data.overlay_tri_sh);
508         if (e_data.overlay_tri_fast_sh)
509                 DRW_shader_free(e_data.overlay_tri_fast_sh);
510         if (e_data.overlay_tri_vcol_sh)
511                 DRW_shader_free(e_data.overlay_tri_vcol_sh);
512         if (e_data.overlay_tri_vcol_fast_sh)
513                 DRW_shader_free(e_data.overlay_tri_vcol_fast_sh);
514         if (e_data.overlay_edge_sh)
515                 DRW_shader_free(e_data.overlay_edge_sh);
516         if (e_data.overlay_edge_vcol_sh)
517                 DRW_shader_free(e_data.overlay_edge_vcol_sh);
518         if (e_data.overlay_vert_sh)
519                 DRW_shader_free(e_data.overlay_vert_sh);
520         if (e_data.overlay_facedot_sh)
521                 DRW_shader_free(e_data.overlay_facedot_sh);
522         if (e_data.overlay_mix_sh)
523                 DRW_shader_free(e_data.overlay_mix_sh);
524         if (e_data.overlay_facefill_sh)
525                 DRW_shader_free(e_data.overlay_facefill_sh);
526         if (e_data.normals_face_sh)
527                 DRW_shader_free(e_data.normals_face_sh);
528         if (e_data.normals_sh)
529                 DRW_shader_free(e_data.normals_sh);
530 }
531
532 DrawEngineType draw_engine_edit_mesh_type = {
533         NULL, NULL,
534         N_("EditMeshMode"),
535         &EDIT_MESH_engine_init,
536         &EDIT_MESH_engine_free,
537         &EDIT_MESH_cache_init,
538         &EDIT_MESH_cache_populate,
539         NULL,
540         NULL,
541         &EDIT_MESH_draw_scene
542 };