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