DRW: Remove the use of GPUTexture buffers for edit wire rendering
[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         else {
389                 /* To be able to use triple load. */
390                 DRW_shgroup_state_enable(*r_face_shgrp, DRW_STATE_FIRST_VERTEX_CONVENTION);
391         }
392
393         *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
394         DRW_shgroup_uniform_block(*r_ledges_shgrp, "globalsBlock", globals_ubo);
395         DRW_shgroup_uniform_vec2(*r_ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
396         DRW_shgroup_uniform_float(*r_ledges_shgrp, "edgeScale", edge_width_scale, 1);
397         DRW_shgroup_uniform_ivec4(*r_ledges_shgrp, "dataMask", data_mask, 1);
398         DRW_shgroup_uniform_bool_copy(*r_ledges_shgrp, "doEdges", do_edges);
399
400         return pass;
401 }
402
403 static float backwire_opacity;
404 static float face_mod;
405 static float size_normal;
406
407 static void EDIT_MESH_cache_init(void *vedata)
408 {
409         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
410         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
411         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
412
413         const DRWContextState *draw_ctx = DRW_context_state_get();
414         View3D *v3d = draw_ctx->v3d;
415         Scene *scene = draw_ctx->scene;
416         ToolSettings *tsettings = scene->toolsettings;
417
418         static float zero = 0.0f;
419
420         if (!stl->g_data) {
421                 /* Alloc transient pointers */
422                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
423         }
424         stl->g_data->ghost_ob = 0;
425         stl->g_data->edit_ob = 0;
426         stl->g_data->do_faces = true;
427         stl->g_data->do_edges = true;
428
429         stl->g_data->do_zbufclip = ((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0;
430
431         /* Applies on top of the theme edge width, so edge-mode can have thick edges. */
432         stl->g_data->edge_width_scale = (tsettings->selectmode & (SCE_SELECT_EDGE)) ? 1.75f : 1.0f;
433
434         stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
435         stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
436         stl->g_data->data_mask[2] = 0xFF; /* Crease */
437         stl->g_data->data_mask[3] = 0xFF; /* BWeight */
438
439         if (draw_ctx->object_edit->type == OB_MESH) {
440                 if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
441                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE) == 0) {
442                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
443                         }
444                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACES) == 0) {
445                                 stl->g_data->data_mask[0] &= ~(VFLAG_FACE_SELECTED & VFLAG_FACE_FREESTYLE);
446                                 stl->g_data->do_faces = false;
447                         }
448                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
449                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
450                         }
451                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SHARP) == 0) {
452                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
453                         }
454                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE) == 0) {
455                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
456                         }
457                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
458                                 if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
459                                         stl->g_data->data_mask[1] &= ~(VFLAG_EDGE_ACTIVE & VFLAG_EDGE_SELECTED);
460                                         stl->g_data->do_edges = false;
461                                 }
462                         }
463                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CREASES) == 0) {
464                                 stl->g_data->data_mask[2] = 0x0;
465                         }
466                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_BWEIGHTS) == 0) {
467                                 stl->g_data->data_mask[3] = 0x0;
468                         }
469                 }
470         }
471
472         {
473                 psl->weight_faces = DRW_pass_create(
474                         "Weight Pass",
475                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
476
477                 stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
478
479                 static float alpha = 1.0f;
480                 DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &alpha, 1);
481                 DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", globals_weight_ramp);
482                 DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", globals_ubo);
483         }
484
485         {
486                 /* Complementary Depth Pass */
487                 psl->depth_hidden_wire = DRW_pass_create(
488                         "Depth Pass Hidden Wire",
489                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
490                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(e_data.depth_sh, psl->depth_hidden_wire);
491         }
492
493         {
494                 /* Depth clearing for ghosting. */
495                 psl->ghost_clear_depth = DRW_pass_create(
496                         "Ghost Depth Clear",
497                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
498
499                 DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.ghost_clear_depth_sh, psl->ghost_clear_depth);
500                 DRW_shgroup_stencil_mask(shgrp, 0x00);
501                 DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
502         }
503
504         {
505                 /* Normals */
506                 psl->normals = DRW_pass_create(
507                         "Edit Mesh Normals Pass",
508                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
509
510                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(e_data.normals_face_sh, psl->normals);
511                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
512                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", ts.colorNormal, 1);
513
514                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(e_data.normals_sh, psl->normals);
515                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
516                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", ts.colorVNormal, 1);
517
518                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(e_data.normals_loop_sh, psl->normals);
519                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
520                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", ts.colorLNormal, 1);
521         }
522
523         if (!stl->g_data->do_zbufclip) {
524                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
525                         &face_mod, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, false,
526                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
527                         &stl->g_data->face_overlay_shgrp,
528                         &stl->g_data->verts_overlay_shgrp,
529                         &stl->g_data->ledges_overlay_shgrp,
530                         &stl->g_data->lverts_overlay_shgrp,
531                         &stl->g_data->facedot_overlay_shgrp);
532         }
533         else {
534                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
535                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
536                         &zero, &stl->g_data->edge_width_scale, stl->g_data->data_mask, stl->g_data->do_edges, true,
537                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
538                         &stl->g_data->face_occluded_shgrp,
539                         &stl->g_data->verts_occluded_shgrp,
540                         &stl->g_data->ledges_occluded_shgrp,
541                         &stl->g_data->lverts_occluded_shgrp,
542                         &stl->g_data->facedot_occluded_shgrp);
543
544                 /* however we loose the front faces value (because we need the depth of occluded wires and
545                  * faces are alpha blended ) so we recover them in a new pass. */
546                 psl->facefill_occlude = DRW_pass_create(
547                         "Front Face Color",
548                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
549                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(e_data.overlay_facefill_sh, psl->facefill_occlude);
550                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo);
551                 DRW_shgroup_uniform_ivec4(stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
552
553                 /* we need a full screen pass to combine the result */
554                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
555
556                 psl->mix_occlude = DRW_pass_create(
557                         "Mix Occluded Wires",
558                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
559                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.overlay_mix_sh, psl->mix_occlude);
560                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
561                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
562                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
563                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
564                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
565         }
566 }
567
568 static void edit_mesh_add_ob_to_pass(
569         Scene *scene, Object *ob,
570         DRWShadingGroup *face_shgrp,
571         DRWShadingGroup *verts_shgrp,
572         DRWShadingGroup *ledges_shgrp,
573         DRWShadingGroup *lverts_shgrp,
574         DRWShadingGroup *facedot_shgrp,
575         DRWShadingGroup *facefill_shgrp)
576 {
577         struct GPUBatch *geo_ovl_tris, *geo_ovl_verts, *geo_ovl_lnor, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
578         ToolSettings *tsettings = scene->toolsettings;
579
580         DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
581
582         DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
583
584         DRW_shgroup_call_add(ledges_shgrp, geo_ovl_ledges, ob->obmat);
585
586         if (facefill_shgrp) {
587                 DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
588         }
589
590         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
591                 /* Thoses are point batches. */
592                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_verts, &geo_ovl_lnor, &geo_ovl_ledges, &geo_ovl_lverts);
593                 DRW_shgroup_call_add(verts_shgrp, geo_ovl_verts, ob->obmat);
594                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_ledges, ob->obmat);
595                 DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
596         }
597
598         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) {
599                 geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
600                 DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
601         }
602 }
603
604 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
605 {
606         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
607         const DRWContextState *draw_ctx = DRW_context_state_get();
608         View3D *v3d = draw_ctx->v3d;
609         Scene *scene = draw_ctx->scene;
610         ToolSettings *tsettings = scene->toolsettings;
611         struct GPUBatch *geom;
612
613         if (ob->type == OB_MESH) {
614                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
615                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
616                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
617                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
618                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
619                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
620
621                         bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0;
622
623                         if (stl->g_data->do_faces == false &&
624                             stl->g_data->do_edges == false &&
625                             (tsettings->selectmode & SCE_SELECT_FACE))
626                         {
627                                 /* Force display of face centers in this case because that's
628                                  * the only way to see if a face is selected. */
629                                 show_face_dots = true;
630                         }
631
632                         /* Updating uniform */
633                         backwire_opacity = v3d->overlay.backwire_opacity;
634                         size_normal = v3d->overlay.normals_length;
635
636                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
637
638                         if (!stl->g_data->do_faces) {
639                                 face_mod = 0.0f;
640                         }
641
642                         if (do_show_weight) {
643                                 geom = DRW_cache_mesh_surface_weights_get(ob, tsettings, false);
644                                 DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
645                         }
646
647                         if (do_occlude_wire) {
648                                 geom = DRW_cache_mesh_surface_get(ob, false);
649                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
650                         }
651
652                         if (fnormals_do) {
653                                 geom = DRW_cache_face_centers_get(ob);
654                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
655                         }
656
657                         if (vnormals_do || lnormals_do) {
658                                 struct GPUBatch *geo_ovl_tris, *geo_ovl_lnor, *geo_ovl_ledges, *geo_ovl_lverts;
659                                 DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_lnor, &geo_ovl_ledges, &geo_ovl_lverts);
660
661                                 if (vnormals_do) {
662                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_tris, ob->obmat);
663                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_ledges, ob->obmat);
664                                         DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geo_ovl_lverts, ob->obmat);
665                                 }
666
667                                 if (lnormals_do) {
668                                         DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geo_ovl_lnor, ob->obmat);
669                                 }
670                         }
671
672                         if (stl->g_data->do_zbufclip) {
673                                 edit_mesh_add_ob_to_pass(
674                                         scene, ob,
675                                         stl->g_data->face_occluded_shgrp,
676                                         stl->g_data->verts_occluded_shgrp,
677                                         stl->g_data->ledges_occluded_shgrp,
678                                         stl->g_data->lverts_occluded_shgrp,
679                                         stl->g_data->facedot_occluded_shgrp,
680                                         (stl->g_data->do_faces) ? stl->g_data->facefill_occluded_shgrp : NULL);
681                         }
682                         else {
683                                 edit_mesh_add_ob_to_pass(
684                                         scene, ob,
685                                         stl->g_data->face_overlay_shgrp,
686                                         stl->g_data->verts_overlay_shgrp,
687                                         stl->g_data->ledges_overlay_shgrp,
688                                         stl->g_data->lverts_overlay_shgrp,
689                                         (show_face_dots) ? stl->g_data->facedot_overlay_shgrp : NULL,
690                                         NULL);
691                         }
692
693                         stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
694                         stl->g_data->edit_ob += 1;
695
696                         /* 3D text overlay */
697                         if (v3d->overlay.edit_flag & (V3D_OVERLAY_EDIT_EDGE_LEN |
698                                                       V3D_OVERLAY_EDIT_FACE_AREA |
699                                                       V3D_OVERLAY_EDIT_FACE_ANG |
700                                                       V3D_OVERLAY_EDIT_EDGE_ANG |
701                                                       V3D_OVERLAY_EDIT_INDICES))
702                         {
703                                 if (DRW_state_show_text()) {
704                                         DRW_edit_mesh_mode_text_measure_stats(
705                                                draw_ctx->ar, v3d, ob, &scene->unit);
706                                 }
707                         }
708                 }
709         }
710 }
711
712 static void EDIT_MESH_draw_scene(void *vedata)
713 {
714         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
715         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
716         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
717         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
718         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
719
720         DRW_draw_pass(psl->weight_faces);
721
722         DRW_draw_pass(psl->depth_hidden_wire);
723
724         if (stl->g_data->do_zbufclip) {
725                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
726                 /* render facefill */
727                 DRW_draw_pass(psl->facefill_occlude);
728
729                 /* Render wires on a separate framebuffer */
730                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
731                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
732                 DRW_draw_pass(psl->normals);
733                 DRW_draw_pass(psl->edit_face_occluded);
734
735                 /* Combine with scene buffer */
736                 GPU_framebuffer_bind(dfbl->color_only_fb);
737                 DRW_draw_pass(psl->mix_occlude);
738         }
739         else {
740                 DRW_draw_pass(psl->normals);
741
742                 const DRWContextState *draw_ctx = DRW_context_state_get();
743                 View3D *v3d = draw_ctx->v3d;
744
745                 if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0) {
746                         if (stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1) {
747                                 /* In the case of single ghost object edit (common case for retopology):
748                                  * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
749                                  * the stencil buffer is no 0x00. */
750                                 const float *viewport_size = DRW_viewport_size_get();
751                                 const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
752                                 struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
753                                 GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
754                                         GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
755                                         GPU_ATTACHMENT_TEXTURE(dtxl->color),
756                                 });
757
758                                 GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
759                                 GPU_framebuffer_bind(fbl->ghost_wire_fb);
760
761                                 DRW_draw_pass(psl->ghost_clear_depth);
762                         }
763                 }
764
765                 DRW_draw_pass(psl->edit_face_overlay);
766         }
767 }
768
769 static void EDIT_MESH_engine_free(void)
770 {
771         DRW_SHADER_FREE_SAFE(e_data.weight_face_shader);
772
773         DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
774         DRW_SHADER_FREE_SAFE(e_data.overlay_lvert_sh);
775         DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh);
776         DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh);
777         DRW_SHADER_FREE_SAFE(e_data.overlay_facefill_sh);
778         DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh);
779         DRW_SHADER_FREE_SAFE(e_data.normals_face_sh);
780         DRW_SHADER_FREE_SAFE(e_data.normals_sh);
781         DRW_SHADER_FREE_SAFE(e_data.ghost_clear_depth_sh);
782
783         for (int i = 0; i < MAX_SHADERS; i++) {
784                 DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh_cache[i]);
785                 DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh_cache[i]);
786         }
787 }
788
789 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
790
791 DrawEngineType draw_engine_edit_mesh_type = {
792         NULL, NULL,
793         N_("EditMeshMode"),
794         &EDIT_MESH_data_size,
795         &EDIT_MESH_engine_init,
796         &EDIT_MESH_engine_free,
797         &EDIT_MESH_cache_init,
798         &EDIT_MESH_cache_populate,
799         NULL,
800         NULL,
801         &EDIT_MESH_draw_scene,
802         NULL,
803         NULL,
804 };