diff --git a/effects/bulge.frag b/effects/bulge.frag index 98f44d3fd..ef950d2df 100644 --- a/effects/bulge.frag +++ b/effects/bulge.frag @@ -1,31 +1,31 @@ -#version 110 +#version 120 +uniform sampler2D tex0; +varying vec4 vTexCoord; +const float PI = 3.1415926535; +uniform vec2 resolution; uniform float amount; +uniform float xoff; +uniform float yoff; -uniform sampler2D myTexture; -varying vec2 vTexCoord; +vec2 distort(vec2 p, vec2 offset) { + float theta = atan(p.y, p.x); + float radius = length(p); + radius = pow(radius, (1.0+amount*0.01)); + p.x = radius * cos(theta) + offset.x; + p.y = radius * sin(theta) + offset.y; + return 0.5 * (p + 1.0); +} void main(void) { - float x = vTexCoord.x; - float y = vTexCoord.y; - - float r = sqrt(pow(x - 0.5, 2.0) + pow(y - 0.5, 2.0)); - float a = atan(y - 0.5, x - 0.5); - float rn = pow(r, (amount*0.1))/0.5; - //float a = atan(x - 0.5, y - 0.5); - - x = rn * cos(a) + 0.5; - y = rn * sin(a) + 0.5; - - if (y < 0.0 || y > 1.0 || x < 0.0 || x > 1.0) { - gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); + vec2 offset = vec2(xoff/resolution.x, yoff/resolution.y); + vec2 xy = 2.0 * vTexCoord.xy - 1.0 - offset; + vec2 uv; + float d = length(xy); + uv = distort(xy, offset); + if (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) { + gl_FragColor = texture2D(tex0, uv); } else { - vec4 textureColor = texture2D(myTexture, vec2(x, y)); - gl_FragColor = vec4( - textureColor.r, - textureColor.g, - textureColor.b, - textureColor.a - ); + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); } } \ No newline at end of file diff --git a/effects/bulge.xml b/effects/bulge.xml index c49b15df9..bad26c9e8 100644 --- a/effects/bulge.xml +++ b/effects/bulge.xml @@ -1,7 +1,11 @@ - + + + + + \ No newline at end of file diff --git a/effects/cornerpin.vert b/effects/cornerpin.vert index de1eacb8c..391718f60 100644 --- a/effects/cornerpin.vert +++ b/effects/cornerpin.vert @@ -24,10 +24,10 @@ void main() { float mid_x = (c2 - c1) / (m1 - m2); float mid_y = m1 * mid_x + c1; - float d0 = sqrt(pow(mid_x - p0.x, 2.0) + pow(mid_y - p0.y, 2.0)); - float d1 = sqrt(pow(p1.x - mid_x, 2.0) + pow(mid_y - p1.y, 2.0)); - float d2 = sqrt(pow(p3.x - mid_x, 2.0) + pow(p3.y - mid_y, 2.0)); - float d3 = sqrt(pow(mid_x - p2.x, 2.0) + pow(p2.y - mid_y, 2.0)); + float d0 = length(vec2(mid_x - p0.x, mid_y - p0.y)); + float d1 = length(vec2(p1.x - mid_x, mid_y - p1.y)); + float d2 = length(vec2(p3.x - mid_x, p3.y - mid_y)); + float d3 = length(vec2(mid_x - p2.x, p2.y - mid_y)); float q; diff --git a/effects/directionalblur.frag b/effects/directionalblur.frag index 5ca6d8e50..4a5f24a18 100644 --- a/effects/directionalblur.frag +++ b/effects/directionalblur.frag @@ -4,16 +4,16 @@ uniform sampler2D image; -uniform float angle; +uniform float angle; // degrees uniform float length; uniform vec2 resolution; void main(void) { - float degrees = (angle*M_PI)/180.0; + float radians = (angle*M_PI)/180.0; float divider = 1.0 / ((length*2.0)+1.0); - float sin_angle = sin(degrees); - float cos_angle = cos(degrees); + float sin_angle = sin(radians); + float cos_angle = cos(radians); gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(divider); for (float i=1.0;i<=length;i++) { diff --git a/effects/fisheye.frag b/effects/fisheye.frag new file mode 100644 index 000000000..9e8aa1e3b --- /dev/null +++ b/effects/fisheye.frag @@ -0,0 +1,27 @@ +#version 120 +uniform sampler2D tex0; +varying vec4 vTexCoord; +#define M_PI 3.1415926535897932384626433832795 + +uniform float size; + +void main(void) { + float maxFactor = 2.0 - (size * 0.01); + + vec2 uv; + vec2 xy = 2.0 * vTexCoord.xy - 1.0; + float d = length(xy); + if (d < (2.0-maxFactor)) { + d = length(xy * maxFactor); + float z = sqrt(1.0 - d * d); + float r = atan(d, z) / M_PI; + float phi = atan(xy.y, xy.x); + + uv.x = r * cos(phi) + 0.5; + uv.y = r * sin(phi) + 0.5; + } else { + uv = vTexCoord.xy; + } + vec4 c = texture2D(tex0, uv); + gl_FragColor = c; +} \ No newline at end of file diff --git a/effects/fisheye.xml b/effects/fisheye.xml new file mode 100644 index 000000000..b94302289 --- /dev/null +++ b/effects/fisheye.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/effects/invert.xml b/effects/invert.xml index bc2ee42fb..0e5d38a64 100644 --- a/effects/invert.xml +++ b/effects/invert.xml @@ -1,7 +1,7 @@ - + - + - + \ No newline at end of file diff --git a/effects/radialblur.frag b/effects/radialblur.frag new file mode 100644 index 000000000..b857d3258 --- /dev/null +++ b/effects/radialblur.frag @@ -0,0 +1,35 @@ +#version 110 + +#define M_PI 3.1415926535897932384626433832795 + +uniform sampler2D image; +uniform float radius; +uniform float center_x; +uniform float center_y; + +uniform vec2 resolution; + +void main(void) { + vec2 distance = vec2((gl_FragCoord.x - (resolution.x/2.0) - center_x), (gl_FragCoord.y - (resolution.y/2.0) - center_y)); + + float angle = atan(distance.y/distance.x); + float sin_angle = sin(angle); + float cos_angle = cos(angle); + + //float multiplier = pow(length((2.0 * (distance / resolution)) - 1.0), 2.0); + float multiplier = length(distance/resolution); + + float limit = radius * multiplier; + + float divider = 1.0 / ((floor(limit)*2.0)+1.0); + + gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(divider); + + for (float i=1.0;i<=limit;i++) { + float y = sin_angle * i; + float x = cos_angle * i; + + gl_FragColor += texture2D(image, vec2(gl_FragCoord.x-x, gl_FragCoord.y-y)/resolution)*(divider); + gl_FragColor += texture2D(image, vec2(gl_FragCoord.x+x, gl_FragCoord.y+y)/resolution)*(divider); + } +} \ No newline at end of file diff --git a/effects/radialblur.xml b/effects/radialblur.xml new file mode 100644 index 000000000..1bd3af991 --- /dev/null +++ b/effects/radialblur.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/effects/test.xml b/effects/test.xml new file mode 100644 index 000000000..09da020b5 --- /dev/null +++ b/effects/test.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/toonify.frag b/effects/toonify.frag new file mode 100644 index 000000000..9a7061e32 --- /dev/null +++ b/effects/toonify.frag @@ -0,0 +1,168 @@ +#version 150 +uniform sampler2D tex0; +in vec4 vTexCoord; +out vec4 FragColor; + +uniform float colors; // 12.0 +uniform float sat_levels; // 4.0 +uniform float bri_levels; // 4.0 +uniform float edge_thres; // 0.2; +uniform float edge_thres2; // 5.0; + +vec3 RGBtoHSV( float r, float g, float b) +{ + float minv, maxv, delta; + vec3 res; + + minv = min(min(r, g), b); + maxv = max(max(r, g), b); + res.z = maxv; // v + + delta = maxv - minv; + + if( maxv != 0.0 ) + res.y = delta / maxv; // s + else { + // r = g = b = 0 // s = 0, v is undefined + res.y = 0.0; + res.x = -1.0; + return res; + } + + if( r == maxv ) + res.x = ( g - b ) / delta; // between yellow & magenta + else if( g == maxv ) + res.x = 2.0 + ( b - r ) / delta; // between cyan & yellow + else + res.x = 4.0 + ( r - g ) / delta; // between magenta & cyan + + res.x = res.x * 60.0; // degrees + if( res.x < 0.0 ) + res.x = res.x + 360.0; + + return res; +} + +vec3 HSVtoRGB(float h, float s, float v ) +{ + int i; + float f, p, q, t; + vec3 res; + + if( s == 0.0 ) + { + // achromatic (grey) + res.x = v; + res.y = v; + res.z = v; + return res; + } + + h /= 60.0; // sector 0 to 5 + i = int(floor( h )); + f = h - float(i); // factorial part of h + p = v * ( 1.0 - s ); + q = v * ( 1.0 - s * f ); + t = v * ( 1.0 - s * ( 1.0 - f ) ); + + switch(i) + { + case 0: + res.x = v; + res.y = t; + res.z = p; + break; + case 1: + res.x = q; + res.y = v; + res.z = p; + break; + case 2: + res.x = p; + res.y = v; + res.z = t; + break; + case 3: + res.x = p; + res.y = q; + res.z = v; + break; + case 4: + res.x = t; + res.y = p; + res.z = v; + break; + default: // case 5: + res.x = v; + res.y = p; + res.z = q; + break; + } + return res; +} + +// averaged pixel intensity from 3 color channels +float avg_intensity(vec4 pix) +{ + return (pix.r + pix.g + pix.b)/3.; +} + +vec4 get_pixel(vec2 coords, float dx, float dy) +{ + return texture(tex0,coords + vec2(dx, dy)); +} + +// returns pixel color +float IsEdge(in vec2 coords) +{ + float dxtex = 1.0 /float(textureSize(tex0,0)) ; + float dytex = 1.0 /float(textureSize(tex0,0)); + float pix[9]; + int k = -1; + float delta; + + // read neighboring pixel intensities + for (int i=-1; i<2; i++) { + for(int j=-1; j<2; j++) { + k++; + pix[k] = avg_intensity(get_pixel(coords,float(i)*dxtex, + float(j)*dytex)); + } + } + + // average color differences around neighboring pixels + delta = (abs(pix[1]-pix[7])+ + abs(pix[5]-pix[3]) + + abs(pix[0]-pix[8])+ + abs(pix[2]-pix[6]) + )/4.; + + //return clamp(5.5*delta,0.0,1.0); + return clamp(edge_thres2*delta,0.0,1.0); +} + +void main() { + vec2 uv = vTexCoord.xy; + vec4 tc = vec4(1.0, 0.0, 0.0, 1.0); + vec3 colorOrg = texture(tex0, uv).rgb; + vec3 vHSV = RGBtoHSV(colorOrg.r,colorOrg.g,colorOrg.b); + + // hue limiting + if (colors == 0.0) { + vHSV.y = 0.0; + } else { + float hue_divider = (360.0/colors); + vHSV.x = round(vHSV.x/hue_divider)*hue_divider; + + float sat_divider = 100.0/sat_levels; + vHSV.y = round((vHSV.y*100.0)/sat_divider)*sat_divider/100.0; + } + + float bri_divider = 100.0/bri_levels; + vHSV.z = round((vHSV.z*100.0)/bri_divider)*bri_divider/100.0; + + float edg = IsEdge(uv); + vec3 vRGB = (edg >= (1.0-((edge_thres-1.0)*0.01)))? vec3(0.0,0.0,0.0):HSVtoRGB(vHSV.x,vHSV.y,vHSV.z); + tc = vec4(vRGB.x,vRGB.y,vRGB.z, 1); + FragColor = tc; +} \ No newline at end of file diff --git a/effects/toonify.xml b/effects/toonify.xml new file mode 100644 index 000000000..81e9a5c68 --- /dev/null +++ b/effects/toonify.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/volumetriclight.frag b/effects/volumetriclight.frag new file mode 100644 index 000000000..3ec626c77 --- /dev/null +++ b/effects/volumetriclight.frag @@ -0,0 +1,15 @@ +#version 110 + +uniform float amount; + +uniform sampler2D tex0; +uniform vec2 resolution; // screen resolution +#define T texture2D(tex0,.5+(p.xy*=.992)) +void main() +{ + vec3 p = gl_FragCoord.xyz/vec3(resolution, 1.0)-.5; + vec3 o = T.rgb; + for (float i=0.;iready_lock.unlock(); media->ready = true; - - if (media->video_tracks.size() == 0) { - emit set_icon(ICON_TYPE_AUDIO, replace); - } else if (contains_still_image) { - emit set_icon(ICON_TYPE_IMAGE, replace); - } else { - emit set_icon(ICON_TYPE_VIDEO, replace); - } - - if (!contains_still_image || media->audio_tracks.size() > 0) { - double frame_rate = 30; - if (!contains_still_image && media->video_tracks.size() > 0) frame_rate = media->video_tracks.at(0)->video_frame_rate; - item->setText(1, frame_to_timecode(media->get_length_in_frames(frame_rate), config.timecode_view, frame_rate)); - - if (media->video_tracks.size() > 0) { - item->setText(2, QString::number(frame_rate) + " FPS"); + if (!cancelled) { + if (media->video_tracks.size() == 0) { + emit set_icon(ICON_TYPE_AUDIO, replace); + } else if (contains_still_image) { + emit set_icon(ICON_TYPE_IMAGE, replace); } else { - item->setText(2, QString::number(media->audio_tracks.at(0)->audio_frequency) + " Hz"); + emit set_icon(ICON_TYPE_VIDEO, replace); + } + + if (!contains_still_image || media->audio_tracks.size() > 0) { + double frame_rate = 30; + if (!contains_still_image && media->video_tracks.size() > 0) frame_rate = media->video_tracks.at(0)->video_frame_rate; + item->setText(1, frame_to_timecode(media->get_length_in_frames(frame_rate), config.timecode_view, frame_rate)); + + if (media->video_tracks.size() > 0) { + item->setText(2, QString::number(frame_rate) + " FPS"); + } else { + item->setText(2, QString::number(media->audio_tracks.at(0)->audio_frequency) + " Hz"); + } } } } diff --git a/project/undo.cpp b/project/undo.cpp index 6eecffd2e..47b3b33c2 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -360,15 +360,8 @@ AddMediaCommand::~AddMediaCommand() { } void AddMediaCommand::undo() { - if (parent == NULL) { - bool found = false; - for (int i=0;isource_table->topLevelItemCount();i++) { - if (panel_project->source_table->topLevelItem(i) == item) { - panel_project->source_table->takeTopLevelItem(i); - found = true; - break; - } - } + if (parent == NULL) { + panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(item)); } else { parent->removeChild(item); } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index e09e4163d..bfef743df 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -2337,8 +2337,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } } - // draw insert indicator - dout << panel_timeline->move_insert << insert_points.isEmpty(); + // draw insert indicator if (panel_timeline->move_insert && !insert_points.isEmpty()) { p.setBrush(Qt::white); p.setPen(Qt::NoPen); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index e3af97d0e..b8a0d238d 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -597,64 +597,66 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) } void ViewerWidget::paintGL() { - bool render_audio = (viewer->playing || rendering); - bool loop = false; - do { - loop = false; + if (viewer->seq != NULL) { + bool render_audio = (viewer->playing || rendering); + bool loop = false; + do { + loop = false; - glClearColor(0, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + glClearColor(0, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); - texture_failed = false; + texture_failed = false; - if (!rendering) retry_timer.stop(); + if (!rendering) retry_timer.stop(); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); - // compose video preview - glClearColor(0, 0, 0, 0); + // compose video preview + glClearColor(0, 0, 0, 0); - QVector nests; + QVector nests; - compose_sequence(nests, render_audio); + compose_sequence(nests, render_audio); - if (waveform) { - double waveform_zoom = (double) waveform_ms->audio_preview.size() / (double) width(); - double timeline_zoom = (double) width() / (double) waveform_clip->timeline_out; + if (waveform) { + double waveform_zoom = (double) waveform_ms->audio_preview.size() / (double) width(); + double timeline_zoom = (double) width() / (double) waveform_clip->timeline_out; - QPainter p(this); - if (viewer->seq->using_workarea) { - int in_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_in); - int out_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_out); + QPainter p(this); + if (viewer->seq->using_workarea) { + int in_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_in); + int out_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_out); - p.fillRect(QRect(in_x, 0, out_x - in_x, height()), QColor(255, 255, 255, 64)); - p.setPen(Qt::white); - p.drawLine(in_x, 0, in_x, height()); - p.drawLine(out_x, 0, out_x, height()); - } - p.setPen(Qt::green); - draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, rect(), 0, width(), waveform_zoom); - p.setPen(Qt::red); - int playhead_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->playhead); - p.drawLine(playhead_x, 0, playhead_x, height()); - } + p.fillRect(QRect(in_x, 0, out_x - in_x, height()), QColor(255, 255, 255, 64)); + p.setPen(Qt::white); + p.drawLine(in_x, 0, in_x, height()); + p.drawLine(out_x, 0, out_x, height()); + } + p.setPen(Qt::green); + draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, rect(), 0, width(), waveform_zoom); + p.setPen(Qt::red); + int playhead_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->playhead); + p.drawLine(playhead_x, 0, playhead_x, height()); + } - if (texture_failed) { - if (rendering) { - dout << "[INFO] Texture failed - looping"; - loop = true; - } else { - retry_timer.start(); - } - } + if (texture_failed) { + if (rendering) { + dout << "[INFO] Texture failed - looping"; + loop = true; + } else { + retry_timer.start(); + } + } - if (config.show_title_safe_area && !rendering) { - drawTitleSafeArea(); - } + if (config.show_title_safe_area && !rendering) { + drawTitleSafeArea(); + } - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - } while (loop); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + } while (loop); + } }