Blender V4.3
draw_cache.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DNA_curve_types.h"
10#include "DNA_curves_types.h"
12#include "DNA_lattice_types.h"
13#include "DNA_mesh_types.h"
14#include "DNA_meta_types.h"
15#include "DNA_modifier_types.h"
16#include "DNA_object_types.h"
17#include "DNA_particle_types.h"
19#include "DNA_scene_types.h"
20#include "DNA_volume_types.h"
21
22#include "UI_resources.hh"
23
24#include "BLI_utildefines.h"
25
26#include "BKE_object.hh"
27#include "BKE_paint.hh"
28
29#include "GPU_batch.hh"
30#include "GPU_batch_utils.hh"
31#include "GPU_capabilities.hh"
32
33#include "MEM_guardedalloc.h"
34
35#include "draw_cache.hh"
36#include "draw_cache_impl.hh"
37#include "draw_manager_c.hh"
38
39/* -------------------------------------------------------------------- */
43#define VCLASS_LIGHT_AREA_SHAPE (1 << 0)
44#define VCLASS_LIGHT_SPOT_SHAPE (1 << 1)
45#define VCLASS_LIGHT_SPOT_BLEND (1 << 2)
46#define VCLASS_LIGHT_SPOT_CONE (1 << 3)
47#define VCLASS_LIGHT_DIST (1 << 4)
48
49#define VCLASS_CAMERA_FRAME (1 << 5)
50#define VCLASS_CAMERA_DIST (1 << 6)
51#define VCLASS_CAMERA_VOLUME (1 << 7)
52
53#define VCLASS_SCREENSPACE (1 << 8)
54#define VCLASS_SCREENALIGNED (1 << 9)
55
56#define VCLASS_EMPTY_SCALED (1 << 10)
57#define VCLASS_EMPTY_AXES (1 << 11)
58#define VCLASS_EMPTY_AXES_NAME (1 << 12)
59#define VCLASS_EMPTY_AXES_SHADOW (1 << 13)
60#define VCLASS_EMPTY_SIZE (1 << 14)
61
62/* Sphere shape resolution */
63/* Low */
64#define DRW_SPHERE_SHAPE_LATITUDE_LOW 32
65#define DRW_SPHERE_SHAPE_LONGITUDE_LOW 24
66/* Medium */
67#define DRW_SPHERE_SHAPE_LATITUDE_MEDIUM 64
68#define DRW_SPHERE_SHAPE_LONGITUDE_MEDIUM 48
69/* High */
70#define DRW_SPHERE_SHAPE_LATITUDE_HIGH 80
71#define DRW_SPHERE_SHAPE_LONGITUDE_HIGH 60
72
75/* -------------------------------------------------------------------- */
79struct Vert {
80 float pos[3];
82
84 operator const void *() const
85 {
86 return this;
87 }
88};
89
90struct VertShaded {
91 float pos[3];
93 float nor[3];
94
95 operator const void *() const
96 {
97 return this;
98 }
99};
100
101/* Batch's only (freed as an array). */
102static struct DRWShapeCache {
103 blender::gpu::Batch *drw_procedural_verts;
104 blender::gpu::Batch *drw_procedural_lines;
105 blender::gpu::Batch *drw_procedural_tris;
106 blender::gpu::Batch *drw_procedural_tri_strips;
107 blender::gpu::Batch *drw_cursor;
108 blender::gpu::Batch *drw_cursor_only_circle;
109 blender::gpu::Batch *drw_fullscreen_quad;
110 blender::gpu::Batch *drw_quad;
111 blender::gpu::Batch *drw_quad_wires;
112 blender::gpu::Batch *drw_grid;
113 blender::gpu::Batch *drw_plain_axes;
114 blender::gpu::Batch *drw_single_arrow;
115 blender::gpu::Batch *drw_cube;
116 blender::gpu::Batch *drw_circle;
117 blender::gpu::Batch *drw_normal_arrow;
118 blender::gpu::Batch *drw_empty_cube;
119 blender::gpu::Batch *drw_empty_sphere;
120 blender::gpu::Batch *drw_empty_cylinder;
121 blender::gpu::Batch *drw_empty_capsule_body;
122 blender::gpu::Batch *drw_empty_capsule_cap;
123 blender::gpu::Batch *drw_empty_cone;
124 blender::gpu::Batch *drw_field_wind;
125 blender::gpu::Batch *drw_field_force;
126 blender::gpu::Batch *drw_field_vortex;
127 blender::gpu::Batch *drw_field_curve;
128 blender::gpu::Batch *drw_field_tube_limit;
129 blender::gpu::Batch *drw_field_cone_limit;
130 blender::gpu::Batch *drw_field_sphere_limit;
131 blender::gpu::Batch *drw_ground_line;
132 blender::gpu::Batch *drw_light_icon_inner_lines;
133 blender::gpu::Batch *drw_light_icon_outer_lines;
134 blender::gpu::Batch *drw_light_icon_sun_rays;
135 blender::gpu::Batch *drw_light_point_lines;
136 blender::gpu::Batch *drw_light_sun_lines;
137 blender::gpu::Batch *drw_light_spot_lines;
138 blender::gpu::Batch *drw_light_spot_volume;
139 blender::gpu::Batch *drw_light_area_disk_lines;
140 blender::gpu::Batch *drw_light_area_square_lines;
141 blender::gpu::Batch *drw_speaker;
142 blender::gpu::Batch *drw_lightprobe_cube;
143 blender::gpu::Batch *drw_lightprobe_planar;
144 blender::gpu::Batch *drw_lightprobe_grid;
145 blender::gpu::Batch *drw_bone_octahedral;
146 blender::gpu::Batch *drw_bone_octahedral_wire;
147 blender::gpu::Batch *drw_bone_box;
148 blender::gpu::Batch *drw_bone_box_wire;
149 blender::gpu::Batch *drw_bone_envelope;
150 blender::gpu::Batch *drw_bone_envelope_outline;
151 blender::gpu::Batch *drw_bone_point;
152 blender::gpu::Batch *drw_bone_point_wire;
153 blender::gpu::Batch *drw_bone_stick;
154 blender::gpu::Batch *drw_bone_arrows;
155 blender::gpu::Batch *drw_bone_dof_sphere;
156 blender::gpu::Batch *drw_bone_dof_lines;
157 blender::gpu::Batch *drw_camera_frame;
158 blender::gpu::Batch *drw_camera_tria;
159 blender::gpu::Batch *drw_camera_tria_wire;
160 blender::gpu::Batch *drw_camera_distances;
161 blender::gpu::Batch *drw_camera_volume;
162 blender::gpu::Batch *drw_camera_volume_wire;
163 blender::gpu::Batch *drw_particle_cross;
164 blender::gpu::Batch *drw_particle_circle;
165 blender::gpu::Batch *drw_particle_axis;
166 blender::gpu::Batch *drw_gpencil_dummy_quad;
167 blender::gpu::Batch *drw_sphere_lod[DRW_LOD_MAX];
168} SHC = {nullptr};
169
171{
172 uint i = sizeof(SHC) / sizeof(blender::gpu::Batch *);
173 blender::gpu::Batch **batch = (blender::gpu::Batch **)&SHC;
174 while (i--) {
176 batch++;
177 }
178}
179
182/* -------------------------------------------------------------------- */
187{
189 /* TODO(fclem): get rid of this dummy VBO. */
190 GPUVertFormat format = {0};
193 GPU_vertbuf_data_alloc(*vbo, 1);
194
196 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
197 }
199}
200
201blender::gpu::Batch *drw_cache_procedural_lines_get()
202{
204 /* TODO(fclem): get rid of this dummy VBO. */
205 GPUVertFormat format = {0};
208 GPU_vertbuf_data_alloc(*vbo, 1);
209
211 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
212 }
214}
215
217{
219 /* TODO(fclem): get rid of this dummy VBO. */
220 GPUVertFormat format = {0};
223 GPU_vertbuf_data_alloc(*vbo, 1);
224
226 }
228}
229
244
247/* -------------------------------------------------------------------- */
258
260 uint pos_id,
261 uint n1_id,
262 uint n2_id,
263 uint *v_idx,
264 const float co1[3],
265 const float co2[3],
266 const float n1[3],
267 const float n2[3])
268{
269 GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1);
270 GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2);
271 GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co1);
272
273 GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1);
274 GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2);
275 GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co2);
276}
277
278#if 0 /* UNUSED */
279static void add_lat_lon_vert(blender::gpu::VertBuf *vbo,
280 uint pos_id,
281 uint nor_id,
282 uint *v_idx,
283 const float rad,
284 const float lat,
285 const float lon)
286{
287 float pos[3], nor[3];
288 nor[0] = sinf(lat) * cosf(lon);
289 nor[1] = cosf(lat);
290 nor[2] = sinf(lat) * sinf(lon);
291 mul_v3_v3fl(pos, nor, rad);
292
293 GPU_vertbuf_attr_set(vbo, nor_id, *v_idx, nor);
294 GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, pos);
295}
296
297static blender::gpu::VertBuf *fill_arrows_vbo(const float scale)
298{
299 /* Position Only 3D format */
300 static GPUVertFormat format = {0};
301 static struct {
302 uint pos;
303 } attr_id;
304 if (format.attr_len == 0) {
306 }
307
308 /* Line */
310 GPU_vertbuf_data_alloc(*vbo, 6 * 3);
311
312 float v1[3] = {0.0, 0.0, 0.0};
313 float v2[3] = {0.0, 0.0, 0.0};
314 float vtmp1[3], vtmp2[3];
315
316 for (int axis = 0; axis < 3; axis++) {
317 const int arrow_axis = (axis == 0) ? 1 : 0;
318
319 v2[axis] = 1.0f;
320 mul_v3_v3fl(vtmp1, v1, scale);
321 mul_v3_v3fl(vtmp2, v2, scale);
322 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 0, vtmp1);
323 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 1, vtmp2);
324
325 v1[axis] = 0.85f;
326 v1[arrow_axis] = -0.08f;
327 mul_v3_v3fl(vtmp1, v1, scale);
328 mul_v3_v3fl(vtmp2, v2, scale);
329 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 2, vtmp1);
330 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 3, vtmp2);
331
332 v1[arrow_axis] = 0.08f;
333 mul_v3_v3fl(vtmp1, v1, scale);
334 mul_v3_v3fl(vtmp2, v2, scale);
335 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 4, vtmp1);
336 GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 5, vtmp2);
337
338 /* reset v1 & v2 to zero */
339 v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
340 }
341
342 return vbo;
343}
344#endif /* UNUSED */
345
346static blender::gpu::VertBuf *sphere_wire_vbo(const float rad, int flag)
347{
348#define NSEGMENTS 32
349 /* Position Only 3D format */
351
353 GPU_vertbuf_data_alloc(*vbo, NSEGMENTS * 2 * 3);
354
355 int v = 0;
356 /* a single ring of vertices */
357 float p[NSEGMENTS][2];
358 for (int i = 0; i < NSEGMENTS; i++) {
359 float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
360 p[i][0] = rad * cosf(angle);
361 p[i][1] = rad * sinf(angle);
362 }
363
364 for (int axis = 0; axis < 3; axis++) {
365 for (int i = 0; i < NSEGMENTS; i++) {
366 for (int j = 0; j < 2; j++) {
367 float cv[2];
368
369 cv[0] = p[(i + j) % NSEGMENTS][0];
370 cv[1] = p[(i + j) % NSEGMENTS][1];
371
372 if (axis == 0) {
373 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 0.0f}, flag});
374 }
375 else if (axis == 1) {
376 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
377 }
378 else {
379 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, cv[0], cv[1]}, flag});
380 }
381 }
382 }
383 }
384
385 return vbo;
386#undef NSEGMENTS
387}
388
389/* Quads */
390
391blender::gpu::Batch *DRW_cache_fullscreen_quad_get()
392{
394 /* Use a triangle instead of a real quad */
395 /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */
396 const float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}};
397 const float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}};
398
399 /* Position Only 2D format */
400 static GPUVertFormat format = {0};
401 static struct {
402 uint pos, uvs;
403 } attr_id;
404 if (format.attr_len == 0) {
407 GPU_vertformat_alias_add(&format, "texCoord");
408 GPU_vertformat_alias_add(&format, "orco"); /* Fix driver bug (see #70004) */
409 }
410
412 GPU_vertbuf_data_alloc(*vbo, 3);
413
414 for (int i = 0; i < 3; i++) {
415 GPU_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]);
416 GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]);
417 }
418
420 }
422}
423
424blender::gpu::Batch *DRW_cache_quad_get()
425{
426 if (!SHC.drw_quad) {
428
430 GPU_vertbuf_data_alloc(*vbo, 4);
431
432 int v = 0;
434 const float p[4][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, {1.0f, -1.0f}};
435 for (int a = 0; a < 4; a++) {
436 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a][0], p[a][1], 0.0f}, flag});
437 }
438
440 }
441 return SHC.drw_quad;
442}
443
444blender::gpu::Batch *DRW_cache_quad_wires_get()
445{
446 if (!SHC.drw_quad_wires) {
448
450 GPU_vertbuf_data_alloc(*vbo, 5);
451
452 int v = 0;
454 const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
455 for (int a = 0; a < 5; a++) {
456 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a % 4][0], p[a % 4][1], 0.0f}, flag});
457 }
458
461 }
462 return SHC.drw_quad_wires;
463}
464
465blender::gpu::Batch *DRW_cache_grid_get()
466{
467 if (!SHC.drw_grid) {
468 /* Position Only 2D format */
469 static GPUVertFormat format = {0};
470 static struct {
471 uint pos;
472 } attr_id;
473 if (format.attr_len == 0) {
475 }
476
478 GPU_vertbuf_data_alloc(*vbo, 8 * 8 * 2 * 3);
479
480 uint v_idx = 0;
481 for (int i = 0; i < 8; i++) {
482 for (int j = 0; j < 8; j++) {
483 float pos0[2] = {float(i) / 8.0f, float(j) / 8.0f};
484 float pos1[2] = {float(i + 1) / 8.0f, float(j) / 8.0f};
485 float pos2[2] = {float(i) / 8.0f, float(j + 1) / 8.0f};
486 float pos3[2] = {float(i + 1) / 8.0f, float(j + 1) / 8.0f};
487
488 madd_v2_v2v2fl(pos0, blender::float2{-1.0f, -1.0f}, pos0, 2.0f);
489 madd_v2_v2v2fl(pos1, blender::float2{-1.0f, -1.0f}, pos1, 2.0f);
490 madd_v2_v2v2fl(pos2, blender::float2{-1.0f, -1.0f}, pos2, 2.0f);
491 madd_v2_v2v2fl(pos3, blender::float2{-1.0f, -1.0f}, pos3, 2.0f);
492
493 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos0);
494 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1);
495 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2);
496
497 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2);
498 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1);
499 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos3);
500 }
501 }
502
504 }
505 return SHC.drw_grid;
506}
507
508/* Sphere */
509static void sphere_lat_lon_vert(blender::gpu::VertBuf *vbo, int *v_ofs, float lat, float lon)
510{
511 float x = sinf(lat) * cosf(lon);
512 float y = cosf(lat);
513 float z = sinf(lat) * sinf(lon);
514 GPU_vertbuf_vert_set(vbo, *v_ofs, VertShaded{{x, y, z}, VCLASS_EMPTY_SCALED, {x, y, z}});
515 (*v_ofs)++;
516}
517
518blender::gpu::Batch *DRW_cache_sphere_get(const eDRWLevelOfDetail level_of_detail)
519{
520 BLI_assert(level_of_detail >= DRW_LOD_LOW && level_of_detail < DRW_LOD_MAX);
521
522 if (!SHC.drw_sphere_lod[level_of_detail]) {
523 int lat_res;
524 int lon_res;
525
526 switch (level_of_detail) {
527 case DRW_LOD_LOW:
530 break;
531 case DRW_LOD_MEDIUM:
534 break;
535 case DRW_LOD_HIGH:
538 break;
539 default:
540 return nullptr;
541 }
542
545
547 int v_len = (lat_res - 1) * lon_res * 6;
548 GPU_vertbuf_data_alloc(*vbo, v_len);
549
550 const float lon_inc = 2 * M_PI / lon_res;
551 const float lat_inc = M_PI / lat_res;
552 float lon, lat;
553
554 int v = 0;
555 lon = 0.0f;
556 for (int i = 0; i < lon_res; i++, lon += lon_inc) {
557 lat = 0.0f;
558 for (int j = 0; j < lat_res; j++, lat += lat_inc) {
559 if (j != lat_res - 1) { /* Pole */
560 sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon + lon_inc);
561 sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon);
562 sphere_lat_lon_vert(vbo, &v, lat, lon);
563 }
564 if (j != 0) { /* Pole */
565 sphere_lat_lon_vert(vbo, &v, lat, lon + lon_inc);
566 sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon + lon_inc);
567 sphere_lat_lon_vert(vbo, &v, lat, lon);
568 }
569 }
570 }
571
572 SHC.drw_sphere_lod[level_of_detail] = GPU_batch_create_ex(
573 GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
574 }
575 return SHC.drw_sphere_lod[level_of_detail];
576}
577
580/* -------------------------------------------------------------------- */
584static void circle_verts(
585 blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
586{
587 for (int a = 0; a < segments; a++) {
588 for (int b = 0; b < 2; b++) {
589 float angle = (2.0f * M_PI * (a + b)) / segments;
590 float s = sinf(angle) * radius;
591 float c = cosf(angle) * radius;
592 int v = *vert_idx;
593 *vert_idx = v + 1;
594 GPU_vertbuf_vert_set(vbo, v, Vert{{s, c, z}, flag});
595 }
596 }
597}
598
600 blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
601{
602 for (int a = 0; a < segments * 2; a += 2) {
603 for (int b = 0; b < 2; b++) {
604 float angle = (2.0f * M_PI * (a + b)) / (segments * 2);
605 float s = sinf(angle) * radius;
606 float c = cosf(angle) * radius;
607 int v = *vert_idx;
608 *vert_idx = v + 1;
609 GPU_vertbuf_vert_set(vbo, v, Vert{{s, c, z}, flag});
610 }
611 }
612}
613
614/* XXX TODO: move that 1 unit cube to more common/generic place? */
615static const float bone_box_verts[8][3] = {
616 {1.0f, 0.0f, 1.0f},
617 {1.0f, 0.0f, -1.0f},
618 {-1.0f, 0.0f, -1.0f},
619 {-1.0f, 0.0f, 1.0f},
620 {1.0f, 1.0f, 1.0f},
621 {1.0f, 1.0f, -1.0f},
622 {-1.0f, 1.0f, -1.0f},
623 {-1.0f, 1.0f, 1.0f},
624};
625
626static const uint bone_box_wire[24] = {
627 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7,
628};
629
630#if 0 /* UNUSED */
631/* aligned with bone_octahedral_wire
632 * Contains adjacent normal index */
633static const uint bone_box_wire_adjacent_face[24] = {
634 0, 2, 0, 4, 1, 6, 1, 8, 3, 10, 5, 10, 7, 11, 9, 11, 3, 8, 2, 5, 4, 7, 6, 9,
635};
636#endif
637
638static const uint bone_box_solid_tris[12][3] = {
639 {0, 2, 1}, /* bottom */
640 {0, 3, 2},
641
642 {0, 1, 5}, /* sides */
643 {0, 5, 4},
644
645 {1, 2, 6},
646 {1, 6, 5},
647
648 {2, 3, 7},
649 {2, 7, 6},
650
651 {3, 0, 4},
652 {3, 4, 7},
653
654 {4, 5, 6}, /* top */
655 {4, 6, 7},
656};
657
662static const uint bone_box_wire_lines_adjacency[12][4] = {
663 {4, 2, 0, 11},
664 {0, 1, 2, 8},
665 {2, 4, 1, 14},
666 {1, 0, 4, 20}, /* bottom */
667 {0, 8, 11, 14},
668 {2, 14, 8, 20},
669 {1, 20, 14, 11},
670 {4, 11, 20, 8}, /* top */
671 {20, 0, 11, 2},
672 {11, 2, 8, 1},
673 {8, 1, 14, 4},
674 {14, 4, 20, 0}, /* sides */
675};
676
677#if 0 /* UNUSED */
678static const uint bone_box_solid_tris_adjacency[12][6] = {
679 {0, 5, 1, 14, 2, 8},
680 {3, 26, 4, 20, 5, 1},
681
682 {6, 2, 7, 16, 8, 11},
683 {9, 7, 10, 32, 11, 24},
684
685 {12, 0, 13, 22, 14, 17},
686 {15, 13, 16, 30, 17, 6},
687
688 {18, 3, 19, 28, 20, 23},
689 {21, 19, 22, 33, 23, 12},
690
691 {24, 4, 25, 10, 26, 29},
692 {27, 25, 28, 34, 29, 18},
693
694 {30, 9, 31, 15, 32, 35},
695 {33, 31, 34, 21, 35, 27},
696};
697#endif
698
699/* aligned with bone_box_solid_tris */
700static const float bone_box_solid_normals[12][3] = {
701 {0.0f, -1.0f, 0.0f},
702 {0.0f, -1.0f, 0.0f},
703
704 {1.0f, 0.0f, 0.0f},
705 {1.0f, 0.0f, 0.0f},
706
707 {0.0f, 0.0f, -1.0f},
708 {0.0f, 0.0f, -1.0f},
709
710 {-1.0f, 0.0f, 0.0f},
711 {-1.0f, 0.0f, 0.0f},
712
713 {0.0f, 0.0f, 1.0f},
714 {0.0f, 0.0f, 1.0f},
715
716 {0.0f, 1.0f, 0.0f},
717 {0.0f, 1.0f, 0.0f},
718};
719
720blender::gpu::Batch *DRW_cache_cube_get()
721{
722 if (!SHC.drw_cube) {
724
725 const int tri_len = ARRAY_SIZE(bone_box_solid_tris);
726 const int vert_len = ARRAY_SIZE(bone_box_verts);
727
729 GPU_vertbuf_data_alloc(*vbo, vert_len);
730
732 GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len);
733
734 int v = 0;
735 for (int i = 0; i < vert_len; i++) {
736 float x = bone_box_verts[i][0];
737 float y = bone_box_verts[i][1] * 2.0f - 1.0f;
738 float z = bone_box_verts[i][2];
740 }
741
742 for (int i = 0; i < tri_len; i++) {
743 const uint *tri_indices = bone_box_solid_tris[i];
744 GPU_indexbuf_add_tri_verts(&elb, tri_indices[0], tri_indices[1], tri_indices[2]);
745 }
746
749 }
750 return SHC.drw_cube;
751}
752
753blender::gpu::Batch *DRW_cache_circle_get()
754{
755#define CIRCLE_RESOL 64
756 if (!SHC.drw_circle) {
758
761
762 int v = 0;
763 for (int a = 0; a < CIRCLE_RESOL + 1; a++) {
764 float x = sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
765 float z = cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
766 float y = 0.0f;
768 }
769
771 }
772 return SHC.drw_circle;
773#undef CIRCLE_RESOL
774}
775
776blender::gpu::Batch *DRW_cache_normal_arrow_get()
777{
778 if (!SHC.drw_normal_arrow) {
779 GPUVertFormat format = {0};
781
783 GPU_vertbuf_data_alloc(*vbo, 2);
784
785 /* TODO: real arrow. For now, it's a line positioned in the vertex shader. */
786
788 }
789 return SHC.drw_normal_arrow;
790}
791
792namespace blender::draw {
793
795{
796 static GPUVertFormat format = {0};
797 static struct {
798 uint wd;
799 } attr_id;
800 if (format.attr_len == 0) {
801 /* initialize vertex format */
802 if (!GPU_crappy_amd_driver()) {
803 /* Some AMD drivers strangely crash with a vbo with this format. */
806 }
807 else {
809 }
810 }
811
813 GPU_vertbuf_data_alloc(*vbo, vert_len);
814
815 if (GPU_vertbuf_get_format(vbo)->stride == 1) {
816 memset(vbo->data<uint8_t>().data(), 0xFF, size_t(vert_len));
817 }
818 else {
819 GPUVertBufRaw wd_step;
820 GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
821 for (int i = 0; i < vert_len; i++) {
822 *((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f;
823 }
824 }
825}
826
827} // namespace blender::draw
828
831/* -------------------------------------------------------------------- */
838blender::gpu::Batch *DRW_gpencil_dummy_buffer_get()
839{
840 if (SHC.drw_gpencil_dummy_quad == nullptr) {
841 GPUVertFormat format = {0};
842 /* NOTE: Use GPU_COMP_U32 to satisfy minimum 4-byte vertex stride for Metal backend. */
845 GPU_vertbuf_data_alloc(*vbo, 4);
846
848 GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
849 }
851}
852
855/* -------------------------------------------------------------------- */
863blender::gpu::Batch *DRW_cache_object_all_edges_get(Object *ob)
864{
865 switch (ob->type) {
866 case OB_MESH:
868 /* TODO: should match #DRW_cache_object_surface_get. */
869 default:
870 return nullptr;
871 }
872}
873
874blender::gpu::Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
875{
876 switch (ob->type) {
877 case OB_MESH:
878 return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
879 default:
880 return nullptr;
881 }
882}
883
884blender::gpu::Batch *DRW_cache_object_face_wireframe_get(const Scene *scene, Object *ob)
885{
886 using namespace blender::draw;
887 switch (ob->type) {
888 case OB_MESH:
890 case OB_POINTCLOUD:
891 return DRW_pointcloud_batch_cache_get_dots(ob);
892 case OB_VOLUME:
893 return DRW_cache_volume_face_wireframe_get(ob);
894 case OB_GREASE_PENCIL:
895 return DRW_cache_grease_pencil_face_wireframe_get(scene, ob);
896 default:
897 return nullptr;
898 }
899}
900
902{
903 switch (ob->type) {
904 case OB_MESH:
906 default:
907 return nullptr;
908 }
909}
910
911blender::gpu::Batch *DRW_cache_object_surface_get(Object *ob)
912{
913 switch (ob->type) {
914 case OB_MESH:
916 default:
917 return nullptr;
918 }
919}
920
922{
923 using namespace blender::draw;
925 short type = (mesh != nullptr) ? short(OB_MESH) : ob->type;
926
927 switch (type) {
928 case OB_MESH:
929 return DRW_mesh_batch_cache_pos_vertbuf_get(
930 *static_cast<Mesh *>((mesh != nullptr) ? mesh : ob->data));
931 default:
932 return nullptr;
933 }
934}
935
937{
938 using namespace blender::draw;
939 short type = ob->type;
940
942 if (mesh != nullptr && type != OB_POINTCLOUD) {
943 /* Some object types can have one data type in ob->data, but will be rendered as mesh.
944 * For point clouds this never happens. Ideally this check would happen at another level
945 * and we would just have to care about ob->data here. */
946 type = OB_MESH;
947 }
948
949 switch (type) {
950 case OB_MESH:
951 return DRW_mesh_material_count_get(
952 *ob, *static_cast<const Mesh *>((mesh != nullptr) ? mesh : ob->data));
953 case OB_CURVES_LEGACY:
954 case OB_SURF:
955 case OB_FONT:
956 return DRW_curve_material_count_get(static_cast<const Curve *>(ob->data));
957 case OB_CURVES:
958 return DRW_curves_material_count_get(static_cast<const Curves *>(ob->data));
959 case OB_POINTCLOUD:
960 return DRW_pointcloud_material_count_get(static_cast<const PointCloud *>(ob->data));
961 case OB_VOLUME:
962 return DRW_volume_material_count_get(static_cast<const Volume *>(ob->data));
963 default:
964 BLI_assert(0);
965 return 0;
966 }
967}
968
970 GPUMaterial **gpumat_array,
971 uint gpumat_array_len)
972{
973 switch (ob->type) {
974 case OB_MESH:
975 return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
976 default:
977 return nullptr;
978 }
979}
980
983/* -------------------------------------------------------------------- */
987blender::gpu::Batch *DRW_cache_plain_axes_get()
988{
989 if (!SHC.drw_plain_axes) {
991
993 GPU_vertbuf_data_alloc(*vbo, 6);
994
995 int v = 0;
997 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, -1.0f, 0.0f}, flag});
998 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 1.0f, 0.0f}, flag});
999 GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 0.0f, 0.0f}, flag});
1000 GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 0.0f, 0.0f}, flag});
1001 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, -1.0f}, flag});
1002 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, flag});
1003
1005 }
1006 return SHC.drw_plain_axes;
1007}
1008
1009blender::gpu::Batch *DRW_cache_empty_cube_get()
1010{
1011 if (!SHC.drw_empty_cube) {
1015
1016 int v = 0;
1017 for (int i = 0; i < ARRAY_SIZE(bone_box_wire); i++) {
1018 float x = bone_box_verts[bone_box_wire[i]][0];
1019 float y = bone_box_verts[bone_box_wire[i]][1] * 2.0 - 1.0f;
1020 float z = bone_box_verts[bone_box_wire[i]][2];
1022 }
1023
1025 }
1026 return SHC.drw_empty_cube;
1027}
1028
1029blender::gpu::Batch *DRW_cache_single_arrow_get()
1030{
1031 if (!SHC.drw_single_arrow) {
1034 GPU_vertbuf_data_alloc(*vbo, 4 * 2 * 2 + 2);
1035
1036 int v = 0;
1038 float p[3][3] = {{0}};
1039 p[0][2] = 1.0f;
1040 p[1][0] = 0.035f;
1041 p[1][1] = 0.035f;
1042 p[2][0] = -0.035f;
1043 p[2][1] = 0.035f;
1044 p[1][2] = p[2][2] = 0.75f;
1045 for (int sides = 0; sides < 4; sides++) {
1046 if (sides % 2 == 1) {
1047 p[1][0] = -p[1][0];
1048 p[2][1] = -p[2][1];
1049 }
1050 else {
1051 p[1][1] = -p[1][1];
1052 p[2][0] = -p[2][0];
1053 }
1054 for (int i = 0, a = 1; i < 2; i++, a++) {
1055 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[i][0], p[i][1], p[i][2]}, flag});
1056 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a][0], p[a][1], p[a][2]}, flag});
1057 }
1058 }
1059 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0}, flag});
1060 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.75f}, flag});
1061
1063 }
1064 return SHC.drw_single_arrow;
1065}
1066
1075
1076blender::gpu::Batch *DRW_cache_empty_cone_get()
1077{
1078#define NSEGMENTS 8
1079 if (!SHC.drw_empty_cone) {
1083
1084 int v = 0;
1086 /* a single ring of vertices */
1087 float p[NSEGMENTS][2];
1088 for (int i = 0; i < NSEGMENTS; i++) {
1089 float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
1090 p[i][0] = cosf(angle);
1091 p[i][1] = sinf(angle);
1092 }
1093 for (int i = 0; i < NSEGMENTS; i++) {
1094 float cv[2];
1095 cv[0] = p[(i) % NSEGMENTS][0];
1096 cv[1] = p[(i) % NSEGMENTS][1];
1097
1098 /* cone sides */
1099 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
1100 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 2.0f, 0.0f}, flag});
1101
1102 /* end ring */
1103 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
1104 cv[0] = p[(i + 1) % NSEGMENTS][0];
1105 cv[1] = p[(i + 1) % NSEGMENTS][1];
1106 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
1107 }
1108
1110 }
1111 return SHC.drw_empty_cone;
1112#undef NSEGMENTS
1113}
1114
1115blender::gpu::Batch *DRW_cache_empty_cylinder_get()
1116{
1117#define NSEGMENTS 12
1118 if (!SHC.drw_empty_cylinder) {
1122
1123 /* a single ring of vertices */
1124 int v = 0;
1126 float p[NSEGMENTS][2];
1127 for (int i = 0; i < NSEGMENTS; i++) {
1128 float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
1129 p[i][0] = cosf(angle);
1130 p[i][1] = sinf(angle);
1131 }
1132 for (int i = 0; i < NSEGMENTS; i++) {
1133 float cv[2], pv[2];
1134 cv[0] = p[(i) % NSEGMENTS][0];
1135 cv[1] = p[(i) % NSEGMENTS][1];
1136 pv[0] = p[(i + 1) % NSEGMENTS][0];
1137 pv[1] = p[(i + 1) % NSEGMENTS][1];
1138
1139 /* cylinder sides */
1140 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], -1.0f}, flag});
1141 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 1.0f}, flag});
1142 /* top ring */
1143 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 1.0f}, flag});
1144 GPU_vertbuf_vert_set(vbo, v++, Vert{{pv[0], pv[1], 1.0f}, flag});
1145 /* bottom ring */
1146 GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], -1.0f}, flag});
1147 GPU_vertbuf_vert_set(vbo, v++, Vert{{pv[0], pv[1], -1.0f}, flag});
1148 }
1149
1151 }
1152 return SHC.drw_empty_cylinder;
1153#undef NSEGMENTS
1154}
1155
1157{
1159 const float pos[8][3] = {
1160 {1.0f, 0.0f, 1.0f},
1161 {1.0f, 0.0f, 0.0f},
1162 {0.0f, 1.0f, 1.0f},
1163 {0.0f, 1.0f, 0.0f},
1164 {-1.0f, 0.0f, 1.0f},
1165 {-1.0f, 0.0f, 0.0f},
1166 {0.0f, -1.0f, 1.0f},
1167 {0.0f, -1.0f, 0.0f},
1168 };
1169
1170 /* Position Only 3D format */
1171 static GPUVertFormat format = {0};
1172 static struct {
1173 uint pos;
1174 } attr_id;
1175 if (format.attr_len == 0) {
1177 }
1178
1180 GPU_vertbuf_data_alloc(*vbo, 8);
1182
1184 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1185 }
1187}
1188
1190{
1191#define NSEGMENTS 24 /* Must be multiple of 2. */
1193 /* a single ring of vertices */
1194 float p[NSEGMENTS][2];
1195 for (int i = 0; i < NSEGMENTS; i++) {
1196 float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
1197 p[i][0] = cosf(angle);
1198 p[i][1] = sinf(angle);
1199 }
1200
1201 /* Position Only 3D format */
1202 static GPUVertFormat format = {0};
1203 static struct {
1204 uint pos;
1205 } attr_id;
1206 if (format.attr_len == 0) {
1208 }
1209
1211 GPU_vertbuf_data_alloc(*vbo, (NSEGMENTS * 2) * 2);
1212
1213 /* Base circle */
1214 int vidx = 0;
1215 for (int i = 0; i < NSEGMENTS; i++) {
1216 float v[3] = {0.0f, 0.0f, 0.0f};
1217 copy_v2_v2(v, p[(i) % NSEGMENTS]);
1218 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1219 copy_v2_v2(v, p[(i + 1) % NSEGMENTS]);
1220 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1221 }
1222
1223 for (int i = 0; i < NSEGMENTS / 2; i++) {
1224 float v[3] = {0.0f, 0.0f, 0.0f};
1225 int ci = i % NSEGMENTS;
1226 int pi = (i + 1) % NSEGMENTS;
1227 /* Y half circle */
1228 copy_v3_fl3(v, p[ci][0], 0.0f, p[ci][1]);
1229 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1230 copy_v3_fl3(v, p[pi][0], 0.0f, p[pi][1]);
1231 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1232 /* X half circle */
1233 copy_v3_fl3(v, 0.0f, p[ci][0], p[ci][1]);
1234 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1235 copy_v3_fl3(v, 0.0f, p[pi][0], p[pi][1]);
1236 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1237 }
1238
1240 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1241 }
1243#undef NSEGMENTS
1244}
1245
1246blender::gpu::Batch *DRW_cache_field_wind_get()
1247{
1248#define CIRCLE_RESOL 32
1249 if (!SHC.drw_field_wind) {
1251
1252 int v_len = 2 * (CIRCLE_RESOL * 4);
1254 GPU_vertbuf_data_alloc(*vbo, v_len);
1255
1256 int v = 0;
1257 int flag = VCLASS_EMPTY_SIZE;
1258 for (int i = 0; i < 4; i++) {
1259 float z = 0.05f * float(i);
1260 circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
1261 }
1262
1264 }
1265 return SHC.drw_field_wind;
1266#undef CIRCLE_RESOL
1267}
1268
1269blender::gpu::Batch *DRW_cache_field_force_get()
1270{
1271#define CIRCLE_RESOL 32
1272 if (!SHC.drw_field_force) {
1274
1275 int v_len = 2 * (CIRCLE_RESOL * 3);
1277 GPU_vertbuf_data_alloc(*vbo, v_len);
1278
1279 int v = 0;
1281 for (int i = 0; i < 3; i++) {
1282 float radius = 1.0f + 0.5f * i;
1283 circle_verts(vbo, &v, CIRCLE_RESOL, radius, 0.0f, flag);
1284 }
1285
1287 }
1288 return SHC.drw_field_force;
1289#undef CIRCLE_RESOL
1290}
1291
1292blender::gpu::Batch *DRW_cache_field_vortex_get()
1293{
1294#define SPIRAL_RESOL 32
1295 if (!SHC.drw_field_vortex) {
1297
1298 int v_len = SPIRAL_RESOL * 2 + 1;
1300 GPU_vertbuf_data_alloc(*vbo, v_len);
1301
1302 int v = 0;
1303 int flag = VCLASS_EMPTY_SIZE;
1304 for (int a = SPIRAL_RESOL; a > -1; a--) {
1305 float r = a / float(SPIRAL_RESOL);
1306 float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
1307 GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * r, cosf(angle) * r, 0.0f}, flag});
1308 }
1309 for (int a = 1; a <= SPIRAL_RESOL; a++) {
1310 float r = a / float(SPIRAL_RESOL);
1311 float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
1312 GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * -r, cosf(angle) * -r, 0.0f}, flag});
1313 }
1314
1317 }
1318 return SHC.drw_field_vortex;
1319#undef SPIRAL_RESOL
1320}
1321
1322blender::gpu::Batch *DRW_cache_field_curve_get()
1323{
1324#define CIRCLE_RESOL 32
1325 if (!SHC.drw_field_curve) {
1327
1328 int v_len = 2 * (CIRCLE_RESOL);
1330 GPU_vertbuf_data_alloc(*vbo, v_len);
1331
1332 int v = 0;
1334 circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, 0.0f, flag);
1335
1337 }
1338 return SHC.drw_field_curve;
1339#undef CIRCLE_RESOL
1340}
1341
1343{
1344#define CIRCLE_RESOL 32
1345#define SIDE_STIPPLE 32
1348
1349 int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
1351 GPU_vertbuf_data_alloc(*vbo, v_len);
1352
1353 int v = 0;
1354 int flag = VCLASS_EMPTY_SIZE;
1355 /* Caps */
1356 for (int i = 0; i < 2; i++) {
1357 float z = i * 2.0f - 1.0f;
1358 circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
1359 }
1360 /* Side Edges */
1361 for (int a = 0; a < 4; a++) {
1362 float angle = (2.0f * M_PI * a) / 4.0f;
1363 for (int i = 0; i < SIDE_STIPPLE; i++) {
1364 float z = (i / float(SIDE_STIPPLE)) * 2.0f - 1.0f;
1365 GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle), cosf(angle), z}, flag});
1366 }
1367 }
1368
1370 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1371 }
1373#undef SIDE_STIPPLE
1374#undef CIRCLE_RESOL
1375}
1376
1378{
1379#define CIRCLE_RESOL 32
1380#define SIDE_STIPPLE 32
1383
1384 int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
1386 GPU_vertbuf_data_alloc(*vbo, v_len);
1387
1388 int v = 0;
1389 int flag = VCLASS_EMPTY_SIZE;
1390 /* Caps */
1391 for (int i = 0; i < 2; i++) {
1392 float z = i * 2.0f - 1.0f;
1393 circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
1394 }
1395 /* Side Edges */
1396 for (int a = 0; a < 4; a++) {
1397 float angle = (2.0f * M_PI * a) / 4.0f;
1398 for (int i = 0; i < SIDE_STIPPLE; i++) {
1399 float z = (i / float(SIDE_STIPPLE)) * 2.0f - 1.0f;
1400 GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * z, cosf(angle) * z, z}, flag});
1401 }
1402 }
1403
1405 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1406 }
1408#undef SIDE_STIPPLE
1409#undef CIRCLE_RESOL
1410}
1411
1413{
1414#define CIRCLE_RESOL 32
1417
1418 int v_len = 2 * CIRCLE_RESOL;
1420 GPU_vertbuf_data_alloc(*vbo, v_len);
1421
1422 int v = 0;
1424 circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, 0.0f, flag);
1425
1427 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1428 }
1430#undef CIRCLE_RESOL
1431}
1432
1435/* -------------------------------------------------------------------- */
1439#define DIAMOND_NSEGMENTS 4
1440#define INNER_NSEGMENTS 8
1441#define OUTER_NSEGMENTS 10
1442#define CIRCLE_NSEGMENTS 32
1443
1444static float light_distance_z_get(char axis, const bool start)
1445{
1446 switch (axis) {
1447 case 'x': /* - X */
1448 return start ? 0.4f : 0.3f;
1449 case 'X': /* + X */
1450 return start ? 0.6f : 0.7f;
1451 case 'y': /* - Y */
1452 return start ? 1.4f : 1.3f;
1453 case 'Y': /* + Y */
1454 return start ? 1.6f : 1.7f;
1455 case 'z': /* - Z */
1456 return start ? 2.4f : 2.3f;
1457 case 'Z': /* + Z */
1458 return start ? 2.6f : 2.7f;
1459 }
1460 return 0.0;
1461}
1462
1463blender::gpu::Batch *DRW_cache_groundline_get()
1464{
1465 if (!SHC.drw_ground_line) {
1467
1468 int v_len = 2 * (1 + DIAMOND_NSEGMENTS);
1470 GPU_vertbuf_data_alloc(*vbo, v_len);
1471
1472 int v = 0;
1473 /* Ground Point */
1474 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.35f, 0.0f, 0);
1475 /* Ground Line */
1476 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 1.0}, 0});
1477 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, 0});
1478
1480 }
1481 return SHC.drw_ground_line;
1482}
1483
1485{
1488
1489 int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS);
1491 GPU_vertbuf_data_alloc(*vbo, v_len);
1492
1493 const float r = 9.0f;
1494 int v = 0;
1495
1496 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
1498
1500 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1501 }
1503}
1504
1506{
1509
1510 int v_len = 2 * OUTER_NSEGMENTS;
1512 GPU_vertbuf_data_alloc(*vbo, v_len);
1513
1514 const float r = 9.0f;
1515 int v = 0;
1516
1517 circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
1518
1520 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1521 }
1523}
1524
1526{
1529
1530 const int num_rays = 8;
1531 int v_len = 4 * num_rays;
1532
1534 GPU_vertbuf_data_alloc(*vbo, v_len);
1535
1536 const float r = 9.0f;
1537
1538 int v = 0;
1539
1540 /* Sun Rays */
1541 for (int a = 0; a < num_rays; a++) {
1542 float angle = (2.0f * M_PI * a) / float(num_rays);
1543 float s = sinf(angle) * r;
1544 float c = cosf(angle) * r;
1545 GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
1546 GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
1547 GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
1548 GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
1549 }
1550
1552 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1553 }
1555}
1556
1558{
1561
1562 int v_len = 2 * CIRCLE_NSEGMENTS;
1564 GPU_vertbuf_data_alloc(*vbo, v_len);
1565
1566 int v = 0;
1567
1568 /* Light area */
1570 circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
1571
1573 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1574 }
1576}
1577
1578blender::gpu::Batch *DRW_cache_light_sun_lines_get()
1579{
1580 if (!SHC.drw_light_sun_lines) {
1582
1583 int v_len = 2;
1585 GPU_vertbuf_data_alloc(*vbo, v_len);
1586
1587 int v = 0;
1588
1589 /* Direction Line */
1590 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, 0});
1591 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, -20.0}, 0}); /* Good default. */
1592
1594 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1595 }
1596 return SHC.drw_light_sun_lines;
1597}
1598
1600{
1603
1604 int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS * 4 + 1);
1606 GPU_vertbuf_data_alloc(*vbo, v_len);
1607
1608 int v = 0;
1609
1610 /* Light area */
1612 circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
1613 /* Cone cap */
1615 circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
1617 circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
1618 /* Cone silhouette */
1620 for (int a = 0; a < CIRCLE_NSEGMENTS; a++) {
1621 float angle = (2.0f * M_PI * a) / CIRCLE_NSEGMENTS;
1622 float s = sinf(angle);
1623 float c = cosf(angle);
1624 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
1625 GPU_vertbuf_vert_set(vbo, v++, Vert{{s, c, -1.0f}, flag});
1626 }
1627 /* Direction Line */
1628 float zsta = light_distance_z_get('z', true);
1629 float zend = light_distance_z_get('z', false);
1630 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
1631 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
1634
1636 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1637 }
1639}
1640
1642{
1645
1646 int v_len = CIRCLE_NSEGMENTS + 1 + 1;
1648 GPU_vertbuf_data_alloc(*vbo, v_len);
1649
1650 int v = 0;
1651 /* Cone apex */
1652 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
1653 /* Cone silhouette */
1655 for (int a = 0; a < CIRCLE_NSEGMENTS + 1; a++) {
1656 float angle = (2.0f * M_PI * a) / CIRCLE_NSEGMENTS;
1657 float s = sinf(-angle);
1658 float c = cosf(-angle);
1659 GPU_vertbuf_vert_set(vbo, v++, Vert{{s, c, -1.0f}, flag});
1660 }
1661
1663 GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1664 }
1666}
1667
1669{
1672
1673 int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS + 1);
1675 GPU_vertbuf_data_alloc(*vbo, v_len);
1676
1677 int v = 0;
1678
1679 /* Light area */
1681 /* Direction Line */
1682 float zsta = light_distance_z_get('z', true);
1683 float zend = light_distance_z_get('z', false);
1684 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
1685 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
1688
1690 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1691 }
1693}
1694
1696{
1699
1701 int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + 4 + 1);
1702 GPU_vertbuf_data_alloc(*vbo, v_len);
1703
1704 int v = 0;
1705
1706 /* Light area */
1708 for (int a = 0; a < 4; a++) {
1709 for (int b = 0; b < 2; b++) {
1710 const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
1711 float x = p[(a + b) % 4][0];
1712 float y = p[(a + b) % 4][1];
1713 GPU_vertbuf_vert_set(vbo, v++, Vert{{x * 0.5f, y * 0.5f, 0.0f}, flag});
1714 }
1715 }
1716 /* Direction Line */
1717 float zsta = light_distance_z_get('z', true);
1718 float zend = light_distance_z_get('z', false);
1719 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
1720 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
1723
1725 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1726 }
1728}
1729
1730#undef CIRCLE_NSEGMENTS
1731#undef OUTER_NSEGMENTS
1732#undef INNER_NSEGMENTS
1733
1736/* -------------------------------------------------------------------- */
1740blender::gpu::Batch *DRW_cache_speaker_get()
1741{
1742 if (!SHC.drw_speaker) {
1743 float v[3];
1744 const int segments = 16;
1745 int vidx = 0;
1746
1747 /* Position Only 3D format */
1748 static GPUVertFormat format = {0};
1749 static struct {
1750 uint pos;
1751 } attr_id;
1752 if (format.attr_len == 0) {
1754 }
1755
1757 GPU_vertbuf_data_alloc(*vbo, 3 * segments * 2 + 4 * 4);
1758
1759 for (int j = 0; j < 3; j++) {
1760 float z = 0.25f * j - 0.125f;
1761 float r = (j == 0 ? 0.5f : 0.25f);
1762
1763 copy_v3_fl3(v, r, 0.0f, z);
1764 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1765 for (int i = 1; i < segments; i++) {
1766 float x = cosf(2.0f * float(M_PI) * i / segments) * r;
1767 float y = sinf(2.0f * float(M_PI) * i / segments) * r;
1768 copy_v3_fl3(v, x, y, z);
1769 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1770 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1771 }
1772 copy_v3_fl3(v, r, 0.0f, z);
1773 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1774 }
1775
1776 for (int j = 0; j < 4; j++) {
1777 float x = (((j + 1) % 2) * (j - 1)) * 0.5f;
1778 float y = ((j % 2) * (j - 2)) * 0.5f;
1779 for (int i = 0; i < 3; i++) {
1780 if (i == 1) {
1781 x *= 0.5f;
1782 y *= 0.5f;
1783 }
1784
1785 float z = 0.25f * i - 0.125f;
1786 copy_v3_fl3(v, x, y, z);
1787 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1788 if (i == 1) {
1789 GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
1790 }
1791 }
1792 }
1793
1795 }
1796 return SHC.drw_speaker;
1797}
1798
1801/* -------------------------------------------------------------------- */
1805blender::gpu::Batch *DRW_cache_lightprobe_cube_get()
1806{
1807 if (!SHC.drw_lightprobe_cube) {
1809
1810 int v_len = (6 + 3 + (1 + 2 * DIAMOND_NSEGMENTS) * 6) * 2;
1812 GPU_vertbuf_data_alloc(*vbo, v_len);
1813
1814 const float r = 14.0f;
1815 int v = 0;
1817 /* Icon */
1818 const float sin_pi_3 = 0.86602540378f;
1819 const float cos_pi_3 = 0.5f;
1820 const float p[7][2] = {
1821 {0.0f, 1.0f},
1822 {sin_pi_3, cos_pi_3},
1823 {sin_pi_3, -cos_pi_3},
1824 {0.0f, -1.0f},
1825 {-sin_pi_3, -cos_pi_3},
1826 {-sin_pi_3, cos_pi_3},
1827 {0.0f, 0.0f},
1828 };
1829 for (int i = 0; i < 6; i++) {
1830 float t1[2], t2[2];
1831 copy_v2_v2(t1, p[i]);
1832 copy_v2_v2(t2, p[(i + 1) % 6]);
1833 GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
1834 GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
1835 }
1836 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[1][0] * r, p[1][1] * r, 0.0f}, flag});
1837 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1838 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[5][0] * r, p[5][1] * r, 0.0f}, flag});
1839 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1840 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[3][0] * r, p[3][1] * r, 0.0f}, flag});
1841 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1842 /* Direction Lines */
1844 for (int i = 0; i < 6; i++) {
1845 char axes[] = "zZyYxX";
1846 float zsta = light_distance_z_get(axes[i], true);
1847 float zend = light_distance_z_get(axes[i], false);
1848 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zsta}, flag});
1849 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zend}, flag});
1850 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, flag);
1851 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, flag);
1852 }
1853
1855 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1856 }
1857 return SHC.drw_lightprobe_cube;
1858}
1859
1860blender::gpu::Batch *DRW_cache_lightprobe_grid_get()
1861{
1862 if (!SHC.drw_lightprobe_grid) {
1864
1865 int v_len = (6 * 2 + 3 + (1 + 2 * DIAMOND_NSEGMENTS) * 6) * 2;
1867 GPU_vertbuf_data_alloc(*vbo, v_len);
1868
1869 const float r = 14.0f;
1870 int v = 0;
1872 /* Icon */
1873 const float sin_pi_3 = 0.86602540378f;
1874 const float cos_pi_3 = 0.5f;
1875 const float p[7][2] = {
1876 {0.0f, 1.0f},
1877 {sin_pi_3, cos_pi_3},
1878 {sin_pi_3, -cos_pi_3},
1879 {0.0f, -1.0f},
1880 {-sin_pi_3, -cos_pi_3},
1881 {-sin_pi_3, cos_pi_3},
1882 {0.0f, 0.0f},
1883 };
1884 for (int i = 0; i < 6; i++) {
1885 float t1[2], t2[2], tr[2];
1886 copy_v2_v2(t1, p[i]);
1887 copy_v2_v2(t2, p[(i + 1) % 6]);
1888 GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
1889 GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
1890 /* Internal wires. */
1891 for (int j = 1; j < 2; j++) {
1892 mul_v2_v2fl(tr, p[(i / 2) * 2 + 1], -0.5f * j);
1893 add_v2_v2v2(t1, p[i], tr);
1894 add_v2_v2v2(t2, p[(i + 1) % 6], tr);
1895 GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
1896 GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
1897 }
1898 }
1899 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[1][0] * r, p[1][1] * r, 0.0f}, flag});
1900 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1901 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[5][0] * r, p[5][1] * r, 0.0f}, flag});
1902 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1903 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[3][0] * r, p[3][1] * r, 0.0f}, flag});
1904 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
1905 /* Direction Lines */
1907 for (int i = 0; i < 6; i++) {
1908 char axes[] = "zZyYxX";
1909 float zsta = light_distance_z_get(axes[i], true);
1910 float zend = light_distance_z_get(axes[i], false);
1911 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zsta}, flag});
1912 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zend}, flag});
1913 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, flag);
1914 circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, flag);
1915 }
1916
1918 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1919 }
1920 return SHC.drw_lightprobe_grid;
1921}
1922
1924{
1927
1928 int v_len = 2 * 4;
1930 GPU_vertbuf_data_alloc(*vbo, v_len);
1931
1932 const float r = 20.0f;
1933 int v = 0;
1934 /* Icon */
1935 const float sin_pi_3 = 0.86602540378f;
1936 const float p[4][2] = {
1937 {0.0f, 0.5f},
1938 {sin_pi_3, 0.0f},
1939 {0.0f, -0.5f},
1940 {-sin_pi_3, 0.0f},
1941 };
1942 for (int i = 0; i < 4; i++) {
1943 for (int a = 0; a < 2; a++) {
1944 float x = p[(i + a) % 4][0] * r;
1945 float y = p[(i + a) % 4][1] * r;
1946 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0}, VCLASS_SCREENSPACE});
1947 }
1948 }
1949
1951 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
1952 }
1954}
1955
1958/* -------------------------------------------------------------------- */
1962static const float bone_octahedral_verts[6][3] = {
1963 {0.0f, 0.0f, 0.0f},
1964 {0.1f, 0.1f, 0.1f},
1965 {0.1f, 0.1f, -0.1f},
1966 {-0.1f, 0.1f, -0.1f},
1967 {-0.1f, 0.1f, 0.1f},
1968 {0.0f, 1.0f, 0.0f},
1969};
1970
1971#if 0 /* UNUSED */
1972
1973static const uint bone_octahedral_wire[24] = {
1974 0, 1, 1, 5, 5, 3, 3, 0, 0, 4, 4, 5, 5, 2, 2, 0, 1, 2, 2, 3, 3, 4, 4, 1,
1975};
1976
1977/* aligned with bone_octahedral_wire
1978 * Contains adjacent normal index */
1979static const uint bone_octahedral_wire_adjacent_face[24] = {
1980 0, 3, 4, 7, 5, 6, 1, 2, 2, 3, 6, 7, 4, 5, 0, 1, 0, 4, 1, 5, 2, 6, 3, 7,
1981};
1982#endif
1983
1984static const uint bone_octahedral_solid_tris[8][3] = {
1985 {2, 1, 0}, /* bottom */
1986 {3, 2, 0},
1987 {4, 3, 0},
1988 {1, 4, 0},
1989
1990 {5, 1, 2}, /* top */
1991 {5, 2, 3},
1992 {5, 3, 4},
1993 {5, 4, 1},
1994};
1995
2008 {0, 1, 2, 6},
2009 {0, 12, 1, 6},
2010 {0, 3, 12, 6},
2011 {0, 2, 3, 6},
2012 {1, 6, 2, 3},
2013 {1, 12, 6, 3},
2014 {1, 0, 12, 3},
2015 {1, 2, 0, 3},
2016 {2, 0, 1, 12},
2017 {2, 3, 0, 12},
2018 {2, 6, 3, 12},
2019 {2, 1, 6, 12},
2020};
2021
2022#if 0 /* UNUSED */
2023static const uint bone_octahedral_solid_tris_adjacency[8][6] = {
2024 {0, 12, 1, 10, 2, 3},
2025 {3, 15, 4, 1, 5, 6},
2026 {6, 18, 7, 4, 8, 9},
2027 {9, 21, 10, 7, 11, 0},
2028
2029 {12, 22, 13, 2, 14, 17},
2030 {15, 13, 16, 5, 17, 20},
2031 {18, 16, 19, 8, 20, 23},
2032 {21, 19, 22, 11, 23, 14},
2033};
2034#endif
2035
2036/* aligned with bone_octahedral_solid_tris */
2037static const float bone_octahedral_solid_normals[8][3] = {
2038 {M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
2039 {-0.00000000f, -M_SQRT1_2, -M_SQRT1_2},
2040 {-M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
2041 {0.00000000f, -M_SQRT1_2, M_SQRT1_2},
2042 {0.99388373f, 0.11043154f, -0.00000000f},
2043 {0.00000000f, 0.11043154f, -0.99388373f},
2044 {-0.99388373f, 0.11043154f, 0.00000000f},
2045 {0.00000000f, 0.11043154f, 0.99388373f},
2046};
2047
2048blender::gpu::Batch *DRW_cache_bone_octahedral_get()
2049{
2050 if (!SHC.drw_bone_octahedral) {
2051 uint v_idx = 0;
2052
2053 static GPUVertFormat format = {0};
2054 static struct {
2055 uint pos, nor;
2056 } attr_id;
2057 if (format.attr_len == 0) {
2060 }
2061
2062 /* Vertices */
2064 GPU_vertbuf_data_alloc(*vbo, 24);
2065
2066 for (int i = 0; i < 8; i++) {
2067 for (int j = 0; j < 3; j++) {
2070 vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][j]]);
2071 }
2072 }
2073
2075 }
2076 return SHC.drw_bone_octahedral;
2077}
2078
2080{
2084
2085 for (int i = 0; i < 12; i++) {
2091 }
2092
2093 /* HACK Reuse vertex buffer. */
2094 blender::gpu::Batch *pos_nor_batch = DRW_cache_bone_octahedral_get();
2095
2097 pos_nor_batch->verts[0],
2098 GPU_indexbuf_build(&elb),
2100 }
2102}
2103
2104blender::gpu::Batch *DRW_cache_bone_box_get()
2105{
2106 if (!SHC.drw_bone_box) {
2107 uint v_idx = 0;
2108
2109 static GPUVertFormat format = {0};
2110 static struct {
2111 uint pos, nor;
2112 } attr_id;
2113 if (format.attr_len == 0) {
2116 }
2117
2118 /* Vertices */
2120 GPU_vertbuf_data_alloc(*vbo, 36);
2121
2122 for (int i = 0; i < 12; i++) {
2123 for (int j = 0; j < 3; j++) {
2126 }
2127 }
2128
2130 }
2131 return SHC.drw_bone_box;
2132}
2133
2134blender::gpu::Batch *DRW_cache_bone_box_wire_get()
2135{
2136 if (!SHC.drw_bone_box_wire) {
2139
2140 for (int i = 0; i < 12; i++) {
2146 }
2147
2148 /* HACK Reuse vertex buffer. */
2149 blender::gpu::Batch *pos_nor_batch = DRW_cache_bone_box_get();
2150
2152 pos_nor_batch->verts[0],
2153 GPU_indexbuf_build(&elb),
2155 }
2156 return SHC.drw_bone_box_wire;
2157}
2158
2159/* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder.
2160 * Note that here we only encode head/tail in forth component of the vector. */
2161static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
2162{
2163 r_nor[0] = sinf(lat) * cosf(lon);
2164 r_nor[1] = sinf(lat) * sinf(lon);
2165 r_nor[2] = cosf(lat);
2166}
2167
2169{
2170 if (!SHC.drw_bone_envelope) {
2171 const int lon_res = 24;
2172 const int lat_res = 24;
2173 const float lon_inc = 2.0f * M_PI / lon_res;
2174 const float lat_inc = M_PI / lat_res;
2175 uint v_idx = 0;
2176
2177 static GPUVertFormat format = {0};
2178 static struct {
2179 uint pos;
2180 } attr_id;
2181 if (format.attr_len == 0) {
2183 }
2184
2185 /* Vertices */
2187 GPU_vertbuf_data_alloc(*vbo, ((lat_res + 1) * 2) * lon_res * 1);
2188
2189 float lon = 0.0f;
2190 for (int i = 0; i < lon_res; i++, lon += lon_inc) {
2191 float lat = 0.0f;
2192 float co1[3], co2[3];
2193
2194 /* NOTE: the poles are duplicated on purpose, to restart the strip. */
2195
2196 /* 1st sphere */
2197 for (int j = 0; j < lat_res; j++, lat += lat_inc) {
2198 benv_lat_lon_to_co(lat, lon, co1);
2199 benv_lat_lon_to_co(lat, lon + lon_inc, co2);
2200
2201 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1);
2202 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2);
2203 }
2204
2205 /* Closing the loop */
2206 benv_lat_lon_to_co(M_PI, lon, co1);
2207 benv_lat_lon_to_co(M_PI, lon + lon_inc, co2);
2208
2209 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1);
2210 GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2);
2211 }
2212
2214 GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2215 }
2216 return SHC.drw_bone_envelope;
2217}
2218
2220{
2222#define CIRCLE_RESOL 64
2223 float v0[2], v1[2], v2[2];
2224 const float radius = 1.0f;
2225
2226 /* Position Only 2D format */
2227 static GPUVertFormat format = {0};
2228 static struct {
2229 uint pos0, pos1, pos2;
2230 } attr_id;
2231 if (format.attr_len == 0) {
2235 }
2236
2239
2240 v0[0] = radius * sinf((2.0f * M_PI * -2) / float(CIRCLE_RESOL));
2241 v0[1] = radius * cosf((2.0f * M_PI * -2) / float(CIRCLE_RESOL));
2242 v1[0] = radius * sinf((2.0f * M_PI * -1) / float(CIRCLE_RESOL));
2243 v1[1] = radius * cosf((2.0f * M_PI * -1) / float(CIRCLE_RESOL));
2244
2245 /* Output 4 verts for each position. See shader for explanation. */
2246 uint v = 0;
2247 for (int a = 0; a <= CIRCLE_RESOL; a++) {
2248 v2[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2249 v2[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2250 GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0);
2251 GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1);
2252 GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
2253 copy_v2_v2(v0, v1);
2254 copy_v2_v2(v1, v2);
2255 }
2256
2259#undef CIRCLE_RESOL
2260 }
2262}
2263
2264blender::gpu::Batch *DRW_cache_bone_point_get()
2265{
2266 if (!SHC.drw_bone_point) {
2267#if 0 /* old style geometry sphere */
2268 const int lon_res = 16;
2269 const int lat_res = 8;
2270 const float rad = 0.05f;
2271 const float lon_inc = 2 * M_PI / lon_res;
2272 const float lat_inc = M_PI / lat_res;
2273 uint v_idx = 0;
2274
2275 static GPUVertFormat format = {0};
2276 static struct {
2277 uint pos, nor;
2278 } attr_id;
2279 if (format.attr_len == 0) {
2282 }
2283
2284 /* Vertices */
2286 GPU_vertbuf_data_alloc(*vbo, (lat_res - 1) * lon_res * 6);
2287
2288 float lon = 0.0f;
2289 for (int i = 0; i < lon_res; i++, lon += lon_inc) {
2290 float lat = 0.0f;
2291 for (int j = 0; j < lat_res; j++, lat += lat_inc) {
2292 if (j != lat_res - 1) { /* Pole */
2293 add_lat_lon_vert(
2294 vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
2295 add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon);
2296 add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
2297 }
2298
2299 if (j != 0) { /* Pole */
2300 add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon + lon_inc);
2301 add_lat_lon_vert(
2302 vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
2303 add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
2304 }
2305 }
2306 }
2307
2309#else
2310# define CIRCLE_RESOL 64
2311 float v[2];
2312 const float radius = 0.05f;
2313
2314 /* Position Only 2D format */
2315 static GPUVertFormat format = {0};
2316 static struct {
2317 uint pos;
2318 } attr_id;
2319 if (format.attr_len == 0) {
2321 }
2322
2325
2326 for (int a = 0; a < CIRCLE_RESOL; a++) {
2327 v[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2328 v[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2329 GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v);
2330 }
2331
2333# undef CIRCLE_RESOL
2334#endif
2335 }
2336 return SHC.drw_bone_point;
2337}
2338
2340{
2341 if (!SHC.drw_bone_point_wire) {
2342#if 0 /* old style geometry sphere */
2345 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2346#else
2347# define CIRCLE_RESOL 64
2348 const float radius = 0.05f;
2349
2350 /* Position Only 2D format */
2351 static GPUVertFormat format = {0};
2352 static struct {
2353 uint pos;
2354 } attr_id;
2355 if (format.attr_len == 0) {
2357 }
2358
2361
2362 uint v = 0;
2363 for (int a = 0; a <= CIRCLE_RESOL; a++) {
2364 float pos[2];
2365 pos[0] = radius * sinf((2.0f * M_PI * a) / CIRCLE_RESOL);
2366 pos[1] = radius * cosf((2.0f * M_PI * a) / CIRCLE_RESOL);
2367 GPU_vertbuf_attr_set(vbo, attr_id.pos, v++, pos);
2368 }
2369
2372# undef CIRCLE_RESOL
2373#endif
2374 }
2375 return SHC.drw_bone_point_wire;
2376}
2377
2378/* keep in sync with armature_stick_vert.glsl */
2379#define COL_WIRE (1 << 0)
2380#define COL_HEAD (1 << 1)
2381#define COL_TAIL (1 << 2)
2382#define COL_BONE (1 << 3)
2383
2384#define POS_HEAD (1 << 4)
2385#define POS_TAIL (1 << 5)
2386#define POS_BONE (1 << 6)
2387
2388blender::gpu::Batch *DRW_cache_bone_stick_get()
2389{
2390 if (!SHC.drw_bone_stick) {
2391#define CIRCLE_RESOL 12
2392 uint v = 0;
2393 uint flag;
2394 const float radius = 2.0f; /* head/tail radius */
2395 float pos[2];
2396
2397 /* Position Only 2D format */
2398 static GPUVertFormat format = {0};
2399 static struct {
2400 uint pos, flag;
2401 } attr_id;
2402 if (format.attr_len == 0) {
2405 }
2406
2407 const uint vcount = (CIRCLE_RESOL + 1) * 2 + 6;
2408
2410 GPU_vertbuf_data_alloc(*vbo, vcount);
2411
2413 GPU_indexbuf_init_ex(&elb, GPU_PRIM_TRI_FAN, (CIRCLE_RESOL + 2) * 2 + 6 + 2, vcount);
2414
2415 /* head/tail points */
2416 for (int i = 0; i < 2; i++) {
2417 /* center vertex */
2418 copy_v2_fl(pos, 0.0f);
2419 flag = (i == 0) ? POS_HEAD : POS_TAIL;
2420 flag |= (i == 0) ? COL_HEAD : COL_TAIL;
2421 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
2424 /* circle vertices */
2425 flag |= COL_WIRE;
2426 for (int a = 0; a < CIRCLE_RESOL; a++) {
2427 pos[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2428 pos[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
2429 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
2432 }
2433 /* Close the circle */
2435
2437 }
2438
2439 /* Bone rectangle */
2440 pos[0] = 0.0f;
2441 for (int i = 0; i < 6; i++) {
2442 pos[1] = ELEM(i, 0, 3) ? 0.0f : ((i < 3) ? 1.0f : -1.0f);
2443 flag = ((i < 2 || i > 4) ? POS_HEAD : POS_TAIL) | (ELEM(i, 0, 3) ? 0 : COL_WIRE) | COL_BONE |
2444 POS_BONE;
2445 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
2448 }
2449
2451 vbo,
2452 GPU_indexbuf_build(&elb),
2454#undef CIRCLE_RESOL
2455 }
2456 return SHC.drw_bone_stick;
2457}
2458
2459#define S_X 0.0215f
2460#define S_Y 0.025f
2461static float x_axis_name[4][2] = {
2462 {0.9f * S_X, 1.0f * S_Y},
2463 {-1.0f * S_X, -1.0f * S_Y},
2464 {-0.9f * S_X, 1.0f * S_Y},
2465 {1.0f * S_X, -1.0f * S_Y},
2466};
2467#define X_LEN ARRAY_SIZE(x_axis_name)
2468#undef S_X
2469#undef S_Y
2470
2471#define S_X 0.0175f
2472#define S_Y 0.025f
2473static float y_axis_name[6][2] = {
2474 {-1.0f * S_X, 1.0f * S_Y},
2475 {0.0f * S_X, -0.1f * S_Y},
2476 {1.0f * S_X, 1.0f * S_Y},
2477 {0.0f * S_X, -0.1f * S_Y},
2478 {0.0f * S_X, -0.1f * S_Y},
2479 {0.0f * S_X, -1.0f * S_Y},
2480};
2481#define Y_LEN ARRAY_SIZE(y_axis_name)
2482#undef S_X
2483#undef S_Y
2484
2485#define S_X 0.02f
2486#define S_Y 0.025f
2487static float z_axis_name[10][2] = {
2488 {-0.95f * S_X, 1.00f * S_Y},
2489 {0.95f * S_X, 1.00f * S_Y},
2490 {0.95f * S_X, 1.00f * S_Y},
2491 {0.95f * S_X, 0.90f * S_Y},
2492 {0.95f * S_X, 0.90f * S_Y},
2493 {-1.00f * S_X, -0.90f * S_Y},
2494 {-1.00f * S_X, -0.90f * S_Y},
2495 {-1.00f * S_X, -1.00f * S_Y},
2496 {-1.00f * S_X, -1.00f * S_Y},
2497 {1.00f * S_X, -1.00f * S_Y},
2498};
2499#define Z_LEN ARRAY_SIZE(z_axis_name)
2500#undef S_X
2501#undef S_Y
2502
2503#define S_X 0.007f
2504#define S_Y 0.007f
2505static float axis_marker[8][2] = {
2506#if 0 /* square */
2507 {-1.0f * S_X, 1.0f * S_Y},
2508 {1.0f * S_X, 1.0f * S_Y},
2509 {1.0f * S_X, 1.0f * S_Y},
2510 {1.0f * S_X, -1.0f * S_Y},
2511 {1.0f * S_X, -1.0f * S_Y},
2512 {-1.0f * S_X, -1.0f * S_Y},
2513 {-1.0f * S_X, -1.0f * S_Y},
2514 {-1.0f * S_X, 1.0f * S_Y}
2515#else /* diamond */
2516 {-S_X, 0.0f},
2517 {0.0f, S_Y},
2518 {0.0f, S_Y},
2519 {S_X, 0.0f},
2520 {S_X, 0.0f},
2521 {0.0f, -S_Y},
2522 {0.0f, -S_Y},
2523 {-S_X, 0.0f}
2524#endif
2525};
2526#define MARKER_LEN ARRAY_SIZE(axis_marker)
2527#define MARKER_FILL_LAYER 6
2528#undef S_X
2529#undef S_Y
2530
2531blender::gpu::Batch *DRW_cache_bone_arrows_get()
2532{
2533 if (!SHC.drw_bone_arrows) {
2536 int v_len = (2 + MARKER_LEN * MARKER_FILL_LAYER) * 3 + (X_LEN + Y_LEN + Z_LEN);
2537 GPU_vertbuf_data_alloc(*vbo, v_len);
2538
2539 int v = 0;
2540 for (int axis = 0; axis < 3; axis++) {
2542 /* Vertex layout is XY screen position and axis in Z.
2543 * Fractional part of Z is a positive offset at axis unit position. */
2544 float p[3] = {0.0f, 0.0f, float(axis)};
2545 /* center to axis line */
2546 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
2547 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
2548 /* Axis end marker */
2549 for (int j = 1; j < MARKER_FILL_LAYER + 1; j++) {
2550 for (int i = 0; i < MARKER_LEN; i++) {
2551 mul_v2_v2fl(p, axis_marker[i], 4.0f * j / float(MARKER_FILL_LAYER));
2552 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
2553 }
2554 }
2555 /* Axis name */
2557 int axis_v_len[] = {X_LEN, Y_LEN, Z_LEN};
2558 float(*axis_v)[2] = (axis == 0) ? x_axis_name : ((axis == 1) ? y_axis_name : z_axis_name);
2559 p[2] = axis + 0.25f;
2560 for (int i = 0; i < axis_v_len[axis]; i++) {
2561 mul_v2_v2fl(p, axis_v[i], 4.0f);
2562 GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
2563 }
2564 }
2565
2567 }
2568 return SHC.drw_bone_arrows;
2569}
2570
2571static const float staticSine[16] = {
2572 0.0f,
2573 0.104528463268f,
2574 0.207911690818f,
2575 0.309016994375f,
2576 0.406736643076f,
2577 0.5f,
2578 0.587785252292f,
2579 0.669130606359f,
2580 0.743144825477f,
2581 0.809016994375f,
2582 0.866025403784f,
2583 0.913545457643f,
2584 0.951056516295f,
2585 0.978147600734f,
2586 0.994521895368f,
2587 1.0f,
2588};
2589
2590#define set_vert(a, b, quarter) \
2591 { \
2592 copy_v2_fl2(pos, (quarter % 2 == 0) ? -(a) : (a), (quarter < 2) ? -(b) : (b)); \
2593 GPU_vertbuf_attr_set(vbo, attr_id.pos, v++, pos); \
2594 } \
2595 ((void)0)
2596
2597blender::gpu::Batch *DRW_cache_bone_dof_sphere_get()
2598{
2599 if (!SHC.drw_bone_dof_sphere) {
2600 int i, j, q, n = ARRAY_SIZE(staticSine);
2601 float x, z, px, pz, pos[2];
2602
2603 /* Position Only 3D format */
2604 static GPUVertFormat format = {0};
2605 static struct {
2606 uint pos;
2607 } attr_id;
2608 if (format.attr_len == 0) {
2610 }
2611
2613 GPU_vertbuf_data_alloc(*vbo, n * n * 6 * 4);
2614
2615 uint v = 0;
2616 for (q = 0; q < 4; q++) {
2617 pz = 0.0f;
2618 for (i = 1; i < n; i++) {
2619 z = staticSine[i];
2620 px = 0.0f;
2621 for (j = 1; j <= (n - i); j++) {
2622 x = staticSine[j];
2623 if (j == n - i) {
2624 set_vert(px, z, q);
2625 set_vert(px, pz, q);
2626 set_vert(x, pz, q);
2627 }
2628 else {
2629 set_vert(x, z, q);
2630 set_vert(x, pz, q);
2631 set_vert(px, z, q);
2632
2633 set_vert(x, pz, q);
2634 set_vert(px, pz, q);
2635 set_vert(px, z, q);
2636 }
2637 px = x;
2638 }
2639 pz = z;
2640 }
2641 }
2642 /* TODO: allocate right count from the beginning. */
2644
2646 }
2647 return SHC.drw_bone_dof_sphere;
2648}
2649
2650blender::gpu::Batch *DRW_cache_bone_dof_lines_get()
2651{
2652 if (!SHC.drw_bone_dof_lines) {
2653 int i, n = ARRAY_SIZE(staticSine);
2654 float pos[2];
2655
2656 /* Position Only 3D format */
2657 static GPUVertFormat format = {0};
2658 static struct {
2659 uint pos;
2660 } attr_id;
2661 if (format.attr_len == 0) {
2663 }
2664
2666 GPU_vertbuf_data_alloc(*vbo, n * 4);
2667
2668 uint v = 0;
2669 for (i = 0; i < n * 4; i++) {
2670 float a = (1.0f - (i / float(n * 4))) * 2.0f * M_PI;
2671 float x = cosf(a);
2672 float y = sinf(a);
2673 set_vert(x, y, 0);
2674 }
2675
2677 GPU_PRIM_LINE_LOOP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2678 }
2679 return SHC.drw_bone_dof_lines;
2680}
2681
2682#undef set_vert
2683
2686/* -------------------------------------------------------------------- */
2690blender::gpu::Batch *DRW_cache_camera_frame_get()
2691{
2692 if (!SHC.drw_camera_frame) {
2694
2695 const int v_len = 2 * (4 + 4);
2697 GPU_vertbuf_data_alloc(*vbo, v_len);
2698
2699 int v = 0;
2700 const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
2701 /* Frame */
2702 for (int a = 0; a < 4; a++) {
2703 for (int b = 0; b < 2; b++) {
2704 float x = p[(a + b) % 4][0];
2705 float y = p[(a + b) % 4][1];
2706 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
2707 }
2708 }
2709 /* Wires to origin. */
2710 for (int a = 0; a < 4; a++) {
2711 float x = p[a][0];
2712 float y = p[a][1];
2713 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
2714 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0f}, VCLASS_CAMERA_FRAME});
2715 }
2716
2718 }
2719 return SHC.drw_camera_frame;
2720}
2721
2722blender::gpu::Batch *DRW_cache_camera_volume_get()
2723{
2724 if (!SHC.drw_camera_volume) {
2726
2727 const int v_len = ARRAY_SIZE(bone_box_solid_tris) * 3;
2729 GPU_vertbuf_data_alloc(*vbo, v_len);
2730
2731 int v = 0;
2733 for (int i = 0; i < ARRAY_SIZE(bone_box_solid_tris); i++) {
2734 for (int a = 0; a < 3; a++) {
2735 float x = bone_box_verts[bone_box_solid_tris[i][a]][2];
2736 float y = bone_box_verts[bone_box_solid_tris[i][a]][0];
2737 float z = bone_box_verts[bone_box_solid_tris[i][a]][1];
2738 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, flag});
2739 }
2740 }
2741
2743 }
2744 return SHC.drw_camera_volume;
2745}
2746
2748{
2751
2752 const int v_len = ARRAY_SIZE(bone_box_wire);
2754 GPU_vertbuf_data_alloc(*vbo, v_len);
2755
2756 int v = 0;
2758 for (int i = 0; i < ARRAY_SIZE(bone_box_wire); i++) {
2759 float x = bone_box_verts[bone_box_wire[i]][2];
2760 float y = bone_box_verts[bone_box_wire[i]][0];
2761 float z = bone_box_verts[bone_box_wire[i]][1];
2762 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, flag});
2763 }
2764
2766 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2767 }
2769}
2770
2772{
2775
2776 const int v_len = 2 * 3;
2778 GPU_vertbuf_data_alloc(*vbo, v_len);
2779
2780 int v = 0;
2781 const float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}};
2782 for (int a = 0; a < 3; a++) {
2783 for (int b = 0; b < 2; b++) {
2784 float x = p[(a + b) % 3][0];
2785 float y = p[(a + b) % 3][1];
2786 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
2787 }
2788 }
2789
2791 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2792 }
2794}
2795
2796blender::gpu::Batch *DRW_cache_camera_tria_get()
2797{
2798 if (!SHC.drw_camera_tria) {
2800
2801 const int v_len = 3;
2803 GPU_vertbuf_data_alloc(*vbo, v_len);
2804
2805 int v = 0;
2806 /* Use camera frame position */
2807 GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 1.0f, 1.0f}, VCLASS_CAMERA_FRAME});
2808 GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 1.0f, 1.0f}, VCLASS_CAMERA_FRAME});
2809 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, VCLASS_CAMERA_FRAME});
2810
2812 }
2813 return SHC.drw_camera_tria;
2814}
2815
2817{
2820
2821 const int v_len = 2 * (1 + DIAMOND_NSEGMENTS * 2 + 2);
2823 GPU_vertbuf_data_alloc(*vbo, v_len);
2824
2825 int v = 0;
2826 /* Direction Line */
2827 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, VCLASS_CAMERA_DIST});
2828 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 1.0}, VCLASS_CAMERA_DIST});
2831 /* Focus cross */
2832 GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0, 0.0, 2.0}, VCLASS_CAMERA_DIST});
2833 GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0, 0.0, 2.0}, VCLASS_CAMERA_DIST});
2834 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 1.0, 2.0}, VCLASS_CAMERA_DIST});
2835 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, -1.0, 2.0}, VCLASS_CAMERA_DIST});
2836
2838 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
2839 }
2841}
2842
2845/* -------------------------------------------------------------------- */
2849blender::gpu::Batch *DRW_cache_mesh_all_verts_get(Object *ob)
2850{
2851 using namespace blender::draw;
2852 BLI_assert(ob->type == OB_MESH);
2853 return DRW_mesh_batch_cache_get_all_verts(*static_cast<Mesh *>(ob->data));
2854}
2855
2856blender::gpu::Batch *DRW_cache_mesh_all_edges_get(Object *ob)
2857{
2858 using namespace blender::draw;
2859 BLI_assert(ob->type == OB_MESH);
2860 return DRW_mesh_batch_cache_get_all_edges(*static_cast<Mesh *>(ob->data));
2861}
2862
2864{
2865 using namespace blender::draw;
2866 BLI_assert(ob->type == OB_MESH);
2867 return DRW_mesh_batch_cache_get_loose_edges(*static_cast<Mesh *>(ob->data));
2868}
2869
2870blender::gpu::Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
2871{
2872 using namespace blender::draw;
2873 BLI_assert(ob->type == OB_MESH);
2874 return DRW_mesh_batch_cache_get_edge_detection(*static_cast<Mesh *>(ob->data), r_is_manifold);
2875}
2876
2877blender::gpu::Batch *DRW_cache_mesh_surface_get(Object *ob)
2878{
2879 using namespace blender::draw;
2880 BLI_assert(ob->type == OB_MESH);
2881 return DRW_mesh_batch_cache_get_surface(*static_cast<Mesh *>(ob->data));
2882}
2883
2885{
2886 using namespace blender::draw;
2887 BLI_assert(ob->type == OB_MESH);
2888 return DRW_mesh_batch_cache_get_surface_edges(*ob, *static_cast<Mesh *>(ob->data));
2889}
2890
2892 GPUMaterial **gpumat_array,
2893 uint gpumat_array_len)
2894{
2895 using namespace blender::draw;
2896 BLI_assert(ob->type == OB_MESH);
2897 return DRW_mesh_batch_cache_get_surface_shaded(
2898 *ob, *static_cast<Mesh *>(ob->data), gpumat_array, gpumat_array_len);
2899}
2900
2902{
2903 using namespace blender::draw;
2904 BLI_assert(ob->type == OB_MESH);
2905 return DRW_mesh_batch_cache_get_surface_texpaint(*ob, *static_cast<Mesh *>(ob->data));
2906}
2907
2909{
2910 using namespace blender::draw;
2911 BLI_assert(ob->type == OB_MESH);
2912 return DRW_mesh_batch_cache_get_surface_texpaint_single(*ob, *static_cast<Mesh *>(ob->data));
2913}
2914
2916{
2917 using namespace blender::draw;
2918 BLI_assert(ob->type == OB_MESH);
2919 return DRW_mesh_batch_cache_get_surface_vertpaint(*ob, *static_cast<Mesh *>(ob->data));
2920}
2921
2923{
2924 using namespace blender::draw;
2925 BLI_assert(ob->type == OB_MESH);
2926 return DRW_mesh_batch_cache_get_surface_sculpt(*ob, *static_cast<Mesh *>(ob->data));
2927}
2928
2930{
2931 using namespace blender::draw;
2932 BLI_assert(ob->type == OB_MESH);
2933 return DRW_mesh_batch_cache_get_surface_weights(*static_cast<Mesh *>(ob->data));
2934}
2935
2937{
2938 using namespace blender::draw;
2939 BLI_assert(ob->type == OB_MESH);
2940 return DRW_mesh_batch_cache_get_wireframes_face(*static_cast<Mesh *>(ob->data));
2941}
2942
2944{
2945 using namespace blender::draw;
2946 BLI_assert(ob->type == OB_MESH);
2947 return DRW_mesh_batch_cache_get_edit_mesh_analysis(*static_cast<Mesh *>(ob->data));
2948}
2949
2951{
2952 using namespace blender::draw;
2953 BLI_assert(ob->type == OB_MESH);
2954 return DRW_mesh_batch_cache_get_surface_viewer_attribute(*static_cast<Mesh *>(ob->data));
2955}
2956
2959/* -------------------------------------------------------------------- */
2963blender::gpu::Batch *DRW_cache_curve_edge_wire_get(Object *ob)
2964{
2965 using namespace blender::draw;
2967 Curve *cu = static_cast<Curve *>(ob->data);
2968 return DRW_curve_batch_cache_get_wire_edge(cu);
2969}
2970
2972{
2973 using namespace blender::draw;
2975 Curve *cu = static_cast<Curve *>(ob->data);
2976 return DRW_curve_batch_cache_get_wire_edge_viewer_attribute(cu);
2977}
2978
2980{
2981 using namespace blender::draw;
2983 Curve *cu = static_cast<Curve *>(ob->data);
2984 return DRW_curve_batch_cache_get_normal_edge(cu);
2985}
2986
2988{
2989 using namespace blender::draw;
2991
2992 Curve *cu = static_cast<Curve *>(ob->data);
2993 return DRW_curve_batch_cache_get_edit_edges(cu);
2994}
2995
2997{
2998 using namespace blender::draw;
3000
3001 Curve *cu = static_cast<Curve *>(ob->data);
3002 return DRW_curve_batch_cache_get_edit_verts(cu);
3003}
3004
3007/* -------------------------------------------------------------------- */
3011blender::gpu::Batch *DRW_cache_text_edge_wire_get(Object *ob)
3012{
3013 using namespace blender::draw;
3014 BLI_assert(ob->type == OB_FONT);
3015 Curve *cu = static_cast<Curve *>(ob->data);
3016 return DRW_curve_batch_cache_get_wire_edge(cu);
3017}
3018
3021/* -------------------------------------------------------------------- */
3025blender::gpu::Batch *DRW_cache_surf_edge_wire_get(Object *ob)
3026{
3027 using namespace blender::draw;
3028 BLI_assert(ob->type == OB_SURF);
3029 Curve *cu = static_cast<Curve *>(ob->data);
3030 return DRW_curve_batch_cache_get_wire_edge(cu);
3031}
3032
3035/* -------------------------------------------------------------------- */
3039blender::gpu::Batch *DRW_cache_lattice_verts_get(Object *ob)
3040{
3041 using namespace blender::draw;
3042 BLI_assert(ob->type == OB_LATTICE);
3043
3044 Lattice *lt = static_cast<Lattice *>(ob->data);
3045 return DRW_lattice_batch_cache_get_all_verts(lt);
3046}
3047
3048blender::gpu::Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
3049{
3050 using namespace blender::draw;
3051 BLI_assert(ob->type == OB_LATTICE);
3052
3053 Lattice *lt = static_cast<Lattice *>(ob->data);
3054 int actdef = -1;
3055
3056 if (use_weight && !BLI_listbase_is_empty(&lt->vertex_group_names) && lt->editlatt->latt->dvert) {
3057 actdef = lt->vertex_group_active_index - 1;
3058 }
3059
3060 return DRW_lattice_batch_cache_get_all_edges(lt, use_weight, actdef);
3061}
3062
3064{
3065 using namespace blender::draw;
3066 BLI_assert(ob->type == OB_LATTICE);
3067
3068 Lattice *lt = static_cast<Lattice *>(ob->data);
3069 return DRW_lattice_batch_cache_get_edit_verts(lt);
3070}
3071
3074/* -------------------------------------------------------------------- */
3080/* -------------------------------------------------------------------- */
3084namespace blender::draw {
3085
3087{
3088 BLI_assert(ob->type == OB_VOLUME);
3089 return DRW_volume_batch_cache_get_wireframes_face(static_cast<Volume *>(ob->data));
3090}
3091
3093{
3094 BLI_assert(ob->type == OB_VOLUME);
3095 return DRW_volume_batch_cache_get_selection_surface(static_cast<Volume *>(ob->data));
3096}
3097
3098} // namespace blender::draw
3099
3102/* -------------------------------------------------------------------- */
3106blender::gpu::Batch *DRW_cache_particles_get_hair(Object *object,
3107 ParticleSystem *psys,
3108 ModifierData *md)
3109{
3110 using namespace blender::draw;
3111 return DRW_particles_batch_cache_get_hair(object, psys, md);
3112}
3113
3114blender::gpu::Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
3115{
3116 using namespace blender::draw;
3117 return DRW_particles_batch_cache_get_dots(object, psys);
3118}
3119
3121 ParticleSystem *psys,
3122 PTCacheEdit *edit,
3123 bool use_weight)
3124{
3125 using namespace blender::draw;
3126 return DRW_particles_batch_cache_get_edit_strands(object, psys, edit, use_weight);
3127}
3128
3130 ParticleSystem *psys,
3131 PTCacheEdit *edit)
3132{
3133 using namespace blender::draw;
3134 return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit);
3135}
3136
3138 ParticleSystem *psys,
3139 PTCacheEdit *edit)
3140{
3141 using namespace blender::draw;
3142 return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit);
3143}
3144
3145blender::gpu::Batch *DRW_cache_particles_get_prim(int type)
3146{
3147 switch (type) {
3148 case PART_DRAW_CROSS:
3149 if (!SHC.drw_particle_cross) {
3152 GPU_vertbuf_data_alloc(*vbo, 6);
3153
3154 int v = 0;
3155 int flag = 0;
3156 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, -1.0f, 0.0f}, flag});
3157 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 1.0f, 0.0f}, flag});
3158 GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 0.0f, 0.0f}, flag});
3159 GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 0.0f, 0.0f}, flag});
3160 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, -1.0f}, flag});
3161 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, flag});
3162
3164 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
3165 }
3166
3167 return SHC.drw_particle_cross;
3168 case PART_DRAW_AXIS:
3169 if (!SHC.drw_particle_axis) {
3172 GPU_vertbuf_data_alloc(*vbo, 6);
3173
3174 int v = 0;
3175 int flag = VCLASS_EMPTY_AXES;
3176 /* Set minimum to 0.001f so we can easily normalize to get the color. */
3177 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0001f, 0.0f}, flag});
3178 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 2.0f, 0.0f}, flag});
3179 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0001f, 0.0f, 0.0f}, flag});
3180 GPU_vertbuf_vert_set(vbo, v++, Vert{{2.0f, 0.0f, 0.0f}, flag});
3181 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0001f}, flag});
3182 GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 2.0f}, flag});
3183
3185 GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
3186 }
3187
3188 return SHC.drw_particle_axis;
3189 case PART_DRAW_CIRC:
3190#define CIRCLE_RESOL 32
3191 if (!SHC.drw_particle_circle) {
3195
3196 int v = 0;
3198 for (int a = 0; a <= CIRCLE_RESOL; a++) {
3199 float angle = (2.0f * M_PI * a) / CIRCLE_RESOL;
3200 float x = sinf(angle);
3201 float y = cosf(angle);
3202 GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0f}, flag});
3203 }
3204
3207 }
3208
3209 return SHC.drw_particle_circle;
3210#undef CIRCLE_RESOL
3211 default:
3212 BLI_assert(false);
3213 break;
3214 }
3215
3216 return nullptr;
3217}
3218
3219blender::gpu::Batch *DRW_cache_cursor_get(bool crosshair_lines)
3220{
3221 blender::gpu::Batch **drw_cursor = crosshair_lines ? &SHC.drw_cursor :
3223
3224 if (*drw_cursor == nullptr) {
3225 const float f5 = 0.25f;
3226 const float f10 = 0.5f;
3227 const float f20 = 1.0f;
3228
3229 const int segments = 16;
3230 const int vert_len = segments + 8;
3231 const int index_len = vert_len + 5;
3232
3233 const uchar red[3] = {255, 0, 0};
3234 const uchar white[3] = {255, 255, 255};
3235
3236 static GPUVertFormat format = {0};
3237 static struct {
3238 uint pos, color;
3239 } attr_id;
3240 if (format.attr_len == 0) {
3244 }
3245
3247 GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
3248
3250 GPU_vertbuf_data_alloc(*vbo, vert_len);
3251
3252 int v = 0;
3253 for (int i = 0; i < segments; i++) {
3254 float angle = float(2 * M_PI) * (float(i) / float(segments));
3255 float x = f10 * cosf(angle);
3256 float y = f10 * sinf(angle);
3257
3258 GPU_vertbuf_attr_set(vbo, attr_id.color, v, (i % 2 == 0) ? red : white);
3259
3262 }
3264
3265 if (crosshair_lines) {
3266 uchar crosshair_color[3];
3267 UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
3268
3270
3271 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{-f20, 0});
3272 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3274 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{-f5, 0});
3275 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3277
3279
3280 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{+f5, 0});
3281 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3283 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{+f20, 0});
3284 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3286
3288
3289 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, -f20});
3290 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3292 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, -f5});
3293 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3295
3297
3298 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, +f5});
3299 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3301 GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, +f20});
3302 GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
3304 }
3305
3307
3308 *drw_cursor = GPU_batch_create_ex(
3310 }
3311 return *drw_cursor;
3312}
3313
3316/* -------------------------------------------------------------------- */
3321{
3322 using namespace blender::draw;
3323 switch (ob->type) {
3324 case OB_MESH:
3325 DRW_mesh_batch_cache_validate(*ob, *(Mesh *)ob->data);
3326 break;
3327 case OB_CURVES_LEGACY:
3328 case OB_FONT:
3329 case OB_SURF:
3330 DRW_curve_batch_cache_validate((Curve *)ob->data);
3331 break;
3332 case OB_LATTICE:
3333 DRW_lattice_batch_cache_validate((Lattice *)ob->data);
3334 break;
3335 case OB_CURVES:
3336 DRW_curves_batch_cache_validate((Curves *)ob->data);
3337 break;
3338 case OB_POINTCLOUD:
3339 DRW_pointcloud_batch_cache_validate((PointCloud *)ob->data);
3340 break;
3341 case OB_VOLUME:
3342 DRW_volume_batch_cache_validate((Volume *)ob->data);
3343 break;
3344 case OB_GREASE_PENCIL:
3345 DRW_grease_pencil_batch_cache_validate((GreasePencil *)ob->data);
3346 default:
3347 break;
3348 }
3349}
3350
3352{
3353 using namespace blender::draw;
3354 const DRWContextState *draw_ctx = DRW_context_state_get();
3355 const Scene *scene = draw_ctx->scene;
3356 const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
3357 draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
3358 const bool is_paint_mode = ELEM(
3360
3361 const bool use_hide = ((ob->type == OB_MESH) &&
3362 ((is_paint_mode && (ob == draw_ctx->obact) &&
3365
3366 switch (ob->type) {
3367 case OB_MESH:
3368 DRW_mesh_batch_cache_create_requested(
3369 *DST.task_graph, *ob, *(Mesh *)ob->data, *scene, is_paint_mode, use_hide);
3370 break;
3371 case OB_CURVES_LEGACY:
3372 case OB_FONT:
3373 case OB_SURF:
3374 DRW_curve_batch_cache_create_requested(ob, scene);
3375 break;
3376 case OB_CURVES:
3377 DRW_curves_batch_cache_create_requested(ob);
3378 break;
3379 case OB_POINTCLOUD:
3380 DRW_pointcloud_batch_cache_create_requested(ob);
3381 break;
3382 /* TODO: all cases. */
3383 default:
3384 break;
3385 }
3386}
3387
3389{
3390 using namespace blender::draw;
3391 /* NOTE: Logic here is duplicated from #drw_batch_cache_generate_requested. */
3392
3393 const DRWContextState *draw_ctx = DRW_context_state_get();
3394 const Scene *scene = draw_ctx->scene;
3395 const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
3396 draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
3397 const bool is_paint_mode = ELEM(
3399
3400 const bool use_hide = ((ob->type == OB_MESH) &&
3401 ((is_paint_mode && (ob == draw_ctx->obact) &&
3404
3406 /* Try getting the mesh first and if that fails, try getting the curve data.
3407 * If the curves are surfaces or have certain modifiers applied to them, the will have mesh data
3408 * of the final result.
3409 */
3410 if (mesh != nullptr) {
3411 DRW_mesh_batch_cache_create_requested(
3412 *DST.task_graph, *ob, *mesh, *scene, is_paint_mode, use_hide);
3413 }
3414 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
3415 DRW_curve_batch_cache_create_requested(ob, scene);
3416 }
3417}
3418
3423
3424namespace blender::draw {
3426{
3427 switch (ob->type) {
3428 case OB_MESH:
3430 break;
3431 case OB_CURVES:
3433 break;
3434 case OB_POINTCLOUD:
3436 break;
3437 default:
3438 break;
3439 }
3440}
3441} // namespace blender::draw
3442
3446 const char *base_name,
3447 const int data_type,
3448 const char *layer_name,
3449 bool is_active_render,
3450 bool is_active_layer)
3451{
3452 char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
3453 GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
3454
3455 /* Attribute layer name. */
3456 SNPRINTF(attr_name, "%s%s", base_name, attr_safe_name);
3457 GPU_vertformat_alias_add(format, attr_name);
3458
3459 /* Auto layer name. */
3460 SNPRINTF(attr_name, "a%s", attr_safe_name);
3461 GPU_vertformat_alias_add(format, attr_name);
3462
3463 /* Active render layer name. */
3464 if (is_active_render) {
3465 GPU_vertformat_alias_add(format, data_type == CD_PROP_FLOAT2 ? "a" : base_name);
3466 }
3467
3468 /* Active display layer name. */
3469 if (is_active_layer) {
3470 SNPRINTF(attr_name, "a%s", base_name);
3471 GPU_vertformat_alias_add(format, attr_name);
3472 }
3473}
eContextObjectMode
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_SCULPT
@ CTX_MODE_EDIT_MESH
@ CTX_MODE_PAINT_VERTEX
@ CTX_MODE_PAINT_WEIGHT
enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, eObjectMode object_mode)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh_no_subsurf_unchecked(const Object *object)
#define BLI_assert(a)
Definition BLI_assert.h:50
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.c:966
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define M_SQRT1_2
#define M_PI
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
MINLINE void copy_v2_fl(float r[2], float f)
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
unsigned char uchar
unsigned int uint
#define UNUSED_FUNCTION(x)
#define ARRAY_SIZE(arr)
#define ELEM(...)
@ CD_PROP_FLOAT2
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ PART_DRAW_CIRC
@ PART_DRAW_CROSS
@ PART_DRAW_AXIS
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
Definition gpu_batch.cc:56
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition GPU_batch.hh:205
@ GPU_BATCH_OWNS_INDEX
Definition GPU_batch.hh:51
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:42
bool GPU_crappy_amd_driver()
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *)
blender::gpu::IndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3, uint v4)
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len)
void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3)
@ GPU_PRIM_TRI_FAN
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINES_ADJ
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRI_STRIP
@ GPU_PRIM_TRIS
void GPU_vertbuf_attr_get_raw_data(blender::gpu::VertBuf *, uint a_idx, GPUVertBufRaw *access)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_vert_set(blender::gpu::VertBuf *verts, uint v_idx, const void *data)
void GPU_vertbuf_data_resize(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
#define GPU_vertbuf_init_with_format(verts, format)
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertformat_safe_attr_name(const char *attr_name, char *r_safe_name, uint max_len)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
#define GPU_MAX_SAFE_ATTR_NAME
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias)
@ GPU_COMP_F32
@ GPU_COMP_I32
@ GPU_COMP_U32
@ GPU_COMP_U8
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its red
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
@ TH_VIEW_OVERLAY
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
MutableSpan< T > data()
local_group_size(16, 16) .push_constant(Type b
#define sinf(x)
#define cosf(x)
blender::gpu::Batch * DRW_cache_groundline_get()
#define DRW_SPHERE_SHAPE_LONGITUDE_HIGH
Definition draw_cache.cc:71
blender::gpu::Batch * DRW_cache_bone_point_get()
#define VCLASS_LIGHT_AREA_SHAPE
Definition draw_cache.cc:43
blender::gpu::Batch * DRW_cache_object_surface_get(Object *ob)
#define set_vert(a, b, quarter)
blender::gpu::Batch * DRW_cache_field_sphere_limit_get()
static struct DRWShapeCache SHC
blender::gpu::Batch * DRW_cache_lightprobe_cube_get()
static const float bone_box_solid_normals[12][3]
blender::gpu::Batch * DRW_cache_light_icon_outer_lines_get()
blender::gpu::Batch * DRW_cache_mesh_surface_weights_get(Object *ob)
blender::gpu::Batch * DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob)
blender::gpu::Batch * DRW_cache_field_vortex_get()
blender::gpu::Batch * DRW_cache_camera_volume_get()
static const uint bone_octahedral_wire_lines_adjacency[12][4]
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob)
static float y_axis_name[6][2]
blender::gpu::Batch * DRW_cache_mesh_surface_edges_get(Object *ob)
blender::gpu::Batch * DRW_cache_empty_cube_get()
void DRW_shape_cache_free()
static void circle_verts(blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
blender::gpu::Batch * DRW_cache_lightprobe_grid_get()
static float x_axis_name[4][2]
blender::gpu::Batch * DRW_cache_light_point_lines_get()
blender::gpu::Batch * DRW_cache_light_spot_lines_get()
blender::gpu::Batch * DRW_cache_lattice_verts_get(Object *ob)
blender::gpu::Batch * DRW_cache_normal_arrow_get()
blender::gpu::Batch * DRW_cache_curve_edge_wire_get(Object *ob)
static void circle_dashed_verts(blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
#define VCLASS_CAMERA_DIST
Definition draw_cache.cc:50
blender::gpu::Batch * DRW_cache_field_force_get()
#define OUTER_NSEGMENTS
static const float staticSine[16]
blender::gpu::Batch * DRW_cache_object_face_wireframe_get(const Scene *scene, Object *ob)
blender::gpu::Batch * DRW_cache_mesh_surface_get(Object *ob)
#define VCLASS_EMPTY_AXES_NAME
Definition draw_cache.cc:58
#define Z_LEN
static blender::gpu::VertBuf * sphere_wire_vbo(const float rad, int flag)
#define VCLASS_LIGHT_SPOT_BLEND
Definition draw_cache.cc:45
blender::gpu::Batch * DRW_cache_particles_get_prim(int type)
blender::gpu::Batch * DRW_cache_circle_get()
blender::gpu::Batch * DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
#define Y_LEN
blender::gpu::Batch * DRW_cache_sphere_get(const eDRWLevelOfDetail level_of_detail)
blender::gpu::Batch * DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
#define DRW_SPHERE_SHAPE_LONGITUDE_MEDIUM
Definition draw_cache.cc:68
static const uint bone_box_wire_lines_adjacency[12][4]
static const uint bone_box_wire[24]
blender::gpu::Batch * DRW_cache_curve_edge_overlay_get(Object *ob)
blender::gpu::Batch * DRW_cache_bone_point_wire_outline_get()
blender::gpu::Batch * DRW_cache_object_all_edges_get(Object *ob)
#define S_X
blender::gpu::Batch * DRW_cache_camera_volume_wire_get()
blender::gpu::Batch * DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
#define DRW_SPHERE_SHAPE_LATITUDE_LOW
Definition draw_cache.cc:64
blender::gpu::Batch * DRW_cache_curve_vert_overlay_get(Object *ob)
blender::gpu::Batch * DRW_cache_mesh_all_edges_get(Object *ob)
void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format, const char *base_name, const int data_type, const char *layer_name, bool is_active_render, bool is_active_layer)
blender::gpu::Batch * DRW_cache_light_area_square_lines_get()
blender::gpu::Batch * DRW_cache_field_cone_limit_get()
blender::gpu::Batch * DRW_cache_surf_edge_wire_get(Object *ob)
blender::gpu::Batch * DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
#define VCLASS_EMPTY_AXES
Definition draw_cache.cc:57
blender::gpu::Batch * DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
blender::gpu::Batch * DRW_cache_mesh_all_verts_get(Object *ob)
blender::gpu::Batch * DRW_cache_text_edge_wire_get(Object *ob)
blender::gpu::Batch ** DRW_cache_mesh_surface_shaded_get(Object *ob, GPUMaterial **gpumat_array, uint gpumat_array_len)
blender::gpu::Batch * drw_cache_procedural_lines_get()
blender::gpu::Batch * DRW_cache_lattice_vert_overlay_get(Object *ob)
blender::gpu::Batch * DRW_cache_light_sun_lines_get()
blender::gpu::Batch * DRW_cache_bone_envelope_solid_get()
blender::gpu::Batch * DRW_cache_mesh_surface_vertpaint_get(Object *ob)
#define VCLASS_EMPTY_SCALED
Definition draw_cache.cc:56
#define COL_HEAD
blender::gpu::Batch * DRW_cache_empty_sphere_get()
static const float bone_box_verts[8][3]
blender::gpu::Batch * DRW_cache_light_icon_sun_rays_get()
blender::gpu::Batch * DRW_cache_field_curve_get()
#define SPIRAL_RESOL
void drw_batch_cache_generate_requested(Object *ob)
#define INNER_NSEGMENTS
blender::gpu::Batch * DRW_cache_mesh_face_wireframe_get(Object *ob)
blender::gpu::VertBuf * DRW_cache_object_pos_vertbuf_get(Object *ob)
#define POS_TAIL
static const float bone_octahedral_verts[6][3]
blender::gpu::Batch * DRW_cache_field_wind_get()
#define MARKER_LEN
blender::gpu::Batch * drw_cache_procedural_triangles_get()
static void UNUSED_FUNCTION add_fancy_edge(blender::gpu::VertBuf *vbo, uint pos_id, uint n1_id, uint n2_id, uint *v_idx, const float co1[3], const float co2[3], const float n1[3], const float n2[3])
blender::gpu::Batch * DRW_cache_cursor_get(bool crosshair_lines)
#define COL_WIRE
blender::gpu::Batch * DRW_cache_bone_arrows_get()
#define NSEGMENTS
static const float bone_octahedral_solid_normals[8][3]
blender::gpu::Batch * DRW_cache_single_arrow_get()
#define CIRCLE_RESOL
#define VCLASS_LIGHT_DIST
Definition draw_cache.cc:47
blender::gpu::Batch * DRW_cache_light_icon_inner_lines_get()
#define DRW_SPHERE_SHAPE_LATITUDE_HIGH
Definition draw_cache.cc:70
void drw_batch_cache_validate(Object *ob)
#define DRW_SPHERE_SHAPE_LONGITUDE_LOW
Definition draw_cache.cc:65
blender::gpu::Batch * DRW_cache_bone_octahedral_wire_get()
#define VCLASS_LIGHT_SPOT_SHAPE
Definition draw_cache.cc:44
blender::gpu::Batch * DRW_cache_lightprobe_planar_get()
blender::gpu::Batch * DRW_cache_bone_octahedral_get()
blender::gpu::Batch * drw_cache_procedural_triangle_strips_get()
void drw_batch_cache_generate_requested_delayed(Object *ob)
blender::gpu::Batch * DRW_cache_particles_get_edit_strands(Object *object, ParticleSystem *psys, PTCacheEdit *edit, bool use_weight)
blender::gpu::Batch * DRW_cache_quad_get()
static GPUVertFormat extra_vert_format()
blender::gpu::Batch * DRW_cache_speaker_get()
#define X_LEN
blender::gpu::Batch * DRW_gpencil_dummy_buffer_get()
#define VCLASS_CAMERA_FRAME
Definition draw_cache.cc:49
#define CIRCLE_NSEGMENTS
#define VCLASS_CAMERA_VOLUME
Definition draw_cache.cc:51
blender::gpu::Batch ** DRW_cache_object_surface_material_get(Object *ob, GPUMaterial **gpumat_array, uint gpumat_array_len)
int DRW_cache_object_material_count_get(const Object *ob)
blender::gpu::Batch * DRW_cache_bone_envelope_outline_get()
blender::gpu::Batch * DRW_cache_bone_dof_lines_get()
#define VCLASS_LIGHT_SPOT_CONE
Definition draw_cache.cc:46
#define S_Y
static float z_axis_name[10][2]
static const uint bone_octahedral_solid_tris[8][3]
blender::gpu::Batch * DRW_cache_particles_get_edit_tip_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
blender::gpu::Batch * DRW_cache_fullscreen_quad_get()
blender::gpu::Batch * DRW_cache_bone_box_get()
blender::gpu::Batch * DRW_cache_camera_distances_get()
#define POS_HEAD
blender::gpu::Batch * DRW_cache_light_area_disk_lines_get()
blender::gpu::Batch * DRW_cache_particles_get_edit_inner_points(Object *object, ParticleSystem *psys, PTCacheEdit *edit)
blender::gpu::Batch * DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
#define VCLASS_SCREENALIGNED
Definition draw_cache.cc:54
blender::gpu::Batch * DRW_cache_camera_tria_wire_get()
#define DIAMOND_NSEGMENTS
blender::gpu::Batch * DRW_cache_quad_wires_get()
blender::gpu::Batch * DRW_cache_camera_frame_get()
#define VCLASS_SCREENSPACE
Definition draw_cache.cc:53
static const uint bone_box_solid_tris[12][3]
blender::gpu::Batch * DRW_cache_bone_stick_get()
blender::gpu::Batch * drw_cache_procedural_points_get()
blender::gpu::Batch * DRW_cache_grid_get()
#define COL_BONE
blender::gpu::Batch * DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
blender::gpu::Batch * DRW_cache_bone_dof_sphere_get()
blender::gpu::Batch * DRW_cache_light_spot_volume_get()
blender::gpu::Batch * DRW_cache_empty_cylinder_get()
#define COL_TAIL
#define MARKER_FILL_LAYER
#define POS_BONE
blender::gpu::Batch * DRW_cache_empty_capsule_body_get()
blender::gpu::Batch * DRW_cache_camera_tria_get()
static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
#define DRW_SPHERE_SHAPE_LATITUDE_MEDIUM
Definition draw_cache.cc:67
blender::gpu::Batch * DRW_cache_mesh_loose_edges_get(Object *ob)
blender::gpu::Batch * DRW_cache_plain_axes_get()
static float axis_marker[8][2]
blender::gpu::Batch * DRW_cache_field_tube_limit_get()
blender::gpu::Batch * DRW_cache_bone_box_wire_get()
static void sphere_lat_lon_vert(blender::gpu::VertBuf *vbo, int *v_ofs, float lat, float lon)
blender::gpu::Batch * DRW_cache_mesh_surface_viewer_attribute_get(Object *ob)
blender::gpu::Batch * DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
static float light_distance_z_get(char axis, const bool start)
blender::gpu::Batch * DRW_cache_empty_cone_get()
blender::gpu::Batch * DRW_cache_curve_edge_normal_get(Object *ob)
blender::gpu::Batch * DRW_cache_object_loose_edges_get(Object *ob)
#define VCLASS_EMPTY_SIZE
Definition draw_cache.cc:60
#define SIDE_STIPPLE
blender::gpu::Batch ** DRW_cache_mesh_surface_texpaint_get(Object *ob)
blender::gpu::Batch * DRW_cache_empty_capsule_cap_get()
blender::gpu::Batch * DRW_cache_cube_get()
eDRWLevelOfDetail
Definition draw_cache.hh:32
@ DRW_LOD_MEDIUM
Definition draw_cache.hh:34
@ DRW_LOD_LOW
Definition draw_cache.hh:33
@ DRW_LOD_HIGH
Definition draw_cache.hh:35
@ DRW_LOD_MAX
Definition draw_cache.hh:37
bool DRW_object_is_in_edit_mode(const Object *ob)
bool DRW_object_use_hide_faces(const Object *ob)
DRWManager DST
const DRWContextState * DRW_context_state_get()
draw_view in_light_buf[] float
struct @620::@622 batch
struct @620::@623 attr_id
format
void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
blender::gpu::Batch * DRW_cache_volume_face_wireframe_get(Object *ob)
blender::gpu::Batch * DRW_volume_batch_cache_get_selection_surface(Volume *volume)
void DRW_mesh_batch_cache_free_old(Mesh *mesh, int ctime)
void DRW_pointcloud_batch_cache_free_old(PointCloud *pointcloud, int ctime)
blender::gpu::Batch * DRW_volume_batch_cache_get_wireframes_face(Volume *volume)
blender::gpu::Batch * DRW_cache_volume_selection_surface_get(Object *ob)
void DRW_vertbuf_create_wiredata(blender::gpu::VertBuf *vbo, const int vert_len)
void DRW_batch_cache_free_old(Object *ob, int ctime)
Frequency::GEOMETRY nor[]
unsigned char uint8_t
Definition stdint.h:78
eObjectMode object_mode
Object * object_edit
TaskGraph * task_graph
GSet * delayed_extraction
blender::gpu::Batch * drw_field_cone_limit
blender::gpu::Batch * drw_field_wind
blender::gpu::Batch * drw_fullscreen_quad
blender::gpu::Batch * drw_light_icon_outer_lines
blender::gpu::Batch * drw_light_icon_inner_lines
blender::gpu::Batch * drw_grid
blender::gpu::Batch * drw_light_spot_volume
blender::gpu::Batch * drw_procedural_lines
blender::gpu::Batch * drw_procedural_tris
blender::gpu::Batch * drw_camera_distances
blender::gpu::Batch * drw_camera_frame
blender::gpu::Batch * drw_particle_axis
blender::gpu::Batch * drw_field_force
blender::gpu::Batch * drw_particle_cross
blender::gpu::Batch * drw_bone_octahedral_wire
blender::gpu::Batch * drw_bone_arrows
blender::gpu::Batch * drw_cube
blender::gpu::Batch * drw_light_point_lines
blender::gpu::Batch * drw_field_tube_limit
blender::gpu::Batch * drw_empty_capsule_body
blender::gpu::Batch * drw_ground_line
blender::gpu::Batch * drw_bone_envelope_outline
blender::gpu::Batch * drw_bone_dof_lines
blender::gpu::Batch * drw_bone_box_wire
blender::gpu::Batch * drw_empty_cube
blender::gpu::Batch * drw_lightprobe_cube
blender::gpu::Batch * drw_camera_tria
blender::gpu::Batch * drw_light_icon_sun_rays
blender::gpu::Batch * drw_quad_wires
blender::gpu::Batch * drw_sphere_lod[DRW_LOD_MAX]
blender::gpu::Batch * drw_procedural_verts
blender::gpu::Batch * drw_gpencil_dummy_quad
blender::gpu::Batch * drw_procedural_tri_strips
blender::gpu::Batch * drw_camera_volume_wire
blender::gpu::Batch * drw_cursor_only_circle
blender::gpu::Batch * drw_empty_sphere
blender::gpu::Batch * drw_single_arrow
blender::gpu::Batch * drw_light_area_disk_lines
blender::gpu::Batch * drw_camera_volume
blender::gpu::Batch * drw_cursor
blender::gpu::Batch * drw_bone_box
blender::gpu::Batch * drw_normal_arrow
blender::gpu::Batch * drw_bone_point
blender::gpu::Batch * drw_bone_envelope
blender::gpu::Batch * drw_quad
blender::gpu::Batch * drw_particle_circle
blender::gpu::Batch * drw_bone_octahedral
blender::gpu::Batch * drw_lightprobe_grid
blender::gpu::Batch * drw_empty_cone
blender::gpu::Batch * drw_camera_tria_wire
blender::gpu::Batch * drw_speaker
blender::gpu::Batch * drw_bone_stick
blender::gpu::Batch * drw_field_vortex
blender::gpu::Batch * drw_empty_capsule_cap
blender::gpu::Batch * drw_field_sphere_limit
blender::gpu::Batch * drw_light_area_square_lines
blender::gpu::Batch * drw_lightprobe_planar
blender::gpu::Batch * drw_plain_axes
blender::gpu::Batch * drw_bone_dof_sphere
blender::gpu::Batch * drw_light_sun_lines
blender::gpu::Batch * drw_empty_cylinder
blender::gpu::Batch * drw_light_spot_lines
blender::gpu::Batch * drw_field_curve
blender::gpu::Batch * drw_circle
blender::gpu::Batch * drw_bone_point_wire
struct Lattice * latt
ListBase vertex_group_names
struct MDeformVert * dvert
int vertex_group_active_index
struct EditLatt * editlatt
float nor[3]
Definition draw_cache.cc:93
float pos[3]
Definition draw_cache.cc:91
int v_class
Definition draw_cache.cc:81
float pos[3]
Definition draw_cache.cc:80
uint8_t flag
Definition wm_window.cc:138