Blender V5.0
gpu_immediate_util.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
10
11#include <cstring>
12
13#include "DNA_userdef_types.h"
14
15#include "BLI_math_rotation.h"
16#include "BLI_math_vector.h"
17#include "BLI_rect.h"
18#include "BLI_utildefines.h"
19
20#include "GPU_immediate.hh"
21
22#include "UI_resources.hh"
23
24static const float cube_coords[8][3] = {
25 {-1, -1, -1},
26 {-1, -1, +1},
27 {-1, +1, -1},
28 {-1, +1, +1},
29 {+1, -1, -1},
30 {+1, -1, +1},
31 {+1, +1, -1},
32 {+1, +1, +1},
33};
34static const int cube_quad_index[6][4] = {
35 {0, 1, 3, 2},
36 {0, 2, 6, 4},
37 {0, 4, 5, 1},
38 {1, 5, 7, 3},
39 {2, 3, 7, 6},
40 {4, 6, 7, 5},
41};
42static const int cube_line_index[12][2] = {
43 {0, 1},
44 {0, 2},
45 {0, 4},
46 {1, 3},
47 {1, 5},
48 {2, 3},
49 {2, 6},
50 {3, 7},
51 {4, 5},
52 {4, 6},
53 {5, 7},
54 {6, 7},
55};
56
57void immRectf(uint pos, float x1, float y1, float x2, float y2)
58{
60 immVertex2f(pos, x1, y1);
61 immVertex2f(pos, x2, y1);
62 immVertex2f(pos, x2, y2);
63 immVertex2f(pos, x1, y2);
64 immEnd();
65}
66
67void immRecti(uint pos, int x1, int y1, int x2, int y2)
68{
70 immVertex2i(pos, x1, y1);
71 immVertex2i(pos, x2, y1);
72 immVertex2i(pos, x2, y2);
73 immVertex2i(pos, x1, y2);
74 immEnd();
75}
76
77void immRectf_fast(uint pos, float x1, float y1, float x2, float y2)
78{
79 immVertex2f(pos, x1, y1);
80 immVertex2f(pos, x2, y1);
81 immVertex2f(pos, x2, y2);
82
83 immVertex2f(pos, x1, y1);
84 immVertex2f(pos, x2, y2);
85 immVertex2f(pos, x1, y2);
86}
87
89 uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4])
90{
91 immAttr4fv(col, color);
92 immVertex2f(pos, x1, y1);
93 immAttr4fv(col, color);
94 immVertex2f(pos, x2, y1);
95 immAttr4fv(col, color);
96 immVertex2f(pos, x2, y2);
97
98 immAttr4fv(col, color);
99 immVertex2f(pos, x1, y1);
100 immAttr4fv(col, color);
101 immVertex2f(pos, x2, y2);
102 immAttr4fv(col, color);
103 immVertex2f(pos, x1, y2);
104}
105
107 uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4])
108{
109 immAttr4fv(col, color);
110 immVertex2i(pos, x1, y1);
111 immAttr4fv(col, color);
112 immVertex2i(pos, x2, y1);
113 immAttr4fv(col, color);
114 immVertex2i(pos, x2, y2);
115
116 immAttr4fv(col, color);
117 immVertex2i(pos, x1, y1);
118 immAttr4fv(col, color);
119 immVertex2i(pos, x2, y2);
120 immAttr4fv(col, color);
121 immVertex2i(pos, x1, y2);
122}
123
124void immRectf_with_texco(const uint pos, const uint tex_coord, const rctf &p, const rctf &uv)
125{
127 immAttr2f(tex_coord, uv.xmin, uv.ymin);
128 immVertex2f(pos, p.xmin, p.ymin);
129
130 immAttr2f(tex_coord, uv.xmin, uv.ymax);
131 immVertex2f(pos, p.xmin, p.ymax);
132
133 immAttr2f(tex_coord, uv.xmax, uv.ymax);
134 immVertex2f(pos, p.xmax, p.ymax);
135
136 immAttr2f(tex_coord, uv.xmax, uv.ymin);
137 immVertex2f(pos, p.xmax, p.ymin);
138 immEnd();
139}
140
141#if 0 /* more complete version in case we want that */
142void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4])
143{
145 uint pos = add_attr(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
147 immUniformColor4fv(color);
148 immRectf(pos, x1, y1, x2, y2);
150}
151#endif
152
154{
155 immUniformColor3ub(((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF));
156}
157
158static void imm_draw_circle(GPUPrimType prim_type,
159 const uint shdr_pos,
160 float x,
161 float y,
162 float radius_x,
163 float radius_y,
164 int nsegments)
165{
166 if (prim_type == GPU_PRIM_LINE_LOOP) {
167 /* NOTE(Metal/AMD): For small primitives, line list more efficient than line strip.. */
168 immBegin(GPU_PRIM_LINES, nsegments * 2);
169
170 immVertex2f(shdr_pos, x + (radius_x * cosf(0.0f)), y + (radius_y * sinf(0.0f)));
171 for (int i = 1; i < nsegments; i++) {
172 const float angle = float(2 * M_PI) * (float(i) / float(nsegments));
173 immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
174 immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
175 }
176 immVertex2f(shdr_pos, x + (radius_x * cosf(0.0f)), y + (radius_y * sinf(0.0f)));
177 immEnd();
178 }
179 else {
180 immBegin(prim_type, nsegments);
181 for (int i = 0; i < nsegments; i++) {
182 const float angle = float(2 * M_PI) * (float(i) / float(nsegments));
183 immVertex2f(shdr_pos, x + (radius_x * cosf(angle)), y + (radius_y * sinf(angle)));
184 }
185 immEnd();
186 }
187}
188
189void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
190{
191 imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius, radius, nsegments);
192}
193
194void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
195{
196 imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, radius, radius, nsegments);
197}
198
200 uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
201{
202 imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
203}
204
206 uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
207{
208 imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, radius_x, radius_y, nsegments);
209}
210
212 uint pos,
213 float x,
214 float y,
215 float radius,
216 int nsegments,
217 float start,
218 float sweep)
219{
220 /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
221 const float angle_start = -DEG2RADF(start) + float(M_PI_2);
222 const float angle_end = -(DEG2RADF(sweep) - angle_start);
223 nsegments += 1;
224 immBegin(prim_type, nsegments);
225 for (int i = 0; i < nsegments; i++) {
226 const float angle = interpf(angle_start, angle_end, (float(i) / float(nsegments - 1)));
227 const float angle_sin = sinf(angle);
228 const float angle_cos = cosf(angle);
229 immVertex2f(pos, x + radius * angle_cos, y + radius * angle_sin);
230 }
231 immEnd();
232}
233
235 uint pos,
236 float x,
237 float y,
238 float z,
239 float rad,
240 int nsegments,
241 float start,
242 float sweep)
243{
244 /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
245 const float angle_start = -DEG2RADF(start) + float(M_PI / 2);
246 const float angle_end = -(DEG2RADF(sweep) - angle_start);
247 nsegments += 1;
248 immBegin(prim_type, nsegments);
249 for (int i = 0; i < nsegments; i++) {
250 const float angle = interpf(angle_start, angle_end, (float(i) / float(nsegments - 1)));
251 const float angle_sin = sinf(angle);
252 const float angle_cos = cosf(angle);
253 immVertex3f(pos, x + rad * angle_cos, y + rad * angle_sin, z);
254 }
255 immEnd();
256}
257
259 uint pos, float x, float y, float radius, int nsegments, float start, float sweep)
260{
261 imm_draw_circle_partial(GPU_PRIM_LINE_STRIP, pos, x, y, radius, nsegments, start, sweep);
262}
263
265 uint pos, float x, float y, float z, float radius, int nsegments, float start, float sweep)
266{
267 imm_draw_circle_partial_3d(GPU_PRIM_LINE_STRIP, pos, x, y, z, radius, nsegments, start, sweep);
268}
269
270static void imm_draw_disk_partial(GPUPrimType prim_type,
271 uint pos,
272 float x,
273 float y,
274 float rad_inner,
275 float rad_outer,
276 int nsegments,
277 float start,
278 float sweep)
279{
280 /* to avoid artifacts */
281 const float max_angle = 3 * 360;
282 CLAMP(sweep, -max_angle, max_angle);
283
284 /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
285 const float angle_start = -DEG2RADF(start) + float(M_PI_2);
286 const float angle_end = -(DEG2RADF(sweep) - angle_start);
287 nsegments += 1;
288 immBegin(prim_type, nsegments * 2);
289 for (int i = 0; i < nsegments; i++) {
290 const float angle = interpf(angle_start, angle_end, (float(i) / float(nsegments - 1)));
291 const float angle_sin = sinf(angle);
292 const float angle_cos = cosf(angle);
293 immVertex2f(pos, x + rad_inner * angle_cos, y + rad_inner * angle_sin);
294 immVertex2f(pos, x + rad_outer * angle_cos, y + rad_outer * angle_sin);
295 }
296 immEnd();
297}
298
300 uint pos,
301 float x,
302 float y,
303 float z,
304 float rad_inner,
305 float rad_outer,
306 int nsegments,
307 float start,
308 float sweep)
309{
310 /* to avoid artifacts */
311 const float max_angle = 3 * 360;
312 CLAMP(sweep, -max_angle, max_angle);
313
314 /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */
315 const float angle_start = -DEG2RADF(start) + float(M_PI_2);
316 const float angle_end = -(DEG2RADF(sweep) - angle_start);
317 nsegments += 1;
318 immBegin(prim_type, nsegments * 2);
319 for (int i = 0; i < nsegments; i++) {
320 const float angle = interpf(angle_start, angle_end, (float(i) / float(nsegments - 1)));
321 const float angle_sin = sinf(angle);
322 const float angle_cos = cosf(angle);
323 immVertex3f(pos, x + rad_inner * angle_cos, y + rad_inner * angle_sin, z);
324 immVertex3f(pos, x + rad_outer * angle_cos, y + rad_outer * angle_sin, z);
325 }
326 immEnd();
327}
328
330 float x,
331 float y,
332 float rad_inner,
333 float rad_outer,
334 int nsegments,
335 float start,
336 float sweep)
337{
339 GPU_PRIM_TRI_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep);
340}
342 float x,
343 float y,
344 float z,
345 float rad_inner,
346 float rad_outer,
347 int nsegments,
348 float start,
349 float sweep)
350{
352 GPU_PRIM_TRI_STRIP, pos, x, y, z, rad_inner, rad_outer, nsegments, start, sweep);
353}
354
355static void imm_draw_circle_3D(GPUPrimType prim_type,
356 uint pos,
357 float x,
358 float y,
359 float radius_x,
360 float radius_y,
361 int nsegments)
362{
363 if (prim_type == GPU_PRIM_LINE_LOOP) {
364 /* NOTE(Metal/AMD): For small primitives, line list more efficient than line strip. */
365 immBegin(GPU_PRIM_LINES, nsegments * 2);
366
367 const float angle = float(2 * M_PI) / float(nsegments);
368 float xprev = cosf(-angle) * radius_x;
369 float yprev = sinf(-angle) * radius_y;
370 const float alpha = 2.0f * cosf(angle);
371
372 float xr = radius_x;
373 float yr = 0;
374
375 for (int i = 0; i < nsegments; i++) {
376 immVertex3f(pos, x + xr, y + yr, 0.0f);
377 if (i) {
378 immVertex3f(pos, x + xr, y + yr, 0.0f);
379 }
380 /* `cos[(n + 1)a] = 2cos(a)cos(na) - cos[(n - 1)a]`. */
381 const float xnext = alpha * xr - xprev;
382 /* `sin[(n + 1)a] = 2cos(a)sin(na) - sin[(n - 1)a]`. */
383 const float ynext = alpha * yr - yprev;
384 xprev = xr;
385 yprev = yr;
386 xr = xnext;
387 yr = ynext;
388 }
389 immVertex3f(pos, x + radius_x, y, 0.0f);
390 immEnd();
391 }
392 else {
393 immBegin(prim_type, nsegments);
394 for (int i = 0; i < nsegments; i++) {
395 float angle = float(2 * M_PI) * (float(i) / float(nsegments));
396 immVertex3f(pos, x + radius_x * cosf(angle), y + radius_y * sinf(angle), 0.0f);
397 }
398 immEnd();
399 }
400}
401
402void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
403{
404 imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius, radius, nsegments);
405}
406
408 uint pos, float x, float y, float radius_x, float radius_y, int nsegments)
409{
410 imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius_x, radius_y, nsegments);
411}
412
413void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
414{
415 imm_draw_circle_3D(GPU_PRIM_LINES, pos, x, y, radius, radius, nsegments / 2);
416}
417
418void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
419{
420 imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, radius, nsegments);
421}
422
424 uint pos, float x, float y, float radius_x, float radius_y, int nsegments)
425{
426 imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius_x, radius_y, nsegments);
427}
428
429void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
430{
431 /* NOTE(Metal/AMD): For small primitives, line list more efficient than line-strip. */
433 immVertex2f(pos, x1, y1);
434 immVertex2f(pos, x1, y2);
435
436 immVertex2f(pos, x1, y2);
437 immVertex2f(pos, x2, y2);
438
439 immVertex2f(pos, x2, y2);
440 immVertex2f(pos, x2, y1);
441
442 immVertex2f(pos, x2, y1);
443 immVertex2f(pos, x1, y1);
444 immEnd();
445}
446
447void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2)
448{
449 /* use this version when GPUVertFormat has a vec3 position */
450 /* NOTE(Metal/AMD): For small primitives, line list more efficient than line-strip. */
452 immVertex3f(pos, x1, y1, 0.0f);
453 immVertex3f(pos, x1, y2, 0.0f);
454
455 immVertex3f(pos, x1, y2, 0.0f);
456 immVertex3f(pos, x2, y2, 0.0f);
457
458 immVertex3f(pos, x2, y2, 0.0f);
459 immVertex3f(pos, x2, y1, 0.0f);
460
461 immVertex3f(pos, x2, y1, 0.0f);
462 immVertex3f(pos, x1, y1, 0.0f);
463 immEnd();
464}
465
467 float y1,
468 float x2,
469 float y2,
470 const float color_primary[4],
471 const float color_secondary[4],
472 int checker_size)
473{
475 immVertexFormat(), "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
476
478
479 immUniform4fv("color1", color_primary);
480 immUniform4fv("color2", color_secondary);
481 immUniform1i("size", checker_size);
482
483 immRectf(pos, x1, y1, x2, y2);
484
486}
487void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2, bool clear_alpha)
488{
489 float checker_primary[4];
490 float checker_secondary[4];
493 checker_primary[3] = clear_alpha ? 0.0 : checker_primary[3];
494 checker_secondary[3] = clear_alpha ? 0.0 : checker_secondary[3];
495 int checker_size = UI_GetThemeValue(TH_TRANSPARENT_CHECKER_SIZE) * U.pixelsize;
496 imm_draw_box_checker_2d_ex(x1, y1, x2, y2, checker_primary, checker_secondary, checker_size);
497}
498
499void imm_draw_cube_fill_3d(uint pos, const float center[3], const float aspect[3])
500{
501 float coords[ARRAY_SIZE(cube_coords)][3];
502
503 for (int i = 0; i < ARRAY_SIZE(cube_coords); i++) {
504 madd_v3_v3v3v3(coords[i], center, cube_coords[i], aspect);
505 }
506
508 for (int i = 0; i < ARRAY_SIZE(cube_quad_index); i++) {
509 immVertex3fv(pos, coords[cube_quad_index[i][0]]);
510 immVertex3fv(pos, coords[cube_quad_index[i][1]]);
511 immVertex3fv(pos, coords[cube_quad_index[i][2]]);
512
513 immVertex3fv(pos, coords[cube_quad_index[i][0]]);
514 immVertex3fv(pos, coords[cube_quad_index[i][2]]);
515 immVertex3fv(pos, coords[cube_quad_index[i][3]]);
516 }
517 immEnd();
518}
519
520void imm_draw_cube_wire_3d(uint pos, const float center[3], const float aspect[3])
521{
522 float coords[ARRAY_SIZE(cube_coords)][3];
523
524 for (int i = 0; i < ARRAY_SIZE(cube_coords); i++) {
525 madd_v3_v3v3v3(coords[i], center, cube_coords[i], aspect);
526 }
527
529 for (int i = 0; i < ARRAY_SIZE(cube_line_index); i++) {
530 immVertex3fv(pos, coords[cube_line_index[i][0]]);
531 immVertex3fv(pos, coords[cube_line_index[i][1]]);
532 }
533 immEnd();
534}
535
537 const float center[3],
538 const float aspect[3],
539 const float factor)
540{
541 float coords[ARRAY_SIZE(cube_coords)][3];
542
543 for (int i = 0; i < ARRAY_SIZE(cube_coords); i++) {
544 madd_v3_v3v3v3(coords[i], center, cube_coords[i], aspect);
545 }
546
548 for (int i = 0; i < ARRAY_SIZE(cube_line_index); i++) {
549 float vec[3], co[3];
550 sub_v3_v3v3(vec, coords[cube_line_index[i][1]], coords[cube_line_index[i][0]]);
551 mul_v3_fl(vec, factor);
552
553 copy_v3_v3(co, coords[cube_line_index[i][0]]);
554 immVertex3fv(pos, co);
555 add_v3_v3(co, vec);
556 immVertex3fv(pos, co);
557
558 copy_v3_v3(co, coords[cube_line_index[i][1]]);
559 immVertex3fv(pos, co);
560 sub_v3_v3(co, vec);
561 immVertex3fv(pos, co);
562 }
563 immEnd();
564}
565
567 uint pos, uint nor, float base, float top, float height, int slices, int stacks)
568{
569 immBegin(GPU_PRIM_TRIS, 6 * slices * stacks);
570 for (int i = 0; i < slices; i++) {
571 const float angle1 = float(2 * M_PI) * (float(i) / float(slices));
572 const float angle2 = float(2 * M_PI) * (float(i + 1) / float(slices));
573 const float cos1 = cosf(angle1);
574 const float sin1 = sinf(angle1);
575 const float cos2 = cosf(angle2);
576 const float sin2 = sinf(angle2);
577
578 for (int j = 0; j < stacks; j++) {
579 float fac1 = float(j) / float(stacks);
580 float fac2 = float(j + 1) / float(stacks);
581 float r1 = base * (1.0f - fac1) + top * fac1;
582 float r2 = base * (1.0f - fac2) + top * fac2;
583 float h1 = height * (float(j) / float(stacks));
584 float h2 = height * (float(j + 1) / float(stacks));
585
586 const float v1[3] = {r1 * cos2, r1 * sin2, h1};
587 const float v2[3] = {r2 * cos2, r2 * sin2, h2};
588 const float v3[3] = {r2 * cos1, r2 * sin1, h2};
589 const float v4[3] = {r1 * cos1, r1 * sin1, h1};
590 float n1[3], n2[3];
591
592 /* calc normals */
593 sub_v3_v3v3(n1, v2, v1);
594 normalize_v3(n1);
595 n1[0] = cos1;
596 n1[1] = sin1;
597 n1[2] = 1 - n1[2];
598
599 sub_v3_v3v3(n2, v3, v4);
600 normalize_v3(n2);
601 n2[0] = cos2;
602 n2[1] = sin2;
603 n2[2] = 1 - n2[2];
604
605 /* first tri */
606 immAttr3fv(nor, n2);
607 immVertex3fv(pos, v1);
609 immAttr3fv(nor, n1);
610 immVertex3fv(pos, v3);
611
612 /* second tri */
613 immVertex3fv(pos, v3);
614 immVertex3fv(pos, v4);
615 immAttr3fv(nor, n2);
616 immVertex3fv(pos, v1);
617 }
618 }
619 immEnd();
620}
621
623 uint pos, float base, float top, float height, int slices, int stacks)
624{
625 immBegin(GPU_PRIM_LINES, 6 * slices * stacks);
626 for (int i = 0; i < slices; i++) {
627 const float angle1 = float(2 * M_PI) * (float(i) / float(slices));
628 const float angle2 = float(2 * M_PI) * (float(i + 1) / float(slices));
629 const float cos1 = cosf(angle1);
630 const float sin1 = sinf(angle1);
631 const float cos2 = cosf(angle2);
632 const float sin2 = sinf(angle2);
633
634 for (int j = 0; j < stacks; j++) {
635 float fac1 = float(j) / float(stacks);
636 float fac2 = float(j + 1) / float(stacks);
637 float r1 = base * (1.0f - fac1) + top * fac1;
638 float r2 = base * (1.0f - fac2) + top * fac2;
639 float h1 = height * (float(j) / float(stacks));
640 float h2 = height * (float(j + 1) / float(stacks));
641
642 const float v1[3] = {r1 * cos2, r1 * sin2, h1};
643 const float v2[3] = {r2 * cos2, r2 * sin2, h2};
644 const float v3[3] = {r2 * cos1, r2 * sin1, h2};
645 const float v4[3] = {r1 * cos1, r1 * sin1, h1};
646
647 immVertex3fv(pos, v1);
649
651 immVertex3fv(pos, v3);
652
653 immVertex3fv(pos, v1);
654 immVertex3fv(pos, v4);
655 }
656 }
657 immEnd();
658}
659
661 uint pos, float base, float top, float height, int slices, int stacks)
662{
663 immBegin(GPU_PRIM_TRIS, 6 * slices * stacks);
664 for (int i = 0; i < slices; i++) {
665 const float angle1 = float(2 * M_PI) * (float(i) / float(slices));
666 const float angle2 = float(2 * M_PI) * (float(i + 1) / float(slices));
667 const float cos1 = cosf(angle1);
668 const float sin1 = sinf(angle1);
669 const float cos2 = cosf(angle2);
670 const float sin2 = sinf(angle2);
671
672 for (int j = 0; j < stacks; j++) {
673 float fac1 = float(j) / float(stacks);
674 float fac2 = float(j + 1) / float(stacks);
675 float r1 = base * (1.0f - fac1) + top * fac1;
676 float r2 = base * (1.0f - fac2) + top * fac2;
677 float h1 = height * (float(j) / float(stacks));
678 float h2 = height * (float(j + 1) / float(stacks));
679
680 const float v1[3] = {r1 * cos2, r1 * sin2, h1};
681 const float v2[3] = {r2 * cos2, r2 * sin2, h2};
682 const float v3[3] = {r2 * cos1, r2 * sin1, h2};
683 const float v4[3] = {r1 * cos1, r1 * sin1, h1};
684
685 /* first tri */
686 immVertex3fv(pos, v1);
688 immVertex3fv(pos, v3);
689
690 /* second tri */
691 immVertex3fv(pos, v3);
692 immVertex3fv(pos, v4);
693 immVertex3fv(pos, v1);
694 }
695 }
696 immEnd();
697}
698
699/* Circle Drawing - Tables for Optimized Drawing Speed */
700constexpr static int CIRCLE_RESOL = 32;
701
702static void circball_array_fill(const float verts[CIRCLE_RESOL][3],
703 const float cent[3],
704 const float radius,
705 const float tmat[4][4])
706{
707 /* 32 values of sin function (still same result!) */
708 const float sinval[CIRCLE_RESOL] = {
709 0.00000000, 0.20129852, 0.39435585, 0.57126821, 0.72479278, 0.84864425, 0.93775213,
710 0.98846832, 0.99871650, 0.96807711, 0.89780453, 0.79077573, 0.65137248, 0.48530196,
711 0.29936312, 0.10116832, -0.10116832, -0.29936312, -0.48530196, -0.65137248, -0.79077573,
712 -0.89780453, -0.96807711, -0.99871650, -0.98846832, -0.93775213, -0.84864425, -0.72479278,
713 -0.57126821, -0.39435585, -0.20129852, 0.00000000,
714 };
715
716 /* 32 values of cos function (still same result!) */
717 const float cosval[CIRCLE_RESOL] = {
718 1.00000000, 0.97952994, 0.91895781, 0.82076344, 0.68896691, 0.52896401, 0.34730525,
719 0.15142777, -0.05064916, -0.25065253, -0.44039415, -0.61210598, -0.75875812, -0.87434661,
720 -0.95413925, -0.99486932, -0.99486932, -0.95413925, -0.87434661, -0.75875812, -0.61210598,
721 -0.44039415, -0.25065253, -0.05064916, 0.15142777, 0.34730525, 0.52896401, 0.68896691,
722 0.82076344, 0.91895781, 0.97952994, 1.00000000,
723 };
724
725 float vx[3], vy[3];
726 float *viter = (float *)verts;
727
728 mul_v3_v3fl(vx, tmat[0], radius);
729 mul_v3_v3fl(vy, tmat[1], radius);
730
731 for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) {
732 viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0];
733 viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1];
734 viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2];
735 }
736}
737
738void imm_drawcircball(const float cent[3], float radius, const float tmat[4][4], uint pos)
739{
740 float verts[CIRCLE_RESOL][3];
741
742 circball_array_fill(verts, cent, radius, tmat);
743
745 for (int i = 0; i < CIRCLE_RESOL; i++) {
747 }
748 immEnd();
749}
MINLINE float interpf(float target, float origin, float t)
#define DEG2RADF(_deg)
#define M_PI_2
#define M_PI
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
unsigned int uint
#define CLAMP(a, b, c)
#define ARRAY_SIZE(arr)
void immEnd()
void immUnbindProgram()
void immAttr4fv(uint attr_id, const float data[4])
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
void immVertex2f(uint attr_id, float x, float y)
void immVertex3f(uint attr_id, float x, float y, float z)
void immUniform1i(const char *name, int x)
void immVertex2i(uint attr_id, int x, int y)
GPUVertFormat * immVertexFormat()
void immUniformColor4fv(const float rgba[4])
void immUniform4fv(const char *name, const float data[4])
void immAttr3fv(uint attr_id, const float data[3])
void immAttr2f(uint attr_id, float x, float y)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
GPUPrimType
@ GPU_PRIM_TRI_FAN
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRI_STRIP
@ GPU_PRIM_TRIS
@ GPU_SHADER_2D_CHECKER
@ GPU_SHADER_3D_UNIFORM_COLOR
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
@ TH_TRANSPARENT_CHECKER_PRIMARY
@ TH_TRANSPARENT_CHECKER_SECONDARY
@ TH_TRANSPARENT_CHECKER_SIZE
void UI_GetThemeColor4fv(int colorid, float col[4])
int UI_GetThemeValue(int colorid)
#define U
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
#define CIRCLE_RESOL
nullptr float
static float verts[][3]
uint pos
uint nor
uint col
uint top
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void imm_draw_cylinder_wire_3d(uint pos, float base, float top, float height, int slices, int stacks)
static void circball_array_fill(const float verts[CIRCLE_RESOL][3], const float cent[3], const float radius, const float tmat[4][4])
void imm_draw_disk_partial_fill_3d(uint pos, float x, float y, float z, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
static void imm_draw_disk_partial_3d(GPUPrimType prim_type, uint pos, float x, float y, float z, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
void imm_draw_cylinder_fill_3d(uint pos, float base, float top, float height, int slices, int stacks)
void imm_draw_circle_partial_wire_2d(uint pos, float x, float y, float radius, int nsegments, float start, float sweep)
void imm_draw_cylinder_fill_normal_3d(uint pos, uint nor, float base, float top, float height, int slices, int stacks)
void imm_draw_box_checker_2d_ex(float x1, float y1, float x2, float y2, const float color_primary[4], const float color_secondary[4], int checker_size)
void imm_draw_circle_wire_aspect_3d(uint pos, float x, float y, float radius_x, float radius_y, int nsegments)
static void imm_draw_disk_partial(GPUPrimType prim_type, uint pos, float x, float y, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2, bool clear_alpha)
void imm_draw_circle_fill_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
void imm_draw_circle_partial_wire_3d(uint pos, float x, float y, float z, float radius, int nsegments, float start, float sweep)
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_drawcircball(const float cent[3], float radius, const float tmat[4][4], uint pos)
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
void immRectf_fast(uint pos, float x1, float y1, float x2, float y2)
void immRecti(uint pos, int x1, int y1, int x2, int y2)
static const int cube_quad_index[6][4]
void imm_draw_circle_wire_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4])
static void imm_draw_circle_partial(GPUPrimType prim_type, uint pos, float x, float y, float radius, int nsegments, float start, float sweep)
void imm_draw_box_wire_3d(uint pos, float x1, float y1, float x2, float y2)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
static void imm_draw_circle_partial_3d(GPUPrimType prim_type, uint pos, float x, float y, float z, float rad, int nsegments, float start, float sweep)
static const float cube_coords[8][3]
static const int cube_line_index[12][2]
void imm_draw_cube_corners_3d(uint pos, const float center[3], const float aspect[3], const float factor)
void imm_draw_cube_wire_3d(uint pos, const float center[3], const float aspect[3])
static void imm_draw_circle_3D(GPUPrimType prim_type, uint pos, float x, float y, float radius_x, float radius_y, int nsegments)
void imm_draw_cube_fill_3d(uint pos, const float center[3], const float aspect[3])
void imm_cpack(uint x)
void imm_draw_circle_fill_aspect_3d(uint pos, float x, float y, float radius_x, float radius_y, int nsegments)
void immRectf_with_texco(const uint pos, const uint tex_coord, const rctf &p, const rctf &uv)
void imm_draw_disk_partial_fill_2d(uint pos, float x, float y, float rad_inner, float rad_outer, int nsegments, float start, float sweep)
void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4])
static void imm_draw_circle(GPUPrimType prim_type, const uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
uint tex_coord
format
#define sinf
#define cosf
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230