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