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