MaskPoint *ap = points[i];
MaskPoint *bp = (i>=points.size()-1) ?
points[0] : points[i+1];
- int dx = ap->x - bp->x, dy = ap->y - bp->y;
- int segments = (int)(sqrt(dx*dx + dy*dy));
- if( !segments ) continue;
+ int segments = 0;
if( ap->control_x2 == 0 && ap->control_y2 == 0 &&
bp->control_x1 == 0 && bp->control_y1 == 0 )
segments = 1;
float y2 = bp->y + bp->control_y1;
float x3 = bp->x, y3 = bp->y;
+// from Playback3D::do_mask_sync
+ float cx3 = - x0 + 3*x1 - 3*x2 + x3;
+ float cx2 = 3*x0 - 6*x1 + 3*x2;
+ float cx1 = -3*x0 + 3*x1;
+ float cx0 = x0;
+
+ float cy3 = - y0 + 3*y1 - 3*y2 + y3;
+ float cy2 = 3*y0 - 6*y1 + 3*y2;
+ float cy1 = -3*y0 + 3*y1;
+ float cy0 = y0;
+
+ if( segments == 0 ) {
+ float maxaccel1 = fabs(2*cy2) + fabs(6*cy3);
+ float maxaccel2 = fabs(2*cx2) + fabs(6*cx3);
+ float maxaccel = maxaccel1 > maxaccel2 ? maxaccel1 : maxaccel2;
+ float h = 1.0;
+ if( maxaccel > 8.0 ) h = sqrt((8.0) / maxaccel);
+ segments = int(1/h);
+ }
+
for( int j = 0; j <= segments; ++j ) {
float t = (float)j / segments;
- float tpow2 = t * t;
- float tpow3 = t * t * t;
- float invt = 1 - t;
- float invtpow2 = invt * invt;
- float invtpow3 = invt * invt * invt;
-
- int x = (invtpow3 * x0
- + 3 * t * invtpow2 * x1
- + 3 * tpow2 * invt * x2
- + tpow3 * x3);
- int y = (invtpow3 * y0
- + 3 * t * invtpow2 * y1
- + 3 * tpow2 * invt * y2
- + tpow3 * y3);
+ float x = cx0 + t*(cx1 + t*(cx2 + t*cx3));
+ float y = cy0 + t*(cy1 + t*(cy2 + t*cy3));
edge.append(x, y);
}
}
" }\n"
"}\n";
-static const char *alpha_frag =
+static const char *multiply_mask4_frag =
"uniform sampler2D tex;\n"
- "uniform sampler2D tex2;\n"
- "uniform vec2 tex2_dimensions;\n"
- "void main() {\n" \
+ "uniform sampler2D tex1;\n"
+ "void main()\n"
+ "{\n"
" gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n"
- " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n"
- " gl_FragColor.a = canvas.a;\n"
+ " gl_FragColor.a *= texture2D(tex1, gl_TexCoord[0].st).r;\n"
+ "}\n";
+
+static const char *multiply_mask3_frag =
+ "uniform sampler2D tex;\n"
+ "uniform sampler2D tex1;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n"
+ " float a = texture2D(tex1, gl_TexCoord[0].st).r;\n"
+ " gl_FragColor.rgb *= vec3(a, a, a);\n"
+ "}\n";
+
+static const char *multiply_yuvmask3_frag =
+ "uniform sampler2D tex;\n"
+ "uniform sampler2D tex1;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n"
+ " float a = texture2D(tex1, gl_TexCoord[0].st).r;\n"
+ " gl_FragColor.gb -= vec2(0.5, 0.5);\n"
+ " gl_FragColor.rgb *= vec3(a, a, a);\n"
+ " gl_FragColor.gb += vec2(0.5, 0.5);\n"
"}\n";
static const char *fade_rgba_frag =
glDrawBuffers(0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- unsigned int shader = VFrame::make_shader(0, alpha_frag, 0);
+ const char *alpha_shader = BC_CModels::has_alpha(color_model) ?
+ multiply_mask4_frag :
+ !BC_CModels::is_yuv(color_model) ?
+ multiply_mask3_frag :
+ multiply_yuvmask3_frag;
+ unsigned int shader = VFrame::make_shader(0, alpha_shader, 0);
glUseProgram(shader);
if( shader > 0 ) {
command->frame->bind_texture(0);
in->BC_Texture::bind(1);
glUniform1i(glGetUniformLocation(shader, "tex"), 0);
- glUniform1i(glGetUniformLocation(shader, "tex2"), 1);
- glUniform2f(glGetUniformLocation(shader, "tex2_dimensions"),
- (float)in->get_texture_w(),
- (float)in->get_texture_h());
-// if( BC_CModels::components(color_model ) == 4) {
-// glEnable(GL_BLEND);
-// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-// }
+ glUniform1i(glGetUniformLocation(shader, "tex1"), 1);
}
command->frame->draw_texture();
command->frame->set_opengl_state(VFrame::SCREEN);
#undef TWO
#define TWO 2.0
-static const char *blend_NORMAL_frag =
- " vec4 result = mix(src_color, src_color, src_color.a);\n";
-
-static const char *blend_ADDITION_frag =
- " vec4 result = dst_color + src_color;\n"
- " result = clamp(result, 0.0, 1.0);\n";
-
-static const char *blend_SUBTRACT_frag =
- " vec4 result = dst_color - src_color;\n"
- " result = clamp(result, 0.0, 1.0);\n";
-
static const char *blend_REPLACE_frag =
" vec4 result = src_color;\n";
+GL_VEC_FRAG(NORMAL);
+GL_VEC_FRAG(ADDITION);
+GL_VEC_FRAG(SUBTRACT);
GL_STD_FRAG(MULTIPLY);
GL_VEC_FRAG(DIVIDE);
GL_VEC_FRAG(MAX);
dst->init_screen();
src->draw_texture();
break;
- case TRANSFER_NORMAL:
-// Move destination to screen
- if( dst->get_opengl_state() != VFrame::SCREEN ) {
- dst->to_texture();
- dst->enable_opengl();
- dst->init_screen();
- dst->draw_texture();
- }
- src->to_texture();
- dst->enable_opengl();
- dst->init_screen();
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- src->draw_texture();
- break;
default:
src->to_texture();
dst->to_texture();