X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fplayback3d.C;h=04c668be0de57f495b1dc9d51c92051bdd18182d;hb=5621db270ccbeabc106e0f438941dba6f930652b;hp=f733105ff231bb18b1b648c69b860f3fb7895701;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index f733105f..04c668be 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -21,6 +21,7 @@ #define GL_GLEXT_PROTOTYPES +#include "bccolors.h" #include "bcsignals.h" #include "bcwindowbase.h" #include "canvas.h" @@ -30,6 +31,7 @@ #include "maskauto.h" #include "mutex.h" #include "overlayframe.inc" +#include "overlayframe.h" #include "playback3d.h" #include "pluginclient.h" #include "pluginvclient.h" @@ -46,6 +48,8 @@ #include #include +#define QQ(q)#q +#define SS(s)QQ(s) // Shaders @@ -53,16 +57,15 @@ // Can't hard code sampler2D +#ifdef HAVE_GL static const char *yuv_to_rgb_frag = "uniform sampler2D tex;\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 yuva = texture2D(tex, gl_TexCoord[0].st);\n" - " yuva.rgb -= vec3(0, 0.5, 0.5);\n" - " const mat3 yuv_to_rgb_matrix = mat3(\n" - " 1, 1, 1, \n" - " 0, -0.34414, 1.77200, \n" - " 1.40200, -0.71414, 0);\n" + " yuva.rgb -= vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = vec4(yuv_to_rgb_matrix * yuva.rgb, yuva.a);\n" "}\n"; @@ -82,14 +85,12 @@ static const char *yuva_to_yuv_frag = static const char *yuva_to_rgb_frag = "uniform sampler2D tex;\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 yuva = texture2D(tex, gl_TexCoord[0].st);\n" - " yuva.rgb -= vec3(0, 0.5, 0.5);\n" - " const mat3 yuv_to_rgb_matrix = mat3(\n" - " 1, 1, 1, \n" - " 0, -0.34414, 1.77200, \n" - " 1.40200, -0.71414, 0);\n" + " yuva.rgb -= vec3(yminf, 0.5, 0.5);\n" " yuva.rgb = yuv_to_rgb_matrix * yuva.rgb;\n" " yuva.rgb *= yuva.a;\n" " yuva.a = 1.0;\n" @@ -98,15 +99,13 @@ static const char *yuva_to_rgb_frag = static const char *rgb_to_yuv_frag = "uniform sampler2D tex;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 rgba = texture2D(tex, gl_TexCoord[0].st);\n" - " const mat3 rgb_to_yuv_matrix = mat3(\n" - " 0.29900, -0.16874, 0.50000, \n" - " 0.58700, -0.33126, -0.41869, \n" - " 0.11400, 0.50000, -0.08131);\n" " rgba.rgb = rgb_to_yuv_matrix * rgba.rgb;\n" - " rgba.rgb += vec3(0, 0.5, 0.5);\n" + " rgba.rgb += vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = rgba;\n" "}\n"; @@ -123,17 +122,15 @@ static const char *rgba_to_rgb_frag = static const char *rgba_to_yuv_frag = "uniform sampler2D tex;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 rgba = texture2D(tex, gl_TexCoord[0].st);\n" - " const mat3 rgb_to_yuv_matrix = mat3(\n" - " 0.29900, -0.16874, 0.50000, \n" - " 0.58700, -0.33126, -0.41869, \n" - " 0.11400, 0.50000, -0.08131);\n" " rgba.rgb *= rgba.a;\n" " rgba.a = 1.0;\n" " rgba.rgb = rgb_to_yuv_matrix * rgba.rgb;\n" - " rgba.rgb += vec3(0, 0.5, 0.5);\n" + " rgba.rgb += vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = rgba;\n" "}\n"; @@ -143,302 +140,114 @@ static const char *rgba_to_rgb_flatten = " gl_FragColor.a = 1.0;\n" "}\n"; -// NORMAL -static const char *blend_normal_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas * (1.0 - gl_FragColor.a) + gl_FragColor * gl_FragColor.a;\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// ADDITION -static const char *blend_add_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas + gl_FragColor;\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// SUBTRACT -static const char *blend_subtract_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = gl_FragColor - canvas;\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; +#define GL_STD_BLEND(FN) \ +static const char *blend_##FN##_frag = \ + "uniform sampler2D tex2;\n" \ + "uniform vec2 tex2_dimensions;\n" \ + "uniform float alpha;\n" \ + "void main() {\n" \ + " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" \ + " vec4 result;\n" \ + " result.rgb = " SS(COLOR_##FN(1.0, gl_FragColor.rgb, gl_FragColor.a, canvas.rgb, canvas.a)) ";\n" \ + " result.a = " SS(ALPHA_##FN(1.0, gl_FragColor.a, canvas.a)) ";\n" \ + " gl_FragColor = mix(canvas, result, alpha);\n" \ + "}\n" + +#define GL_VEC_BLEND(FN) \ +static const char *blend_##FN##_frag = \ + "uniform sampler2D tex2;\n" \ + "uniform vec2 tex2_dimensions;\n" \ + "uniform float alpha;\n" \ + "void main() {\n" \ + " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" \ + " vec4 result;\n" \ + " result.r = " SS(COLOR_##FN(1.0, gl_FragColor.r, gl_FragColor.a, canvas.r, canvas.a)) ";\n" \ + " result.g = " SS(COLOR_##FN(1.0, gl_FragColor.g, gl_FragColor.a, canvas.g, canvas.a)) ";\n" \ + " result.b = " SS(COLOR_##FN(1.0, gl_FragColor.b, gl_FragColor.a, canvas.b, canvas.a)) ";\n" \ + " result.a = " SS(ALPHA_##FN(1.0, gl_FragColor.a, canvas.a)) ";\n" \ + " result = clamp(result, 0.0, 1.0);\n" \ + " gl_FragColor = mix(canvas, result, alpha);\n" \ + "}\n" + +#undef mabs +#define mabs abs +#undef mmin +#define mmin min +#undef mmax +#define mmax max + +#undef ZERO +#define ZERO 0.0 +#undef ONE +#define ONE 1.0 +#undef TWO +#define TWO 2.0 -// MULTIPLY -static const char *blend_multiply_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas * gl_FragColor;\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DIVIDE -static const char *blend_divide_frag = +// NORMAL +static const char *blend_NORMAL_frag = "uniform sampler2D tex2;\n" "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = gl_FragColor / canvas;\n" - " if(!canvas.r) result.r = 1.0;\n" - " if(!canvas.g) result.g = 1.0;\n" - " if(!canvas.b) result.b = 1.0;\n" - " if(!canvas.a) result.a = 1.0;\n" - " result = clamp(result, 0.0, 1.0);\n" + " vec4 result = mix(canvas, gl_FragColor, gl_FragColor.a);\n" " gl_FragColor = mix(canvas, result, alpha);\n" "}\n"; // REPLACE -static const char *blend_replace_frag = - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - "}\n"; - -// MAX -static const char *blend_max_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = max(canvas, gl_FragColor);\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// MIN -static const char *blend_min_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = min(canvas, gl_FragColor);\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// AVERAGE -static const char *blend_average_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = (canvas + gl_FragColor) * 0.5;\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DARKEN -static const char *blend_darken_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +" - " gl_FragColor.rgb * (1.0 - canvas.a) +" - " min(canvas.rgb, gl_FragColor.rgb), " - " canvas.a + gl_FragColor.a - canvas.a * gl_FragColor.a);\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// LIGHTEN -static const char *blend_lighten_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(canvas.rgb * (1.0 - gl_FragColor.a) +" - " gl_FragColor.rgb * (1.0 - canvas.a) +" - " max(canvas.rgb, gl_FragColor.rgb), " - " canvas.a + gl_FragColor.a - canvas.a * gl_FragColor.a);\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DST -static const char *blend_dst_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" -// " gl_FragColor.a *= alpha;\n" -// " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" -// " vec4 result = canvas;\n" -// " gl_FragColor = mix(result, canvas, alpha);\n" - " gl_FragColor = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - "}\n"; - -// DST_ATOP -static const char *blend_dst_atop_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(canvas.rgb * gl_FragColor.a + " - "(1.0 - canvas.a) * gl_FragColor.rgb, gl_FragColor.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DST_IN -static const char *blend_dst_in_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas * gl_FragColor.a;\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DST_OUT -static const char *blend_dst_out_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" +static const char *blend_REPLACE_frag = "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas * (1.0 - gl_FragColor.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// DST_OVER -static const char *blend_dst_over_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(canvas.rgb + (1.0 - canvas.a) * gl_FragColor.rgb, " - " gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// SRC -static const char *blend_src_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = gl_FragColor;\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// SRC_ATOP -static const char *blend_src_atop_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(gl_FragColor.rgb * canvas.a + " - "canvas.rgb * (1.0 - gl_FragColor.a), canvas.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" "}\n"; -// SRC_IN -static const char *blend_src_in_frag = +// ADDITION +static const char *blend_ADDITION_frag = "uniform sampler2D tex2;\n" "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = gl_FragColor * canvas.a;\n" + " vec4 result = clamp(gl_FragColor + canvas, 0.0, 1.0);\n" " gl_FragColor = mix(canvas, result, alpha);\n" "}\n"; -// SRC_OUT -static const char *blend_src_out_frag = +// SUBTRACT +static const char *blend_SUBTRACT_frag = "uniform sampler2D tex2;\n" "uniform vec2 tex2_dimensions;\n" "uniform float alpha;\n" "void main() {\n" - " gl_FragColor.a *= alpha;\n" " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = gl_FragColor * (1.0 - canvas.a);\n" + " vec4 result = clamp(gl_FragColor - canvas, 0.0, 1.0);\n" " gl_FragColor = mix(canvas, result, alpha);\n" "}\n"; -// SRC_OVER -static const char *blend_src_over_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(gl_FragColor.rgb + (1.0 - gl_FragColor.a) * canvas.rgb, " - "gl_FragColor.a + canvas.a - gl_FragColor.a * canvas.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// OR -static const char *blend_or_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = canvas + gl_FragColor - canvas * gl_FragColor;\n" - " result = clamp(result, 0.0, 1.0);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; - -// XOR -static const char *blend_xor_frag = - "uniform sampler2D tex2;\n" - "uniform vec2 tex2_dimensions;\n" - "uniform float alpha;\n" - "void main() {\n" - " gl_FragColor.a *= alpha;\n" - " vec4 canvas = texture2D(tex2, gl_FragCoord.xy / tex2_dimensions);\n" - " vec4 result = vec4(gl_FragColor.rgb * (1.0 - canvas.a) + " - "(1.0 - gl_FragColor.a) * canvas.rgb, " - "gl_FragColor.a + canvas.a - 2.0 * gl_FragColor.a * canvas.a);\n" - " gl_FragColor = mix(canvas, result, alpha);\n" - "}\n"; +GL_STD_BLEND(MULTIPLY); +GL_VEC_BLEND(DIVIDE); +GL_VEC_BLEND(MAX); +GL_VEC_BLEND(MIN); +GL_VEC_BLEND(DARKEN); +GL_VEC_BLEND(LIGHTEN); +GL_STD_BLEND(DST); +GL_STD_BLEND(DST_ATOP); +GL_STD_BLEND(DST_IN); +GL_STD_BLEND(DST_OUT); +GL_STD_BLEND(DST_OVER); +GL_STD_BLEND(SRC); +GL_STD_BLEND(SRC_ATOP); +GL_STD_BLEND(SRC_IN); +GL_STD_BLEND(SRC_OUT); +GL_STD_BLEND(SRC_OVER); +GL_STD_BLEND(AND); +GL_STD_BLEND(OR); +GL_STD_BLEND(XOR); +GL_VEC_BLEND(OVERLAY); +GL_STD_BLEND(SCREEN); +GL_VEC_BLEND(BURN); +GL_VEC_BLEND(DODGE); +GL_VEC_BLEND(HARDLIGHT); +GL_VEC_BLEND(SOFTLIGHT); +GL_VEC_BLEND(DIFFERENCE); static const char *read_texture_frag = "uniform sampler2D tex;\n" @@ -504,11 +313,7 @@ static const char *fade_yuv_frag = " gl_FragColor.gb += vec2(0.5, 0.5);\n" "}\n"; - - - - - +#endif Playback3DCommand::Playback3DCommand() @@ -762,7 +567,7 @@ void Playback3D::copy_from_sync(Playback3DCommand *command) // command->frame->get_h(), // BC_RGB888, // -1); -// command->frame->to_ram(); +// command->frame->screen_to_ram(); // // window->clear_box(0, // 0, @@ -889,28 +694,15 @@ void Playback3D::draw_output(Playback3DCommand *command) // Undo any previous shader settings command->frame->bind_texture(0); - - - // Convert colormodel - unsigned int frag_shader = 0; - switch(command->frame->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - frag_shader = VFrame::make_shader(0, - yuv_to_rgb_frag, - 0); - break; - } - - - if(frag_shader > 0) - { - glUseProgram(frag_shader); - int variable = glGetUniformLocation(frag_shader, "tex"); + unsigned int shader = !BC_CModels::is_yuv(command->frame->get_color_model()) ? 0 : + VFrame::make_shader(0, yuv_to_rgb_frag, 0); + if( shader > 0 ) { + glUseProgram(shader); // Set texture unit of the texture + int variable = glGetUniformLocation(shader, "tex"); glUniform1i(variable, 0); + BC_GL_YUV_TO_RGB(shader); } if(BC_CModels::components(command->frame->get_color_model()) == 4) @@ -1075,6 +867,7 @@ void Playback3D::do_camera_sync(Playback3DCommand *command) command->frame->set_opengl_state(VFrame::SCREEN); + command->frame->screen_to_ram(); command->canvas->get_canvas()->unlock_window(); } command->canvas->unlock_canvas(); @@ -1112,29 +905,36 @@ void Playback3D::overlay_sync(Playback3DCommand *command) // To do these operations, we need to copy the input buffer to a texture // and blend 2 textures in a shader static const char * const overlay_shaders[TRANSFER_TYPES] = { - blend_normal_frag, // TRANSFER_NORMAL - blend_add_frag, // TRANSFER_ADDITION - blend_subtract_frag, // TRANSFER_SUBTRACT - blend_multiply_frag, // TRANSFER_MULTIPLY - blend_divide_frag, // TRANSFER_DIVIDE - blend_replace_frag, // TRANSFER_REPLACE - blend_max_frag, // TRANSFER_MAX - blend_min_frag, // TRANSFER_MIN - blend_average_frag, // TRANSFER_AVERAGE - blend_darken_frag, // TRANSFER_DARKEN - blend_lighten_frag, // TRANSFER_LIGHTEN - blend_dst_frag, // TRANSFER_DST - blend_dst_atop_frag, // TRANSFER_DST_ATOP - blend_dst_in_frag, // TRANSFER_DST_IN - blend_dst_out_frag, // TRANSFER_DST_OUT - blend_dst_over_frag, // TRANSFER_DST_OVER - blend_src_frag, // TRANSFER_SRC - blend_src_atop_frag, // TRANSFER_SRC_ATOP - blend_src_in_frag, // TRANSFER_SRC_IN - blend_src_out_frag, // TRANSFER_SRC_OUT - blend_src_over_frag, // TRANSFER_SRC_OVER - blend_or_frag, // TRANSFER_OR - blend_xor_frag // TRANSFER_XOR + blend_NORMAL_frag, // TRANSFER_NORMAL + blend_ADDITION_frag, // TRANSFER_ADDITION + blend_SUBTRACT_frag, // TRANSFER_SUBTRACT + blend_MULTIPLY_frag, // TRANSFER_MULTIPLY + blend_DIVIDE_frag, // TRANSFER_DIVIDE + blend_REPLACE_frag, // TRANSFER_REPLACE + blend_MAX_frag, // TRANSFER_MAX + blend_MIN_frag, // TRANSFER_MIN + blend_DARKEN_frag, // TRANSFER_DARKEN + blend_LIGHTEN_frag, // TRANSFER_LIGHTEN + blend_DST_frag, // TRANSFER_DST + blend_DST_ATOP_frag, // TRANSFER_DST_ATOP + blend_DST_IN_frag, // TRANSFER_DST_IN + blend_DST_OUT_frag, // TRANSFER_DST_OUT + blend_DST_OVER_frag, // TRANSFER_DST_OVER + blend_SRC_frag, // TRANSFER_SRC + blend_SRC_ATOP_frag, // TRANSFER_SRC_ATOP + blend_SRC_IN_frag, // TRANSFER_SRC_IN + blend_SRC_OUT_frag, // TRANSFER_SRC_OUT + blend_SRC_OVER_frag, // TRANSFER_SRC_OVER + blend_AND_frag, // TRANSFER_AND + blend_OR_frag, // TRANSFER_OR + blend_XOR_frag, // TRANSFER_XOR + blend_OVERLAY_frag, // TRANSFER_OVERLAY + blend_SCREEN_frag, // TRANSFER_SCREEN + blend_BURN_frag, // TRANSFER_BURN + blend_DODGE_frag, // TRANSFER_DODGE + blend_HARDLIGHT_frag, // TRANSFER_HARDLIGHT + blend_SOFTLIGHT_frag, // TRANSFER_SOFTLIGHT + blend_DIFFERENCE_frag, // TRANSFER_DIFFERENCE }; command->canvas->lock_canvas("Playback3D::overlay_sync"); @@ -1186,8 +986,9 @@ void Playback3D::overlay_sync(Playback3DCommand *command) } - const char *shader_stack[4] = { 0, 0, 0, 0, }; - int total_shaders = 0; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int total_shaders = 0, need_matrix = 0; VFrame::init_screen(canvas_w, canvas_h); @@ -1196,13 +997,10 @@ void Playback3D::overlay_sync(Playback3DCommand *command) // Convert colormodel to RGB if not nested. // The color model setting in the output frame is ignored. - if( command->is_nested <= 0 ) { // not nested - switch(command->input->get_color_model()) { - case BC_YUV888: - case BC_YUVA8888: - shader_stack[total_shaders++] = yuv_to_rgb_frag; - break; - } + if( command->is_nested <= 0 && // not nested + BC_CModels::is_yuv(command->input->get_color_model()) ) { + need_matrix = 1; + shader_stack[total_shaders++] = yuv_to_rgb_frag; } // get the shaders @@ -1235,24 +1033,22 @@ void Playback3D::overlay_sync(Playback3DCommand *command) } // run the shaders - unsigned int frag_shader = 0; - if(shader_stack[0]) { - frag_shader = VFrame::make_shader(0, - shader_stack[0], shader_stack[1], - shader_stack[2], shader_stack[3], 0); - - glUseProgram(frag_shader); - + add_shader(0); + unsigned int shader = !shader_stack[0] ? 0 : + VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); + if( need_matrix ) BC_GL_YUV_TO_RGB(shader); // Set texture unit of the texture - glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); // Set texture unit of the temp texture - glUniform1i(glGetUniformLocation(frag_shader, "tex2"), 1); + glUniform1i(glGetUniformLocation(shader, "tex2"), 1); // Set alpha - int variable = glGetUniformLocation(frag_shader, "alpha"); + int variable = glGetUniformLocation(shader, "alpha"); glUniform1f(variable, command->alpha); // Set dimensions of the temp texture if(temp_texture) - glUniform2f(glGetUniformLocation(frag_shader, "tex2_dimensions"), + glUniform2f(glGetUniformLocation(shader, "tex2_dimensions"), (float)temp_texture->get_texture_w(), (float)temp_texture->get_texture_h()); } @@ -1440,6 +1236,7 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) // Need to tabulate every vertex in persistent memory because // gluTessVertex doesn't copy them. ArrayList coords; + coords.set_array_delete(); for(int i = 0; i < points->total; i++) { MaskPoint *point1 = points->values[i]; @@ -1578,27 +1375,19 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) // For unfeathered masks, we could use a stencil buffer // for further optimization but we also need a YUV algorithm. unsigned int frag_shader = 0; - switch(temp_texture->get_texture_components()) - { - case 3: - if(command->frame->get_color_model() == BC_YUV888) - frag_shader = VFrame::make_shader(0, - multiply_yuvmask3_frag, - 0); - else - frag_shader = VFrame::make_shader(0, - multiply_mask3_frag, - 0); - break; - case 4: - frag_shader = VFrame::make_shader(0, - multiply_mask4_frag, - 0); - break; + switch(temp_texture->get_texture_components()) { + case 3: + frag_shader = VFrame::make_shader(0, + command->frame->get_color_model() == BC_YUV888 ? + multiply_yuvmask3_frag : multiply_mask3_frag, + 0); + break; + case 4: + frag_shader = VFrame::make_shader(0, multiply_mask4_frag, 0); + break; } - if(frag_shader) - { + if( frag_shader ) { int variable; glUseProgram(frag_shader); if((variable = glGetUniformLocation(frag_shader, "tex")) >= 0) @@ -1681,8 +1470,7 @@ void Playback3D::convert_cmodel_sync(Playback3DCommand *command) #ifdef HAVE_GL command->canvas->lock_canvas("Playback3D::convert_cmodel_sync"); - if(command->canvas->get_canvas()) - { + if( command->canvas->get_canvas() ) { BC_WindowBase *window = command->canvas->get_canvas(); window->lock_window("Playback3D::convert_cmodel_sync"); window->enable_opengl(); @@ -1693,47 +1481,45 @@ void Playback3D::convert_cmodel_sync(Playback3DCommand *command) command->frame->to_texture(); // Colormodel permutation - const char *shader = 0; int src_cmodel = command->frame->get_color_model(); int dst_cmodel = command->dst_cmodel; - typedef struct - { - int src; - int dst; + typedef struct { + int src, dst, typ; const char *shader; } cmodel_shader_table_t; - static cmodel_shader_table_t cmodel_shader_table[] = - { - { BC_RGB888, BC_YUV888, rgb_to_yuv_frag }, - { BC_RGB888, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGBA8888, BC_RGB888, rgba_to_rgb_frag }, - { BC_RGBA8888, BC_RGB_FLOAT, rgba_to_rgb_frag }, - { BC_RGBA8888, BC_YUV888, rgba_to_yuv_frag }, - { BC_RGBA8888, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGB_FLOAT, BC_YUV888, rgb_to_yuv_frag }, - { BC_RGB_FLOAT, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGBA_FLOAT, BC_RGB888, rgba_to_rgb_frag }, - { BC_RGBA_FLOAT, BC_RGB_FLOAT, rgba_to_rgb_frag }, - { BC_RGBA_FLOAT, BC_YUV888, rgba_to_yuv_frag }, - { BC_RGBA_FLOAT, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_YUV888, BC_RGB888, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGBA8888, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGB_FLOAT, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGBA_FLOAT, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_RGB888, yuva_to_rgb_frag }, - { BC_YUVA8888, BC_RGBA8888, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_RGB_FLOAT, yuva_to_rgb_frag }, - { BC_YUVA8888, BC_RGBA_FLOAT, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_YUV888, yuva_to_yuv_frag }, + enum { rgb_to_rgb, rgb_to_yuv, yuv_to_rgb, yuv_to_yuv, }; + int type = -1; + static cmodel_shader_table_t cmodel_shader_table[] = { + { BC_RGB888, BC_YUV888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB888, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGBA8888, BC_RGB888, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA8888, BC_RGB_FLOAT, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA8888, BC_YUV888, rgb_to_yuv, rgba_to_yuv_frag }, + { BC_RGBA8888, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB_FLOAT, BC_YUV888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB_FLOAT, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGBA_FLOAT,BC_RGB888, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA_FLOAT,BC_RGB_FLOAT, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA_FLOAT,BC_YUV888, rgb_to_yuv, rgba_to_yuv_frag }, + { BC_RGBA_FLOAT,BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_YUV888, BC_RGB888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGBA8888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGB_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGBA_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_RGB888, yuv_to_rgb, yuva_to_rgb_frag }, + { BC_YUVA8888, BC_RGBA8888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_RGB_FLOAT, yuv_to_rgb, yuva_to_rgb_frag }, + { BC_YUVA8888, BC_RGBA_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_YUV888, yuv_to_yuv, yuva_to_yuv_frag }, }; + const char *shader = 0; int table_size = sizeof(cmodel_shader_table) / sizeof(cmodel_shader_table_t); - for(int i = 0; i < table_size; i++) - { - if(cmodel_shader_table[i].src == src_cmodel && - cmodel_shader_table[i].dst == dst_cmodel) - { + for( int i=0; idst_cmodel, // shader); - if(shader) - { + const char *shader_stack[9]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + if( shader ) { //printf("Playback3D::convert_cmodel_sync %d\n", __LINE__); + shader_stack[current_shader++] = shader; + shader_stack[current_shader] = 0; + unsigned int shader_id = VFrame::make_shader(shader_stack); + command->frame->bind_texture(0); - unsigned int shader_id = -1; - if(shader) - { - shader_id = VFrame::make_shader(0, - shader, - 0); - glUseProgram(shader_id); - glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); + glUseProgram(shader_id); + + glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); + switch( type ) { + case rgb_to_yuv: + BC_GL_RGB_TO_YUV(shader_id); + break; + case yuv_to_rgb: + BC_GL_YUV_TO_RGB(shader_id); + break; } command->frame->draw_texture(); - if(shader) glUseProgram(0); - command->frame->set_opengl_state(VFrame::SCREEN); } @@ -1838,8 +1631,7 @@ void Playback3D::do_fade_sync(Playback3DCommand *command) } - if(frag_shader) - { + if( frag_shader ) { glUseProgram(frag_shader); int variable; if((variable = glGetUniformLocation(frag_shader, "tex")) >= 0)