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();
253 &txl->snapshot_depth_tx, size[0], size[1], GPU_DEPTH24_STENCIL8, DRWTextureFlag(0));
255 &txl->snapshot_color_tx, size[0], size[1], GPU_R11F_G11F_B10F, DRWTextureFlag(0));
257 &txl->snapshot_reveal_tx, size[0], size[1], GPU_R11F_G11F_B10F, DRWTextureFlag(0));
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 const bool use_stroke_order_3d = (grease_pencil.flag & GREASE_PENCIL_STROKE_ORDER_3D) != 0;
390 GPENCIL_tObject *tgp_ob = gpencil_object_cache_add(pd, ob, use_stroke_order_3d, bounds);
391
392 int mat_ofs = 0;
393 GPENCIL_MaterialPool *matpool = gpencil_material_pool_create(pd, ob, &mat_ofs, is_vertex_mode);
394
395 GPUTexture *tex_fill = txl->dummy_texture;
396 GPUTexture *tex_stroke = txl->dummy_texture;
397
398 blender::gpu::Batch *iter_geom = nullptr;
399 DRWShadingGroup *grp;
400 int vfirst = 0;
401 int vcount = 0;
402
403 const auto drawcall_flush = [&]() {
404#if !DISABLE_BATCHING
405 if (iter_geom != nullptr) {
406 DRW_shgroup_call_range(grp, ob, iter_geom, vfirst, vcount);
407 }
408#endif
409 iter_geom = nullptr;
410 vfirst = -1;
411 vcount = 0;
412 };
413
414 const auto drawcall_add =
415 [&](blender::gpu::Batch *draw_geom, const int v_first, const int v_count) {
416#if DISABLE_BATCHING
417 DRW_shgroup_call_range(grp, ob, geom, v_first, v_count);
418 return;
419#endif
420 int last = vfirst + vcount;
421 /* Interrupt draw-call grouping if the sequence is not consecutive. */
422 if ((draw_geom != iter_geom) || (v_first - last > 0)) {
423 drawcall_flush();
424 }
425 iter_geom = draw_geom;
426 if (vfirst == -1) {
427 vfirst = v_first;
428 }
429 vcount = v_first + v_count - vfirst;
430 };
431
432 int t_offset = 0;
433 /* Note that we loop over all the drawings (including the onion skinned ones) to make sure we
434 * match the offsets of the batch cache. */
435 const Vector<DrawingInfo> drawings = retrieve_visible_drawings(*pd->scene, grease_pencil, true);
436 const Span<const Layer *> layers = grease_pencil.layers();
437 for (const DrawingInfo info : drawings) {
438 const Layer &layer = *layers[info.layer_index];
439
440 const bke::CurvesGeometry &curves = info.drawing.strokes();
441 const OffsetIndices<int> points_by_curve = curves.evaluated_points_by_curve();
442 const bke::AttributeAccessor attributes = curves.attributes();
443 const VArray<bool> cyclic = *attributes.lookup_or_default<bool>(
444 "cyclic", bke::AttrDomain::Curve, false);
445
446 IndexMaskMemory memory;
447 const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
448 *ob, info.drawing, memory);
449
450 /* Precompute all the triangle and vertex counts.
451 * In case the drawing should not be rendered, we need to compute the offset where the next
452 * drawing begins. */
453 Array<int> num_triangles_per_stroke(visible_strokes.size());
454 Array<int> num_vertices_per_stroke(visible_strokes.size());
455 int total_num_triangles = 0;
456 int total_num_vertices = 0;
457 visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
458 const IndexRange points = points_by_curve[stroke_i];
459 const int num_stroke_triangles = (points.size() >= 3) ? (points.size() - 2) : 0;
460 const int num_stroke_vertices = (points.size() +
461 int(cyclic[stroke_i] && (points.size() >= 3)));
462 num_triangles_per_stroke[pos] = num_stroke_triangles;
463 num_vertices_per_stroke[pos] = num_stroke_vertices;
464 total_num_triangles += num_stroke_triangles;
465 total_num_vertices += num_stroke_vertices;
466 });
467
468 bool is_layer_used_as_mask = false;
469 const bool show_drawing_in_render = use_layer_in_render(
470 grease_pencil, layer, *pd->view_layer, is_layer_used_as_mask);
471 if (!show_drawing_in_render) {
472 /* Skip over the entire drawing. */
473 t_offset += total_num_triangles;
474 t_offset += total_num_vertices * 2;
475 continue;
476 }
477
478 drawcall_flush();
479
481 pd, ob, layer, info.onion_id, is_layer_used_as_mask, tgp_ob);
482
483 const bool use_lights = pd->use_lighting &&
484 ((layer.base.flag & GP_LAYER_TREE_NODE_USE_LIGHTS) != 0) &&
486
487 GPUUniformBuf *lights_ubo = (use_lights) ? pd->global_light_pool->ubo :
489
490 GPUUniformBuf *ubo_mat;
491 gpencil_material_resources_get(matpool, 0, nullptr, nullptr, &ubo_mat);
492
493 grp = tgp_layer->base_shgrp;
494 DRW_shgroup_uniform_block(grp, "gp_lights", lights_ubo);
495 DRW_shgroup_uniform_block(grp, "gp_materials", ubo_mat);
496 DRW_shgroup_uniform_texture(grp, "gpFillTexture", tex_fill);
497 DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", tex_stroke);
498 DRW_shgroup_uniform_int_copy(grp, "gpMaterialOffset", mat_ofs);
499 /* Since we don't use the sbuffer in GPv3, this is always 0. */
500 DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0.0f);
502
503 const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
504 "material_index", bke::AttrDomain::Curve, 0);
505
506 const bool only_lines = !ELEM(ob->mode,
510 info.frame_number != pd->cfra && pd->use_multiedit_lines_only &&
511 do_multi_frame;
512 const bool is_onion = info.onion_id != 0;
513
514 visible_strokes.foreach_index([&](const int stroke_i, const int pos) {
515 const IndexRange points = points_by_curve[stroke_i];
516 /* The material index is allowed to be negative as it's stored as a generic attribute. We
517 * clamp it here to avoid crashing in the rendering code. Any stroke with a material < 0 will
518 * use the first material in the first material slot.*/
519 const int material_index = std::max(stroke_materials[stroke_i], 0);
520 const MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, material_index + 1);
521
522 const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
523 const bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0);
524 const bool show_fill = (points.size() >= 3) &&
525 ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0) &&
526 (!pd->simplify_fill);
527 const bool hide_onion = is_onion && ((gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN) != 0 ||
528 (!do_onion && !do_multi_frame));
529 const bool skip_stroke = hide_material || (!show_stroke && !show_fill) ||
530 (only_lines && !do_onion && is_onion) || hide_onion;
531
532 if (skip_stroke) {
533 t_offset += num_triangles_per_stroke[pos];
534 t_offset += num_vertices_per_stroke[pos] * 2;
535 return;
536 }
537
538 GPUUniformBuf *new_ubo_mat;
539 GPUTexture *new_tex_fill = nullptr;
540 GPUTexture *new_tex_stroke = nullptr;
542 matpool, mat_ofs + material_index, &new_tex_stroke, &new_tex_fill, &new_ubo_mat);
543
544 const bool resource_changed = (ubo_mat != new_ubo_mat) ||
545 (new_tex_fill && (new_tex_fill != tex_fill)) ||
546 (new_tex_stroke && (new_tex_stroke != tex_stroke));
547
548 if (resource_changed) {
549 drawcall_flush();
550
551 grp = DRW_shgroup_create_sub(grp);
552 if (new_ubo_mat != ubo_mat) {
553 DRW_shgroup_uniform_block(grp, "gp_materials", new_ubo_mat);
554 ubo_mat = new_ubo_mat;
555 }
556 if (new_tex_fill) {
557 DRW_shgroup_uniform_texture(grp, "gpFillTexture", new_tex_fill);
558 tex_fill = new_tex_fill;
559 }
560 if (new_tex_stroke) {
561 DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", new_tex_stroke);
562 tex_stroke = new_tex_stroke;
563 }
564 }
565
566 blender::gpu::Batch *geom = draw::DRW_cache_grease_pencil_get(pd->scene, ob);
567 if (iter_geom != geom) {
568 drawcall_flush();
569
570 blender::gpu::VertBuf *position_tx = draw::DRW_cache_grease_pencil_position_buffer_get(
571 pd->scene, ob);
572 blender::gpu::VertBuf *color_tx = draw::DRW_cache_grease_pencil_color_buffer_get(pd->scene,
573 ob);
574 DRW_shgroup_buffer_texture(grp, "gp_pos_tx", position_tx);
575 DRW_shgroup_buffer_texture(grp, "gp_col_tx", color_tx);
576 }
577
578 if (show_fill) {
579 const int v_first = t_offset * 3;
580 const int v_count = num_triangles_per_stroke[pos] * 3;
581 drawcall_add(geom, v_first, v_count);
582 }
583
584 t_offset += num_triangles_per_stroke[pos];
585
586 if (show_stroke) {
587 const int v_first = t_offset * 3;
588 const int v_count = num_vertices_per_stroke[pos] * 2 * 3;
589 drawcall_add(geom, v_first, v_count);
590 }
591
592 t_offset += num_vertices_per_stroke[pos] * 2;
593 });
594 }
595
596 drawcall_flush();
597
598 return tgp_ob;
599}
600
601void GPENCIL_cache_populate(void *ved, Object *ob)
602{
603 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
604 GPENCIL_PrivateData *pd = vedata->stl->pd;
605 GPENCIL_TextureList *txl = vedata->txl;
606
607 /* object must be visible */
609 return;
610 }
611
612 if (ob->data && (ob->type == OB_GREASE_PENCIL) && (ob->dt >= OB_SOLID)) {
615 vedata,
616 ob,
617 tgp_ob,
619 }
620
621 if (ob->type == OB_LAMP && pd->use_lights) {
623 }
624}
625
626void GPENCIL_cache_finish(void *ved)
627{
628 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
629 GPENCIL_PrivateData *pd = vedata->stl->pd;
630 GPENCIL_FramebufferList *fbl = vedata->fbl;
631
632 /* Upload UBO data. */
636 while ((pool = (GPENCIL_MaterialPool *)BLI_memblock_iterstep(&iter))) {
637 GPU_uniformbuf_update(pool->ubo, pool->mat_data);
638 }
639
641 GPENCIL_LightPool *lpool;
642 while ((lpool = (GPENCIL_LightPool *)BLI_memblock_iterstep(&iter))) {
643 GPU_uniformbuf_update(lpool->ubo, lpool->light_data);
644 }
645
646 /* Sort object by decreasing Z to avoid most of alpha ordering issues. */
648
649 /* Create frame-buffers only if needed. */
650 if (pd->tobjects.first) {
652
653 const float *size = DRW_viewport_size_get();
658
660 {
661 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
662 GPU_ATTACHMENT_TEXTURE(pd->color_tx),
663 GPU_ATTACHMENT_TEXTURE(pd->reveal_tx),
664 });
665
666 if (pd->use_layer_fb) {
668 size[0], size[1], format, &draw_engine_gpencil_type);
670 size[0], size[1], format, &draw_engine_gpencil_type);
671
673 {
674 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
675 GPU_ATTACHMENT_TEXTURE(pd->color_layer_tx),
676 GPU_ATTACHMENT_TEXTURE(pd->reveal_layer_tx),
677 });
678 }
679
680 if (pd->use_object_fb) {
682 size[0], size[1], format, &draw_engine_gpencil_type);
684 size[0], size[1], format, &draw_engine_gpencil_type);
685
687 {
688 GPU_ATTACHMENT_TEXTURE(pd->depth_tx),
689 GPU_ATTACHMENT_TEXTURE(pd->color_object_tx),
690 GPU_ATTACHMENT_TEXTURE(pd->reveal_object_tx),
691 });
692 }
693
694 if (pd->use_mask_fb) {
695 /* We need an extra depth to not disturb the normal drawing.
696 * The color_tx is needed for frame-buffer completeness. */
697 GPUTexture *color_tx, *depth_tx;
698 depth_tx = DRW_texture_pool_query_2d(
701 /* Use high quality format for render. */
702 eGPUTextureFormat mask_format = pd->is_render ? GPU_R16 : GPU_R8;
704 size[0], size[1], mask_format, &draw_engine_gpencil_type);
705
707 {
708 GPU_ATTACHMENT_TEXTURE(depth_tx),
709 GPU_ATTACHMENT_TEXTURE(color_tx),
710 GPU_ATTACHMENT_TEXTURE(pd->mask_tx),
711 });
712 }
713
715 }
716}
717
718static void GPENCIL_draw_scene_depth_only(void *ved)
719{
720 using namespace blender::draw;
721 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
722 GPENCIL_PrivateData *pd = vedata->stl->pd;
724
725 if (DRW_state_is_fbo()) {
727 }
728
730 LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
731 DRW_draw_pass(layer->geom_ps);
732 }
733 }
734
735 if (DRW_state_is_fbo()) {
737 }
738
739 pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = nullptr;
740
741 /* Free temp stroke buffers. */
742 if (pd->sbuffer_gpd) {
743 DRW_cache_gpencil_sbuffer_clear(pd->obact);
744 }
745}
746
748{
749 GPENCIL_PassList *psl = vedata->psl;
750 GPENCIL_FramebufferList *fbl = vedata->fbl;
751 const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
752 float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f;
753 bool inverted = false;
754 /* OPTI(@fclem): we could optimize by only clearing if the new mask_bits does not contain all
755 * the masks already rendered in the buffer, and drawing only the layers not already drawn. */
756 bool cleared = false;
757
758 DRW_stats_group_start("GPencil Mask");
759
761
762 for (int i = 0; i < GP_MAX_MASKBITS; i++) {
763 if (!BLI_BITMAP_TEST(layer->mask_bits, i)) {
764 continue;
765 }
766
767 if (BLI_BITMAP_TEST_BOOL(layer->mask_invert_bits, i) != inverted) {
768 if (cleared) {
770 }
771 inverted = !inverted;
772 }
773
774 if (!cleared) {
775 cleared = true;
776 GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth);
777 }
778
779 GPENCIL_tLayer *mask_layer = grease_pencil_layer_cache_get(ob, i, true);
780 /* When filtering by view-layer, the mask could be null and must be ignored. */
781 if (mask_layer == nullptr) {
782 continue;
783 }
784
785 DRW_draw_pass(mask_layer->geom_ps);
786 }
787
788 if (!inverted) {
789 /* Blend shader expect an opacity mask not a reavealage buffer. */
791 }
792
794}
795
797{
798 GPENCIL_PassList *psl = vedata->psl;
799 GPENCIL_PrivateData *pd = vedata->stl->pd;
800 GPENCIL_FramebufferList *fbl = vedata->fbl;
801 const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
802
803 DRW_stats_group_start("GPencil Object");
804
805 GPUFrameBuffer *fb_object = (ob->vfx.first) ? fbl->object_fb : fbl->gpencil_fb;
806
807 GPU_framebuffer_bind(fb_object);
808 GPU_framebuffer_clear_depth_stencil(fb_object, ob->is_drawmode3d ? 1.0f : 0.0f, 0x00);
809
810 if (ob->vfx.first) {
811 GPU_framebuffer_multi_clear(fb_object, clear_cols);
812 }
813
814 LISTBASE_FOREACH (GPENCIL_tLayer *, layer, &ob->layers) {
815 if (layer->mask_bits) {
816 gpencil_draw_mask(vedata, ob, layer);
817 }
818
819 if (layer->blend_ps) {
821 GPU_framebuffer_multi_clear(fbl->layer_fb, clear_cols);
822 }
823 else {
824 GPU_framebuffer_bind(fb_object);
825 }
826
827 DRW_draw_pass(layer->geom_ps);
828
829 if (layer->blend_ps) {
830 GPU_framebuffer_bind(fb_object);
831 DRW_draw_pass(layer->blend_ps);
832 }
833 }
834
835 LISTBASE_FOREACH (GPENCIL_tVfx *, vfx, &ob->vfx) {
836 GPU_framebuffer_bind(*(vfx->target_fb));
837 DRW_draw_pass(vfx->vfx_ps);
838 }
839
842
843 if (pd->scene_fb) {
846 }
847
849}
850
852{
853 GPENCIL_PrivateData *pd = vedata->stl->pd;
854 GPENCIL_FramebufferList *fbl = vedata->fbl;
856
857 if (!pd->snapshot_buffer_dirty) {
858 /* Copy back cached render. */
862 /* Bypass drawing. */
863 pd->tobjects.first = pd->tobjects.last = nullptr;
864 }
865}
866
868{
869 GPENCIL_PrivateData *pd = vedata->stl->pd;
870 GPENCIL_FramebufferList *fbl = vedata->fbl;
872
873 if (pd->snapshot_buffer_dirty) {
874 /* Save to snapshot buffer. */
878 pd->snapshot_buffer_dirty = false;
879 }
880 /* Draw the sbuffer stroke(s). */
882 GPENCIL_draw_object(vedata, ob);
883 }
884}
885
886void GPENCIL_draw_scene(void *ved)
887{
888 using namespace blender::draw;
889 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
890 GPENCIL_PrivateData *pd = vedata->stl->pd;
891 GPENCIL_FramebufferList *fbl = vedata->fbl;
892 float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
893
894 /* Fade 3D objects. */
895 if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f) && (pd->obact != nullptr) &&
897 {
898 float background_color[3];
899 ED_view3d_background_color_get(pd->scene, pd->v3d, background_color);
900 /* Blend color. */
901 interp_v3_v3v3(clear_cols[0], background_color, clear_cols[0], pd->fade_3d_object_opacity);
902
903 mul_v4_fl(clear_cols[1], pd->fade_3d_object_opacity);
904 }
905
906 if (pd->draw_depth_only) {
908 return;
909 }
910
911 if (pd->tobjects.first == nullptr) {
912 return;
913 }
914
915 if (pd->do_fast_drawing) {
917 }
918
919 if (pd->tobjects.first) {
921 GPU_framebuffer_multi_clear(fbl->gpencil_fb, clear_cols);
922 }
923
925 GPENCIL_draw_object(vedata, ob);
926 }
927
928 if (pd->do_fast_drawing) {
929 GPENCIL_fast_draw_end(vedata);
930 }
931
932 if (pd->scene_fb) {
934 }
935
936 pd->gp_object_pool = pd->gp_layer_pool = pd->gp_vfx_pool = pd->gp_maskbit_pool = nullptr;
937
938 /* Free temp stroke buffers. */
939 if (pd->sbuffer_gpd) {
940 DRW_cache_gpencil_sbuffer_clear(pd->obact);
941 }
942}
943
945{
947}
948
950
952 /*next*/ nullptr,
953 /*prev*/ nullptr,
954 /*idname*/ N_("GpencilMode"),
955 /*vedata_size*/ &GPENCIL_data_size,
956 /*engine_init*/ &GPENCIL_engine_init,
957 /*engine_free*/ &GPENCIL_engine_free,
958 /*instance_free*/ nullptr,
959 /*cache_init*/ &GPENCIL_cache_init,
960 /*cache_populate*/ &GPENCIL_cache_populate,
961 /*cache_finish*/ &GPENCIL_cache_finish,
962 /*draw_scene*/ &GPENCIL_draw_scene,
963 /*view_update*/ nullptr,
964 /*id_update*/ nullptr,
965 /*render_to_image*/ &GPENCIL_render_to_image,
966 /*store_metadata*/ nullptr,
967};
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_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
@ OB_CAMERA
@ OB_GREASE_PENCIL
@ OB_LAMP
@ OB_GPENCIL_LEGACY
@ OB_USE_GPENCIL_LIGHTS
@ GP_USE_MULTI_FRAME_EDITING
@ V3D_SHADING_VERTEX_COLOR
#define V3D_USES_SCENE_WORLD(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
#define V3D_USES_SCENE_LIGHTS(v3d)
@ RV3D_CAMOB
@ V3D_HIDE_OVERLAYS
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)
struct GPUShader GPUShader
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
OffsetIndices< int > evaluated_points_by_curve() 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
struct GPUShader * GPENCIL_shader_depth_merge_get(void)
void GPENCIL_shader_free(void)
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)
DrawEngineType draw_engine_gpencil_type
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
static ulong state[N]
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
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 GPENCIL_PrivateData::@202 tobjects_infront
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::@203 sbuffer_tobjects
struct BLI_memblock * gp_material_pool
struct View3D * v3d
struct GPENCIL_PrivateData::@202 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
float plane_mat[4][4]
struct GPENCIL_tObject::@201 vfx
GPENCIL_tLayer * first
struct GPENCIL_tObject::@200 layers
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)