Merge branch 'master' into blender2.8
[blender.git] / source / blender / draw / engines / gpencil / gpencil_engine.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_engine.c
23  *  \ingroup draw
24  */
25 #include "DRW_engine.h"
26 #include "DRW_render.h"
27
28 #include "BKE_camera.h"
29 #include "BKE_object.h"
30 #include "BKE_paint.h"
31 #include "BKE_gpencil.h"
32 #include "BKE_shader_fx.h"
33
34 #include "DNA_gpencil_types.h"
35 #include "DNA_view3d_types.h"
36
37 #include "draw_mode_engines.h"
38
39 #include "UI_resources.h"
40
41 #include "GPU_texture.h"
42
43 #include "gpencil_engine.h"
44
45 #include "DEG_depsgraph_query.h"
46
47 #include "ED_screen.h"
48 #include "ED_gpencil.h"
49
50 #include "WM_api.h"
51
52 extern char datatoc_gpencil_fill_vert_glsl[];
53 extern char datatoc_gpencil_fill_frag_glsl[];
54 extern char datatoc_gpencil_stroke_vert_glsl[];
55 extern char datatoc_gpencil_stroke_geom_glsl[];
56 extern char datatoc_gpencil_stroke_frag_glsl[];
57 extern char datatoc_gpencil_zdepth_mix_frag_glsl[];
58 extern char datatoc_gpencil_simple_mix_frag_glsl[];
59 extern char datatoc_gpencil_point_vert_glsl[];
60 extern char datatoc_gpencil_point_geom_glsl[];
61 extern char datatoc_gpencil_point_frag_glsl[];
62 extern char datatoc_gpencil_background_frag_glsl[];
63 extern char datatoc_gpencil_paper_frag_glsl[];
64 extern char datatoc_gpencil_edit_point_vert_glsl[];
65 extern char datatoc_gpencil_edit_point_geom_glsl[];
66 extern char datatoc_gpencil_edit_point_frag_glsl[];
67 extern char datatoc_gpencil_blend_frag_glsl[];
68
69 /* *********** STATIC *********** */
70 static GPENCIL_e_data e_data = {NULL}; /* Engine data */
71
72 /* *********** FUNCTIONS *********** */
73
74 /* create a multisample buffer if not present */
75 void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h)
76 {
77         GPENCIL_FramebufferList *fbl = vedata->fbl;
78         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
79         GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
80
81         short samples = stl->storage->multisamples;
82
83         if (samples > 0) {
84                 if (!fbl->multisample_fb) {
85                         fbl->multisample_fb = GPU_framebuffer_create();
86                         if (fbl->multisample_fb) {
87                                 if (txl->multisample_color == NULL) {
88                                         txl->multisample_color = GPU_texture_create_2D_multisample(
89                                                 rect_w, rect_h, GPU_RGBA16F, NULL, samples, NULL);
90                                 }
91                                 if (txl->multisample_depth == NULL) {
92                                         txl->multisample_depth = GPU_texture_create_2D_multisample(
93                                                 rect_w, rect_h, GPU_DEPTH_COMPONENT24, NULL, samples, NULL);
94                                 }
95                                 GPU_framebuffer_ensure_config(
96                                         &fbl->multisample_fb, {
97                                             GPU_ATTACHMENT_TEXTURE(txl->multisample_depth),
98                                             GPU_ATTACHMENT_TEXTURE(txl->multisample_color)
99                                         });
100                         }
101                 }
102         }
103 }
104
105 static void GPENCIL_create_framebuffers(void *vedata)
106 {
107         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
108         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
109
110         /* Go full 32bits for rendering */
111         GPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F;
112
113         if (DRW_state_is_fbo()) {
114                 const float *viewport_size = DRW_viewport_size_get();
115                 const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] };
116
117                 /* create multiframe framebuffer for AA */
118                 if ((stl->storage->framebuffer_flag & GP_FRAMEBUFFER_MULTISAMPLE) &&
119                     (stl->storage->multisamples > 0))
120                 {
121                         DRW_gpencil_multisample_ensure(vedata, size[0], size[1]);
122                 }
123
124                 /* Framebufers for basic object drawing */
125                 if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) {
126                         /* temp textures for ping-pong buffers */
127                         e_data.temp_depth_tx_a = DRW_texture_pool_query_2D(
128                                 size[0], size[1], GPU_DEPTH_COMPONENT24,
129                                 &draw_engine_gpencil_type);
130                         e_data.temp_color_tx_a = DRW_texture_pool_query_2D(size[0], size[1], fb_format,
131                                 &draw_engine_gpencil_type);
132                         GPU_framebuffer_ensure_config(
133                                 &fbl->temp_fb_a, {
134                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a),
135                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a)
136                                 });
137
138                         e_data.temp_depth_tx_b = DRW_texture_pool_query_2D(
139                                 size[0], size[1], GPU_DEPTH_COMPONENT24,
140                                 &draw_engine_gpencil_type);
141                         e_data.temp_color_tx_b = DRW_texture_pool_query_2D(
142                                 size[0], size[1], fb_format,
143                                 &draw_engine_gpencil_type);
144                         GPU_framebuffer_ensure_config(
145                                 &fbl->temp_fb_b, {
146                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b),
147                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b)
148                                 });
149
150                         /* used for FX effects and Layer blending */
151                         e_data.temp_depth_tx_fx = DRW_texture_pool_query_2D(
152                                 size[0], size[1], GPU_DEPTH_COMPONENT24,
153                                 &draw_engine_gpencil_type);
154                         e_data.temp_color_tx_fx = DRW_texture_pool_query_2D(
155                                 size[0], size[1], fb_format,
156                                 &draw_engine_gpencil_type);
157                         GPU_framebuffer_ensure_config(
158                                 &fbl->temp_fb_fx, {
159                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_fx),
160                                         GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_fx),
161                                 });
162                 }
163
164                 /* background framebuffer to speed up drawing process (always 16 bits) */
165                 if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_DRAW) {
166                         e_data.background_depth_tx = DRW_texture_pool_query_2D(
167                                 size[0], size[1], GPU_DEPTH_COMPONENT24,
168                                 &draw_engine_gpencil_type);
169                         e_data.background_color_tx = DRW_texture_pool_query_2D(
170                                 size[0], size[1], GPU_RGBA32F,
171                                 &draw_engine_gpencil_type);
172                         GPU_framebuffer_ensure_config(
173                                 &fbl->background_fb, {
174                                         GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx),
175                                         GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx)
176                                 });
177                 }
178         }
179 }
180
181 static void GPENCIL_create_shaders(void)
182 {
183         /* normal fill shader */
184         if (!e_data.gpencil_fill_sh) {
185                 e_data.gpencil_fill_sh = DRW_shader_create(
186                         datatoc_gpencil_fill_vert_glsl, NULL,
187                         datatoc_gpencil_fill_frag_glsl, NULL);
188         }
189
190         /* normal stroke shader using geometry to display lines (line mode) */
191         if (!e_data.gpencil_stroke_sh) {
192                 e_data.gpencil_stroke_sh = DRW_shader_create(
193                         datatoc_gpencil_stroke_vert_glsl,
194                         datatoc_gpencil_stroke_geom_glsl,
195                         datatoc_gpencil_stroke_frag_glsl,
196                         NULL);
197         }
198
199         /* dot/rectangle mode for normal strokes using geometry */
200         if (!e_data.gpencil_point_sh) {
201                 e_data.gpencil_point_sh = DRW_shader_create(
202                         datatoc_gpencil_point_vert_glsl,
203                         datatoc_gpencil_point_geom_glsl,
204                         datatoc_gpencil_point_frag_glsl,
205                         NULL);
206         }
207         /* used for edit points or strokes with one point only */
208         if (!e_data.gpencil_edit_point_sh) {
209                 e_data.gpencil_edit_point_sh = DRW_shader_create(
210                         datatoc_gpencil_edit_point_vert_glsl,
211                         datatoc_gpencil_edit_point_geom_glsl,
212                         datatoc_gpencil_edit_point_frag_glsl, NULL);
213         }
214
215         /* used for edit lines for edit modes */
216         if (!e_data.gpencil_line_sh) {
217                 e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
218         }
219
220         /* used to filling during drawing */
221         if (!e_data.gpencil_drawing_fill_sh) {
222                 e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
223         }
224
225         /* full screen for mix zdepth*/
226         if (!e_data.gpencil_fullscreen_sh) {
227                 e_data.gpencil_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_zdepth_mix_frag_glsl, NULL);
228         }
229         if (!e_data.gpencil_simple_fullscreen_sh) {
230                 e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_simple_mix_frag_glsl, NULL);
231         }
232
233         /* blend */
234         if (!e_data.gpencil_blend_fullscreen_sh) {
235                 e_data.gpencil_blend_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_blend_frag_glsl, NULL);
236         }
237
238         /* shaders for use when drawing */
239         if (!e_data.gpencil_background_sh) {
240                 e_data.gpencil_background_sh = DRW_shader_create_fullscreen(datatoc_gpencil_background_frag_glsl, NULL);
241         }
242         if (!e_data.gpencil_paper_sh) {
243                 e_data.gpencil_paper_sh = DRW_shader_create_fullscreen(datatoc_gpencil_paper_frag_glsl, NULL);
244         }
245 }
246
247 void GPENCIL_engine_init(void *vedata)
248 {
249         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
250         /* init storage */
251         if (!stl->storage) {
252                 stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
253
254                 /* unit matrix */
255                 unit_m4(stl->storage->unit_matrix);
256         }
257
258         stl->storage->multisamples = U.gpencil_multisamples;
259
260         /* create shaders */
261         GPENCIL_create_shaders();
262         GPENCIL_create_fx_shaders(&e_data);
263
264         /* blank texture used if no texture defined for fill shader */
265         if (!e_data.gpencil_blank_texture) {
266                 float rect[16][16][4] = {{{0.0f}}};
267                 e_data.gpencil_blank_texture = DRW_texture_create_2D(16, 16, GPU_RGBA8, DRW_TEX_FILTER, (float *)rect);
268         }
269 }
270
271 static void GPENCIL_engine_free(void)
272 {
273         /* only free custom shaders, builtin shaders are freed in blender close */
274         DRW_SHADER_FREE_SAFE(e_data.gpencil_fill_sh);
275         DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh);
276         DRW_SHADER_FREE_SAFE(e_data.gpencil_point_sh);
277         DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
278         DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
279         DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
280         DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh);
281         DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
282         DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
283
284         DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
285
286         GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke);
287         MEM_SAFE_FREE(e_data.batch_buffer_stroke);
288
289         GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
290         MEM_SAFE_FREE(e_data.batch_buffer_fill);
291
292         GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_ctrlpoint);
293         MEM_SAFE_FREE(e_data.batch_buffer_ctrlpoint);
294
295         GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
296         MEM_SAFE_FREE(e_data.batch_grid);
297
298         /* effects */
299         GPENCIL_delete_fx_shaders(&e_data);
300 }
301
302 void GPENCIL_cache_init(void *vedata)
303 {
304         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
305         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
306         const DRWContextState *draw_ctx = DRW_context_state_get();
307         Scene *scene = draw_ctx->scene;
308         View3D *v3d = draw_ctx->v3d;
309
310         /* Special handling for when active object is GP object (e.g. for draw mode) */
311         Object *obact = draw_ctx->obact;
312         bGPdata *obact_gpd = NULL;
313         MaterialGPencilStyle *gp_style = NULL;
314
315         if (obact && (obact->type == OB_GPENCIL) && (obact->data)) {
316                 obact_gpd = (bGPdata *)obact->data;
317                 gp_style = BKE_material_gpencil_settings_get(obact, obact->actcol);
318         }
319
320         if (!stl->g_data) {
321                 /* Alloc transient pointers */
322                 stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
323                 stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */
324                 stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; /* used for drawing */
325         }
326         stl->storage->tonemapping = 0;
327
328         stl->g_data->shgrps_edit_line = NULL;
329         stl->g_data->shgrps_edit_point = NULL;
330
331         if (!stl->shgroups) {
332                 /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning.
333                  */
334                 stl->shgroups = MEM_mallocN(sizeof(GPENCIL_shgroup) * GPENCIL_MAX_SHGROUPS, "GPENCIL_shgroup");
335         }
336
337         /* init gp objects cache */
338         stl->g_data->gp_cache_used = 0;
339         stl->g_data->gp_cache_size = 0;
340         stl->g_data->gp_object_cache = NULL;
341
342         {
343                 /* Stroke pass */
344                 psl->stroke_pass = DRW_pass_create(
345                         "GPencil Stroke Pass",
346                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND);
347                 stl->storage->shgroup_id = 0;
348
349                 /* edit pass */
350                 psl->edit_pass = DRW_pass_create(
351                         "GPencil Edit Pass",
352                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
353
354                 /* detect if playing animation */
355                 if (draw_ctx->evil_C) {
356
357                         bool playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
358                         if (playing != stl->storage->is_playing) {
359                                 stl->storage->reset_cache = true;
360                         }
361                         stl->storage->is_playing = playing;
362                 }
363                 else {
364                         stl->storage->is_playing = false;
365                         stl->storage->reset_cache = false;
366                 }
367                 /* save render state */
368                 stl->storage->is_render = DRW_state_is_image_render();
369                 stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview");
370
371                 if (obact_gpd) {
372                         /* for some reason, when press play there is a delay in the animation flag check
373                          * and this produces errors. To be sure, we set cache as dirty because the frame
374                          * is changing.
375                          */
376                         if (stl->storage->is_playing == true) {
377                                 obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
378                         }
379                         /* if render, set as dirty to update all data */
380                         else if (stl->storage->is_render == true) {
381                                 obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
382                         }
383                 }
384
385                 /* save simplify flags (can change while drawing, so it's better to save) */
386                 stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing);
387                 stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing);
388                 stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing);
389                 stl->storage->simplify_blend = GP_SIMPLIFY_BLEND(scene, stl->storage->is_playing);
390
391                 /* save pixsize */
392                 stl->storage->pixsize = DRW_viewport_pixelsize_get();
393                 if ((!DRW_state_is_opengl_render()) && (stl->storage->is_render)) {
394                         stl->storage->pixsize = &stl->storage->render_pixsize;
395                 }
396
397                 /* detect if painting session */
398                 if ((obact_gpd) &&
399                     (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) &&
400                     (stl->storage->is_playing == false))
401                 {
402                         /* need the original to avoid cow overhead while drawing */
403                         bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
404                         if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
405                             (gpd_orig->runtime.sbuffer_size > 0) &&
406                             ((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0))
407                         {
408                                 stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
409                         }
410                         else {
411                                 stl->g_data->session_flag = GP_DRW_PAINT_IDLE;
412                         }
413                 }
414                 else {
415                         /* if not drawing mode */
416                         stl->g_data->session_flag = GP_DRW_PAINT_HOLD;
417                 }
418
419                 if (gp_style) {
420                         stl->storage->stroke_style = gp_style->stroke_style;
421                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
422                         if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) {
423                                 stl->storage->color_type = GPENCIL_COLOR_TEXTURE;
424                                 if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
425                                         stl->storage->color_type = GPENCIL_COLOR_PATTERN;
426                                 }
427                         }
428                 }
429                 else {
430                         stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID;
431                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
432                 }
433
434                 /* drawing buffer pass for drawing the stroke that is being drawing by the user. The data
435                  * is stored in sbuffer
436                  */
437                 psl->drawing_pass = DRW_pass_create(
438                         "GPencil Drawing Pass",
439                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
440
441                 /* full screen pass to combine the result with default framebuffer */
442                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
443                 psl->mix_pass = DRW_pass_create(
444                         "GPencil Mix Pass",
445                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
446                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
447                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
448                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
449                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
450                 DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
451
452                 /* mix pass no blend used to copy between passes. A separated pass is required
453                  * because if mix_pass is used, the acumulation of blend degrade the colors.
454                  *
455                  * This pass is used too to take the snapshot used for background_pass. This image
456                  * will be used as the background while the user is drawing.
457                  */
458                 psl->mix_pass_noblend = DRW_pass_create(
459                         "GPencil Mix Pass no blend",
460                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
461                 DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass_noblend);
462                 DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
463                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
464                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
465                 DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
466
467                 /* Painting session pass (used only to speedup while the user is drawing )
468                  * This pass is used to show the snapshot of the current grease pencil strokes captured
469                  * when the user starts to draw (see comments above).
470                  * In this way, the previous strokes don't need to be redraw and the drawing process
471                  * is far to agile.
472                  */
473                 psl->background_pass = DRW_pass_create(
474                         "GPencil Background Painting Session Pass",
475                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
476                 DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh, psl->background_pass);
477                 DRW_shgroup_call_add(background_shgrp, quad, NULL);
478                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
479                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
480
481                 /* pass for drawing paper (only if viewport)
482                  * In render, the v3d is null so the paper is disabled
483                  * The paper is way to isolate the drawing in complex scene and to have a cleaner
484                  * drawing area.
485                  */
486                 if (v3d) {
487                         psl->paper_pass = DRW_pass_create(
488                                 "GPencil Paper Pass",
489                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
490                         DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
491                         DRW_shgroup_call_add(paper_shgrp, quad, NULL);
492                         DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
493                         DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
494                 }
495
496                 /* grid pass */
497                 if (v3d) {
498                         psl->grid_pass = DRW_pass_create(
499                                 "GPencil Grid Pass",
500                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
501                         stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
502                 }
503
504                 /* blend layers pass */
505                 psl->blend_pass = DRW_pass_create(
506                         "GPencil Blend Layers Pass",
507                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
508                 DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh, psl->blend_pass);
509                 DRW_shgroup_call_add(blend_shgrp, quad, NULL);
510                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
511                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
512                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
513                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &e_data.temp_depth_tx_fx);
514                 DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
515                 DRW_shgroup_uniform_int(blend_shgrp, "clamp_layer", &stl->storage->clamp_layer, 1);
516                 DRW_shgroup_uniform_float(blend_shgrp, "blend_opacity", &stl->storage->blend_opacity, 1);
517                 DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
518
519                 /* create effects passes */
520                 if (!stl->storage->simplify_fx) {
521                         GPENCIL_create_fx_passes(psl);
522                 }
523         }
524 }
525
526 static void gpencil_add_draw_data(void *vedata, Object *ob)
527 {
528         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
529         bGPdata *gpd = (bGPdata *)ob->data;
530         const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
531
532         int i = stl->g_data->gp_cache_used - 1;
533         tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
534
535         if (!cache_ob->is_dup_ob) {
536                 /* fill shading groups */
537                 if (!is_multiedit) {
538                         DRW_gpencil_populate_datablock(&e_data, vedata, ob, cache_ob);
539                 }
540                 else {
541                         DRW_gpencil_populate_multiedit(&e_data, vedata, ob, cache_ob);
542                 }
543         }
544
545         /* FX passses */
546         cache_ob->has_fx = false;
547         if ((!stl->storage->simplify_fx) &&
548             (BKE_shaderfx_has_gpencil(ob)))
549         {
550                 cache_ob->has_fx = true;
551                 if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
552                         DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
553                 }
554         }
555
556 }
557
558 void GPENCIL_cache_populate(void *vedata, Object *ob)
559 {
560         /* object must be visible */
561         if (!DRW_object_is_visible_in_active_context(ob)) {
562                 return;
563         }
564
565         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
566         const DRWContextState *draw_ctx = DRW_context_state_get();
567         Scene *scene = draw_ctx->scene;
568         ToolSettings *ts = scene->toolsettings;
569         View3D *v3d = draw_ctx->v3d;
570
571         if (ob->type == OB_GPENCIL && ob->data) {
572                 bGPdata *gpd = (bGPdata *)ob->data;
573
574                 /* enable multisample and basic framebuffer creation */
575                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_MULTISAMPLE;
576                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_BASIC;
577
578                 /* when start/stop animation the cache must be set as dirty to reset all data */
579                 if (stl->storage->reset_cache) {
580                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
581                         stl->storage->reset_cache = false;
582                 }
583
584                 if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
585
586                         /* save gp objects for drawing later */
587                         stl->g_data->gp_object_cache = gpencil_object_cache_add(
588                                 stl->g_data->gp_object_cache, ob,
589                                 &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
590
591                         /* load drawing data */
592                         gpencil_add_draw_data(vedata, ob);
593                 }
594
595                 /* draw current painting strokes
596                 * (only if region is equal to originated paint region)
597                 */
598                 if ((draw_ctx->obact == ob) &&
599                     ((gpd->runtime.ar == NULL) || (gpd->runtime.ar == draw_ctx->ar)))
600                 {
601                         DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
602                 }
603
604                 /* grid */
605                 if ((v3d) &&
606                     ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
607                     (v3d->gp_flag & V3D_GP_SHOW_GRID) &&
608                     (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact))
609                 {
610                         GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
611                         MEM_SAFE_FREE(e_data.batch_grid);
612
613                         e_data.batch_grid = DRW_gpencil_get_grid(ob);
614
615                         /* define grid orientation */
616                         if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_VIEW) {
617                                 copy_m4_m4(stl->storage->grid_matrix, ob->obmat);
618                         }
619                         else {
620                                 /* align always to view */
621                                 invert_m4_m4(stl->storage->grid_matrix, draw_ctx->rv3d->viewmat);
622                                 /* copy ob location */
623                                 copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
624                         }
625
626                         DRW_shgroup_call_add(
627                                 stl->g_data->shgrps_grid,
628                                 e_data.batch_grid,
629                                 stl->storage->grid_matrix);
630                 }
631         }
632 }
633
634 void GPENCIL_cache_finish(void *vedata)
635 {
636         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
637
638         /* draw particles */
639         DRW_gpencil_populate_particles(&e_data, vedata);
640
641         if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
642                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_DRAW;
643         }
644
645         /* create framebuffers */
646         GPENCIL_create_framebuffers(vedata);
647
648 }
649
650 /* helper function to sort inverse gpencil objects using qsort */
651 static int gpencil_object_cache_compare_zdepth(const void *a1, const void *a2)
652 {
653         const tGPencilObjectCache *ps1 = a1, *ps2 = a2;
654
655         if (ps1->zdepth < ps2->zdepth) return 1;
656         else if (ps1->zdepth > ps2->zdepth) return -1;
657
658         return 0;
659 }
660
661 /* prepare a texture with full viewport screenshot for fast drawing */
662 static void gpencil_prepare_fast_drawing(
663         GPENCIL_StorageList *stl, DefaultFramebufferList *dfbl,
664         GPENCIL_FramebufferList *fbl, DRWPass *pass,
665         const float clearcol[4])
666 {
667         if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
668                 GPU_framebuffer_bind(fbl->background_fb);
669                 /* clean only in first loop cycle */
670                 if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) {
671                         GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f);
672                         stl->g_data->session_flag = GP_DRW_PAINT_FILLING;
673                 }
674                 /* repeat pass to fill temp texture */
675                 DRW_draw_pass(pass);
676                 /* set default framebuffer again */
677                 GPU_framebuffer_bind(dfbl->default_fb);
678         }
679 }
680
681 static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
682 {
683         /* reset all cache flags */
684         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
685                 tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
686                 bGPdata *gpd = cache_ob->gpd;
687                 gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
688
689                 /* free shgrp array */
690                 cache_ob->tot_layers = 0;
691                 MEM_SAFE_FREE(cache_ob->shgrp_array);
692         }
693
694         /* free the cache itself */
695         MEM_SAFE_FREE(stl->g_data->gp_object_cache);
696 }
697
698 static void gpencil_draw_pass_range(
699         GPENCIL_FramebufferList *fbl, GPENCIL_StorageList *stl,
700         GPENCIL_PassList *psl, GPENCIL_TextureList *txl,
701         GPUFrameBuffer *fb,
702         DRWShadingGroup *init_shgrp, DRWShadingGroup *end_shgrp, bool multi)
703 {
704         if (init_shgrp == NULL) {
705                 return;
706         }
707
708         /* previews don't use AA */
709         if ((!stl->storage->is_mat_preview) && (multi)) {
710                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
711         }
712
713         DRW_draw_pass_subset(
714                 psl->stroke_pass, init_shgrp, end_shgrp);
715
716         if ((!stl->storage->is_mat_preview) && (multi)) {
717                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
718         }
719
720 }
721
722 /* draw scene */
723 void GPENCIL_draw_scene(void *ved)
724 {
725         GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
726         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
727
728         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
729         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
730         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
731         GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
732
733         tGPencilObjectCache *cache_ob;
734         tGPencilObjectCache_shgrp *array_elm = NULL;
735         DRWShadingGroup *init_shgrp = NULL;
736         DRWShadingGroup *end_shgrp = NULL;
737
738         const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
739
740         const DRWContextState *draw_ctx = DRW_context_state_get();
741         View3D *v3d = draw_ctx->v3d;
742         Object *obact = draw_ctx->obact;
743         const bool playing = stl->storage->is_playing;
744         const bool is_render = stl->storage->is_render;
745         bGPdata *gpd_act = (obact) && (obact->type == OB_GPENCIL) ? (bGPdata *)obact->data : NULL;
746         const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd_act);
747
748         /* paper pass to display a comfortable area to draw over complex scenes with geometry */
749         if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
750                 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
751                     (v3d->gp_flag & V3D_GP_SHOW_PAPER))
752                 {
753                         DRW_draw_pass(psl->paper_pass);
754                 }
755         }
756
757         /* if we have a painting session, we use fast viewport drawing method */
758         if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) {
759                 GPU_framebuffer_bind(dfbl->default_fb);
760
761                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
762
763                 DRW_draw_pass(psl->background_pass);
764                 DRW_draw_pass(psl->drawing_pass);
765
766                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
767
768                 /* free memory */
769                 gpencil_free_obj_runtime(stl);
770
771                 /* grid pass */
772                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
773                         if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
774                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
775                         {
776                                 DRW_draw_pass(psl->grid_pass);
777                         }
778                 }
779
780                 return;
781         }
782
783         if (DRW_state_is_fbo()) {
784
785                 /* Draw all pending objects */
786                 if (stl->g_data->gp_cache_used > 0) {
787
788                         /* sort by zdepth */
789                         qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
790                               sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
791
792                         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
793                                 cache_ob = &stl->g_data->gp_object_cache[i];
794                                 bGPdata *gpd = cache_ob->gpd;
795                                 init_shgrp = NULL;
796                                 /* Render stroke in separated framebuffer */
797                                 GPU_framebuffer_bind(fbl->temp_fb_a);
798                                 GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
799
800                                 /* Stroke Pass:
801                                  * draw only a subset that usually starts with a fill and ends with stroke
802                                  */
803                                 bool use_blend = false;
804                                 if (cache_ob->tot_layers > 0) {
805                                         for (int e = 0; e < cache_ob->tot_layers; e++) {
806                                                 bool is_last = e == cache_ob->tot_layers - 1 ? true : false;
807                                                 array_elm = &cache_ob->shgrp_array[e];
808
809                                                 if (((array_elm->mode == eGplBlendMode_Normal) &&
810                                                      (!use_blend) && (!array_elm->clamp_layer)) ||
811                                                     (e == 0))
812                                                 {
813                                                         if (init_shgrp == NULL) {
814                                                                 init_shgrp = array_elm->init_shgrp;
815                                                         }
816                                                         end_shgrp = array_elm->end_shgrp;
817                                                 }
818                                                 else {
819                                                         use_blend = true;
820                                                         /* draw pending groups */
821                                                         gpencil_draw_pass_range(
822                                                                 fbl, stl, psl, txl, fbl->temp_fb_a,
823                                                                 init_shgrp, end_shgrp, is_last);
824
825                                                         /* draw current group in separated texture */
826                                                         init_shgrp = array_elm->init_shgrp;
827                                                         end_shgrp = array_elm->end_shgrp;
828
829                                                         GPU_framebuffer_bind(fbl->temp_fb_fx);
830                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
831                                                         gpencil_draw_pass_range(
832                                                                 fbl, stl, psl, txl, fbl->temp_fb_fx,
833                                                                 init_shgrp, end_shgrp,
834                                                                 is_last);
835
836                                                         /* Blend A texture and FX texture */
837                                                         GPU_framebuffer_bind(fbl->temp_fb_b);
838                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
839                                                         stl->storage->blend_mode = array_elm->mode;
840                                                         stl->storage->clamp_layer = (int)array_elm->clamp_layer;
841                                                         stl->storage->blend_opacity = array_elm->blend_opacity;
842                                                         stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
843                                                         DRW_draw_pass(psl->blend_pass);
844                                                         stl->storage->tonemapping = 0;
845
846                                                         /* Copy B texture to A texture to follow loop */
847                                                         e_data.input_depth_tx = e_data.temp_depth_tx_b;
848                                                         e_data.input_color_tx = e_data.temp_color_tx_b;
849
850                                                         GPU_framebuffer_bind(fbl->temp_fb_a);
851                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
852                                                         DRW_draw_pass(psl->mix_pass_noblend);
853
854                                                         /* prepare next group */
855                                                         init_shgrp = NULL;
856                                                 }
857
858                                         }
859                                         /* last group */
860                                         gpencil_draw_pass_range(
861                                                 fbl, stl, psl, txl, fbl->temp_fb_a,
862                                                 init_shgrp, end_shgrp,
863                                                 true);
864                                 }
865
866                                 /* Current buffer drawing */
867                                 if ((!is_render) && (cache_ob->is_dup_ob == false)) {
868                                         DRW_draw_pass(psl->drawing_pass);
869                                 }
870                                 /* fx passes */
871                                 if (cache_ob->has_fx == true) {
872                                         stl->storage->tonemapping = 0;
873                                         DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
874                                 }
875
876                                 e_data.input_depth_tx = e_data.temp_depth_tx_a;
877                                 e_data.input_color_tx = e_data.temp_color_tx_a;
878
879                                 /* Combine with scene buffer */
880                                 if ((!is_render) || (fbl->main == NULL)) {
881                                         GPU_framebuffer_bind(dfbl->default_fb);
882                                 }
883                                 else {
884                                         GPU_framebuffer_bind(fbl->main);
885                                 }
886                                 /* tonemapping */
887                                 stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
888
889                                 DRW_draw_pass(psl->mix_pass);
890
891                                 /* prepare for fast drawing */
892                                 if (!is_render) {
893                                         if (!playing) {
894                                                 gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
895                                         }
896                                 }
897                                 else {
898                                         /* if render, the cache must be dirty for next loop */
899                                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
900                                 }
901                         }
902                         /* edit points */
903                         if ((!is_render) && (!playing) && (is_edit)) {
904                                 DRW_draw_pass(psl->edit_pass);
905                         }
906                 }
907                 /* grid pass */
908                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
909                         if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
910                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
911                         {
912                                 DRW_draw_pass(psl->grid_pass);
913                         }
914                 }
915         }
916         /* free memory */
917         gpencil_free_obj_runtime(stl);
918
919         /* reset  */
920         if (DRW_state_is_fbo()) {
921                 /* attach again default framebuffer */
922                 if (!is_render) {
923                         GPU_framebuffer_bind(dfbl->default_fb);
924                 }
925
926                 /* the temp texture is ready. Now we can use fast screen drawing */
927                 if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) {
928                         stl->g_data->session_flag = GP_DRW_PAINT_READY;
929                 }
930         }
931 }
932
933 static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data);
934
935 DrawEngineType draw_engine_gpencil_type = {
936         NULL, NULL,
937         N_("GpencilMode"),
938         &GPENCIL_data_size,
939         &GPENCIL_engine_init,
940         &GPENCIL_engine_free,
941         &GPENCIL_cache_init,
942         &GPENCIL_cache_populate,
943         &GPENCIL_cache_finish,
944         NULL,
945         &GPENCIL_draw_scene,
946         NULL,
947         NULL,
948         &GPENCIL_render_to_image,
949 };