1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2017, Blender Foundation.
17  */
18 
19 /** \file
20  * \ingroup draw
21  */
22 #include "DRW_engine.h"
23 #include "DRW_render.h"
24 
25 #include "BKE_gpencil.h"
26 #include "BKE_lib_id.h"
27 #include "BKE_main.h"
28 #include "BKE_object.h"
29 #include "BKE_paint.h"
30 #include "BKE_shader_fx.h"
31 
32 #include "BKE_camera.h"
33 #include "BKE_global.h" /* for G.debug */
34 
35 #include "BLI_link_utils.h"
36 #include "BLI_listbase.h"
37 #include "BLI_memblock.h"
38 
39 #include "DNA_camera_types.h"
40 #include "DNA_gpencil_types.h"
41 #include "DNA_screen_types.h"
42 #include "DNA_view3d_types.h"
43 
44 #include "GPU_texture.h"
45 #include "GPU_uniform_buffer.h"
46 
47 #include "gpencil_engine.h"
48 
49 #include "DEG_depsgraph_query.h"
50 
51 #include "ED_screen.h"
52 #include "ED_view3d.h"
53 
54 #include "UI_resources.h"
55 
56 /* *********** FUNCTIONS *********** */
57 
GPENCIL_engine_init(void * ved)58 void GPENCIL_engine_init(void *ved)
59 {
60   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
61   GPENCIL_StorageList *stl = vedata->stl;
62   GPENCIL_TextureList *txl = vedata->txl;
63   GPENCIL_FramebufferList *fbl = vedata->fbl;
64   DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
65   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
66   const DRWContextState *ctx = DRW_context_state_get();
67   const View3D *v3d = ctx->v3d;
68 
69   if (!stl->pd) {
70     stl->pd = MEM_callocN(sizeof(GPENCIL_PrivateData), "GPENCIL_PrivateData");
71   }
72 
73   if (txl->dummy_texture == NULL) {
74     const float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}};
75     txl->dummy_texture = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, (float *)pixels);
76   }
77 
78   GPENCIL_ViewLayerData *vldata = GPENCIL_view_layer_data_ensure();
79 
80   /* Resize and reset memblocks. */
81   BLI_memblock_clear(vldata->gp_light_pool, gpencil_light_pool_free);
82   BLI_memblock_clear(vldata->gp_material_pool, gpencil_material_pool_free);
83   BLI_memblock_clear(vldata->gp_object_pool, NULL);
84   BLI_memblock_clear(vldata->gp_layer_pool, NULL);
85   BLI_memblock_clear(vldata->gp_vfx_pool, NULL);
86   BLI_memblock_clear(vldata->gp_maskbit_pool, NULL);
87 
88   stl->pd->gp_light_pool = vldata->gp_light_pool;
89   stl->pd->gp_material_pool = vldata->gp_material_pool;
90   stl->pd->gp_maskbit_pool = vldata->gp_maskbit_pool;
91   stl->pd->gp_object_pool = vldata->gp_object_pool;
92   stl->pd->gp_layer_pool = vldata->gp_layer_pool;
93   stl->pd->gp_vfx_pool = vldata->gp_vfx_pool;
94   stl->pd->view_layer = ctx->view_layer;
95   stl->pd->scene = ctx->scene;
96   stl->pd->v3d = ctx->v3d;
97   stl->pd->last_light_pool = NULL;
98   stl->pd->last_material_pool = NULL;
99   stl->pd->tobjects.first = NULL;
100   stl->pd->tobjects.last = NULL;
101   stl->pd->tobjects_infront.first = NULL;
102   stl->pd->tobjects_infront.last = NULL;
103   stl->pd->sbuffer_tobjects.first = NULL;
104   stl->pd->sbuffer_tobjects.last = NULL;
105   stl->pd->dummy_tx = txl->dummy_texture;
106   stl->pd->draw_depth_only = !DRW_state_is_fbo();
107   stl->pd->draw_wireframe = (v3d && v3d->shading.type == OB_WIRE) && !stl->pd->draw_depth_only;
108   stl->pd->scene_depth_tx = stl->pd->draw_depth_only ? txl->dummy_texture : dtxl->depth;
109   stl->pd->scene_fb = dfbl->default_fb;
110   stl->pd->is_render = txl->render_depth_tx || (v3d && v3d->shading.type == OB_RENDER);
111   stl->pd->is_viewport = (v3d != NULL);
112   stl->pd->global_light_pool = gpencil_light_pool_add(stl->pd);
113   stl->pd->shadeless_light_pool = gpencil_light_pool_add(stl->pd);
114   /* Small HACK: we don't want the global pool to be reused,
115    * so we set the last light pool to NULL. */
116   stl->pd->last_light_pool = NULL;
117 
118   bool use_scene_lights = false;
119   bool use_scene_world = false;
120 
121   if (v3d) {
122     use_scene_lights = ((v3d->shading.type == OB_MATERIAL) &&
123                         (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) ||
124                        ((v3d->shading.type == OB_RENDER) &&
125                         (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER));
126 
127     use_scene_world = ((v3d->shading.type == OB_MATERIAL) &&
128                        (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) ||
129                       ((v3d->shading.type == OB_RENDER) &&
130                        (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER));
131 
132     stl->pd->v3d_color_type = (v3d->shading.type == OB_SOLID) ? v3d->shading.color_type : -1;
133     /* Special case: If Vertex Paint mode, use always Vertex mode. */
134     if (v3d->shading.type == OB_SOLID && ctx->obact && ctx->obact->type == OB_GPENCIL &&
135         ctx->obact->mode == OB_MODE_VERTEX_GPENCIL) {
136       stl->pd->v3d_color_type = V3D_SHADING_VERTEX_COLOR;
137     }
138 
139     copy_v3_v3(stl->pd->v3d_single_color, v3d->shading.single_color);
140 
141     /* For non active frame, use only lines in multiedit mode. */
142     const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
143     stl->pd->use_multiedit_lines_only = !overlays_on ||
144                                         (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) != 0;
145 
146     const bool shmode_xray_support = v3d->shading.type <= OB_SOLID;
147     stl->pd->xray_alpha = (shmode_xray_support && XRAY_ENABLED(v3d)) ? XRAY_ALPHA(v3d) : 1.0f;
148   }
149   else if (stl->pd->is_render) {
150     use_scene_lights = true;
151     use_scene_world = true;
152     stl->pd->use_multiedit_lines_only = false;
153     stl->pd->xray_alpha = 1.0f;
154     stl->pd->v3d_color_type = -1;
155   }
156 
157   stl->pd->use_lighting = (v3d && v3d->shading.type > OB_SOLID) || stl->pd->is_render;
158   stl->pd->use_lights = use_scene_lights;
159 
160   if (txl->render_depth_tx != NULL) {
161     stl->pd->scene_depth_tx = txl->render_depth_tx;
162     stl->pd->scene_fb = fbl->render_fb;
163   }
164 
165   gpencil_light_ambient_add(stl->pd->shadeless_light_pool, (float[3]){1.0f, 1.0f, 1.0f});
166 
167   World *world = ctx->scene->world;
168   if (world != NULL && use_scene_world) {
169     gpencil_light_ambient_add(stl->pd->global_light_pool, &world->horr);
170   }
171   else if (v3d) {
172     float world_light[3];
173     copy_v3_fl(world_light, v3d->shading.studiolight_intensity);
174     gpencil_light_ambient_add(stl->pd->global_light_pool, world_light);
175   }
176 
177   float viewmatinv[4][4];
178   DRW_view_viewmat_get(NULL, viewmatinv, true);
179   copy_v3_v3(stl->pd->camera_z_axis, viewmatinv[2]);
180   copy_v3_v3(stl->pd->camera_pos, viewmatinv[3]);
181   stl->pd->camera_z_offset = dot_v3v3(viewmatinv[3], viewmatinv[2]);
182 
183   if (ctx && ctx->rv3d && v3d) {
184     stl->pd->camera = (ctx->rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL;
185   }
186   else {
187     stl->pd->camera = NULL;
188   }
189 }
190 
GPENCIL_cache_init(void * ved)191 void GPENCIL_cache_init(void *ved)
192 {
193   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
194   GPENCIL_PassList *psl = vedata->psl;
195   GPENCIL_TextureList *txl = vedata->txl;
196   GPENCIL_FramebufferList *fbl = vedata->fbl;
197   GPENCIL_PrivateData *pd = vedata->stl->pd;
198   DRWShadingGroup *grp;
199 
200   const DRWContextState *draw_ctx = DRW_context_state_get();
201   pd->cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
202   pd->simplify_antialias = GPENCIL_SIMPLIFY_AA(draw_ctx->scene);
203   pd->use_layer_fb = false;
204   pd->use_object_fb = false;
205   pd->use_mask_fb = false;
206   /* Always use high precision for render. */
207   pd->use_signed_fb = !pd->is_viewport;
208 
209   if (draw_ctx->v3d) {
210     const bool hide_overlay = ((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) != 0);
211     const bool show_onion = ((draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) != 0);
212     const bool playing = (draw_ctx->evil_C != NULL) ?
213                              ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) !=
214                                  NULL :
215                              false;
216     pd->do_onion = show_onion && !hide_overlay && !playing;
217     /* Save simplify flags (can change while drawing, so it's better to save). */
218     Scene *scene = draw_ctx->scene;
219     pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, playing);
220     pd->simplify_fx = GPENCIL_SIMPLIFY_FX(scene, playing) ||
221                       (draw_ctx->v3d->shading.type < OB_RENDER);
222 
223     /* Fade Layer. */
224     const bool is_fade_layer = ((!hide_overlay) && (!pd->is_render) &&
225                                 (draw_ctx->v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS));
226     pd->fade_layer_opacity = (is_fade_layer) ? draw_ctx->v3d->overlay.gpencil_fade_layer : -1.0f;
227     pd->vertex_paint_opacity = draw_ctx->v3d->overlay.gpencil_vertex_paint_opacity;
228     /* Fade GPencil Objects. */
229     const bool is_fade_object = ((!hide_overlay) && (!pd->is_render) &&
230                                  (draw_ctx->v3d->gp_flag & V3D_GP_FADE_OBJECTS) &&
231                                  (draw_ctx->v3d->gp_flag & V3D_GP_FADE_NOACTIVE_GPENCIL));
232     pd->fade_gp_object_opacity = (is_fade_object) ? draw_ctx->v3d->overlay.gpencil_paper_opacity :
233                                                     -1.0f;
234     pd->fade_3d_object_opacity = ((!hide_overlay) && (!pd->is_render) &&
235                                   (draw_ctx->v3d->gp_flag & V3D_GP_FADE_OBJECTS)) ?
236                                      draw_ctx->v3d->overlay.gpencil_paper_opacity :
237                                      -1.0f;
238   }
239   else {
240     pd->do_onion = true;
241     pd->simplify_fill = false;
242     pd->simplify_fx = false;
243     pd->fade_layer_opacity = -1.0f;
244   }
245 
246   {
247     pd->sbuffer_stroke = NULL;
248     pd->sbuffer_gpd = NULL;
249     pd->sbuffer_layer = NULL;
250     pd->stroke_batch = NULL;
251     pd->fill_batch = NULL;
252     pd->do_fast_drawing = false;
253 
254     pd->obact = draw_ctx->obact;
255     if (pd->obact && pd->obact->type == OB_GPENCIL) {
256       /* Check if active object has a temp stroke data. */
257       bGPdata *gpd = (bGPdata *)pd->obact->data;
258       if (gpd->runtime.sbuffer_used > 0) {
259         pd->sbuffer_gpd = gpd;
260         pd->sbuffer_stroke = DRW_cache_gpencil_sbuffer_stroke_data_get(pd->obact);
261         pd->sbuffer_layer = BKE_gpencil_layer_active_get(pd->sbuffer_gpd);
262         pd->do_fast_drawing = false; /* TODO option */
263       }
264     }
265   }
266 
267   if (pd->do_fast_drawing) {
268     pd->snapshot_buffer_dirty = (txl->snapshot_color_tx == NULL);
269     const float *size = DRW_viewport_size_get();
270     DRW_texture_ensure_2d(&txl->snapshot_depth_tx, size[0], size[1], GPU_DEPTH24_STENCIL8, 0);
271     DRW_texture_ensure_2d(&txl->snapshot_color_tx, size[0], size[1], GPU_R11F_G11F_B10F, 0);
272     DRW_texture_ensure_2d(&txl->snapshot_reveal_tx, size[0], size[1], GPU_R11F_G11F_B10F, 0);
273 
274     GPU_framebuffer_ensure_config(&fbl->snapshot_fb,
275                                   {
276                                       GPU_ATTACHMENT_TEXTURE(txl->snapshot_depth_tx),
277                                       GPU_ATTACHMENT_TEXTURE(txl->snapshot_color_tx),
278                                       GPU_ATTACHMENT_TEXTURE(txl->snapshot_reveal_tx),
279                                   });
280   }
281   else {
282     /* Free uneeded buffers. */
283     GPU_FRAMEBUFFER_FREE_SAFE(fbl->snapshot_fb);
284     DRW_TEXTURE_FREE_SAFE(txl->snapshot_depth_tx);
285     DRW_TEXTURE_FREE_SAFE(txl->snapshot_color_tx);
286     DRW_TEXTURE_FREE_SAFE(txl->snapshot_reveal_tx);
287   }
288 
289   {
290     DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
291     DRW_PASS_CREATE(psl->merge_depth_ps, state);
292 
293     GPUShader *sh = GPENCIL_shader_depth_merge_get();
294     grp = DRW_shgroup_create(sh, psl->merge_depth_ps);
295     DRW_shgroup_uniform_texture_ref(grp, "depthBuf", &pd->depth_tx);
296     DRW_shgroup_uniform_bool(grp, "strokeOrder3d", &pd->is_stroke_order_3d, 1);
297     DRW_shgroup_uniform_vec4(grp, "gpModelMatrix", pd->object_bound_mat[0], 4);
298     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
299   }
300   {
301     DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_LOGIC_INVERT;
302     DRW_PASS_CREATE(psl->mask_invert_ps, state);
303 
304     GPUShader *sh = GPENCIL_shader_mask_invert_get();
305     grp = DRW_shgroup_create(sh, psl->mask_invert_ps);
306     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
307   }
308 
309   Camera *cam = (pd->camera != NULL) ? pd->camera->data : NULL;
310 
311   /* Pseudo DOF setup. */
312   if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
313     const float *vp_size = DRW_viewport_size_get();
314     float fstop = cam->dof.aperture_fstop;
315     float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
316     float focus_dist = BKE_camera_object_dof_distance(pd->camera);
317     float focal_len = cam->lens;
318 
319     const float scale_camera = 0.001f;
320     /* we want radius here for the aperture number  */
321     float aperture = 0.5f * scale_camera * focal_len / fstop;
322     float focal_len_scaled = scale_camera * focal_len;
323     float sensor_scaled = scale_camera * sensor;
324 
325     if (draw_ctx->rv3d != NULL) {
326       sensor_scaled *= draw_ctx->rv3d->viewcamtexcofac[0];
327     }
328 
329     pd->dof_params[1] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
330     pd->dof_params[1] *= vp_size[0] / sensor_scaled;
331     pd->dof_params[0] = -focus_dist * pd->dof_params[1];
332   }
333   else {
334     /* Disable DoF blur scalling. */
335     pd->camera = NULL;
336   }
337 }
338 
339 #define DRAW_NOW 2
340 
341 typedef struct gpIterPopulateData {
342   Object *ob;
343   GPENCIL_tObject *tgp_ob;
344   GPENCIL_PrivateData *pd;
345   GPENCIL_MaterialPool *matpool;
346   DRWShadingGroup *grp;
347   /* Last material UBO bound. Used to avoid uneeded buffer binding. */
348   GPUUniformBuf *ubo_mat;
349   GPUUniformBuf *ubo_lights;
350   /* Last texture bound. */
351   GPUTexture *tex_fill;
352   GPUTexture *tex_stroke;
353   /* Offset in the material pool to the first material of this object. */
354   int mat_ofs;
355   /* Is the sbuffer call need to be issued. */
356   int do_sbuffer_call;
357   /* Indices to do correct insertion of the sbuffer stroke. */
358   int stroke_index_last;
359   int stroke_index_offset;
360   /* Infos for call batching. */
361   struct GPUBatch *geom;
362   bool instancing;
363   int vfirst, vcount;
364 } gpIterPopulateData;
365 
366 #define DISABLE_BATCHING 0
367 
gpencil_drawcall_flush(gpIterPopulateData * iter)368 static void gpencil_drawcall_flush(gpIterPopulateData *iter)
369 {
370 #if !DISABLE_BATCHING
371   if (iter->geom != NULL) {
372     if (iter->instancing) {
373       DRW_shgroup_call_instance_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
374     }
375     else {
376       DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
377     }
378   }
379 #endif
380 
381   iter->geom = NULL;
382   iter->vfirst = -1;
383   iter->vcount = 0;
384 }
385 
386 /* Group drawcalls that are consecutive and with the same type. Reduces GPU driver overhead. */
gpencil_drawcall_add(gpIterPopulateData * iter,struct GPUBatch * geom,bool instancing,int v_first,int v_count)387 static void gpencil_drawcall_add(
388     gpIterPopulateData *iter, struct GPUBatch *geom, bool instancing, int v_first, int v_count)
389 {
390 #if DISABLE_BATCHING
391   if (instancing) {
392     DRW_shgroup_call_instance_range(iter->grp, iter->ob, geom, v_first, v_count);
393   }
394   else {
395     DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
396   }
397 #endif
398 
399   int last = iter->vfirst + iter->vcount;
400   /* Interupt drawcall grouping if the sequence is not consecutive. */
401   if ((geom != iter->geom) || (v_first - last > 3)) {
402     gpencil_drawcall_flush(iter);
403   }
404   iter->geom = geom;
405   iter->instancing = instancing;
406   if (iter->vfirst == -1) {
407     iter->vfirst = v_first;
408   }
409   iter->vcount = v_first + v_count - iter->vfirst;
410 }
411 
412 static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
413                                           bGPDframe *gpf,
414                                           bGPDstroke *gps,
415                                           void *thunk);
416 
gpencil_sbuffer_cache_populate(gpIterPopulateData * iter)417 static void gpencil_sbuffer_cache_populate(gpIterPopulateData *iter)
418 {
419   iter->do_sbuffer_call = DRAW_NOW;
420   /* In order to draw the sbuffer stroke correctly mixed with other strokes,
421    * we need to offset the stroke index of the sbuffer stroke and the subsequent strokes.
422    * Remember, sbuffer stroke indices start from 0. So we add last index to avoid
423    * masking issues. */
424   iter->grp = DRW_shgroup_create_sub(iter->grp);
425   DRW_shgroup_uniform_block(iter->grp, "gpMaterialBlock", iter->ubo_mat);
426   DRW_shgroup_uniform_float_copy(iter->grp, "strokeIndexOffset", iter->stroke_index_last);
427 
428   const DRWContextState *ctx = DRW_context_state_get();
429   ToolSettings *ts = ctx->scene->toolsettings;
430   if (ts->gpencil_v3d_align & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)) {
431     /* In this case we can't do correct projection during stroke. We just disable depth test. */
432     DRW_shgroup_uniform_texture(iter->grp, "gpSceneDepthTexture", iter->pd->dummy_tx);
433   }
434 
435   gpencil_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, iter);
436   gpencil_drawcall_flush(iter);
437 
438   iter->stroke_index_offset = iter->pd->sbuffer_stroke->totpoints + 1;
439   iter->do_sbuffer_call = 0;
440 }
441 
gpencil_layer_cache_populate(bGPDlayer * gpl,bGPDframe * gpf,bGPDstroke * UNUSED (gps),void * thunk)442 static void gpencil_layer_cache_populate(bGPDlayer *gpl,
443                                          bGPDframe *gpf,
444                                          bGPDstroke *UNUSED(gps),
445                                          void *thunk)
446 {
447   gpIterPopulateData *iter = (gpIterPopulateData *)thunk;
448   GPENCIL_PrivateData *pd = iter->pd;
449   bGPdata *gpd = (bGPdata *)iter->ob->data;
450 
451   gpencil_drawcall_flush(iter);
452 
453   if (iter->do_sbuffer_call) {
454     gpencil_sbuffer_cache_populate(iter);
455   }
456   else {
457     iter->do_sbuffer_call = !pd->do_fast_drawing && (gpd == pd->sbuffer_gpd) &&
458                             (gpl == pd->sbuffer_layer) &&
459                             (gpf == NULL || gpf->runtime.onion_id == 0.0f);
460   }
461 
462   GPENCIL_tLayer *tgp_layer = gpencil_layer_cache_add(pd, iter->ob, gpl, gpf, iter->tgp_ob);
463 
464   const bool use_lights = pd->use_lighting && ((gpl->flag & GP_LAYER_USE_LIGHTS) != 0) &&
465                           (iter->ob->dtx & OB_USE_GPENCIL_LIGHTS);
466 
467   iter->ubo_lights = (use_lights) ? pd->global_light_pool->ubo : pd->shadeless_light_pool->ubo;
468 
469   gpencil_material_resources_get(iter->matpool, 0, NULL, NULL, &iter->ubo_mat);
470 
471   /* Iterator dependent uniforms. */
472   DRWShadingGroup *grp = iter->grp = tgp_layer->base_shgrp;
473   DRW_shgroup_uniform_block(grp, "gpLightBlock", iter->ubo_lights);
474   DRW_shgroup_uniform_block(grp, "gpMaterialBlock", iter->ubo_mat);
475   DRW_shgroup_uniform_texture(grp, "gpFillTexture", iter->tex_fill);
476   DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", iter->tex_stroke);
477   DRW_shgroup_uniform_int_copy(grp, "gpMaterialOffset", iter->mat_ofs);
478   DRW_shgroup_uniform_float_copy(grp, "strokeIndexOffset", iter->stroke_index_offset);
479 }
480 
gpencil_stroke_cache_populate(bGPDlayer * gpl,bGPDframe * gpf,bGPDstroke * gps,void * thunk)481 static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
482                                           bGPDframe *gpf,
483                                           bGPDstroke *gps,
484                                           void *thunk)
485 {
486   gpIterPopulateData *iter = (gpIterPopulateData *)thunk;
487 
488   MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(iter->ob, gps->mat_nr + 1);
489 
490   const bool is_render = iter->pd->is_render;
491   bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
492   bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0) ||
493                      (!is_render && ((gps->flag & GP_STROKE_NOFILL) != 0));
494   bool show_fill = (gps->tot_triangles > 0) && ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0) &&
495                    (!iter->pd->simplify_fill) && ((gps->flag & GP_STROKE_NOFILL) == 0);
496 
497   bool only_lines = gpl && gpf && gpl->actframe != gpf && iter->pd->use_multiedit_lines_only;
498   bool hide_onion = gpl && gpf && gpf->runtime.onion_id != 0 &&
499                     ((gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN) != 0);
500 
501   if (hide_material || (!show_stroke && !show_fill) || only_lines || hide_onion) {
502     return;
503   }
504 
505   GPUUniformBuf *ubo_mat;
506   GPUTexture *tex_stroke, *tex_fill;
507   gpencil_material_resources_get(
508       iter->matpool, iter->mat_ofs + gps->mat_nr, &tex_stroke, &tex_fill, &ubo_mat);
509 
510   bool resource_changed = (iter->ubo_mat != ubo_mat) ||
511                           (tex_fill && (iter->tex_fill != tex_fill)) ||
512                           (tex_stroke && (iter->tex_stroke != tex_stroke));
513 
514   if (resource_changed) {
515     gpencil_drawcall_flush(iter);
516 
517     iter->grp = DRW_shgroup_create_sub(iter->grp);
518     if (iter->ubo_mat != ubo_mat) {
519       DRW_shgroup_uniform_block(iter->grp, "gpMaterialBlock", ubo_mat);
520       iter->ubo_mat = ubo_mat;
521     }
522     if (tex_fill) {
523       DRW_shgroup_uniform_texture(iter->grp, "gpFillTexture", tex_fill);
524       iter->tex_fill = tex_fill;
525     }
526     if (tex_stroke) {
527       DRW_shgroup_uniform_texture(iter->grp, "gpStrokeTexture", tex_stroke);
528       iter->tex_stroke = tex_stroke;
529     }
530   }
531 
532   bool do_sbuffer = (iter->do_sbuffer_call == DRAW_NOW);
533 
534   if (show_fill) {
535     GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_fill_get(iter->ob) :
536                                   DRW_cache_gpencil_fills_get(iter->ob, iter->pd->cfra);
537     int vfirst = gps->runtime.fill_start * 3;
538     int vcount = gps->tot_triangles * 3;
539     gpencil_drawcall_add(iter, geom, false, vfirst, vcount);
540   }
541 
542   if (show_stroke) {
543     GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_stroke_get(iter->ob) :
544                                   DRW_cache_gpencil_strokes_get(iter->ob, iter->pd->cfra);
545     /* Start one vert before to have gl_InstanceID > 0 (see shader). */
546     int vfirst = gps->runtime.stroke_start - 1;
547     /* Include "potential" cyclic vertex and start adj vertex (see shader). */
548     int vcount = gps->totpoints + 1 + 1;
549     gpencil_drawcall_add(iter, geom, true, vfirst, vcount);
550   }
551 
552   iter->stroke_index_last = gps->runtime.stroke_start + gps->totpoints + 1;
553 }
554 
gpencil_sbuffer_cache_populate_fast(GPENCIL_Data * vedata,gpIterPopulateData * iter)555 static void gpencil_sbuffer_cache_populate_fast(GPENCIL_Data *vedata, gpIterPopulateData *iter)
556 {
557   bGPdata *gpd = (bGPdata *)iter->ob->data;
558   if (gpd != iter->pd->sbuffer_gpd) {
559     return;
560   }
561 
562   GPENCIL_TextureList *txl = vedata->txl;
563   GPUTexture *depth_texture = iter->pd->scene_depth_tx;
564   GPENCIL_tObject *last_tgp_ob = iter->pd->tobjects.last;
565   /* Create another temp object that only contain the stroke. */
566   iter->tgp_ob = gpencil_object_cache_add(iter->pd, iter->ob);
567   /* Remove from the main list. */
568   iter->pd->tobjects.last = last_tgp_ob;
569   last_tgp_ob->next = NULL;
570   /* Add to sbuffer tgpobject list. */
571   BLI_LINKS_APPEND(&iter->pd->sbuffer_tobjects, iter->tgp_ob);
572   /* Remove depth test with scene (avoid self occlusion). */
573   iter->pd->scene_depth_tx = txl->dummy_texture;
574 
575   gpencil_layer_cache_populate(
576       iter->pd->sbuffer_layer, iter->pd->sbuffer_layer->actframe, NULL, iter);
577 
578   const DRWContextState *ctx = DRW_context_state_get();
579   ToolSettings *ts = ctx->scene->toolsettings;
580   if (ts->gpencil_v3d_align & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)) {
581     /* In this case we can't do correct projection during stroke. We just disable depth test. */
582     DRW_shgroup_uniform_texture(iter->grp, "gpSceneDepthTexture", iter->pd->dummy_tx);
583   }
584 
585   iter->do_sbuffer_call = DRAW_NOW;
586   gpencil_stroke_cache_populate(NULL, NULL, iter->pd->sbuffer_stroke, iter);
587   gpencil_drawcall_flush(iter);
588 
589   gpencil_vfx_cache_populate(vedata, iter->ob, iter->tgp_ob);
590 
591   /* Restore state. */
592   iter->do_sbuffer_call = 0;
593   iter->pd->scene_depth_tx = depth_texture;
594 }
595 
GPENCIL_cache_populate(void * ved,Object * ob)596 void GPENCIL_cache_populate(void *ved, Object *ob)
597 {
598   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
599   GPENCIL_PrivateData *pd = vedata->stl->pd;
600   GPENCIL_TextureList *txl = vedata->txl;
601   const bool is_final_render = DRW_state_is_image_render();
602 
603   /* object must be visible */
604   if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
605     return;
606   }
607 
608   if (ob->data && (ob->type == OB_GPENCIL) && (ob->dt >= OB_SOLID)) {
609     gpIterPopulateData iter = {0};
610     iter.ob = ob;
611     iter.pd = pd;
612     iter.tgp_ob = gpencil_object_cache_add(pd, ob);
613     iter.matpool = gpencil_material_pool_create(pd, ob, &iter.mat_ofs);
614     iter.tex_fill = txl->dummy_texture;
615     iter.tex_stroke = txl->dummy_texture;
616 
617     /* Special case for rendering onion skin. */
618     bGPdata *gpd = (bGPdata *)ob->data;
619     bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
620 
621     BKE_gpencil_visible_stroke_iter(is_final_render ? pd->view_layer : NULL,
622                                     ob,
623                                     gpencil_layer_cache_populate,
624                                     gpencil_stroke_cache_populate,
625                                     &iter,
626                                     do_onion,
627                                     pd->cfra);
628 
629     gpencil_drawcall_flush(&iter);
630 
631     if (iter.do_sbuffer_call) {
632       gpencil_sbuffer_cache_populate(&iter);
633     }
634 
635     gpencil_vfx_cache_populate(vedata, ob, iter.tgp_ob);
636 
637     if (pd->do_fast_drawing) {
638       gpencil_sbuffer_cache_populate_fast(vedata, &iter);
639     }
640   }
641 
642   if (ob->type == OB_LAMP && pd->use_lights) {
643     gpencil_light_pool_populate(pd->global_light_pool, ob);
644   }
645 }
646 
GPENCIL_cache_finish(void * ved)647 void GPENCIL_cache_finish(void *ved)
648 {
649   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
650   GPENCIL_PrivateData *pd = vedata->stl->pd;
651   GPENCIL_FramebufferList *fbl = vedata->fbl;
652 
653   /* Upload UBO data. */
654   BLI_memblock_iter iter;
655   BLI_memblock_iternew(pd->gp_material_pool, &iter);
656   GPENCIL_MaterialPool *pool;
657   while ((pool = (GPENCIL_MaterialPool *)BLI_memblock_iterstep(&iter))) {
658     GPU_uniformbuf_update(pool->ubo, pool->mat_data);
659   }
660 
661   BLI_memblock_iternew(pd->gp_light_pool, &iter);
662   GPENCIL_LightPool *lpool;
663   while ((lpool = (GPENCIL_LightPool *)BLI_memblock_iterstep(&iter))) {
664     GPU_uniformbuf_update(lpool->ubo, lpool->light_data);
665   }
666 
667   /* Sort object by decreasing Z to avoid most of alpha ordering issues. */
668   gpencil_object_cache_sort(pd);
669 
670   /* Create framebuffers only if needed. */
671   if (pd->tobjects.first) {
672     eGPUTextureFormat format = pd->use_signed_fb ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
673 
674     const float *size = DRW_viewport_size_get();
675     pd->depth_tx = DRW_texture_pool_query_2d(
676         size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
677     pd->color_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type);
678     pd->reveal_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type);
679 
680     GPU_framebuffer_ensure_config(&fbl->gpencil_fb,
681                                   {
682                                       GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
683                                       GPU_ATTACHMENT_TEXTURE(pd->color_tx),
684                                       GPU_ATTACHMENT_TEXTURE(pd->reveal_tx),
685                                   });
686 
687     if (pd->use_layer_fb) {
688       pd->color_layer_tx = DRW_texture_pool_query_2d(
689           size[0], size[1], format, &draw_engine_gpencil_type);
690       pd->reveal_layer_tx = DRW_texture_pool_query_2d(
691           size[0], size[1], format, &draw_engine_gpencil_type);
692 
693       GPU_framebuffer_ensure_config(&fbl->layer_fb,
694                                     {
695                                         GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
696                                         GPU_ATTACHMENT_TEXTURE(pd->color_layer_tx),
697                                         GPU_ATTACHMENT_TEXTURE(pd->reveal_layer_tx),
698                                     });
699     }
700 
701     if (pd->use_object_fb) {
702       pd->color_object_tx = DRW_texture_pool_query_2d(
703           size[0], size[1], format, &draw_engine_gpencil_type);
704       pd->reveal_object_tx = DRW_texture_pool_query_2d(
705           size[0], size[1], format, &draw_engine_gpencil_type);
706 
707       GPU_framebuffer_ensure_config(&fbl->object_fb,
708                                     {
709                                         GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
710                                         GPU_ATTACHMENT_TEXTURE(pd->color_object_tx),
711                                         GPU_ATTACHMENT_TEXTURE(pd->reveal_object_tx),
712                                     });
713     }
714 
715     if (pd->use_mask_fb) {
716       /* We need an extra depth to not disturb the normal drawing.
717        * The color_tx is needed for frame-buffer completeness. */
718       GPUTexture *color_tx, *depth_tx;
719       depth_tx = DRW_texture_pool_query_2d(
720           size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
721       color_tx = DRW_texture_pool_query_2d(size[0], size[1], GPU_R8, &draw_engine_gpencil_type);
722       /* Use high quality format for render. */
723       eGPUTextureFormat mask_format = pd->is_render ? GPU_R16 : GPU_R8;
724       pd->mask_tx = DRW_texture_pool_query_2d(
725           size[0], size[1], mask_format, &draw_engine_gpencil_type);
726 
727       GPU_framebuffer_ensure_config(&fbl->mask_fb,
728                                     {
729                                         GPU_ATTACHMENT_TEXTURE(depth_tx),
730                                         GPU_ATTACHMENT_TEXTURE(color_tx),
731                                         GPU_ATTACHMENT_TEXTURE(pd->mask_tx),
732                                     });
733     }
734 
735     GPENCIL_antialiasing_init(vedata);
736   }
737 }
738 
GPENCIL_draw_scene_depth_only(void * ved)739 static void GPENCIL_draw_scene_depth_only(void *ved)
740 {
741   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
742   GPENCIL_PrivateData *pd = vedata->stl->pd;
743   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
744 
745   if (DRW_state_is_fbo()) {
746     GPU_framebuffer_bind(dfbl->depth_only_fb);
747   }
748 
749   LISTBASE_FOREACH (GPENCIL_tObject *, ob, &pd->tobjects) {
750     LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
751       DRW_draw_pass(layer->geom_ps);
752     }
753   }
754 
755   if (DRW_state_is_fbo()) {
756     GPU_framebuffer_bind(dfbl->default_fb);
757   }
758 
759   pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = NULL;
760 
761   /* Free temp stroke buffers. */
762   if (pd->sbuffer_gpd) {
763     DRW_cache_gpencil_sbuffer_clear(pd->obact);
764   }
765 }
766 
gpencil_draw_mask(GPENCIL_Data * vedata,GPENCIL_tObject * ob,GPENCIL_tLayer * layer)767 static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL_tLayer *layer)
768 {
769   GPENCIL_PassList *psl = vedata->psl;
770   GPENCIL_FramebufferList *fbl = vedata->fbl;
771   const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
772   float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f;
773   bool inverted = false;
774   /* OPTI(fclem) we could optimize by only clearing if the new mask_bits does not contain all
775    * the masks already rendered in the buffer, and drawing only the layers not already drawn. */
776   bool cleared = false;
777 
778   DRW_stats_group_start("GPencil Mask");
779 
780   GPU_framebuffer_bind(fbl->mask_fb);
781 
782   for (int i = 0; i < GP_MAX_MASKBITS; i++) {
783     if (!BLI_BITMAP_TEST(layer->mask_bits, i)) {
784       continue;
785     }
786 
787     if (BLI_BITMAP_TEST_BOOL(layer->mask_invert_bits, i) != inverted) {
788       if (cleared) {
789         DRW_draw_pass(psl->mask_invert_ps);
790       }
791       inverted = !inverted;
792     }
793 
794     if (!cleared) {
795       cleared = true;
796       GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth);
797     }
798 
799     GPENCIL_tLayer *mask_layer = gpencil_layer_cache_get(ob, i);
800     BLI_assert(mask_layer);
801 
802     DRW_draw_pass(mask_layer->geom_ps);
803   }
804 
805   if (!inverted) {
806     /* Blend shader expect an opacity mask not a reavealage buffer. */
807     DRW_draw_pass(psl->mask_invert_ps);
808   }
809 
810   DRW_stats_group_end();
811 }
812 
GPENCIL_draw_object(GPENCIL_Data * vedata,GPENCIL_tObject * ob)813 static void GPENCIL_draw_object(GPENCIL_Data *vedata, GPENCIL_tObject *ob)
814 {
815   GPENCIL_PassList *psl = vedata->psl;
816   GPENCIL_PrivateData *pd = vedata->stl->pd;
817   GPENCIL_FramebufferList *fbl = vedata->fbl;
818   const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
819 
820   DRW_stats_group_start("GPencil Object");
821 
822   GPUFrameBuffer *fb_object = (ob->vfx.first) ? fbl->object_fb : fbl->gpencil_fb;
823 
824   GPU_framebuffer_bind(fb_object);
825   GPU_framebuffer_clear_depth_stencil(fb_object, ob->is_drawmode3d ? 1.0f : 0.0f, 0x00);
826 
827   if (ob->vfx.first) {
828     GPU_framebuffer_multi_clear(fb_object, clear_cols);
829   }
830 
831   LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
832     if (layer->mask_bits) {
833       gpencil_draw_mask(vedata, ob, layer);
834     }
835 
836     if (layer->blend_ps) {
837       GPU_framebuffer_bind(fbl->layer_fb);
838       GPU_framebuffer_multi_clear(fbl->layer_fb, clear_cols);
839     }
840     else {
841       GPU_framebuffer_bind(fb_object);
842     }
843 
844     DRW_draw_pass(layer->geom_ps);
845 
846     if (layer->blend_ps) {
847       GPU_framebuffer_bind(fb_object);
848       DRW_draw_pass(layer->blend_ps);
849     }
850   }
851 
852   LISTBASE_FOREACH (GPENCIL_tVfx *, vfx, &ob->vfx) {
853     GPU_framebuffer_bind(*(vfx->target_fb));
854     DRW_draw_pass(vfx->vfx_ps);
855   }
856 
857   copy_m4_m4(pd->object_bound_mat, ob->plane_mat);
858   pd->is_stroke_order_3d = ob->is_drawmode3d;
859 
860   if (pd->scene_fb) {
861     GPU_framebuffer_bind(pd->scene_fb);
862     DRW_draw_pass(psl->merge_depth_ps);
863   }
864 
865   DRW_stats_group_end();
866 }
867 
GPENCIL_fast_draw_start(GPENCIL_Data * vedata)868 static void GPENCIL_fast_draw_start(GPENCIL_Data *vedata)
869 {
870   GPENCIL_PrivateData *pd = vedata->stl->pd;
871   GPENCIL_FramebufferList *fbl = vedata->fbl;
872   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
873 
874   if (!pd->snapshot_buffer_dirty) {
875     /* Copy back cached render. */
876     GPU_framebuffer_blit(fbl->snapshot_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT);
877     GPU_framebuffer_blit(fbl->snapshot_fb, 0, fbl->gpencil_fb, 0, GPU_COLOR_BIT);
878     GPU_framebuffer_blit(fbl->snapshot_fb, 1, fbl->gpencil_fb, 1, GPU_COLOR_BIT);
879     /* Bypass drawing. */
880     pd->tobjects.first = pd->tobjects.last = NULL;
881   }
882 }
883 
GPENCIL_fast_draw_end(GPENCIL_Data * vedata)884 static void GPENCIL_fast_draw_end(GPENCIL_Data *vedata)
885 {
886   GPENCIL_PrivateData *pd = vedata->stl->pd;
887   GPENCIL_FramebufferList *fbl = vedata->fbl;
888   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
889 
890   if (pd->snapshot_buffer_dirty) {
891     /* Save to snapshot buffer. */
892     GPU_framebuffer_blit(dfbl->default_fb, 0, fbl->snapshot_fb, 0, GPU_DEPTH_BIT);
893     GPU_framebuffer_blit(fbl->gpencil_fb, 0, fbl->snapshot_fb, 0, GPU_COLOR_BIT);
894     GPU_framebuffer_blit(fbl->gpencil_fb, 1, fbl->snapshot_fb, 1, GPU_COLOR_BIT);
895     pd->snapshot_buffer_dirty = false;
896   }
897   /* Draw the sbuffer stroke(s). */
898   LISTBASE_FOREACH (GPENCIL_tObject *, ob, &pd->sbuffer_tobjects) {
899     GPENCIL_draw_object(vedata, ob);
900   }
901 }
902 
GPENCIL_draw_scene(void * ved)903 void GPENCIL_draw_scene(void *ved)
904 {
905   GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
906   GPENCIL_PrivateData *pd = vedata->stl->pd;
907   GPENCIL_FramebufferList *fbl = vedata->fbl;
908   float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
909 
910   /* Fade 3D objects. */
911   if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f) && (pd->obact != NULL) &&
912       (pd->obact->type == OB_GPENCIL)) {
913     float background_color[3];
914     ED_view3d_background_color_get(pd->scene, pd->v3d, background_color);
915     /* Blend color. */
916     interp_v3_v3v3(clear_cols[0], background_color, clear_cols[0], pd->fade_3d_object_opacity);
917 
918     mul_v4_fl(clear_cols[1], pd->fade_3d_object_opacity);
919   }
920 
921   if (pd->draw_depth_only) {
922     GPENCIL_draw_scene_depth_only(vedata);
923     return;
924   }
925 
926   if (pd->tobjects.first == NULL) {
927     return;
928   }
929 
930   if (pd->do_fast_drawing) {
931     GPENCIL_fast_draw_start(vedata);
932   }
933 
934   if (pd->tobjects.first) {
935     GPU_framebuffer_bind(fbl->gpencil_fb);
936     GPU_framebuffer_multi_clear(fbl->gpencil_fb, clear_cols);
937   }
938 
939   LISTBASE_FOREACH (GPENCIL_tObject *, ob, &pd->tobjects) {
940     GPENCIL_draw_object(vedata, ob);
941   }
942 
943   if (pd->do_fast_drawing) {
944     GPENCIL_fast_draw_end(vedata);
945   }
946 
947   if (pd->scene_fb) {
948     GPENCIL_antialiasing_draw(vedata);
949   }
950 
951   pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = NULL;
952 
953   /* Free temp stroke buffers. */
954   if (pd->sbuffer_gpd) {
955     DRW_cache_gpencil_sbuffer_clear(pd->obact);
956   }
957 }
958 
GPENCIL_engine_free(void)959 static void GPENCIL_engine_free(void)
960 {
961   GPENCIL_shader_free();
962 }
963 
964 static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data);
965 
966 DrawEngineType draw_engine_gpencil_type = {
967     NULL,
968     NULL,
969     N_("GpencilMode"),
970     &GPENCIL_data_size,
971     &GPENCIL_engine_init,
972     &GPENCIL_engine_free,
973     &GPENCIL_cache_init,
974     &GPENCIL_cache_populate,
975     &GPENCIL_cache_finish,
976     &GPENCIL_draw_scene,
977     NULL,
978     NULL,
979     &GPENCIL_render_to_image,
980 };
981