Blender V4.3
gpencil_engine_c.cc
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#include "DRW_engine.hh"
9#include "DRW_render.hh"
10
11#include "BKE_curves.hh"
13#include "BKE_gpencil_legacy.h"
14#include "BKE_grease_pencil.h"
15#include "BKE_grease_pencil.hh"
16#include "BKE_lib_id.hh"
17#include "BKE_main.hh"
18#include "BKE_object.hh"
19#include "BKE_paint.hh"
20#include "BKE_shader_fx.h"
21
22#include "BKE_camera.h"
23#include "BKE_global.hh" /* for G.debug */
24
25#include "BLI_link_utils.h"
26#include "BLI_listbase.h"
27#include "BLI_memblock.h"
28#include "BLI_virtual_array.hh"
29
30#include "DNA_camera_types.h"
32#include "DNA_screen_types.h"
33#include "DNA_view3d_types.h"
34
35#include "GPU_texture.hh"
36#include "GPU_uniform_buffer.hh"
37
38#include "gpencil_engine.h"
39
41
42#include "ED_grease_pencil.hh"
43#include "ED_screen.hh"
44#include "ED_view3d.hh"
45
46#include "UI_resources.hh"
47
48/* *********** FUNCTIONS *********** */
49
50void GPENCIL_engine_init(void *ved)
51{
52 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
53 GPENCIL_StorageList *stl = vedata->stl;
54 GPENCIL_TextureList *txl = vedata->txl;
55 GPENCIL_FramebufferList *fbl = vedata->fbl;
59 const View3D *v3d = ctx->v3d;
60
61 if (!stl->pd) {
62 stl->pd = static_cast<GPENCIL_PrivateData *>(
63 MEM_callocN(sizeof(GPENCIL_PrivateData), "GPENCIL_PrivateData"));
64 }
65
66 if (txl->dummy_texture == nullptr) {
67 const float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}};
68 txl->dummy_texture = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, (float *)pixels);
69 }
70
72
73 /* Resize and reset memory-blocks. */
76 BLI_memblock_clear(vldata->gp_object_pool, nullptr);
77 BLI_memblock_clear(vldata->gp_layer_pool, nullptr);
78 BLI_memblock_clear(vldata->gp_vfx_pool, nullptr);
79 BLI_memblock_clear(vldata->gp_maskbit_pool, nullptr);
80
81 stl->pd->gp_light_pool = vldata->gp_light_pool;
82 stl->pd->gp_material_pool = vldata->gp_material_pool;
83 stl->pd->gp_maskbit_pool = vldata->gp_maskbit_pool;
84 stl->pd->gp_object_pool = vldata->gp_object_pool;
85 stl->pd->gp_layer_pool = vldata->gp_layer_pool;
86 stl->pd->gp_vfx_pool = vldata->gp_vfx_pool;
87 stl->pd->view_layer = ctx->view_layer;
88 stl->pd->scene = ctx->scene;
89 stl->pd->v3d = ctx->v3d;
90 stl->pd->last_light_pool = nullptr;
91 stl->pd->last_material_pool = nullptr;
92 stl->pd->tobjects.first = nullptr;
93 stl->pd->tobjects.last = nullptr;
94 stl->pd->tobjects_infront.first = nullptr;
95 stl->pd->tobjects_infront.last = nullptr;
96 stl->pd->sbuffer_tobjects.first = nullptr;
97 stl->pd->sbuffer_tobjects.last = nullptr;
98 stl->pd->dummy_tx = txl->dummy_texture;
100 stl->pd->draw_wireframe = (v3d && v3d->shading.type == OB_WIRE) && !stl->pd->draw_depth_only;
101 stl->pd->scene_depth_tx = stl->pd->draw_depth_only ? txl->dummy_texture : dtxl->depth;
102 stl->pd->scene_fb = dfbl->default_fb;
103 stl->pd->is_render = txl->render_depth_tx || (v3d && v3d->shading.type == OB_RENDER);
104 stl->pd->is_viewport = (v3d != nullptr);
107 /* Small HACK: we don't want the global pool to be reused,
108 * so we set the last light pool to nullptr. */
109 stl->pd->last_light_pool = nullptr;
110
111 bool use_scene_lights = false;
112 bool use_scene_world = false;
113
114 if (v3d) {
115 use_scene_lights = V3D_USES_SCENE_LIGHTS(v3d);
116
117 use_scene_world = V3D_USES_SCENE_WORLD(v3d);
118
119 stl->pd->v3d_color_type = (v3d->shading.type == OB_SOLID) ? v3d->shading.color_type : -1;
120 /* Special case: If we're in Vertex Paint mode, enforce V3D_SHADING_VERTEX_COLOR setting.*/
121 if (v3d->shading.type == OB_SOLID && ctx->obact &&
123 {
125 }
126
128
129 /* For non active frame, use only lines in multiedit mode. */
130 const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
131 stl->pd->use_multiedit_lines_only = overlays_on &&
133
134 const bool shmode_xray_support = v3d->shading.type <= OB_SOLID;
135 stl->pd->xray_alpha = (shmode_xray_support && XRAY_ENABLED(v3d)) ? XRAY_ALPHA(v3d) : 1.0f;
136 }
137 else if (stl->pd->is_render) {
138 use_scene_lights = true;
139 use_scene_world = true;
140 stl->pd->use_multiedit_lines_only = false;
141 stl->pd->xray_alpha = 1.0f;
142 stl->pd->v3d_color_type = -1;
143 }
144
145 stl->pd->use_lighting = (v3d && v3d->shading.type > OB_SOLID) || stl->pd->is_render;
146 stl->pd->use_lights = use_scene_lights;
147
148 if (txl->render_depth_tx != nullptr) {
149 stl->pd->scene_depth_tx = txl->render_depth_tx;
150 stl->pd->scene_fb = fbl->render_fb;
151 }
152
154
155 World *world = ctx->scene->world;
156 if (world != nullptr && use_scene_world) {
158 }
159 else if (v3d) {
160 float world_light[3];
161 copy_v3_fl(world_light, v3d->shading.studiolight_intensity);
163 }
164
165 float viewmatinv[4][4];
166 DRW_view_viewmat_get(nullptr, viewmatinv, true);
167 copy_v3_v3(stl->pd->camera_z_axis, viewmatinv[2]);
168 copy_v3_v3(stl->pd->camera_pos, viewmatinv[3]);
169 stl->pd->camera_z_offset = dot_v3v3(viewmatinv[3], viewmatinv[2]);
170
171 if (ctx && ctx->rv3d && v3d) {
172 stl->pd->camera = (ctx->rv3d->persp == RV3D_CAMOB) ? v3d->camera : nullptr;
173 }
174 else {
175 stl->pd->camera = nullptr;
176 }
177}
178
179void GPENCIL_cache_init(void *ved)
180{
181 using namespace blender::draw;
182 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
183 GPENCIL_PassList *psl = vedata->psl;
184 GPENCIL_TextureList *txl = vedata->txl;
185 GPENCIL_FramebufferList *fbl = vedata->fbl;
186 GPENCIL_PrivateData *pd = vedata->stl->pd;
187 DRWShadingGroup *grp;
188
189 const DRWContextState *draw_ctx = DRW_context_state_get();
190 pd->cfra = int(DEG_get_ctime(draw_ctx->depsgraph));
192 pd->use_layer_fb = false;
193 pd->use_object_fb = false;
194 pd->use_mask_fb = false;
195 /* Always use high precision for render. */
196 pd->use_signed_fb = !pd->is_viewport;
197
198 if (draw_ctx->v3d) {
199 const bool hide_overlay = ((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) != 0);
200 const bool show_onion = ((draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) != 0);
201 const bool playing = (draw_ctx->evil_C != nullptr) ?
203 nullptr :
204 false;
205 pd->do_onion = show_onion && !hide_overlay && !playing;
206 pd->playing = playing;
207 /* Save simplify flags (can change while drawing, so it's better to save). */
208 Scene *scene = draw_ctx->scene;
209 pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, playing);
210 pd->simplify_fx = GPENCIL_SIMPLIFY_FX(scene, playing) ||
211 (draw_ctx->v3d->shading.type < OB_RENDER);
212
213 /* Fade Layer. */
214 const bool is_fade_layer = ((!hide_overlay) && (!pd->is_render) &&
216 pd->fade_layer_opacity = (is_fade_layer) ? draw_ctx->v3d->overlay.gpencil_fade_layer : -1.0f;
218 /* Fade GPencil Objects. */
219 const bool is_fade_object = ((!hide_overlay) && (!pd->is_render) &&
220 (draw_ctx->v3d->gp_flag & V3D_GP_FADE_OBJECTS) &&
222 pd->fade_gp_object_opacity = (is_fade_object) ? draw_ctx->v3d->overlay.gpencil_paper_opacity :
223 -1.0f;
224 pd->fade_3d_object_opacity = ((!hide_overlay) && (!pd->is_render) &&
225 (draw_ctx->v3d->gp_flag & V3D_GP_FADE_OBJECTS)) ?
227 -1.0f;
228 }
229 else {
230 pd->do_onion = true;
231 Scene *scene = draw_ctx->scene;
232 pd->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, false);
233 pd->simplify_fx = GPENCIL_SIMPLIFY_FX(scene, false);
234 pd->fade_layer_opacity = -1.0f;
235 pd->playing = false;
236 }
237
238 {
239 pd->sbuffer_stroke = nullptr;
240 pd->sbuffer_gpd = nullptr;
241 pd->sbuffer_layer = nullptr;
242 pd->stroke_batch = nullptr;
243 pd->fill_batch = nullptr;
244 pd->do_fast_drawing = false;
245
246 pd->obact = draw_ctx->obact;
247 }
248
249 if (pd->do_fast_drawing) {
250 pd->snapshot_buffer_dirty = (txl->snapshot_color_tx == nullptr);
251 const float *size = DRW_viewport_size_get();
258
260 {
261 GPU_ATTACHMENT_TEXTURE(txl->snapshot_depth_tx),
262 GPU_ATTACHMENT_TEXTURE(txl->snapshot_color_tx),
263 GPU_ATTACHMENT_TEXTURE(txl->snapshot_reveal_tx),
264 });
265 }
266 else {
267 /* Free unneeded buffers. */
272 }
273
274 {
277
279 grp = DRW_shgroup_create(sh, psl->merge_depth_ps);
280 DRW_shgroup_uniform_texture_ref(grp, "depthBuf", &pd->depth_tx);
281 DRW_shgroup_uniform_bool(grp, "strokeOrder3d", &pd->is_stroke_order_3d, 1);
282 DRW_shgroup_uniform_vec4(grp, "gpModelMatrix", pd->object_bound_mat[0], 4);
284 }
285 {
288
290 grp = DRW_shgroup_create(sh, psl->mask_invert_ps);
292 }
293
294 Camera *cam = static_cast<Camera *>(
295 (pd->camera != nullptr && pd->camera->type == OB_CAMERA) ? pd->camera->data : nullptr);
296
297 /* Pseudo DOF setup. */
298 if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
299 const float *vp_size = DRW_viewport_size_get();
300 float fstop = cam->dof.aperture_fstop;
301 float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
302 float focus_dist = BKE_camera_object_dof_distance(pd->camera);
303 float focal_len = cam->lens;
304
305 const float scale_camera = 0.001f;
306 /* We want radius here for the aperture number. */
307 float aperture = 0.5f * scale_camera * focal_len / fstop;
308 float focal_len_scaled = scale_camera * focal_len;
309 float sensor_scaled = scale_camera * sensor;
310
311 if (draw_ctx->rv3d != nullptr) {
312 sensor_scaled *= draw_ctx->rv3d->viewcamtexcofac[0];
313 }
314
315 pd->dof_params[1] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
316 pd->dof_params[1] *= vp_size[0] / sensor_scaled;
317 pd->dof_params[0] = -focus_dist * pd->dof_params[1];
318 }
319 else {
320 /* Disable DoF blur scaling. */
321 pd->camera = nullptr;
322 }
323}
324
325#define DISABLE_BATCHING 0
326
327/* Check if the passed in layer is used by any other layer as a mask (in the viewlayer). */
328static bool is_used_as_layer_mask_in_viewlayer(const GreasePencil &grease_pencil,
329 const blender::bke::greasepencil::Layer &mask_layer,
330 const ViewLayer &view_layer)
331{
332 using namespace blender::bke::greasepencil;
333 for (const Layer *layer : grease_pencil.layers()) {
334 if (layer->view_layer_name().is_empty() ||
335 !STREQ(view_layer.name, layer->view_layer_name().c_str()))
336 {
337 continue;
338 }
339
340 if ((layer->base.flag & GP_LAYER_TREE_NODE_DISABLE_MASKS_IN_VIEWLAYER) != 0) {
341 continue;
342 }
343
344 LISTBASE_FOREACH (GreasePencilLayerMask *, mask, &layer->masks) {
345 if (STREQ(mask->layer_name, mask_layer.name().c_str())) {
346 return true;
347 }
348 }
349 }
350 return false;
351}
352
353/* Returns true if this layer should be rendered (as part of the viewlayer). */
354static bool use_layer_in_render(const GreasePencil &grease_pencil,
356 const ViewLayer &view_layer,
357 bool &r_is_used_as_mask)
358{
359 if (!layer.view_layer_name().is_empty() &&
360 !STREQ(view_layer.name, layer.view_layer_name().c_str()))
361 {
362 /* Do not skip layers that are masks when rendering the viewlayer so that it can still be used
363 * to clip/mask other layers. */
364 if (is_used_as_layer_mask_in_viewlayer(grease_pencil, layer, view_layer)) {
365 r_is_used_as_mask = true;
366 }
367 else {
368 return false;
369 }
370 }
371 return true;
372}
373
376 Object *ob)
377{
378 using namespace blender;
379 using namespace blender::ed::greasepencil;
380 using namespace blender::bke::greasepencil;
381 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
382 const bool is_vertex_mode = (ob->mode & OB_MODE_VERTEX_PAINT) != 0;
383 const blender::Bounds<float3> bounds = grease_pencil.bounds_min_max_eval().value_or(
385
386 const bool do_onion = !pd->is_render && pd->do_onion;
387 const bool do_multi_frame = (((pd->scene->toolsettings->gpencil_flags &
389 (ob->mode != OB_MODE_OBJECT));
390 const bool use_stroke_order_3d = (grease_pencil.flag & GREASE_PENCIL_STROKE_ORDER_3D) != 0;
391 GPENCIL_tObject *tgp_ob = gpencil_object_cache_add(pd, ob, use_stroke_order_3d, bounds);
392
393 int mat_ofs = 0;
394 GPENCIL_MaterialPool *matpool = gpencil_material_pool_create(pd, ob, &mat_ofs, is_vertex_mode);
395
396 GPUTexture *tex_fill = txl->dummy_texture;
397 GPUTexture *tex_stroke = txl->dummy_texture;
398
399 blender::gpu::Batch *iter_geom = nullptr;
400 DRWShadingGroup *grp;
401 int vfirst = 0;
402 int vcount = 0;
403
404 const auto drawcall_flush = [&]() {
405#if !DISABLE_BATCHING
406 if (iter_geom != nullptr) {
407 DRW_shgroup_call_range(grp, ob, iter_geom, vfirst, vcount);
408 }
409#endif
410 iter_geom = nullptr;
411 vfirst = -1;
412 vcount = 0;
413 };
414
415 const auto drawcall_add =
416 [&](blender::gpu::Batch *draw_geom, const int v_first, const int v_count) {
417#if DISABLE_BATCHING
418 DRW_shgroup_call_range(grp, ob, geom, v_first, v_count);
419 return;
420#endif
421 int last = vfirst + vcount;
422 /* Interrupt draw-call grouping if the sequence is not consecutive. */
423 if ((draw_geom != iter_geom) || (v_first - last > 0)) {
424 drawcall_flush();
425 }
426 iter_geom = draw_geom;
427 if (vfirst == -1) {
428 vfirst = v_first;
429 }
430 vcount = v_first + v_count - vfirst;
431 };
432
433 int t_offset = 0;
434 /* Note that we loop over all the drawings (including the onion skinned ones) to make sure we
435 * match the offsets of the batch cache. */
436 const Vector<DrawingInfo> drawings = retrieve_visible_drawings(*pd->scene, grease_pencil, true);
437 const Span<const Layer *> layers = grease_pencil.layers();
438 for (const DrawingInfo info : drawings) {
439 const Layer &layer = *layers[info.layer_index];
440
441 const bke::CurvesGeometry &curves = info.drawing.strokes();
442 const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
443 const bke::AttributeAccessor attributes = curves.attributes();
444 const VArray<bool> cyclic = *attributes.lookup_or_default<bool>(
445 "cyclic", bke::AttrDomain::Curve, false);
446
447 IndexMaskMemory memory;
449 *ob, info.drawing, memory);
450
451 /* Precompute all the triangle and vertex counts.
452 * In case the drawing should not be rendered, we need to compute the offset where the next
453 * drawing begins. */
454 Array<int> num_triangles_per_stroke(visible_strokes.size());
455 Array<int> num_vertices_per_stroke(visible_strokes.size());
456 int total_num_triangles = 0;
457 int total_num_vertices = 0;
458 visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
459 const IndexRange points = points_by_curve[stroke_i];
460 const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
461 const int num_stroke_vertices = (points.size() +
462 int(cyclic[stroke_i] && (points.size() >= 3)));
463 num_triangles_per_stroke[pos] = num_stroke_triangles;
464 num_vertices_per_stroke[pos] = num_stroke_vertices;
465 total_num_triangles += num_stroke_triangles;
466 total_num_vertices += num_stroke_vertices;
467 });
468
469 bool is_layer_used_as_mask = false;
470 const bool show_drawing_in_render = use_layer_in_render(
471 grease_pencil, layer, *pd->view_layer, is_layer_used_as_mask);
472 if (!show_drawing_in_render) {
473 /* Skip over the entire drawing. */
474 t_offset += total_num_triangles;
475 t_offset += total_num_vertices * 2;
476 continue;
477 }
478
479 drawcall_flush();
480
482 pd, ob, layer, info.onion_id, is_layer_used_as_mask, tgp_ob);
483
484 const bool use_lights = pd->use_lighting &&
485 ((layer.base.flag & GP_LAYER_TREE_NODE_USE_LIGHTS) != 0) &&
487
488 GPUUniformBuf *lights_ubo = (use_lights) ? pd->global_light_pool->ubo :
490
491 GPUUniformBuf *ubo_mat;
492 gpencil_material_resources_get(matpool, 0, nullptr, nullptr, &ubo_mat);
493
494 grp = tgp_layer->base_shgrp;
495 DRW_shgroup_uniform_block(grp, "gp_lights", lights_ubo);
496 DRW_shgroup_uniform_block(grp, "gp_materials", ubo_mat);
497 DRW_shgroup_uniform_texture(grp, "gpFillTexture", tex_fill);
498 DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", tex_stroke);
499 DRW_shgroup_uniform_int_copy(grp, "gpMaterialOffset", mat_ofs);
500 /* Since we don't use the sbuffer in GPv3, this is always 0. */
501 DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0f);
503
504 const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
505 "material_index", bke::AttrDomain::Curve, 0);
506
507 const bool only_lines = !ELEM(ob->mode,
511 info.frame_number != pd->cfra && pd->use_multiedit_lines_only &&
512 do_multi_frame;
513 const bool is_onion = info.onion_id != 0;
514
515 visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
516 const IndexRange points = points_by_curve[stroke_i];
517 /* The material index is allowed to be negative as it's stored as a generic attribute. We
518 * clamp it here to avoid crashing in the rendering code. Any stroke with a material < 0 will
519 * use the first material in the first material slot.*/
520 const int material_index = std::max(stroke_materials[stroke_i], 0);
521 const MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, material_index + 1);
522
523 const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
524 const bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0);
525 const bool show_fill = (points.size() >= 3) &&
526 ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0) &&
527 (!pd->simplify_fill);
528 const bool hide_onion = is_onion && ((gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN) != 0 ||
529 (!do_onion && !do_multi_frame));
530 const bool skip_stroke = hide_material || (!show_stroke && !show_fill) ||
531 (only_lines && !do_onion && is_onion) || hide_onion;
532
533 if (skip_stroke) {
534 t_offset += num_triangles_per_stroke[pos];
535 t_offset += num_vertices_per_stroke[pos] * 2;
536 return;
537 }
538
539 GPUUniformBuf *new_ubo_mat;
540 GPUTexture *new_tex_fill = nullptr;
541 GPUTexture *new_tex_stroke = nullptr;
543 matpool, mat_ofs + material_index, &new_tex_stroke, &new_tex_fill, &new_ubo_mat);
544
545 const bool resource_changed = (ubo_mat != new_ubo_mat) ||
546 (new_tex_fill && (new_tex_fill != tex_fill)) ||
547 (new_tex_stroke && (new_tex_stroke != tex_stroke));
548
549 if (resource_changed) {
550 drawcall_flush();
551
552 grp = DRW_shgroup_create_sub(grp);
553 if (new_ubo_mat != ubo_mat) {
554 DRW_shgroup_uniform_block(grp, "gp_materials", new_ubo_mat);
555 ubo_mat = new_ubo_mat;
556 }
557 if (new_tex_fill) {
558 DRW_shgroup_uniform_texture(grp, "gpFillTexture", new_tex_fill);
559 tex_fill = new_tex_fill;
560 }
561 if (new_tex_stroke) {
562 DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", new_tex_stroke);
563 tex_stroke = new_tex_stroke;
564 }
565 }
566
567 blender::gpu::Batch *geom = draw::DRW_cache_grease_pencil_get(pd->scene, ob);
568 if (iter_geom != geom) {
569 drawcall_flush();
570
572 pd->scene, ob);
574 ob);
575 DRW_shgroup_buffer_texture(grp, "gp_pos_tx", position_tx);
576 DRW_shgroup_buffer_texture(grp, "gp_col_tx", color_tx);
577 }
578
579 if (show_fill) {
580 const int v_first = t_offset * 3;
581 const int v_count = num_triangles_per_stroke[pos] * 3;
582 drawcall_add(geom, v_first, v_count);
583 }
584
585 t_offset += num_triangles_per_stroke[pos];
586
587 if (show_stroke) {
588 const int v_first = t_offset * 3;
589 const int v_count = num_vertices_per_stroke[pos] * 2 * 3;
590 drawcall_add(geom, v_first, v_count);
591 }
592
593 t_offset += num_vertices_per_stroke[pos] * 2;
594 });
595 }
596
597 drawcall_flush();
598
599 return tgp_ob;
600}
601
602void GPENCIL_cache_populate(void *ved, Object *ob)
603{
604 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
605 GPENCIL_PrivateData *pd = vedata->stl->pd;
606 GPENCIL_TextureList *txl = vedata->txl;
607
608 /* object must be visible */
610 return;
611 }
612
613 if (ob->data && (ob->type == OB_GREASE_PENCIL) && (ob->dt >= OB_SOLID)) {
616 vedata,
617 ob,
618 tgp_ob,
620 }
621
622 if (ob->type == OB_LAMP && pd->use_lights) {
624 }
625}
626
627void GPENCIL_cache_finish(void *ved)
628{
629 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
630 GPENCIL_PrivateData *pd = vedata->stl->pd;
631 GPENCIL_FramebufferList *fbl = vedata->fbl;
632
633 /* Upload UBO data. */
637 while ((pool = (GPENCIL_MaterialPool *)BLI_memblock_iterstep(&iter))) {
638 GPU_uniformbuf_update(pool->ubo, pool->mat_data);
639 }
640
642 GPENCIL_LightPool *lpool;
643 while ((lpool = (GPENCIL_LightPool *)BLI_memblock_iterstep(&iter))) {
644 GPU_uniformbuf_update(lpool->ubo, lpool->light_data);
645 }
646
647 /* Sort object by decreasing Z to avoid most of alpha ordering issues. */
649
650 /* Create frame-buffers only if needed. */
651 if (pd->tobjects.first) {
653
654 const float *size = DRW_viewport_size_get();
659
661 {
662 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
663 GPU_ATTACHMENT_TEXTURE(pd->color_tx),
664 GPU_ATTACHMENT_TEXTURE(pd->reveal_tx),
665 });
666
667 if (pd->use_layer_fb) {
672
674 {
675 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
676 GPU_ATTACHMENT_TEXTURE(pd->color_layer_tx),
677 GPU_ATTACHMENT_TEXTURE(pd->reveal_layer_tx),
678 });
679 }
680
681 if (pd->use_object_fb) {
686
688 {
689 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
690 GPU_ATTACHMENT_TEXTURE(pd->color_object_tx),
691 GPU_ATTACHMENT_TEXTURE(pd->reveal_object_tx),
692 });
693 }
694
695 if (pd->use_mask_fb) {
696 /* We need an extra depth to not disturb the normal drawing.
697 * The color_tx is needed for frame-buffer completeness. */
698 GPUTexture *color_tx, *depth_tx;
699 depth_tx = DRW_texture_pool_query_2d(
702 /* Use high quality format for render. */
703 eGPUTextureFormat mask_format = pd->is_render ? GPU_R16 : GPU_R8;
705 size[0], size[1], mask_format, &draw_engine_gpencil_type);
706
708 {
709 GPU_ATTACHMENT_TEXTURE(depth_tx),
710 GPU_ATTACHMENT_TEXTURE(color_tx),
711 GPU_ATTACHMENT_TEXTURE(pd->mask_tx),
712 });
713 }
714
716 }
717}
718
719static void GPENCIL_draw_scene_depth_only(void *ved)
720{
721 using namespace blender::draw;
722 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
723 GPENCIL_PrivateData *pd = vedata->stl->pd;
725
726 if (DRW_state_is_fbo()) {
728 }
729
731 LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
732 DRW_draw_pass(layer->geom_ps);
733 }
734 }
735
736 if (DRW_state_is_fbo()) {
738 }
739
740 pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = nullptr;
741
742 /* Free temp stroke buffers. */
743 if (pd->sbuffer_gpd) {
745 }
746}
747
749{
750 GPENCIL_PassList *psl = vedata->psl;
751 GPENCIL_FramebufferList *fbl = vedata->fbl;
752 const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
753 float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f;
754 bool inverted = false;
755 /* OPTI(@fclem): we could optimize by only clearing if the new mask_bits does not contain all
756 * the masks already rendered in the buffer, and drawing only the layers not already drawn. */
757 bool cleared = false;
758
759 DRW_stats_group_start("GPencil Mask");
760
762
763 for (int i = 0; i < GP_MAX_MASKBITS; i++) {
764 if (!BLI_BITMAP_TEST(layer->mask_bits, i)) {
765 continue;
766 }
767
768 if (BLI_BITMAP_TEST_BOOL(layer->mask_invert_bits, i) != inverted) {
769 if (cleared) {
771 }
772 inverted = !inverted;
773 }
774
775 if (!cleared) {
776 cleared = true;
777 GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth);
778 }
779
780 GPENCIL_tLayer *mask_layer = grease_pencil_layer_cache_get(ob, i, true);
781 /* When filtering by view-layer, the mask could be null and must be ignored. */
782 if (mask_layer == nullptr) {
783 continue;
784 }
785
786 DRW_draw_pass(mask_layer->geom_ps);
787 }
788
789 if (!inverted) {
790 /* Blend shader expect an opacity mask not a reavealage buffer. */
792 }
793
795}
796
798{
799 GPENCIL_PassList *psl = vedata->psl;
800 GPENCIL_PrivateData *pd = vedata->stl->pd;
801 GPENCIL_FramebufferList *fbl = vedata->fbl;
802 const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
803
804 DRW_stats_group_start("GPencil Object");
805
806 GPUFrameBuffer *fb_object = (ob->vfx.first) ? fbl->object_fb : fbl->gpencil_fb;
807
808 GPU_framebuffer_bind(fb_object);
809 GPU_framebuffer_clear_depth_stencil(fb_object, ob->is_drawmode3d ? 1.0f : 0.0f, 0x00);
810
811 if (ob->vfx.first) {
812 GPU_framebuffer_multi_clear(fb_object, clear_cols);
813 }
814
815 LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
816 if (layer->mask_bits) {
817 gpencil_draw_mask(vedata, ob, layer);
818 }
819
820 if (layer->blend_ps) {
822 GPU_framebuffer_multi_clear(fbl->layer_fb, clear_cols);
823 }
824 else {
825 GPU_framebuffer_bind(fb_object);
826 }
827
828 DRW_draw_pass(layer->geom_ps);
829
830 if (layer->blend_ps) {
831 GPU_framebuffer_bind(fb_object);
832 DRW_draw_pass(layer->blend_ps);
833 }
834 }
835
836 LISTBASE_FOREACH (GPENCIL_tVfx *, vfx, &ob->vfx) {
837 GPU_framebuffer_bind(*(vfx->target_fb));
838 DRW_draw_pass(vfx->vfx_ps);
839 }
840
843
844 if (pd->scene_fb) {
847 }
848
850}
851
853{
854 GPENCIL_PrivateData *pd = vedata->stl->pd;
855 GPENCIL_FramebufferList *fbl = vedata->fbl;
857
858 if (!pd->snapshot_buffer_dirty) {
859 /* Copy back cached render. */
863 /* Bypass drawing. */
864 pd->tobjects.first = pd->tobjects.last = nullptr;
865 }
866}
867
869{
870 GPENCIL_PrivateData *pd = vedata->stl->pd;
871 GPENCIL_FramebufferList *fbl = vedata->fbl;
873
874 if (pd->snapshot_buffer_dirty) {
875 /* Save to snapshot buffer. */
879 pd->snapshot_buffer_dirty = false;
880 }
881 /* Draw the sbuffer stroke(s). */
883 GPENCIL_draw_object(vedata, ob);
884 }
885}
886
887void GPENCIL_draw_scene(void *ved)
888{
889 using namespace blender::draw;
890 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
891 GPENCIL_PrivateData *pd = vedata->stl->pd;
892 GPENCIL_FramebufferList *fbl = vedata->fbl;
893 float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
894
895 /* Fade 3D objects. */
896 if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f) && (pd->obact != nullptr) &&
898 {
899 float background_color[3];
900 ED_view3d_background_color_get(pd->scene, pd->v3d, background_color);
901 /* Blend color. */
902 interp_v3_v3v3(clear_cols[0], background_color, clear_cols[0], pd->fade_3d_object_opacity);
903
904 mul_v4_fl(clear_cols[1], pd->fade_3d_object_opacity);
905 }
906
907 if (pd->draw_depth_only) {
909 return;
910 }
911
912 if (pd->tobjects.first == nullptr) {
913 return;
914 }
915
916 if (pd->do_fast_drawing) {
918 }
919
920 if (pd->tobjects.first) {
922 GPU_framebuffer_multi_clear(fbl->gpencil_fb, clear_cols);
923 }
924
926 GPENCIL_draw_object(vedata, ob);
927 }
928
929 if (pd->do_fast_drawing) {
930 GPENCIL_fast_draw_end(vedata);
931 }
932
933 if (pd->scene_fb) {
935 }
936
937 pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = nullptr;
938
939 /* Free temp stroke buffers. */
940 if (pd->sbuffer_gpd) {
942 }
943}
944
946{
948}
949
951
953 /*next*/ nullptr,
954 /*prev*/ nullptr,
955 /*idname*/ N_("GpencilMode"),
956 /*vedata_size*/ &GPENCIL_data_size,
957 /*engine_init*/ &GPENCIL_engine_init,
958 /*engine_free*/ &GPENCIL_engine_free,
959 /*instance_free*/ nullptr,
960 /*cache_init*/ &GPENCIL_cache_init,
961 /*cache_populate*/ &GPENCIL_cache_populate,
962 /*cache_finish*/ &GPENCIL_cache_finish,
963 /*draw_scene*/ &GPENCIL_draw_scene,
964 /*view_update*/ nullptr,
965 /*id_update*/ nullptr,
966 /*render_to_image*/ &GPENCIL_render_to_image,
967 /*store_metadata*/ nullptr,
968};
Camera data-block and utility functions.
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
float BKE_camera_object_dof_distance(const struct Object *ob)
wmWindowManager * CTX_wm_manager(const bContext *C)
Low-level operations for curves.
#define GPENCIL_SIMPLIFY_AA(scene)
#define GPENCIL_SIMPLIFY_FILL(scene, playing)
#define GPENCIL_SIMPLIFY_FX(scene, playing)
Low-level operations for grease pencil that cannot be defined in the C++ header yet.
Low-level operations for grease pencil.
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition BLI_bitmap.h:65
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition BLI_bitmap.h:75
#define LISTBASE_FOREACH(type, var, list)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition math_vector.c:36
MINLINE void copy_v3_fl(float r[3], float f)
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL()
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
void * BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define ELEM(...)
#define STREQ(a, b)
float DEG_get_ctime(const Depsgraph *graph)
@ CAM_DOF_ENABLED
@ GP_LAYER_TREE_NODE_USE_LIGHTS
@ GP_LAYER_TREE_NODE_DISABLE_MASKS_IN_VIEWLAYER
@ GREASE_PENCIL_STROKE_ORDER_3D
@ GP_MATERIAL_HIDE_ONIONSKIN
@ GP_MATERIAL_HIDE
@ GP_MATERIAL_STROKE_SHOW
@ GP_MATERIAL_FILL_SHOW
@ OB_WIRE
@ OB_SOLID
@ OB_RENDER
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_EDIT
@ OB_MODE_PAINT_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_OBJECT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
@ OB_USE_GPENCIL_LIGHTS
@ OB_CAMERA
@ OB_GREASE_PENCIL
@ OB_LAMP
@ OB_GPENCIL_LEGACY
@ GP_USE_MULTI_FRAME_EDITING
@ V3D_SHADING_VERTEX_COLOR
#define V3D_USES_SCENE_WORLD(v3d)
@ V3D_HIDE_OVERLAYS
@ RV3D_CAMOB
#define V3D_USES_SCENE_LIGHTS(v3d)
@ V3D_GP_FADE_OBJECTS
@ V3D_GP_SHOW_MULTIEDIT_LINES
@ V3D_GP_FADE_NOACTIVE_GPENCIL
@ V3D_GP_FADE_NOACTIVE_LAYERS
@ V3D_GP_SHOW_ONION_SKIN
DRWTextureFlag
@ DRW_TEX_WRAP
#define DRW_PASS_CREATE(pass, state)
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
#define DRW_VIEWPORT_DATA_SIZE(ty)
#define DRW_TEXTURE_FREE_SAFE(tex)
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
#define XRAY_ENABLED(v3d)
void ED_view3d_background_color_get(const Scene *scene, const View3D *v3d, float r_color[3])
#define XRAY_ALPHA(v3d)
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
@ GPU_DEPTH_BIT
@ GPU_COLOR_BIT
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb, const float clear_col[4], float clear_depth)
void GPU_framebuffer_multi_clear(GPUFrameBuffer *framebuffer, const float(*clear_colors)[4])
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, int read_slot, GPUFrameBuffer *fb_write, int write_slot, eGPUFrameBufferBits blit_buffers)
eGPUTextureFormat
@ GPU_DEPTH24_STENCIL8
@ GPU_R16
@ GPU_R8
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between world
struct GPUShader GPUShader
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
int64_t size() const
void foreach_index(Fn &&fn) const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr const char * c_str() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
StringRefNull view_layer_name() const
#define fabsf(x)
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
const float * DRW_viewport_size_get()
int DRW_object_visibility_in_active_context(const Object *ob)
DefaultTextureList * DRW_viewport_texture_list_get()
const DRWContextState * DRW_context_state_get()
bool DRW_state_is_fbo()
DRWShadingGroup * DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup, const char *name, blender::gpu::VertBuf *vertex_buffer)
void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
void DRW_shgroup_call_range(DRWShadingGroup *shgroup, const Object *ob, blender::gpu::Batch *geom, uint v_sta, uint v_num)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, const Object *ob, uint tri_count)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_draw_pass(DRWPass *pass)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end()
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
void DRW_texture_ensure_2d(GPUTexture **tex, int w, int h, eGPUTextureFormat format, DRWTextureFlag flags)
DRWState
Definition draw_state.hh:25
@ DRW_STATE_DEPTH_LESS
Definition draw_state.hh:37
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_LOGIC_INVERT
Definition draw_state.hh:64
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
void GPENCIL_antialiasing_draw(GPENCIL_Data *vedata)
void GPENCIL_antialiasing_init(GPENCIL_Data *vedata)
GPENCIL_tLayer * grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, const Object *ob, const blender::bke::greasepencil::Layer &layer, const int onion_id, const bool is_used_as_mask, GPENCIL_tObject *tgp_ob)
GPENCIL_tLayer * grease_pencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int layer_id, const bool skip_onion)
GPENCIL_tObject * gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob, const bool is_stroke_order_3d, const blender::Bounds< float3 > bounds)
void gpencil_object_cache_sort(GPENCIL_PrivateData *pd)
GPENCIL_MaterialPool * gpencil_material_pool_create(GPENCIL_PrivateData *pd, Object *ob, int *ofs, const bool is_vertex_mode)
void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
GPENCIL_LightPool * gpencil_light_pool_add(GPENCIL_PrivateData *pd)
GPENCIL_ViewLayerData * GPENCIL_view_layer_data_ensure()
void gpencil_light_pool_free(void *storage)
void gpencil_material_pool_free(void *storage)
void gpencil_light_ambient_add(GPENCIL_LightPool *lightpool, const float color[3])
void gpencil_material_resources_get(GPENCIL_MaterialPool *first_pool, int mat_id, GPUTexture **r_tex_stroke, GPUTexture **r_tex_fill, GPUUniformBuf **r_ubo_mat)
struct GPUShader * GPENCIL_shader_mask_invert_get(void)
void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObject *tgp_ob, const bool is_edit_mode)
#define GP_MAX_MASKBITS
void GPENCIL_engine_init(void *vedata)
void GPENCIL_cache_init(void *vedata)
struct GPUShader * GPENCIL_shader_depth_merge_get(void)
void GPENCIL_cache_finish(void *vedata)
void GPENCIL_cache_populate(void *vedata, struct Object *ob)
void GPENCIL_shader_free(void)
DrawEngineType draw_engine_gpencil_type
void GPENCIL_draw_scene(void *vedata)
void GPENCIL_render_to_image(void *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect)
static const DrawEngineDataSize GPENCIL_data_size
void GPENCIL_cache_populate(void *ved, Object *ob)
void GPENCIL_draw_scene(void *ved)
static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL_tLayer *layer)
static void GPENCIL_draw_scene_depth_only(void *ved)
static void GPENCIL_engine_free()
static bool is_used_as_layer_mask_in_viewlayer(const GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &mask_layer, const ViewLayer &view_layer)
void GPENCIL_cache_init(void *ved)
void GPENCIL_cache_finish(void *ved)
static void GPENCIL_draw_object(GPENCIL_Data *vedata, GPENCIL_tObject *ob)
static void GPENCIL_fast_draw_end(GPENCIL_Data *vedata)
static GPENCIL_tObject * grease_pencil_object_cache_populate(GPENCIL_PrivateData *pd, GPENCIL_TextureList *txl, Object *ob)
void GPENCIL_engine_init(void *ved)
static void GPENCIL_fast_draw_start(GPENCIL_Data *vedata)
static bool use_layer_in_render(const GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &layer, const ViewLayer &view_layer, bool &r_is_used_as_mask)
format
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ccl_device_inline float4 mask(const int4 mask, const float4 a)
static ulong state[N]
blender::gpu::Batch * DRW_cache_grease_pencil_get(const Scene *scene, Object *ob)
gpu::VertBuf * DRW_cache_grease_pencil_position_buffer_get(const Scene *scene, Object *ob)
void DRW_cache_gpencil_sbuffer_clear(Object *ob)
gpu::VertBuf * DRW_cache_grease_pencil_color_buffer_get(const Scene *scene, Object *ob)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
IndexMask retrieve_visible_strokes(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
VecBase< float, 3 > float3
char sensor_fit
float sensor_y
float sensor_x
struct CameraDOFSettings dof
ViewLayer * view_layer
Depsgraph * depsgraph
const bContext * evil_C
RegionView3D * rv3d
GPUFrameBuffer * depth_only_fb
GPUFrameBuffer * default_fb
struct GPENCIL_TextureList * txl
struct GPENCIL_PassList * psl
struct GPENCIL_StorageList * stl
struct GPENCIL_FramebufferList * fbl
struct GPUFrameBuffer * render_fb
struct GPUFrameBuffer * snapshot_fb
struct GPUFrameBuffer * mask_fb
struct GPUFrameBuffer * gpencil_fb
struct GPUFrameBuffer * object_fb
struct GPUFrameBuffer * layer_fb
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN]
struct GPUUniformBuf * ubo
struct DRWPass * mask_invert_ps
struct DRWPass * merge_depth_ps
float object_bound_mat[4][4]
GPENCIL_LightPool * last_light_pool
struct BLI_memblock * gp_vfx_pool
struct GPENCIL_PrivateData::@075263135205165144040021316300227366261161172302 tobjects_infront
GPUTexture * scene_depth_tx
struct bGPDstroke * sbuffer_stroke
struct BLI_memblock * gp_layer_pool
GPUTexture * color_object_tx
GPENCIL_LightPool * shadeless_light_pool
struct bGPDlayer * sbuffer_layer
struct ViewLayer * view_layer
struct BLI_memblock * gp_maskbit_pool
blender::gpu::Batch * fill_batch
struct BLI_memblock * gp_object_pool
GPENCIL_tObject * first
blender::gpu::Batch * stroke_batch
GPENCIL_LightPool * global_light_pool
struct GPENCIL_PrivateData::@075263135205165144040021316300227366261161172302 tobjects
struct BLI_memblock * gp_material_pool
struct View3D * v3d
struct GPENCIL_PrivateData::@306021236127224062014147153055313313031254062000 sbuffer_tobjects
GPUFrameBuffer * scene_fb
struct Scene * scene
GPENCIL_tObject * last
GPUTexture * reveal_layer_tx
struct bGPdata * sbuffer_gpd
GPUTexture * color_layer_tx
struct BLI_memblock * gp_light_pool
GPENCIL_MaterialPool * last_material_pool
GPUTexture * reveal_object_tx
struct GPENCIL_PrivateData * pd
struct GPUTexture * snapshot_reveal_tx
struct GPUTexture * snapshot_depth_tx
struct GPUTexture * snapshot_color_tx
struct GPUTexture * render_depth_tx
struct GPUTexture * dummy_texture
struct BLI_memblock * gp_vfx_pool
struct BLI_memblock * gp_material_pool
struct BLI_memblock * gp_maskbit_pool
struct BLI_memblock * gp_light_pool
struct BLI_memblock * gp_layer_pool
struct BLI_memblock * gp_object_pool
DRWShadingGroup * base_shgrp
BLI_bitmap * mask_invert_bits
BLI_bitmap * mask_bits
float plane_mat[4][4]
struct GPENCIL_tObject::@117060204327112013346067233377200155103124235313 vfx
GPENCIL_tLayer * first
struct GPENCIL_tObject::@244154305164030075072341172347154006300235046364 layers
GreasePencilLayerTreeNode base
float viewcamtexcofac[4]
struct ToolSettings * toolsettings
struct World * world
float gpencil_vertex_paint_opacity
View3DOverlay overlay
struct Object * camera
View3DShading shading
char name[64]
#define N_(msgid)