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