Blender V5.0
interface_draw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cmath>
10#include <cstring>
11
12#include "DNA_color_types.h"
13#include "DNA_curve_types.h"
15#include "DNA_movieclip_types.h"
16#include "DNA_screen_types.h"
17
18#include "BLI_math_rotation.h"
19#include "BLI_polyfill_2d.h"
20#include "BLI_rect.h"
21#include "BLI_string_utf8.h"
22#include "BLI_utildefines.h"
23
24#include "MEM_guardedalloc.h"
25
26#include "BKE_colorband.hh"
27#include "BKE_colortools.hh"
28#include "BKE_curveprofile.h"
29#include "BKE_tracking.h"
30
32#include "IMB_imbuf.hh"
33#include "IMB_imbuf_types.hh"
34
35#include "BIF_glutil.hh"
36
37#include "BLF_api.hh"
38
39#include "GPU_batch.hh"
40#include "GPU_batch_presets.hh"
41#include "GPU_immediate.hh"
42#include "GPU_immediate_util.hh"
43#include "GPU_matrix.hh"
44#include "GPU_shader_shared.hh"
45#include "GPU_state.hh"
46#include "GPU_uniform_buffer.hh"
47
48/* own include */
49#include "interface_intern.hh"
50
52
54{
55 /* Not sure the roundbox function is the best place to change this
56 * if this is undone, it's not that big a deal, only makes curves edges square. */
57 roundboxtype = type;
58}
59
60#if 0 /* unused */
61int UI_draw_roundbox_corner_get()
62{
63 return roundboxtype;
64}
65#endif
66
68 const float inner1[4],
69 const float inner2[4],
70 float shade_dir,
71 const float outline[4],
72 float outline_width,
73 float rad)
74{
75 /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
76 * If it has been scaled, then it's no longer valid. */
77 uiWidgetBaseParameters widget_params{};
78 widget_params.recti.xmin = rect->xmin + outline_width;
79 widget_params.recti.ymin = rect->ymin + outline_width;
80 widget_params.recti.xmax = rect->xmax - outline_width;
81 widget_params.recti.ymax = rect->ymax - outline_width;
82 widget_params.rect = *rect;
83 widget_params.radi = rad;
84 widget_params.rad = rad;
85 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
86 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
87 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
88 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
89 widget_params.color_inner1[0] = inner1 ? inner1[0] : 0.0f;
90 widget_params.color_inner1[1] = inner1 ? inner1[1] : 0.0f;
91 widget_params.color_inner1[2] = inner1 ? inner1[2] : 0.0f;
92 widget_params.color_inner1[3] = inner1 ? inner1[3] : 0.0f;
93 widget_params.color_inner2[0] = inner2 ? inner2[0] : inner1 ? inner1[0] : 0.0f;
94 widget_params.color_inner2[1] = inner2 ? inner2[1] : inner1 ? inner1[1] : 0.0f;
95 widget_params.color_inner2[2] = inner2 ? inner2[2] : inner1 ? inner1[2] : 0.0f;
96 widget_params.color_inner2[3] = inner2 ? inner2[3] : inner1 ? inner1[3] : 0.0f;
97 widget_params.color_outline[0] = outline ? outline[0] : inner1 ? inner1[0] : 0.0f;
98 widget_params.color_outline[1] = outline ? outline[1] : inner1 ? inner1[1] : 0.0f;
99 widget_params.color_outline[2] = outline ? outline[2] : inner1 ? inner1[2] : 0.0f;
100 widget_params.color_outline[3] = outline ? outline[3] : inner1 ? inner1[3] : 0.0f;
101 widget_params.shade_dir = shade_dir;
102 widget_params.alpha_discard = 1.0f;
103
104 blender::gpu::Batch *batch = ui_batch_roundbox_widget_get();
106 GPU_batch_uniform_4fv_array(batch, "parameters", 11, (const float (*)[4]) & widget_params);
110}
111
113 const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
114{
115 const float colv[4] = {
116 float(col[0]) / 255.0f,
117 float(col[1]) / 255.0f,
118 float(col[2]) / 255.0f,
119 float(alpha) / 255.0f,
120 };
121 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
122}
123
125 const rctf *rect, bool filled, float rad, const float col[3], float alpha)
126{
127 const float colv[4] = {col[0], col[1], col[2], alpha};
128 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
129}
130
131void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
132{
133 /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
134 * of the previous AA method. Better fix the callers. */
135 float colv[4] = {color[0], color[1], color[2], color[3]};
136 if (filled) {
137 colv[3] *= 0.65f;
138 }
139
140 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
141}
142
143void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
144{
145 /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
146 UI_draw_roundbox_4fv_ex(rect, (filled) ? col : nullptr, nullptr, 1.0f, col, U.pixelsize, rad);
147}
148
150 const float rad,
151 const blender::float4 color)
152{
155 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
156
157 float vec[4][2] = {
158 {0.195, 0.02},
159 {0.55, 0.169},
160 {0.831, 0.45},
161 {0.98, 0.805},
162 };
163 for (int a = 0; a < 4; a++) {
164 mul_v2_fl(vec[a], rad);
165 }
166
168 immUniformColor4fv(color);
169
172 immVertex2f(pos, rect.xmin, rect.ymax);
173 immVertex2f(pos, rect.xmin, rect.ymax - rad);
174 for (int a = 0; a < 4; a++) {
175 immVertex2f(pos, rect.xmin + vec[a][1], rect.ymax - rad + vec[a][0]);
176 }
177 immVertex2f(pos, rect.xmin + rad, rect.ymax);
178 immEnd();
179 }
180
183 immVertex2f(pos, rect.xmax, rect.ymax);
184 immVertex2f(pos, rect.xmax - rad, rect.ymax);
185 for (int a = 0; a < 4; a++) {
186 immVertex2f(pos, rect.xmax - rad + vec[a][0], rect.ymax - vec[a][1]);
187 }
188 immVertex2f(pos, rect.xmax, rect.ymax - rad);
189 immEnd();
190 }
191
194 immVertex2f(pos, rect.xmax, rect.ymin);
195 immVertex2f(pos, rect.xmax, rect.ymin + rad);
196 for (int a = 0; a < 4; a++) {
197 immVertex2f(pos, rect.xmax - vec[a][1], rect.ymin + rad - vec[a][0]);
198 }
199 immVertex2f(pos, rect.xmax - rad, rect.ymin);
200 immEnd();
201 }
202
205 immVertex2f(pos, rect.xmin, rect.ymin);
206 immVertex2f(pos, rect.xmin + rad, rect.ymin);
207 for (int a = 0; a < 4; a++) {
208 immVertex2f(pos, rect.xmin + rad - vec[a][0], rect.ymin + vec[a][1]);
209 }
210 immVertex2f(pos, rect.xmin, rect.ymin + rad);
211 immEnd();
212 }
213
215}
216
217void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
218{
219 const int ofs_y = 4 * U.pixelsize;
220
223 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
224
226 immUniformColor4fv(color);
227
228 immRectf(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
230}
231
232/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
233
235 float rad,
236 uchar highlight[3],
237 uchar highlight_fade[3])
238{
239 /* NOTE: based on `UI_draw_roundbox` functions
240 * check on making a version which allows us to skip some sides. */
241
244 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
246 format, "color", blender::gpu::VertAttrType::UNORM_8_8_8_8);
247 /* add a 1px offset, looks nicer */
248 const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
249 const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
250 int a;
251 float vec[4][2] = {
252 {0.195, 0.02},
253 {0.55, 0.169},
254 {0.831, 0.45},
255 {0.98, 0.805},
256 };
257
258 /* Multiply. */
259 for (a = 0; a < 4; a++) {
260 mul_v2_fl(vec[a], rad);
261 }
262
265
266 immAttr4ub(col, UNPACK3(highlight), 255);
267
268 /* start with corner left-top */
270 immVertex2f(pos, minx, maxy - rad);
271 for (a = 0; a < 4; a++) {
272 immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
273 }
274 immVertex2f(pos, minx + rad, maxy);
275 }
276 else {
277 immVertex2f(pos, minx, maxy);
278 }
279
280 /* corner right-top */
282 immVertex2f(pos, maxx - rad, maxy);
283 for (a = 0; a < 4; a++) {
284 immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
285 }
286 immVertex2f(pos, maxx, maxy - rad);
287 }
288 else {
289 immVertex2f(pos, maxx, maxy);
290 }
291
292 immAttr4ub(col, UNPACK3(highlight_fade), 255);
293
294 /* corner right-bottom */
296 immVertex2f(pos, maxx, miny + rad);
297 for (a = 0; a < 4; a++) {
298 immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
299 }
300 immVertex2f(pos, maxx - rad, miny);
301 }
302 else {
303 immVertex2f(pos, maxx, miny);
304 }
305
306 /* corner left-bottom */
308 immVertex2f(pos, minx + rad, miny);
309 for (a = 0; a < 4; a++) {
310 immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
311 }
312 immVertex2f(pos, minx, miny + rad);
313 }
314 else {
315 immVertex2f(pos, minx, miny);
316 }
317
318 immAttr4ub(col, UNPACK3(highlight), 255);
319
320 /* back to corner left-top */
321 immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);
322
323 immEnd();
325}
326
327void ui_draw_but_IMAGE(ARegion * /*region*/,
328 uiBut *but,
329 const uiWidgetColors * /*wcol*/,
330 const rcti *rect)
331{
332#ifdef WITH_HEADLESS
333 (void)rect;
334 (void)but;
335#else
336 ImBuf *ibuf = (ImBuf *)but->poin;
337
338 if (!ibuf) {
339 return;
340 }
341
342 const int w = BLI_rcti_size_x(rect);
343 const int h = BLI_rcti_size_y(rect);
344
345 /* scissor doesn't seem to be doing the right thing...? */
346# if 0
347 /* prevent drawing outside widget area */
348 int scissor[4];
349 GPU_scissor_get(scissor);
350 GPU_scissor(rect->xmin, rect->ymin, w, h);
351# endif
352
353 /* Combine with premultiplied alpha. */
355
356 if (w != ibuf->x || h != ibuf->y) {
357 /* We scale the bitmap, rather than have OGL do a worse job. */
358 IMB_scale(ibuf, w, h, IMBScaleFilter::Box, false);
359 }
360
361 float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
362 if (but->col[3] != 0) {
363 /* Optionally use uiBut's col to recolor the image. */
365 }
366
369 float(rect->xmin),
370 float(rect->ymin),
371 ibuf->x,
372 ibuf->y,
373 blender::gpu::TextureFormat::UNORM_8_8_8_8,
374 false,
375 ibuf->byte_buffer.data,
376 1.0f,
377 1.0f,
378 col);
379
381
382# if 0
383 /* Restore scissor-test. */
384 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
385# endif
386
387#endif
388}
389
391 const rctf *rect,
392 const float title_aspect[2],
393 const float action_aspect[2])
394{
395 const float size_x_half = (rect->xmax - rect->xmin) * 0.5f;
396 const float size_y_half = (rect->ymax - rect->ymin) * 0.5f;
397
398 const float *safe_areas[] = {title_aspect, action_aspect};
399 const int safe_len = ARRAY_SIZE(safe_areas);
400
401 for (int i = 0; i < safe_len; i++) {
402 if (safe_areas[i][0] || safe_areas[i][1]) {
403 const float margin_x = safe_areas[i][0] * size_x_half;
404 const float margin_y = safe_areas[i][1] * size_y_half;
405
406 const float minx = rect->xmin + margin_x;
407 const float miny = rect->ymin + margin_y;
408 const float maxx = rect->xmax - margin_x;
409 const float maxy = rect->ymax - margin_y;
410
411 imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
412 }
413 }
414}
415
416static void draw_scope_end(const rctf *rect)
417{
419
420 /* outline */
422 const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
423 rctf box_rect{};
424 box_rect.xmin = rect->xmin - 1;
425 box_rect.xmax = rect->xmax + 1;
426 box_rect.ymin = rect->ymin;
427 box_rect.ymax = rect->ymax + 1;
428 UI_draw_roundbox_4fv(&box_rect, false, 3.0f, color);
429}
430
431static void histogram_draw_one(float r,
432 float g,
433 float b,
434 float alpha,
435 float x,
436 float y,
437 float w,
438 float h,
439 const float *data,
440 int res,
441 const bool is_line,
442 uint pos_attr)
443{
444 const float color[4] = {r, g, b, alpha};
445
446 /* that can happen */
447 if (res == 0) {
448 return;
449 }
450
451 GPU_line_smooth(true);
453
454 immUniformColor4fv(color);
455
456 if (is_line) {
457 /* curve outline */
458 GPU_line_width(1.5);
459
461 for (int i = 0; i < res; i++) {
462 const float x2 = x + i * (w / float(res));
463 immVertex2f(pos_attr, x2, y + (data[i] * h));
464 }
465 immEnd();
466
467 GPU_line_width(1.0f);
468 }
469 else {
470 /* under the curve */
472 immVertex2f(pos_attr, x, y);
473 immVertex2f(pos_attr, x, y + (data[0] * h));
474 for (int i = 1; i < res; i++) {
475 const float x2 = x + i * (w / float(res));
476 immVertex2f(pos_attr, x2, y + (data[i] * h));
477 immVertex2f(pos_attr, x2, y);
478 }
479 immEnd();
480
481 /* curve outline */
482 immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
483
486 for (int i = 0; i < res; i++) {
487 const float x2 = x + i * (w / float(res));
488 immVertex2f(pos_attr, x2, y + (data[i] * h));
489 }
490 immEnd();
491 }
492
493 GPU_line_smooth(false);
494}
495
496#define HISTOGRAM_TOT_GRID_LINES 4
497
499 uiBut *but,
500 const uiWidgetColors * /*wcol*/,
501 const rcti *recti)
502{
503 Histogram *hist = (Histogram *)but->poin;
504 const int res = hist->x_resolution;
505 const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
506
507 rctf rect{};
508 rect.xmin = float(recti->xmin + 1);
509 rect.xmax = float(recti->xmax - 1);
510 rect.ymin = float(recti->ymin + 1);
511 rect.ymax = float(recti->ymax - 1);
512
513 const float w = BLI_rctf_size_x(&rect);
514 const float h = BLI_rctf_size_y(&rect) * hist->ymax;
515
517
518 float color[4];
521 rctf back_rect{};
522 back_rect.xmin = rect.xmin - 1;
523 back_rect.xmax = rect.xmax + 1;
524 back_rect.ymin = rect.ymin - 1;
525 back_rect.ymax = rect.ymax + 1;
526
527 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
528
529 /* need scissor test, histogram can draw outside of boundary */
530 int scissor[4];
531 GPU_scissor_get(scissor);
532 rcti scissor_new{};
533 scissor_new.xmin = rect.xmin;
534 scissor_new.ymin = rect.ymin;
535 scissor_new.xmax = rect.xmax;
536 scissor_new.ymax = rect.ymax;
537 const rcti scissor_region = {0, region->winx, 0, region->winy};
538 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
539 GPU_scissor(scissor_new.xmin,
540 scissor_new.ymin,
541 BLI_rcti_size_x(&scissor_new),
542 BLI_rcti_size_y(&scissor_new));
543
546 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
547
549
550 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
551 /* draw grid lines here */
552 for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
553 const float fac = float(i) / float(HISTOGRAM_TOT_GRID_LINES);
554
555 /* so we can tell the 1.0 color point */
557 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
558 }
559
561
562 immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
563 immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
564
565 immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
566 immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
567
568 immEnd();
569 }
570
571 if (hist->mode == HISTO_MODE_LUMA) {
573 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
574 }
575 else if (hist->mode == HISTO_MODE_ALPHA) {
577 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
578 }
579 else {
580 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_R)) {
582 1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
583 }
584 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_G)) {
586 0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
587 }
588 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_B)) {
590 0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
591 }
592 }
593
595
596 /* Restore scissor test. */
597 GPU_scissor(UNPACK4(scissor));
598
599 /* outline */
600 draw_scope_end(&rect);
601}
602
603#undef HISTOGRAM_TOT_GRID_LINES
604
605static void waveform_draw_one(const float *waveform, int waveform_num, const float col[3])
606{
609 "It is not allowed to draw a batch when immediate mode has a shader bound. It will "
610 "use the incorrect shader and is hard to discover.");
611 GPUVertFormat format = {0};
612 const uint pos_id = GPU_vertformat_attr_add(
613 &format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
614
616 GPU_vertbuf_data_alloc(*vbo, waveform_num);
617
618 GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
619
620 /* TODO: store the #blender::gpu::Batch inside the scope. */
621 blender::gpu::Batch *batch = GPU_batch_create_ex(
622 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
624 GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
625 GPU_batch_uniform_1f(batch, "size", 1.0f);
627
629}
630
635static_assert(sizeof(WaveformColorVertex) == 24);
636
637static void waveform_draw_rgb(const float *waveform,
638 int waveform_num,
639 const float *col,
640 float alpha)
641{
642 GPUVertFormat format = {0};
643 GPU_vertformat_attr_add(&format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
644 GPU_vertformat_attr_add(&format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
645
647
648 GPU_vertbuf_data_alloc(*vbo, waveform_num);
650 for (int i = 0; i < waveform_num; i++) {
651 memcpy(&data->pos, waveform, sizeof(data->pos));
652 memcpy(&data->color, col, sizeof(float) * 3);
653 data->color.w = alpha;
654 waveform += 2;
655 col += 3;
656 data++;
657 }
659 GPU_vertbuf_use(vbo);
660
661 blender::gpu::Batch *batch = GPU_batch_create_ex(
662 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
664 GPU_batch_uniform_1f(batch, "size", 1.0f);
667}
668
669static void circle_draw_rgb(float *points, int tot_points, const float *col, GPUPrimType prim)
670{
671 GPUVertFormat format = {0};
672 const uint pos_id = GPU_vertformat_attr_add(
673 &format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
674 const uint col_id = GPU_vertformat_attr_add(
675 &format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
676
678
679 GPU_vertbuf_data_alloc(*vbo, tot_points);
680 GPU_vertbuf_attr_fill(vbo, pos_id, points);
681 GPU_vertbuf_attr_fill(vbo, col_id, col);
682
683 blender::gpu::Batch *batch = GPU_batch_create_ex(prim, vbo, nullptr, GPU_BATCH_OWNS_VBO);
684
688}
689
691 uiBut *but,
692 const uiWidgetColors * /*wcol*/,
693 const rcti *recti)
694{
695 Scopes *scopes = (Scopes *)but->poin;
696 int scissor[4];
697 float colors[3][3];
698 const float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
699 /* Colors pre-multiplied by alpha for speed up. */
700 float colors_alpha[3][3], colorsycc_alpha[3][3];
701 float min, max;
702
703 if (scopes == nullptr) {
704 return;
705 }
706
707 rctf rect{};
708 rect.xmin = float(recti->xmin + 1);
709 rect.xmax = float(recti->xmax - 1);
710 rect.ymin = float(recti->ymin + 1);
711 rect.ymax = float(recti->ymax - 1);
712
713 if (scopes->wavefrm_yfac < 0.5f) {
714 scopes->wavefrm_yfac = 0.98f;
715 }
716 const float w = BLI_rctf_size_x(&rect) - 7;
717 const float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
718 const float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
719 const float w3 = w / 3.0f;
720
721 /* log scale for alpha */
722 const float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
723
724 unit_m3(colors);
725
726 for (int c = 0; c < 3; c++) {
727 for (int i = 0; i < 3; i++) {
728 colors_alpha[c][i] = colors[c][i] * alpha;
729 colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
730 }
731 }
732
733 /* Flush text cache before changing scissors. */
735
737
738 float color[4];
741 rctf back_rect{};
742 back_rect.xmin = rect.xmin - 1.0f;
743 back_rect.xmax = rect.xmax + 1.0f;
744 back_rect.ymin = rect.ymin - 1.0f;
745 back_rect.ymax = rect.ymax + 1.0f;
746 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
747
748 /* need scissor test, waveform can draw outside of boundary */
749 GPU_scissor_get(scissor);
750 rcti scissor_new{};
751 scissor_new.xmin = rect.xmin;
752 scissor_new.ymin = rect.ymin;
753 scissor_new.xmax = rect.xmax;
754 scissor_new.ymax = rect.ymax;
755 const rcti scissor_region = {0, region->winx, 0, region->winy};
756 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
757 GPU_scissor(scissor_new.xmin,
758 scissor_new.ymin,
759 BLI_rcti_size_x(&scissor_new),
760 BLI_rcti_size_y(&scissor_new));
761
762 /* draw scale numbers first before binding any shader */
763 for (int i = 0; i < 6; i++) {
764 char str[4];
765 SNPRINTF_UTF8(str, "%-3d", i * 20);
766 str[3] = '\0';
767 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
768 BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
769 }
770
771 /* Flush text cache before drawing things on top. */
773
776 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
777
779
780 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
781
782 /* draw grid lines here */
784
785 for (int i = 0; i < 6; i++) {
786 immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
787 immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
788 }
789
790 immEnd();
791
792 /* 3 vertical separation */
793 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
795
796 for (int i = 1; i < 3; i++) {
797 immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
798 immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
799 }
800
801 immEnd();
802 }
803
804 /* separate min max zone on the right */
806 immVertex2f(pos, rect.xmin + w, rect.ymin);
807 immVertex2f(pos, rect.xmin + w, rect.ymax);
808 immEnd();
809
810 /* 16-235-240 level in case of ITU-R BT601/709 */
811 immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
814
815 immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
816 immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
817
818 immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
819 immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
820
821 immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
822 immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
823
824 immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
825 immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
826
827 immEnd();
828 }
829 /* 7.5 IRE black point level for NTSC */
830 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
832 immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
833 immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
834 immEnd();
835 }
836
837 if (scopes->ok && scopes->waveform_1 != nullptr) {
839 GPU_point_size(1.0);
840
841 /* LUMA (1 channel) */
842 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
843 const float col[3] = {alpha, alpha, alpha};
844
846 GPU_matrix_translate_2f(rect.xmin, yofs);
848
850 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
852
854
855 /* min max */
856 immUniformColor3f(0.5f, 0.5f, 0.5f);
857 min = yofs + scopes->minmax[0][0] * h;
858 max = yofs + scopes->minmax[0][1] * h;
859 CLAMP(min, rect.ymin, rect.ymax);
860 CLAMP(max, rect.ymin, rect.ymax);
861
863 immVertex2f(pos, rect.xmax - 3, min);
864 immVertex2f(pos, rect.xmax - 3, max);
865 immEnd();
866 }
867 /* RGB (3 channel) */
868 else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
870 GPU_matrix_translate_2f(rect.xmin, yofs);
873 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
874 waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
875 waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
878 }
879 /* PARADE / YCC (3 channels) */
880 else if (ELEM(scopes->wavefrm_mode,
885 {
886 const int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
889 GPU_matrix_translate_2f(rect.xmin, yofs);
890 GPU_matrix_scale_2f(w3, h);
891
893 scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
894
895 GPU_matrix_translate_2f(1.0f, 0.0f);
897 scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
898
899 GPU_matrix_translate_2f(1.0f, 0.0f);
901 scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
902
905 }
906
907 /* min max */
908 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
909 for (int c = 0; c < 3; c++) {
911 immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
912 }
913 else {
915 colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
916 }
917 min = yofs + scopes->minmax[c][0] * h;
918 max = yofs + scopes->minmax[c][1] * h;
919 CLAMP(min, rect.ymin, rect.ymax);
920 CLAMP(max, rect.ymin, rect.ymax);
921
923 immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
924 immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
925 immEnd();
926 }
927 }
928 }
929
931
932 /* Restore scissor test. */
933 GPU_scissor(UNPACK4(scissor));
934
935 /* outline */
936 draw_scope_end(&rect);
937
939}
940
941static float polar_to_x(float center, float diam, float ampli, float angle)
942{
943 return center + diam * ampli * cosf(angle);
944}
945
946static float polar_to_y(float center, float diam, float ampli, float angle)
947{
948 return center + diam * ampli * sinf(angle);
949}
950
952 uint pos, float centerx, float centery, float diam, const float colf[3], char label)
953{
954 float y, u, v;
955 float tangle = 0.0f, tampli;
956 float dangle, dampli;
957 const char labelstr[2] = {label, '\0'};
958
959 rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
962
963 if (u > 0 && v >= 0) {
964 tangle = atanf(v / u);
965 }
966 else if (u > 0 && v < 0) {
967 tangle = atanf(v / u) + 2.0f * float(M_PI);
968 }
969 else if (u < 0) {
970 tangle = atanf(v / u) + float(M_PI);
971 }
972 else if (u == 0 && v > 0.0f) {
973 tangle = M_PI_2;
974 }
975 else if (u == 0 && v < 0.0f) {
976 tangle = -M_PI_2;
977 }
978 tampli = sqrtf(u * u + v * v);
979
980 /* small target vary by 2.5 degree and 2.5 IRE unit */
981 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
982 dangle = DEG2RADF(2.5f);
983 dampli = 2.5f / 200.0f;
986 polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
987 polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
989 polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
990 polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
992 polar_to_x(centerx, diam, tampli - dampli, tangle - dangle),
993 polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
995 polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
996 polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
997
998 /* draw color letter as text */
999 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.3f);
1000 BLF_draw_default(polar_to_x(centerx, diam, tampli, tangle) + 5,
1001 polar_to_y(centery, diam, tampli, tangle),
1002 0,
1003 labelstr,
1004 strlen(labelstr));
1005
1006 immEnd();
1007}
1008
1010 uiBut *but,
1011 const uiWidgetColors * /*wcol*/,
1012 const rcti *recti)
1013{
1014 const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
1015 const Scopes *scopes = (const Scopes *)but->poin;
1016
1017 const float colors[6][3] = {
1018 {0.75, 0.0, 0.0}, /* Red */
1019 {0.75, 0.75, 0.0}, /* Yellow */
1020 {0.0, 0.75, 0.0}, /* Green */
1021 {0.0, 0.75, 0.75}, /* Cyan */
1022 {0.0, 0.0, 0.75}, /* Blue */
1023 {0.75, 0.0, 0.75}, /* Magenta */
1024 };
1025
1026 const char color_names[] = {'R', 'Y', 'G', 'C', 'B', 'M'};
1027
1028 rctf rect{};
1029 rect.xmin = float(recti->xmin + 1);
1030 rect.xmax = float(recti->xmax - 1);
1031 rect.ymin = float(recti->ymin + 1);
1032 rect.ymax = float(recti->ymax - 1);
1033
1034 const float w = BLI_rctf_size_x(&rect);
1035 const float h = BLI_rctf_size_y(&rect);
1036 const float centerx = rect.xmin + w * 0.5f;
1037 const float centery = rect.ymin + h * 0.5f;
1038 const float diam = ((w < h) ? w : h) * 0.9f;
1039
1040 const float alpha = scopes->vecscope_alpha;
1041
1042 GPU_line_smooth(true);
1044
1045 float color[4];
1048 rctf back_rect{};
1049 back_rect.xmin = rect.xmin - 1;
1050 back_rect.xmax = rect.xmax + 1;
1051 back_rect.ymin = rect.ymin - 1;
1052 back_rect.ymax = rect.ymax + 1;
1053 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
1054
1055 /* need scissor test, vectorscope can draw outside of boundary */
1056 int scissor[4];
1057 GPU_scissor_get(scissor);
1058 rcti scissor_new{};
1059 scissor_new.xmin = rect.xmin;
1060 scissor_new.ymin = rect.ymin;
1061 scissor_new.xmax = rect.xmax;
1062 scissor_new.ymax = rect.ymax;
1063 const rcti scissor_region = {0, region->winx, 0, region->winy};
1064 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1065 GPU_scissor(scissor_new.xmin,
1066 scissor_new.ymin,
1067 BLI_rcti_size_x(&scissor_new),
1068 BLI_rcti_size_y(&scissor_new));
1069
1072 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1073
1075 const int increment = 6;
1076 const int tot_points = int(360 / increment);
1077 const float r = 0.5f;
1078 float step = 360.0f / (tot_points - 1);
1079
1080 float circle_fill_points[(tot_points * 2) + 2];
1081 float circle_fill_vertex_colors[(tot_points * 4) + 4];
1082
1083 /* draw filled RGB circle for background, only for LUMA mode */
1084 if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1085 /* Initialize center point and color */
1086 circle_fill_points[0] = centerx;
1087 circle_fill_points[1] = centery;
1088 circle_fill_vertex_colors[0] = 0.2f;
1089 circle_fill_vertex_colors[1] = 0.2f;
1090 circle_fill_vertex_colors[2] = 0.2f;
1091 circle_fill_vertex_colors[3] = 0.8f;
1092
1093 for (int i = 0; i < tot_points; i++) {
1094 float angle = step * i;
1095 const float a = DEG2RADF(angle);
1096
1097 const float x = polar_to_x(centerx, diam, r, a);
1098 const float y = polar_to_y(centery, diam, r, a);
1099
1100 const float u = (x - centerx) / diam / SCOPES_VEC_U_SCALE;
1101 const float v = (y - centery) / diam / SCOPES_VEC_V_SCALE;
1102
1103 circle_fill_points[(i + 1) * 2] = x;
1104 circle_fill_points[(i + 1) * 2 + 1] = y;
1105
1106 float r, g, b;
1107 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1108
1109 circle_fill_vertex_colors[(i + 1) * 4] = r * 0.2f;
1110 circle_fill_vertex_colors[(i + 1) * 4 + 1] = g * 0.2f;
1111 circle_fill_vertex_colors[(i + 1) * 4 + 2] = b * 0.2f;
1112 circle_fill_vertex_colors[(i + 1) * 4 + 3] = 0.8f;
1113 }
1114
1117 circle_fill_points, tot_points + 1, circle_fill_vertex_colors, GPU_PRIM_TRI_FAN);
1118 }
1119 /* draw filled Gray circle for background, only for RGB mode */
1120 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1122 immBegin(GPU_PRIM_TRI_FAN, tot_points + 2);
1123 immUniformColor3f(0.16f, 0.16f, 0.16f);
1124 immVertex2f(pos, centerx, centery);
1125
1126 for (int i = 0; i <= 360; i += increment) {
1127 const float a = DEG2RADF(float(i));
1128 immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
1129 }
1130 immEnd();
1131 }
1132
1133 /* draw RGB ring */
1134 float circle_points[(tot_points * 2) + 3] = {};
1135 float circle_vertex_colors[(tot_points * 4) + 5] = {};
1136
1137 for (int i = 0; i < tot_points; i++) {
1138 float angle = step * i;
1139 const float a = DEG2RADF(angle);
1140
1141 const float x = polar_to_x(centerx, diam, 0.5f, a);
1142 const float y = polar_to_y(centery, diam, 0.5f, a);
1143 circle_points[i * 2] = x;
1144 circle_points[i * 2 + 1] = y;
1145
1146 const float u = (x - centerx) / diam / SCOPES_VEC_U_SCALE;
1147 const float v = (y - centery) / diam / SCOPES_VEC_V_SCALE;
1148 float r, g, b;
1149 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1150
1151 circle_vertex_colors[i * 4] = r;
1152 circle_vertex_colors[i * 4 + 1] = g;
1153 circle_vertex_colors[i * 4 + 2] = b;
1154 circle_vertex_colors[i * 4 + 3] = 0.8f;
1155 }
1156
1158 GPU_line_width(2.5f);
1159 circle_draw_rgb(circle_points, tot_points, circle_vertex_colors, GPU_PRIM_LINE_LOOP);
1160 GPU_line_width(1.5f);
1161
1162 /* inner circles */
1164 for (int j = 0; j < 4; j++) {
1165 float inner_circle_points[(tot_points * 2) + 3] = {};
1166 float inner_circle_colors[(tot_points * 4) + 5] = {};
1167 const float r = (j + 1) * 0.1f;
1168
1169 for (int i = 0; i < tot_points; i++) {
1170 float angle = step * i;
1171 const float a = DEG2RADF(angle);
1172
1173 inner_circle_points[i * 2] = polar_to_x(centerx, diam, r, a);
1174 inner_circle_points[i * 2 + 1] = polar_to_y(centery, diam, r, a);
1175
1176 inner_circle_colors[i * 4] = 0.1f;
1177 inner_circle_colors[i * 4 + 1] = 0.1f;
1178 inner_circle_colors[i * 4 + 2] = 0.1f;
1179 inner_circle_colors[i * 4 + 3] = 0.8f;
1180 }
1181 circle_draw_rgb(inner_circle_points, tot_points, inner_circle_colors, GPU_PRIM_LINE_LOOP);
1182 }
1183
1184 /* draw grid elements */
1185 /* cross */
1186 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.1f);
1188
1189 immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
1190 immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
1191
1192 immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
1193 immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
1194
1195 immEnd();
1196
1197 /* skin tone line */
1199 immUniformColor3f(0.25f, 0.25f, 0.25f);
1200
1203 pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
1205 pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
1206 immEnd();
1207
1208 /* saturation points */
1209 for (int i = 0; i < 6; i++) {
1210 vectorscope_draw_target(pos, centerx, centery, diam, colors[i], color_names[i]);
1211 }
1212
1213 if (scopes->ok && scopes->vecscope != nullptr) {
1214 /* pixel point cloud */
1215 GPU_point_size(1.0);
1216
1218 GPU_matrix_translate_2f(centerx, centery);
1219 GPU_matrix_scale_1f(diam);
1220
1221 const float col[3] = {alpha, alpha, alpha};
1222 if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1224 waveform_draw_rgb(scopes->vecscope, scopes->waveform_tot, scopes->vecscope_rgb, alpha);
1225 }
1226 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1229 waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
1231 }
1232
1234 }
1235
1237
1238 /* Restore scissor test. */
1239 GPU_scissor(UNPACK4(scissor));
1240 /* outline */
1241 draw_scope_end(&rect);
1242
1244}
1245
1246static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth)
1247{
1248 /* Half-width equals height for better AA with 45 degree slope. */
1250 immVertex2f(pos, x1 + halfwidth, y1);
1251 immVertex2f(pos, x1, y1 + halfwidth);
1252 immVertex2f(pos, x1 - halfwidth, y1);
1253 immEnd();
1254}
1255
1256static void ui_draw_colorband_handle_box(uint pos, float x1, float y1, float x2, float y2)
1257{
1259 immVertex2f(pos, x2, y1);
1260 immVertex2f(pos, x1, y1);
1261 immVertex2f(pos, x2, y2);
1262 immVertex2f(pos, x1, y2);
1263 immEnd();
1264}
1265
1266static void ui_draw_colorband_handle(uint shdr_pos,
1267 const rcti *rect,
1268 float x,
1269 const float rgb[3],
1270 const ColorManagedDisplay *display,
1271 bool active)
1272{
1273 const float sizey = BLI_rcti_size_y(rect);
1274 float colf[3] = {UNPACK3(rgb)};
1275
1276 const float half_width = sizey / 3.5f;
1277 const float height = half_width * 1.4f;
1278
1279 float y1 = rect->ymin;
1280 const float y2 = rect->ymax;
1281
1282 /* align to pixels */
1283 x = floorf(x);
1284
1286
1287 /* Allow the lines to decrease as we get really small. */
1288 float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize),
1289 0.5f);
1290
1291 /* Make things transparent as we get tiny. */
1292 uchar alpha = std::min(int(fabs(half_width - 2.0f) * 50.0f), 255);
1293
1295
1296 float viewport_size[4];
1297 GPU_viewport_size_get_f(viewport_size);
1298 immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
1299 immUniform1i("colors_len", 2); /* "advanced" mode */
1300 if (active) {
1301 immUniform4f("color", 1.0f, 1.0f, 1.0f, alpha / 255.0f);
1302 immUniform4f("color2", 0.0f, 0.0f, 0.0f, alpha / 255.0f);
1303 }
1304 else {
1305 immUniform4f("color", 0.7f, 0.7f, 0.7f, alpha / 255.0f);
1306 immUniform4f("color2", 0.4f, 0.4f, 0.4f, alpha / 255.0f);
1307 }
1308 immUniform1f("dash_width", sizey / 6.0f / UI_SCALE_FAC);
1309 immUniform1f("udash_factor", 0.5f);
1310
1312 immVertex2f(shdr_pos, x, y1);
1313 immVertex2f(shdr_pos, x, y2);
1314 immEnd();
1315
1317
1319
1320 /* shift handle down */
1321 y1 -= half_width / 2.0f;
1322
1323 /* Black outline around the lower box. */
1324 immUniformColor4ub(0, 0, 0, alpha);
1325
1327 x - half_width - line_width,
1328 y1 - line_width,
1329 x + half_width + line_width,
1330 y1 + height);
1331
1332 /* Grey box, inset by line width. */
1333 immUniformColor4ub(128, 128, 128, alpha);
1334 ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1, x + half_width, y1 + height);
1335
1336 if (display) {
1338 }
1339
1340 /* Color value, inset by another line width. */
1341 immUniformColor3fvAlpha(colf, alpha);
1343 x - (half_width - line_width),
1344 y1 + line_width,
1345 x + (half_width - line_width),
1346 y1 + height - line_width);
1347
1348 /* Black outline around the top triangle. */
1349 immUniformColor4ub(0, 0, 0, alpha);
1350 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width + line_width);
1351
1352 GPU_polygon_smooth(true);
1353
1354 /* Triangle main color. */
1355 if (active) {
1356 immUniformColor4ub(220, 220, 220, alpha);
1357 }
1358 else {
1359 immUniformColor4ub(96, 96, 96, alpha);
1360 }
1361 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width - (0.5f * line_width));
1362
1364
1365 GPU_polygon_smooth(false);
1367}
1368
1369void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1370{
1371 const ColorManagedDisplay *display = ui_block_cm_display_get(but->block);
1372 uint pos_id, col_id;
1373
1374 uiButColorBand *but_coba = (uiButColorBand *)but;
1375 ColorBand *coba = (but_coba->edit_coba == nullptr) ? (ColorBand *)but->poin :
1376 but_coba->edit_coba;
1377
1378 if (coba == nullptr) {
1379 return;
1380 }
1381
1382 const float x1 = rect->xmin + U.pixelsize;
1383 const float sizex = rect->xmax - x1 - U.pixelsize;
1384 const float y1 = rect->ymin + U.pixelsize;
1385 const float sizey = rect->ymax - y1 - U.pixelsize;
1386 const float sizey_solid = sizey * 0.25f;
1387
1388 /* exit early if too narrow */
1389 if (sizex <= 0) {
1390 return;
1391 }
1392
1394
1395 /* Line width outline. */
1397 pos_id = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1401 immVertex2f(pos_id, rect->xmin, rect->ymin);
1402 immVertex2f(pos_id, rect->xmax, rect->ymin);
1403 immVertex2f(pos_id, rect->xmin, rect->ymax);
1404 immVertex2f(pos_id, rect->xmax, rect->ymax);
1405 immEnd();
1407
1408 /* Drawing the checkerboard. */
1410 const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f;
1411 const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f;
1412 immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f);
1413 immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f);
1414 immUniform1i("size", 8);
1415 immRectf(pos_id, x1, y1, x1 + sizex, y1 + sizey);
1417
1418 /* New format */
1420 pos_id = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1421 col_id = GPU_vertformat_attr_add(
1422 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
1424
1425 CBData *cbd = coba->data;
1426
1427 float v1[2], v2[2];
1428 float colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
1429
1430 v1[1] = y1 + sizey_solid;
1431 v2[1] = y1 + sizey;
1432
1433 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1434 for (int a = 0; a <= sizex; a++) {
1435 const float pos = float(a) / sizex;
1436 BKE_colorband_evaluate(coba, pos, colf);
1437 if (display) {
1439 }
1440
1441 v1[0] = v2[0] = x1 + a;
1442
1443 immAttr4fv(col_id, colf);
1444 immVertex2fv(pos_id, v1);
1445 immVertex2fv(pos_id, v2);
1446 }
1447 immEnd();
1448
1449 /* layer: color ramp without alpha for reference when manipulating ramp properties */
1450 v1[1] = y1;
1451 v2[1] = y1 + sizey_solid;
1452
1453 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1454 for (int a = 0; a <= sizex; a++) {
1455 const float pos = float(a) / sizex;
1456 BKE_colorband_evaluate(coba, pos, colf);
1457 if (display) {
1459 }
1460
1461 v1[0] = v2[0] = x1 + a;
1462
1463 immAttr4f(col_id, colf[0], colf[1], colf[2], 1.0f);
1464 immVertex2fv(pos_id, v1);
1465 immVertex2fv(pos_id, v2);
1466 }
1467 immEnd();
1468
1470
1471 /* New format */
1473 pos_id = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1474
1475 /* layer: draw handles */
1476 for (int a = 0; a < coba->tot; a++, cbd++) {
1477 if (a != coba->cur) {
1478 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1479 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false);
1480 }
1481 }
1482
1483 /* layer: active handle */
1484 if (coba->tot != 0) {
1485 cbd = &coba->data[coba->cur];
1486 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1487 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true);
1488 }
1489}
1490
1492 const uiWidgetColors *wcol,
1493 const rcti *rect,
1494 const float radius)
1495{
1496 /* sphere color */
1497 const float diffuse[3] = {1.0f, 1.0f, 1.0f};
1498 float light[3];
1499 const float size = 0.5f * min_ff(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
1500
1501 /* backdrop */
1503 rctf box_rect{};
1504 box_rect.xmin = rect->xmin;
1505 box_rect.xmax = rect->xmax;
1506 box_rect.ymin = rect->ymin;
1507 box_rect.ymax = rect->ymax;
1508 UI_draw_roundbox_3ub_alpha(&box_rect, true, radius, wcol->inner, 255);
1509
1511
1512 /* setup lights */
1513 ui_but_v3_get(but, light);
1514
1515 /* transform to button */
1517
1518 const bool use_project_matrix = (size >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
1519 if (use_project_matrix) {
1522 }
1523
1524 GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect),
1525 rect->ymin + 0.5f * BLI_rcti_size_y(rect));
1527
1528 blender::gpu::Batch *sphere = GPU_batch_preset_sphere(2);
1529 SimpleLightingData simple_lighting_data;
1530 copy_v4_fl4(simple_lighting_data.l_color, diffuse[0], diffuse[1], diffuse[2], 1.0f);
1531 copy_v3_v3(simple_lighting_data.light, light);
1533 sizeof(SimpleLightingData), &simple_lighting_data, __func__);
1534
1536 GPU_batch_uniformbuf_bind(sphere, "simple_lighting_data", ubo);
1537 GPU_batch_draw(sphere);
1539
1540 /* Restore. */
1542
1543 /* AA circle */
1546 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1549
1551 GPU_line_smooth(true);
1552 imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
1554 GPU_line_smooth(false);
1555
1556 if (use_project_matrix) {
1558 }
1559
1560 /* matrix after circle */
1562
1564}
1565
1567 const rcti *rect,
1568 const float zoom_x,
1569 const float zoom_y,
1570 const float offset_x,
1571 const float offset_y,
1572 const float step)
1573{
1574 const float start_x = (ceilf(offset_x / step) * step - offset_x) * zoom_x + rect->xmin;
1575 const float start_y = (ceilf(offset_y / step) * step - offset_y) * zoom_y + rect->ymin;
1576
1577 const int line_count_x = ceilf((rect->xmax - start_x) / (step * zoom_x));
1578 const int line_count_y = ceilf((rect->ymax - start_y) / (step * zoom_y));
1579
1580 if (line_count_x + line_count_y == 0) {
1581 return;
1582 }
1583
1584 immBegin(GPU_PRIM_LINES, (line_count_x + line_count_y) * 2);
1585 for (int i = 0; i < line_count_x; i++) {
1586 const float x = start_x + i * step * zoom_x;
1587 immVertex2f(pos, x, rect->ymin);
1588 immVertex2f(pos, x, rect->ymax);
1589 }
1590 for (int i = 0; i < line_count_y; i++) {
1591 const float y = start_y + i * step * zoom_y;
1592 immVertex2f(pos, rect->xmin, y);
1593 immVertex2f(pos, rect->xmax, y);
1594 }
1595 immEnd();
1596}
1597
1598void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1599{
1600 uiButCurveMapping *but_cumap = (uiButCurveMapping *)but;
1601 CurveMapping *cumap = (but_cumap->edit_cumap == nullptr) ? (CurveMapping *)but->poin :
1602 but_cumap->edit_cumap;
1603
1604 const bool inactive = but->flag & UI_BUT_INACTIVE;
1605 const float fade_factor_float = inactive ? 0.33f : 1.0f;
1606 const uchar fade_factor_uchar = inactive ? 3 : 1;
1607
1608 const float clip_size_x = BLI_rctf_size_x(&cumap->curr);
1609 const float clip_size_y = BLI_rctf_size_y(&cumap->curr);
1610
1611 /* zero-sized curve */
1612 if (clip_size_x == 0.0f || clip_size_y == 0.0f) {
1613 return;
1614 }
1615
1616 /* calculate offset and zoom */
1617 const float zoomx = (BLI_rcti_size_x(rect) - 1.0f) / clip_size_x;
1618 const float zoomy = (BLI_rcti_size_y(rect) - 1.0f) / clip_size_y;
1619 const float offsx = cumap->curr.xmin - (1.0f / zoomx);
1620 const float offsy = cumap->curr.ymin - (1.0f / zoomy);
1621
1622 /* exit early if too narrow */
1623 if (zoomx <= 0.0f) {
1624 return;
1625 }
1626
1627 CurveMap *cuma = &cumap->cm[cumap->cur];
1628
1629 /* need scissor test, curve can draw outside of boundary */
1630 int scissor[4];
1631 GPU_scissor_get(scissor);
1632 rcti scissor_new{};
1633 scissor_new.xmin = rect->xmin;
1634 scissor_new.ymin = rect->ymin;
1635 scissor_new.xmax = rect->xmax;
1636 scissor_new.ymax = rect->ymax;
1637 const rcti scissor_region = {0, region->winx, 0, region->winy};
1638 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1639 GPU_scissor(scissor_new.xmin,
1640 scissor_new.ymin,
1641 BLI_rcti_size_x(&scissor_new),
1642 BLI_rcti_size_y(&scissor_new));
1643
1644 /* Do this first to not mess imm context */
1645 if (but_cumap->gradient_type == UI_GRAD_H) {
1646 /* magic trigger for curve backgrounds */
1647 const float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
1648
1649 rcti grid{};
1650 grid.xmin = rect->xmin + zoomx * (-offsx);
1651 grid.xmax = grid.xmin + zoomx;
1652 grid.ymin = rect->ymin + zoomy * (-offsy);
1653 grid.ymax = grid.ymin + zoomy;
1654
1655 const ColorManagedDisplay *display = ui_block_cm_display_get(but->block);
1656 ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f, display);
1657 }
1658
1659 GPU_line_width(1.0f);
1660
1662 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1664
1665 /* backdrop */
1666 float color_backdrop[4] = {0, 0, 0, 1};
1667
1669 if (but_cumap->gradient_type == UI_GRAD_H) {
1670 /* grid, hsv uses different grid */
1671 ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
1672 immUniformColor4fv(color_backdrop);
1673 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
1674 }
1675 else {
1676 /* Draw backdrop. */
1677 immUniformColor3ubvAlpha(wcol->inner, (wcol->inner[3] / fade_factor_uchar));
1678 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1679
1680 /* Draw an outline around the clipped limits. */
1681 if (cumap->flag & CUMA_DO_CLIP) {
1683 pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1684
1685 immUniformColor3ubvAlpha(wcol->item, (wcol->item[3] / fade_factor_uchar));
1686 GPU_line_width(2.0f);
1688 rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
1689 rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
1690 rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
1691 rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
1692 GPU_line_width(1.0f);
1693 }
1694
1695 /* grid, every 0.25 step */
1696 immUniformColor3ubvAlpha(wcol->outline_sel, 64 / fade_factor_uchar);
1697 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
1698 /* grid, every 1.0 step */
1699 immUniformColor3ubvAlpha(wcol->outline_sel, 92 / fade_factor_uchar);
1700 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
1701 /* axes */
1702 uchar col_axis_x[3], col_axis_y[3];
1703 UI_GetThemeColor3ubv(TH_AXIS_X, col_axis_x);
1704 UI_GetThemeColor3ubv(TH_AXIS_Y, col_axis_y);
1705
1707 immUniformColor3ubvAlpha(col_axis_x, 128 / fade_factor_uchar);
1708 immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
1709 immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
1710 immEnd();
1711
1713 immUniformColor3ubvAlpha(col_axis_y, 128 / fade_factor_uchar);
1714 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
1715 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
1716 immEnd();
1717 }
1719
1720 /* cfra option */
1721 /* XXX 2.48 */
1722#if 0
1723 if (cumap->flag & CUMA_DRAW_CFRA) {
1724 immUniformColor3ub(0x60, 0xc0, 0x40);
1726 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
1727 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
1728 immEnd();
1729 }
1730#endif
1731 /* sample option */
1732
1733 if (cumap->flag & CUMA_DRAW_SAMPLE) {
1734 immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
1735 if (but_cumap->gradient_type == UI_GRAD_H) {
1736 float tsample[3];
1737 float hsv[3];
1738 linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
1739 rgb_to_hsv_v(tsample, hsv);
1740 immUniformColor3ub(240, 240, 240);
1741
1742 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
1743 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
1744 }
1745 else if (cumap->cur == 3) {
1746 const float lum = IMB_colormanagement_get_luminance(cumap->sample);
1747 immUniformColor3ub(240, 240, 240);
1748
1749 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
1750 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
1751 }
1752 else {
1753 if (cumap->cur == 0) {
1754 immUniformColor3ub(240, 100, 100);
1755 }
1756 else if (cumap->cur == 1) {
1757 immUniformColor3ub(100, 240, 100);
1758 }
1759 else {
1760 immUniformColor3ub(100, 100, 240);
1761 }
1762
1763 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
1764 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
1765 }
1766 immEnd();
1767 }
1769
1770 if (cuma->table == nullptr) {
1771 BKE_curvemapping_changed(cumap, false);
1772 }
1773
1774 CurveMapPoint *cmp = cuma->table;
1775 rctf line_range;
1776
1777 /* First curve point. */
1778 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1779 line_range.xmin = rect->xmin;
1780 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
1781 }
1782 else {
1783 line_range.xmin = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
1784 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
1785 }
1786 /* Last curve point. */
1787 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1788 line_range.xmax = rect->xmax;
1789 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
1790 }
1791 else {
1792 line_range.xmax = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
1793 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
1794 }
1795
1798
1799 /* Curve filled. */
1800 immUniformColor3ubvAlpha(wcol->item, wcol->item[3] / fade_factor_uchar);
1801 immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4);
1802 immVertex2f(pos, line_range.xmin, rect->ymin);
1803 immVertex2f(pos, line_range.xmin, line_range.ymin);
1804 for (int a = 0; a <= CM_TABLE; a++) {
1805 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1806 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1807 immVertex2f(pos, fx, rect->ymin);
1808 immVertex2f(pos, fx, fy);
1809 }
1810 immVertex2f(pos, line_range.xmax, rect->ymin);
1811 immVertex2f(pos, line_range.xmax, line_range.ymax);
1812 immEnd();
1813
1814 /* Curve line. */
1815 GPU_line_width(1.0f);
1816 immUniformColor3ubvAlpha(wcol->inner_sel, wcol->inner_sel[3] / fade_factor_uchar);
1817 GPU_line_smooth(true);
1819 immVertex2f(pos, line_range.xmin, line_range.ymin);
1820 for (int a = 0; a <= CM_TABLE; a++) {
1821 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1822 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1823 immVertex2f(pos, fx, fy);
1824 }
1825 immVertex2f(pos, line_range.xmax, line_range.ymax);
1826 immEnd();
1827
1828 /* Reset state for fill & line. */
1829 GPU_line_smooth(false);
1832
1833 /* The points, use aspect to make them visible on edges. */
1835 pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1837
1839
1840 float color_point[4], color_point_select[4], color_point_outline[4];
1841 rgba_uchar_to_float(color_point, wcol->text);
1842 rgba_uchar_to_float(color_point_select, wcol->text_sel);
1843 rgba_uchar_to_float(color_point_outline, wcol->inner_sel);
1844 color_point[3] = fade_factor_float;
1845 color_point_select[3] = fade_factor_float;
1846 color_point_outline[3] *= fade_factor_float;
1847
1848 cmp = cuma->curve;
1849 const float point_size = max_ff(U.pixelsize * 2.0f,
1850 min_ff(UI_SCALE_FAC / but->block->aspect * 6.0f, 20.0f));
1851
1852 int selected = 0;
1853 /* Find the total number of selected points. */
1854 for (int i = 0; i < cuma->totpoint; i++) {
1855 if (cmp[i].flag & CUMA_SELECT) {
1856 selected++;
1857 }
1858 }
1859
1860 /* Curve widgets using a gradient background (such as Hue Correct), draw
1861 * an additional point in the back, forming an outline so they stand out. */
1862 if (but_cumap->gradient_type == UI_GRAD_H) {
1863 if ((cuma->totpoint - selected) > 0) {
1864 /* Background (outline) for unselected points. */
1865 immUniform4fv("color", color_point_outline);
1866 immUniform1f("size", point_size * 1.4f);
1867 immBegin(GPU_PRIM_POINTS, cuma->totpoint - selected);
1868 for (int a = 0; a < cuma->totpoint; a++) {
1869 if (cmp[a].flag & CUMA_SELECT) {
1870 continue;
1871 }
1872 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1873 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1874 immVertex2f(pos, fx, fy);
1875 }
1876 immEnd();
1877 }
1878 if (selected > 0) {
1879 /* Background (outline) for selected points. */
1880 immUniform1f("size", point_size * 1.8f);
1881 immBegin(GPU_PRIM_POINTS, selected);
1882 for (int a = 0; a < cuma->totpoint; a++) {
1883 if (!(cmp[a].flag & CUMA_SELECT)) {
1884 continue;
1885 }
1886 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1887 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1888 immVertex2f(pos, fx, fy);
1889 }
1890 immEnd();
1891 }
1892 }
1893
1894 if ((cuma->totpoint - selected) > 0) {
1895 /* Unselected points. */
1896 immUniform1f("size", point_size);
1897 immUniform4fv("color", color_point);
1898 immBegin(GPU_PRIM_POINTS, cuma->totpoint - selected);
1899 for (int a = 0; a < cuma->totpoint; a++) {
1900 if (cmp[a].flag & CUMA_SELECT) {
1901 continue;
1902 }
1903 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1904 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1905 immVertex2f(pos, fx, fy);
1906 }
1907 immEnd();
1908 }
1909
1910 if (selected > 0) {
1911 /* Selected points. */
1912 immUniform1f("size", point_size * 1.2f);
1913 immUniform4fv("color", color_point_select);
1914 immBegin(GPU_PRIM_POINTS, selected);
1915 for (int a = 0; a < cuma->totpoint; a++) {
1916 if (!(cmp[a].flag & CUMA_SELECT)) {
1917 continue;
1918 }
1919 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1920 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1921 immVertex2f(pos, fx, fy);
1922 }
1923 immEnd();
1924 }
1925
1928
1929 /* Restore scissor-test. */
1930 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
1931
1932 /* outline */
1934 pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1936
1938 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1939
1941}
1942
1947{
1948 return (point->flag & PROF_SELECT &&
1949 (ELEM(point->h1, HD_FREE, HD_ALIGN) || ELEM(point->h2, HD_FREE, HD_ALIGN))) ||
1951}
1952
1954 uiBut *but,
1955 const uiWidgetColors *wcol,
1956 const rcti *rect)
1957{
1958 float fx, fy;
1959
1960 uiButCurveProfile *but_profile = (uiButCurveProfile *)but;
1961 CurveProfile *profile = (but_profile->edit_profile == nullptr) ? (CurveProfile *)but->poin :
1962 but_profile->edit_profile;
1963
1964 /* Calculate offset and zoom. */
1965 const float zoomx = (BLI_rcti_size_x(rect) - 1.0f) / BLI_rctf_size_x(&profile->view_rect);
1966 const float zoomy = (BLI_rcti_size_y(rect) - 1.0f) / BLI_rctf_size_y(&profile->view_rect);
1967 const float offsx = profile->view_rect.xmin - (1.0f / zoomx);
1968 const float offsy = profile->view_rect.ymin - (1.0f / zoomy);
1969
1970 /* Exit early if too narrow. */
1971 if (zoomx <= 0.0f) {
1972 return;
1973 }
1974
1975 /* Test needed because path can draw outside of boundary. */
1976 int scissor[4];
1977 GPU_scissor_get(scissor);
1978 rcti scissor_new{};
1979 scissor_new.xmin = rect->xmin;
1980 scissor_new.ymin = rect->ymin;
1981 scissor_new.xmax = rect->xmax;
1982 scissor_new.ymax = rect->ymax;
1983
1984 const rcti scissor_region = {0, region->winx, 0, region->winy};
1985 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1986 GPU_scissor(scissor_new.xmin,
1987 scissor_new.ymin,
1988 BLI_rcti_size_x(&scissor_new),
1989 BLI_rcti_size_y(&scissor_new));
1990
1991 GPU_line_width(1.0f);
1992
1994 uint pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
1996
1997 /* Draw the backdrop. */
1999 /* Main backdrop. */
2001 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
2002
2003 if (!(profile->flag & PROF_USE_CLIP)) {
2005 immRectf(pos,
2006 rect->xmin + zoomx * (profile->clip_rect.xmin - offsx),
2007 rect->ymin + zoomy * (profile->clip_rect.ymin - offsy),
2008 rect->xmin + zoomx * (profile->clip_rect.xmax - offsx),
2009 rect->ymin + zoomy * (profile->clip_rect.ymax - offsy));
2010 }
2011
2012 /* 0.25 step grid. */
2014 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
2015 /* 1.0 step grid. */
2017 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
2019
2020 /* Draw the path's fill. */
2021 if (profile->table == nullptr) {
2023 }
2024 CurveProfilePoint *pts = profile->table;
2025 /* Also add the last points on the right and bottom edges to close off the fill polygon. */
2026 const bool add_left_tri = profile->view_rect.xmin < 0.0f;
2027 const bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
2028 int tot_points = BKE_curveprofile_table_size(profile) + 1 + add_left_tri + add_bottom_tri;
2029 const uint tot_triangles = tot_points - 2;
2030
2031 /* Create array of the positions of the table's points. */
2032 float (*table_coords)[2] = static_cast<float (*)[2]>(
2033 MEM_mallocN(sizeof(*table_coords) * tot_points, __func__));
2034 for (uint i = 0; i < uint(BKE_curveprofile_table_size(profile)); i++) {
2035 /* Only add the points from the table here. */
2036 table_coords[i][0] = pts[i].x;
2037 table_coords[i][1] = pts[i].y;
2038 }
2039 /* Using some extra margin (-1.0f) for the coordinates used to complete the polygon
2040 * avoids the profile line crossing itself in some common situations, which can lead to
2041 * incorrect triangulation. See #841183. */
2042 if (add_left_tri && add_bottom_tri) {
2043 /* Add left side, bottom left corner, and bottom side points. */
2044 table_coords[tot_points - 3][0] = profile->view_rect.xmin - 1.0f;
2045 table_coords[tot_points - 3][1] = 1.0f;
2046 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
2047 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
2048 table_coords[tot_points - 1][0] = 1.0f;
2049 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
2050 }
2051 else if (add_left_tri) {
2052 /* Add the left side and bottom left corner points. */
2053 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
2054 table_coords[tot_points - 2][1] = 1.0f;
2055 table_coords[tot_points - 1][0] = profile->view_rect.xmin - 1.0f;
2056 table_coords[tot_points - 1][1] = -1.0f;
2057 }
2058 else if (add_bottom_tri) {
2059 /* Add the bottom side and bottom left corner points. */
2060 table_coords[tot_points - 2][0] = -1.0f;
2061 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
2062 table_coords[tot_points - 1][0] = 1.0f;
2063 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
2064 }
2065 else {
2066 /* Just add the bottom corner point. Side points would be redundant anyway. */
2067 table_coords[tot_points - 1][0] = -1.0f;
2068 table_coords[tot_points - 1][1] = -1.0f;
2069 }
2070
2071 /* Calculate the table point indices of the triangles for the profile's fill. */
2072 if (tot_triangles > 0) {
2073 uint(*tri_indices)[3] = static_cast<uint(*)[3]>(
2074 MEM_mallocN(sizeof(*tri_indices) * tot_triangles, __func__));
2075 BLI_polyfill_calc(table_coords, tot_points, -1, tri_indices);
2076
2077 /* Draw the triangles for the profile fill. */
2080 GPU_polygon_smooth(false);
2081 immBegin(GPU_PRIM_TRIS, 3 * tot_triangles);
2082 for (uint i = 0; i < tot_triangles; i++) {
2083 const uint *tri = tri_indices[i];
2084 for (uint j = 0; j < 3; j++) {
2085 fx = rect->xmin + zoomx * (table_coords[tri[j]][0] - offsx);
2086 fy = rect->ymin + zoomy * (table_coords[tri[j]][1] - offsy);
2087 immVertex2f(pos, fx, fy);
2088 }
2089 }
2090 immEnd();
2091 MEM_freeN(tri_indices);
2092 }
2093
2094 /* Draw the profile's path so the edge stands out a bit. */
2095 tot_points -= (add_left_tri + add_left_tri);
2096 const int edges_len = tot_points - 1;
2097 if (edges_len > 0) {
2098 GPU_line_width(1.0f);
2100 GPU_line_smooth(true);
2101 immBegin(GPU_PRIM_LINE_STRIP, tot_points);
2102 for (int i = 0; i < tot_points; i++) {
2103 fx = rect->xmin + zoomx * (table_coords[i][0] - offsx);
2104 fy = rect->ymin + zoomy * (table_coords[i][1] - offsy);
2105 immVertex2f(pos, fx, fy);
2106 }
2107 immEnd();
2108 }
2109
2110 MEM_SAFE_FREE(table_coords);
2111
2112 /* Draw the handles for the selected control points. */
2113 pts = profile->path;
2114 const int path_len = tot_points = uint(profile->path_len);
2115 int selected_free_points = 0;
2116 for (int i = 0; i < path_len; i++) {
2117 if (point_draw_handles(&pts[i])) {
2118 selected_free_points++;
2119 }
2120 }
2121 /* Draw the lines to the handles from the points. */
2122 if (selected_free_points > 0) {
2123 GPU_line_width(1.0f);
2125 GPU_line_smooth(true);
2126 immBegin(GPU_PRIM_LINES, selected_free_points * 4);
2127 float ptx, pty;
2128 for (int i = 0; i < path_len; i++) {
2129 if (point_draw_handles(&pts[i])) {
2130 ptx = rect->xmin + zoomx * (pts[i].x - offsx);
2131 pty = rect->ymin + zoomy * (pts[i].y - offsy);
2132
2133 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2134 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2135 immVertex2f(pos, ptx, pty);
2136 immVertex2f(pos, fx, fy);
2137
2138 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2139 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2140 immVertex2f(pos, ptx, pty);
2141 immVertex2f(pos, fx, fy);
2142 }
2143 }
2144 immEnd();
2145 }
2147
2148 /* New GPU instructions for control points and sampled points. */
2150 pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
2152
2154
2155 float color_point[4], color_point_select[4], color_sample[4];
2156 rgba_uchar_to_float(color_point, wcol->text);
2157 color_point[3] = 1.0f;
2158 rgba_uchar_to_float(color_point_select, wcol->text_sel);
2159 color_point_select[3] = 1.0f;
2160 color_sample[0] = float(wcol->item[0]) / 255.0f;
2161 color_sample[1] = float(wcol->item[1]) / 255.0f;
2162 color_sample[2] = float(wcol->item[2]) / 255.0f;
2163 color_sample[3] = float(wcol->item[3]) / 255.0f;
2164
2165 int selected = 0;
2166 for (int i = 0; i < path_len; i++) {
2167 if (pts[i].flag & PROF_SELECT) {
2168 selected++;
2169 }
2170 }
2171
2172 /* Draw the control points. */
2173 GPU_line_smooth(false);
2175 const float point_size = max_ff(U.pixelsize * 2.0f,
2176 min_ff(UI_SCALE_FAC / but->block->aspect * 6.0f, 20.0f));
2177
2178 if ((path_len - selected) > 0) {
2179 /* Unselected control points. */
2180 immUniform4fv("color", color_point);
2181 immUniform1f("size", point_size);
2182 immBegin(GPU_PRIM_POINTS, path_len - selected);
2183 for (int i = 0; i < path_len; i++) {
2184 if (pts[i].flag & PROF_SELECT) {
2185 continue;
2186 }
2187 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2188 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2189 immVertex2f(pos, fx, fy);
2190 }
2191 immEnd();
2192 }
2193 if (selected > 0) {
2194 /* Selected control points. */
2195 immUniform4fv("color", color_point_select);
2196 immUniform1f("size", point_size * 1.2f);
2197 immBegin(GPU_PRIM_POINTS, selected);
2198 for (int i = 0; i < path_len; i++) {
2199 if (!(pts[i].flag & PROF_SELECT)) {
2200 continue;
2201 }
2202 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2203 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2204 immVertex2f(pos, fx, fy);
2205 }
2206 immEnd();
2207 }
2208
2209 /* Find the total number of selected handles. */
2210 selected = 0;
2211 for (int i = 0; i < path_len; i++) {
2212 if (point_draw_handles(&pts[i])) {
2213 if (pts[i].flag & PROF_H1_SELECT) {
2214 selected++;
2215 }
2216 if (pts[i].flag & PROF_H2_SELECT) {
2217 selected++;
2218 }
2219 }
2220 }
2221
2222 if (((selected_free_points * 2) - selected) > 0) {
2223 /* Unselected handles. */
2224 immUniform4fv("color", color_point);
2225 immUniform1f("size", point_size);
2226 immBegin(GPU_PRIM_POINTS, (selected_free_points * 2) - selected);
2227 for (int i = 0; i < path_len; i++) {
2228 if (point_draw_handles(&pts[i])) {
2229 if (!(pts[i].flag & PROF_H1_SELECT)) {
2230 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2231 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2232 immVertex2f(pos, fx, fy);
2233 }
2234 if (!(pts[i].flag & PROF_H2_SELECT)) {
2235 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2236 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2237 immVertex2f(pos, fx, fy);
2238 }
2239 }
2240 }
2241 immEnd();
2242 }
2243
2244 if (selected > 0) {
2245 /* Selected Handles. */
2246 immUniform4fv("color", color_point_select);
2247 immUniform1f("size", point_size * 1.2f);
2248 immBegin(GPU_PRIM_POINTS, selected);
2249 for (int i = 0; i < path_len; i++) {
2250 if (point_draw_handles(&pts[i])) {
2251 if (pts[i].flag & PROF_H1_SELECT) {
2252 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2253 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2254 immVertex2f(pos, fx, fy);
2255 }
2256 if (pts[i].flag & PROF_H2_SELECT) {
2257 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2258 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2259 immVertex2f(pos, fx, fy);
2260 }
2261 }
2262 }
2263 immEnd();
2264 }
2265
2266 /* Draw the sampled points in addition to the control points if they have been created */
2267 pts = profile->segments;
2268 const int segments_len = uint(profile->segments_len);
2269 if (segments_len > 0 && pts) {
2270 immUniform4fv("color", color_sample);
2271 immUniform1f("size", point_size);
2272 immBegin(GPU_PRIM_POINTS, segments_len);
2273 for (int i = 0; i < segments_len; i++) {
2274 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2275 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2276 immVertex2f(pos, fx, fy);
2277 }
2278 immEnd();
2279 }
2281
2282 /* Restore scissor-test. */
2283 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
2284
2285 /* Outline */
2287 pos = GPU_vertformat_attr_add(format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
2289
2290 immUniformColor3ubv((const uchar *)wcol->outline);
2291 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
2294}
2295
2297 uiBut *but,
2298 const uiWidgetColors * /*wcol*/,
2299 const rcti *recti)
2300{
2301 bool ok = false;
2302 MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
2303
2304 rctf rect{};
2305 rect.xmin = float(recti->xmin + 1);
2306 rect.xmax = float(recti->xmax - 1);
2307 rect.ymin = float(recti->ymin + 1);
2308 rect.ymax = float(recti->ymax - 1);
2309
2310 const int width = BLI_rctf_size_x(&rect) + 1;
2311 const int height = BLI_rctf_size_y(&rect);
2312
2314
2315 /* need scissor test, preview image can draw outside of boundary */
2316 int scissor[4];
2317 GPU_scissor_get(scissor);
2318 rcti scissor_new{};
2319 scissor_new.xmin = rect.xmin;
2320 scissor_new.ymin = rect.ymin;
2321 scissor_new.xmax = rect.xmax;
2322 scissor_new.ymax = rect.ymax;
2323 const rcti scissor_region = {0, region->winx, 0, region->winy};
2324 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
2325 GPU_scissor(scissor_new.xmin,
2326 scissor_new.ymin,
2327 BLI_rcti_size_x(&scissor_new),
2328 BLI_rcti_size_y(&scissor_new));
2329
2330 if (scopes->track_disabled) {
2331 const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
2333 rctf disabled_rect{};
2334 disabled_rect.xmin = rect.xmin - 1;
2335 disabled_rect.xmax = rect.xmax + 1;
2336 disabled_rect.ymin = rect.ymin;
2337 disabled_rect.ymax = rect.ymax + 1;
2338 UI_draw_roundbox_4fv(&disabled_rect, true, 3.0f, color);
2339
2340 ok = true;
2341 }
2342 else if ((scopes->track_search) &&
2343 ((!scopes->track_preview) ||
2344 (scopes->track_preview->x != width || scopes->track_preview->y != height)))
2345 {
2346 if (scopes->track_preview) {
2348 }
2349
2351 scopes->frame_height,
2352 scopes->track_search,
2353 scopes->track,
2354 &scopes->undist_marker,
2355 true,
2356 scopes->use_track_mask,
2357 width,
2358 height,
2359 scopes->track_pos);
2360 if (tmpibuf) {
2361 if (tmpibuf->float_buffer.data) {
2362 IMB_byte_from_float(tmpibuf);
2363 }
2364
2365 if (tmpibuf->byte_buffer.data) {
2366 scopes->track_preview = tmpibuf;
2367 }
2368 else {
2369 IMB_freeImBuf(tmpibuf);
2370 }
2371 }
2372 }
2373
2374 if (!ok && scopes->track_preview) {
2376
2377 /* draw content of pattern area */
2378 GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
2379
2380 if (width > 0 && height > 0) {
2381 const ImBuf *drawibuf = scopes->track_preview;
2382 float col_sel[4], col_outline[4];
2383
2384 if (scopes->use_track_mask) {
2385 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2387 rctf mask_rect{};
2388 mask_rect.xmin = rect.xmin - 1;
2389 mask_rect.xmax = rect.xmax + 1;
2390 mask_rect.ymin = rect.ymin;
2391 mask_rect.ymax = rect.ymax + 1;
2392 UI_draw_roundbox_4fv(&mask_rect, true, 3.0f, color);
2393 }
2394
2397 rect.xmin,
2398 rect.ymin + 1,
2399 drawibuf->x,
2400 drawibuf->y,
2401 blender::gpu::TextureFormat::UNORM_8_8_8_8,
2402 true,
2403 drawibuf->byte_buffer.data,
2404 1.0f,
2405 1.0f,
2406 nullptr);
2407
2408 /* draw cross for pixel position */
2409 GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
2410 GPU_scissor(rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect));
2411
2414 format, "pos", blender::gpu::VertAttrType::SFLOAT_32_32);
2416 format, "color", blender::gpu::VertAttrType::SFLOAT_32_32_32_32);
2418
2421
2422 /* Do stipple cross with geometry */
2423 immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
2424 const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
2425 for (int axe = 0; axe < 2; axe++) {
2426 for (int i = 0; i < 7; i++) {
2427 const float x1 = pos_sel[i] * (1 - axe);
2428 const float y1 = pos_sel[i] * axe;
2429 const float x2 = pos_sel[i + 1] * (1 - axe);
2430 const float y2 = pos_sel[i + 1] * axe;
2431
2432 if (i % 2 == 1) {
2433 immAttr4fv(col, col_sel);
2434 }
2435 else {
2436 immAttr4fv(col, col_outline);
2437 }
2438
2439 immVertex2f(pos, x1, y1);
2440 immVertex2f(pos, x2, y2);
2441 }
2442 }
2443 immEnd();
2444
2446 }
2447
2449
2450 ok = true;
2451 }
2452
2453 if (!ok) {
2454 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2456 rctf box_rect{};
2457 box_rect.xmin = rect.xmin - 1;
2458 box_rect.xmax = rect.xmax + 1;
2459 box_rect.ymin = rect.ymin;
2460 box_rect.ymax = rect.ymax + 1;
2461 UI_draw_roundbox_4fv(&box_rect, true, 3.0f, color);
2462 }
2463
2464 /* Restore scissor test. */
2465 GPU_scissor(UNPACK4(scissor));
2466 /* outline */
2467 draw_scope_end(&rect);
2468
2470}
2471
2472/* ****************************************************** */
2473
2475 const rctf *rct, const float radius, const float width, const float aspect, const float alpha)
2476{
2477 if (width == 0.0f) {
2478 return;
2479 }
2480
2481 /* This undoes the scale of the view for higher zoom factors to clamp the shadow size. */
2482 const float clamped_aspect = smoothminf(aspect, 1.0f, 0.5f);
2483 const float shadow_width = width * clamped_aspect;
2484 const float shadow_offset = min_ff(shadow_width, BLI_rctf_size_y(rct) - 2.0f * radius);
2485
2486 const float inner_radius = max_ff(radius - U.pixelsize, 0.0);
2487 const float shadow_radius = radius + shadow_width - U.pixelsize;
2488
2490
2491 uiWidgetBaseParameters widget_params{};
2492 widget_params.recti.xmin = rct->xmin;
2493 widget_params.recti.ymin = rct->ymin;
2494 widget_params.recti.xmax = rct->xmax;
2495 widget_params.recti.ymax = rct->ymax;
2496 widget_params.rect.xmin = rct->xmin - shadow_width;
2497 widget_params.rect.ymin = rct->ymin - shadow_width;
2498 widget_params.rect.xmax = rct->xmax + shadow_width;
2499 widget_params.rect.ymax = rct->ymax + shadow_width - shadow_offset;
2500 widget_params.radi = inner_radius;
2501 widget_params.rad = shadow_radius;
2502 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
2503 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
2504 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
2505 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
2506 widget_params.alpha_discard = 1.0f;
2507
2508 blender::gpu::Batch *batch = ui_batch_roundbox_shadow_get();
2510 GPU_batch_uniform_4fv_array(batch, "parameters", 4, (const float (*)[4]) & widget_params);
2511 GPU_batch_uniform_1f(batch, "alpha", alpha);
2513
2515}
void immDrawPixelsTexTiled(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, blender::gpu::TextureFormat gpu_format, bool use_filter, const void *rect, float xzoom, float yzoom, const float color[4])
Definition glutil.cc:342
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
Definition glutil.cc:37
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
void BKE_curvemapping_changed(CurveMapping *cumap, bool rem_doubles)
void BKE_curveprofile_update(struct CurveProfile *profile, int update_flags)
@ PROF_UPDATE_NONE
int BKE_curveprofile_table_size(const struct CurveProfile *profile)
struct ImBuf * BKE_tracking_sample_pattern(int frame_width, int frame_height, const struct ImBuf *search_ib, const struct MovieTrackingTrack *track, const struct MovieTrackingMarker *marker, bool from_anchor, bool use_mask, int num_samples_x, int num_samples_y, float pos[2])
int BLF_default()
void BLF_batch_draw_flush()
Definition blf.cc:540
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:514
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
#define BLI_YUV_ITU_BT709
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
MINLINE void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition math_color.cc:67
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
Definition math_color.cc:91
#define DEG2RADF(_deg)
#define M_PI_2
#define M_PI
void unit_m3(float m[3][3])
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define SNPRINTF_UTF8(dst, format,...)
unsigned char uchar
unsigned int uint
#define CLAMP(a, b, c)
#define UNPACK4(a)
#define ARRAY_SIZE(arr)
#define ARRAY_SET_ITEMS(...)
#define UNPACK3(a)
#define ELEM(...)
@ CUMA_EXTEND_EXTRAPOLATE
@ CUMA_DO_CLIP
@ CUMA_DRAW_CFRA
@ CUMA_DRAW_SAMPLE
@ HISTO_MODE_B
@ HISTO_MODE_G
@ HISTO_MODE_LUMA
@ HISTO_MODE_RGB
@ HISTO_MODE_ALPHA
@ HISTO_MODE_R
@ HISTO_FLAG_LINE
@ SCOPES_VECSCOPE_LUMA
@ SCOPES_VECSCOPE_RGB
@ CUMA_SELECT
@ SCOPES_WAVEFRM_YCC_JPEG
@ SCOPES_WAVEFRM_RGB
@ SCOPES_WAVEFRM_YCC_601
@ SCOPES_WAVEFRM_YCC_709
@ SCOPES_WAVEFRM_LUMA
@ SCOPES_WAVEFRM_RGB_PARADE
#define SCOPES_VEC_U_SCALE
#define SCOPES_VEC_V_SCALE
#define CM_TABLE
@ HD_FREE
@ HD_ALIGN
#define UI_SCALE_FAC
#define GPU_batch_uniform_1f(batch, name, x)
Definition GPU_batch.hh:271
void GPU_batch_discard(blender::gpu::Batch *batch)
#define GPU_batch_uniformbuf_bind(batch, name, ubo)
Definition GPU_batch.hh:286
void GPU_batch_program_set_builtin(blender::gpu::Batch *batch, GPUBuiltinShader shader_id)
#define GPU_batch_uniform_4fv_array(batch, name, len, val)
Definition GPU_batch.hh:282
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, GPUBatchFlag owns_flag)
Definition gpu_batch.cc:51
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:42
void GPU_batch_draw(blender::gpu::Batch *batch)
#define GPU_batch_uniform_4f(batch, name, x, y, z, w)
Definition GPU_batch.hh:275
blender::gpu::Batch * GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT
void immUniformColor4ubv(const unsigned char rgba[4])
void immUniform4f(const char *name, float x, float y, float z, float w)
void immEnd()
void immUnbindProgram()
void immAttr4fv(uint attr_id, const float data[4])
void immBindBuiltinProgram(GPUBuiltinShader shader_id)
void immAttr4ub(uint attr_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
void immUniform2f(const char *name, float x, float y)
void immUniformColor4f(float r, float g, float b, float a)
void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
void immVertex2f(uint attr_id, float x, float y)
void immVertex2fv(uint attr_id, const float data[2])
void immUniformColor3ubv(const unsigned char rgb[3])
void immUniform1i(const char *name, int x)
void immBeginAtMost(GPUPrimType, uint max_vertex_len)
void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a)
void immUniform1f(const char *name, float x)
void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
GPUVertFormat * immVertexFormat()
void immAttr4f(uint attr_id, float x, float y, float z, float w)
void immUniformColor4fv(const float rgba[4])
void immUniformColor3f(float r, float g, float b)
void immUniform4fv(const char *name, const float data[4])
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
bool immIsShaderBound()
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
void GPU_matrix_scale_2f(float x, float y)
void GPU_matrix_ortho_set_z(float near, float far)
void GPU_matrix_push()
void GPU_matrix_push_projection()
void GPU_matrix_scale_1f(float factor)
void GPU_matrix_pop_projection()
void GPU_matrix_pop()
static constexpr int GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT
void GPU_matrix_translate_2f(float x, float y)
GPUPrimType
@ GPU_PRIM_TRI_FAN
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRI_STRIP
@ GPU_PRIM_TRIS
@ GPU_SHADER_3D_SMOOTH_COLOR
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
@ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA
@ GPU_SHADER_3D_POINT_FLAT_COLOR
@ GPU_SHADER_2D_CHECKER
@ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
@ GPU_SHADER_SIMPLE_LIGHTING
@ GPU_SHADER_2D_WIDGET_SHADOW
@ GPU_SHADER_2D_WIDGET_BASE
@ GPU_SHADER_3D_IMAGE_COLOR
void GPU_program_point_size(bool enable)
Definition gpu_state.cc:180
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_ADDITIVE
Definition GPU_state.hh:89
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
void GPU_face_culling(GPUFaceCullTest culling)
Definition gpu_state.cc:47
void GPU_blend(GPUBlend blend)
Definition gpu_state.cc:42
void GPU_scissor(int x, int y, int width, int height)
Definition gpu_state.cc:193
void GPU_point_size(float size)
Definition gpu_state.cc:172
@ GPU_CULL_NONE
Definition GPU_state.hh:136
@ GPU_CULL_BACK
Definition GPU_state.hh:138
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:273
void GPU_scissor_get(int coords[4])
Definition gpu_state.cc:268
void GPU_polygon_smooth(bool enable)
Definition gpu_state.cc:83
void GPU_uniformbuf_free(blender::gpu::UniformBuf *ubo)
blender::gpu::UniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_vertbuf_use(blender::gpu::VertBuf *)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &format)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
uint GPU_vertformat_attr_add(GPUVertFormat *format, blender::StringRef name, blender::gpu::VertAttrType type)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3])
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], const ColorManagedDisplay *display, const ColorManagedDisplaySpace display_space=DISPLAY_SPACE_DRAW)
void IMB_byte_from_float(ImBuf *ibuf)
void IMB_freeImBuf(ImBuf *ibuf)
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Definition scaling.cc:465
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define UI_ALPHA_CHECKER_LIGHT
@ UI_BUT_INACTIVE
#define UI_ALPHA_CHECKER_DARK
@ UI_CNR_BOTTOM_LEFT
@ UI_CNR_BOTTOM_RIGHT
@ UI_CNR_ALL
@ UI_CNR_TOP_LEFT
@ UI_CNR_TOP_RIGHT
@ UI_GRAD_H
blender::ocio::Display ColorManagedDisplay
@ TH_MARKER_OUTLINE
@ TH_PREVIEW_BACK
@ TH_AXIS_Y
@ TH_AXIS_X
@ TH_SEL_MARKER
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
void UI_GetThemeColor4fv(int colorid, float col[4])
#define U
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
MutableSpan< T > data()
nullptr float
#define str(s)
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
uint pos
uint col
#define active
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
const ColorManagedDisplay * ui_block_cm_display_get(uiBlock *block)
void ui_but_v3_get(uiBut *but, float vec[3])
#define HISTOGRAM_TOT_GRID_LINES
void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
void ui_draw_but_IMAGE(ARegion *, uiBut *but, const uiWidgetColors *, const rcti *rect)
void ui_draw_dropshadow(const rctf *rct, const float radius, const float width, const float aspect, const float alpha)
static int roundboxtype
void UI_draw_safe_areas(uint pos, const rctf *rect, const float title_aspect[2], const float action_aspect[2])
static float polar_to_x(float center, float diam, float ampli, float angle)
static void histogram_draw_one(float r, float g, float b, float alpha, float x, float y, float w, float h, const float *data, int res, const bool is_line, uint pos_attr)
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
void UI_draw_roundbox_4fv_ex(const rctf *rect, const float inner1[4], const float inner2[4], float shade_dir, const float outline[4], float outline_width, float rad)
static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth)
static void draw_scope_end(const rctf *rect)
static float polar_to_y(float center, float diam, float ampli, float angle)
static void ui_draw_colorband_handle_box(uint pos, float x1, float y1, float x2, float y2)
void UI_draw_roundbox_corner_set(int type)
void ui_draw_rounded_corners_inverted(const rcti &rect, const float rad, const blender::float4 color)
void ui_draw_but_WAVEFORM(ARegion *region, uiBut *but, const uiWidgetColors *, const rcti *recti)
static void vectorscope_draw_target(uint pos, float centerx, float centery, float diam, const float colf[3], char label)
void UI_draw_roundbox_3fv_alpha(const rctf *rect, bool filled, float rad, const float col[3], float alpha)
void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
void ui_draw_but_HISTOGRAM(ARegion *region, uiBut *but, const uiWidgetColors *, const rcti *recti)
static bool point_draw_handles(CurveProfilePoint *point)
static void circle_draw_rgb(float *points, int tot_points, const float *col, GPUPrimType prim)
static void ui_draw_colorband_handle(uint shdr_pos, const rcti *rect, float x, const float rgb[3], const ColorManagedDisplay *display, bool active)
void ui_draw_but_TRACKPREVIEW(ARegion *region, uiBut *but, const uiWidgetColors *, const rcti *recti)
static void ui_draw_but_curve_grid(const uint pos, const rcti *rect, const float zoom_x, const float zoom_y, const float offset_x, const float offset_y, const float step)
void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rect, const float radius)
void ui_draw_but_VECTORSCOPE(ARegion *region, uiBut *but, const uiWidgetColors *, const rcti *recti)
void ui_draw_but_CURVEPROFILE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
void UI_draw_roundbox_3ub_alpha(const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
static void waveform_draw_rgb(const float *waveform, int waveform_num, const float *col, float alpha)
void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
static void waveform_draw_one(const float *waveform, int waveform_num, const float col[3])
void ui_draw_but_TAB_outline(const rcti *rect, float rad, uchar highlight[3], uchar highlight_fade[3])
void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
void ui_draw_gradient(const rcti *rect, const float hsv[3], eButGradientType type, float alpha, const ColorManagedDisplay *display)
blender::gpu::Batch * ui_batch_roundbox_shadow_get()
blender::gpu::Batch * ui_batch_roundbox_widget_get()
format
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
MINLINE float smoothminf(float a, float b, float c)
ccl_device_inline float2 fabs(const float2 a)
static ulong state[N]
VecBase< float, 4 > float4
VecBase< float, 2 > float2
#define floorf
#define sqrtf
#define atanf
#define sinf
#define cosf
#define ceilf
#define min(a, b)
Definition sort.cc:36
CBData data[32]
CurveMapPoint * table
CurveMapPoint * curve
float ext_out[2]
float ext_in[2]
CurveMap cm[4]
CurveProfilePoint * path
CurveProfilePoint * table
CurveProfilePoint * segments
float data_a[256]
float data_luma[256]
float data_r[256]
float data_b[256]
float data_g[256]
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
struct ImBuf * track_preview
struct ImBuf * track_search
struct MovieTrackingMarker undist_marker
struct MovieTrackingTrack * track
int vecscope_mode
float wavefrm_yfac
float * waveform_3
float * waveform_2
float wavefrm_alpha
float * vecscope_rgb
float minmax[3][2]
float vecscope_alpha
float * waveform_1
float * vecscope
blender::float2 pos
blender::float4 color
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
ColorBand * edit_coba
CurveMapping * edit_cumap
eButGradientType gradient_type
CurveProfile * edit_profile
uiBlock * block
uchar col[4]
unsigned char inner_sel[4]
unsigned char inner[4]
unsigned char outline[4]
unsigned char outline_sel[4]
unsigned char text[4]
unsigned char item[4]
unsigned char text_sel[4]
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len
uint8_t flag
Definition wm_window.cc:145