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