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