Blender V5.0
gpencil_engine_private.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "BLI_bitmap.h"
12#include "BLI_memblock.h"
13
14#include "DNA_shader_fx_types.h"
15#include "DRW_render.hh"
16
17#include "BKE_grease_pencil.hh"
18
19#include "GPU_batch.hh"
20
21#include "draw_pass.hh"
22#include "draw_view_data.hh"
23
24#define GP_LIGHT
25
26#include "gpencil_defines.hh"
27#include "gpencil_shader.hh"
29
30struct GpencilBatchCache;
31struct Object;
32struct RenderEngine;
33struct RenderLayer;
34struct View3D;
35
36/* used to convert pixel scale. */
37#define GPENCIL_PIXEL_FACTOR 2000.0f
38
39/* used to expand VBOs. Size has a big impact in the speed */
40#define GPENCIL_VBO_BLOCK_SIZE 128
41
42#define GP_MAX_MASKBITS 256
43
44namespace blender::draw::gpencil {
45
47 /* Single linked-list. */
49 /* GPU representation of materials. */
51 /* Matching ubo. */
53 /* Texture per material. NULL means none. */
56 /* Number of material used in this pool. */
58};
59
60struct LightPool {
61 /* GPU representation of materials. */
63 /* Matching ubo. */
65 /* Number of light in the pool. */
67};
68
69/* Temporary gpencil FX reflection used by the gpencil::Instance. */
70struct tVfx {
72 struct tVfx *next = nullptr;
73 std::unique_ptr<PassSimple> vfx_ps = std::make_unique<PassSimple>("vfx");
74 /* Frame-buffer reference since it may not be allocated yet. */
76};
77
78/* Temporary gpencil layer reflection used by the gpencil::Instance. */
79struct tLayer {
81 struct tLayer *next;
83 std::unique_ptr<PassSimple> geom_ps;
85 std::unique_ptr<PassSimple> blend_ps;
93};
94
95/* Temporary object reflection used by the gpencil::Instance. */
96struct tObject {
98 struct tObject *next;
99
100 struct {
103
104 struct {
107
108 /* Distance to camera. Used for sorting. */
109 float camera_z;
110 /* Normal used for shading. Based on view angle. */
112 /* Used for drawing depth merge pass. */
113 float plane_mat[4][4];
114
116
117 /* Use Material Holdout. */
119};
120
121/* *********** LISTS *********** */
122
123struct Instance final : public DrawEngine {
124 PassSimple smaa_edge_ps = {"smaa_edge"};
125 PassSimple smaa_weight_ps = {"smaa_weight"};
126 PassSimple smaa_resolve_ps = {"smaa_resolve"};
127 PassSimple accumulate_ps = {"aa_accumulate"};
128 /* Composite the object depth to the default depth buffer to occlude overlays. */
129 PassSimple merge_depth_ps = {"merge_depth_ps"};
130 /* Invert mask buffer content. */
131 PassSimple mask_invert_ps = {"mask_invert_ps"};
132
134
135 /* Dummy texture to avoid errors cause by empty sampler. */
136 Texture dummy_texture = {"dummy_texture"};
137 Texture dummy_depth = {"dummy_depth"};
138 /* Textures used during render. Containing underlying rendered scene. */
139 Texture render_depth_tx = {"render_depth_tx"};
140 Texture render_color_tx = {"render_color_tx"};
141 /* Snapshot for smoother drawing. */
142 Texture snapshot_depth_tx = {"snapshot_depth_tx"};
143 Texture snapshot_color_tx = {"snapshot_color_tx"};
144 Texture snapshot_reveal_tx = {"snapshot_reveal_tx"};
145 /* Textures used by Anti-aliasing. */
146 Texture smaa_area_tx = {"smaa_area_tx"};
147 Texture smaa_search_tx = {"smaa_search_tx"};
148
149 /* Temp Textures (shared with other engines). */
150 TextureFromPool depth_tx = {"depth_tx"};
151 TextureFromPool color_tx = {"color_tx"};
152 TextureFromPool color_layer_tx = {"color_layer_tx"};
153 TextureFromPool color_object_tx = {"color_object_tx"};
154 /* Revealage is 1 - alpha */
155 TextureFromPool reveal_tx = {"reveal_tx"};
156 TextureFromPool reveal_layer_tx = {"reveal_layer_tx"};
157 TextureFromPool reveal_object_tx = {"reveal_object_tx"};
158 /* Mask texture */
159 TextureFromPool mask_depth_tx = {"mask_depth_tx"};
160 TextureFromPool mask_color_tx = {"mask_color_tx"};
162 /* Anti-Aliasing. */
163 TextureFromPool smaa_edge_tx = {"smaa_edge_tx"};
164 TextureFromPool smaa_weight_tx = {"smaa_weight_tx"};
165
166 Framebuffer render_fb = {"render_fb"};
167 Framebuffer gpencil_fb = {"gpencil_fb"};
168 Framebuffer gpencil_pass_fb = {"gpencil_pass_fb"};
169 Framebuffer snapshot_fb = {"snapshot_fb"};
170 Framebuffer layer_fb = {"layer_fb"};
171 Framebuffer object_fb = {"object_fb"};
172 Framebuffer mask_fb = {"mask_fb"};
173 Framebuffer smaa_edge_fb = {"smaa_edge_fb"};
174 Framebuffer smaa_weight_fb = {"smaa_weight_fb"};
175
176 /* NOTE: These do not preserve the PassSimple memory across frames.
177 * If that becomes a bottleneck, these containers can be improved. */
180
181 /* tObject */
183 /* tLayer */
185 /* tVfx */
187 /* MaterialPool */
189 /* LightPool */
191 /* BLI_bitmap */
193
194 const DRWContext *draw_ctx = nullptr;
195
196 /* Last used material pool. */
198 /* Last used light pool. */
200 /* Common lightpool containing all lights in the scene. */
202 /* Common lightpool containing one ambient white light. */
204 /* Linked list of tObjects. */
205 struct {
208 /* Used to record whether the `tobjects` list is sorted. Do not sort drawings again in separate
209 * pass rendering to avoid generating infinite lists. */
211 /* Pointer to dtxl->depth */
214 /* Used for render accumulation antialiasing. */
215 Texture accumulation_tx = {"gp_accumulation_tx"};
216 Framebuffer accumulation_fb = {"gp_accumulation_fb"};
217 /* Copy of txl->dummy_tx */
219 /* Copy of v3d->shading.single_color. */
221 /* Copy of v3d->shading.color_type or -1 to ignore. */
223 /* Current frame */
224 int cfra;
225 /* If we are rendering for final render (F12).
226 * NOTE: set to false for viewport and opengl rendering (including sequencer scene rendering),
227 * but set to true when rendering in #OB_RENDER shading mode (viewport or opengl rendering). */
229 /* If we are in viewport display (used for VFX). */
231 /* Is shading set to wire-frame. */
233 /* Used by the depth merge step. */
235 /* Used for computing object distance to camera. */
237 float camera_pos[3];
238 /* Pseudo depth of field parameter. Used to scale blur radius. */
239 float dof_params[2];
240 /* Used for DoF Setup. */
242 /* Copy of draw_ctx->view_layer for convenience. */
244 /* Copy of draw_ctx->scene for convenience. */
245 struct Scene *scene;
246 /* Copy of draw_ctx->vie3d for convenience. */
247 struct View3D *v3d;
248
249 /* Active object. */
251 /* List of temp objects containing the stroke. */
252 struct {
253 tObject *first, *last;
255 /* Batches containing the temp stroke. */
256 gpu::Batch *stroke_batch;
257 gpu::Batch *fill_batch;
259
260 /* Display onion skinning */
262 /* Show only the onion skins of the active object. */
264 /* Playing animation */
266 /* simplify settings */
270 /* Use scene lighting or flat shading (global setting). */
272 /* Use physical lights or just ambient lighting. */
274 /* Do we need additional frame-buffers? */
278 /* If viewport compositor is active, we need to render grease pencil onto another additional
279 * pass. */
281 /* Some blend mode needs to add negative values.
282 * This is only supported if target texture is signed. Only switch for the `reveal_tex`. */
284 /* Use only lines for multiedit and not active frame. */
286 /* Layer opacity for fading. */
288 /* Opacity for fading gpencil objects. */
290 /* Opacity for fading 3D objects. */
292 /* Mask opacity uniform. */
294 /* X-ray transparency in solid mode. */
296 /* Mask invert uniform. */
298 /* Vertex Paint opacity. */
300 /* Force 3D depth rendering. */
302
304 {
305 BLI_memblock_destroy(gp_light_pool, light_pool_free);
306 BLI_memblock_destroy(gp_material_pool, material_pool_free);
309 delete gp_layer_pool;
310 delete gp_vfx_pool;
311 }
312
313 void acquire_resources();
314 void release_resources();
315
317 {
318 return "Grease Pencil";
319 }
320
321 void init() final;
322
323 void begin_sync() final;
324 void object_sync(ObjectRef &ob_ref, Manager &manager) final;
325 void end_sync() final;
326
327 void draw(Manager &manager) final;
328
329 void antialiasing_accumulate(Manager &manager, float alpha);
330
331 static float2 antialiasing_sample_get(int sample_index, int sample_count);
332
333 private:
334 tObject *object_sync_do(Object *ob, ResourceHandleRange res_handle);
335
336 /* Check if the passed in layer is used by any other layer as a mask (in the viewlayer). */
337 bool is_used_as_layer_mask_in_viewlayer(const GreasePencil &grease_pencil,
338 const bke::greasepencil::Layer &mask_layer,
339 const ViewLayer &view_layer);
340
341 /* Returns true if this layer should be rendered (as part of the viewlayer). */
342 bool use_layer_in_render(const GreasePencil &grease_pencil,
343 const bke::greasepencil::Layer &layer,
344 const ViewLayer &view_layer,
345 bool &r_is_used_as_mask);
346
347 void draw_mask(View &view, tObject *ob, tLayer *layer);
348 void draw_object(View &view, tObject *ob);
349
350 void antialiasing_init();
351 void antialiasing_draw(Manager &manager);
352
353 struct VfxFramebufferRef {
354 /* These may not be allocated yet, use address of future pointer. */
358 };
359
360 SwapChain<VfxFramebufferRef, 2> vfx_swapchain_;
361
362 PassSimple &vfx_pass_create(const char *name,
364 gpu::Shader *sh,
365 tObject *tgp_ob,
367
368 void vfx_blur_sync(BlurShaderFxData *fx, Object *ob, tObject *tgp_ob);
369 void vfx_colorize_sync(ColorizeShaderFxData *fx, Object *ob, tObject *tgp_ob);
370 void vfx_flip_sync(FlipShaderFxData *fx, Object *ob, tObject *tgp_ob);
371 void vfx_rim_sync(RimShaderFxData *fx, Object *ob, tObject *tgp_ob);
372 void vfx_pixelize_sync(PixelShaderFxData *fx, Object *ob, tObject *tgp_ob);
373 void vfx_shadow_sync(ShadowShaderFxData *fx, Object *ob, tObject *tgp_ob);
374 void vfx_glow_sync(GlowShaderFxData *fx, Object *ob, tObject *tgp_ob);
375 void vfx_wave_sync(WaveShaderFxData *fx, Object *ob, tObject *tgp_ob);
376 void vfx_swirl_sync(SwirlShaderFxData *fx, Object *ob, tObject *tgp_ob);
377
378 void vfx_sync(Object *ob, tObject *tgp_ob);
379
380 static void material_pool_free(void *storage)
381 {
382 MaterialPool *matpool = (MaterialPool *)storage;
383 GPU_UBO_FREE_SAFE(matpool->ubo);
384 }
385
386 static void light_pool_free(void *storage)
387 {
388 LightPool *lightpool = (LightPool *)storage;
389 GPU_UBO_FREE_SAFE(lightpool->ubo);
390 }
391};
392
394 void *engine_type; /* Required */
396
398};
399
400/* geometry batch cache functions */
401struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra);
402
404 Object *ob,
405 bool is_stroke_order_3d,
408
409tLayer *grease_pencil_layer_cache_get(tObject *tgp_ob, int layer_id, bool skip_onion);
410
412 const Object *ob,
413 const bke::greasepencil::Layer &layer,
414 int onion_id,
415 bool is_used_as_mask,
416 tObject *tgp_ob);
423 Object *ob,
424 int *ofs,
425 bool is_vertex_mode);
427 int mat_id,
428 gpu::Texture **r_tex_stroke,
429 gpu::Texture **r_tex_fill,
430 gpu::UniformBuf **r_ubo_mat);
431
432void gpencil_light_ambient_add(LightPool *lightpool, const float color[3]);
433void gpencil_light_pool_populate(LightPool *lightpool, Object *ob);
439
440} // namespace blender::draw::gpencil
Low-level operations for grease pencil.
#define BLI_BITMAP_SIZE(_num)
Definition BLI_bitmap.h:32
unsigned int BLI_bitmap
Definition BLI_bitmap.h:13
#define final(a, b, c)
Definition BLI_hash.h:19
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
#define BLI_memblock_create(elem_size)
static AppView * view
#define GPU_UBO_FREE_SAFE(ubo)
DRWState
Definition draw_state.hh:25
#define GPU_INFO_SIZE
#define GPENCIL_MATERIAL_BUFFER_LEN
#define GPENCIL_LIGHT_BUFFER_LEN
#define GP_MAX_MASKBITS
BLI_INLINE float fb(float length, float L)
static ulong state[N]
void gpencil_light_ambient_add(LightPool *lightpool, const float color[3])
void gpencil_object_cache_sort(Instance *inst)
void gpencil_light_pool_populate(LightPool *lightpool, Object *ob)
LightPool * gpencil_light_pool_add(Instance *inst)
tLayer * grease_pencil_layer_cache_add(Instance *inst, const Object *ob, const bke::greasepencil::Layer &layer, const int onion_id, const bool is_used_as_mask, tObject *tgp_ob)
void gpencil_material_resources_get(MaterialPool *first_pool, int mat_id, gpu::Texture **r_tex_stroke, gpu::Texture **r_tex_fill, gpu::UniformBuf **r_ubo_mat)
struct GpencilBatchCache * gpencil_batch_cache_get(struct Object *ob, int cfra)
tLayer * grease_pencil_layer_cache_get(tObject *tgp_ob, int layer_id, const bool skip_onion)
LightPool * gpencil_light_pool_create(Instance *inst, Object *)
MaterialPool * gpencil_material_pool_create(Instance *inst, Object *ob, int *ofs, const bool is_vertex_mode)
tObject * gpencil_object_cache_add(Instance *inst, Object *ob, const bool is_stroke_order_3d, const Bounds< float3 > bounds)
detail::Pass< command::DrawCommandBuf > PassSimple
MatBase< float, 4, 4 > float4x4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
const char * name
static constexpr GPUSamplerState internal_sampler()
draw::detail::SubPassVector< tLayer > tLayer_Pool
struct blender::draw::gpencil::Instance::@053346266241271021036107110366172237215334041065 sbuffer_tobjects
struct blender::draw::gpencil::Instance::@236154265015220156065132174366266070164251065066 tobjects
static float2 antialiasing_sample_get(int sample_index, int sample_count)
struct blender::draw::gpencil::Instance::@236154265015220156065132174366266070164251065066 tobjects_infront
void object_sync(ObjectRef &ob_ref, Manager &manager) final
draw::detail::SubPassVector< tVfx > tVfx_Pool
void antialiasing_accumulate(Manager &manager, float alpha)
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN]
gpu::Texture * tex_fill[GPENCIL_MATERIAL_BUFFER_LEN]
gpu::Texture * tex_stroke[GPENCIL_MATERIAL_BUFFER_LEN]
gpMaterial mat_data[GPENCIL_MATERIAL_BUFFER_LEN]
std::unique_ptr< PassSimple > geom_ps
std::unique_ptr< PassSimple > blend_ps
struct blender::draw::gpencil::tObject::@205301145252027033255155341114207373222070270161 layers
struct blender::draw::gpencil::tObject::@173025115035047336003051253055014360144006015207 vfx
std::unique_ptr< PassSimple > vfx_ps