Merge branch 'blender2.7'
[blender.git] / source / blender / draw / modes / edit_mesh_mode.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file \ingroup draw
20  */
21
22 #include "DRW_engine.h"
23 #include "DRW_render.h"
24
25 #include "GPU_extensions.h"
26
27 #include "DNA_mesh_types.h"
28 #include "DNA_view3d_types.h"
29
30 #include "draw_common.h"
31
32 #include "draw_cache_impl.h"
33 #include "draw_mode_engines.h"
34
35 #include "edit_mesh_mode_intern.h" /* own include */
36
37 #include "BKE_editmesh.h"
38 #include "BKE_object.h"
39
40 #include "BIF_glutil.h"
41
42 #include "BLI_dynstr.h"
43 #include "BLI_string_utils.h"
44
45 extern char datatoc_paint_weight_vert_glsl[];
46 extern char datatoc_paint_weight_frag_glsl[];
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_glsl[];
52 extern char datatoc_edit_mesh_overlay_mix_frag_glsl[];
53 extern char datatoc_edit_mesh_overlay_facefill_vert_glsl[];
54 extern char datatoc_edit_mesh_overlay_facefill_frag_glsl[];
55 extern char datatoc_edit_normals_vert_glsl[];
56 extern char datatoc_edit_normals_geom_glsl[];
57 extern char datatoc_common_globals_lib_glsl[];
58
59 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
60 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
61 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
62 extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
63 extern char datatoc_gpu_shader_depth_only_frag_glsl[];
64
65 /* *********** LISTS *********** */
66 typedef struct EDIT_MESH_PassList {
67         struct DRWPass *weight_faces;
68         struct DRWPass *depth_hidden_wire;
69         struct DRWPass *ghost_clear_depth;
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         struct GPUFrameBuffer *ghost_wire_fb;
80 } EDIT_MESH_FramebufferList;
81
82 typedef struct EDIT_MESH_StorageList {
83         struct EDIT_MESH_PrivateData *g_data;
84 } EDIT_MESH_StorageList;
85
86 typedef struct EDIT_MESH_Data {
87         void *engine_type;
88         EDIT_MESH_FramebufferList *fbl;
89         DRWViewportEmptyList *txl;
90         EDIT_MESH_PassList *psl;
91         EDIT_MESH_StorageList *stl;
92 } EDIT_MESH_Data;
93
94 #define MAX_SHADERS 16
95
96 /** Can only contain shaders (freed as array). */
97 typedef struct EDIT_MESH_Shaders {
98         /* weight */
99         GPUShader *weight_face;
100
101         /* Geometry */
102         GPUShader *overlay_vert;
103         GPUShader *overlay_edge;
104         GPUShader *overlay_edge_flat;
105         GPUShader *overlay_face;
106         GPUShader *overlay_facedot;
107
108         GPUShader *overlay_mix;
109         GPUShader *overlay_facefill;
110         GPUShader *normals_face;
111         GPUShader *normals_loop;
112         GPUShader *normals;
113         GPUShader *depth;
114         GPUShader *ghost_clear_depth;
115 } EDIT_MESH_Shaders;
116
117 /* *********** STATIC *********** */
118 static struct {
119         EDIT_MESH_Shaders sh_data[GPU_SHADER_CFG_LEN];
120
121         /* temp buffer texture */
122         struct GPUTexture *occlude_wire_depth_tx;
123         struct GPUTexture *occlude_wire_color_tx;
124 } e_data = {NULL}; /* Engine data */
125
126 typedef struct EDIT_MESH_PrivateData {
127         /* weight */
128         DRWShadingGroup *fweights_shgrp;
129         DRWShadingGroup *depth_shgrp_hidden_wire;
130
131         DRWShadingGroup *fnormals_shgrp;
132         DRWShadingGroup *vnormals_shgrp;
133         DRWShadingGroup *lnormals_shgrp;
134
135         DRWShadingGroup *vert_shgrp;
136         DRWShadingGroup *edge_shgrp;
137         DRWShadingGroup *face_shgrp;
138         DRWShadingGroup *face_cage_shgrp;
139         DRWShadingGroup *facedot_shgrp;
140
141         DRWShadingGroup *facefill_occluded_shgrp;
142
143         int data_mask[4];
144         int ghost_ob;
145         int edit_ob;
146         bool do_zbufclip;
147         bool do_faces;
148         bool do_edges;
149 } EDIT_MESH_PrivateData; /* Transient data */
150
151 /* *********** FUNCTIONS *********** */
152
153
154 static void EDIT_MESH_engine_init(void *vedata)
155 {
156         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
157
158         const DRWContextState *draw_ctx = DRW_context_state_get();
159         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
160
161         const float *viewport_size = DRW_viewport_size_get();
162         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
163
164         e_data.occlude_wire_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
165                                                                  &draw_engine_edit_mesh_type);
166         e_data.occlude_wire_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
167                                                                  &draw_engine_edit_mesh_type);
168
169         GPU_framebuffer_ensure_config(&fbl->occlude_wire_fb, {
170                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_depth_tx),
171                 GPU_ATTACHMENT_TEXTURE(e_data.occlude_wire_color_tx)
172         });
173
174         if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
175                 DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
176         }
177
178         const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
179
180         if (!sh_data->weight_face) {
181                 sh_data->weight_face = GPU_shader_create_from_arrays({
182                         .vert = (const char *[]){sh_cfg_data->lib, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
183                         .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
184                         .defs = (const char *[]){sh_cfg_data->def, NULL},
185                 });
186
187                 char *lib = BLI_string_joinN(sh_cfg_data->lib, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl);
188                 /* Use geometry shader to draw edge wireframe. This ensure us
189                  * the same result accross platforms and more flexibility. But
190                  * we pay the cost of running a geometry shader.
191                  * In the future we might consider using only the vertex shader
192                  * and loading data manually with buffer textures. */
193                 const bool use_geom_shader = true;
194                 const char *geom_sh_code[] = {lib, datatoc_edit_mesh_overlay_geom_glsl, NULL};
195                 if (!use_geom_shader) {
196                         geom_sh_code[0] = NULL;
197                 }
198                 const char *use_geom_def = use_geom_shader ? "#define USE_GEOM_SHADER\n" : "";
199                 sh_data->overlay_face = GPU_shader_create_from_arrays({
200                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
201                         .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL},
202                         .defs = (const char *[]){sh_cfg_data->def, "#define FACE\n", NULL},
203                 });
204                 sh_data->overlay_edge = GPU_shader_create_from_arrays({
205                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
206                         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
207                         .defs = (const char *[]){sh_cfg_data->def, use_geom_def, "#define EDGE\n", NULL},
208                         .geom = (use_geom_shader) ? geom_sh_code : NULL,
209                 });
210                 sh_data->overlay_edge_flat = GPU_shader_create_from_arrays({
211                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
212                         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL},
213                         .defs = (const char *[]){sh_cfg_data->def, use_geom_def, "#define EDGE\n", "#define FLAT\n", NULL},
214                         .geom = (use_geom_shader) ? geom_sh_code : NULL,
215                 });
216                 sh_data->overlay_vert = GPU_shader_create_from_arrays({
217                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
218                         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
219                         .defs = (const char *[]){sh_cfg_data->def, "#define VERT\n", NULL},
220                 });
221                 sh_data->overlay_facedot = GPU_shader_create_from_arrays({
222                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL},
223                         .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL},
224                         .defs = (const char *[]){sh_cfg_data->def, "#define FACEDOT\n", NULL},
225                 });
226                 sh_data->overlay_facefill = GPU_shader_create_from_arrays({
227                         .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL},
228                         .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL},
229                         .defs = (const char *[]){sh_cfg_data->def, NULL},
230                 });
231                 MEM_freeN(lib);
232
233                 sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL);
234
235                 sh_data->normals_face = GPU_shader_create_from_arrays({
236                         .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
237                         .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
238                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
239                         .defs = (const char *[]){sh_cfg_data->def, "#define FACE_NORMALS\n", NULL},
240                 });
241
242                 sh_data->normals_loop = GPU_shader_create_from_arrays({
243                         .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
244                         .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
245                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
246                         .defs = (const char *[]){sh_cfg_data->def, "#define LOOP_NORMALS\n", NULL},
247                 });
248
249                 sh_data->normals = GPU_shader_create_from_arrays({
250                         .vert = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_vert_glsl, NULL},
251                         .geom = (const char *[]){sh_cfg_data->lib, datatoc_edit_normals_geom_glsl, NULL},
252                         .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
253                         .defs = (const char *[]){sh_cfg_data->def, NULL},
254                 });
255
256                 sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->sh_cfg);
257
258                 sh_data->ghost_clear_depth = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL);
259         }
260 }
261
262 static DRWPass *edit_mesh_create_overlay_pass(
263         float *face_alpha, int *data_mask, bool do_edges, bool UNUSED(xray),
264         DRWState statemod,
265         DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, DRWShadingGroup **r_facedot_shgrp,
266         DRWShadingGroup **r_edge_shgrp, DRWShadingGroup **r_vert_shgrp)
267 {
268         const DRWContextState *draw_ctx = DRW_context_state_get();
269         RegionView3D *rv3d = draw_ctx->rv3d;
270         Scene *scene = draw_ctx->scene;
271         ToolSettings *tsettings = scene->toolsettings;
272         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
273         const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
274         const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
275         const bool select_edge = (tsettings->selectmode & SCE_SELECT_EDGE) != 0;
276         float winmat[4][4];
277         float viewdist = rv3d->dist;
278         DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
279         /* special exception for ortho camera (viewdist isnt used for perspective cameras) */
280         if (rv3d->persp == RV3D_CAMOB && rv3d->is_persp == false) {
281                 viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1]));
282         }
283         const float depth_ofs = bglPolygonOffsetCalc((float *)winmat, viewdist, 1.0f);
284
285         DRWPass *pass = DRW_pass_create(
286                 "Edit Mesh Face Overlay Pass",
287                 DRW_STATE_WRITE_COLOR | DRW_STATE_POINT | statemod);
288
289         DRWShadingGroup *grp;
290
291         GPUShader *vert_sh = sh_data->overlay_vert;
292         GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat;
293         GPUShader *face_sh = sh_data->overlay_face;
294         GPUShader *facedot_sh = sh_data->overlay_facedot;
295
296         /* Faces */
297         if (select_face) {
298                 grp = *r_facedot_shgrp = DRW_shgroup_create(facedot_sh, pass);
299                 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
300                 DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
301                 if (rv3d->rflag & RV3D_CLIPPING) {
302                         DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
303                 }
304         }
305
306         grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass);
307         DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
308         DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1);
309         DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
310         DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
311         DRW_shgroup_uniform_float_copy(grp, "ofs", 0.0f);
312         if (rv3d->rflag & RV3D_CLIPPING) {
313                 DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
314         }
315
316         /* Cage geom needs to be offseted to avoid Z-fighting. */
317         grp = *r_face_cage_shgrp = DRW_shgroup_create_sub(*r_face_shgrp);
318         DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
319
320         /* Edges */
321         grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass);
322         DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
323         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
324         DRW_shgroup_uniform_vec2(grp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
325         DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1);
326         DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges);
327         DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs);
328         DRW_shgroup_uniform_float_copy(grp, "edgeScale", select_edge ? 1.75f : 1.0f);
329         DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE);
330         /* To match blender loop structure. */
331         DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION);
332         if (rv3d->rflag & RV3D_CLIPPING) {
333                 DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
334         }
335
336         /* Verts */
337         if (select_vert) {
338                 grp = *r_vert_shgrp = DRW_shgroup_create(vert_sh, pass);
339                 DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
340                 DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
341                 DRW_shgroup_uniform_float_copy(grp, "ofs", depth_ofs * 1.5f);
342                 DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE | DRW_STATE_WRITE_DEPTH);
343                 DRW_shgroup_state_disable(grp, DRW_STATE_BLEND);
344                 if (rv3d->rflag & RV3D_CLIPPING) {
345                         DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d);
346                 }
347         }
348
349         return pass;
350 }
351
352 static float backwire_opacity;
353 static float face_mod;
354 static float size_normal;
355
356 static void EDIT_MESH_cache_init(void *vedata)
357 {
358         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
359         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
360         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
361
362         const DRWContextState *draw_ctx = DRW_context_state_get();
363         View3D *v3d = draw_ctx->v3d;
364         RegionView3D *rv3d = draw_ctx->rv3d;
365         Scene *scene = draw_ctx->scene;
366         ToolSettings *tsettings = scene->toolsettings;
367         EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
368         static float zero = 0.0f;
369
370         if (!stl->g_data) {
371                 /* Alloc transient pointers */
372                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
373         }
374         stl->g_data->ghost_ob = 0;
375         stl->g_data->edit_ob = 0;
376         stl->g_data->do_faces = true;
377         stl->g_data->do_edges = true;
378
379         stl->g_data->do_zbufclip = ((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0;
380
381         stl->g_data->data_mask[0] = 0xFF; /* Face Flag */
382         stl->g_data->data_mask[1] = 0xFF; /* Edge Flag */
383         stl->g_data->data_mask[2] = 0xFF; /* Crease */
384         stl->g_data->data_mask[3] = 0xFF; /* BWeight */
385
386         if (draw_ctx->object_edit->type == OB_MESH) {
387                 if (BKE_object_is_in_editmode(draw_ctx->object_edit)) {
388                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE) == 0) {
389                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_FREESTYLE;
390                         }
391                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACES) == 0) {
392                                 stl->g_data->data_mask[0] &= ~(VFLAG_FACE_SELECTED & VFLAG_FACE_FREESTYLE);
393                                 stl->g_data->do_faces = false;
394                         }
395                         if ((tsettings->selectmode & SCE_SELECT_FACE) == 0) {
396                                 stl->g_data->data_mask[0] &= ~VFLAG_FACE_ACTIVE;
397                         }
398                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SEAMS) == 0) {
399                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SEAM;
400                         }
401                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_SHARP) == 0) {
402                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_SHARP;
403                         }
404                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE) == 0) {
405                                 stl->g_data->data_mask[1] &= ~VFLAG_EDGE_FREESTYLE;
406                         }
407                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
408                                 if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
409                                         stl->g_data->data_mask[1] &= ~(VFLAG_EDGE_ACTIVE & VFLAG_EDGE_SELECTED);
410                                         stl->g_data->do_edges = false;
411                                 }
412                         }
413                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CREASES) == 0) {
414                                 stl->g_data->data_mask[2] = 0x0;
415                         }
416                         if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_BWEIGHTS) == 0) {
417                                 stl->g_data->data_mask[3] = 0x0;
418                         }
419                 }
420         }
421
422         {
423                 psl->weight_faces = DRW_pass_create(
424                         "Weight Pass",
425                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
426
427                 stl->g_data->fweights_shgrp = DRW_shgroup_create(sh_data->weight_face, psl->weight_faces);
428
429                 static float alpha = 1.0f;
430                 DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &alpha, 1);
431                 DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", G_draw.weight_ramp);
432                 DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", G_draw.block_ubo);
433                 if (rv3d->rflag & RV3D_CLIPPING) {
434                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
435                 }
436         }
437
438         {
439                 /* Complementary Depth Pass */
440                 psl->depth_hidden_wire = DRW_pass_create(
441                         "Depth Pass Hidden Wire",
442                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK);
443                 stl->g_data->depth_shgrp_hidden_wire = DRW_shgroup_create(sh_data->depth, psl->depth_hidden_wire);
444                 if (rv3d->rflag & RV3D_CLIPPING) {
445                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
446                 }
447         }
448
449         {
450                 /* Depth clearing for ghosting. */
451                 psl->ghost_clear_depth = DRW_pass_create(
452                         "Ghost Depth Clear",
453                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_STENCIL_NEQUAL);
454
455                 DRWShadingGroup *shgrp = DRW_shgroup_create(sh_data->ghost_clear_depth, psl->ghost_clear_depth);
456                 DRW_shgroup_stencil_mask(shgrp, 0x00);
457                 DRW_shgroup_call_add(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
458         }
459
460         {
461                 /* Normals */
462                 psl->normals = DRW_pass_create(
463                         "Edit Mesh Normals Pass",
464                         DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL);
465
466                 stl->g_data->fnormals_shgrp = DRW_shgroup_create(sh_data->normals_face, psl->normals);
467                 DRW_shgroup_uniform_float(stl->g_data->fnormals_shgrp, "normalSize", &size_normal, 1);
468                 DRW_shgroup_uniform_vec4(stl->g_data->fnormals_shgrp, "color", G_draw.block.colorNormal, 1);
469                 if (rv3d->rflag & RV3D_CLIPPING) {
470                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fnormals_shgrp, rv3d);
471                 }
472
473                 stl->g_data->vnormals_shgrp = DRW_shgroup_create(sh_data->normals, psl->normals);
474                 DRW_shgroup_uniform_float(stl->g_data->vnormals_shgrp, "normalSize", &size_normal, 1);
475                 DRW_shgroup_uniform_vec4(stl->g_data->vnormals_shgrp, "color", G_draw.block.colorVNormal, 1);
476                 if (rv3d->rflag & RV3D_CLIPPING) {
477                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vnormals_shgrp, rv3d);
478                 }
479
480                 stl->g_data->lnormals_shgrp = DRW_shgroup_create(sh_data->normals_loop, psl->normals);
481                 DRW_shgroup_uniform_float(stl->g_data->lnormals_shgrp, "normalSize", &size_normal, 1);
482                 DRW_shgroup_uniform_vec4(stl->g_data->lnormals_shgrp, "color", G_draw.block.colorLNormal, 1);
483                 if (rv3d->rflag & RV3D_CLIPPING) {
484                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lnormals_shgrp, rv3d);
485                 }
486         }
487
488         if (!stl->g_data->do_zbufclip) {
489                 psl->edit_face_overlay = edit_mesh_create_overlay_pass(
490                         &face_mod, stl->g_data->data_mask, stl->g_data->do_edges, false,
491                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND,
492                         &stl->g_data->face_shgrp,
493                         &stl->g_data->face_cage_shgrp,
494                         &stl->g_data->facedot_shgrp,
495                         &stl->g_data->edge_shgrp,
496                         &stl->g_data->vert_shgrp);
497         }
498         else {
499                 /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
500                 psl->edit_face_occluded = edit_mesh_create_overlay_pass(
501                         &zero, stl->g_data->data_mask, stl->g_data->do_edges, true,
502                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH,
503                         &stl->g_data->face_shgrp,
504                         &stl->g_data->face_cage_shgrp,
505                         &stl->g_data->facedot_shgrp,
506                         &stl->g_data->edge_shgrp,
507                         &stl->g_data->vert_shgrp);
508
509                 /* however we loose the front faces value (because we need the depth of occluded wires and
510                  * faces are alpha blended ) so we recover them in a new pass. */
511                 psl->facefill_occlude = DRW_pass_create(
512                         "Front Face Color",
513                         DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
514                 stl->g_data->facefill_occluded_shgrp = DRW_shgroup_create(sh_data->overlay_facefill, psl->facefill_occlude);
515                 DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", G_draw.block_ubo);
516                 DRW_shgroup_uniform_ivec4(stl->g_data->facefill_occluded_shgrp, "dataMask", stl->g_data->data_mask, 1);
517                 if (rv3d->rflag & RV3D_CLIPPING) {
518                         DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->facefill_occluded_shgrp, rv3d);
519                 }
520
521                 /* we need a full screen pass to combine the result */
522                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
523
524                 psl->mix_occlude = DRW_pass_create(
525                         "Mix Occluded Wires",
526                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
527                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(sh_data->overlay_mix, psl->mix_occlude);
528                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
529                 DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
530                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireColor", &e_data.occlude_wire_color_tx);
531                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "wireDepth", &e_data.occlude_wire_depth_tx);
532                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "sceneDepth", &dtxl->depth);
533         }
534 }
535
536 static void edit_mesh_add_ob_to_pass(
537         Scene *scene, Object *ob,
538         EDIT_MESH_PrivateData *g_data,
539         DRWShadingGroup *facedot_shgrp,
540         DRWShadingGroup *facefill_shgrp)
541 {
542         struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter;
543         ToolSettings *tsettings = scene->toolsettings;
544
545         bool has_edit_mesh_cage = false;
546         /* TODO: Should be its own function. */
547         Mesh *me = (Mesh *)ob->data;
548         BMEditMesh *embm = me->edit_mesh;
549         if (embm) {
550                 has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
551         }
552
553         DRWShadingGroup *face_shgrp = (has_edit_mesh_cage) ? g_data->face_cage_shgrp : g_data->face_shgrp;
554         DRWShadingGroup *vert_shgrp = g_data->vert_shgrp;
555         DRWShadingGroup *edge_shgrp = g_data->edge_shgrp;
556
557         face_shgrp = (facefill_shgrp != NULL) ? facefill_shgrp : face_shgrp;
558
559         geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
560         geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
561         DRW_shgroup_call_add(edge_shgrp, geom_edges, ob->obmat);
562         DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat);
563
564         if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
565                 geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
566                 DRW_shgroup_call_add(vert_shgrp, geom_verts, ob->obmat);
567         }
568
569         if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) {
570                 geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
571                 DRW_shgroup_call_add(facedot_shgrp, geom_fcenter, ob->obmat);
572         }
573 }
574
575 static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
576 {
577         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
578         const DRWContextState *draw_ctx = DRW_context_state_get();
579         View3D *v3d = draw_ctx->v3d;
580         Scene *scene = draw_ctx->scene;
581         ToolSettings *tsettings = scene->toolsettings;
582         struct GPUBatch *geom;
583
584         if (ob->type == OB_MESH) {
585                 if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) {
586                         bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
587                         bool do_show_weight = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
588                         bool fnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
589                         bool vnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
590                         bool lnormals_do = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
591
592                         bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0;
593
594                         if (stl->g_data->do_faces == false &&
595                             stl->g_data->do_edges == false &&
596                             (tsettings->selectmode & SCE_SELECT_FACE))
597                         {
598                                 /* Force display of face centers in this case because that's
599                                  * the only way to see if a face is selected. */
600                                 show_face_dots = true;
601                         }
602
603                         /* Updating uniform */
604                         backwire_opacity = v3d->overlay.backwire_opacity;
605                         size_normal = v3d->overlay.normals_length;
606
607                         face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
608
609                         if (!stl->g_data->do_faces) {
610                                 face_mod = 0.0f;
611                         }
612
613                         if (do_show_weight) {
614                                 geom = DRW_cache_mesh_surface_weights_get(ob);
615                                 DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
616                         }
617
618                         if (do_occlude_wire) {
619                                 geom = DRW_cache_mesh_surface_get(ob);
620                                 DRW_shgroup_call_add(stl->g_data->depth_shgrp_hidden_wire, geom, ob->obmat);
621                         }
622
623                         if (vnormals_do) {
624                                 geom = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
625                                 DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat);
626                         }
627                         if (lnormals_do) {
628                                 geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
629                                 DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geom, ob->obmat);
630                         }
631                         if (fnormals_do) {
632                                 geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
633                                 DRW_shgroup_call_add(stl->g_data->fnormals_shgrp, geom, ob->obmat);
634                         }
635
636                         if (stl->g_data->do_zbufclip) {
637                                 edit_mesh_add_ob_to_pass(
638                                         scene, ob, stl->g_data,
639                                         stl->g_data->facedot_shgrp,
640                                         (stl->g_data->do_faces) ? stl->g_data->facefill_occluded_shgrp : NULL);
641                         }
642                         else {
643                                 edit_mesh_add_ob_to_pass(
644                                         scene, ob, stl->g_data,
645                                         (show_face_dots) ? stl->g_data->facedot_shgrp : NULL,
646                                         NULL);
647                         }
648
649                         stl->g_data->ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
650                         stl->g_data->edit_ob += 1;
651
652                         /* 3D text overlay */
653                         if (v3d->overlay.edit_flag & (V3D_OVERLAY_EDIT_EDGE_LEN |
654                                                       V3D_OVERLAY_EDIT_FACE_AREA |
655                                                       V3D_OVERLAY_EDIT_FACE_ANG |
656                                                       V3D_OVERLAY_EDIT_EDGE_ANG |
657                                                       V3D_OVERLAY_EDIT_INDICES))
658                         {
659                                 if (DRW_state_show_text()) {
660                                         DRW_edit_mesh_mode_text_measure_stats(
661                                                draw_ctx->ar, v3d, ob, &scene->unit);
662                                 }
663                         }
664                 }
665         }
666 }
667
668 static void EDIT_MESH_draw_scene(void *vedata)
669 {
670         EDIT_MESH_PassList *psl = ((EDIT_MESH_Data *)vedata)->psl;
671         EDIT_MESH_StorageList *stl = ((EDIT_MESH_Data *)vedata)->stl;
672         EDIT_MESH_FramebufferList *fbl = ((EDIT_MESH_Data *)vedata)->fbl;
673         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
674         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
675
676         DRW_draw_pass(psl->weight_faces);
677
678         DRW_draw_pass(psl->depth_hidden_wire);
679
680         if (stl->g_data->do_zbufclip) {
681                 float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
682                 /* render facefill */
683                 DRW_draw_pass(psl->facefill_occlude);
684
685                 /* Render wires on a separate framebuffer */
686                 GPU_framebuffer_bind(fbl->occlude_wire_fb);
687                 GPU_framebuffer_clear_color_depth(fbl->occlude_wire_fb, clearcol, 1.0f);
688                 DRW_draw_pass(psl->normals);
689                 DRW_draw_pass(psl->edit_face_occluded);
690
691                 /* Combine with scene buffer */
692                 GPU_framebuffer_bind(dfbl->color_only_fb);
693                 DRW_draw_pass(psl->mix_occlude);
694         }
695         else {
696                 DRW_draw_pass(psl->normals);
697
698                 const DRWContextState *draw_ctx = DRW_context_state_get();
699                 View3D *v3d = draw_ctx->v3d;
700
701                 if (v3d->shading.type == OB_SOLID && (v3d->shading.flag & XRAY_FLAG(v3d)) == 0 &&
702                     stl->g_data->ghost_ob == 1 && stl->g_data->edit_ob == 1)
703                 {
704                         /* In the case of single ghost object edit (common case for retopology):
705                          * we duplicate the depht+stencil buffer and clear all depth to 1.0f where
706                          * the stencil buffer is no 0x00. */
707                         const float *viewport_size = DRW_viewport_size_get();
708                         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
709                         struct GPUTexture *ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_edit_mesh_type);
710                         GPU_framebuffer_ensure_config(&fbl->ghost_wire_fb, {
711                                 GPU_ATTACHMENT_TEXTURE(ghost_depth_tx),
712                                 GPU_ATTACHMENT_TEXTURE(dtxl->color),
713                         });
714
715                         GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->ghost_wire_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
716                         GPU_framebuffer_bind(fbl->ghost_wire_fb);
717
718                         DRW_draw_pass(psl->ghost_clear_depth);
719
720                         DRW_draw_pass(psl->edit_face_overlay);
721                 }
722                 else {
723                         // MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
724
725                         DRW_draw_pass(psl->edit_face_overlay);
726
727                         // MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
728                 }
729         }
730
731         DRW_state_clip_planes_reset();
732 }
733
734 static void EDIT_MESH_engine_free(void)
735 {
736         for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
737                 EDIT_MESH_Shaders *sh_data = &e_data.sh_data[sh_data_index];
738                 /* Don't free builtins. */
739                 sh_data->depth = NULL;
740                 GPUShader **sh_data_as_array = (GPUShader **)sh_data;
741                 for (int i = 0; i < (sizeof(EDIT_MESH_Shaders) / sizeof(GPUShader *)); i++) {
742                         DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
743                 }
744         }
745 }
746
747 static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data);
748
749 DrawEngineType draw_engine_edit_mesh_type = {
750         NULL, NULL,
751         N_("EditMeshMode"),
752         &EDIT_MESH_data_size,
753         &EDIT_MESH_engine_init,
754         &EDIT_MESH_engine_free,
755         &EDIT_MESH_cache_init,
756         &EDIT_MESH_cache_populate,
757         NULL,
758         NULL,
759         &EDIT_MESH_draw_scene,
760         NULL,
761         NULL,
762 };