diff --git a/app/shaders/rgbwaveform.frag b/app/shaders/rgbwaveform.frag index c97562daa..3e839b386 100644 --- a/app/shaders/rgbwaveform.frag +++ b/app/shaders/rgbwaveform.frag @@ -5,8 +5,13 @@ uniform sampler2D ove_maintex; uniform vec2 ove_resolution; +uniform vec2 ove_viewport; +uniform vec3 luma_coeffs; -uniform float threshold; +uniform float waveform_scale; +uniform vec2 waveform_dims; +uniform vec4 waveform_region; +uniform vec4 waveform_uv; in vec2 ove_texcoord; @@ -14,18 +19,53 @@ out vec4 fragColor; void main(void) { vec3 col = vec3(0.0); - float s = ove_texcoord.y * 1.8 - 0.15; - float maxb = s + threshold; - float minb = s - threshold; + // Set an increment default to 10 bit encodings. This would likely be + // better served as a UI control, as waveforms will change their combing + // based on how granular the increment is set. For example, it can be + // challenging to spot 8 bit combing with an increment of 1. / 2.^8 - 1. + float increment = 1.0 / (pow(2, 10) - 1.0); + float maxb = waveform_dims.y + increment; + float minb = waveform_dims.y - increment; - int y_lim = int(ove_resolution.y); + // Intensity would make sense to also expose via the UI, as a density + // slider allows you to peek past certain values or reveal very low + // values. Hard coding it for now, as there isn't a clear way to have + // the various bit depth / code values always display at a consistent + // emission output strength. + float intensity = 0.10; - for (int i = 0; i < y_lim; i++) { - vec3 x = texture(ove_maintex, vec2(ove_texcoord.x, float(i) / float(ove_resolution.y))).rgb; - col += step(x, vec3(maxb)) * step(vec3(minb), x) / (ove_resolution.y * 0.125); + int y_lim = int(waveform_dims.y); - float l = dot(x, x); - col += step(l, maxb * maxb) * step(minb * minb, l) / (ove_resolution.y * 0.125); + vec3 cur_col = vec3(0.0); + vec3 cur_lum = vec3(0.0); + + if ( + (gl_FragCoord.x >= waveform_region.x) && + (gl_FragCoord.y >= waveform_region.y) && + (gl_FragCoord.x < waveform_region.z) && + (gl_FragCoord.y < waveform_region.w) + ) { + // col = vec3(0.5, 0.5, 0.0); + // int start = int(waveform_region.y); + int stop = int(waveform_dims.y); + float ratio = 0.0; + float waveform_x = (ove_texcoord.x - waveform_uv.x) / waveform_scale; + float waveform_y = (ove_texcoord.y - waveform_uv.y) / waveform_scale; + for (int i = 0; i < waveform_dims.y; i++) { + ratio = float(i) / float(waveform_dims.y); + cur_col = texture( + ove_maintex, + vec2(waveform_x, ratio) + ).rgb; + + col += step(vec3(waveform_y - increment), cur_col) * + step(cur_col, vec3(waveform_y + increment)) * intensity; + + cur_lum = vec3(dot(cur_col, luma_coeffs)); + + col += step(vec3(waveform_y - increment), cur_lum) * + step(cur_lum, vec3(waveform_y + increment)) * intensity; + } } fragColor = vec4(col, 1.0); diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp index 0ce873bc5..39c6f81cb 100644 --- a/app/widget/scope/waveform/waveform.cpp +++ b/app/widget/scope/waveform/waveform.cpp @@ -21,6 +21,11 @@ #include "waveform.h" +#include +#include +#include + +#include "common/qtutils.h" #include "node/node.h" #include "render/backend/opengl/openglrenderfunctions.h" @@ -106,9 +111,35 @@ void WaveformScope::paintGL() pipeline_->bind(); pipeline_->setUniformValue("ove_resolution", texture_.width(), texture_.height()); pipeline_->setUniformValue("ove_viewport", width(), height()); + GLfloat luma[3] = {0.0, 0.0, 0.0}; + color_manager()->GetDefaultLumaCoefs(luma); + pipeline_->setUniformValue("luma_coeffs", luma[0], luma[1], luma[2]); - // The general size of a pixel - pipeline_->setUniformValue("threshold", 2.0f / static_cast(height())); + // Scale of the waveform relative to the viewport surface. + float waveform_scale = 0.80; + pipeline_->setUniformValue("waveform_scale", waveform_scale); + float waveform_dim_x = width() * waveform_scale; + float waveform_dim_y = height() * waveform_scale; + pipeline_->setUniformValue( + "waveform_dims", waveform_dim_x, waveform_dim_y); + + float waveform_start_dim_x = (width() - waveform_dim_x) / 2.0; + float waveform_start_dim_y = (height() - waveform_dim_y) / 2.0; + float waveform_end_dim_x = width() - waveform_start_dim_x; + float waveform_end_dim_y = height() - waveform_start_dim_y; + pipeline_->setUniformValue( + "waveform_region", + waveform_start_dim_x, waveform_start_dim_y, + waveform_end_dim_x, waveform_end_dim_y); + + float waveform_start_uv_x = waveform_start_dim_x / width(); + float waveform_start_uv_y = waveform_start_dim_y / height(); + float waveform_end_uv_x = waveform_end_dim_x / width(); + float waveform_end_uv_y = waveform_end_dim_y / height(); + pipeline_->setUniformValue( + "waveform_uv", + waveform_start_uv_x, waveform_start_uv_y, + waveform_end_uv_x, waveform_end_uv_y); pipeline_->release(); @@ -119,6 +150,36 @@ void WaveformScope::paintGL() OpenGLRenderFunctions::Blit(pipeline_); managed_tex_.Release(); + + QPainter p(this); + QFontMetrics font_metrics = QFontMetrics(QFont()); + QString label; + float ire_increment = 0.1; + float ire_steps = int(1.0 / ire_increment); + QVector ire_lines(ire_steps + 1); + int font_x_offset = 0; + int font_y_offset = font_metrics.capHeight() / 2.0; + + p.setCompositionMode(QPainter::CompositionMode_Plus); + + p.setPen(QColor(0.0, 0.6 * 255.0, 0.0)); + p.setFont(QFont()); + + for (int i=0; i <= ire_steps; i++) { + ire_lines[i].setLine( + waveform_start_dim_x, + (waveform_dim_y * (i * ire_increment)) + waveform_start_dim_y, + waveform_end_dim_x, + (waveform_dim_y * (i * ire_increment)) + waveform_start_dim_y); + label = QString::number(1.0 - (i * ire_increment), 'f', 1); + font_x_offset = QFontMetricsWidth(font_metrics, label) + 4; + + p.drawText( + waveform_start_dim_x - font_x_offset, + (waveform_dim_y * (i * ire_increment)) + waveform_start_dim_y + font_y_offset, + label); + } + p.drawLines(ire_lines); } }