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