VSE: tweak look of Vectorscope to match upcoming Image vectorscope #117738
|
@ -631,28 +631,116 @@ static void draw_waveform_graticule(ARegion *region, SeqQuadsBatch &quads, const
|
|||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
static void draw_vectorscope_graticule(SeqQuadsBatch &quads, const rctf &area)
|
||||
static void draw_vectorscope_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
|
||||
{
|
||||
using namespace blender;
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
|
||||
|
||||
const float w = BLI_rctf_size_x(&area);
|
||||
const float h = BLI_rctf_size_y(&area);
|
||||
const float centerx = BLI_rctf_cent_x(&area);
|
||||
const float centery = BLI_rctf_cent_y(&area);
|
||||
const float rad_base = ((w < h) ? w : h) * 0.5f;
|
||||
/* vectorscope image is scaled over YUV range, +/- (0.436, 0.615) */
|
||||
const float rad_x = rad_base * (0.5f / 0.436f);
|
||||
const float rad_y = rad_base * (0.5f / 0.615f);
|
||||
const float2 center{BLI_rctf_cent_x(&area), BLI_rctf_cent_y(&area)};
|
||||
/* Vectorscope image is scaled over UV range (+/-0.615). */
|
||||
const float radius = ((w < h) ? w : h) * 0.5f * (0.5f / 0.615f);
|
||||
|
||||
/* center cross */
|
||||
uchar col_grid[4] = {128, 128, 128, 96};
|
||||
quads.add_line(centerx - rad_base * 0.1f, centery, centerx + rad_base * 0.1f, centery, col_grid);
|
||||
quads.add_line(centerx, centery - rad_base * 0.1f, centerx, centery + rad_base * 0.1f, col_grid);
|
||||
/* Precalculate circle points/colors. */
|
||||
constexpr int circle_delta = 6;
|
||||
constexpr int num_circle_points = 360 / circle_delta;
|
||||
float2 circle_pos[num_circle_points];
|
||||
float3 circle_col[num_circle_points];
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
float a = DEG2RADF(i * circle_delta);
|
||||
float u = cosf(a);
|
||||
float v = sinf(a);
|
||||
circle_pos[i] = float2(u, v);
|
||||
|
||||
/* fully saturated vs "safe" (0.75) colored areas */
|
||||
float3 col;
|
||||
yuv_to_rgb(0.5f, u, v, &col.x, &col.y, &col.z, BLI_YUV_ITU_BT709);
|
||||
circle_col[i] = col;
|
||||
}
|
||||
|
||||
/* Draw colored background and outer ring, additively blended
|
||||
* since vectorscope image is already drawn. */
|
||||
GPU_blend(GPU_BLEND_ADDITIVE);
|
||||
|
||||
constexpr float alpha_f = 0.8f;
|
||||
constexpr uchar alpha_b = uchar(alpha_f * 255.0f);
|
||||
const uchar4 col_center(50, 50, 50, alpha_b);
|
||||
|
||||
uchar4 col1(0, 0, 0, alpha_b);
|
||||
uchar4 col2(0, 0, 0, alpha_b);
|
||||
uchar4 col3(0, 0, 0, alpha_b);
|
||||
|
||||
/* Background: since the quads batch utility draws quads, draw two
|
||||
* segments of the circle (two triangles) in one iteration. */
|
||||
constexpr float mul_background = 0.2f;
|
||||
for (int i = 0; i < num_circle_points; i += 2) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
int idx3 = (i + 2) % num_circle_points;
|
||||
float2 pt1 = center + circle_pos[idx1] * radius;
|
||||
float2 pt2 = center + circle_pos[idx2] * radius;
|
||||
float2 pt3 = center + circle_pos[idx3] * radius;
|
||||
float3 rgb1 = circle_col[idx1] * mul_background;
|
||||
float3 rgb2 = circle_col[idx2] * mul_background;
|
||||
float3 rgb3 = circle_col[idx3] * mul_background;
|
||||
rgb_float_to_uchar(col1, rgb1);
|
||||
rgb_float_to_uchar(col2, rgb2);
|
||||
rgb_float_to_uchar(col3, rgb3);
|
||||
quads.add_quad(pt1.x,
|
||||
pt1.y,
|
||||
pt2.x,
|
||||
pt2.y,
|
||||
center.x,
|
||||
center.y,
|
||||
pt3.x,
|
||||
pt3.y,
|
||||
col1,
|
||||
col2,
|
||||
col_center,
|
||||
col3);
|
||||
}
|
||||
|
||||
/* Outer ring. */
|
||||
const float outer_radius = radius * 1.02f;
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
float2 pt1a = center + circle_pos[idx1] * radius;
|
||||
float2 pt2a = center + circle_pos[idx2] * radius;
|
||||
float2 pt1b = center + circle_pos[idx1] * outer_radius;
|
||||
float2 pt2b = center + circle_pos[idx2] * outer_radius;
|
||||
float3 rgb1 = circle_col[idx1];
|
||||
float3 rgb2 = circle_col[idx2];
|
||||
rgb_float_to_uchar(col1, rgb1);
|
||||
rgb_float_to_uchar(col2, rgb2);
|
||||
quads.add_quad(
|
||||
pt1a.x, pt1a.y, pt1b.x, pt1b.y, pt2a.x, pt2a.y, pt2b.x, pt2b.y, col1, col1, col2, col2);
|
||||
}
|
||||
|
||||
quads.draw();
|
||||
|
||||
/* Draw grid and other labels using regular alpha blending. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
const uchar4 col_grid(128, 128, 128, 128);
|
||||
|
||||
/* Cross. */
|
||||
quads.add_line(center.x - radius, center.y, center.x + radius, center.y, col_grid);
|
||||
quads.add_line(center.x, center.y - radius, center.x, center.y + radius, col_grid);
|
||||
|
||||
/* Inner circles. */
|
||||
for (int j = 1; j < 5; j++) {
|
||||
float r = radius * j * 0.2f;
|
||||
for (int i = 0; i < num_circle_points; i++) {
|
||||
int idx1 = i;
|
||||
int idx2 = (i + 1) % num_circle_points;
|
||||
float2 pt1 = center + circle_pos[idx1] * r;
|
||||
float2 pt2 = center + circle_pos[idx2] * r;
|
||||
quads.add_line(pt1.x, pt1.y, pt2.x, pt2.y, col_grid);
|
||||
}
|
||||
}
|
||||
|
||||
/* "Safe" (0.75 saturation) primary color locations and labels. */
|
||||
const float3 primaries[6] = {
|
||||
{1, 0, 0},
|
||||
{1, 1, 0},
|
||||
|
@ -661,35 +749,43 @@ static void draw_vectorscope_graticule(SeqQuadsBatch &quads, const rctf &area)
|
|||
{0, 0, 1},
|
||||
{1, 0, 1},
|
||||
};
|
||||
float2 center{centerx, centery};
|
||||
float2 rad_scale{rad_x * 2, rad_y * 2};
|
||||
const char *names = "RYGCBM";
|
||||
|
||||
/* Calculate size of single text letter. */
|
||||
char buf[2] = {'M', 0};
|
||||
float text_scale_x, text_scale_y;
|
||||
UI_view2d_scale_get_inverse(®ion->v2d, &text_scale_x, &text_scale_y);
|
||||
float text_width, text_height;
|
||||
BLF_width_and_height(BLF_default(), buf, 1, &text_width, &text_height);
|
||||
text_width *= text_scale_x;
|
||||
text_height *= text_scale_y;
|
||||
|
||||
const uchar4 col_target(128, 128, 128, 192);
|
||||
const float delta = radius * 0.01f;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float3 prim0 = primaries[i];
|
||||
float3 prim1 = primaries[(i + 1) % 6];
|
||||
float3 safe0 = prim0 * 0.75f;
|
||||
float3 safe1 = prim1 * 0.75f;
|
||||
float2 uv0 = center + rgb_to_uv(prim0) * rad_scale;
|
||||
float2 uv1 = center + rgb_to_uv(prim1) * rad_scale;
|
||||
float2 uv2 = center + rgb_to_uv(safe0) * rad_scale;
|
||||
float2 uv3 = center + rgb_to_uv(safe1) * rad_scale;
|
||||
uchar col0[4] = {uchar(prim0.x * 255), uchar(prim0.y * 255), uchar(prim0.z * 255), 64};
|
||||
uchar col1[4] = {uchar(prim1.x * 255), uchar(prim1.y * 255), uchar(prim1.z * 255), 64};
|
||||
uchar col2[4] = {uchar(safe0.x * 255), uchar(safe0.y * 255), uchar(safe0.z * 255), 64};
|
||||
uchar col3[4] = {uchar(safe1.x * 255), uchar(safe1.y * 255), uchar(safe1.z * 255), 64};
|
||||
quads.add_quad(uv0.x, uv0.y, uv1.x, uv1.y, uv2.x, uv2.y, uv3.x, uv3.y, col0, col1, col2, col3);
|
||||
col0[3] = col1[3] = col2[3] = col3[3] = 192;
|
||||
quads.add_line(uv0.x, uv0.y, uv1.x, uv1.y, col0, col1);
|
||||
quads.add_line(uv2.x, uv2.y, uv3.x, uv3.y, col2, col3);
|
||||
float3 safe = primaries[i] * 0.75f;
|
||||
float2 pos = center + rgb_to_uv(safe) * (radius * 2);
|
||||
quads.add_wire_quad(pos.x - delta, pos.y - delta, pos.x + delta, pos.y + delta, col_target);
|
||||
|
||||
buf[0] = names[i];
|
||||
UI_view2d_text_cache_add(®ion->v2d,
|
||||
pos.x + delta * 1.2f + text_width / 4,
|
||||
pos.y - text_height / 2,
|
||||
buf,
|
||||
1,
|
||||
col_target);
|
||||
}
|
||||
|
||||
/* skin tone line */
|
||||
uchar col_tone[4] = {255, 102, 0, 128};
|
||||
const float tone_line_len = 0.895f; /* makes it end at outer edge of saturation ring. */
|
||||
quads.add_line(centerx,
|
||||
centery,
|
||||
centerx + cosf(skin_rad) * rad_x * tone_line_len,
|
||||
centery + sinf(skin_rad) * rad_y * tone_line_len,
|
||||
/* Skin tone line. */
|
||||
const uchar4 col_tone(255, 102, 0, 128);
|
||||
quads.add_line(center.x,
|
||||
center.y,
|
||||
center.x + cosf(skin_rad) * radius,
|
||||
center.y + sinf(skin_rad) * radius,
|
||||
col_tone);
|
||||
|
||||
quads.draw();
|
||||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
static void sequencer_draw_scopes(Scene *scene, ARegion *region, SpaceSeq *sseq)
|
||||
|
@ -794,7 +890,7 @@ static void sequencer_draw_scopes(Scene *scene, ARegion *region, SpaceSeq *sseq)
|
|||
}
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
|
||||
use_blend = true;
|
||||
draw_vectorscope_graticule(quads, preview);
|
||||
draw_vectorscope_graticule(region, quads, preview);
|
||||
}
|
||||
|
||||
quads.draw();
|
||||
|
|
|
@ -64,8 +64,8 @@ static blender::float2 rgb_to_uv_normalized(const float rgb[3])
|
|||
float u = -0.09991f * r - 0.33609f * g + 0.436f * b;
|
||||
float v = 0.615f * r - 0.55861f * g - 0.05639f * b;
|
||||
|
||||
/* Normalize: (U, V) range is +/- (0.436, 0.615) */
|
||||
u = clamp_f(u * (0.5f / 0.436f) + 0.5f, 0.0f, 1.0f);
|
||||
/* Normalize: possible range is +/- 0.615. */
|
||||
u = clamp_f(u * (0.5f / 0.615f) + 0.5f, 0.0f, 1.0f);
|
||||
v = clamp_f(v * (0.5f / 0.615f) + 0.5f, 0.0f, 1.0f);
|
||||
return float2(u, v);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue