Merge branch 'master' into greasepencil-object
[blender.git] / source / blender / draw / engines / gpencil / gpencil_draw_utils.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 2017, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw
21  */
22
23 #include "BLI_polyfill_2d.h"
24
25 #include "DRW_render.h"
26
27 #include "BKE_gpencil.h"
28 #include "BKE_gpencil_modifier.h"
29 #include "BKE_image.h"
30 #include "BKE_material.h"
31 #include "BKE_paint.h"
32
33 #include "BLI_hash.h"
34
35 #include "ED_gpencil.h"
36
37 #include "DNA_gpencil_types.h"
38 #include "DNA_material_types.h"
39 #include "DNA_view3d_types.h"
40 #include "DNA_gpencil_modifier_types.h"
41
42 /* If builtin shaders are needed */
43 #include "GPU_shader.h"
44 #include "GPU_texture.h"
45
46 /* For EvaluationContext... */
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
49
50 #include "IMB_imbuf_types.h"
51
52 #include "gpencil_engine.h"
53
54 #include "UI_resources.h"
55
56 /* fill type to communicate to shader */
57 #define SOLID 0
58 #define GRADIENT 1
59 #define RADIAL 2
60 #define CHESS 3
61 #define TEXTURE 4
62 #define PATTERN 5
63
64 /* Get number of vertex for using in GPU VBOs */
65 static void gpencil_calc_vertex(GPENCIL_StorageList *stl,
66                                 tGPencilObjectCache *cache_ob,
67                                 GpencilBatchCache *cache,
68                                 bGPdata *gpd,
69                                 int cfra_eval)
70 {
71   if (!cache->is_dirty) {
72     return;
73   }
74
75   Object *ob = cache_ob->ob;
76   const DRWContextState *draw_ctx = DRW_context_state_get();
77   const bool main_onion = draw_ctx->v3d != NULL ?
78                               (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) :
79                               true;
80   const bool playing = stl->storage->is_playing;
81   const bool overlay = draw_ctx->v3d != NULL ?
82                            (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) :
83                            true;
84   const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && overlay &&
85                         main_onion && DRW_gpencil_onion_active(gpd) && !playing;
86
87   const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
88
89   cache_ob->tot_vertex = 0;
90   cache_ob->tot_triangles = 0;
91   int derived_idx = 0;
92
93   for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
94     bGPDframe *init_gpf = NULL;
95     const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
96     if (gpl->flag & GP_LAYER_HIDE) {
97       derived_idx++;
98       continue;
99     }
100
101     /* if multiedit or onion skin need to count all frames of the layer */
102     if ((is_multiedit) || (is_onion)) {
103       init_gpf = gpl->frames.first;
104     }
105     else {
106       init_gpf = &ob->runtime.derived_frames[derived_idx];
107     }
108
109     if (init_gpf == NULL) {
110       continue;
111     }
112
113     for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
114       for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
115         cache_ob->tot_vertex += gps->totpoints + 3;
116         cache_ob->tot_triangles += gps->totpoints - 1;
117       }
118       if ((!is_multiedit) && (!is_onion)) {
119         break;
120       }
121     }
122     derived_idx++;
123   }
124
125   cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3;
126   cache->b_stroke.tot_vertex = cache_ob->tot_vertex;
127   cache->b_point.tot_vertex = cache_ob->tot_vertex;
128   cache->b_edit.tot_vertex = cache_ob->tot_vertex;
129   cache->b_edlin.tot_vertex = cache_ob->tot_vertex;
130
131   /* some modifiers can change the number of points */
132   int factor = 0;
133   GpencilModifierData *md;
134   for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
135     const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
136     /* only modifiers that change size */
137     if (mti && mti->getDuplicationFactor) {
138       factor = mti->getDuplicationFactor(md);
139
140       cache->b_fill.tot_vertex *= factor;
141       cache->b_stroke.tot_vertex *= factor;
142       cache->b_point.tot_vertex *= factor;
143       cache->b_edit.tot_vertex *= factor;
144       cache->b_edlin.tot_vertex *= factor;
145     }
146   }
147 }
148
149 /* Helper for doing all the checks on whether a stroke can be drawn */
150 static bool gpencil_can_draw_stroke(struct MaterialGPencilStyle *gp_style,
151                                     const bGPDstroke *gps,
152                                     const bool onion,
153                                     const bool is_mat_preview)
154 {
155   /* skip stroke if it doesn't have any valid data */
156   if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) {
157     return false;
158   }
159
160   /* if mat preview render always visible */
161   if (is_mat_preview) {
162     return true;
163   }
164
165   /* check if the color is visible */
166   if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
167       (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) {
168     return false;
169   }
170
171   /* stroke can be drawn */
172   return true;
173 }
174
175 /* calc bounding box in 2d using flat projection data */
176 static void gpencil_calc_2d_bounding_box(const float (*points2d)[2],
177                                          int totpoints,
178                                          float minv[2],
179                                          float maxv[2])
180 {
181   minv[0] = points2d[0][0];
182   minv[1] = points2d[0][1];
183   maxv[0] = points2d[0][0];
184   maxv[1] = points2d[0][1];
185
186   for (int i = 1; i < totpoints; i++) {
187     /* min */
188     if (points2d[i][0] < minv[0]) {
189       minv[0] = points2d[i][0];
190     }
191     if (points2d[i][1] < minv[1]) {
192       minv[1] = points2d[i][1];
193     }
194     /* max */
195     if (points2d[i][0] > maxv[0]) {
196       maxv[0] = points2d[i][0];
197     }
198     if (points2d[i][1] > maxv[1]) {
199       maxv[1] = points2d[i][1];
200     }
201   }
202   /* use a perfect square */
203   if (maxv[0] > maxv[1]) {
204     maxv[1] = maxv[0];
205   }
206   else {
207     maxv[0] = maxv[1];
208   }
209 }
210
211 /* calc texture coordinates using flat projected points */
212 static void gpencil_calc_stroke_fill_uv(
213     const float (*points2d)[2], int totpoints, float minv[2], float maxv[2], float (*r_uv)[2])
214 {
215   float d[2];
216   d[0] = maxv[0] - minv[0];
217   d[1] = maxv[1] - minv[1];
218   for (int i = 0; i < totpoints; i++) {
219     r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
220     r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
221   }
222 }
223
224 /* recalc the internal geometry caches for fill and uvs */
225 static void DRW_gpencil_recalc_geometry_caches(Object *ob,
226                                                bGPDlayer *gpl,
227                                                MaterialGPencilStyle *gp_style,
228                                                bGPDstroke *gps)
229 {
230   if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
231     /* Calculate triangles cache for filling area (must be done only after changes) */
232     if ((gps->tot_triangles == 0) || (gps->triangles == NULL)) {
233       if ((gps->totpoints > 2) &&
234           ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0) ||
235            (gpl->blend_mode != eGplBlendMode_Normal))) {
236         DRW_gpencil_triangulate_stroke_fill(ob, gps);
237       }
238     }
239
240     /* calc uv data along the stroke */
241     ED_gpencil_calc_stroke_uv(ob, gps);
242
243     /* clear flag */
244     gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
245   }
246 }
247
248 static void set_wireframe_color(Object *ob,
249                                 bGPDlayer *gpl,
250                                 View3D *v3d,
251                                 GPENCIL_StorageList *stl,
252                                 MaterialGPencilStyle *gp_style,
253                                 int id,
254                                 const bool is_fill)
255 {
256   const DRWContextState *draw_ctx = DRW_context_state_get();
257   World *world = draw_ctx->scene->world;
258
259   float color[4];
260   if (((gp_style->stroke_rgba[3] < GPENCIL_ALPHA_OPACITY_THRESH) ||
261        (((gp_style->flag & GP_STYLE_STROKE_SHOW) == 0))) &&
262       (gp_style->fill_rgba[3] >= GPENCIL_ALPHA_OPACITY_THRESH)) {
263     copy_v4_v4(color, gp_style->fill_rgba);
264   }
265   else {
266     copy_v4_v4(color, gp_style->stroke_rgba);
267   }
268   float alpha = color[3];
269
270   /* wire color */
271   if ((v3d) && (id > -1)) {
272     const char type = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
273                            v3d->shading.wire_color_type :
274                            v3d->shading.color_type);
275     /* if fill and wire, use background color */
276     if ((is_fill) && (stl->shgroups[id].shading_type[0] == OB_WIRE)) {
277       if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) {
278         UI_GetThemeColor4fv(TH_BACK, stl->shgroups[id].wire_color);
279         stl->shgroups[id].wire_color[3] = 1.0f;
280       }
281       else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
282         color[0] = world->horr;
283         color[1] = world->horg;
284         color[2] = world->horb;
285         color[3] = 1.0f;
286         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
287       }
288       else {
289         copy_v3_v3(color, v3d->shading.background_color);
290         color[3] = 1.0f;
291         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
292       }
293       return;
294     }
295
296     /* strokes */
297     switch (type) {
298       case V3D_SHADING_SINGLE_COLOR: {
299         if (stl->shgroups[id].shading_type[0] == OB_WIRE) {
300           UI_GetThemeColor4fv(TH_WIRE, color);
301         }
302         else {
303           copy_v3_v3(color, v3d->shading.single_color);
304         }
305         color[3] = alpha;
306         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
307         break;
308       }
309       case V3D_SHADING_OBJECT_COLOR: {
310         copy_v4_v4(color, ob->color);
311         color[3] = alpha;
312         linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
313         break;
314       }
315       case V3D_SHADING_RANDOM_COLOR: {
316         uint gpl_hash = 1;
317         uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
318         if (gpl) {
319           gpl_hash = BLI_ghashutil_strhash_p_murmur(gpl->info);
320         }
321
322         float hue = BLI_hash_int_01(ob_hash * gpl_hash);
323         float hsv[3] = {hue, 0.40f, 0.8f};
324         float wire_col[3];
325         hsv_to_rgb_v(hsv, &wire_col[0]);
326
327         stl->shgroups[id].wire_color[0] = wire_col[0];
328         stl->shgroups[id].wire_color[1] = wire_col[1];
329         stl->shgroups[id].wire_color[2] = wire_col[2];
330         stl->shgroups[id].wire_color[3] = alpha;
331         break;
332       }
333       default: {
334         copy_v4_v4(stl->shgroups[id].wire_color, color);
335         break;
336       }
337     }
338   }
339   else {
340     copy_v4_v4(stl->shgroups[id].wire_color, color);
341   }
342
343   /* if solid, the alpha must be set to 1.0 */
344   if (stl->shgroups[id].shading_type[0] == OB_SOLID) {
345     stl->shgroups[id].wire_color[3] = 1.0f;
346   }
347 }
348
349 /* create shading group for filling */
350 static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
351                                                         GPENCIL_Data *vedata,
352                                                         DRWPass *pass,
353                                                         GPUShader *shader,
354                                                         Object *ob,
355                                                         bGPdata *gpd,
356                                                         bGPDlayer *gpl,
357                                                         MaterialGPencilStyle *gp_style,
358                                                         int id,
359                                                         int shading_type[2])
360 {
361   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
362   const DRWContextState *draw_ctx = DRW_context_state_get();
363   View3D *v3d = draw_ctx->v3d;
364
365   /* e_data.gpencil_fill_sh */
366   DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
367
368   DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1);
369
370   /* set style type */
371   switch (gp_style->fill_style) {
372     case GP_STYLE_FILL_STYLE_SOLID:
373       stl->shgroups[id].fill_style = SOLID;
374       break;
375     case GP_STYLE_FILL_STYLE_GRADIENT:
376       if (gp_style->gradient_type == GP_STYLE_GRADIENT_LINEAR) {
377         stl->shgroups[id].fill_style = GRADIENT;
378       }
379       else {
380         stl->shgroups[id].fill_style = RADIAL;
381       }
382       break;
383     case GP_STYLE_FILL_STYLE_CHESSBOARD:
384       stl->shgroups[id].fill_style = CHESS;
385       break;
386     case GP_STYLE_FILL_STYLE_TEXTURE:
387       if (gp_style->flag & GP_STYLE_FILL_PATTERN) {
388         stl->shgroups[id].fill_style = PATTERN;
389       }
390       else {
391         stl->shgroups[id].fill_style = TEXTURE;
392       }
393       break;
394     default:
395       stl->shgroups[id].fill_style = GP_STYLE_FILL_STYLE_SOLID;
396       break;
397   }
398   DRW_shgroup_uniform_int(grp, "fill_type", &stl->shgroups[id].fill_style, 1);
399
400   DRW_shgroup_uniform_float(grp, "mix_factor", &gp_style->mix_factor, 1);
401
402   DRW_shgroup_uniform_float(grp, "gradient_angle", &gp_style->gradient_angle, 1);
403   DRW_shgroup_uniform_float(grp, "gradient_radius", &gp_style->gradient_radius, 1);
404   DRW_shgroup_uniform_float(grp, "pattern_gridsize", &gp_style->pattern_gridsize, 1);
405   DRW_shgroup_uniform_vec2(grp, "gradient_scale", gp_style->gradient_scale, 1);
406   DRW_shgroup_uniform_vec2(grp, "gradient_shift", gp_style->gradient_shift, 1);
407
408   DRW_shgroup_uniform_float(grp, "texture_angle", &gp_style->texture_angle, 1);
409   DRW_shgroup_uniform_vec2(grp, "texture_scale", gp_style->texture_scale, 1);
410   DRW_shgroup_uniform_vec2(grp, "texture_offset", gp_style->texture_offset, 1);
411   DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
412   DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
413
414   stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_FILL_TEX_MIX ? 1 : 0;
415   DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
416
417   stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
418   DRW_shgroup_uniform_int(grp, "texture_flip", &stl->shgroups[id].texture_flip, 1);
419
420   stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
421   DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
422   DRW_shgroup_uniform_int(grp, "drawmode", (const int *)&gpd->draw_mode, 1);
423
424   /* viewport x-ray */
425   stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
426   DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
427
428   /* shading type */
429   stl->shgroups[id].shading_type[0] = GPENCIL_USE_SOLID(stl) ? (int)OB_RENDER : shading_type[0];
430   if (v3d) {
431     stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
432                                              v3d->shading.wire_color_type :
433                                              v3d->shading.color_type);
434   }
435
436   DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
437
438   /* wire color */
439   set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, true);
440   DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
441
442   /* image texture */
443   if ((gp_style->flag & GP_STYLE_FILL_TEX_MIX) ||
444       (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE)) {
445     ImBuf *ibuf;
446     Image *image = gp_style->ima;
447     ImageUser iuser = {NULL};
448     void *lock;
449
450     iuser.ok = true;
451
452     ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
453
454     if (ibuf == NULL || ibuf->rect == NULL) {
455       BKE_image_release_ibuf(image, ibuf, NULL);
456     }
457     else {
458       GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true);
459       DRW_shgroup_uniform_texture(grp, "myTexture", texture);
460
461       stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0;
462       DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
463
464       BKE_image_release_ibuf(image, ibuf, NULL);
465     }
466   }
467   else {
468     /* if no texture defined, need a blank texture to avoid errors in draw manager */
469     DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
470     stl->shgroups[id].texture_clamp = 0;
471     DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
472   }
473
474   return grp;
475 }
476
477 /* check if some onion is enabled */
478 bool DRW_gpencil_onion_active(bGPdata *gpd)
479 {
480   for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
481     if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
482       return true;
483     }
484   }
485   return false;
486 }
487
488 /* create shading group for strokes */
489 DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
490                                                    GPENCIL_Data *vedata,
491                                                    DRWPass *pass,
492                                                    GPUShader *shader,
493                                                    Object *ob,
494                                                    bGPdata *gpd,
495                                                    bGPDlayer *gpl,
496                                                    bGPDstroke *gps,
497                                                    MaterialGPencilStyle *gp_style,
498                                                    int id,
499                                                    bool onion,
500                                                    const float scale,
501                                                    const int shading_type[2])
502 {
503   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
504   const float *viewport_size = DRW_viewport_size_get();
505   const DRWContextState *draw_ctx = DRW_context_state_get();
506   View3D *v3d = draw_ctx->v3d;
507
508   /* e_data.gpencil_stroke_sh */
509   DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
510
511   DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
512
513   DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
514
515   /* avoid wrong values */
516   if ((gpd) && (gpd->pixfactor == 0.0f)) {
517     gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
518   }
519
520   /* object scale and depth */
521   if ((ob) && (id > -1)) {
522     stl->shgroups[id].obj_scale = scale;
523     DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
524     stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
525     DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
526
527     stl->shgroups[id].stroke_style = gp_style->stroke_style;
528     stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
529     if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
530       stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
531       if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
532         stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
533       }
534     }
535     DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
536     DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
537
538     stl->shgroups[id].caps_mode[0] = gps->caps[0];
539     stl->shgroups[id].caps_mode[1] = gps->caps[1];
540     DRW_shgroup_uniform_int(grp, "caps_mode", &stl->shgroups[id].caps_mode[0], 2);
541
542     stl->shgroups[id].gradient_f = gps->gradient_f;
543     copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
544     DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
545
546     /* viewport x-ray */
547     stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
548     DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
549
550     stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER :
551                                                                             shading_type[0];
552     if (v3d) {
553       stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
554                                                v3d->shading.wire_color_type :
555                                                v3d->shading.color_type);
556     }
557     DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
558
559     /* wire color */
560     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
561     DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
562
563     /* mix stroke factor */
564     stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
565                                               gp_style->mix_stroke_factor :
566                                               0.0f;
567     DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
568   }
569   else {
570     stl->storage->obj_scale = 1.0f;
571     stl->storage->keep_size = 0;
572     stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
573     DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
574     DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
575     DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
576     if (gpd) {
577       DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
578     }
579     else {
580       DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
581     }
582     const int zero[2] = {0, 0};
583     DRW_shgroup_uniform_int(grp, "caps_mode", &zero[0], 2);
584
585     DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
586
587     /* viewport x-ray */
588     DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
589     DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
590
591     /* mix stroke factor */
592     stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
593                                           gp_style->mix_stroke_factor :
594                                           0.0f;
595     DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
596   }
597
598   DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
599
600   if ((gpd) && (id > -1)) {
601     stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
602     DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
603   }
604   else {
605     /* for drawing always on predefined z-depth */
606     DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
607   }
608
609   /* image texture for pattern */
610   if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
611     ImBuf *ibuf;
612     Image *image = gp_style->sima;
613     ImageUser iuser = {NULL};
614     void *lock;
615
616     iuser.ok = true;
617
618     ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
619
620     if (ibuf == NULL || ibuf->rect == NULL) {
621       BKE_image_release_ibuf(image, ibuf, NULL);
622     }
623     else {
624       GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
625       DRW_shgroup_uniform_texture(grp, "myTexture", texture);
626
627       BKE_image_release_ibuf(image, ibuf, NULL);
628     }
629   }
630   else {
631     /* if no texture defined, need a blank texture to avoid errors in draw manager */
632     DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
633   }
634
635   return grp;
636 }
637
638 /* create shading group for points */
639 static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
640                                                          GPENCIL_Data *vedata,
641                                                          DRWPass *pass,
642                                                          GPUShader *shader,
643                                                          Object *ob,
644                                                          bGPdata *gpd,
645                                                          bGPDlayer *gpl,
646                                                          bGPDstroke *gps,
647                                                          MaterialGPencilStyle *gp_style,
648                                                          int id,
649                                                          bool onion,
650                                                          const float scale,
651                                                          const int shading_type[2])
652 {
653   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
654   const float *viewport_size = DRW_viewport_size_get();
655   const DRWContextState *draw_ctx = DRW_context_state_get();
656   View3D *v3d = draw_ctx->v3d;
657
658   /* e_data.gpencil_stroke_sh */
659   DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
660
661   DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
662   DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
663
664   /* avoid wrong values */
665   if ((gpd) && (gpd->pixfactor == 0.0f)) {
666     gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
667   }
668
669   /* object scale and depth */
670   if ((ob) && (id > -1)) {
671     stl->shgroups[id].obj_scale = scale;
672     DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
673     stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
674     DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
675
676     stl->shgroups[id].mode = gp_style->mode;
677     stl->shgroups[id].stroke_style = gp_style->stroke_style;
678     stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
679     if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
680       stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
681       if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
682         stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
683       }
684     }
685     DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
686     DRW_shgroup_uniform_int(grp, "mode", &stl->shgroups[id].mode, 1);
687     DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
688
689     stl->shgroups[id].gradient_f = gps->gradient_f;
690     copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
691     DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
692     DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->shgroups[id].gradient_s, 1);
693
694     /* viewport x-ray */
695     stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
696     DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
697
698     stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER :
699                                                                             shading_type[0];
700     if (v3d) {
701       stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
702                                                v3d->shading.wire_color_type :
703                                                v3d->shading.color_type);
704     }
705     DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
706
707     /* wire color */
708     set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
709     DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
710
711     /* mix stroke factor */
712     stl->shgroups[id].mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
713                                               gp_style->mix_stroke_factor :
714                                               0.0f;
715     DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->shgroups[id].mix_stroke_factor, 1);
716
717     /* lock rotation of dots and boxes */
718     stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
719     DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
720   }
721   else {
722     stl->storage->obj_scale = 1.0f;
723     stl->storage->keep_size = 0;
724     stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
725     stl->storage->mode = gp_style->mode;
726     DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
727     DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
728     DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
729     DRW_shgroup_uniform_int(grp, "mode", &stl->storage->mode, 1);
730     if (gpd) {
731       DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
732     }
733     else {
734       DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
735     }
736
737     DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
738     DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->storage->gradient_s, 1);
739
740     /* viewport x-ray */
741     DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
742     DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
743
744     /* mix stroke factor */
745     stl->storage->mix_stroke_factor = (gp_style->flag & GP_STYLE_STROKE_TEX_MIX) ?
746                                           gp_style->mix_stroke_factor :
747                                           0.0f;
748     DRW_shgroup_uniform_float(grp, "mix_stroke_factor", &stl->storage->mix_stroke_factor, 1);
749
750     /* lock rotation of dots and boxes */
751     DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
752   }
753
754   DRW_shgroup_uniform_vec4(grp, "colormix", gp_style->stroke_rgba, 1);
755
756   if ((gpd) && (id > -1)) {
757     stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
758     DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&stl->shgroups[id].xray_mode, 1);
759   }
760   else {
761     /* for drawing always on predefined z-depth */
762     DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
763   }
764
765   /* image texture */
766   if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
767     ImBuf *ibuf;
768     Image *image = gp_style->sima;
769     ImageUser iuser = {NULL};
770     void *lock;
771
772     iuser.ok = true;
773
774     ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
775
776     if (ibuf == NULL || ibuf->rect == NULL) {
777       BKE_image_release_ibuf(image, ibuf, NULL);
778     }
779     else {
780       GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
781       DRW_shgroup_uniform_texture(grp, "myTexture", texture);
782
783       BKE_image_release_ibuf(image, ibuf, NULL);
784     }
785   }
786   else {
787     /* if no texture defined, need a blank texture to avoid errors in draw manager */
788     DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
789   }
790
791   return grp;
792 }
793
794 /* add fill vertex info  */
795 static void gpencil_add_fill_vertexdata(GpencilBatchCache *cache,
796                                         Object *ob,
797                                         bGPDlayer *gpl,
798                                         bGPDframe *gpf,
799                                         bGPDstroke *gps,
800                                         float opacity,
801                                         const float tintcolor[4],
802                                         const bool onion,
803                                         const bool custonion)
804 {
805   MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
806   if (gps->totpoints >= 3) {
807     float tfill[4];
808     /* set color using material, tint color and opacity */
809     interp_v3_v3v3(tfill, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
810     tfill[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
811     if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0) ||
812         (gpl->blend_mode != eGplBlendMode_Normal)) {
813       if (cache->is_dirty) {
814         const float *color;
815         if (!onion) {
816           color = tfill;
817         }
818         else {
819           if (custonion) {
820             color = tintcolor;
821           }
822           else {
823             ARRAY_SET_ITEMS(tfill, UNPACK3(gps->runtime.tmp_fill_rgba), tintcolor[3]);
824             color = tfill;
825           }
826         }
827         /* create vertex data */
828         const int old_len = cache->b_fill.vbo_len;
829         DRW_gpencil_get_fill_geom(&cache->b_fill, ob, gps, color);
830
831         /* add to list of groups */
832         if (old_len < cache->b_fill.vbo_len) {
833           cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
834                                                      gpl,
835                                                      gpf,
836                                                      gps,
837                                                      eGpencilBatchGroupType_Fill,
838                                                      onion,
839                                                      cache->b_fill.vbo_len,
840                                                      &cache->grp_size,
841                                                      &cache->grp_used);
842         }
843       }
844     }
845   }
846 }
847
848 /* add stroke vertex info */
849 static void gpencil_add_stroke_vertexdata(GpencilBatchCache *cache,
850                                           Object *ob,
851                                           bGPDlayer *gpl,
852                                           bGPDframe *gpf,
853                                           bGPDstroke *gps,
854                                           const float opacity,
855                                           const float tintcolor[4],
856                                           const bool onion,
857                                           const bool custonion)
858 {
859   float tcolor[4];
860   float ink[4];
861   short sthickness;
862   MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
863
864   /* set color using base color, tint color and opacity */
865   if (cache->is_dirty) {
866     if (!onion) {
867       /* if special stroke, use fill color as stroke color */
868       if (gps->flag & GP_STROKE_NOFILL) {
869         interp_v3_v3v3(tcolor, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
870         tcolor[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
871       }
872       else {
873         interp_v3_v3v3(tcolor, gps->runtime.tmp_stroke_rgba, tintcolor, tintcolor[3]);
874         tcolor[3] = gps->runtime.tmp_stroke_rgba[3] * opacity;
875       }
876       copy_v4_v4(ink, tcolor);
877     }
878     else {
879       if (custonion) {
880         copy_v4_v4(ink, tintcolor);
881       }
882       else {
883         ARRAY_SET_ITEMS(tcolor, UNPACK3(gps->runtime.tmp_stroke_rgba), opacity);
884         copy_v4_v4(ink, tcolor);
885       }
886     }
887
888     sthickness = gps->thickness + gpl->line_change;
889     CLAMP_MIN(sthickness, 1);
890
891     if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
892       /* create vertex data */
893       const int old_len = cache->b_stroke.vbo_len;
894       DRW_gpencil_get_stroke_geom(&cache->b_stroke, gps, sthickness, ink);
895
896       /* add to list of groups */
897       if (old_len < cache->b_stroke.vbo_len) {
898         cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
899                                                    gpl,
900                                                    gpf,
901                                                    gps,
902                                                    eGpencilBatchGroupType_Stroke,
903                                                    onion,
904                                                    cache->b_stroke.vbo_len,
905                                                    &cache->grp_size,
906                                                    &cache->grp_used);
907       }
908     }
909     else {
910       /* create vertex data */
911       const int old_len = cache->b_point.vbo_len;
912       DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink);
913
914       /* add to list of groups */
915       if (old_len < cache->b_point.vbo_len) {
916         cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
917                                                    gpl,
918                                                    gpf,
919                                                    gps,
920                                                    eGpencilBatchGroupType_Point,
921                                                    onion,
922                                                    cache->b_point.vbo_len,
923                                                    &cache->grp_size,
924                                                    &cache->grp_used);
925       }
926     }
927   }
928 }
929
930 /* add edit points vertex info */
931 static void gpencil_add_editpoints_vertexdata(GpencilBatchCache *cache,
932                                               Object *ob,
933                                               bGPdata *gpd,
934                                               bGPDlayer *gpl,
935                                               bGPDframe *gpf,
936                                               bGPDstroke *gps)
937 {
938   const DRWContextState *draw_ctx = DRW_context_state_get();
939   View3D *v3d = draw_ctx->v3d;
940   MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
941
942   /* alpha factor for edit points/line to make them more subtle */
943   float edit_alpha = v3d->vertex_opacity;
944
945   if (GPENCIL_ANY_EDIT_MODE(gpd)) {
946     Object *obact = DRW_context_state_get()->obact;
947     if ((!obact) || (obact->type != OB_GPENCIL)) {
948       return;
949     }
950     const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
951
952     if (cache->is_dirty) {
953       if ((obact == ob) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
954           (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES)) {
955         /* line of the original stroke */
956         DRW_gpencil_get_edlin_geom(&cache->b_edlin, gps, edit_alpha, gpd->flag);
957
958         /* add to list of groups */
959         cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
960                                                    gpl,
961                                                    gpf,
962                                                    gps,
963                                                    eGpencilBatchGroupType_Edlin,
964                                                    false,
965                                                    cache->b_edlin.vbo_len,
966                                                    &cache->grp_size,
967                                                    &cache->grp_used);
968       }
969       /* edit points */
970       if ((gps->flag & GP_STROKE_SELECT) || (is_weight_paint)) {
971         if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) ||
972             ((gp_style->flag & GP_STYLE_COLOR_LOCKED) == 0)) {
973           if (obact == ob) {
974             DRW_gpencil_get_edit_geom(&cache->b_edit, gps, edit_alpha, gpd->flag);
975
976             /* add to list of groups */
977             cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
978                                                        gpl,
979                                                        gpf,
980                                                        gps,
981                                                        eGpencilBatchGroupType_Edit,
982                                                        false,
983                                                        cache->b_edit.vbo_len,
984                                                        &cache->grp_size,
985                                                        &cache->grp_used);
986           }
987         }
988       }
989     }
990   }
991 }
992
993 /* main function to draw strokes */
994 static void gpencil_draw_strokes(GpencilBatchCache *cache,
995                                  GPENCIL_e_data *e_data,
996                                  void *vedata,
997                                  Object *ob,
998                                  bGPdata *gpd,
999                                  bGPDlayer *gpl,
1000                                  bGPDframe *gpf,
1001                                  const float opacity,
1002                                  const float tintcolor[4],
1003                                  const bool custonion,
1004                                  tGPencilObjectCache *cache_ob)
1005 {
1006   GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1007   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1008   const DRWContextState *draw_ctx = DRW_context_state_get();
1009   Scene *scene = draw_ctx->scene;
1010   View3D *v3d = draw_ctx->v3d;
1011   bGPDstroke *gps;
1012   float viewmatrix[4][4];
1013   const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
1014   const bool playing = stl->storage->is_playing;
1015   const bool is_render = (bool)stl->storage->is_render;
1016   const bool is_mat_preview = (bool)stl->storage->is_mat_preview;
1017   const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true;
1018
1019   /* Get evaluation context */
1020   /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files
1021    * (i.e. the thumbnail offscreen rendering fails)
1022    */
1023   Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
1024
1025   /* get parent matrix and save as static data */
1026   ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
1027   copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix);
1028
1029   if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) {
1030     copy_m4_m4(gpf->runtime.viewmatrix, cache_ob->obmat);
1031   }
1032
1033   for (gps = gpf->strokes.first; gps; gps = gps->next) {
1034     MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
1035
1036     /* check if stroke can be drawn */
1037     if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) {
1038       continue;
1039     }
1040
1041     /* be sure recalc all cache in source stroke to avoid recalculation when frame change
1042      * and improve fps */
1043     DRW_gpencil_recalc_geometry_caches(ob, gpl, gp_style, gps->runtime.gps_orig);
1044
1045     /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is
1046      * enabled */
1047     if ((stl->storage->simplify_fill) &&
1048         (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) {
1049       if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
1050           (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) ||
1051           (gpl->blend_mode != eGplBlendMode_Normal)) {
1052         continue;
1053       }
1054     }
1055
1056     if ((gpl->actframe->framenum == gpf->framenum) || (!is_multiedit) || (overlay_multiedit)) {
1057       /* copy color to temp fields to apply temporal changes in the stroke */
1058       copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
1059       copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
1060
1061       /* hide any blend layer */
1062       if ((!stl->storage->simplify_blend) || (gpl->blend_mode == eGplBlendMode_Normal)) {
1063         /* fill */
1064         if ((gp_style->flag & GP_STYLE_FILL_SHOW) && (!stl->storage->simplify_fill) &&
1065             ((gps->flag & GP_STROKE_NOFILL) == 0)) {
1066           gpencil_add_fill_vertexdata(
1067               cache, ob, gpl, gpf, gps, opacity, tintcolor, false, custonion);
1068         }
1069         /* stroke */
1070         /* No fill strokes, must show stroke always */
1071         if (((gp_style->flag & GP_STYLE_STROKE_SHOW) || (gps->flag & GP_STROKE_NOFILL)) &&
1072             ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
1073              (gpl->blend_mode == eGplBlendMode_Normal))) {
1074           /* recalc strokes uv (geometry can be changed by modifiers) */
1075           if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
1076             ED_gpencil_calc_stroke_uv(ob, gps);
1077           }
1078
1079           gpencil_add_stroke_vertexdata(
1080               cache, ob, gpl, gpf, gps, opacity, tintcolor, false, custonion);
1081         }
1082       }
1083     }
1084
1085     /* edit points (only in edit mode and not play animation not render) */
1086     if ((draw_ctx->obact == ob) && (!playing) && (!is_render) && (!cache_ob->is_dup_ob)) {
1087       if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
1088         if (!stl->g_data->shgrps_edit_line) {
1089           stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh,
1090                                                              psl->edit_pass);
1091         }
1092         if (!stl->g_data->shgrps_edit_point) {
1093           stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh,
1094                                                               psl->edit_pass);
1095           const float *viewport_size = DRW_viewport_size_get();
1096           DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1);
1097         }
1098
1099         gpencil_add_editpoints_vertexdata(cache, ob, gpd, gpl, gpf, gps);
1100       }
1101     }
1102   }
1103 }
1104
1105 /* get alpha factor for onion strokes */
1106 static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd)
1107 {
1108 #define MIN_ALPHA_VALUE 0.01f
1109
1110   /* if fade is disabled, opacity is equal in all frames */
1111   if ((gpd->onion_flag & GP_ONION_FADE) == 0) {
1112     color[3] = gpd->onion_factor;
1113   }
1114   else {
1115     /* add override opacity factor */
1116     color[3] += gpd->onion_factor - 0.5f;
1117   }
1118
1119   CLAMP(color[3], MIN_ALPHA_VALUE, 1.0f);
1120 }
1121
1122 /* function to draw strokes for onion only */
1123 static void gpencil_draw_onion_strokes(GpencilBatchCache *cache,
1124                                        void *vedata,
1125                                        Object *ob,
1126                                        bGPdata *gpd,
1127                                        bGPDlayer *gpl,
1128                                        bGPDframe *gpf,
1129                                        const float opacity,
1130                                        const float tintcolor[4],
1131                                        const bool custonion)
1132 {
1133   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1134   Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
1135
1136   float viewmatrix[4][4];
1137
1138   /* get parent matrix and save as static data */
1139   ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
1140   copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix);
1141
1142   for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
1143     MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
1144     if (gp_style == NULL) {
1145       continue;
1146     }
1147     copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
1148     copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
1149
1150     int id = stl->storage->shgroup_id;
1151     /* check if stroke can be drawn */
1152     if (gpencil_can_draw_stroke(gp_style, gps, true, false) == false) {
1153       continue;
1154     }
1155     /* limit the number of shading groups */
1156     if (id >= GPENCIL_MAX_SHGROUPS) {
1157       continue;
1158     }
1159
1160     /* stroke */
1161     gpencil_add_stroke_vertexdata(cache, ob, gpl, gpf, gps, opacity, tintcolor, true, custonion);
1162
1163     stl->storage->shgroup_id++;
1164   }
1165 }
1166
1167 /* draw onion-skinning for a layer */
1168 static void gpencil_draw_onionskins(GpencilBatchCache *cache,
1169                                     void *vedata,
1170                                     Object *ob,
1171                                     bGPdata *gpd,
1172                                     bGPDlayer *gpl,
1173                                     bGPDframe *gpf)
1174 {
1175
1176   const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)};
1177   const float alpha = 1.0f;
1178   float color[4];
1179   int idx;
1180   float fac = 1.0f;
1181   int step = 0;
1182   int mode = 0;
1183   bool colflag = false;
1184   bGPDframe *gpf_loop = NULL;
1185   int last = gpf->framenum;
1186
1187   colflag = (bool)gpd->onion_flag & GP_ONION_GHOST_PREVCOL;
1188
1189   /* -------------------------------
1190    * 1) Draw Previous Frames First
1191    * ------------------------------- */
1192   step = gpd->gstep;
1193   mode = gpd->onion_mode;
1194
1195   if (gpd->onion_flag & GP_ONION_GHOST_PREVCOL) {
1196     copy_v3_v3(color, gpd->gcolor_prev);
1197   }
1198   else {
1199     copy_v3_v3(color, default_color);
1200   }
1201
1202   idx = 0;
1203   for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
1204     /* only selected frames */
1205     if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
1206       continue;
1207     }
1208     /* absolute range */
1209     if (mode == GP_ONION_MODE_ABSOLUTE) {
1210       if ((gpf->framenum - gf->framenum) > step) {
1211         break;
1212       }
1213     }
1214     /* relative range */
1215     if (mode == GP_ONION_MODE_RELATIVE) {
1216       idx++;
1217       if (idx > step) {
1218         break;
1219       }
1220     }
1221     /* alpha decreases with distance from curframe index */
1222     if (mode != GP_ONION_MODE_SELECTED) {
1223       if (mode == GP_ONION_MODE_ABSOLUTE) {
1224         fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(step + 1));
1225       }
1226       else {
1227         fac = 1.0f - ((float)idx / (float)(step + 1));
1228       }
1229       color[3] = alpha * fac * 0.66f;
1230     }
1231     else {
1232       idx++;
1233       fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
1234       color[3] = fac;
1235     }
1236
1237     /* if loop option, save the frame to use later */
1238     if ((mode != GP_ONION_MODE_ABSOLUTE) && (gpd->onion_flag & GP_ONION_LOOP)) {
1239       gpf_loop = gf;
1240     }
1241
1242     gpencil_get_onion_alpha(color, gpd);
1243     gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
1244   }
1245   /* -------------------------------
1246    * 2) Now draw next frames
1247    * ------------------------------- */
1248   step = gpd->gstep_next;
1249   mode = gpd->onion_mode;
1250
1251   if (gpd->onion_flag & GP_ONION_GHOST_NEXTCOL) {
1252     copy_v3_v3(color, gpd->gcolor_next);
1253   }
1254   else {
1255     copy_v3_v3(color, default_color);
1256   }
1257
1258   idx = 0;
1259   for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
1260     /* only selected frames */
1261     if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
1262       continue;
1263     }
1264     /* absolute range */
1265     if (mode == GP_ONION_MODE_ABSOLUTE) {
1266       if ((gf->framenum - gpf->framenum) > step) {
1267         break;
1268       }
1269     }
1270     /* relative range */
1271     if (mode == GP_ONION_MODE_RELATIVE) {
1272       idx++;
1273       if (idx > step) {
1274         break;
1275       }
1276     }
1277     /* alpha decreases with distance from curframe index */
1278     if (mode != GP_ONION_MODE_SELECTED) {
1279       if (mode == GP_ONION_MODE_ABSOLUTE) {
1280         fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(step + 1));
1281       }
1282       else {
1283         fac = 1.0f - ((float)idx / (float)(step + 1));
1284       }
1285       color[3] = alpha * fac * 0.66f;
1286     }
1287     else {
1288       idx++;
1289       fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
1290       color[3] = fac;
1291     }
1292
1293     gpencil_get_onion_alpha(color, gpd);
1294     gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
1295     if (last < gf->framenum) {
1296       last = gf->framenum;
1297     }
1298   }
1299
1300   /* Draw first frame in blue for loop mode */
1301   if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) {
1302     if ((last == gpf->framenum) || (gpf->next == NULL)) {
1303       gpencil_get_onion_alpha(color, gpd);
1304       gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gpf_loop, color[3], color, colflag);
1305     }
1306   }
1307 }
1308
1309 /* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was
1310  * modified) */
1311 void DRW_gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps)
1312 {
1313   BLI_assert(gps->totpoints >= 3);
1314
1315   bGPdata *gpd = (bGPdata *)ob->data;
1316
1317   /* allocate memory for temporary areas */
1318   gps->tot_triangles = gps->totpoints - 2;
1319   uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles,
1320                                         "GP Stroke temp triangulation");
1321   float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints,
1322                                     "GP Stroke temp 2d points");
1323   float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
1324
1325   int direction = 0;
1326
1327   /* convert to 2d and triangulate */
1328   BKE_gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
1329   BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
1330
1331   /* calc texture coordinates automatically */
1332   float minv[2];
1333   float maxv[2];
1334   /* first needs bounding box data */
1335   if (gpd->flag & GP_DATA_UV_ADAPTIVE) {
1336     gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv);
1337   }
1338   else {
1339     ARRAY_SET_ITEMS(minv, -1.0f, -1.0f);
1340     ARRAY_SET_ITEMS(maxv, 1.0f, 1.0f);
1341   }
1342
1343   /* calc uv data */
1344   gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv);
1345
1346   /* Number of triangles */
1347   gps->tot_triangles = gps->totpoints - 2;
1348   /* save triangulation data in stroke cache */
1349   if (gps->tot_triangles > 0) {
1350     if (gps->triangles == NULL) {
1351       gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles,
1352                                    "GP Stroke triangulation");
1353     }
1354     else {
1355       gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
1356     }
1357
1358     for (int i = 0; i < gps->tot_triangles; i++) {
1359       bGPDtriangle *stroke_triangle = &gps->triangles[i];
1360       memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
1361       /* copy texture coordinates */
1362       copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]);
1363       copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]);
1364       copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]);
1365     }
1366   }
1367   else {
1368     /* No triangles needed - Free anything allocated previously */
1369     if (gps->triangles) {
1370       MEM_freeN(gps->triangles);
1371     }
1372
1373     gps->triangles = NULL;
1374   }
1375
1376   /* disable recalculation flag */
1377   if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
1378     gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
1379   }
1380
1381   /* clear memory */
1382   MEM_SAFE_FREE(tmp_triangles);
1383   MEM_SAFE_FREE(points2d);
1384   MEM_SAFE_FREE(uv);
1385 }
1386
1387 /* draw stroke in drawing buffer */
1388 void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
1389                                          void *vedata,
1390                                          ToolSettings *ts,
1391                                          Object *ob)
1392 {
1393   GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1394   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1395   const DRWContextState *draw_ctx = DRW_context_state_get();
1396   View3D *v3d = draw_ctx->v3d;
1397   const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
1398   Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
1399   const bool is_paint_tool = (bool)((brush) && (brush->gpencil_tool == GPAINT_TOOL_DRAW));
1400   bGPdata *gpd_eval = ob->data;
1401   /* need the original to avoid cow overhead while drawing */
1402   bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
1403
1404   MaterialGPencilStyle *gp_style = NULL;
1405   float obscale = mat4_to_scale(ob->obmat);
1406
1407   /* use the brush material */
1408   Material *ma = BKE_gpencil_object_material_get_from_brush(ob, brush);
1409   if (ma != NULL) {
1410     gp_style = ma->gp_style;
1411   }
1412   /* this is not common, but avoid any special situations when brush could be without material */
1413   if (gp_style == NULL) {
1414     gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol);
1415   }
1416
1417   /* drawing strokes */
1418   /* Check if may need to draw the active stroke cache, only if this layer is the active layer
1419    * that is being edited. (Stroke buffer is currently stored in gp-data)
1420    */
1421   if (gpd->runtime.sbuffer_size > 0) {
1422     if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
1423       /* It should also be noted that sbuffer contains temporary point types
1424        * i.e. tGPspoints NOT bGPDspoints
1425        */
1426       short lthick = brush->size * obscale;
1427
1428       /* save gradient info */
1429       stl->storage->gradient_f = brush->gpencil_settings->gradient_f;
1430       copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s);
1431       stl->storage->use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
1432
1433       /* if only one point, don't need to draw buffer because the user has no time to see it */
1434       if (gpd->runtime.sbuffer_size > 1) {
1435         if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
1436           stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create(
1437               e_data,
1438               vedata,
1439               psl->drawing_pass,
1440               e_data->gpencil_stroke_sh,
1441               NULL,
1442               gpd,
1443               NULL,
1444               NULL,
1445               gp_style,
1446               -1,
1447               false,
1448               1.0f,
1449               (const int *)stl->storage->shade_render);
1450         }
1451         else {
1452           stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create(
1453               e_data,
1454               vedata,
1455               psl->drawing_pass,
1456               e_data->gpencil_point_sh,
1457               NULL,
1458               gpd,
1459               NULL,
1460               NULL,
1461               gp_style,
1462               -1,
1463               false,
1464               1.0f,
1465               (const int *)stl->storage->shade_render);
1466         }
1467
1468         /* clean previous version of the batch */
1469         if (stl->storage->buffer_stroke) {
1470           GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
1471           MEM_SAFE_FREE(e_data->batch_buffer_stroke);
1472           stl->storage->buffer_stroke = false;
1473         }
1474
1475         /* use unit matrix because the buffer is in screen space and does not need conversion */
1476         if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
1477           e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(gpd, lthick);
1478         }
1479         else {
1480           e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(gpd, lthick);
1481         }
1482
1483         /* buffer strokes, must show stroke always */
1484         DRW_shgroup_call_add(stl->g_data->shgrps_drawing_stroke,
1485                              e_data->batch_buffer_stroke,
1486                              stl->storage->unit_matrix);
1487
1488         if ((gpd->runtime.sbuffer_size >= 3) &&
1489             (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
1490             ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
1491             ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
1492             (gp_style->flag & GP_STYLE_FILL_SHOW)) {
1493           /* if not solid, fill is simulated with solid color */
1494           if (gpd->runtime.bfill_style > 0) {
1495             gpd->runtime.sfill[3] = 0.5f;
1496           }
1497           stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(e_data->gpencil_drawing_fill_sh,
1498                                                                 psl->drawing_pass);
1499
1500           /* clean previous version of the batch */
1501           if (stl->storage->buffer_fill) {
1502             GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill);
1503             MEM_SAFE_FREE(e_data->batch_buffer_fill);
1504             stl->storage->buffer_fill = false;
1505           }
1506
1507           e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
1508           DRW_shgroup_call_add(stl->g_data->shgrps_drawing_fill,
1509                                e_data->batch_buffer_fill,
1510                                stl->storage->unit_matrix);
1511           stl->storage->buffer_fill = true;
1512         }
1513         stl->storage->buffer_stroke = true;
1514       }
1515     }
1516   }
1517
1518   /* control points for primitives and speed guide */
1519   const bool is_cppoint = (gpd->runtime.tot_cp_points > 0);
1520   const bool is_speed_guide = (ts->gp_sculpt.guide.use_guide &&
1521                                (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL));
1522   const bool is_show_gizmo = (((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) &&
1523                               ((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0));
1524
1525   if ((overlay) && (is_paint_tool) && (is_cppoint || is_speed_guide) && (is_show_gizmo) &&
1526       ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0)) {
1527     DRWShadingGroup *shgrp = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->drawing_pass);
1528     const float *viewport_size = DRW_viewport_size_get();
1529     DRW_shgroup_uniform_vec2(shgrp, "Viewport", viewport_size, 1);
1530
1531     /* clean previous version of the batch */
1532     if (stl->storage->buffer_ctrlpoint) {
1533       GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_ctrlpoint);
1534       MEM_SAFE_FREE(e_data->batch_buffer_ctrlpoint);
1535       stl->storage->buffer_ctrlpoint = false;
1536     }
1537
1538     e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
1539
1540     DRW_shgroup_call_add(shgrp, e_data->batch_buffer_ctrlpoint, stl->storage->unit_matrix);
1541
1542     stl->storage->buffer_ctrlpoint = true;
1543   }
1544 }
1545
1546 /* create all missing batches */
1547 static void DRW_gpencil_create_batches(GpencilBatchCache *cache)
1548 {
1549   if ((cache->b_point.vbo) && (cache->b_point.batch == NULL)) {
1550     cache->b_point.batch = GPU_batch_create_ex(
1551         GPU_PRIM_POINTS, cache->b_point.vbo, NULL, GPU_BATCH_OWNS_VBO);
1552   }
1553   if ((cache->b_stroke.vbo) && (cache->b_stroke.batch == NULL)) {
1554     cache->b_stroke.batch = GPU_batch_create_ex(
1555         GPU_PRIM_LINE_STRIP_ADJ, cache->b_stroke.vbo, NULL, GPU_BATCH_OWNS_VBO);
1556   }
1557   if ((cache->b_fill.vbo) && (cache->b_fill.batch == NULL)) {
1558     cache->b_fill.batch = GPU_batch_create_ex(
1559         GPU_PRIM_TRIS, cache->b_fill.vbo, NULL, GPU_BATCH_OWNS_VBO);
1560   }
1561   if ((cache->b_edit.vbo) && (cache->b_edit.batch == NULL)) {
1562     cache->b_edit.batch = GPU_batch_create_ex(
1563         GPU_PRIM_POINTS, cache->b_edit.vbo, NULL, GPU_BATCH_OWNS_VBO);
1564   }
1565   if ((cache->b_edlin.vbo) && (cache->b_edlin.batch == NULL)) {
1566     cache->b_edlin.batch = GPU_batch_create_ex(
1567         GPU_PRIM_LINE_STRIP, cache->b_edlin.vbo, NULL, GPU_BATCH_OWNS_VBO);
1568   }
1569 }
1570
1571 /* create all shading groups */
1572 static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
1573                                         void *vedata,
1574                                         Object *ob,
1575                                         GpencilBatchCache *cache,
1576                                         tGPencilObjectCache *cache_ob)
1577 {
1578   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1579   GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1580   bGPdata *gpd = (bGPdata *)ob->data;
1581   DRWPass *stroke_pass = GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d;
1582
1583   GpencilBatchGroup *elm = NULL;
1584   DRWShadingGroup *shgrp = NULL;
1585   tGPencilObjectCache_shgrp *array_elm = NULL;
1586
1587   bGPDlayer *gpl = NULL;
1588   bGPDlayer *gpl_prev = NULL;
1589   int idx = 0;
1590   bool tag_first = false;
1591
1592   const DRWContextState *draw_ctx = DRW_context_state_get();
1593   const View3D *v3d = draw_ctx->v3d;
1594
1595   const bool overlay = draw_ctx->v3d != NULL ?
1596                            (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) :
1597                            true;
1598   const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
1599   const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion &&
1600                         DRW_gpencil_onion_active(gpd) && overlay;
1601
1602   int start_stroke = 0;
1603   int start_point = 0;
1604   int start_fill = 0;
1605   int start_edit = 0;
1606   int start_edlin = 0;
1607
1608   for (int i = 0; i < cache->grp_used; i++) {
1609     elm = &cache->grp_cache[i];
1610     array_elm = &cache_ob->shgrp_array[idx];
1611     const float scale = cache_ob->scale;
1612
1613     /* save last group when change */
1614     if (gpl_prev == NULL) {
1615       gpl_prev = elm->gpl;
1616       tag_first = true;
1617     }
1618     else {
1619       if (elm->gpl != gpl_prev) {
1620         /* first layer is always blend Normal */
1621         array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
1622         array_elm->end_shgrp = shgrp;
1623         gpl_prev = elm->gpl;
1624         tag_first = true;
1625         idx++;
1626       }
1627     }
1628
1629     gpl = elm->gpl;
1630     bGPDframe *gpf = elm->gpf;
1631     bGPDstroke *gps = elm->gps;
1632     MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
1633     /* if the user switch used material from data to object,
1634      * the material could not be available */
1635     if (gp_style == NULL) {
1636       break;
1637     }
1638
1639     /* limit the number of shading groups */
1640     if (i >= GPENCIL_MAX_SHGROUPS) {
1641       break;
1642     }
1643
1644     switch (elm->type) {
1645       case eGpencilBatchGroupType_Stroke: {
1646         const int len = elm->vertex_idx - start_stroke;
1647
1648         shgrp = DRW_gpencil_shgroup_stroke_create(e_data,
1649                                                   vedata,
1650                                                   stroke_pass,
1651                                                   e_data->gpencil_stroke_sh,
1652                                                   ob,
1653                                                   gpd,
1654                                                   gpl,
1655                                                   gps,
1656                                                   gp_style,
1657                                                   stl->storage->shgroup_id,
1658                                                   elm->onion,
1659                                                   scale,
1660                                                   cache_ob->shading_type);
1661         if ((do_onion) || (elm->onion == false)) {
1662           DRW_shgroup_call_range_add(shgrp,
1663                                      cache->b_stroke.batch,
1664                                      (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
1665                                                               cache_ob->obmat,
1666                                      start_stroke,
1667                                      len);
1668         }
1669         stl->storage->shgroup_id++;
1670         start_stroke = elm->vertex_idx;
1671         break;
1672       }
1673       case eGpencilBatchGroupType_Point: {
1674         const int len = elm->vertex_idx - start_point;
1675
1676         shgrp = DRW_gpencil_shgroup_point_create(e_data,
1677                                                  vedata,
1678                                                  stroke_pass,
1679                                                  e_data->gpencil_point_sh,
1680                                                  ob,
1681                                                  gpd,
1682                                                  gpl,
1683                                                  gps,
1684                                                  gp_style,
1685                                                  stl->storage->shgroup_id,
1686                                                  elm->onion,
1687                                                  scale,
1688                                                  cache_ob->shading_type);
1689
1690         if ((do_onion) || (elm->onion == false)) {
1691           DRW_shgroup_call_range_add(shgrp,
1692                                      cache->b_point.batch,
1693                                      (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
1694                                                               cache_ob->obmat,
1695                                      start_point,
1696                                      len);
1697         }
1698         stl->storage->shgroup_id++;
1699         start_point = elm->vertex_idx;
1700         break;
1701       }
1702       case eGpencilBatchGroupType_Fill: {
1703         const int len = elm->vertex_idx - start_fill;
1704
1705         shgrp = DRW_gpencil_shgroup_fill_create(e_data,
1706                                                 vedata,
1707                                                 stroke_pass,
1708                                                 e_data->gpencil_fill_sh,
1709                                                 ob,
1710                                                 gpd,
1711                                                 gpl,
1712                                                 gp_style,
1713                                                 stl->storage->shgroup_id,
1714                                                 cache_ob->shading_type);
1715
1716         if ((do_onion) || (elm->onion == false)) {
1717           DRW_shgroup_call_range_add(shgrp,
1718                                      cache->b_fill.batch,
1719                                      (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
1720                                                               cache_ob->obmat,
1721                                      start_fill,
1722                                      len);
1723         }
1724         stl->storage->shgroup_id++;
1725         start_fill = elm->vertex_idx;
1726         break;
1727       }
1728       case eGpencilBatchGroupType_Edit: {
1729         if (stl->g_data->shgrps_edit_point) {
1730           const int len = elm->vertex_idx - start_edit;
1731           /* use always the same group */
1732           DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_point,
1733                                      cache->b_edit.batch,
1734                                      (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
1735                                                               cache_ob->obmat,
1736                                      start_edit,
1737                                      len);
1738
1739           start_edit = elm->vertex_idx;
1740         }
1741         break;
1742       }
1743       case eGpencilBatchGroupType_Edlin: {
1744         if (stl->g_data->shgrps_edit_line) {
1745           const int len = elm->vertex_idx - start_edlin;
1746           /* use always the same group */
1747           DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_line,
1748                                      cache->b_edlin.batch,
1749                                      (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
1750                                                               cache_ob->obmat,
1751                                      start_edlin,
1752                                      len);
1753
1754           start_edlin = elm->vertex_idx;
1755         }
1756         break;
1757       }
1758       default: {
1759         break;
1760       }
1761     }
1762     /* save first group */
1763     if ((shgrp != NULL) && (tag_first)) {
1764       array_elm = &cache_ob->shgrp_array[idx];
1765       array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
1766       array_elm->clamp_layer = gpl->flag & GP_LAYER_USE_MASK;
1767       array_elm->blend_opacity = gpl->opacity;
1768       array_elm->init_shgrp = shgrp;
1769       cache_ob->tot_layers++;
1770
1771       tag_first = false;
1772     }
1773   }
1774
1775   /* save last group */
1776   if (shgrp != NULL) {
1777     array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
1778     array_elm->end_shgrp = shgrp;
1779   }
1780 }
1781 /* populate a datablock for multiedit (no onions, no modifiers) */
1782 void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data,
1783                                     void *vedata,
1784                                     Object *ob,
1785                                     tGPencilObjectCache *cache_ob)
1786 {
1787   bGPdata *gpd = (bGPdata *)ob->data;
1788   bGPDframe *gpf = NULL;
1789
1790   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1791   const DRWContextState *draw_ctx = DRW_context_state_get();
1792   int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
1793   GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
1794
1795   /* check if playing animation */
1796   const bool playing = stl->storage->is_playing;
1797
1798   /* calc max size of VBOs */
1799   gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
1800
1801   /* draw strokes */
1802   for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1803     /* don't draw layer if hidden */
1804     if (gpl->flag & GP_LAYER_HIDE) {
1805       continue;
1806     }
1807
1808     /* list of frames to draw */
1809     if (!playing) {
1810       for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1811         if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
1812           gpencil_draw_strokes(cache,
1813                                e_data,
1814                                vedata,
1815                                ob,
1816                                gpd,
1817                                gpl,
1818                                gpf,
1819                                gpl->opacity,
1820                                gpl->tintcolor,
1821                                false,
1822                                cache_ob);
1823         }
1824       }
1825     }
1826     else {
1827       gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
1828       if (gpf) {
1829         gpencil_draw_strokes(cache,
1830                              e_data,
1831                              vedata,
1832                              ob,
1833                              gpd,
1834                              gpl,
1835                              gpf,
1836                              gpl->opacity,
1837                              gpl->tintcolor,
1838                              false,
1839                              cache_ob);
1840       }
1841     }
1842   }
1843
1844   /* create batchs and shading groups */
1845   DRW_gpencil_create_batches(cache);
1846   DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1847
1848   cache->is_dirty = false;
1849 }
1850
1851 /* helper for populate a complete grease pencil datablock */
1852 void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data,
1853                                     void *vedata,
1854                                     Object *ob,
1855                                     tGPencilObjectCache *cache_ob)
1856 {
1857   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1858   const DRWContextState *draw_ctx = DRW_context_state_get();
1859   const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph);
1860   Scene *scene = draw_ctx->scene;
1861
1862   /* Use original data to shared in edit/transform operators */
1863   bGPdata *gpd_eval = (bGPdata *)ob->data;
1864   bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
1865
1866   View3D *v3d = draw_ctx->v3d;
1867   int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
1868
1869   bGPDframe *derived_gpf = NULL;
1870   const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
1871   const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
1872
1873   float opacity;
1874   bGPDframe *gpf = NULL;
1875   bGPDlayer *gpl_active = BKE_gpencil_layer_getactive(gpd);
1876
1877   /* check if playing animation */
1878   const bool playing = stl->storage->is_playing;
1879
1880   GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
1881
1882   /* if object is duplicate, only create shading groups */
1883   if (cache_ob->is_dup_ob) {
1884     DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1885     return;
1886   }
1887
1888   /* calc max size of VBOs */
1889   gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
1890
1891   /* draw normal strokes */
1892   for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1893     /* don't draw layer if hidden */
1894     if (gpl->flag & GP_LAYER_HIDE) {
1895       continue;
1896     }
1897
1898     const bool is_solomode = GPENCIL_PAINT_MODE(gpd) && (!playing) && (!stl->storage->is_render) &&
1899                              (gpl->flag & GP_LAYER_SOLO_MODE);
1900
1901     /* filter view layer to gp layers in the same view layer (for compo) */
1902     if ((stl->storage->is_render) && (gpl->viewlayername[0] != '\0')) {
1903       if (!STREQ(view_layer->name, gpl->viewlayername)) {
1904         continue;
1905       }
1906     }
1907
1908     /* remap time */
1909     int remap_cfra = cfra_eval;
1910     if ((time_remap) && (!stl->storage->simplify_modif)) {
1911       remap_cfra = BKE_gpencil_time_modifier(
1912           draw_ctx->depsgraph, scene, ob, gpl, cfra_eval, stl->storage->is_render);
1913     }
1914
1915     gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
1916     if (gpf == NULL) {
1917       continue;
1918     }
1919
1920     /* if solo mode, display only frames with keyframe in the current frame */
1921     if ((is_solomode) && (gpf->framenum != remap_cfra)) {
1922       continue;
1923     }
1924
1925     opacity = gpl->opacity;
1926     /* if pose mode, maybe the overlay to fade geometry is enabled */
1927     if ((draw_ctx->obact) && (draw_ctx->object_mode == OB_MODE_POSE) &&
1928         (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT)) {
1929       opacity = opacity * v3d->overlay.xray_alpha_bone;
1930     }
1931     /* fade no active layers */
1932     if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) &&
1933         (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) && (draw_ctx->obact) &&
1934         (draw_ctx->obact == ob) && (gpl != gpl_active)) {
1935       opacity = opacity * v3d->overlay.gpencil_fade_layer;
1936     }
1937
1938     /* Get derived frames array data */
1939     int derived_idx = BLI_findindex(&gpd->layers, gpl);
1940     derived_gpf = &ob->runtime.derived_frames[derived_idx];
1941
1942     /* draw onion skins */
1943     if (!ID_IS_LINKED(&gpd->id)) {
1944       if ((gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
1945           ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) && (!cache_ob->is_dup_ob) &&
1946           (gpd->id.us <= 1)) {
1947         if ((!stl->storage->is_render) ||
1948             ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) {
1949           gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf);
1950         }
1951       }
1952     }
1953     /* draw normal strokes */
1954     gpencil_draw_strokes(cache,
1955                          e_data,
1956                          vedata,
1957                          ob,
1958                          gpd,
1959                          gpl,
1960                          derived_gpf,
1961                          opacity,
1962                          gpl->tintcolor,
1963                          false,
1964                          cache_ob);
1965   }
1966
1967   /* create batchs and shading groups */
1968   DRW_gpencil_create_batches(cache);
1969   DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1970
1971   cache->is_dirty = false;
1972 }
1973
1974 void DRW_gpencil_populate_particles(GPENCIL_e_data *e_data, GHash *gh_objects, void *vedata)
1975 {
1976   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1977
1978   /* add particles */
1979   for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
1980     tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
1981     if (cache_ob->is_dup_ob) {
1982       /* reasign duplicate objects because memory for particles is not available
1983        * and need to use the original datablock and runtime data */
1984       Object *ob = (Object *)BLI_ghash_lookup(gh_objects, cache_ob->name);
1985       if (ob) {
1986         cache_ob->ob = ob;
1987         cache_ob->gpd = (bGPdata *)ob->data;
1988         GpencilBatchCache *cache = ob->runtime.gpencil_cache;
1989         if (cache != NULL) {
1990           DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
1991         }
1992       }
1993     }
1994   }
1995 }