Blender V4.5
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.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#include "UI_interface.hh"
49
50/* own include */
51#include "interface_intern.hh"
52
54
56{
57 /* Not sure the roundbox function is the best place to change this
58 * if this is undone, it's not that big a deal, only makes curves edges square. */
59 roundboxtype = type;
60}
61
62#if 0 /* unused */
63int UI_draw_roundbox_corner_get()
64{
65 return roundboxtype;
66}
67#endif
68
70 const float inner1[4],
71 const float inner2[4],
72 float shade_dir,
73 const float outline[4],
74 float outline_width,
75 float rad)
76{
77 /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
78 * If it has been scaled, then it's no longer valid. */
79 uiWidgetBaseParameters widget_params{};
80 widget_params.recti.xmin = rect->xmin + outline_width;
81 widget_params.recti.ymin = rect->ymin + outline_width;
82 widget_params.recti.xmax = rect->xmax - outline_width;
83 widget_params.recti.ymax = rect->ymax - outline_width;
84 widget_params.rect = *rect;
85 widget_params.radi = rad;
86 widget_params.rad = rad;
87 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
88 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
89 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
90 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
91 widget_params.color_inner1[0] = inner1 ? inner1[0] : 0.0f;
92 widget_params.color_inner1[1] = inner1 ? inner1[1] : 0.0f;
93 widget_params.color_inner1[2] = inner1 ? inner1[2] : 0.0f;
94 widget_params.color_inner1[3] = inner1 ? inner1[3] : 0.0f;
95 widget_params.color_inner2[0] = inner2 ? inner2[0] : inner1 ? inner1[0] : 0.0f;
96 widget_params.color_inner2[1] = inner2 ? inner2[1] : inner1 ? inner1[1] : 0.0f;
97 widget_params.color_inner2[2] = inner2 ? inner2[2] : inner1 ? inner1[2] : 0.0f;
98 widget_params.color_inner2[3] = inner2 ? inner2[3] : inner1 ? inner1[3] : 0.0f;
99 widget_params.color_outline[0] = outline ? outline[0] : inner1 ? inner1[0] : 0.0f;
100 widget_params.color_outline[1] = outline ? outline[1] : inner1 ? inner1[1] : 0.0f;
101 widget_params.color_outline[2] = outline ? outline[2] : inner1 ? inner1[2] : 0.0f;
102 widget_params.color_outline[3] = outline ? outline[3] : inner1 ? inner1[3] : 0.0f;
103 widget_params.shade_dir = shade_dir;
104 widget_params.alpha_discard = 1.0f;
105
106 blender::gpu::Batch *batch = ui_batch_roundbox_widget_get();
108 GPU_batch_uniform_4fv_array(batch, "parameters", 11, (const float(*)[4]) & widget_params);
112}
113
115 const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
116{
117 const float colv[4] = {
118 float(col[0]) / 255.0f,
119 float(col[1]) / 255.0f,
120 float(col[2]) / 255.0f,
121 float(alpha) / 255.0f,
122 };
123 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
124}
125
127 const rctf *rect, bool filled, float rad, const float col[3], float alpha)
128{
129 const float colv[4] = {col[0], col[1], col[2], alpha};
130 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
131}
132
133void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
134{
135 /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
136 * of the previous AA method. Better fix the callers. */
137 float colv[4] = {color[0], color[1], color[2], color[3]};
138 if (filled) {
139 colv[3] *= 0.65f;
140 }
141
142 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
143}
144
145void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
146{
147 /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
148 UI_draw_roundbox_4fv_ex(rect, (filled) ? col : nullptr, nullptr, 1.0f, col, U.pixelsize, rad);
149}
150
152 const float rad,
153 const blender::float4 color)
154{
157
158 float vec[4][2] = {
159 {0.195, 0.02},
160 {0.55, 0.169},
161 {0.831, 0.45},
162 {0.98, 0.805},
163 };
164 for (int a = 0; a < 4; a++) {
165 mul_v2_fl(vec[a], rad);
166 }
167
169 immUniformColor4fv(color);
170
173 immVertex2f(pos, rect.xmin, rect.ymax);
174 immVertex2f(pos, rect.xmin, rect.ymax - rad);
175 for (int a = 0; a < 4; a++) {
176 immVertex2f(pos, rect.xmin + vec[a][1], rect.ymax - rad + vec[a][0]);
177 }
178 immVertex2f(pos, rect.xmin + rad, rect.ymax);
179 immEnd();
180 }
181
184 immVertex2f(pos, rect.xmax, rect.ymax);
185 immVertex2f(pos, rect.xmax - rad, rect.ymax);
186 for (int a = 0; a < 4; a++) {
187 immVertex2f(pos, rect.xmax - rad + vec[a][0], rect.ymax - vec[a][1]);
188 }
189 immVertex2f(pos, rect.xmax, rect.ymax - rad);
190 immEnd();
191 }
192
195 immVertex2f(pos, rect.xmax, rect.ymin);
196 immVertex2f(pos, rect.xmax, rect.ymin + rad);
197 for (int a = 0; a < 4; a++) {
198 immVertex2f(pos, rect.xmax - vec[a][1], rect.ymin + rad - vec[a][0]);
199 }
200 immVertex2f(pos, rect.xmax - rad, rect.ymin);
201 immEnd();
202 }
203
206 immVertex2f(pos, rect.xmin, rect.ymin);
207 immVertex2f(pos, rect.xmin + rad, rect.ymin);
208 for (int a = 0; a < 4; a++) {
209 immVertex2f(pos, rect.xmin + rad - vec[a][0], rect.ymin + vec[a][1]);
210 }
211 immVertex2f(pos, rect.xmin, rect.ymin + rad);
212 immEnd();
213 }
214
216}
217
218void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
219{
220 const int ofs_y = 4 * U.pixelsize;
221
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
246 /* add a 1px offset, looks nicer */
247 const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
248 const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
249 int a;
250 float vec[4][2] = {
251 {0.195, 0.02},
252 {0.55, 0.169},
253 {0.831, 0.45},
254 {0.98, 0.805},
255 };
256
257 /* Multiply. */
258 for (a = 0; a < 4; a++) {
259 mul_v2_fl(vec[a], rad);
260 }
261
264
265 immAttr4ub(col, UNPACK3(highlight), 255);
266
267 /* start with corner left-top */
269 immVertex2f(pos, minx, maxy - rad);
270 for (a = 0; a < 4; a++) {
271 immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
272 }
273 immVertex2f(pos, minx + rad, maxy);
274 }
275 else {
276 immVertex2f(pos, minx, maxy);
277 }
278
279 /* corner right-top */
281 immVertex2f(pos, maxx - rad, maxy);
282 for (a = 0; a < 4; a++) {
283 immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
284 }
285 immVertex2f(pos, maxx, maxy - rad);
286 }
287 else {
288 immVertex2f(pos, maxx, maxy);
289 }
290
291 immAttr4ub(col, UNPACK3(highlight_fade), 255);
292
293 /* corner right-bottom */
295 immVertex2f(pos, maxx, miny + rad);
296 for (a = 0; a < 4; a++) {
297 immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
298 }
299 immVertex2f(pos, maxx - rad, miny);
300 }
301 else {
302 immVertex2f(pos, maxx, miny);
303 }
304
305 /* corner left-bottom */
307 immVertex2f(pos, minx + rad, miny);
308 for (a = 0; a < 4; a++) {
309 immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
310 }
311 immVertex2f(pos, minx, miny + rad);
312 }
313 else {
314 immVertex2f(pos, minx, miny);
315 }
316
317 immAttr4ub(col, UNPACK3(highlight), 255);
318
319 /* back to corner left-top */
320 immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);
321
322 immEnd();
324}
325
326void ui_draw_but_IMAGE(ARegion * /*region*/,
327 uiBut *but,
328 const uiWidgetColors * /*wcol*/,
329 const rcti *rect)
330{
331#ifdef WITH_HEADLESS
332 (void)rect;
333 (void)but;
334#else
335 ImBuf *ibuf = (ImBuf *)but->poin;
336
337 if (!ibuf) {
338 return;
339 }
340
341 const int w = BLI_rcti_size_x(rect);
342 const int h = BLI_rcti_size_y(rect);
343
344 /* scissor doesn't seem to be doing the right thing...? */
345# if 0
346 /* prevent drawing outside widget area */
347 int scissor[4];
348 GPU_scissor_get(scissor);
349 GPU_scissor(rect->xmin, rect->ymin, w, h);
350# endif
351
352 /* Combine with premultiplied alpha. */
354
355 if (w != ibuf->x || h != ibuf->y) {
356 /* We scale the bitmap, rather than have OGL do a worse job. */
357 IMB_scale(ibuf, w, h, IMBScaleFilter::Box, false);
358 }
359
360 float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
361 if (but->col[3] != 0) {
362 /* Optionally use uiBut's col to recolor the image. */
364 }
365
368 float(rect->xmin),
369 float(rect->ymin),
370 ibuf->x,
371 ibuf->y,
372 GPU_RGBA8,
373 false,
374 ibuf->byte_buffer.data,
375 1.0f,
376 1.0f,
377 col);
378
380
381# if 0
382 /* Restore scissor-test. */
383 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
384# endif
385
386#endif
387}
388
390 const rctf *rect,
391 const float title_aspect[2],
392 const float action_aspect[2])
393{
394 const float size_x_half = (rect->xmax - rect->xmin) * 0.5f;
395 const float size_y_half = (rect->ymax - rect->ymin) * 0.5f;
396
397 const float *safe_areas[] = {title_aspect, action_aspect};
398 const int safe_len = ARRAY_SIZE(safe_areas);
399
400 for (int i = 0; i < safe_len; i++) {
401 if (safe_areas[i][0] || safe_areas[i][1]) {
402 const float margin_x = safe_areas[i][0] * size_x_half;
403 const float margin_y = safe_areas[i][1] * size_y_half;
404
405 const float minx = rect->xmin + margin_x;
406 const float miny = rect->ymin + margin_y;
407 const float maxx = rect->xmax - margin_x;
408 const float maxy = rect->ymax - margin_y;
409
410 imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
411 }
412 }
413}
414
415static void draw_scope_end(const rctf *rect)
416{
418
419 /* outline */
421 const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
422 rctf box_rect{};
423 box_rect.xmin = rect->xmin - 1;
424 box_rect.xmax = rect->xmax + 1;
425 box_rect.ymin = rect->ymin;
426 box_rect.ymax = rect->ymax + 1;
427 UI_draw_roundbox_4fv(&box_rect, false, 3.0f, color);
428}
429
430static void histogram_draw_one(float r,
431 float g,
432 float b,
433 float alpha,
434 float x,
435 float y,
436 float w,
437 float h,
438 const float *data,
439 int res,
440 const bool is_line,
441 uint pos_attr)
442{
443 const float color[4] = {r, g, b, alpha};
444
445 /* that can happen */
446 if (res == 0) {
447 return;
448 }
449
450 GPU_line_smooth(true);
452
453 immUniformColor4fv(color);
454
455 if (is_line) {
456 /* curve outline */
457 GPU_line_width(1.5);
458
460 for (int i = 0; i < res; i++) {
461 const float x2 = x + i * (w / float(res));
462 immVertex2f(pos_attr, x2, y + (data[i] * h));
463 }
464 immEnd();
465
466 GPU_line_width(1.0f);
467 }
468 else {
469 /* under the curve */
471 immVertex2f(pos_attr, x, y);
472 immVertex2f(pos_attr, x, y + (data[0] * h));
473 for (int i = 1; i < res; i++) {
474 const float x2 = x + i * (w / float(res));
475 immVertex2f(pos_attr, x2, y + (data[i] * h));
476 immVertex2f(pos_attr, x2, y);
477 }
478 immEnd();
479
480 /* curve outline */
481 immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
482
485 for (int i = 0; i < res; i++) {
486 const float x2 = x + i * (w / float(res));
487 immVertex2f(pos_attr, x2, y + (data[i] * h));
488 }
489 immEnd();
490 }
491
492 GPU_line_smooth(false);
493}
494
495#define HISTOGRAM_TOT_GRID_LINES 4
496
498 uiBut *but,
499 const uiWidgetColors * /*wcol*/,
500 const rcti *recti)
501{
502 Histogram *hist = (Histogram *)but->poin;
503 const int res = hist->x_resolution;
504 const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
505
506 rctf rect{};
507 rect.xmin = float(recti->xmin + 1);
508 rect.xmax = float(recti->xmax - 1);
509 rect.ymin = float(recti->ymin + 1);
510 rect.ymax = float(recti->ymax - 1);
511
512 const float w = BLI_rctf_size_x(&rect);
513 const float h = BLI_rctf_size_y(&rect) * hist->ymax;
514
516
517 float color[4];
520 rctf back_rect{};
521 back_rect.xmin = rect.xmin - 1;
522 back_rect.xmax = rect.xmax + 1;
523 back_rect.ymin = rect.ymin - 1;
524 back_rect.ymax = rect.ymax + 1;
525
526 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
527
528 /* need scissor test, histogram can draw outside of boundary */
529 int scissor[4];
530 GPU_scissor_get(scissor);
531 rcti scissor_new{};
532 scissor_new.xmin = rect.xmin;
533 scissor_new.ymin = rect.ymin;
534 scissor_new.xmax = rect.xmax;
535 scissor_new.ymax = rect.ymax;
536 const rcti scissor_region = {0, region->winx, 0, region->winy};
537 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
538 GPU_scissor(scissor_new.xmin,
539 scissor_new.ymin,
540 BLI_rcti_size_x(&scissor_new),
541 BLI_rcti_size_y(&scissor_new));
542
545
547
548 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
549 /* draw grid lines here */
550 for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
551 const float fac = float(i) / float(HISTOGRAM_TOT_GRID_LINES);
552
553 /* so we can tell the 1.0 color point */
555 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
556 }
557
559
560 immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
561 immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
562
563 immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
564 immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
565
566 immEnd();
567 }
568
569 if (hist->mode == HISTO_MODE_LUMA) {
571 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
572 }
573 else if (hist->mode == HISTO_MODE_ALPHA) {
575 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
576 }
577 else {
578 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_R)) {
580 1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
581 }
582 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_G)) {
584 0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
585 }
586 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_B)) {
588 0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
589 }
590 }
591
593
594 /* Restore scissor test. */
595 GPU_scissor(UNPACK4(scissor));
596
597 /* outline */
598 draw_scope_end(&rect);
599}
600
601#undef HISTOGRAM_TOT_GRID_LINES
602
603static void waveform_draw_one(const float *waveform, int waveform_num, const float col[3])
604{
607 "It is not allowed to draw a batch when immediate mode has a shader bound. It will "
608 "use the incorrect shader and is hard to discover.");
609 GPUVertFormat format = {0};
611
613 GPU_vertbuf_data_alloc(*vbo, waveform_num);
614
615 GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
616
617 /* TODO: store the #blender::gpu::Batch inside the scope. */
618 blender::gpu::Batch *batch = GPU_batch_create_ex(
619 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
621 GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
622 GPU_batch_uniform_1f(batch, "size", 1.0f);
624
626}
627
632static_assert(sizeof(WaveformColorVertex) == 24);
633
634static void waveform_draw_rgb(const float *waveform,
635 int waveform_num,
636 const float *col,
637 float alpha)
638{
639 GPUVertFormat format = {0};
642
644
645 GPU_vertbuf_data_alloc(*vbo, waveform_num);
647 for (int i = 0; i < waveform_num; i++) {
648 memcpy(&data->pos, waveform, sizeof(data->pos));
649 memcpy(&data->color, col, sizeof(float) * 3);
650 data->color.w = alpha;
651 waveform += 2;
652 col += 3;
653 data++;
654 }
656 GPU_vertbuf_use(vbo);
657
658 blender::gpu::Batch *batch = GPU_batch_create_ex(
659 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
661 GPU_batch_uniform_1f(batch, "size", 1.0f);
664}
665
666static void circle_draw_rgb(float *points, int tot_points, const float *col, GPUPrimType prim)
667{
668 GPUVertFormat format = {0};
670 const uint col_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
671
673
674 GPU_vertbuf_data_alloc(*vbo, tot_points);
675 GPU_vertbuf_attr_fill(vbo, pos_id, points);
676 GPU_vertbuf_attr_fill(vbo, col_id, col);
677
678 blender::gpu::Batch *batch = GPU_batch_create_ex(prim, vbo, nullptr, GPU_BATCH_OWNS_VBO);
679
683}
684
686 uiBut *but,
687 const uiWidgetColors * /*wcol*/,
688 const rcti *recti)
689{
690 Scopes *scopes = (Scopes *)but->poin;
691 int scissor[4];
692 float colors[3][3];
693 const float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
694 /* Colors pre-multiplied by alpha for speed up. */
695 float colors_alpha[3][3], colorsycc_alpha[3][3];
696 float min, max;
697
698 if (scopes == nullptr) {
699 return;
700 }
701
702 rctf rect{};
703 rect.xmin = float(recti->xmin + 1);
704 rect.xmax = float(recti->xmax - 1);
705 rect.ymin = float(recti->ymin + 1);
706 rect.ymax = float(recti->ymax - 1);
707
708 if (scopes->wavefrm_yfac < 0.5f) {
709 scopes->wavefrm_yfac = 0.98f;
710 }
711 const float w = BLI_rctf_size_x(&rect) - 7;
712 const float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
713 const float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
714 const float w3 = w / 3.0f;
715
716 /* log scale for alpha */
717 const float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
718
719 unit_m3(colors);
720
721 for (int c = 0; c < 3; c++) {
722 for (int i = 0; i < 3; i++) {
723 colors_alpha[c][i] = colors[c][i] * alpha;
724 colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
725 }
726 }
727
728 /* Flush text cache before changing scissors. */
730
732
733 float color[4];
736 rctf back_rect{};
737 back_rect.xmin = rect.xmin - 1.0f;
738 back_rect.xmax = rect.xmax + 1.0f;
739 back_rect.ymin = rect.ymin - 1.0f;
740 back_rect.ymax = rect.ymax + 1.0f;
741 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
742
743 /* need scissor test, waveform can draw outside of boundary */
744 GPU_scissor_get(scissor);
745 rcti scissor_new{};
746 scissor_new.xmin = rect.xmin;
747 scissor_new.ymin = rect.ymin;
748 scissor_new.xmax = rect.xmax;
749 scissor_new.ymax = rect.ymax;
750 const rcti scissor_region = {0, region->winx, 0, region->winy};
751 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
752 GPU_scissor(scissor_new.xmin,
753 scissor_new.ymin,
754 BLI_rcti_size_x(&scissor_new),
755 BLI_rcti_size_y(&scissor_new));
756
757 /* draw scale numbers first before binding any shader */
758 for (int i = 0; i < 6; i++) {
759 char str[4];
760 SNPRINTF(str, "%-3d", i * 20);
761 str[3] = '\0';
762 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
763 BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
764 }
765
766 /* Flush text cache before drawing things on top. */
768
771
773
774 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
775
776 /* draw grid lines here */
778
779 for (int i = 0; i < 6; i++) {
780 immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
781 immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
782 }
783
784 immEnd();
785
786 /* 3 vertical separation */
787 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
789
790 for (int i = 1; i < 3; i++) {
791 immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
792 immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
793 }
794
795 immEnd();
796 }
797
798 /* separate min max zone on the right */
800 immVertex2f(pos, rect.xmin + w, rect.ymin);
801 immVertex2f(pos, rect.xmin + w, rect.ymax);
802 immEnd();
803
804 /* 16-235-240 level in case of ITU-R BT601/709 */
805 immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
808
809 immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
810 immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
811
812 immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
813 immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
814
815 immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
816 immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
817
818 immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
819 immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
820
821 immEnd();
822 }
823 /* 7.5 IRE black point level for NTSC */
824 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
826 immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
827 immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
828 immEnd();
829 }
830
831 if (scopes->ok && scopes->waveform_1 != nullptr) {
833 GPU_point_size(1.0);
834
835 /* LUMA (1 channel) */
836 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
837 const float col[3] = {alpha, alpha, alpha};
838
840 GPU_matrix_translate_2f(rect.xmin, yofs);
842
844 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
846
848
849 /* min max */
850 immUniformColor3f(0.5f, 0.5f, 0.5f);
851 min = yofs + scopes->minmax[0][0] * h;
852 max = yofs + scopes->minmax[0][1] * h;
853 CLAMP(min, rect.ymin, rect.ymax);
854 CLAMP(max, rect.ymin, rect.ymax);
855
857 immVertex2f(pos, rect.xmax - 3, min);
858 immVertex2f(pos, rect.xmax - 3, max);
859 immEnd();
860 }
861 /* RGB (3 channel) */
862 else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
864 GPU_matrix_translate_2f(rect.xmin, yofs);
867 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
868 waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
869 waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
872 }
873 /* PARADE / YCC (3 channels) */
874 else if (ELEM(scopes->wavefrm_mode,
879 {
880 const int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
883 GPU_matrix_translate_2f(rect.xmin, yofs);
884 GPU_matrix_scale_2f(w3, h);
885
887 scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
888
889 GPU_matrix_translate_2f(1.0f, 0.0f);
891 scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
892
893 GPU_matrix_translate_2f(1.0f, 0.0f);
895 scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
896
899 }
900
901 /* min max */
902 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
903 for (int c = 0; c < 3; c++) {
905 immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
906 }
907 else {
909 colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
910 }
911 min = yofs + scopes->minmax[c][0] * h;
912 max = yofs + scopes->minmax[c][1] * h;
913 CLAMP(min, rect.ymin, rect.ymax);
914 CLAMP(max, rect.ymin, rect.ymax);
915
917 immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
918 immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
919 immEnd();
920 }
921 }
922 }
923
925
926 /* Restore scissor test. */
927 GPU_scissor(UNPACK4(scissor));
928
929 /* outline */
930 draw_scope_end(&rect);
931
933}
934
935static float polar_to_x(float center, float diam, float ampli, float angle)
936{
937 return center + diam * ampli * cosf(angle);
938}
939
940static float polar_to_y(float center, float diam, float ampli, float angle)
941{
942 return center + diam * ampli * sinf(angle);
943}
944
946 uint pos, float centerx, float centery, float diam, const float colf[3], char label)
947{
948 float y, u, v;
949 float tangle = 0.0f, tampli;
950 float dangle, dampli;
951 const char labelstr[2] = {label, '\0'};
952
953 rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
956
957 if (u > 0 && v >= 0) {
958 tangle = atanf(v / u);
959 }
960 else if (u > 0 && v < 0) {
961 tangle = atanf(v / u) + 2.0f * float(M_PI);
962 }
963 else if (u < 0) {
964 tangle = atanf(v / u) + float(M_PI);
965 }
966 else if (u == 0 && v > 0.0f) {
967 tangle = M_PI_2;
968 }
969 else if (u == 0 && v < 0.0f) {
970 tangle = -M_PI_2;
971 }
972 tampli = sqrtf(u * u + v * v);
973
974 /* small target vary by 2.5 degree and 2.5 IRE unit */
975 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
976 dangle = DEG2RADF(2.5f);
977 dampli = 2.5f / 200.0f;
980 polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
981 polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
983 polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
984 polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
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));
991
992 /* draw color letter as text */
993 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.3f);
994 BLF_draw_default(polar_to_x(centerx, diam, tampli, tangle) + 5,
995 polar_to_y(centery, diam, tampli, tangle),
996 0,
997 labelstr,
998 strlen(labelstr));
999
1000 immEnd();
1001}
1002
1004 uiBut *but,
1005 const uiWidgetColors * /*wcol*/,
1006 const rcti *recti)
1007{
1008 const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
1009 const Scopes *scopes = (const Scopes *)but->poin;
1010
1011 const float colors[6][3] = {
1012 {0.75, 0.0, 0.0}, /* Red */
1013 {0.75, 0.75, 0.0}, /* Yellow */
1014 {0.0, 0.75, 0.0}, /* Green */
1015 {0.0, 0.75, 0.75}, /* Cyan */
1016 {0.0, 0.0, 0.75}, /* Blue */
1017 {0.75, 0.0, 0.75}, /* Magenta */
1018 };
1019
1020 const char color_names[] = {'R', 'Y', 'G', 'C', 'B', 'M'};
1021
1022 rctf rect{};
1023 rect.xmin = float(recti->xmin + 1);
1024 rect.xmax = float(recti->xmax - 1);
1025 rect.ymin = float(recti->ymin + 1);
1026 rect.ymax = float(recti->ymax - 1);
1027
1028 const float w = BLI_rctf_size_x(&rect);
1029 const float h = BLI_rctf_size_y(&rect);
1030 const float centerx = rect.xmin + w * 0.5f;
1031 const float centery = rect.ymin + h * 0.5f;
1032 const float diam = ((w < h) ? w : h) * 0.9f;
1033
1034 const float alpha = scopes->vecscope_alpha;
1035
1036 GPU_line_smooth(true);
1038
1039 float color[4];
1042 rctf back_rect{};
1043 back_rect.xmin = rect.xmin - 1;
1044 back_rect.xmax = rect.xmax + 1;
1045 back_rect.ymin = rect.ymin - 1;
1046 back_rect.ymax = rect.ymax + 1;
1047 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
1048
1049 /* need scissor test, vectorscope can draw outside of boundary */
1050 int scissor[4];
1051 GPU_scissor_get(scissor);
1052 rcti scissor_new{};
1053 scissor_new.xmin = rect.xmin;
1054 scissor_new.ymin = rect.ymin;
1055 scissor_new.xmax = rect.xmax;
1056 scissor_new.ymax = rect.ymax;
1057 const rcti scissor_region = {0, region->winx, 0, region->winy};
1058 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1059 GPU_scissor(scissor_new.xmin,
1060 scissor_new.ymin,
1061 BLI_rcti_size_x(&scissor_new),
1062 BLI_rcti_size_y(&scissor_new));
1063
1066
1068 const int increment = 6;
1069 const int tot_points = int(360 / increment);
1070 const float r = 0.5f;
1071 float step = 360.0f / (tot_points - 1);
1072
1073 float circle_fill_points[(tot_points * 2) + 2];
1074 float circle_fill_vertex_colors[(tot_points * 4) + 4];
1075
1076 /* draw filled RGB circle for background, only for LUMA mode */
1077 if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1078 /* Initialize center point and color */
1079 circle_fill_points[0] = centerx;
1080 circle_fill_points[1] = centery;
1081 circle_fill_vertex_colors[0] = 0.2f;
1082 circle_fill_vertex_colors[1] = 0.2f;
1083 circle_fill_vertex_colors[2] = 0.2f;
1084 circle_fill_vertex_colors[3] = 0.8f;
1085
1086 for (int i = 0; i < tot_points; i++) {
1087 float angle = step * i;
1088 const float a = DEG2RADF(angle);
1089
1090 const float x = polar_to_x(centerx, diam, r, a);
1091 const float y = polar_to_y(centery, diam, r, a);
1092
1093 const float u = (x - centerx) / diam / SCOPES_VEC_U_SCALE;
1094 const float v = (y - centery) / diam / SCOPES_VEC_V_SCALE;
1095
1096 circle_fill_points[(i + 1) * 2] = x;
1097 circle_fill_points[(i + 1) * 2 + 1] = y;
1098
1099 float r, g, b;
1100 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1101
1102 circle_fill_vertex_colors[(i + 1) * 4] = r * 0.2f;
1103 circle_fill_vertex_colors[(i + 1) * 4 + 1] = g * 0.2f;
1104 circle_fill_vertex_colors[(i + 1) * 4 + 2] = b * 0.2f;
1105 circle_fill_vertex_colors[(i + 1) * 4 + 3] = 0.8f;
1106 }
1107
1110 circle_fill_points, tot_points + 1, circle_fill_vertex_colors, GPU_PRIM_TRI_FAN);
1111 }
1112 /* draw filled Gray circle for background, only for RGB mode */
1113 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1115 immBegin(GPU_PRIM_TRI_FAN, tot_points + 2);
1116 immUniformColor3f(0.16f, 0.16f, 0.16f);
1117 immVertex2f(pos, centerx, centery);
1118
1119 for (int i = 0; i <= 360; i += increment) {
1120 const float a = DEG2RADF(float(i));
1121 immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
1122 }
1123 immEnd();
1124 }
1125
1126 /* draw RGB ring */
1127 float circle_points[(tot_points * 2) + 3] = {};
1128 float circle_vertex_colors[(tot_points * 4) + 5] = {};
1129
1130 for (int i = 0; i < tot_points; i++) {
1131 float angle = step * i;
1132 const float a = DEG2RADF(angle);
1133
1134 const float x = polar_to_x(centerx, diam, 0.5f, a);
1135 const float y = polar_to_y(centery, diam, 0.5f, a);
1136 circle_points[i * 2] = x;
1137 circle_points[i * 2 + 1] = y;
1138
1139 const float u = (x - centerx) / diam / SCOPES_VEC_U_SCALE;
1140 const float v = (y - centery) / diam / SCOPES_VEC_V_SCALE;
1141 float r, g, b;
1142 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1143
1144 circle_vertex_colors[i * 4] = r;
1145 circle_vertex_colors[i * 4 + 1] = g;
1146 circle_vertex_colors[i * 4 + 2] = b;
1147 circle_vertex_colors[i * 4 + 3] = 0.8f;
1148 }
1149
1151 GPU_line_width(2.5f);
1152 circle_draw_rgb(circle_points, tot_points, circle_vertex_colors, GPU_PRIM_LINE_LOOP);
1153 GPU_line_width(1.5f);
1154
1155 /* inner circles */
1157 for (int j = 0; j < 4; j++) {
1158 float inner_circle_points[(tot_points * 2) + 3] = {};
1159 float inner_circle_colors[(tot_points * 4) + 5] = {};
1160 const float r = (j + 1) * 0.1f;
1161
1162 for (int i = 0; i < tot_points; i++) {
1163 float angle = step * i;
1164 const float a = DEG2RADF(angle);
1165
1166 inner_circle_points[i * 2] = polar_to_x(centerx, diam, r, a);
1167 inner_circle_points[i * 2 + 1] = polar_to_y(centery, diam, r, a);
1168
1169 inner_circle_colors[i * 4] = 0.1f;
1170 inner_circle_colors[i * 4 + 1] = 0.1f;
1171 inner_circle_colors[i * 4 + 2] = 0.1f;
1172 inner_circle_colors[i * 4 + 3] = 0.8f;
1173 }
1174 circle_draw_rgb(inner_circle_points, tot_points, inner_circle_colors, GPU_PRIM_LINE_LOOP);
1175 }
1176
1177 /* draw grid elements */
1178 /* cross */
1179 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.1f);
1181
1182 immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
1183 immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
1184
1185 immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
1186 immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
1187
1188 immEnd();
1189
1190 /* skin tone line */
1192 immUniformColor3f(0.25f, 0.25f, 0.25f);
1193
1196 pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
1198 pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
1199 immEnd();
1200
1201 /* saturation points */
1202 for (int i = 0; i < 6; i++) {
1203 vectorscope_draw_target(pos, centerx, centery, diam, colors[i], color_names[i]);
1204 }
1205
1206 if (scopes->ok && scopes->vecscope != nullptr) {
1207 /* pixel point cloud */
1208 GPU_point_size(1.0);
1209
1211 GPU_matrix_translate_2f(centerx, centery);
1212 GPU_matrix_scale_1f(diam);
1213
1214 const float col[3] = {alpha, alpha, alpha};
1215 if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1217 waveform_draw_rgb(scopes->vecscope, scopes->waveform_tot, scopes->vecscope_rgb, alpha);
1218 }
1219 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1221 waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
1222 }
1223
1225 }
1226
1228
1229 /* Restore scissor test. */
1230 GPU_scissor(UNPACK4(scissor));
1231 /* outline */
1232 draw_scope_end(&rect);
1233
1235}
1236
1237static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth)
1238{
1239 /* Half-width equals height for better AA with 45 degree slope. */
1241 immVertex2f(pos, x1 + halfwidth, y1);
1242 immVertex2f(pos, x1, y1 + halfwidth);
1243 immVertex2f(pos, x1 - halfwidth, y1);
1244 immEnd();
1245}
1246
1247static void ui_draw_colorband_handle_box(uint pos, float x1, float y1, float x2, float y2)
1248{
1250 immVertex2f(pos, x2, y1);
1251 immVertex2f(pos, x1, y1);
1252 immVertex2f(pos, x2, y2);
1253 immVertex2f(pos, x1, y2);
1254 immEnd();
1255}
1256
1257static void ui_draw_colorband_handle(uint shdr_pos,
1258 const rcti *rect,
1259 float x,
1260 const float rgb[3],
1261 const ColorManagedDisplay *display,
1262 bool active)
1263{
1264 const float sizey = BLI_rcti_size_y(rect);
1265 float colf[3] = {UNPACK3(rgb)};
1266
1267 const float half_width = sizey / 3.5f;
1268 const float height = half_width * 1.4f;
1269
1270 float y1 = rect->ymin;
1271 const float y2 = rect->ymax;
1272
1273 /* align to pixels */
1274 x = floorf(x);
1275
1277
1278 /* Allow the lines to decrease as we get really small. */
1279 float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize),
1280 0.5f);
1281
1282 /* Make things transparent as we get tiny. */
1283 uchar alpha = std::min(int(fabs(half_width - 2.0f) * 50.0f), 255);
1284
1286
1287 float viewport_size[4];
1288 GPU_viewport_size_get_f(viewport_size);
1289 immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
1290 immUniform1i("colors_len", 2); /* "advanced" mode */
1291 if (active) {
1292 immUniform4f("color", 1.0f, 1.0f, 1.0f, alpha / 255.0f);
1293 immUniform4f("color2", 0.0f, 0.0f, 0.0f, alpha / 255.0f);
1294 }
1295 else {
1296 immUniform4f("color", 0.7f, 0.7f, 0.7f, alpha / 255.0f);
1297 immUniform4f("color2", 0.4f, 0.4f, 0.4f, alpha / 255.0f);
1298 }
1299 immUniform1f("dash_width", sizey / 6.0f / UI_SCALE_FAC);
1300 immUniform1f("udash_factor", 0.5f);
1301
1303 immVertex2f(shdr_pos, x, y1);
1304 immVertex2f(shdr_pos, x, y2);
1305 immEnd();
1306
1308
1310
1311 /* shift handle down */
1312 y1 -= half_width / 2.0f;
1313
1314 /* Black outline around the lower box. */
1315 immUniformColor4ub(0, 0, 0, alpha);
1316
1318 x - half_width - line_width,
1319 y1 - line_width,
1320 x + half_width + line_width,
1321 y1 + height);
1322
1323 /* Grey box, inset by line width. */
1324 immUniformColor4ub(128, 128, 128, alpha);
1325 ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1, x + half_width, y1 + height);
1326
1327 if (display) {
1329 }
1330
1331 /* Color value, inset by another line width. */
1332 immUniformColor3fvAlpha(colf, alpha);
1334 x - (half_width - line_width),
1335 y1 + line_width,
1336 x + (half_width - line_width),
1337 y1 + height - line_width);
1338
1339 /* Black outline around the top triangle. */
1340 immUniformColor4ub(0, 0, 0, alpha);
1341 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width + line_width);
1342
1343 GPU_polygon_smooth(true);
1344
1345 /* Triangle main color. */
1346 if (active) {
1347 immUniformColor4ub(220, 220, 220, alpha);
1348 }
1349 else {
1350 immUniformColor4ub(96, 96, 96, alpha);
1351 }
1352 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width - (0.5f * line_width));
1353
1355
1356 GPU_polygon_smooth(false);
1358}
1359
1360void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1361{
1362 const ColorManagedDisplay *display = ui_block_cm_display_get(but->block);
1363 uint pos_id, col_id;
1364
1365 uiButColorBand *but_coba = (uiButColorBand *)but;
1366 ColorBand *coba = (but_coba->edit_coba == nullptr) ? (ColorBand *)but->poin :
1367 but_coba->edit_coba;
1368
1369 if (coba == nullptr) {
1370 return;
1371 }
1372
1373 const float x1 = rect->xmin + U.pixelsize;
1374 const float sizex = rect->xmax - x1 - U.pixelsize;
1375 const float y1 = rect->ymin + U.pixelsize;
1376 const float sizey = rect->ymax - y1 - U.pixelsize;
1377 const float sizey_solid = sizey * 0.25f;
1378
1379 /* exit early if too narrow */
1380 if (sizex <= 0) {
1381 return;
1382 }
1383
1385
1386 /* Line width outline. */
1392 immVertex2f(pos_id, rect->xmin, rect->ymin);
1393 immVertex2f(pos_id, rect->xmax, rect->ymin);
1394 immVertex2f(pos_id, rect->xmin, rect->ymax);
1395 immVertex2f(pos_id, rect->xmax, rect->ymax);
1396 immEnd();
1398
1399 /* Drawing the checkerboard. */
1401 const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f;
1402 const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f;
1403 immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f);
1404 immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f);
1405 immUniform1i("size", 8);
1406 immRectf(pos_id, x1, y1, x1 + sizex, y1 + sizey);
1408
1409 /* New format */
1414
1415 CBData *cbd = coba->data;
1416
1417 float v1[2], v2[2];
1418 float colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
1419
1420 v1[1] = y1 + sizey_solid;
1421 v2[1] = y1 + sizey;
1422
1423 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1424 for (int a = 0; a <= sizex; a++) {
1425 const float pos = float(a) / sizex;
1426 BKE_colorband_evaluate(coba, pos, colf);
1427 if (display) {
1429 }
1430
1431 v1[0] = v2[0] = x1 + a;
1432
1433 immAttr4fv(col_id, colf);
1434 immVertex2fv(pos_id, v1);
1435 immVertex2fv(pos_id, v2);
1436 }
1437 immEnd();
1438
1439 /* layer: color ramp without alpha for reference when manipulating ramp properties */
1440 v1[1] = y1;
1441 v2[1] = y1 + sizey_solid;
1442
1443 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1444 for (int a = 0; a <= sizex; a++) {
1445 const float pos = float(a) / sizex;
1446 BKE_colorband_evaluate(coba, pos, colf);
1447 if (display) {
1449 }
1450
1451 v1[0] = v2[0] = x1 + a;
1452
1453 immAttr4f(col_id, colf[0], colf[1], colf[2], 1.0f);
1454 immVertex2fv(pos_id, v1);
1455 immVertex2fv(pos_id, v2);
1456 }
1457 immEnd();
1458
1460
1461 /* New format */
1464
1465 /* layer: draw handles */
1466 for (int a = 0; a < coba->tot; a++, cbd++) {
1467 if (a != coba->cur) {
1468 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1469 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false);
1470 }
1471 }
1472
1473 /* layer: active handle */
1474 if (coba->tot != 0) {
1475 cbd = &coba->data[coba->cur];
1476 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1477 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true);
1478 }
1479}
1480
1482 const uiWidgetColors *wcol,
1483 const rcti *rect,
1484 const float radius)
1485{
1486 /* sphere color */
1487 const float diffuse[3] = {1.0f, 1.0f, 1.0f};
1488 float light[3];
1489 const float size = 0.5f * min_ff(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
1490
1491 /* backdrop */
1493 rctf box_rect{};
1494 box_rect.xmin = rect->xmin;
1495 box_rect.xmax = rect->xmax;
1496 box_rect.ymin = rect->ymin;
1497 box_rect.ymax = rect->ymax;
1498 UI_draw_roundbox_3ub_alpha(&box_rect, true, radius, wcol->inner, 255);
1499
1501
1502 /* setup lights */
1503 ui_but_v3_get(but, light);
1504
1505 /* transform to button */
1507
1508 const bool use_project_matrix = (size >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
1509 if (use_project_matrix) {
1512 }
1513
1514 GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect),
1515 rect->ymin + 0.5f * BLI_rcti_size_y(rect));
1517
1518 blender::gpu::Batch *sphere = GPU_batch_preset_sphere(2);
1519 SimpleLightingData simple_lighting_data;
1520 copy_v4_fl4(simple_lighting_data.l_color, diffuse[0], diffuse[1], diffuse[2], 1.0f);
1521 copy_v3_v3(simple_lighting_data.light, light);
1522 GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(
1523 sizeof(SimpleLightingData), &simple_lighting_data, __func__);
1524
1526 GPU_batch_uniformbuf_bind(sphere, "simple_lighting_data", ubo);
1527 GPU_batch_draw(sphere);
1529
1530 /* Restore. */
1532
1533 /* AA circle */
1538
1540 GPU_line_smooth(true);
1541 imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
1543 GPU_line_smooth(false);
1544
1545 if (use_project_matrix) {
1547 }
1548
1549 /* matrix after circle */
1551
1553}
1554
1556 const rcti *rect,
1557 const float zoom_x,
1558 const float zoom_y,
1559 const float offset_x,
1560 const float offset_y,
1561 const float step)
1562{
1563 const float start_x = (ceilf(offset_x / step) * step - offset_x) * zoom_x + rect->xmin;
1564 const float start_y = (ceilf(offset_y / step) * step - offset_y) * zoom_y + rect->ymin;
1565
1566 const int line_count_x = ceilf((rect->xmax - start_x) / (step * zoom_x));
1567 const int line_count_y = ceilf((rect->ymax - start_y) / (step * zoom_y));
1568
1569 if (line_count_x + line_count_y == 0) {
1570 return;
1571 }
1572
1573 immBegin(GPU_PRIM_LINES, (line_count_x + line_count_y) * 2);
1574 for (int i = 0; i < line_count_x; i++) {
1575 const float x = start_x + i * step * zoom_x;
1576 immVertex2f(pos, x, rect->ymin);
1577 immVertex2f(pos, x, rect->ymax);
1578 }
1579 for (int i = 0; i < line_count_y; i++) {
1580 const float y = start_y + i * step * zoom_y;
1581 immVertex2f(pos, rect->xmin, y);
1582 immVertex2f(pos, rect->xmax, y);
1583 }
1584 immEnd();
1585}
1586
1587static void gl_shaded_color_get(const uchar color[3], int shade, uchar r_color[3])
1588{
1589 r_color[0] = color[0] - shade > 0 ? color[0] - shade : 0;
1590 r_color[1] = color[1] - shade > 0 ? color[1] - shade : 0;
1591 r_color[2] = color[2] - shade > 0 ? color[2] - shade : 0;
1592}
1593
1594static void gl_shaded_color_get_fl(const uchar *color, int shade, float r_color[3])
1595{
1596 uchar color_shaded[3];
1597 gl_shaded_color_get(color, shade, color_shaded);
1598 rgb_uchar_to_float(r_color, color_shaded);
1599}
1600
1601static void gl_shaded_color(const uchar *color, int shade)
1602{
1603 uchar color_shaded[3];
1604 gl_shaded_color_get(color, shade, color_shaded);
1605 immUniformColor3ubv(color_shaded);
1606}
1607
1608void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1609{
1610 uiButCurveMapping *but_cumap = (uiButCurveMapping *)but;
1611 CurveMapping *cumap = (but_cumap->edit_cumap == nullptr) ? (CurveMapping *)but->poin :
1612 but_cumap->edit_cumap;
1613
1614 const float clip_size_x = BLI_rctf_size_x(&cumap->curr);
1615 const float clip_size_y = BLI_rctf_size_y(&cumap->curr);
1616
1617 /* zero-sized curve */
1618 if (clip_size_x == 0.0f || clip_size_y == 0.0f) {
1619 return;
1620 }
1621
1622 /* calculate offset and zoom */
1623 const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / clip_size_x;
1624 const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / clip_size_y;
1625 const float offsx = cumap->curr.xmin - (1.0f / zoomx);
1626 const float offsy = cumap->curr.ymin - (1.0f / zoomy);
1627
1628 /* exit early if too narrow */
1629 if (zoomx == 0.0f) {
1630 return;
1631 }
1632
1633 CurveMap *cuma = &cumap->cm[cumap->cur];
1634
1635 /* need scissor test, curve can draw outside of boundary */
1636 int scissor[4];
1637 GPU_scissor_get(scissor);
1638 rcti scissor_new{};
1639 scissor_new.xmin = rect->xmin;
1640 scissor_new.ymin = rect->ymin;
1641 scissor_new.xmax = rect->xmax;
1642 scissor_new.ymax = rect->ymax;
1643 const rcti scissor_region = {0, region->winx, 0, region->winy};
1644 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1645 GPU_scissor(scissor_new.xmin,
1646 scissor_new.ymin,
1647 BLI_rcti_size_x(&scissor_new),
1648 BLI_rcti_size_y(&scissor_new));
1649
1650 /* Do this first to not mess imm context */
1651 if (but_cumap->gradient_type == UI_GRAD_H) {
1652 /* magic trigger for curve backgrounds */
1653 const float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
1654
1655 rcti grid{};
1656 grid.xmin = rect->xmin + zoomx * (-offsx);
1657 grid.xmax = grid.xmin + zoomx;
1658 grid.ymin = rect->ymin + zoomy * (-offsy);
1659 grid.ymax = grid.ymin + zoomy;
1660 ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);
1661 }
1662
1663 GPU_line_width(1.0f);
1664
1668
1669 /* backdrop */
1670 float color_backdrop[4] = {0, 0, 0, 1};
1671
1672 if (but_cumap->gradient_type == UI_GRAD_H) {
1673 /* grid, hsv uses different grid */
1675 ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
1676 immUniformColor4fv(color_backdrop);
1677 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
1679 }
1680 else {
1681 if (cumap->flag & CUMA_DO_CLIP) {
1682 gl_shaded_color_get_fl(wcol->inner, -20, color_backdrop);
1683 immUniformColor3fv(color_backdrop);
1684 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1686 immRectf(pos,
1687 rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
1688 rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
1689 rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
1690 rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
1691 }
1692 else {
1693 rgb_uchar_to_float(color_backdrop, wcol->inner);
1694 immUniformColor3fv(color_backdrop);
1695 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1696 }
1697
1698 /* grid, every 0.25 step */
1699 gl_shaded_color(wcol->inner, -16);
1700 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
1701 /* grid, every 1.0 step */
1702 gl_shaded_color(wcol->inner, -24);
1703 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
1704 /* axes */
1705 gl_shaded_color(wcol->inner, -50);
1707 immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
1708 immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
1709 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
1710 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
1711 immEnd();
1712 }
1713
1714 /* cfra option */
1715 /* XXX 2.48 */
1716#if 0
1717 if (cumap->flag & CUMA_DRAW_CFRA) {
1718 immUniformColor3ub(0x60, 0xc0, 0x40);
1720 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
1721 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
1722 immEnd();
1723 }
1724#endif
1725 /* sample option */
1726
1727 if (cumap->flag & CUMA_DRAW_SAMPLE) {
1728 immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
1729 if (but_cumap->gradient_type == UI_GRAD_H) {
1730 float tsample[3];
1731 float hsv[3];
1732 linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
1733 rgb_to_hsv_v(tsample, hsv);
1734 immUniformColor3ub(240, 240, 240);
1735
1736 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
1737 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
1738 }
1739 else if (cumap->cur == 3) {
1740 const float lum = IMB_colormanagement_get_luminance(cumap->sample);
1741 immUniformColor3ub(240, 240, 240);
1742
1743 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
1744 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
1745 }
1746 else {
1747 if (cumap->cur == 0) {
1748 immUniformColor3ub(240, 100, 100);
1749 }
1750 else if (cumap->cur == 1) {
1751 immUniformColor3ub(100, 240, 100);
1752 }
1753 else {
1754 immUniformColor3ub(100, 100, 240);
1755 }
1756
1757 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
1758 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
1759 }
1760 immEnd();
1761 }
1763
1764 if (cuma->table == nullptr) {
1765 BKE_curvemapping_changed(cumap, false);
1766 }
1767
1768 CurveMapPoint *cmp = cuma->table;
1769 rctf line_range;
1770
1771 /* First curve point. */
1772 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1773 line_range.xmin = rect->xmin;
1774 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
1775 }
1776 else {
1777 line_range.xmin = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
1778 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
1779 }
1780 /* Last curve point. */
1781 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1782 line_range.xmax = rect->xmax;
1783 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
1784 }
1785 else {
1786 line_range.xmax = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
1787 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
1788 }
1789
1792
1793 /* Curve filled. */
1794 immUniformColor3ubvAlpha(wcol->item, 128);
1795 immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4);
1796 immVertex2f(pos, line_range.xmin, rect->ymin);
1797 immVertex2f(pos, line_range.xmin, line_range.ymin);
1798 for (int a = 0; a <= CM_TABLE; a++) {
1799 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1800 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1801 immVertex2f(pos, fx, rect->ymin);
1802 immVertex2f(pos, fx, fy);
1803 }
1804 immVertex2f(pos, line_range.xmax, rect->ymin);
1805 immVertex2f(pos, line_range.xmax, line_range.ymax);
1806 immEnd();
1807
1808 /* Curve line. */
1809 GPU_line_width(1.0f);
1810 immUniformColor3ubvAlpha(wcol->item, 255);
1811 GPU_line_smooth(true);
1813 immVertex2f(pos, line_range.xmin, line_range.ymin);
1814 for (int a = 0; a <= CM_TABLE; a++) {
1815 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1816 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1817 immVertex2f(pos, fx, fy);
1818 }
1819 immVertex2f(pos, line_range.xmax, line_range.ymax);
1820 immEnd();
1821
1822 /* Reset state for fill & line. */
1823 GPU_line_smooth(false);
1826
1827 /* The points, use aspect to make them visible on edges. */
1833
1835
1836 /* Calculate vertex colors based on text theme. */
1837 float color_vert[4], color_vert_select[4];
1838 UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
1839 UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
1840 if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
1841 interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
1842 }
1843 if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
1844 /* Ensure brightest text color is used for selection. */
1845 swap_v3_v3(color_vert, color_vert_select);
1846 }
1847
1848 cmp = cuma->curve;
1849 const float point_size = max_ff(U.pixelsize * 3.0f,
1850 min_ff(UI_SCALE_FAC / but->block->aspect * 6.0f, 20.0f));
1852 for (int a = 0; a < cuma->totpoint; a++) {
1853 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1854 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1855 immAttr4fv(col, (cmp[a].flag & CUMA_SELECT) ? color_vert_select : color_vert);
1856 immAttr1f(size, point_size);
1857 immVertex2f(pos, fx, fy);
1858 }
1859 immEnd();
1861
1862 /* Restore scissor-test. */
1863 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
1864
1865 /* outline */
1869
1871 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1872
1874}
1875
1880{
1881 return (point->flag & PROF_SELECT &&
1882 (ELEM(point->h1, HD_FREE, HD_ALIGN) || ELEM(point->h2, HD_FREE, HD_ALIGN))) ||
1884}
1885
1887 uiBut *but,
1888 const uiWidgetColors *wcol,
1889 const rcti *rect)
1890{
1891 float fx, fy;
1892
1893 uiButCurveProfile *but_profile = (uiButCurveProfile *)but;
1894 CurveProfile *profile = (but_profile->edit_profile == nullptr) ? (CurveProfile *)but->poin :
1895 but_profile->edit_profile;
1896
1897 /* Calculate offset and zoom. */
1898 const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect);
1899 const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect);
1900 const float offsx = profile->view_rect.xmin - (1.0f / zoomx);
1901 const float offsy = profile->view_rect.ymin - (1.0f / zoomy);
1902
1903 /* Exit early if too narrow. */
1904 if (zoomx == 0.0f) {
1905 return;
1906 }
1907
1908 /* Test needed because path can draw outside of boundary. */
1909 int scissor[4];
1910 GPU_scissor_get(scissor);
1911 rcti scissor_new{};
1912 scissor_new.xmin = rect->xmin;
1913 scissor_new.ymin = rect->ymin;
1914 scissor_new.xmax = rect->xmax;
1915 scissor_new.ymax = rect->ymax;
1916
1917 const rcti scissor_region = {0, region->winx, 0, region->winy};
1918 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1919 GPU_scissor(scissor_new.xmin,
1920 scissor_new.ymin,
1921 BLI_rcti_size_x(&scissor_new),
1922 BLI_rcti_size_y(&scissor_new));
1923
1924 GPU_line_width(1.0f);
1925
1929
1930 /* Draw the backdrop. */
1931 float color_backdrop[4] = {0, 0, 0, 1};
1932 if (profile->flag & PROF_USE_CLIP) {
1933 gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
1934 immUniformColor3fv(color_backdrop);
1935 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1937 immRectf(pos,
1938 rect->xmin + zoomx * (profile->clip_rect.xmin - offsx),
1939 rect->ymin + zoomy * (profile->clip_rect.ymin - offsy),
1940 rect->xmin + zoomx * (profile->clip_rect.xmax - offsx),
1941 rect->ymin + zoomy * (profile->clip_rect.ymax - offsy));
1942 }
1943 else {
1944 rgb_uchar_to_float(color_backdrop, (uchar *)wcol->inner);
1945 immUniformColor3fv(color_backdrop);
1946 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1947 }
1948
1949 /* 0.25 step grid. */
1950 gl_shaded_color((uchar *)wcol->inner, -16);
1951 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
1952 /* 1.0 step grid. */
1953 gl_shaded_color((uchar *)wcol->inner, -24);
1954 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
1955
1956 /* Draw the path's fill. */
1957 if (profile->table == nullptr) {
1959 }
1960 CurveProfilePoint *pts = profile->table;
1961 /* Also add the last points on the right and bottom edges to close off the fill polygon. */
1962 const bool add_left_tri = profile->view_rect.xmin < 0.0f;
1963 const bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
1964 int tot_points = BKE_curveprofile_table_size(profile) + 1 + add_left_tri + add_bottom_tri;
1965 const uint tot_triangles = tot_points - 2;
1966
1967 /* Create array of the positions of the table's points. */
1968 float(*table_coords)[2] = static_cast<float(*)[2]>(
1969 MEM_mallocN(sizeof(*table_coords) * tot_points, __func__));
1970 for (uint i = 0; i < uint(BKE_curveprofile_table_size(profile)); i++) {
1971 /* Only add the points from the table here. */
1972 table_coords[i][0] = pts[i].x;
1973 table_coords[i][1] = pts[i].y;
1974 }
1975 /* Using some extra margin (-1.0f) for the coordinates used to complete the polygon
1976 * avoids the profile line crossing itself in some common situations, which can lead to
1977 * incorrect triangulation. See #841183. */
1978 if (add_left_tri && add_bottom_tri) {
1979 /* Add left side, bottom left corner, and bottom side points. */
1980 table_coords[tot_points - 3][0] = profile->view_rect.xmin - 1.0f;
1981 table_coords[tot_points - 3][1] = 1.0f;
1982 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
1983 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
1984 table_coords[tot_points - 1][0] = 1.0f;
1985 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
1986 }
1987 else if (add_left_tri) {
1988 /* Add the left side and bottom left corner points. */
1989 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
1990 table_coords[tot_points - 2][1] = 1.0f;
1991 table_coords[tot_points - 1][0] = profile->view_rect.xmin - 1.0f;
1992 table_coords[tot_points - 1][1] = -1.0f;
1993 }
1994 else if (add_bottom_tri) {
1995 /* Add the bottom side and bottom left corner points. */
1996 table_coords[tot_points - 2][0] = -1.0f;
1997 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
1998 table_coords[tot_points - 1][0] = 1.0f;
1999 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
2000 }
2001 else {
2002 /* Just add the bottom corner point. Side points would be redundant anyway. */
2003 table_coords[tot_points - 1][0] = -1.0f;
2004 table_coords[tot_points - 1][1] = -1.0f;
2005 }
2006
2007 /* Calculate the table point indices of the triangles for the profile's fill. */
2008 if (tot_triangles > 0) {
2009 uint(*tri_indices)[3] = static_cast<uint(*)[3]>(
2010 MEM_mallocN(sizeof(*tri_indices) * tot_triangles, __func__));
2011 BLI_polyfill_calc(table_coords, tot_points, -1, tri_indices);
2012
2013 /* Draw the triangles for the profile fill. */
2014 immUniformColor3ubvAlpha(wcol->item, 128);
2016 GPU_polygon_smooth(false);
2017 immBegin(GPU_PRIM_TRIS, 3 * tot_triangles);
2018 for (uint i = 0; i < tot_triangles; i++) {
2019 const uint *tri = tri_indices[i];
2020 for (uint j = 0; j < 3; j++) {
2021 fx = rect->xmin + zoomx * (table_coords[tri[j]][0] - offsx);
2022 fy = rect->ymin + zoomy * (table_coords[tri[j]][1] - offsy);
2023 immVertex2f(pos, fx, fy);
2024 }
2025 }
2026 immEnd();
2027 MEM_freeN(tri_indices);
2028 }
2029
2030 /* Draw the profile's path so the edge stands out a bit. */
2031 tot_points -= (add_left_tri + add_left_tri);
2032 const int edges_len = tot_points - 1;
2033 if (edges_len > 0) {
2034 GPU_line_width(1.0f);
2035 immUniformColor3ubvAlpha((const uchar *)wcol->item, 255);
2036 GPU_line_smooth(true);
2037 immBegin(GPU_PRIM_LINE_STRIP, tot_points);
2038 for (int i = 0; i < tot_points; i++) {
2039 fx = rect->xmin + zoomx * (table_coords[i][0] - offsx);
2040 fy = rect->ymin + zoomy * (table_coords[i][1] - offsy);
2041 immVertex2f(pos, fx, fy);
2042 }
2043 immEnd();
2044 }
2045
2046 MEM_SAFE_FREE(table_coords);
2047
2048 /* Draw the handles for the selected control points. */
2049 pts = profile->path;
2050 const int path_len = tot_points = uint(profile->path_len);
2051 int selected_free_points = 0;
2052 for (int i = 0; i < path_len; i++) {
2053 if (point_draw_handles(&pts[i])) {
2054 selected_free_points++;
2055 }
2056 }
2057 /* Draw the lines to the handles from the points. */
2058 if (selected_free_points > 0) {
2059 GPU_line_width(1.0f);
2060 gl_shaded_color((uchar *)wcol->inner, -24);
2061 GPU_line_smooth(true);
2062 immBegin(GPU_PRIM_LINES, selected_free_points * 4);
2063 float ptx, pty;
2064 for (int i = 0; i < path_len; i++) {
2065 if (point_draw_handles(&pts[i])) {
2066 ptx = rect->xmin + zoomx * (pts[i].x - offsx);
2067 pty = rect->ymin + zoomy * (pts[i].y - offsy);
2068
2069 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2070 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2071 immVertex2f(pos, ptx, pty);
2072 immVertex2f(pos, fx, fy);
2073
2074 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2075 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2076 immVertex2f(pos, ptx, pty);
2077 immVertex2f(pos, fx, fy);
2078 }
2079 }
2080 immEnd();
2081 }
2083
2084 /* New GPU instructions for control points and sampled points. */
2090
2092
2093 /* Calculate vertex colors based on text theme. */
2094 float color_vert[4], color_vert_select[4], color_sample[4];
2095 UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
2096 UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
2097 color_sample[0] = float(wcol->item[0]) / 255.0f;
2098 color_sample[1] = float(wcol->item[1]) / 255.0f;
2099 color_sample[2] = float(wcol->item[2]) / 255.0f;
2100 color_sample[3] = float(wcol->item[3]) / 255.0f;
2101 if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
2102 interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
2103 }
2104 if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
2105 /* Ensure brightest text color is used for selection. */
2106 swap_v3_v3(color_vert, color_vert_select);
2107 }
2108
2109 float point_size;
2110
2111 /* Draw the control points. */
2112 GPU_line_smooth(false);
2113 if (path_len > 0) {
2115 point_size = max_ff(3.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 5.0f, 5.0f));
2116 immBegin(GPU_PRIM_POINTS, path_len);
2117 for (int i = 0; i < path_len; i++) {
2118 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2119 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2120 immAttr1f(size, point_size);
2121 immAttr4fv(col, (pts[i].flag & PROF_SELECT) ? color_vert_select : color_vert);
2122 immVertex2f(pos, fx, fy);
2123 }
2124 immEnd();
2125 }
2126
2127 /* Draw the handle points. */
2128 if (selected_free_points > 0) {
2129 GPU_line_smooth(false);
2131 point_size = max_ff(2.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 4.0f, 4.0f));
2132 immBegin(GPU_PRIM_POINTS, selected_free_points * 2);
2133 for (int i = 0; i < path_len; i++) {
2134 if (point_draw_handles(&pts[i])) {
2135 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2136 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2137 immAttr1f(size, point_size);
2138 immAttr4fv(col, (pts[i].flag & PROF_H1_SELECT) ? color_vert_select : color_vert);
2139 immVertex2f(pos, fx, fy);
2140 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2141 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2142 immAttr4fv(col, (pts[i].flag & PROF_H2_SELECT) ? color_vert_select : color_vert);
2143 immVertex2f(pos, fx, fy);
2144 }
2145 }
2146 immEnd();
2147 }
2148
2149 /* Draw the sampled points in addition to the control points if they have been created */
2150 pts = profile->segments;
2151 const int segments_len = uint(profile->segments_len);
2152 if (segments_len > 0 && pts) {
2153 point_size = max_ff(2.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 3.0f, 3.0f));
2154 immBegin(GPU_PRIM_POINTS, segments_len);
2155 for (int i = 0; i < segments_len; i++) {
2156 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2157 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2158 immAttr1f(size, point_size);
2159 immAttr4fv(col, color_sample);
2160 immVertex2f(pos, fx, fy);
2161 }
2162 immEnd();
2163 }
2165
2166 /* Restore scissor-test. */
2167 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
2168
2169 /* Outline */
2173
2174 immUniformColor3ubv((const uchar *)wcol->outline);
2175 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
2177}
2178
2180 uiBut *but,
2181 const uiWidgetColors * /*wcol*/,
2182 const rcti *recti)
2183{
2184 bool ok = false;
2185 MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
2186
2187 rctf rect{};
2188 rect.xmin = float(recti->xmin + 1);
2189 rect.xmax = float(recti->xmax - 1);
2190 rect.ymin = float(recti->ymin + 1);
2191 rect.ymax = float(recti->ymax - 1);
2192
2193 const int width = BLI_rctf_size_x(&rect) + 1;
2194 const int height = BLI_rctf_size_y(&rect);
2195
2197
2198 /* need scissor test, preview image can draw outside of boundary */
2199 int scissor[4];
2200 GPU_scissor_get(scissor);
2201 rcti scissor_new{};
2202 scissor_new.xmin = rect.xmin;
2203 scissor_new.ymin = rect.ymin;
2204 scissor_new.xmax = rect.xmax;
2205 scissor_new.ymax = rect.ymax;
2206 const rcti scissor_region = {0, region->winx, 0, region->winy};
2207 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
2208 GPU_scissor(scissor_new.xmin,
2209 scissor_new.ymin,
2210 BLI_rcti_size_x(&scissor_new),
2211 BLI_rcti_size_y(&scissor_new));
2212
2213 if (scopes->track_disabled) {
2214 const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
2216 rctf disabled_rect{};
2217 disabled_rect.xmin = rect.xmin - 1;
2218 disabled_rect.xmax = rect.xmax + 1;
2219 disabled_rect.ymin = rect.ymin;
2220 disabled_rect.ymax = rect.ymax + 1;
2221 UI_draw_roundbox_4fv(&disabled_rect, true, 3.0f, color);
2222
2223 ok = true;
2224 }
2225 else if ((scopes->track_search) &&
2226 ((!scopes->track_preview) ||
2227 (scopes->track_preview->x != width || scopes->track_preview->y != height)))
2228 {
2229 if (scopes->track_preview) {
2231 }
2232
2234 scopes->frame_height,
2235 scopes->track_search,
2236 scopes->track,
2237 &scopes->undist_marker,
2238 true,
2239 scopes->use_track_mask,
2240 width,
2241 height,
2242 scopes->track_pos);
2243 if (tmpibuf) {
2244 if (tmpibuf->float_buffer.data) {
2245 IMB_byte_from_float(tmpibuf);
2246 }
2247
2248 if (tmpibuf->byte_buffer.data) {
2249 scopes->track_preview = tmpibuf;
2250 }
2251 else {
2252 IMB_freeImBuf(tmpibuf);
2253 }
2254 }
2255 }
2256
2257 if (!ok && scopes->track_preview) {
2259
2260 /* draw content of pattern area */
2261 GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
2262
2263 if (width > 0 && height > 0) {
2264 const ImBuf *drawibuf = scopes->track_preview;
2265 float col_sel[4], col_outline[4];
2266
2267 if (scopes->use_track_mask) {
2268 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2270 rctf mask_rect{};
2271 mask_rect.xmin = rect.xmin - 1;
2272 mask_rect.xmax = rect.xmax + 1;
2273 mask_rect.ymin = rect.ymin;
2274 mask_rect.ymax = rect.ymax + 1;
2275 UI_draw_roundbox_4fv(&mask_rect, true, 3.0f, color);
2276 }
2277
2280 rect.xmin,
2281 rect.ymin + 1,
2282 drawibuf->x,
2283 drawibuf->y,
2284 GPU_RGBA8,
2285 true,
2286 drawibuf->byte_buffer.data,
2287 1.0f,
2288 1.0f,
2289 nullptr);
2290
2291 /* draw cross for pixel position */
2292 GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
2293 GPU_scissor(rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect));
2294
2299
2302
2303 /* Do stipple cross with geometry */
2304 immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
2305 const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
2306 for (int axe = 0; axe < 2; axe++) {
2307 for (int i = 0; i < 7; i++) {
2308 const float x1 = pos_sel[i] * (1 - axe);
2309 const float y1 = pos_sel[i] * axe;
2310 const float x2 = pos_sel[i + 1] * (1 - axe);
2311 const float y2 = pos_sel[i + 1] * axe;
2312
2313 if (i % 2 == 1) {
2314 immAttr4fv(col, col_sel);
2315 }
2316 else {
2317 immAttr4fv(col, col_outline);
2318 }
2319
2320 immVertex2f(pos, x1, y1);
2321 immVertex2f(pos, x2, y2);
2322 }
2323 }
2324 immEnd();
2325
2327 }
2328
2330
2331 ok = true;
2332 }
2333
2334 if (!ok) {
2335 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2337 rctf box_rect{};
2338 box_rect.xmin = rect.xmin - 1;
2339 box_rect.xmax = rect.xmax + 1;
2340 box_rect.ymin = rect.ymin;
2341 box_rect.ymax = rect.ymax + 1;
2342 UI_draw_roundbox_4fv(&box_rect, true, 3.0f, color);
2343 }
2344
2345 /* Restore scissor test. */
2346 GPU_scissor(UNPACK4(scissor));
2347 /* outline */
2348 draw_scope_end(&rect);
2349
2351}
2352
2353/* ****************************************************** */
2354
2356 const rctf *rct, const float radius, const float width, const float aspect, const float alpha)
2357{
2358 if (width == 0.0f) {
2359 return;
2360 }
2361
2362 /* This undoes the scale of the view for higher zoom factors to clamp the shadow size. */
2363 const float clamped_aspect = smoothminf(aspect, 1.0f, 0.5f);
2364 const float shadow_width = width * clamped_aspect;
2365 const float shadow_offset = min_ff(shadow_width, BLI_rctf_size_y(rct) - 2.0f * radius);
2366
2367 const float inner_radius = max_ff(radius - U.pixelsize, 0.0);
2368 const float shadow_radius = radius + shadow_width - U.pixelsize;
2369
2371
2372 uiWidgetBaseParameters widget_params{};
2373 widget_params.recti.xmin = rct->xmin;
2374 widget_params.recti.ymin = rct->ymin;
2375 widget_params.recti.xmax = rct->xmax;
2376 widget_params.recti.ymax = rct->ymax;
2377 widget_params.rect.xmin = rct->xmin - shadow_width;
2378 widget_params.rect.ymin = rct->ymin - shadow_width;
2379 widget_params.rect.xmax = rct->xmax + shadow_width;
2380 widget_params.rect.ymax = rct->ymax + shadow_width - shadow_offset;
2381 widget_params.radi = inner_radius;
2382 widget_params.rad = shadow_radius;
2383 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
2384 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
2385 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
2386 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
2387 widget_params.alpha_discard = 1.0f;
2388
2389 blender::gpu::Batch *batch = ui_batch_roundbox_shadow_get();
2391 GPU_batch_uniform_4fv_array(batch, "parameters", 4, (const float(*)[4]) & widget_params);
2392 GPU_batch_uniform_1f(batch, "alpha", alpha);
2394
2396}
void immDrawPixelsTexTiled(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, eGPUTextureFormat gpu_format, bool use_filter, const void *rect, float xzoom, float yzoom, const float color[4])
Definition glutil.cc:329
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
Definition glutil.cc:36
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:395
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()
blender::ocio::Display ColorManagedDisplay
Definition BLF_api.hh:35
void BLF_batch_draw_flush()
Definition blf.cc:537
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:511
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])
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 rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
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
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
#define DEG2RADF(_deg)
#define M_PI_2
#define M_PI
void unit_m3(float m[3][3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void swap_v3_v3(float a[3], float b[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(dst, format,...)
Definition BLI_string.h:599
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
@ CUMA_SELECT
@ SCOPES_WAVEFRM_YCC_JPEG
@ SCOPES_WAVEFRM_RGB
@ SCOPES_WAVEFRM_YCC_601
@ SCOPES_WAVEFRM_YCC_709
@ SCOPES_WAVEFRM_LUMA
@ SCOPES_WAVEFRM_RGB_PARADE
@ 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
@ HD_FREE
@ HD_ALIGN
#define UI_SCALE_FAC
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
Definition gpu_batch.cc:51
#define GPU_batch_uniform_1f(batch, name, x)
Definition GPU_batch.hh:301
void GPU_batch_discard(blender::gpu::Batch *batch)
#define GPU_batch_uniformbuf_bind(batch, name, ubo)
Definition GPU_batch.hh:316
#define GPU_batch_uniform_4fv_array(batch, name, len, val)
Definition GPU_batch.hh:312
void GPU_batch_program_set_builtin(blender::gpu::Batch *batch, eGPUBuiltinShader shader_id)
void GPU_batch_draw(blender::gpu::Batch *batch)
#define GPU_batch_uniform_4f(batch, name, x, y, z, w)
Definition GPU_batch.hh:305
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:41
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 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 immAttr1f(uint attr_id, float x)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
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 immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
void immUniformColor3fv(const float rgb[3])
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_3D_POINT_VARYING_SIZE_VARYING_COLOR
@ 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_face_culling(eGPUFaceCullTest culling)
Definition gpu_state.cc:47
@ 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_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
@ GPU_CULL_NONE
Definition GPU_state.hh:136
@ GPU_CULL_BACK
Definition GPU_state.hh:138
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
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
@ GPU_RGBA8
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_free(GPUUniformBuf *ubo)
#define GPU_vertbuf_create_with_format(format)
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)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
uint GPU_vertformat_attr_add(GPUVertFormat *, blender::StringRef name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_U8
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)
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:777
Read Guarded memory(de)allocation.
#define UI_ALPHA_CHECKER_LIGHT
#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
@ TH_MARKER_OUTLINE
@ TH_PREVIEW_BACK
@ TH_SEL_MARKER
@ TH_TEXT
@ TH_TEXT_HI
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()
#define sinf(x)
#define cosf(x)
#define ceilf(x)
#define atanf(x)
#define floorf(x)
#define sqrtf(x)
#define str(s)
uint pos
struct @242053044010324116347033273112253060004051364061::@051143074301336237271216303350234260141112266062 batch
uint col
#define active
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
#define MEM_SAFE_FREE(v)
#define SCOPES_VEC_U_SCALE
#define SCOPES_VEC_V_SCALE
#define CM_TABLE
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 void gl_shaded_color_get_fl(const uchar *color, int shade, float r_color[3])
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 gl_shaded_color_get(const uchar color[3], int shade, uchar r_color[3])
static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth)
static void draw_scope_end(const rctf *rect)
static void gl_shaded_color(const uchar *color, int shade)
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)
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 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[4]
unsigned char outline[4]
unsigned char item[4]
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len
uint8_t flag
Definition wm_window.cc:139