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