Blender V4.5
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_memblock.h"
12#include "DNA_shader_fx_types.h"
13#include "DRW_render.hh"
14
15#include "BLI_bitmap.h"
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. */
52 struct GPUUniformBuf *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. */
64 struct GPUUniformBuf *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. */
75 GPUFrameBuffer **target_fb = nullptr;
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 snapshot_fb = {"snapshot_fb"};
169 Framebuffer layer_fb = {"layer_fb"};
170 Framebuffer object_fb = {"object_fb"};
171 Framebuffer mask_fb = {"mask_fb"};
172 Framebuffer smaa_edge_fb = {"smaa_edge_fb"};
173 Framebuffer smaa_weight_fb = {"smaa_weight_fb"};
174
175 /* NOTE: These do not preserve the PassSimple memory across frames.
176 * If that becomes a bottleneck, these containers can be improved. */
179
180 /* tObject */
182 /* tLayer */
184 /* tVfx */
186 /* MaterialPool */
188 /* LightPool */
190 /* BLI_bitmap */
192
193 const DRWContext *draw_ctx = nullptr;
194
195 /* Last used material pool. */
197 /* Last used light pool. */
199 /* Common lightpool containing all lights in the scene. */
201 /* Common lightpool containing one ambient white light. */
203 /* Linked list of tObjects. */
204 struct {
207 /* Used to record whether the `tobjects` list is sorted. Do not sort drawings again in separate
208 * pass rendering to avoid generating infinite lists. */
210 /* Pointer to dtxl->depth */
211 GPUTexture *scene_depth_tx;
212 GPUFrameBuffer *scene_fb;
213 /* Used for render accumulation antialiasing. */
214 Texture accumulation_tx = {"gp_accumulation_tx"};
215 Framebuffer accumulation_fb = {"gp_accumulation_fb"};
216 /* Copy of txl->dummy_tx */
217 GPUTexture *dummy_tx;
218 /* Copy of v3d->shading.single_color. */
220 /* Copy of v3d->shading.color_type or -1 to ignore. */
222 /* Current frame */
223 int cfra;
224 /* If we are rendering for final render (F12).
225 * NOTE: set to false for viewport and opengl rendering (including sequencer scene rendering),
226 * but set to true when rendering in #OB_RENDER shading mode (viewport or opengl rendering). */
228 /* If we are in viewport display (used for VFX). */
230 /* Is shading set to wire-frame. */
232 /* Used by the depth merge step. */
234 /* Used for computing object distance to camera. */
236 float camera_pos[3];
237 /* Pseudo depth of field parameter. Used to scale blur radius. */
238 float dof_params[2];
239 /* Used for DoF Setup. */
241 /* Copy of draw_ctx->view_layer for convenience. */
243 /* Copy of draw_ctx->scene for convenience. */
244 struct Scene *scene;
245 /* Copy of draw_ctx->vie3d for convenience. */
246 struct View3D *v3d;
247
248 /* Active object. */
250 /* List of temp objects containing the stroke. */
251 struct {
252 tObject *first, *last;
254 /* Batches containing the temp stroke. */
255 gpu::Batch *stroke_batch;
256 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 /* Some blend mode needs to add negative values.
279 * This is only supported if target texture is signed. Only switch for the `reveal_tex`. */
281 /* Use only lines for multiedit and not active frame. */
283 /* Layer opacity for fading. */
285 /* Opacity for fading gpencil objects. */
287 /* Opacity for fading 3D objects. */
289 /* Mask opacity uniform. */
291 /* X-ray transparency in solid mode. */
293 /* Mask invert uniform. */
295 /* Vertex Paint opacity. */
297 /* Force 3D depth rendering. */
299
301 {
302 BLI_memblock_destroy(gp_light_pool, light_pool_free);
303 BLI_memblock_destroy(gp_material_pool, material_pool_free);
306 delete gp_layer_pool;
307 delete gp_vfx_pool;
308 }
309
310 void acquire_resources();
311 void release_resources();
312
314 {
315 return "Grease Pencil";
316 }
317
318 void init() final;
319
320 void begin_sync() final;
321 void object_sync(ObjectRef &ob_ref, Manager &manager) final;
322 void end_sync() final;
323
324 void draw(Manager &manager) final;
325
326 void antialiasing_accumulate(Manager &manager, float alpha);
327
328 static float2 antialiasing_sample_get(int sample_index, int sample_count);
329
330 private:
331 tObject *object_sync_do(Object *ob, ResourceHandle res_handle);
332
333 /* Check if the passed in layer is used by any other layer as a mask (in the viewlayer). */
334 bool is_used_as_layer_mask_in_viewlayer(const GreasePencil &grease_pencil,
335 const bke::greasepencil::Layer &mask_layer,
336 const ViewLayer &view_layer);
337
338 /* Returns true if this layer should be rendered (as part of the viewlayer). */
339 bool use_layer_in_render(const GreasePencil &grease_pencil,
340 const bke::greasepencil::Layer &layer,
341 const ViewLayer &view_layer,
342 bool &r_is_used_as_mask);
343
344 void draw_mask(View &view, tObject *ob, tLayer *layer);
345 void draw_object(View &view, tObject *ob);
346
347 void fast_draw_start();
348 void fast_draw_end(View &view);
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. */
355 GPUFrameBuffer **fb;
356 GPUTexture **color_tx;
357 GPUTexture **reveal_tx;
358 };
359
360 SwapChain<VfxFramebufferRef, 2> vfx_swapchain_;
361
362 PassSimple &vfx_pass_create(const char *name,
364 GPUShader *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 struct GPUTexture **r_tex_stroke,
429 struct GPUTexture **r_tex_fill,
430 struct GPUUniformBuf **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_material_resources_get(MaterialPool *first_pool, int mat_id, GPUTexture **r_tex_stroke, GPUTexture **r_tex_fill, GPUUniformBuf **r_ubo_mat)
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)
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
static constexpr GPUSamplerState internal_sampler()
struct blender::draw::gpencil::Instance::@347154071322053171023237172044324150040312176346 sbuffer_tobjects
draw::detail::SubPassVector< tLayer > tLayer_Pool
static float2 antialiasing_sample_get(int sample_index, int sample_count)
struct blender::draw::gpencil::Instance::@152377213014026372203341216150255134366273024311 tobjects_infront
void object_sync(ObjectRef &ob_ref, Manager &manager) final
struct blender::draw::gpencil::Instance::@152377213014026372203341216150255134366273024311 tobjects
draw::detail::SubPassVector< tVfx > tVfx_Pool
void antialiasing_accumulate(Manager &manager, float alpha)
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN]
struct GPUTexture * tex_stroke[GPENCIL_MATERIAL_BUFFER_LEN]
struct GPUTexture * tex_fill[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::@261115346126022153273150100117013047072144070143 layers
struct blender::draw::gpencil::tObject::@276074042154162376333337100100321162123366311017 vfx
std::unique_ptr< PassSimple > vfx_ps