X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fdissolve%2Fdissolve.C;h=6c04fa07a8081acd6fb89cc83609a4acc4f1ec3c;hb=af44bff549c39ac8bb6e42a791e7a211e1013526;hp=d264f6cf7091a7863df5032582ed5160faa73697;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/dissolve/dissolve.C b/cinelerra-5.1/plugins/dissolve/dissolve.C index d264f6cf..6c04fa07 100644 --- a/cinelerra-5.1/plugins/dissolve/dissolve.C +++ b/cinelerra-5.1/plugins/dissolve/dissolve.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "dissolve.h" @@ -56,7 +56,7 @@ int DissolveMain::uses_gui() { return 0; } int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing) { - fade = (float)PluginClient::get_source_position() / + fade = (float)PluginClient::get_source_position() / PluginClient::get_total_len(); // Use hardware @@ -69,78 +69,10 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing) // Use software if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1); - -// There is a problem when dissolving from a big picture to a small picture. -// In order to make it dissolve correctly, we have to manually decrese alpha of big picture. - switch (outgoing->get_color_model()) - { - case BC_RGBA8888: - case BC_YUVA8888: - { - uint8_t** data_rows = (uint8_t **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - uint8_t* alpha_chan = data_rows[i] + 3; - for(int j = 0; j < w; j++) - { - *alpha_chan = (uint8_t) (*alpha_chan * (1-fade)); - alpha_chan+=4; - } - } - break; - } - case BC_YUVA16161616: - { - uint16_t** data_rows = (uint16_t **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - uint16_t* alpha_chan = data_rows[i] + 3; // 3 since this is uint16_t - for(int j = 0; j < w; j++) - { - *alpha_chan = (uint16_t)(*alpha_chan * (1-fade)); - alpha_chan += 8; - } - } - break; - } - case BC_RGBA_FLOAT: - { - float** data_rows = (float **)outgoing->get_rows(); - int w = outgoing->get_w(); - int h = outgoing->get_h(); - for(int i = 0; i < h; i++) - { - float* alpha_chan = data_rows[i] + 3; // 3 since this is floats - for(int j = 0; j < w; j++) - { - *alpha_chan = *alpha_chan * (1-fade); - alpha_chan += sizeof(float); - } - } - break; - } - default: - break; - } - - - overlayer->overlay(outgoing, - incoming, - 0, - 0, - incoming->get_w(), - incoming->get_h(), - 0, - 0, - incoming->get_w(), - incoming->get_h(), - fade, - TRANSFER_NORMAL, - NEAREST_NEIGHBOR); + overlayer->overlay(outgoing, incoming, + 0, 0, incoming->get_w(), incoming->get_h(), + 0, 0, incoming->get_w(), incoming->get_h(), + fade, TRANSFER_SRC, NEAREST_NEIGHBOR); return 0; } @@ -148,35 +80,59 @@ int DissolveMain::process_realtime(VFrame *incoming, VFrame *outgoing) int DissolveMain::handle_opengl() { #ifdef HAVE_GL + static const char *blend_dissolve = + "uniform float fade;\n" + "uniform sampler2D src_tex;\n" + "uniform sampler2D dst_tex;\n" + "uniform vec2 dst_tex_dimensions;\n" + "uniform vec3 chroma_offset;\n" + "void main()\n" + "{\n" + " vec4 result_color;\n" + " vec4 dst_color = texture2D(dst_tex, gl_FragCoord.xy / dst_tex_dimensions);\n" + " vec4 src_color = texture2D(src_tex, gl_TexCoord[0].st);\n" + " src_color.rgb -= chroma_offset;\n" + " dst_color.rgb -= chroma_offset;\n" + " result_color = mix(dst_color, src_color, fade);\n" + " result_color.rgb += chroma_offset;\n" + " gl_FragColor = result_color;\n" + "}\n"; // Read images from RAM - get_input()->to_texture(); - get_output()->to_texture(); - -// Create output pbuffer - get_output()->enable_opengl(); - - VFrame::init_screen(get_output()->get_w(), get_output()->get_h()); - -// Enable output texture - get_output()->bind_texture(0); -// Draw output texture + VFrame *src = get_input(); + src->to_texture(); + VFrame *dst = get_output(); + dst->to_texture(); + dst->enable_opengl(); + dst->init_screen(); + src->bind_texture(0); + dst->bind_texture(1); + + unsigned int shader = VFrame::make_shader(0, blend_dissolve, 0); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1f(glGetUniformLocation(shader, "fade"), fade); + glUniform1i(glGetUniformLocation(shader, "src_tex"), 0); + glUniform1i(glGetUniformLocation(shader, "dst_tex"), 1); + if(BC_CModels::is_yuv(dst->get_color_model())) + glUniform3f(glGetUniformLocation(shader, "chroma_offset"), 0.0, 0.5, 0.5); + else + glUniform3f(glGetUniformLocation(shader, "chroma_offset"), 0.0, 0.0, 0.0); + glUniform2f(glGetUniformLocation(shader, "dst_tex_dimensions"), + (float)dst->get_texture_w(), + (float)dst->get_texture_h()); + } glDisable(GL_BLEND); - glColor4f(1, 1, 1, 1); - get_output()->draw_texture(); - -// Draw input texture - get_input()->bind_texture(0); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(1, 1, 1, fade); - get_input()->draw_texture(); - + src->draw_texture(); + glUseProgram(0); glDisable(GL_BLEND); - get_output()->set_opengl_state(VFrame::SCREEN); - + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + dst->set_opengl_state(VFrame::SCREEN); #endif return 0; }