Blender V4.3
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
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
47#include "UI_interface.hh"
48
49/* own include */
50#include "interface_intern.hh"
51
53
55{
56 /* Not sure the roundbox function is the best place to change this
57 * if this is undone, it's not that big a deal, only makes curves edges square. */
58 roundboxtype = type;
59}
60
61#if 0 /* unused */
62int UI_draw_roundbox_corner_get()
63{
64 return roundboxtype;
65}
66#endif
67
69 const float inner1[4],
70 const float inner2[4],
71 float shade_dir,
72 const float outline[4],
73 float outline_width,
74 float rad)
75{
76 /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
77 * If it has been scaled, then it's no longer valid. */
78 uiWidgetBaseParameters widget_params{};
79 widget_params.recti.xmin = rect->xmin + outline_width;
80 widget_params.recti.ymin = rect->ymin + outline_width;
81 widget_params.recti.xmax = rect->xmax - outline_width;
82 widget_params.recti.ymax = rect->ymax - outline_width;
83 widget_params.rect = *rect;
84 widget_params.radi = rad;
85 widget_params.rad = rad;
86 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
87 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
88 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
89 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
90 widget_params.color_inner1[0] = inner1 ? inner1[0] : 0.0f;
91 widget_params.color_inner1[1] = inner1 ? inner1[1] : 0.0f;
92 widget_params.color_inner1[2] = inner1 ? inner1[2] : 0.0f;
93 widget_params.color_inner1[3] = inner1 ? inner1[3] : 0.0f;
94 widget_params.color_inner2[0] = inner2 ? inner2[0] : inner1 ? inner1[0] : 0.0f;
95 widget_params.color_inner2[1] = inner2 ? inner2[1] : inner1 ? inner1[1] : 0.0f;
96 widget_params.color_inner2[2] = inner2 ? inner2[2] : inner1 ? inner1[2] : 0.0f;
97 widget_params.color_inner2[3] = inner2 ? inner2[3] : inner1 ? inner1[3] : 0.0f;
98 widget_params.color_outline[0] = outline ? outline[0] : inner1 ? inner1[0] : 0.0f;
99 widget_params.color_outline[1] = outline ? outline[1] : inner1 ? inner1[1] : 0.0f;
100 widget_params.color_outline[2] = outline ? outline[2] : inner1 ? inner1[2] : 0.0f;
101 widget_params.color_outline[3] = outline ? outline[3] : inner1 ? inner1[3] : 0.0f;
102 widget_params.shade_dir = shade_dir;
103 widget_params.alpha_discard = 1.0f;
104
105 blender::gpu::Batch *batch = ui_batch_roundbox_widget_get();
107 GPU_batch_uniform_4fv_array(batch, "parameters", 11, (const float(*)[4]) & widget_params);
111}
112
114 const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha)
115{
116 const float colv[4] = {
117 float(col[0]) / 255.0f,
118 float(col[1]) / 255.0f,
119 float(col[2]) / 255.0f,
120 float(alpha) / 255.0f,
121 };
122 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
123}
124
126 const rctf *rect, bool filled, float rad, const float col[3], float alpha)
127{
128 const float colv[4] = {col[0], col[1], col[2], alpha};
129 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
130}
131
132void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
133{
134 /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
135 * of the previous AA method. Better fix the callers. */
136 float colv[4] = {color[0], color[1], color[2], color[3]};
137 if (filled) {
138 colv[3] *= 0.65f;
139 }
140
141 UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad);
142}
143
144void UI_draw_roundbox_4fv(const rctf *rect, bool filled, float rad, const float col[4])
145{
146 /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
147 UI_draw_roundbox_4fv_ex(rect, (filled) ? col : nullptr, nullptr, 1.0f, col, U.pixelsize, rad);
148}
149
151 const float rad,
152 const blender::float4 color)
153{
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
225 immUniformColor4fv(color);
226
227 immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
229}
230
231/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
232
234 float rad,
235 uchar highlight[3],
236 uchar highlight_fade[3])
237{
242 /* add a 1px offset, looks nicer */
243 const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
244 const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
245 int a;
246 float vec[4][2] = {
247 {0.195, 0.02},
248 {0.55, 0.169},
249 {0.831, 0.45},
250 {0.98, 0.805},
251 };
252
253 /* Multiply. */
254 for (a = 0; a < 4; a++) {
255 mul_v2_fl(vec[a], rad);
256 }
257
260
261 immAttr3ubv(col, highlight);
262
263 /* start with corner left-top */
265 immVertex2f(pos, minx, maxy - rad);
266 for (a = 0; a < 4; a++) {
267 immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
268 }
269 immVertex2f(pos, minx + rad, maxy);
270 }
271 else {
272 immVertex2f(pos, minx, maxy);
273 }
274
275 /* corner right-top */
277 immVertex2f(pos, maxx - rad, maxy);
278 for (a = 0; a < 4; a++) {
279 immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
280 }
281 immVertex2f(pos, maxx, maxy - rad);
282 }
283 else {
284 immVertex2f(pos, maxx, maxy);
285 }
286
287 immAttr3ubv(col, highlight_fade);
288
289 /* corner right-bottom */
291 immVertex2f(pos, maxx, miny + rad);
292 for (a = 0; a < 4; a++) {
293 immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
294 }
295 immVertex2f(pos, maxx - rad, miny);
296 }
297 else {
298 immVertex2f(pos, maxx, miny);
299 }
300
301 /* corner left-bottom */
303 immVertex2f(pos, minx + rad, miny);
304 for (a = 0; a < 4; a++) {
305 immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
306 }
307 immVertex2f(pos, minx, miny + rad);
308 }
309 else {
310 immVertex2f(pos, minx, miny);
311 }
312
313 immAttr3ubv(col, highlight);
314
315 /* back to corner left-top */
316 immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);
317
318 immEnd();
320}
321
322void ui_draw_but_IMAGE(ARegion * /*region*/,
323 uiBut *but,
324 const uiWidgetColors * /*wcol*/,
325 const rcti *rect)
326{
327#ifdef WITH_HEADLESS
328 (void)rect;
329 (void)but;
330#else
331 ImBuf *ibuf = (ImBuf *)but->poin;
332
333 if (!ibuf) {
334 return;
335 }
336
337 const int w = BLI_rcti_size_x(rect);
338 const int h = BLI_rcti_size_y(rect);
339
340 /* scissor doesn't seem to be doing the right thing...? */
341# if 0
342 /* prevent drawing outside widget area */
343 int scissor[4];
344 GPU_scissor_get(scissor);
345 GPU_scissor(rect->xmin, rect->ymin, w, h);
346# endif
347
348 /* Combine with premultiplied alpha. */
350
351 if (w != ibuf->x || h != ibuf->y) {
352 /* We scale the bitmap, rather than have OGL do a worse job. */
353 IMB_scale(ibuf, w, h, IMBScaleFilter::Box, false);
354 }
355
356 float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
357 if (but->col[3] != 0) {
358 /* Optionally use uiBut's col to recolor the image. */
360 }
361
364 float(rect->xmin),
365 float(rect->ymin),
366 ibuf->x,
367 ibuf->y,
368 GPU_RGBA8,
369 false,
370 ibuf->byte_buffer.data,
371 1.0f,
372 1.0f,
373 col);
374
376
377# if 0
378 /* Restore scissor-test. */
379 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
380# endif
381
382#endif
383}
384
386 const rctf *rect,
387 const float title_aspect[2],
388 const float action_aspect[2])
389{
390 const float size_x_half = (rect->xmax - rect->xmin) * 0.5f;
391 const float size_y_half = (rect->ymax - rect->ymin) * 0.5f;
392
393 const float *safe_areas[] = {title_aspect, action_aspect};
394 const int safe_len = ARRAY_SIZE(safe_areas);
395
396 for (int i = 0; i < safe_len; i++) {
397 if (safe_areas[i][0] || safe_areas[i][1]) {
398 const float margin_x = safe_areas[i][0] * size_x_half;
399 const float margin_y = safe_areas[i][1] * size_y_half;
400
401 const float minx = rect->xmin + margin_x;
402 const float miny = rect->ymin + margin_y;
403 const float maxx = rect->xmax - margin_x;
404 const float maxy = rect->ymax - margin_y;
405
406 imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
407 }
408 }
409}
410
411static void draw_scope_end(const rctf *rect)
412{
414
415 /* outline */
417 const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
418 rctf box_rect{};
419 box_rect.xmin = rect->xmin - 1;
420 box_rect.xmax = rect->xmax + 1;
421 box_rect.ymin = rect->ymin;
422 box_rect.ymax = rect->ymax + 1;
423 UI_draw_roundbox_4fv(&box_rect, false, 3.0f, color);
424}
425
426static void histogram_draw_one(float r,
427 float g,
428 float b,
429 float alpha,
430 float x,
431 float y,
432 float w,
433 float h,
434 const float *data,
435 int res,
436 const bool is_line,
437 uint pos_attr)
438{
439 const float color[4] = {r, g, b, alpha};
440
441 /* that can happen */
442 if (res == 0) {
443 return;
444 }
445
446 GPU_line_smooth(true);
448
449 immUniformColor4fv(color);
450
451 if (is_line) {
452 /* curve outline */
453 GPU_line_width(1.5);
454
456 for (int i = 0; i < res; i++) {
457 const float x2 = x + i * (w / float(res));
458 immVertex2f(pos_attr, x2, y + (data[i] * h));
459 }
460 immEnd();
461
462 GPU_line_width(1.0f);
463 }
464 else {
465 /* under the curve */
467 immVertex2f(pos_attr, x, y);
468 immVertex2f(pos_attr, x, y + (data[0] * h));
469 for (int i = 1; i < res; i++) {
470 const float x2 = x + i * (w / float(res));
471 immVertex2f(pos_attr, x2, y + (data[i] * h));
472 immVertex2f(pos_attr, x2, y);
473 }
474 immEnd();
475
476 /* curve outline */
477 immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
478
481 for (int i = 0; i < res; i++) {
482 const float x2 = x + i * (w / float(res));
483 immVertex2f(pos_attr, x2, y + (data[i] * h));
484 }
485 immEnd();
486 }
487
488 GPU_line_smooth(false);
489}
490
491#define HISTOGRAM_TOT_GRID_LINES 4
492
494 uiBut *but,
495 const uiWidgetColors * /*wcol*/,
496 const rcti *recti)
497{
498 Histogram *hist = (Histogram *)but->poin;
499 const int res = hist->x_resolution;
500 const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
501
502 rctf rect{};
503 rect.xmin = float(recti->xmin + 1);
504 rect.xmax = float(recti->xmax - 1);
505 rect.ymin = float(recti->ymin + 1);
506 rect.ymax = float(recti->ymax - 1);
507
508 const float w = BLI_rctf_size_x(&rect);
509 const float h = BLI_rctf_size_y(&rect) * hist->ymax;
510
512
513 float color[4];
516 rctf back_rect{};
517 back_rect.xmin = rect.xmin - 1;
518 back_rect.xmax = rect.xmax + 1;
519 back_rect.ymin = rect.ymin - 1;
520 back_rect.ymax = rect.ymax + 1;
521
522 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
523
524 /* need scissor test, histogram can draw outside of boundary */
525 int scissor[4];
526 GPU_scissor_get(scissor);
527 GPU_scissor((rect.xmin - 1),
528 (rect.ymin - 1),
529 (rect.xmax + 1) - (rect.xmin - 1),
530 (rect.ymax + 1) - (rect.ymin - 1));
531
534
536
537 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
538 /* draw grid lines here */
539 for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
540 const float fac = float(i) / float(HISTOGRAM_TOT_GRID_LINES);
541
542 /* so we can tell the 1.0 color point */
543 if (i == HISTOGRAM_TOT_GRID_LINES) {
544 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
545 }
546
548
549 immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
550 immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
551
552 immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
553 immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
554
555 immEnd();
556 }
557
558 if (hist->mode == HISTO_MODE_LUMA) {
560 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
561 }
562 else if (hist->mode == HISTO_MODE_ALPHA) {
564 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
565 }
566 else {
567 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_R)) {
569 1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
570 }
571 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_G)) {
573 0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
574 }
575 if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_B)) {
577 0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
578 }
579 }
580
582
583 /* Restore scissor test. */
584 GPU_scissor(UNPACK4(scissor));
585
586 /* outline */
587 draw_scope_end(&rect);
588}
589
590#undef HISTOGRAM_TOT_GRID_LINES
591
592static void waveform_draw_one(const float *waveform, int waveform_num, const float col[3])
593{
594 GPUVertFormat format = {0};
596
598 GPU_vertbuf_data_alloc(*vbo, waveform_num);
599
600 GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
601
602 /* TODO: store the #blender::gpu::Batch inside the scope. */
603 blender::gpu::Batch *batch = GPU_batch_create_ex(
604 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
606 GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
608
610}
611
616static_assert(sizeof(WaveformColorVertex) == 24);
617
618static void waveform_draw_rgb(const float *waveform,
619 int waveform_num,
620 const float *col,
621 float alpha)
622{
623 GPUVertFormat format = {0};
626
628
629 GPU_vertbuf_data_alloc(*vbo, waveform_num);
631 for (int i = 0; i < waveform_num; i++) {
632 memcpy(&data->pos, waveform, sizeof(data->pos));
633 memcpy(&data->color, col, sizeof(float) * 3);
634 data->color.w = alpha;
635 waveform += 2;
636 col += 3;
637 data++;
638 }
640 GPU_vertbuf_use(vbo);
641
642 blender::gpu::Batch *batch = GPU_batch_create_ex(
643 GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
644
648}
649
650static void circle_draw_rgb(float *points, int tot_points, const float *col, GPUPrimType prim)
651{
652 GPUVertFormat format = {0};
654 const uint col_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
655
657
658 GPU_vertbuf_data_alloc(*vbo, tot_points);
659 GPU_vertbuf_attr_fill(vbo, pos_id, points);
660 GPU_vertbuf_attr_fill(vbo, col_id, col);
661
662 blender::gpu::Batch *batch = GPU_batch_create_ex(prim, vbo, nullptr, GPU_BATCH_OWNS_VBO);
663
667}
668
670 uiBut *but,
671 const uiWidgetColors * /*wcol*/,
672 const rcti *recti)
673{
674 Scopes *scopes = (Scopes *)but->poin;
675 int scissor[4];
676 float colors[3][3];
677 const float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
678 /* Colors pre-multiplied by alpha for speed up. */
679 float colors_alpha[3][3], colorsycc_alpha[3][3];
680 float min, max;
681
682 if (scopes == nullptr) {
683 return;
684 }
685
686 rctf rect{};
687 rect.xmin = float(recti->xmin + 1);
688 rect.xmax = float(recti->xmax - 1);
689 rect.ymin = float(recti->ymin + 1);
690 rect.ymax = float(recti->ymax - 1);
691
692 if (scopes->wavefrm_yfac < 0.5f) {
693 scopes->wavefrm_yfac = 0.98f;
694 }
695 const float w = BLI_rctf_size_x(&rect) - 7;
696 const float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
697 const float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
698 const float w3 = w / 3.0f;
699
700 /* log scale for alpha */
701 const float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
702
703 unit_m3(colors);
704
705 for (int c = 0; c < 3; c++) {
706 for (int i = 0; i < 3; i++) {
707 colors_alpha[c][i] = colors[c][i] * alpha;
708 colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
709 }
710 }
711
712 /* Flush text cache before changing scissors. */
714
716
717 float color[4];
720 rctf back_rect{};
721 back_rect.xmin = rect.xmin - 1.0f;
722 back_rect.xmax = rect.xmax + 1.0f;
723 back_rect.ymin = rect.ymin - 1.0f;
724 back_rect.ymax = rect.ymax + 1.0f;
725 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
726
727 /* need scissor test, waveform can draw outside of boundary */
728 GPU_scissor_get(scissor);
729 GPU_scissor((rect.xmin - 1),
730 (rect.ymin - 1),
731 (rect.xmax + 1) - (rect.xmin - 1),
732 (rect.ymax + 1) - (rect.ymin - 1));
733
734 /* draw scale numbers first before binding any shader */
735 for (int i = 0; i < 6; i++) {
736 char str[4];
737 SNPRINTF(str, "%-3d", i * 20);
738 str[3] = '\0';
739 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
740 BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
741 }
742
743 /* Flush text cache before drawing things on top. */
745
748
750
751 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
752
753 /* draw grid lines here */
755
756 for (int i = 0; i < 6; i++) {
757 immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
758 immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
759 }
760
761 immEnd();
762
763 /* 3 vertical separation */
764 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
766
767 for (int i = 1; i < 3; i++) {
768 immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
769 immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
770 }
771
772 immEnd();
773 }
774
775 /* separate min max zone on the right */
777 immVertex2f(pos, rect.xmin + w, rect.ymin);
778 immVertex2f(pos, rect.xmin + w, rect.ymax);
779 immEnd();
780
781 /* 16-235-240 level in case of ITU-R BT601/709 */
782 immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
785
786 immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
787 immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
788
789 immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
790 immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
791
792 immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
793 immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
794
795 immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
796 immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
797
798 immEnd();
799 }
800 /* 7.5 IRE black point level for NTSC */
801 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
803 immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
804 immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
805 immEnd();
806 }
807
808 if (scopes->ok && scopes->waveform_1 != nullptr) {
810 GPU_point_size(1.0);
811
812 /* LUMA (1 channel) */
813 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
814 const float col[3] = {alpha, alpha, alpha};
815
817 GPU_matrix_translate_2f(rect.xmin, yofs);
819
820 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
821
823
824 /* min max */
825 immUniformColor3f(0.5f, 0.5f, 0.5f);
826 min = yofs + scopes->minmax[0][0] * h;
827 max = yofs + scopes->minmax[0][1] * h;
828 CLAMP(min, rect.ymin, rect.ymax);
829 CLAMP(max, rect.ymin, rect.ymax);
830
832 immVertex2f(pos, rect.xmax - 3, min);
833 immVertex2f(pos, rect.xmax - 3, max);
834 immEnd();
835 }
836 /* RGB (3 channel) */
837 else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
839 GPU_matrix_translate_2f(rect.xmin, yofs);
841
842 waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
843 waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
844 waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
845
847 }
848 /* PARADE / YCC (3 channels) */
849 else if (ELEM(scopes->wavefrm_mode,
854 {
855 const int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
856
858 GPU_matrix_translate_2f(rect.xmin, yofs);
859 GPU_matrix_scale_2f(w3, h);
860
862 scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
863
864 GPU_matrix_translate_2f(1.0f, 0.0f);
866 scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
867
868 GPU_matrix_translate_2f(1.0f, 0.0f);
870 scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
871
873 }
874
875 /* min max */
876 if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
877 for (int c = 0; c < 3; c++) {
879 immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
880 }
881 else {
883 colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
884 }
885 min = yofs + scopes->minmax[c][0] * h;
886 max = yofs + scopes->minmax[c][1] * h;
887 CLAMP(min, rect.ymin, rect.ymax);
888 CLAMP(max, rect.ymin, rect.ymax);
889
891 immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
892 immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
893 immEnd();
894 }
895 }
896 }
897
899
900 /* Restore scissor test. */
901 GPU_scissor(UNPACK4(scissor));
902
903 /* outline */
904 draw_scope_end(&rect);
905
907}
908
909static float polar_to_x(float center, float diam, float ampli, float angle)
910{
911 return center + diam * ampli * cosf(angle);
912}
913
914static float polar_to_y(float center, float diam, float ampli, float angle)
915{
916 return center + diam * ampli * sinf(angle);
917}
918
920 uint pos, float centerx, float centery, float diam, const float colf[3], char label)
921{
922 float y, u, v;
923 float tangle = 0.0f, tampli;
924 float dangle, dampli;
925 const char labelstr[2] = {label, '\0'};
926
927 rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
928
929 if (u > 0 && v >= 0) {
930 tangle = atanf(v / u);
931 }
932 else if (u > 0 && v < 0) {
933 tangle = atanf(v / u) + 2.0f * float(M_PI);
934 }
935 else if (u < 0) {
936 tangle = atanf(v / u) + float(M_PI);
937 }
938 else if (u == 0 && v > 0.0f) {
939 tangle = M_PI_2;
940 }
941 else if (u == 0 && v < 0.0f) {
942 tangle = -M_PI_2;
943 }
944 tampli = sqrtf(u * u + v * v);
945
946 /* small target vary by 2.5 degree and 2.5 IRE unit */
947 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
948 dangle = DEG2RADF(2.5f);
949 dampli = 2.5f / 200.0f;
952 polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
953 polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
955 polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
956 polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
958 polar_to_x(centerx, diam, tampli - dampli, tangle - dangle),
959 polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
961 polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
962 polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
963
964 /* draw color letter as text */
965 BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.3f);
966 BLF_draw_default(polar_to_x(centerx, diam, tampli, tangle) + 5,
967 polar_to_y(centery, diam, tampli, tangle),
968 0,
969 labelstr,
970 strlen(labelstr));
971
972 immEnd();
973}
974
976 uiBut *but,
977 const uiWidgetColors * /*wcol*/,
978 const rcti *recti)
979{
980 const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
981 Scopes *scopes = (Scopes *)but->poin;
982
983 const float colors[6][3] = {
984 {0.75, 0.0, 0.0}, /* Red */
985 {0.75, 0.75, 0.0}, /* Yellow */
986 {0.0, 0.75, 0.0}, /* Green */
987 {0.0, 0.75, 0.75}, /* Cyan */
988 {0.0, 0.0, 0.75}, /* Blue */
989 {0.75, 0.0, 0.75}, /* Magenta */
990 };
991
992 const char color_names[] = {'R', 'Y', 'G', 'C', 'B', 'M'};
993
994 rctf rect{};
995 rect.xmin = float(recti->xmin + 1);
996 rect.xmax = float(recti->xmax - 1);
997 rect.ymin = float(recti->ymin + 1);
998 rect.ymax = float(recti->ymax - 1);
999
1000 const float w = BLI_rctf_size_x(&rect);
1001 const float h = BLI_rctf_size_y(&rect);
1002 const float centerx = rect.xmin + w * 0.5f;
1003 const float centery = rect.ymin + h * 0.5f;
1004 const float diam = (w < h) ? w : h;
1005
1006 const float alpha = scopes->vecscope_alpha;
1007
1008 GPU_line_smooth(true);
1010
1011 float color[4];
1014 rctf back_rect{};
1015 back_rect.xmin = rect.xmin - 1;
1016 back_rect.xmax = rect.xmax + 1;
1017 back_rect.ymin = rect.ymin - 1;
1018 back_rect.ymax = rect.ymax + 1;
1019 UI_draw_roundbox_4fv(&back_rect, true, 3.0f, color);
1020
1021 /* need scissor test, hvectorscope can draw outside of boundary */
1022 int scissor[4];
1023 GPU_scissor_get(scissor);
1024 GPU_scissor((rect.xmin - 1),
1025 (rect.ymin - 1),
1026 (rect.xmax + 1) - (rect.xmin - 1),
1027 (rect.ymax + 1) - (rect.ymin - 1));
1028
1031
1033 const int increment = 6;
1034 const int tot_points = int(360 / increment);
1035 const float r = 0.5f;
1036 float step = 360.0f / (tot_points - 1);
1037
1038 float circle_fill_points[(tot_points * 2) + 2];
1039 float circle_fill_vertex_colors[(tot_points * 4) + 4];
1040
1041 /* draw filled RGB circle for background, only for LUMA mode */
1042 if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1043 /* Initialize center point and color */
1044 circle_fill_points[0] = centerx;
1045 circle_fill_points[1] = centery;
1046 circle_fill_vertex_colors[0] = 0.2f;
1047 circle_fill_vertex_colors[1] = 0.2f;
1048 circle_fill_vertex_colors[2] = 0.2f;
1049 circle_fill_vertex_colors[3] = 0.8f;
1050
1051 for (int i = 0; i < tot_points; i++) {
1052 float angle = step * i;
1053 const float a = DEG2RADF(angle);
1054
1055 const float x = polar_to_x(centerx, diam, r, a);
1056 const float y = polar_to_y(centery, diam, r, a);
1057
1058 const float u = polar_to_x(0.0f, 1.0, 1.0f, a);
1059 const float v = polar_to_y(0.0f, 1.0, 1.0f, a);
1060
1061 circle_fill_points[(i + 1) * 2] = x;
1062 circle_fill_points[(i + 1) * 2 + 1] = y;
1063
1064 float r, g, b;
1065 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1066
1067 circle_fill_vertex_colors[(i + 1) * 4] = r * 0.2f;
1068 circle_fill_vertex_colors[(i + 1) * 4 + 1] = g * 0.2f;
1069 circle_fill_vertex_colors[(i + 1) * 4 + 2] = b * 0.2f;
1070 circle_fill_vertex_colors[(i + 1) * 4 + 3] = 0.8f;
1071 }
1072
1075 circle_fill_points, tot_points + 1, circle_fill_vertex_colors, GPU_PRIM_TRI_FAN);
1076 }
1077 /* draw filled Gray circle for background, only for RGB mode */
1078 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1080 immBegin(GPU_PRIM_TRI_FAN, tot_points + 2);
1081 immUniformColor3f(0.16f, 0.16f, 0.16f);
1082 immVertex2f(pos, centerx, centery);
1083
1084 for (int i = 0; i <= 360; i += increment) {
1085 const float a = DEG2RADF(float(i));
1086 immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
1087 }
1088 immEnd();
1089 }
1090
1091 /* draw RGB ring */
1092 float circle_points[(tot_points * 2) + 3] = {};
1093 float circle_vertex_colors[(tot_points * 4) + 5] = {};
1094
1095 for (int i = 0; i < tot_points; i++) {
1096 float angle = step * i;
1097 const float a = DEG2RADF(angle);
1098
1099 const float x = polar_to_x(centerx, diam, 0.5f, a);
1100 const float y = polar_to_y(centery, diam, 0.5f, a);
1101 circle_points[i * 2] = x;
1102 circle_points[i * 2 + 1] = y;
1103
1104 const float u = polar_to_x(0.0f, 1.0, 1.0f, a);
1105 const float v = polar_to_y(0.0f, 1.0, 1.0f, a);
1106 float r, g, b;
1107 yuv_to_rgb(0.5f, u, v, &r, &g, &b, BLI_YUV_ITU_BT709);
1108
1109 circle_vertex_colors[i * 4] = r;
1110 circle_vertex_colors[i * 4 + 1] = g;
1111 circle_vertex_colors[i * 4 + 2] = b;
1112 circle_vertex_colors[i * 4 + 3] = 0.8f;
1113 }
1114
1116 GPU_line_width(2.5f);
1117 circle_draw_rgb(circle_points, tot_points, circle_vertex_colors, GPU_PRIM_LINE_LOOP);
1118 GPU_line_width(1.5f);
1119
1120 /* inner circles */
1122 for (int j = 0; j < 4; j++) {
1123 float inner_circle_points[(tot_points * 2) + 3] = {};
1124 float inner_circle_colors[(tot_points * 4) + 5] = {};
1125 const float r = (j + 1) * 0.1f;
1126
1127 for (int i = 0; i < tot_points; i++) {
1128 float angle = step * i;
1129 const float a = DEG2RADF(angle);
1130
1131 inner_circle_points[i * 2] = polar_to_x(centerx, diam, r, a);
1132 inner_circle_points[i * 2 + 1] = polar_to_y(centery, diam, r, a);
1133
1134 inner_circle_colors[i * 4] = 0.1f;
1135 inner_circle_colors[i * 4 + 1] = 0.1f;
1136 inner_circle_colors[i * 4 + 2] = 0.1f;
1137 inner_circle_colors[i * 4 + 3] = 0.8f;
1138 }
1139 circle_draw_rgb(inner_circle_points, tot_points, inner_circle_colors, GPU_PRIM_LINE_LOOP);
1140 }
1141
1142 /* draw grid elements */
1143 /* cross */
1144 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.1f);
1146
1147 immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
1148 immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
1149
1150 immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
1151 immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
1152
1153 immEnd();
1154
1155 /* skin tone line */
1157 immUniformColor3f(0.25f, 0.25f, 0.25f);
1158
1161 pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
1163 pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
1164 immEnd();
1165
1166 /* saturation points */
1167 for (int i = 0; i < 6; i++) {
1168 vectorscope_draw_target(pos, centerx, centery, diam, colors[i], color_names[i]);
1169 }
1170
1171 if (scopes->ok && scopes->vecscope != nullptr) {
1172 /* pixel point cloud */
1173 GPU_point_size(1.0);
1174
1176 GPU_matrix_translate_2f(centerx, centery);
1177 GPU_matrix_scale_1f(diam);
1178
1179 const float col[3] = {alpha, alpha, alpha};
1180 if (scopes->vecscope_mode == SCOPES_VECSCOPE_RGB) {
1182 waveform_draw_rgb(scopes->vecscope, scopes->waveform_tot, scopes->vecscope_rgb, alpha);
1183 }
1184 else if (scopes->vecscope_mode == SCOPES_VECSCOPE_LUMA) {
1186 waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
1187 }
1188
1190 }
1191
1193
1194 /* Restore scissor test. */
1195 GPU_scissor(UNPACK4(scissor));
1196 /* outline */
1197 draw_scope_end(&rect);
1198
1200}
1201
1202static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth)
1203{
1204 /* Half-width equals height for better AA with 45 degree slope. */
1206 immVertex2f(pos, x1 + halfwidth, y1);
1207 immVertex2f(pos, x1, y1 + halfwidth);
1208 immVertex2f(pos, x1 - halfwidth, y1);
1209 immEnd();
1210}
1211
1212static void ui_draw_colorband_handle_box(uint pos, float x1, float y1, float x2, float y2)
1213{
1215 immVertex2f(pos, x2, y1);
1216 immVertex2f(pos, x1, y1);
1217 immVertex2f(pos, x2, y2);
1218 immVertex2f(pos, x1, y2);
1219 immEnd();
1220}
1221
1222static void ui_draw_colorband_handle(uint shdr_pos,
1223 const rcti *rect,
1224 float x,
1225 const float rgb[3],
1226 ColorManagedDisplay *display,
1227 bool active)
1228{
1229 const float sizey = BLI_rcti_size_y(rect);
1230 float colf[3] = {UNPACK3(rgb)};
1231
1232 const float half_width = sizey / 3.5f;
1233 const float height = half_width * 1.4f;
1234
1235 float y1 = rect->ymin;
1236 const float y2 = rect->ymax;
1237
1238 /* align to pixels */
1239 x = floorf(x);
1240
1242
1243 /* Allow the lines to decrease as we get really small. */
1244 float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize),
1245 0.5f);
1246
1247 /* Make things transparent as we get tiny. */
1248 uchar alpha = std::min(int(fabs(half_width - 2.0f) * 50.0f), 255);
1249
1251
1252 float viewport_size[4];
1253 GPU_viewport_size_get_f(viewport_size);
1254 immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
1255 immUniform1i("colors_len", 2); /* "advanced" mode */
1256 if (active) {
1257 immUniform4f("color", 1.0f, 1.0f, 1.0f, alpha / 255.0f);
1258 immUniform4f("color2", 0.0f, 0.0f, 0.0f, alpha / 255.0f);
1259 }
1260 else {
1261 immUniform4f("color", 0.7f, 0.7f, 0.7f, alpha / 255.0f);
1262 immUniform4f("color2", 0.4f, 0.4f, 0.4f, alpha / 255.0f);
1263 }
1264 immUniform1f("dash_width", sizey / 6.0f / UI_SCALE_FAC);
1265 immUniform1f("udash_factor", 0.5f);
1266
1268 immVertex2f(shdr_pos, x, y1);
1269 immVertex2f(shdr_pos, x, y2);
1270 immEnd();
1271
1273
1275
1276 /* shift handle down */
1277 y1 -= half_width / 2.0f;
1278
1279 /* Black outline around the lower box. */
1280 immUniformColor4ub(0, 0, 0, alpha);
1281
1283 x - half_width - line_width,
1284 y1 - line_width,
1285 x + half_width + line_width,
1286 y1 + height);
1287
1288 /* Grey box, inset by line width. */
1289 immUniformColor4ub(128, 128, 128, alpha);
1290 ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1, x + half_width, y1 + height);
1291
1292 if (display) {
1294 }
1295
1296 /* Color value, inset by another line width. */
1297 immUniformColor3fvAlpha(colf, alpha);
1299 x - (half_width - line_width),
1300 y1 + line_width,
1301 x + (half_width - line_width),
1302 y1 + height - line_width);
1303
1304 /* Black outline around the top triangle. */
1305 immUniformColor4ub(0, 0, 0, alpha);
1306 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width + line_width);
1307
1308 GPU_polygon_smooth(true);
1309
1310 /* Triangle main color. */
1311 if (active) {
1312 immUniformColor4ub(220, 220, 220, alpha);
1313 }
1314 else {
1315 immUniformColor4ub(96, 96, 96, alpha);
1316 }
1317 ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width - (0.5f * line_width));
1318
1320
1321 GPU_polygon_smooth(false);
1323}
1324
1325void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1326{
1328 uint pos_id, col_id;
1329
1330 uiButColorBand *but_coba = (uiButColorBand *)but;
1331 ColorBand *coba = (but_coba->edit_coba == nullptr) ? (ColorBand *)but->poin :
1332 but_coba->edit_coba;
1333
1334 if (coba == nullptr) {
1335 return;
1336 }
1337
1338 const float x1 = rect->xmin + U.pixelsize;
1339 const float sizex = rect->xmax - x1 - U.pixelsize;
1340 const float y1 = rect->ymin + U.pixelsize;
1341 const float sizey = rect->ymax - y1 - U.pixelsize;
1342 const float sizey_solid = sizey * 0.25f;
1343
1344 /* exit early if too narrow */
1345 if (sizex <= 0) {
1346 return;
1347 }
1348
1350
1351 /* Line width outline. */
1357 immVertex2f(pos_id, rect->xmin, rect->ymin);
1358 immVertex2f(pos_id, rect->xmax, rect->ymin);
1359 immVertex2f(pos_id, rect->xmin, rect->ymax);
1360 immVertex2f(pos_id, rect->xmax, rect->ymax);
1361 immEnd();
1363
1364 /* Drawing the checkerboard. */
1366 const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f;
1367 const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f;
1368 immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f);
1369 immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f);
1370 immUniform1i("size", 8);
1371 immRectf(pos_id, x1, y1, x1 + sizex, y1 + sizey);
1373
1374 /* New format */
1379
1380 CBData *cbd = coba->data;
1381
1382 float v1[2], v2[2];
1383 float colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
1384
1385 v1[1] = y1 + sizey_solid;
1386 v2[1] = y1 + sizey;
1387
1388 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1389 for (int a = 0; a <= sizex; a++) {
1390 const float pos = float(a) / sizex;
1391 BKE_colorband_evaluate(coba, pos, colf);
1392 if (display) {
1394 }
1395
1396 v1[0] = v2[0] = x1 + a;
1397
1398 immAttr4fv(col_id, colf);
1399 immVertex2fv(pos_id, v1);
1400 immVertex2fv(pos_id, v2);
1401 }
1402 immEnd();
1403
1404 /* layer: color ramp without alpha for reference when manipulating ramp properties */
1405 v1[1] = y1;
1406 v2[1] = y1 + sizey_solid;
1407
1408 immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
1409 for (int a = 0; a <= sizex; a++) {
1410 const float pos = float(a) / sizex;
1411 BKE_colorband_evaluate(coba, pos, colf);
1412 if (display) {
1414 }
1415
1416 v1[0] = v2[0] = x1 + a;
1417
1418 immAttr4f(col_id, colf[0], colf[1], colf[2], 1.0f);
1419 immVertex2fv(pos_id, v1);
1420 immVertex2fv(pos_id, v2);
1421 }
1422 immEnd();
1423
1425
1426 /* New format */
1429
1430 /* layer: draw handles */
1431 for (int a = 0; a < coba->tot; a++, cbd++) {
1432 if (a != coba->cur) {
1433 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1434 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false);
1435 }
1436 }
1437
1438 /* layer: active handle */
1439 if (coba->tot != 0) {
1440 cbd = &coba->data[coba->cur];
1441 const float pos = x1 + cbd->pos * (sizex - 1) + 1;
1442 ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true);
1443 }
1444}
1445
1447 const uiWidgetColors *wcol,
1448 const rcti *rect,
1449 const float radius)
1450{
1451 /* sphere color */
1452 const float diffuse[3] = {1.0f, 1.0f, 1.0f};
1453 float light[3];
1454 const float size = 0.5f * min_ff(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
1455
1456 /* backdrop */
1458 rctf box_rect{};
1459 box_rect.xmin = rect->xmin;
1460 box_rect.xmax = rect->xmax;
1461 box_rect.ymin = rect->ymin;
1462 box_rect.ymax = rect->ymax;
1463 UI_draw_roundbox_3ub_alpha(&box_rect, true, radius, wcol->inner, 255);
1464
1466
1467 /* setup lights */
1468 ui_but_v3_get(but, light);
1469
1470 /* transform to button */
1472
1473 const bool use_project_matrix = (size >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT);
1474 if (use_project_matrix) {
1476 GPU_matrix_ortho_set_z(-size, size);
1477 }
1478
1479 GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect),
1480 rect->ymin + 0.5f * BLI_rcti_size_y(rect));
1481 GPU_matrix_scale_1f(size);
1482
1483 blender::gpu::Batch *sphere = GPU_batch_preset_sphere(2);
1484 SimpleLightingData simple_lighting_data;
1485 copy_v4_fl4(simple_lighting_data.l_color, diffuse[0], diffuse[1], diffuse[2], 1.0f);
1486 copy_v3_v3(simple_lighting_data.light, light);
1487 GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(
1488 sizeof(SimpleLightingData), &simple_lighting_data, __func__);
1489
1491 GPU_batch_uniformbuf_bind(sphere, "simple_lighting_data", ubo);
1492 GPU_batch_draw(sphere);
1494
1495 /* Restore. */
1497
1498 /* AA circle */
1503
1505 GPU_line_smooth(true);
1506 imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
1508 GPU_line_smooth(false);
1509
1510 if (use_project_matrix) {
1512 }
1513
1514 /* matrix after circle */
1516
1518}
1519
1521 const rcti *rect,
1522 const float zoom_x,
1523 const float zoom_y,
1524 const float offset_x,
1525 const float offset_y,
1526 const float step)
1527{
1528 const float start_x = (ceilf(offset_x / step) * step - offset_x) * zoom_x + rect->xmin;
1529 const float start_y = (ceilf(offset_y / step) * step - offset_y) * zoom_y + rect->ymin;
1530
1531 const int line_count_x = ceilf((rect->xmax - start_x) / (step * zoom_x));
1532 const int line_count_y = ceilf((rect->ymax - start_y) / (step * zoom_y));
1533
1534 if (line_count_x + line_count_y == 0) {
1535 return;
1536 }
1537
1538 immBegin(GPU_PRIM_LINES, (line_count_x + line_count_y) * 2);
1539 for (int i = 0; i < line_count_x; i++) {
1540 const float x = start_x + i * step * zoom_x;
1541 immVertex2f(pos, x, rect->ymin);
1542 immVertex2f(pos, x, rect->ymax);
1543 }
1544 for (int i = 0; i < line_count_y; i++) {
1545 const float y = start_y + i * step * zoom_y;
1546 immVertex2f(pos, rect->xmin, y);
1547 immVertex2f(pos, rect->xmax, y);
1548 }
1549 immEnd();
1550}
1551
1552static void gl_shaded_color_get(const uchar color[3], int shade, uchar r_color[3])
1553{
1554 r_color[0] = color[0] - shade > 0 ? color[0] - shade : 0;
1555 r_color[1] = color[1] - shade > 0 ? color[1] - shade : 0;
1556 r_color[2] = color[2] - shade > 0 ? color[2] - shade : 0;
1557}
1558
1559static void gl_shaded_color_get_fl(const uchar *color, int shade, float r_color[3])
1560{
1561 uchar color_shaded[3];
1562 gl_shaded_color_get(color, shade, color_shaded);
1563 rgb_uchar_to_float(r_color, color_shaded);
1564}
1565
1566static void gl_shaded_color(const uchar *color, int shade)
1567{
1568 uchar color_shaded[3];
1569 gl_shaded_color_get(color, shade, color_shaded);
1570 immUniformColor3ubv(color_shaded);
1571}
1572
1573void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
1574{
1575 uiButCurveMapping *but_cumap = (uiButCurveMapping *)but;
1576 CurveMapping *cumap = (but_cumap->edit_cumap == nullptr) ? (CurveMapping *)but->poin :
1577 but_cumap->edit_cumap;
1578
1579 const float clip_size_x = BLI_rctf_size_x(&cumap->curr);
1580 const float clip_size_y = BLI_rctf_size_y(&cumap->curr);
1581
1582 /* zero-sized curve */
1583 if (clip_size_x == 0.0f || clip_size_y == 0.0f) {
1584 return;
1585 }
1586
1587 /* calculate offset and zoom */
1588 const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / clip_size_x;
1589 const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / clip_size_y;
1590 const float offsx = cumap->curr.xmin - (1.0f / zoomx);
1591 const float offsy = cumap->curr.ymin - (1.0f / zoomy);
1592
1593 /* exit early if too narrow */
1594 if (zoomx == 0.0f) {
1595 return;
1596 }
1597
1598 CurveMap *cuma = &cumap->cm[cumap->cur];
1599
1600 /* need scissor test, curve can draw outside of boundary */
1601 int scissor[4];
1602 GPU_scissor_get(scissor);
1603 rcti scissor_new{};
1604 scissor_new.xmin = rect->xmin;
1605 scissor_new.ymin = rect->ymin;
1606 scissor_new.xmax = rect->xmax;
1607 scissor_new.ymax = rect->ymax;
1608 const rcti scissor_region = {0, region->winx, 0, region->winy};
1609 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1610 GPU_scissor(scissor_new.xmin,
1611 scissor_new.ymin,
1612 BLI_rcti_size_x(&scissor_new),
1613 BLI_rcti_size_y(&scissor_new));
1614
1615 /* Do this first to not mess imm context */
1616 if (but_cumap->gradient_type == UI_GRAD_H) {
1617 /* magic trigger for curve backgrounds */
1618 const float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
1619
1620 rcti grid{};
1621 grid.xmin = rect->xmin + zoomx * (-offsx);
1622 grid.xmax = grid.xmin + zoomx;
1623 grid.ymin = rect->ymin + zoomy * (-offsy);
1624 grid.ymax = grid.ymin + zoomy;
1625 ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);
1626 }
1627
1628 GPU_line_width(1.0f);
1629
1633
1634 /* backdrop */
1635 float color_backdrop[4] = {0, 0, 0, 1};
1636
1637 if (but_cumap->gradient_type == UI_GRAD_H) {
1638 /* grid, hsv uses different grid */
1640 ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
1641 immUniformColor4fv(color_backdrop);
1642 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
1644 }
1645 else {
1646 if (cumap->flag & CUMA_DO_CLIP) {
1647 gl_shaded_color_get_fl(wcol->inner, -20, color_backdrop);
1648 immUniformColor3fv(color_backdrop);
1649 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1651 immRectf(pos,
1652 rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
1653 rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
1654 rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
1655 rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
1656 }
1657 else {
1658 rgb_uchar_to_float(color_backdrop, wcol->inner);
1659 immUniformColor3fv(color_backdrop);
1660 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1661 }
1662
1663 /* grid, every 0.25 step */
1664 gl_shaded_color(wcol->inner, -16);
1665 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
1666 /* grid, every 1.0 step */
1667 gl_shaded_color(wcol->inner, -24);
1668 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
1669 /* axes */
1670 gl_shaded_color(wcol->inner, -50);
1672 immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
1673 immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
1674 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
1675 immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
1676 immEnd();
1677 }
1678
1679 /* cfra option */
1680 /* XXX 2.48 */
1681#if 0
1682 if (cumap->flag & CUMA_DRAW_CFRA) {
1683 immUniformColor3ub(0x60, 0xc0, 0x40);
1685 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
1686 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
1687 immEnd();
1688 }
1689#endif
1690 /* sample option */
1691
1692 if (cumap->flag & CUMA_DRAW_SAMPLE) {
1693 immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
1694 if (but_cumap->gradient_type == UI_GRAD_H) {
1695 float tsample[3];
1696 float hsv[3];
1697 linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
1698 rgb_to_hsv_v(tsample, hsv);
1699 immUniformColor3ub(240, 240, 240);
1700
1701 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
1702 immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
1703 }
1704 else if (cumap->cur == 3) {
1705 const float lum = IMB_colormanagement_get_luminance(cumap->sample);
1706 immUniformColor3ub(240, 240, 240);
1707
1708 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
1709 immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
1710 }
1711 else {
1712 if (cumap->cur == 0) {
1713 immUniformColor3ub(240, 100, 100);
1714 }
1715 else if (cumap->cur == 1) {
1716 immUniformColor3ub(100, 240, 100);
1717 }
1718 else {
1719 immUniformColor3ub(100, 100, 240);
1720 }
1721
1722 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
1723 immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
1724 }
1725 immEnd();
1726 }
1728
1729 if (cuma->table == nullptr) {
1730 BKE_curvemapping_changed(cumap, false);
1731 }
1732
1733 CurveMapPoint *cmp = cuma->table;
1734 rctf line_range;
1735
1736 /* First curve point. */
1737 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1738 line_range.xmin = rect->xmin;
1739 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
1740 }
1741 else {
1742 line_range.xmin = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
1743 line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
1744 }
1745 /* Last curve point. */
1746 if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
1747 line_range.xmax = rect->xmax;
1748 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
1749 }
1750 else {
1751 line_range.xmax = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
1752 line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
1753 }
1754
1757
1758 /* Curve filled. */
1759 immUniformColor3ubvAlpha(wcol->item, 128);
1760 immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4);
1761 immVertex2f(pos, line_range.xmin, rect->ymin);
1762 immVertex2f(pos, line_range.xmin, line_range.ymin);
1763 for (int a = 0; a <= CM_TABLE; a++) {
1764 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1765 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1766 immVertex2f(pos, fx, rect->ymin);
1767 immVertex2f(pos, fx, fy);
1768 }
1769 immVertex2f(pos, line_range.xmax, rect->ymin);
1770 immVertex2f(pos, line_range.xmax, line_range.ymax);
1771 immEnd();
1772
1773 /* Curve line. */
1774 GPU_line_width(1.0f);
1775 immUniformColor3ubvAlpha(wcol->item, 255);
1776 GPU_line_smooth(true);
1778 immVertex2f(pos, line_range.xmin, line_range.ymin);
1779 for (int a = 0; a <= CM_TABLE; a++) {
1780 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1781 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1782 immVertex2f(pos, fx, fy);
1783 }
1784 immVertex2f(pos, line_range.xmax, line_range.ymax);
1785 immEnd();
1786
1787 /* Reset state for fill & line. */
1788 GPU_line_smooth(false);
1791
1792 /* The points, use aspect to make them visible on edges. */
1798
1800
1801 /* Calculate vertex colors based on text theme. */
1802 float color_vert[4], color_vert_select[4];
1803 UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
1804 UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
1805 if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
1806 interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
1807 }
1808 if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
1809 /* Ensure brightest text color is used for selection. */
1810 swap_v3_v3(color_vert, color_vert_select);
1811 }
1812
1813 cmp = cuma->curve;
1814 const float point_size = max_ff(U.pixelsize * 3.0f,
1815 min_ff(UI_SCALE_FAC / but->block->aspect * 6.0f, 20.0f));
1817 for (int a = 0; a < cuma->totpoint; a++) {
1818 const float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
1819 const float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
1820 immAttr4fv(col, (cmp[a].flag & CUMA_SELECT) ? color_vert_select : color_vert);
1821 immAttr1f(size, point_size);
1822 immVertex2f(pos, fx, fy);
1823 }
1824 immEnd();
1826
1827 /* Restore scissor-test. */
1828 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
1829
1830 /* outline */
1834
1836 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1837
1839}
1840
1845{
1846 return (point->flag & PROF_SELECT &&
1847 (ELEM(point->h1, HD_FREE, HD_ALIGN) || ELEM(point->h2, HD_FREE, HD_ALIGN))) ||
1848 ELEM(point->flag, PROF_H1_SELECT, PROF_H2_SELECT);
1849}
1850
1852 uiBut *but,
1853 const uiWidgetColors *wcol,
1854 const rcti *rect)
1855{
1856 float fx, fy;
1857
1858 uiButCurveProfile *but_profile = (uiButCurveProfile *)but;
1859 CurveProfile *profile = (but_profile->edit_profile == nullptr) ? (CurveProfile *)but->poin :
1860 but_profile->edit_profile;
1861
1862 /* Calculate offset and zoom. */
1863 const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect);
1864 const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect);
1865 const float offsx = profile->view_rect.xmin - (1.0f / zoomx);
1866 const float offsy = profile->view_rect.ymin - (1.0f / zoomy);
1867
1868 /* Exit early if too narrow. */
1869 if (zoomx == 0.0f) {
1870 return;
1871 }
1872
1873 /* Test needed because path can draw outside of boundary. */
1874 int scissor[4];
1875 GPU_scissor_get(scissor);
1876 rcti scissor_new{};
1877 scissor_new.xmin = rect->xmin;
1878 scissor_new.ymin = rect->ymin;
1879 scissor_new.xmax = rect->xmax;
1880 scissor_new.ymax = rect->ymax;
1881
1882 const rcti scissor_region = {0, region->winx, 0, region->winy};
1883 BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
1884 GPU_scissor(scissor_new.xmin,
1885 scissor_new.ymin,
1886 BLI_rcti_size_x(&scissor_new),
1887 BLI_rcti_size_y(&scissor_new));
1888
1889 GPU_line_width(1.0f);
1890
1894
1895 /* Draw the backdrop. */
1896 float color_backdrop[4] = {0, 0, 0, 1};
1897 if (profile->flag & PROF_USE_CLIP) {
1898 gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
1899 immUniformColor3fv(color_backdrop);
1900 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1902 immRectf(pos,
1903 rect->xmin + zoomx * (profile->clip_rect.xmin - offsx),
1904 rect->ymin + zoomy * (profile->clip_rect.ymin - offsy),
1905 rect->xmin + zoomx * (profile->clip_rect.xmax - offsx),
1906 rect->ymin + zoomy * (profile->clip_rect.ymax - offsy));
1907 }
1908 else {
1909 rgb_uchar_to_float(color_backdrop, (uchar *)wcol->inner);
1910 immUniformColor3fv(color_backdrop);
1911 immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1912 }
1913
1914 /* 0.25 step grid. */
1915 gl_shaded_color((uchar *)wcol->inner, -16);
1916 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
1917 /* 1.0 step grid. */
1918 gl_shaded_color((uchar *)wcol->inner, -24);
1919 ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
1920
1921 /* Draw the path's fill. */
1922 if (profile->table == nullptr) {
1924 }
1925 CurveProfilePoint *pts = profile->table;
1926 /* Also add the last points on the right and bottom edges to close off the fill polygon. */
1927 const bool add_left_tri = profile->view_rect.xmin < 0.0f;
1928 const bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
1929 int tot_points = BKE_curveprofile_table_size(profile) + 1 + add_left_tri + add_bottom_tri;
1930 const uint tot_triangles = tot_points - 2;
1931
1932 /* Create array of the positions of the table's points. */
1933 float(*table_coords)[2] = static_cast<float(*)[2]>(
1934 MEM_mallocN(sizeof(*table_coords) * tot_points, __func__));
1935 for (uint i = 0; i < uint(BKE_curveprofile_table_size(profile)); i++) {
1936 /* Only add the points from the table here. */
1937 table_coords[i][0] = pts[i].x;
1938 table_coords[i][1] = pts[i].y;
1939 }
1940 /* Using some extra margin (-1.0f) for the coordinates used to complete the polygon
1941 * avoids the profile line crossing itself in some common situations, which can lead to
1942 * incorrect triangulation. See #841183. */
1943 if (add_left_tri && add_bottom_tri) {
1944 /* Add left side, bottom left corner, and bottom side points. */
1945 table_coords[tot_points - 3][0] = profile->view_rect.xmin - 1.0f;
1946 table_coords[tot_points - 3][1] = 1.0f;
1947 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
1948 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
1949 table_coords[tot_points - 1][0] = 1.0f;
1950 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
1951 }
1952 else if (add_left_tri) {
1953 /* Add the left side and bottom left corner points. */
1954 table_coords[tot_points - 2][0] = profile->view_rect.xmin - 1.0f;
1955 table_coords[tot_points - 2][1] = 1.0f;
1956 table_coords[tot_points - 1][0] = profile->view_rect.xmin - 1.0f;
1957 table_coords[tot_points - 1][1] = -1.0f;
1958 }
1959 else if (add_bottom_tri) {
1960 /* Add the bottom side and bottom left corner points. */
1961 table_coords[tot_points - 2][0] = -1.0f;
1962 table_coords[tot_points - 2][1] = profile->view_rect.ymin - 1.0f;
1963 table_coords[tot_points - 1][0] = 1.0f;
1964 table_coords[tot_points - 1][1] = profile->view_rect.ymin - 1.0f;
1965 }
1966 else {
1967 /* Just add the bottom corner point. Side points would be redundant anyway. */
1968 table_coords[tot_points - 1][0] = -1.0f;
1969 table_coords[tot_points - 1][1] = -1.0f;
1970 }
1971
1972 /* Calculate the table point indices of the triangles for the profile's fill. */
1973 if (tot_triangles > 0) {
1974 uint(*tri_indices)[3] = static_cast<uint(*)[3]>(
1975 MEM_mallocN(sizeof(*tri_indices) * tot_triangles, __func__));
1976 BLI_polyfill_calc(table_coords, tot_points, -1, tri_indices);
1977
1978 /* Draw the triangles for the profile fill. */
1979 immUniformColor3ubvAlpha(wcol->item, 128);
1981 GPU_polygon_smooth(false);
1982 immBegin(GPU_PRIM_TRIS, 3 * tot_triangles);
1983 for (uint i = 0; i < tot_triangles; i++) {
1984 const uint *tri = tri_indices[i];
1985 for (uint j = 0; j < 3; j++) {
1986 fx = rect->xmin + zoomx * (table_coords[tri[j]][0] - offsx);
1987 fy = rect->ymin + zoomy * (table_coords[tri[j]][1] - offsy);
1988 immVertex2f(pos, fx, fy);
1989 }
1990 }
1991 immEnd();
1992 MEM_freeN(tri_indices);
1993 }
1994
1995 /* Draw the profile's path so the edge stands out a bit. */
1996 tot_points -= (add_left_tri + add_left_tri);
1997 const int edges_len = tot_points - 1;
1998 if (edges_len > 0) {
1999 GPU_line_width(1.0f);
2000 immUniformColor3ubvAlpha((const uchar *)wcol->item, 255);
2001 GPU_line_smooth(true);
2002 immBegin(GPU_PRIM_LINE_STRIP, tot_points);
2003 for (int i = 0; i < tot_points; i++) {
2004 fx = rect->xmin + zoomx * (table_coords[i][0] - offsx);
2005 fy = rect->ymin + zoomy * (table_coords[i][1] - offsy);
2006 immVertex2f(pos, fx, fy);
2007 }
2008 immEnd();
2009 }
2010
2011 MEM_SAFE_FREE(table_coords);
2012
2013 /* Draw the handles for the selected control points. */
2014 pts = profile->path;
2015 const int path_len = tot_points = uint(profile->path_len);
2016 int selected_free_points = 0;
2017 for (int i = 0; i < path_len; i++) {
2018 if (point_draw_handles(&pts[i])) {
2019 selected_free_points++;
2020 }
2021 }
2022 /* Draw the lines to the handles from the points. */
2023 if (selected_free_points > 0) {
2024 GPU_line_width(1.0f);
2025 gl_shaded_color((uchar *)wcol->inner, -24);
2026 GPU_line_smooth(true);
2027 immBegin(GPU_PRIM_LINES, selected_free_points * 4);
2028 float ptx, pty;
2029 for (int i = 0; i < path_len; i++) {
2030 if (point_draw_handles(&pts[i])) {
2031 ptx = rect->xmin + zoomx * (pts[i].x - offsx);
2032 pty = rect->ymin + zoomy * (pts[i].y - offsy);
2033
2034 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2035 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2036 immVertex2f(pos, ptx, pty);
2037 immVertex2f(pos, fx, fy);
2038
2039 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2040 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2041 immVertex2f(pos, ptx, pty);
2042 immVertex2f(pos, fx, fy);
2043 }
2044 }
2045 immEnd();
2046 }
2048
2049 /* New GPU instructions for control points and sampled points. */
2054
2055 /* Calculate vertex colors based on text theme. */
2056 float color_vert[4], color_vert_select[4], color_sample[4];
2057 UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
2058 UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
2059 color_sample[0] = float(wcol->item[0]) / 255.0f;
2060 color_sample[1] = float(wcol->item[1]) / 255.0f;
2061 color_sample[2] = float(wcol->item[2]) / 255.0f;
2062 color_sample[3] = float(wcol->item[3]) / 255.0f;
2063 if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
2064 interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
2065 }
2066 if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
2067 /* Ensure brightest text color is used for selection. */
2068 swap_v3_v3(color_vert, color_vert_select);
2069 }
2070
2071 /* Draw the control points. */
2072 GPU_line_smooth(false);
2073 if (path_len > 0) {
2075 GPU_point_size(max_ff(3.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 5.0f, 5.0f)));
2076 immBegin(GPU_PRIM_POINTS, path_len);
2077 for (int i = 0; i < path_len; i++) {
2078 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2079 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2080 immAttr4fv(col, (pts[i].flag & PROF_SELECT) ? color_vert_select : color_vert);
2081 immVertex2f(pos, fx, fy);
2082 }
2083 immEnd();
2084 }
2085
2086 /* Draw the handle points. */
2087 if (selected_free_points > 0) {
2088 GPU_line_smooth(false);
2090 GPU_point_size(max_ff(2.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 4.0f, 4.0f)));
2091 immBegin(GPU_PRIM_POINTS, selected_free_points * 2);
2092 for (int i = 0; i < path_len; i++) {
2093 if (point_draw_handles(&pts[i])) {
2094 fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
2095 fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
2096 immAttr4fv(col, (pts[i].flag & PROF_H1_SELECT) ? color_vert_select : color_vert);
2097 immVertex2f(pos, fx, fy);
2098
2099 fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
2100 fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
2101 immAttr4fv(col, (pts[i].flag & PROF_H2_SELECT) ? color_vert_select : color_vert);
2102 immVertex2f(pos, fx, fy);
2103 }
2104 }
2105 immEnd();
2106 }
2107
2108 /* Draw the sampled points in addition to the control points if they have been created */
2109 pts = profile->segments;
2110 const int segments_len = uint(profile->segments_len);
2111 if (segments_len > 0 && pts) {
2112 GPU_point_size(max_ff(2.0f, min_ff(UI_SCALE_FAC / but->block->aspect * 3.0f, 3.0f)));
2113 immBegin(GPU_PRIM_POINTS, segments_len);
2114 for (int i = 0; i < segments_len; i++) {
2115 fx = rect->xmin + zoomx * (pts[i].x - offsx);
2116 fy = rect->ymin + zoomy * (pts[i].y - offsy);
2117 immAttr4fv(col, color_sample);
2118 immVertex2f(pos, fx, fy);
2119 }
2120 immEnd();
2121 }
2123
2124 /* Restore scissor-test. */
2125 GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
2126
2127 /* Outline */
2131
2132 immUniformColor3ubv((const uchar *)wcol->outline);
2133 imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
2135}
2136
2138 uiBut *but,
2139 const uiWidgetColors * /*wcol*/,
2140 const rcti *recti)
2141{
2142 bool ok = false;
2143 MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
2144
2145 rctf rect{};
2146 rect.xmin = float(recti->xmin + 1);
2147 rect.xmax = float(recti->xmax - 1);
2148 rect.ymin = float(recti->ymin + 1);
2149 rect.ymax = float(recti->ymax - 1);
2150
2151 const int width = BLI_rctf_size_x(&rect) + 1;
2152 const int height = BLI_rctf_size_y(&rect);
2153
2155
2156 /* need scissor test, preview image can draw outside of boundary */
2157 int scissor[4];
2158 GPU_scissor_get(scissor);
2159 GPU_scissor((rect.xmin - 1),
2160 (rect.ymin - 1),
2161 (rect.xmax + 1) - (rect.xmin - 1),
2162 (rect.ymax + 1) - (rect.ymin - 1));
2163
2164 if (scopes->track_disabled) {
2165 const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
2167 rctf disabled_rect{};
2168 disabled_rect.xmin = rect.xmin - 1;
2169 disabled_rect.xmax = rect.xmax + 1;
2170 disabled_rect.ymin = rect.ymin;
2171 disabled_rect.ymax = rect.ymax + 1;
2172 UI_draw_roundbox_4fv(&disabled_rect, true, 3.0f, color);
2173
2174 ok = true;
2175 }
2176 else if ((scopes->track_search) &&
2177 ((!scopes->track_preview) ||
2178 (scopes->track_preview->x != width || scopes->track_preview->y != height)))
2179 {
2180 if (scopes->track_preview) {
2182 }
2183
2185 scopes->frame_height,
2186 scopes->track_search,
2187 scopes->track,
2188 &scopes->undist_marker,
2189 true,
2190 scopes->use_track_mask,
2191 width,
2192 height,
2193 scopes->track_pos);
2194 if (tmpibuf) {
2195 if (tmpibuf->float_buffer.data) {
2196 IMB_rect_from_float(tmpibuf);
2197 }
2198
2199 if (tmpibuf->byte_buffer.data) {
2200 scopes->track_preview = tmpibuf;
2201 }
2202 else {
2203 IMB_freeImBuf(tmpibuf);
2204 }
2205 }
2206 }
2207
2208 if (!ok && scopes->track_preview) {
2210
2211 /* draw content of pattern area */
2212 GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
2213
2214 if (width > 0 && height > 0) {
2215 const ImBuf *drawibuf = scopes->track_preview;
2216 float col_sel[4], col_outline[4];
2217
2218 if (scopes->use_track_mask) {
2219 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2221 rctf mask_rect{};
2222 mask_rect.xmin = rect.xmin - 1;
2223 mask_rect.xmax = rect.xmax + 1;
2224 mask_rect.ymin = rect.ymin;
2225 mask_rect.ymax = rect.ymax + 1;
2226 UI_draw_roundbox_4fv(&mask_rect, true, 3.0f, color);
2227 }
2228
2231 rect.xmin,
2232 rect.ymin + 1,
2233 drawibuf->x,
2234 drawibuf->y,
2235 GPU_RGBA8,
2236 true,
2237 drawibuf->byte_buffer.data,
2238 1.0f,
2239 1.0f,
2240 nullptr);
2241
2242 /* draw cross for pixel position */
2243 GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
2244 GPU_scissor(rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect));
2245
2250
2253
2254 /* Do stipple cross with geometry */
2255 immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
2256 const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
2257 for (int axe = 0; axe < 2; axe++) {
2258 for (int i = 0; i < 7; i++) {
2259 const float x1 = pos_sel[i] * (1 - axe);
2260 const float y1 = pos_sel[i] * axe;
2261 const float x2 = pos_sel[i + 1] * (1 - axe);
2262 const float y2 = pos_sel[i + 1] * axe;
2263
2264 if (i % 2 == 1) {
2265 immAttr4fv(col, col_sel);
2266 }
2267 else {
2268 immAttr4fv(col, col_outline);
2269 }
2270
2271 immVertex2f(pos, x1, y1);
2272 immVertex2f(pos, x2, y2);
2273 }
2274 }
2275 immEnd();
2276
2278 }
2279
2281
2282 ok = true;
2283 }
2284
2285 if (!ok) {
2286 const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
2288 rctf box_rect{};
2289 box_rect.xmin = rect.xmin - 1;
2290 box_rect.xmax = rect.xmax + 1;
2291 box_rect.ymin = rect.ymin;
2292 box_rect.ymax = rect.ymax + 1;
2293 UI_draw_roundbox_4fv(&box_rect, true, 3.0f, color);
2294 }
2295
2296 /* Restore scissor test. */
2297 GPU_scissor(UNPACK4(scissor));
2298 /* outline */
2299 draw_scope_end(&rect);
2300
2302}
2303
2304/* ****************************************************** */
2305
2307 const rctf *rct, const float radius, const float width, const float aspect, const float alpha)
2308{
2309 if (width == 0.0f) {
2310 return;
2311 }
2312
2313 /* This undoes the scale of the view for higher zoom factors to clamp the shadow size. */
2314 const float clamped_aspect = smoothminf(aspect, 1.0f, 0.5f);
2315 const float shadow_width = width * clamped_aspect;
2316 const float shadow_offset = min_ff(shadow_width, BLI_rctf_size_y(rct) - 2.0f * radius);
2317
2318 const float inner_radius = max_ff(radius - U.pixelsize, 0.0);
2319 const float shadow_radius = radius + shadow_width - U.pixelsize;
2320
2322
2323 uiWidgetBaseParameters widget_params{};
2324 widget_params.recti.xmin = rct->xmin;
2325 widget_params.recti.ymin = rct->ymin;
2326 widget_params.recti.xmax = rct->xmax;
2327 widget_params.recti.ymax = rct->ymax;
2328 widget_params.rect.xmin = rct->xmin - shadow_width;
2329 widget_params.rect.ymin = rct->ymin - shadow_width;
2330 widget_params.rect.xmax = rct->xmax + shadow_width;
2331 widget_params.rect.ymax = rct->ymax + shadow_width - shadow_offset;
2332 widget_params.radi = inner_radius;
2333 widget_params.rad = shadow_radius;
2334 widget_params.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
2335 widget_params.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
2336 widget_params.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
2337 widget_params.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
2338 widget_params.alpha_discard = 1.0f;
2339
2340 blender::gpu::Batch *batch = ui_batch_roundbox_shadow_get();
2342 GPU_batch_uniform_4fv_array(batch, "parameters", 4, (const float(*)[4]) & widget_params);
2343 GPU_batch_uniform_1f(batch, "alpha", alpha);
2345
2347}
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:334
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
Definition glutil.cc:40
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:523
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition blf.cc:497
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
#define M_PI_2
#define M_PI
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])
void unit_m3(float m[3][3])
#define DEG2RADF(_deg)
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)
Definition math_vector.c:36
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:193
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:189
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:197
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:201
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
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
@ SCOPES_WAVEFRM_YCC_JPEG
@ SCOPES_WAVEFRM_RGB
@ SCOPES_WAVEFRM_YCC_601
@ SCOPES_WAVEFRM_YCC_709
@ SCOPES_WAVEFRM_LUMA
@ SCOPES_WAVEFRM_RGB_PARADE
@ HISTO_FLAG_LINE
@ CUMA_SELECT
@ SCOPES_VECSCOPE_LUMA
@ SCOPES_VECSCOPE_RGB
#define CM_TABLE
@ 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:56
#define GPU_batch_uniform_1f(batch, name, x)
Definition GPU_batch.hh:299
void GPU_batch_discard(blender::gpu::Batch *batch)
#define GPU_batch_uniformbuf_bind(batch, name, ubo)
Definition GPU_batch.hh:314
#define GPU_batch_uniform_4fv_array(batch, name, len, val)
Definition GPU_batch.hh:310
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:303
@ GPU_BATCH_OWNS_VBO
Definition GPU_batch.hh:42
blender::gpu::Batch * GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT
void immUniformColor4ubv(const unsigned char rgba[4])
void immAttr3ubv(uint attr_id, const unsigned char data[3])
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 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])
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void immRecti(uint pos, int x1, int y1, int x2, int 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()
#define 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_2D_CHECKER
@ 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:175
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:161
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
@ GPU_CULL_NONE
Definition GPU_state.hh:133
@ GPU_CULL_BACK
Definition GPU_state.hh:135
void GPU_scissor(int x, int y, int width, int height)
Definition gpu_state.cc:188
void GPU_point_size(float size)
Definition gpu_state.cc:167
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:262
void GPU_scissor_get(int coords[4])
Definition gpu_state.cc:257
void GPU_polygon_smooth(bool enable)
Definition gpu_state.cc:83
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
@ GPU_FETCH_INT_TO_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_I32
@ GPU_COMP_U8
BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3])
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display)
void IMB_rect_from_float(ImBuf *ibuf)
Definition divers.cc:694
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Definition scaling.cc:779
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define UI_ALPHA_CHECKER_LIGHT
#define UI_ALPHA_CHECKER_DARK
@ UI_GRAD_H
@ UI_CNR_BOTTOM_LEFT
@ UI_CNR_BOTTOM_RIGHT
@ UI_CNR_ALL
@ UI_CNR_TOP_LEFT
@ UI_CNR_TOP_RIGHT
@ TH_MARKER_OUTLINE
@ TH_PREVIEW_BACK
@ TH_SEL_MARKER
@ TH_TEXT
@ TH_TEXT_HI
void UI_GetThemeColor4fv(int colorid, float col[4])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
MutableSpan< T > data()
local_group_size(16, 16) .push_constant(Type b
const char * label
#define sinf(x)
#define cosf(x)
#define ceilf(x)
#define atanf(x)
#define floorf(x)
#define sqrtf(x)
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
#define str(s)
struct @620::@622 batch
uint col
void IMB_freeImBuf(ImBuf *)
void ui_but_v3_get(uiBut *but, float vec[3])
ColorManagedDisplay * ui_block_cm_display_get(uiBlock *block)
void ui_draw_but_HISTOGRAM(ARegion *, uiBut *but, const uiWidgetColors *, const rcti *recti)
void ui_draw_but_TRACKPREVIEW(ARegion *, uiBut *but, const uiWidgetColors *, const rcti *recti)
#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)
static void ui_draw_colorband_handle(uint shdr_pos, const rcti *rect, float x, const float rgb[3], ColorManagedDisplay *display, bool active)
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])
void ui_draw_but_WAVEFORM(ARegion *, uiBut *but, const uiWidgetColors *, const rcti *recti)
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)
void ui_draw_but_VECTORSCOPE(ARegion *, uiBut *but, const uiWidgetColors *, const rcti *recti)
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)
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)
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_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_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:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
MINLINE float smoothminf(float a, float b, float c)
ccl_device_inline float2 fabs(const float2 a)
static ulong state[N]
#define min(a, b)
Definition sort.c:32
CBData data[32]
CurveMapPoint * table
CurveMapPoint * curve
float ext_out[2]
float ext_in[2]
CurveMap cm[4]
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]
float max
uint8_t flag
Definition wm_window.cc:138