From 80badaa5a81ab9f99302e6b89a479e0860df8988 Mon Sep 17 00:00:00 2001 From: Troy James Sobotka Date: Mon, 11 May 2020 16:07:15 -0700 Subject: [PATCH] Waveform Fixes and Modifications Fixes: * Values exceeding the encoded range. Future may account for a certain range above and below current values. * Minor calculation problem that prevented the above fix from working properly. * Streamlined the shader code. * Add a vertex shader to handle the scaling. * Use the viewport resolution as the scaled version to save performance. --- app/shaders/rgbwaveform.frag | 71 ++++++++------------------ app/shaders/rgbwaveform.vert | 29 +++++++++++ app/widget/scope/waveform/waveform.cpp | 42 ++++++--------- 3 files changed, 65 insertions(+), 77 deletions(-) create mode 100644 app/shaders/rgbwaveform.vert diff --git a/app/shaders/rgbwaveform.frag b/app/shaders/rgbwaveform.frag index 4e6b13f08..e568b37cd 100644 --- a/app/shaders/rgbwaveform.frag +++ b/app/shaders/rgbwaveform.frag @@ -1,6 +1,3 @@ -// Adapted from "RGB Waveform" by lebek -// https://www.shadertoy.com/view/4dK3Wc - #version 150 uniform sampler2D ove_maintex; @@ -9,64 +6,36 @@ uniform vec2 ove_viewport; uniform vec3 luma_coeffs; uniform float waveform_scale; -uniform vec2 waveform_dims; -uniform vec4 waveform_region; -uniform vec4 waveform_uv; in vec2 ove_texcoord; out vec4 fragColor; void main(void) { - vec3 col = vec3(0.0); - // 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; - - // 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 waveform_height = ceil(waveform_scale * ove_viewport.y); + float quantisation = 1.0 / (waveform_height - 1.0); float intensity = 0.10; + vec4 col = vec4(0.0); + vec4 cur_col = vec4(0.0); + float ratio = 0.0; - int y_lim = int(waveform_dims.y); + for (int i = 0; i < waveform_height; i++) { + ratio = float(i) / float(waveform_height - 1.0); + cur_col.rgb = texture( + ove_maintex, + vec2(ove_texcoord.x, ratio) + ).rgb; - vec3 cur_col = vec3(0.0); - vec3 cur_lum = vec3(0.0); + cur_col.w = dot(cur_col.rgb, luma_coeffs); - 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 - 1); - 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; - } + col += ( + step(vec4(ove_texcoord.y - quantisation), cur_col) * + step(cur_col, vec4(ove_texcoord.y + quantisation)) * + intensity) + + (step(1.0 - quantisation, ove_texcoord.y) * + step(vec4(1.0 - quantisation), cur_col) * intensity); } - fragColor = vec4(col, 1.0); + col.rgb += vec3(col.w); + fragColor = vec4(col.rgb, 1.0); } diff --git a/app/shaders/rgbwaveform.vert b/app/shaders/rgbwaveform.vert new file mode 100644 index 000000000..88fde9934 --- /dev/null +++ b/app/shaders/rgbwaveform.vert @@ -0,0 +1,29 @@ +#version 150 + +uniform float waveform_scale; +uniform vec2 ove_resolution; + +in vec4 a_position; +in vec2 a_texcoord; + +out vec2 ove_texcoord; + +mat4 scale_mat4(vec3 scale) { + return mat4( + scale.x, 0.0, 0.0, 0.0, + 0.0, scale.y, 0.0, 0.0, + 0.0, 0.0, scale.z, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); +} + +void main() { + // Create identity matrix + mat4 transform = mat4(1.0); + + // Scale the scope + transform *= scale_mat4(vec3(waveform_scale, waveform_scale, 1.0)); + + gl_Position = transform * a_position; + ove_texcoord = a_texcoord; +} \ No newline at end of file diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp index daefe84e7..ff4f1296b 100644 --- a/app/widget/scope/waveform/waveform.cpp +++ b/app/widget/scope/waveform/waveform.cpp @@ -41,8 +41,10 @@ OpenGLShaderPtr WaveformScope::CreateShader() OpenGLShaderPtr pipeline = OpenGLShader::Create(); pipeline->create(); - pipeline->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex()); - pipeline->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(":/shaders/rgbwaveform.frag")); + pipeline->addShaderFromSourceCode(QOpenGLShader::Vertex, + Node::ReadFileAsString(":/shaders/rgbwaveform.vert")); + pipeline->addShaderFromSourceCode(QOpenGLShader::Fragment, + Node::ReadFileAsString(":/shaders/rgbwaveform.frag")); pipeline->link(); return pipeline; @@ -51,12 +53,6 @@ OpenGLShaderPtr WaveformScope::CreateShader() void WaveformScope::DrawScope() { float waveform_scale = 0.80f; - float waveform_dim_x = width() * waveform_scale; - float waveform_dim_y = height() * waveform_scale; - float waveform_start_dim_x = (width() - waveform_dim_x) / 2.0f; - float waveform_start_dim_y = (height() - waveform_dim_y) / 2.0f; - float waveform_end_dim_x = width() - waveform_start_dim_x; - float waveform_end_dim_y = height() - waveform_start_dim_y; // Draw waveform through shader pipeline()->bind(); @@ -68,22 +64,6 @@ void WaveformScope::DrawScope() // Scale of the waveform relative to the viewport surface. pipeline()->setUniformValue("waveform_scale", waveform_scale); - pipeline()->setUniformValue( - "waveform_dims", waveform_dim_x, waveform_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(); @@ -93,9 +73,19 @@ void WaveformScope::DrawScope() managed_tex().Release(); + float waveform_dim_x = ceil((width() - 1.0) * waveform_scale); + float waveform_dim_y = ceil((height() - 1.0) * waveform_scale); + float waveform_start_dim_x = + ((width() - 1.0) - waveform_dim_x) / 2.0f; + float waveform_start_dim_y = + ((height() - 1.0) - waveform_dim_y) / 2.0f; + float waveform_end_dim_x = (width() - 1.0) - waveform_start_dim_x; + // Draw line overlays QPainter p(this); - QFontMetrics font_metrics = QFontMetrics(QFont()); + QFont font; + font.setPixelSize(10); + QFontMetrics font_metrics = QFontMetrics(font); QString label; float ire_increment = 0.1f; int ire_steps = qRound(1.0 / ire_increment); @@ -106,7 +96,7 @@ void WaveformScope::DrawScope() p.setCompositionMode(QPainter::CompositionMode_Plus); p.setPen(QColor(0.0, 0.6 * 255.0, 0.0)); - p.setFont(QFont()); + p.setFont(font); for (int i=0; i <= ire_steps; i++) { ire_lines[i].setLine(