Blender V5.0
grease_pencil_image_render.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_color.hh"
6#include "BLI_math_geom.h"
7#include "BLI_math_matrix.hh"
8#include "BLI_math_vector.hh"
9
10#include "BKE_attribute.hh"
11#include "BKE_camera.h"
12#include "BKE_curves.hh"
13#include "BKE_grease_pencil.hh"
14#include "BKE_image.hh"
15#include "BKE_material.hh"
16
18#include "DNA_material_types.h"
19#include "DNA_object_types.h"
20#include "DNA_scene_types.h"
21#include "DNA_userdef_types.h"
22#include "DNA_view3d_types.h"
23
24#include "ED_grease_pencil.hh"
25#include "ED_view3d.hh"
26
27#include "IMB_imbuf.hh"
28#include "IMB_imbuf_types.hh"
29
30#include "GPU_debug.hh"
31#include "GPU_framebuffer.hh"
32#include "GPU_immediate.hh"
33#include "GPU_matrix.hh"
34#include "GPU_primitive.hh"
35#include "GPU_shader_builtin.hh"
36#include "GPU_shader_shared.hh"
37#include "GPU_state.hh"
38#include "GPU_texture.hh"
39#include "GPU_uniform_buffer.hh"
40#include "GPU_vertex_format.hh"
41
43
44/* Enable GPU debug capture (needs WITH_RENDERDOC option). */
45constexpr const bool enable_debug_gpu_capture = true;
46
47RegionViewData region_init(ARegion &region, const int2 &win_size)
48{
49 RegionView3D &rv3d = *static_cast<RegionView3D *>(region.regiondata);
50
51 const RegionViewData data = {
52 int2{region.winx, region.winy}, region.winrct, ED_view3d_mats_rv3d_backup(&rv3d)};
53
54 /* Resize region. */
55 region.winrct.xmin = 0;
56 region.winrct.ymin = 0;
57 region.winrct.xmax = win_size.x;
58 region.winrct.ymax = win_size.y;
59 region.winx = short(win_size.x);
60 region.winy = short(win_size.y);
61
62 return data;
63}
64
66{
67 RegionView3D &rv3d = *static_cast<RegionView3D *>(region.regiondata);
68
69 region.winx = data.winsize.x;
70 region.winy = data.winsize.y;
71 region.winrct = data.winrct;
72
73 ED_view3d_mats_rv3d_restore(&rv3d, data.rv3d_store);
75}
76
78{
80 GPU_debug_capture_begin("Grease Pencil Image Render");
81 }
82
83 char err_out[256] = "unknown";
84 GPUOffScreen *offscreen = GPU_offscreen_create(win_size.x,
85 win_size.y,
86 true,
87 blender::gpu::TextureFormat::UNORM_8_8_8_8,
89 false,
90 err_out);
91 if (offscreen == nullptr) {
92 return nullptr;
93 }
94
95 GPU_offscreen_bind(offscreen, true);
96
101
102 GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
103 GPU_clear_depth(1.0f);
104
105 return offscreen;
106}
107
109{
112
113 const int2 win_size = {GPU_offscreen_width(buffer), GPU_offscreen_height(buffer)};
114 const uint imb_flag = IB_byte_data;
115 ImBuf *ibuf = IMB_allocImBuf(win_size.x, win_size.y, 32, imb_flag);
116 if (ibuf->float_buffer.data) {
118 }
119 else if (ibuf->byte_buffer.data) {
121 }
122 if (ibuf->float_buffer.data && ibuf->byte_buffer.data) {
124 }
125
126 Image *ima = BKE_image_add_from_imbuf(&bmain, ibuf, "Grease Pencil Fill");
127 ima->id.tag |= ID_TAG_DOIT;
128
129 BKE_image_release_ibuf(ima, ibuf, nullptr);
130
131 /* Switch back to regular frame-buffer. */
132 GPU_offscreen_unbind(buffer, true);
133 GPU_offscreen_free(buffer);
134
137 }
138
139 return ima;
140}
141
142void compute_view_matrices(const ViewContext &view_context,
143 const Scene &scene,
144 const int2 &win_size,
145 const float2 &zoom,
146 const float2 &offset)
147{
148 rctf viewplane;
149 float clip_start, clip_end;
150 const bool is_ortho = ED_view3d_viewplane_get(view_context.depsgraph,
151 view_context.v3d,
152 view_context.rv3d,
153 win_size.x,
154 win_size.y,
155 &viewplane,
156 &clip_start,
157 &clip_end,
158 nullptr);
159
160 /* Rescale `viewplane` to fit all strokes. */
161 const float2 view_min = float2(viewplane.xmin, viewplane.ymin);
162 const float2 view_max = float2(viewplane.xmax, viewplane.ymax);
163 const float2 view_extent = view_max - view_min;
164 const float2 view_center = 0.5f * (view_max + view_min);
165 const float2 offset_abs = offset * view_extent;
166 const float2 view_min_new = (view_min - view_center) * zoom + view_center + offset_abs;
167 const float2 view_max_new = (view_max - view_center) * zoom + view_center + offset_abs;
168 viewplane.xmin = view_min_new.x;
169 viewplane.ymin = view_min_new.y;
170 viewplane.xmax = view_max_new.x;
171 viewplane.ymax = view_max_new.y;
172
173 float4x4 winmat;
174 if (is_ortho) {
175 orthographic_m4(winmat.ptr(),
176 viewplane.xmin,
177 viewplane.xmax,
178 viewplane.ymin,
179 viewplane.ymax,
180 -clip_end,
181 clip_end);
182 }
183 else {
184 perspective_m4(winmat.ptr(),
185 viewplane.xmin,
186 viewplane.xmax,
187 viewplane.ymin,
188 viewplane.ymax,
189 clip_start,
190 clip_end);
191 }
192
194 &scene,
195 view_context.v3d,
196 view_context.region,
197 nullptr,
198 winmat.ptr(),
199 nullptr,
200 true);
201}
202
204{
206}
207
212
217
222
224 const float3 &position,
225 const float point_size,
226 const ColorGeometry4f &color)
227{
229 uint attr_pos = GPU_vertformat_attr_add(
230 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
231 uint attr_size = GPU_vertformat_attr_add(format, "size", blender::gpu::VertAttrType::SFLOAT_32);
232 uint attr_color = GPU_vertformat_attr_add(
233 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
234
238 immAttr1f(attr_size, point_size * M_SQRT2);
239 immAttr4fv(attr_color, color);
240 immVertex3fv(attr_pos, math::transform_point(transform, position));
241 immEnd();
244}
245
247 const IndexRange indices,
248 Span<float3> positions,
249 const VArray<ColorGeometry4f> &colors,
250 const bool cyclic,
251 const float line_width)
252{
254 const uint attr_pos = GPU_vertformat_attr_add(
255 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
256 const uint attr_color = GPU_vertformat_attr_add(
257 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
259
260 GPU_line_width(line_width);
261 /* If cyclic the curve needs one more vertex. */
262 const int cyclic_add = (cyclic && indices.size() > 2) ? 1 : 0;
263 immBeginAtMost(GPU_PRIM_LINE_STRIP, indices.size() + cyclic_add);
264
265 for (const int point_i : indices) {
266 immAttr4fv(attr_color, colors[point_i]);
267 immVertex3fv(attr_pos, math::transform_point(transform, positions[point_i]));
268 }
269
270 if (cyclic && indices.size() > 2) {
271 const int point_i = indices[0];
272 immAttr4fv(attr_color, colors[point_i]);
273 immVertex3fv(attr_pos, math::transform_point(transform, positions[point_i]));
274 }
275
276 immEnd();
278}
279
281 const int2 &win_size,
282 const Object &object,
283 const eGPDstroke_Caps cap_start,
284 const eGPDstroke_Caps cap_end,
285 const bool is_fill_stroke)
286{
288 copy_v2_v2(data.viewport, float2(win_size));
289 data.pixsize = rv3d.pixsize;
290 data.objscale = math::average(float3(object.scale));
291 /* TODO Was based on the GP_DATA_STROKE_KEEPTHICKNESS flag which is currently not converted. */
292 data.keep_size = false;
293 data.pixfactor = 1.0f;
294 /* X-ray mode always to 3D space to avoid wrong Z-depth calculation (#60051). */
295 data.xraymode = GP_XRAY_3DSPACE;
296 data.caps_start = cap_start;
297 data.caps_end = cap_end;
298 data.fill_stroke = is_fill_stroke;
299
300 return GPU_uniformbuf_create_ex(sizeof(GPencilStrokeData), &data, __func__);
301}
302
303constexpr const float min_stroke_thickness = 0.05f;
304
306 const RegionView3D &rv3d,
307 const int2 &win_size,
308 const Object &object,
309 const IndexRange indices,
310 Span<float3> positions,
311 const VArray<float> &radii,
312 const VArray<ColorGeometry4f> &colors,
313 const bool cyclic,
314 const eGPDstroke_Caps cap_start,
315 const eGPDstroke_Caps cap_end,
316 const bool fill_stroke,
317 const float radius_scale)
318{
319 if (indices.is_empty()) {
320 return;
321 }
322
324 /* Format is matching shader manual load. Keep in sync with #GreasePencilStrokeData.
325 * Only the name of the first attribute is important. */
326 const uint attr_pos = GPU_vertformat_attr_add(
327 format, "gp_vert_data", blender::gpu::VertAttrType::SFLOAT_32_32_32);
328 const uint attr_thickness = GPU_vertformat_attr_add(
329 format, "thickness", blender::gpu::VertAttrType::SFLOAT_32);
330 const uint attr_color = GPU_vertformat_attr_add(
331 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
332
335 rv3d, win_size, object, cap_start, cap_end, fill_stroke);
336 immBindUniformBuf("gpencil_stroke_data", ubo);
337
338 /* If cyclic the curve needs one more vertex. */
339 const int cyclic_add = (cyclic && indices.size() > 2) ? 1 : 0;
340
342 indices.size() + cyclic_add + 2);
343
344 auto draw_point = [&](const int point_i) {
345 constexpr const float radius_to_pixel_factor =
347 const float thickness = radii[point_i] * radius_scale * radius_to_pixel_factor;
348
349 immAttr4fv(attr_color, colors[point_i]);
350 immAttr1f(attr_thickness, std::max(thickness, min_stroke_thickness));
351 immVertex3fv(attr_pos, math::transform_point(transform, positions[point_i]));
352 };
353
354 /* First point for adjacency (not drawn). */
355 if (cyclic && indices.size() > 2) {
356 draw_point(indices.last() - 1);
357 }
358 else {
359 draw_point(indices.first() + 1);
360 }
361
362 for (const int point_i : indices) {
363 draw_point(point_i);
364 }
365
366 if (cyclic && indices.size() > 2) {
367 draw_point(indices.first());
368 draw_point(indices.first() + 1);
369 }
370 /* Last adjacency point (not drawn). */
371 else {
372 draw_point(indices.last() - 1);
373 }
374
375 immEnd();
376
377 /* Expanded `drawcall`. */
378 GPUPrimType expand_prim_type = GPUPrimType::GPU_PRIM_TRIS;
379 /* Hard-coded in shader. */
380 const uint expand_prim_len = 12;
381 /* Do not count adjacency info for start and end primitives. */
382 const uint final_vert_len = ((batch->vertex_count_get() - 2) * expand_prim_len) * 3;
383
384 if (final_vert_len > 0) {
386
387 /* TODO(fclem): get rid of this dummy VBO. */
388 GPUVertFormat format = {0};
389 GPU_vertformat_attr_add(&format, "dummy", gpu::VertAttrType::SFLOAT_32);
391 GPU_vertbuf_data_alloc(*vbo, 1);
392
393 gpu::Batch *gpu_batch = GPU_batch_create_ex(
394 expand_prim_type, vbo, nullptr, GPU_BATCH_OWNS_VBO);
395
396 GPU_batch_set_shader(gpu_batch, batch->shader);
397 GPU_batch_draw_advanced(gpu_batch, 0, final_vert_len, 0, 1);
398
399 GPU_batch_discard(gpu_batch);
400 }
402
404
406}
407
408static void draw_dots(const float4x4 &transform,
409 const IndexRange indices,
410 Span<float3> positions,
411 const VArray<float> &radii,
412 const VArray<ColorGeometry4f> &colors,
413 const float radius_scale)
414{
415 if (indices.is_empty()) {
416 return;
417 }
418
420 const uint attr_pos = GPU_vertformat_attr_add(
421 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
423 format, "size", blender::gpu::VertAttrType::SFLOAT_32);
424 const uint attr_color = GPU_vertformat_attr_add(
425 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
426
429
431
432 for (const int point_i : indices) {
433 constexpr const float radius_to_pixel_factor =
435 const float thickness = radii[point_i] * radius_scale * radius_to_pixel_factor;
436
437 immAttr4fv(attr_color, colors[point_i]);
438 /* NOTE: extra factor 0.5 for point size to match rendering. */
439 immAttr1f(attr_size, std::max(thickness, min_stroke_thickness) * 0.5f);
440 immVertex3fv(attr_pos, math::transform_point(transform, positions[point_i]));
441 }
442
443 immEnd();
446}
447
449 const IndexRange indices,
450 Span<float3> centers,
451 const VArray<float> &radii,
452 const VArray<ColorGeometry4f> &colors,
453 const float2 &viewport_size,
454 const float line_width,
455 const bool fill)
456{
457 if (indices.is_empty()) {
458 return;
459 }
460
461 constexpr const int segments_num = 32;
462 static const float2 coords[] = {
463 {1.0000f, 0.0000f}, {0.9808f, 0.1951f}, {0.9239f, 0.3827f}, {0.8315f, 0.5556f},
464 {0.7071f, 0.7071f}, {0.5556f, 0.8315f}, {0.3827f, 0.9239f}, {0.1951f, 0.9808f},
465 {0.0000f, 1.0000f}, {-0.1951f, 0.9808f}, {-0.3827f, 0.9239f}, {-0.5556f, 0.8315f},
466 {-0.7071f, 0.7071f}, {-0.8315f, 0.5556f}, {-0.9239f, 0.3827f}, {-0.9808f, 0.1951f},
467 {-1.0000f, 0.0000f}, {-0.9808f, -0.1951f}, {-0.9239f, -0.3827f}, {-0.8315f, -0.5556f},
468 {-0.7071f, -0.7071f}, {-0.5556f, -0.8315f}, {-0.3827f, -0.9239f}, {-0.1951f, -0.9808f},
469 {-0.0000f, -1.0000f}, {0.1951f, -0.9808f}, {0.3827f, -0.9239f}, {0.5556f, -0.8315f},
470 {0.7071f, -0.7071f}, {0.8315f, -0.5556f}, {0.9239f, -0.3827f}, {0.9808f, -0.1951f},
471 };
472
474 const uint attr_pos = GPU_vertformat_attr_add(
475 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
476 const uint attr_color = GPU_vertformat_attr_add(
477 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
478
479 const float scale = math::average(math::to_scale(transform));
480
481 if (fill) {
483
484 for (const int point_i : indices) {
485 const float radius = radii[point_i];
486 const ColorGeometry4f color = colors[point_i];
487 const float3 center = math::transform_point(transform, centers[point_i]);
488
489 immBegin(GPU_PRIM_TRI_STRIP, segments_num);
490
491 for (const int i : IndexRange(segments_num / 2)) {
492 immAttr4fv(attr_color, color);
493 immVertex3fv(attr_pos, center + float3(radius * scale * coords[i], 0.0f));
494 if (segments_num - 1 - i > i) {
495 immAttr4fv(attr_color, color);
496 immVertex3fv(attr_pos,
497 center + float3(radius * scale * coords[segments_num - 1 - i], 0.0f));
498 }
499 }
500
501 immEnd();
502 }
503
505 }
506 else {
508
509 immUniform2fv("viewportSize", viewport_size);
510 immUniform1f("lineWidth", line_width * U.pixelsize);
511
512 for (const int point_i : indices) {
513 const float radius = radii[point_i];
514 const ColorGeometry4f color = colors[point_i];
515 const float3 center = math::transform_point(transform, centers[point_i]);
516
517 immBegin(GPU_PRIM_LINE_STRIP, segments_num + 1);
518
519 for (const int i : IndexRange(segments_num)) {
520 immAttr4fv(attr_color, color);
521 immVertex3fv(attr_pos, center + float3(radius * scale * coords[i], 0.0f));
522 }
523 immAttr4fv(attr_color, color);
524 immVertex3fv(attr_pos, center + float3(radius * scale * coords[0], 0.0f));
525
526 immEnd();
527 }
528
530 }
531}
532
535 Span<float3> start_positions,
536 Span<float3> end_positions,
537 const VArray<ColorGeometry4f> &colors,
538 float line_width)
539{
541 const uint attr_pos = GPU_vertformat_attr_add(
542 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
543 const uint attr_color = GPU_vertformat_attr_add(
544 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
546
547 GPU_line_width(line_width);
549
550 for (const int point_i : indices) {
551 immAttr4fv(attr_color, colors[point_i]);
552 immVertex3fv(attr_pos, math::transform_point(transform, start_positions[point_i]));
553
554 immAttr4fv(attr_color, colors[point_i]);
555 immVertex3fv(attr_pos, math::transform_point(transform, end_positions[point_i]));
556 }
557
558 immEnd();
560}
561
563{
564 if (curves.is_single_type(CURVE_TYPE_POLY)) {
566 }
567
568 const CPPType &type = input.type();
569 GArray<> out(type, curves.evaluated_points_num());
570 curves.interpolate_to_evaluated(input, out.as_mutable_span());
571 return GVArray::from_garray(std::move(out));
572};
573
575 const int2 &win_size,
576 const Object &object,
577 const bke::greasepencil::Drawing &drawing,
578 const float4x4 &transform,
579 const IndexMask &strokes_mask,
580 const VArray<ColorGeometry4f> &colors,
581 const bool use_xray,
582 const float radius_scale)
583{
584 set_view_matrix(rv3d);
585
587 /* Do not write to depth (avoid self-occlusion). */
588 const bool prev_depth_mask = GPU_depth_mask_get();
589 GPU_depth_mask(false);
590 if (!use_xray) {
592 /* First arg is normally rv3d->dist, but this isn't
593 * available here and seems to work quite well without. */
594 GPU_polygon_offset(1.0f, 1.0f);
595 }
596
597 const bke::CurvesGeometry &curves = drawing.strokes();
598 const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
599 const Span<float3> positions = curves.evaluated_positions();
600 const bke::AttributeAccessor attributes = curves.attributes();
601 const VArray<bool> cyclic = curves.cyclic();
602
603 curves.ensure_can_interpolate_to_evaluated();
604
605 const VArray<float> radii =
606 attribute_interpolate(VArraySpan(drawing.radii()), curves).typed<float>();
607 const VArray<ColorGeometry4f> eval_colors =
609
610 const VArray<int8_t> stroke_start_caps = *attributes.lookup_or_default<int8_t>(
612 const VArray<int8_t> stroke_end_caps = *attributes.lookup_or_default<int8_t>(
614 const VArray<int> materials = *attributes.lookup_or_default<int>(
615 "material_index", bke::AttrDomain::Curve, 0);
616
617 /* Note: Serial loop without GrainSize, since immediate mode drawing can't happen in worker
618 * threads, has to be from the main thread. */
619 strokes_mask.foreach_index([&](const int stroke_i) {
620 /* Check if the color is visible. */
621 const int material_index = materials[stroke_i];
622 const Material *mat = BKE_object_material_get(const_cast<Object *>(&object),
623 material_index + 1);
624 const eMaterialGPencilStyle_Mode stroke_mode = mat && mat->gp_style ?
626 mat->gp_style->mode) :
628
629 if (mat == nullptr || (mat->gp_style->flag & GP_MATERIAL_HIDE)) {
630 return;
631 }
632
633 switch (eMaterialGPencilStyle_Mode(stroke_mode)) {
636 rv3d,
637 win_size,
638 object,
639 points_by_curve[stroke_i],
640 positions,
641 radii,
642 eval_colors,
643 cyclic[stroke_i],
644 eGPDstroke_Caps(stroke_start_caps[stroke_i]),
645 eGPDstroke_Caps(stroke_end_caps[stroke_i]),
646 false,
647 radius_scale);
648 break;
651 /* NOTE: Squares don't have their own shader, render as dots too. */
652 draw_dots(
653 transform, points_by_curve[stroke_i], positions, radii, eval_colors, radius_scale);
654 break;
655 }
656 });
657
658 if (!use_xray) {
660
661 GPU_polygon_offset(0.0f, 0.0f);
662 }
663 GPU_depth_mask(prev_depth_mask);
666}
667
668} // namespace blender::ed::greasepencil::image_render
Camera data-block and utility functions.
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
Image * BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
#define M_SQRT2
void orthographic_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
void perspective_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
MINLINE void copy_v2_v2(float r[2], const float a[2])
unsigned int uint
@ ID_TAG_DOIT
Definition DNA_ID.h:1036
@ GP_MATERIAL_HIDE
eMaterialGPencilStyle_Mode
@ GP_MATERIAL_MODE_SQUARE
@ GP_MATERIAL_MODE_DOT
@ GP_MATERIAL_MODE_LINE
Object is a sort of wrapper for general info.
RV3DMatrixStore * ED_view3d_mats_rv3d_backup(RegionView3D *rv3d)
void ED_view3d_mats_rv3d_restore(RegionView3D *rv3d, RV3DMatrixStore *rv3dmat)
void ED_view3D_mats_rv3d_free(RV3DMatrixStore *rv3d_mat)
bool ED_view3d_viewplane_get(const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, int winx, int winy, rctf *r_viewplane, float *r_clip_start, float *r_clip_end, float *r_pixsize)
void ED_view3d_update_viewmat(const Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4], const rcti *rect, bool offscreen)
void GPU_batch_discard(blender::gpu::Batch *batch)
void GPU_batch_draw_advanced(blender::gpu::Batch *batch, int vertex_first, int vertex_count, int instance_first, int instance_count)
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, GPUBatchFlag owns_flag)
Definition gpu_batch.cc:51
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:42
void GPU_batch_bind_as_resources(blender::gpu::Batch *batch, blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants=nullptr)
void GPU_batch_set_shader(blender::gpu::Batch *batch, blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_debug_capture_end()
Definition gpu_debug.cc:93
void GPU_debug_capture_begin(const char *title)
Definition gpu_debug.cc:78
int GPU_offscreen_width(const GPUOffScreen *offscreen)
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
int GPU_offscreen_height(const GPUOffScreen *offscreen)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool with_depth_buffer, blender::gpu::TextureFormat format, eGPUTextureUsage usage, bool clear, char err_out[256])
void GPU_clear_color(float red, float green, float blue, float alpha)
void GPU_offscreen_free(GPUOffScreen *offscreen)
void GPU_clear_depth(float depth)
void GPU_offscreen_read_color(GPUOffScreen *offscreen, eGPUDataFormat data_format, void *r_data)
void GPU_offscreen_unbind(GPUOffScreen *offscreen, bool restore)
void immEnd()
void immUniform2fv(const char *name, const float data[2])
void immUnbindProgram()
void immAttr4fv(uint attr_id, const float data[4])
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immAttr1f(uint attr_id, float x)
blender::gpu::Batch * immBeginBatchAtMost(GPUPrimType, uint vertex_len)
void immBindUniformBuf(const char *name, blender::gpu::UniformBuf *ubo)
void immBeginAtMost(GPUPrimType, uint max_vertex_len)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat()
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void GPU_matrix_identity_projection_set()
void GPU_matrix_identity_set()
#define GPU_matrix_set(x)
void GPU_matrix_push()
void GPU_matrix_push_projection()
void GPU_matrix_pop_projection()
#define GPU_matrix_projection_set(x)
void GPU_polygon_offset(float viewdist, float dist)
void GPU_matrix_pop()
GPUPrimType
@ GPU_PRIM_LINE_STRIP_ADJ
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRI_STRIP
@ GPU_PRIM_TRIS
@ GPU_SHADER_GPENCIL_STROKE
@ GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
@ GPU_SHADER_3D_POLYLINE_FLAT_COLOR
void GPU_program_point_size(bool enable)
Definition gpu_state.cc:180
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
void GPU_depth_test(GPUDepthTest test)
Definition gpu_state.cc:68
bool GPU_depth_mask_get()
Definition gpu_state.cc:287
@ GPU_DATA_UBYTE
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_HOST_READ
void GPU_uniformbuf_free(blender::gpu::UniformBuf *ubo)
blender::gpu::UniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
void IMB_byte_from_float(ImBuf *ibuf)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
@ IB_byte_data
#define U
BMesh const char void * data
static GVArray from_garray(GArray<> array)
static GVArray from_span(GSpan span)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
const bke::CurvesGeometry & strokes() const
void foreach_index(Fn &&fn) const
static ushort indices[]
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
static uint attr_size(GPUVertCompType type, int len)
#define input
#define out
format
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR
void compute_view_matrices(const ViewContext &view_context, const Scene &scene, const int2 &win_size, const float2 &zoom, const float2 &offset)
void region_reset(ARegion &region, const RegionViewData &data)
static GVArray attribute_interpolate(const GSpan &input, const bke::CurvesGeometry &curves)
void draw_lines(const float4x4 &transform, IndexRange indices, Span< float3 > start_positions, Span< float3 > end_positions, const VArray< ColorGeometry4f > &colors, float line_width)
static gpu::UniformBuf * create_shader_ubo(const RegionView3D &rv3d, const int2 &win_size, const Object &object, const eGPDstroke_Caps cap_start, const eGPDstroke_Caps cap_end, const bool is_fill_stroke)
Image * image_render_end(Main &bmain, GPUOffScreen *buffer)
void draw_grease_pencil_strokes(const RegionView3D &rv3d, const int2 &win_size, const Object &object, const bke::greasepencil::Drawing &drawing, const float4x4 &transform, const IndexMask &strokes_mask, const VArray< ColorGeometry4f > &colors, const bool use_xray, const float radius_scale)
RegionViewData region_init(ARegion &region, const int2 &win_size)
static void draw_grease_pencil_stroke(const float4x4 &transform, const RegionView3D &rv3d, const int2 &win_size, const Object &object, const IndexRange indices, Span< float3 > positions, const VArray< float > &radii, const VArray< ColorGeometry4f > &colors, const bool cyclic, const eGPDstroke_Caps cap_start, const eGPDstroke_Caps cap_end, const bool fill_stroke, const float radius_scale)
static void draw_dots(const float4x4 &transform, const IndexRange indices, Span< float3 > positions, const VArray< float > &radii, const VArray< ColorGeometry4f > &colors, const float radius_scale)
void draw_circles(const float4x4 &transform, const IndexRange indices, Span< float3 > centers, const VArray< float > &radii, const VArray< ColorGeometry4f > &colors, const float2 &viewport_size, const float line_width, const bool fill)
void draw_dot(const float4x4 &transform, const float3 &position, const float point_size, const ColorGeometry4f &color)
void draw_polyline(const float4x4 &transform, const IndexRange indices, Span< float3 > positions, const VArray< ColorGeometry4f > &colors, const bool cyclic, const float line_width)
GPUOffScreen * image_render_begin(const int2 &win_size)
T average(const VecBase< T, Size > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
void * regiondata
int tag
Definition DNA_ID.h:442
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
struct MaterialGPencilStyle * gp_style
float viewmat[4][4]
float winmat[4][4]
RegionView3D * rv3d
Definition ED_view3d.hh:80
ARegion * region
Definition ED_view3d.hh:77
View3D * v3d
Definition ED_view3d.hh:78
Depsgraph * depsgraph
Definition ED_view3d.hh:72
const c_style_mat & ptr() const
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
i
Definition text_draw.cc:230