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