X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fgradient%2Fgradient.C;h=826f817f6d0de267afad55418b796331e156dfa3;hp=a7f611b4d2e0f58d2ac5b5d43bc9fdfbf10847ed;hb=59e74f262d7b6be235f2bbfaac35ef4274f52dc9;hpb=258b919564933c544cc13c01060f44177a6aff91 diff --git a/cinelerra-5.1/plugins/gradient/gradient.C b/cinelerra-5.1/plugins/gradient/gradient.C index a7f611b4..826f817f 100644 --- a/cinelerra-5.1/plugins/gradient/gradient.C +++ b/cinelerra-5.1/plugins/gradient/gradient.C @@ -35,35 +35,20 @@ #include "theme.h" #include "vframe.h" - - - REGISTER_PLUGIN(GradientMain) - - - - - GradientConfig::GradientConfig() { reset(); } void GradientConfig::reset() - { angle = 0; in_radius = 0; out_radius = 100; - in_r = 0xff; - in_g = 0xff; - in_b = 0xff; - in_a = 0xff; - out_r = 0x0; - out_g = 0x0; - out_b = 0x0; - out_a = 0x0; + in_r = in_g = in_b = in_a = 0xff; + out_r = out_g = out_b = out_a = 0x00; shape = GradientConfig::LINEAR; rate = GradientConfig::LINEAR; center_x = 50; @@ -108,16 +93,12 @@ void GradientConfig::copy_from(GradientConfig &that) center_y = that.center_y; } -void GradientConfig::interpolate(GradientConfig &prev, - GradientConfig &next, - long prev_frame, - long next_frame, - long current_frame) +void GradientConfig::interpolate(GradientConfig &prev, GradientConfig &next, + long prev_frame, long next_frame, long current_frame) { double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); - this->angle = (int)(prev.angle * prev_scale + next.angle * next_scale); this->in_radius = (int)(prev.in_radius * prev_scale + next.in_radius * next_scale); this->out_radius = (int)(prev.out_radius * prev_scale + next.out_radius * next_scale); @@ -147,26 +128,11 @@ int GradientConfig::get_out_color() return result; } - - - - - - - - - - #define COLOR_W 100 #define COLOR_H 30 GradientWindow::GradientWindow(GradientMain *plugin) - : PluginClientWindow(plugin, - 350, - 290, - 350, - 290, - 0) + : PluginClientWindow(plugin, 350, 290, 350, 290, 0) { this->plugin = plugin; angle = 0; @@ -175,14 +141,16 @@ GradientWindow::GradientWindow(GradientMain *plugin) center_y = 0; center_x_title = 0; center_y_title = 0; + in_color_thread = 0; + out_color_thread = 0; } - GradientWindow::~GradientWindow() { delete in_color_thread; delete out_color_thread; } + void GradientWindow::create_objects() { int margin = plugin->get_theme()->widget_border; @@ -190,10 +158,8 @@ void GradientWindow::create_objects() BC_Title *title; add_subwindow(title = new BC_Title(x, y, _("Shape:"))); - add_subwindow(shape = new GradientShape(plugin, - this, - x + title->get_w() + margin, - y)); + add_subwindow(shape = new GradientShape(plugin, this, + x + title->get_w() + margin, y)); shape->create_objects(); y += shape->get_h() + margin; shape_x = x; @@ -202,19 +168,14 @@ void GradientWindow::create_objects() add_subwindow(title = new BC_Title(x, y, _("Rate:"))); add_subwindow(rate = new GradientRate(plugin, - x + title->get_w() + margin, - y)); + x + title->get_w() + margin, y)); rate->create_objects(); y += rate->get_h() + margin; - int x1 = x; - int y1 = y; - + int x1 = x, y1 = y; BC_Title *title1; add_subwindow(title1 = new BC_Title(x, y, _("Inner radius:"))); - y += BC_Slider::get_span(0) + margin; - BC_Title *title2; add_subwindow(title2 = new BC_Title(x, y, _("Outer radius:"))); @@ -222,10 +183,8 @@ void GradientWindow::create_objects() y = y1; x += MAX(title1->get_w(), title2->get_w()) + margin; - add_subwindow(in_radius = new GradientInRadius(plugin, x, y)); y += in_radius->get_h() + margin; - add_subwindow(out_radius = new GradientOutRadius(plugin, x, y)); y += out_radius->get_h() + margin; @@ -249,19 +208,11 @@ void GradientWindow::create_objects() update_out_color(); update_shape(); - draw_3d_border(in_color_x - 2, - in_color_y - 2, - COLOR_W + 4, - COLOR_H + 4, - 1); - - draw_3d_border(out_color_x - 2, - out_color_y - 2, - COLOR_W + 4, - COLOR_H + 4, - 1); - + draw_3d_border(in_color_x - 2, in_color_y - 2, + COLOR_W + 4, COLOR_H + 4, 1); + draw_3d_border(out_color_x - 2, out_color_y - 2, + COLOR_W + 4, COLOR_H + 4, 1); show_window(); } @@ -269,48 +220,32 @@ void GradientWindow::update_shape() { int x = shape_x, y = shape_y; - if(plugin->config.shape == GradientConfig::LINEAR) - { - delete center_x_title; - delete center_y_title; - delete center_x; - delete center_y; - center_x_title = 0; - center_y_title = 0; - center_x = 0; - center_y = 0; - - if(!angle) - { + if( plugin->config.shape == GradientConfig::LINEAR ) { + delete center_x_title; center_x_title = 0; + delete center_y_title; center_y_title = 0; + delete center_x; center_x = 0; + delete center_y; center_y = 0; + if( !angle ) { add_subwindow(angle_title = new BC_Title(x, y, _("Angle:"))); add_subwindow(angle = new GradientAngle(plugin, x + angle_title->get_w() + 10, y)); } } - else - { - delete angle_title; - delete angle; - angle_title = 0; - angle = 0; - if(!center_x) - { + else { + delete angle_title; angle_title = 0; + delete angle; angle = 0; + if( !center_x ) { add_subwindow(center_x_title = new BC_Title(x, y, _("Center X:"))); add_subwindow(center_x = new GradientCenterX(plugin, - x + center_x_title->get_w() + 10, - y)); + x + center_x_title->get_w() + 10, y)); x += center_x_title->get_w() + 10 + center_x->get_w() + 10; add_subwindow(center_y_title = new BC_Title(x, y, _("Center Y:"))); add_subwindow(center_y = new GradientCenterY(plugin, - x + center_y_title->get_w() + 10, - y)); + x + center_y_title->get_w() + 10, y)); } } show_window(); } - - - void GradientWindow::update_in_color() { //printf("GradientWindow::update_in_color 1 %08x\n", plugin->config.get_in_color()); @@ -333,18 +268,7 @@ void GradientWindow::done_event(int result) out_color_thread->close_window(); } - - - - - - - - -GradientShape::GradientShape(GradientMain *plugin, - GradientWindow *gui, - int x, - int y) +GradientShape::GradientShape(GradientMain *plugin, GradientWindow *gui, int x, int y) : BC_PopupMenu(x, y, 100, to_text(plugin->config.shape), 1) { this->plugin = plugin; @@ -357,17 +281,14 @@ void GradientShape::create_objects() } char* GradientShape::to_text(int shape) { - switch(shape) - { - case GradientConfig::LINEAR: - return _("Linear"); - default: - return _("Radial"); + switch( shape ) { + case GradientConfig::LINEAR: return _("Linear"); } + return _("Radial"); } int GradientShape::from_text(char *text) { - if(!strcmp(text, to_text(GradientConfig::LINEAR))) + if( !strcmp(text, to_text(GradientConfig::LINEAR)) ) return GradientConfig::LINEAR; return GradientConfig::RADIAL; } @@ -380,8 +301,6 @@ int GradientShape::handle_event() } - - GradientCenterX::GradientCenterX(GradientMain *plugin, int x, int y) : BC_FPot(x, y, plugin->config.center_x, 0, 100) { @@ -395,7 +314,6 @@ int GradientCenterX::handle_event() } - GradientCenterY::GradientCenterY(GradientMain *plugin, int x, int y) : BC_FPot(x, y, plugin->config.center_y, 0, 100) { @@ -410,14 +328,8 @@ int GradientCenterY::handle_event() } - - GradientAngle::GradientAngle(GradientMain *plugin, int x, int y) - : BC_FPot(x, - y, - plugin->config.angle, - -180, - 180) + : BC_FPot(x, y, plugin->config.angle, -180, 180) { this->plugin = plugin; } @@ -431,11 +343,7 @@ int GradientAngle::handle_event() GradientRate::GradientRate(GradientMain *plugin, int x, int y) - : BC_PopupMenu(x, - y, - 100, - to_text(plugin->config.rate), - 1) + : BC_PopupMenu(x, y, 100, to_text(plugin->config.rate), 1) { this->plugin = plugin; } @@ -447,21 +355,17 @@ void GradientRate::create_objects() } char* GradientRate::to_text(int shape) { - switch(shape) - { - case GradientConfig::LINEAR: - return _("Linear"); - case GradientConfig::LOG: - return _("Log"); - default: - return _("Square"); + switch( shape ) { + case GradientConfig::LINEAR: return _("Linear"); + case GradientConfig::LOG: return _("Log"); } + return _("Square"); } int GradientRate::from_text(char *text) { - if(!strcmp(text, to_text(GradientConfig::LINEAR))) + if( !strcmp(text, to_text(GradientConfig::LINEAR)) ) return GradientConfig::LINEAR; - if(!strcmp(text, to_text(GradientConfig::LOG))) + if( !strcmp(text, to_text(GradientConfig::LOG)) ) return GradientConfig::LOG; return GradientConfig::SQUARE; } @@ -473,16 +377,9 @@ int GradientRate::handle_event() } - GradientInRadius::GradientInRadius(GradientMain *plugin, int x, int y) - : BC_FSlider(x, - y, - 0, - 200, - 200, - (float)0, - (float)100, - (float)plugin->config.in_radius) + : BC_FSlider(x, y, 0, 200, 200, + 0.f, 100.f, (float)plugin->config.in_radius) { this->plugin = plugin; } @@ -496,14 +393,8 @@ int GradientInRadius::handle_event() GradientOutRadius::GradientOutRadius(GradientMain *plugin, int x, int y) - : BC_FSlider(x, - y, - 0, - 200, - 200, - (float)0, - (float)100, - (float)plugin->config.out_radius) + : BC_FSlider(x, y, 0, 200, 200, + 0.f, 100.f, (float)plugin->config.out_radius) { this->plugin = plugin; } @@ -581,21 +472,13 @@ int GradientInColorThread::handle_new_color(int output, int alpha) window->flush(); window->unlock_window(); plugin->send_configure_change(); -// printf("GradientInColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n", -// plugin->config.in_r, -// plugin->config.in_g, -// plugin->config.in_b, -// plugin->config.in_a, -// plugin->config.out_r, -// plugin->config.out_g, -// plugin->config.out_b, -// plugin->config.out_a); - +//printf("GradientInColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n", +// plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, plugin->config.in_a, +// plugin->config.out_r, plugin->config.out_g, plugin->config.out_b, plugin->config.out_a); return 1; } - GradientOutColorThread::GradientOutColorThread(GradientMain *plugin, GradientWindow *window) : ColorPicker(1, _("Outer color")) @@ -615,29 +498,13 @@ int GradientOutColorThread::handle_new_color(int output, int alpha) window->flush(); window->unlock_window(); plugin->send_configure_change(); -// printf("GradientOutColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n", -// plugin->config.in_r, -// plugin->config.in_g, -// plugin->config.in_b, -// plugin->config.in_a, -// plugin->config.out_r, -// plugin->config.out_g, -// plugin->config.out_b, -// plugin->config.out_a); +//printf("GradientOutColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n", +// plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, plugin->config.in_a, +// plugin->config.out_r, plugin->config.out_g, plugin->config.out_b, plugin->config.out_a); return 1; } - - - - - - - - - - GradientMain::GradientMain(PluginServer *server) : PluginVClient(server) { @@ -646,15 +513,16 @@ GradientMain::GradientMain(PluginServer *server) gradient = 0; engine = 0; overlayer = 0; + table = 0; + table_size = 0; } GradientMain::~GradientMain() { - - - if(gradient) delete gradient; - if(engine) delete engine; - if(overlayer) delete overlayer; + delete [] table; + delete gradient; + delete engine; + delete overlayer; } const char* GradientMain::plugin_title() { return N_("Gradient"); } @@ -677,69 +545,59 @@ int GradientMain::process_buffer(VFrame *frame, { this->input = frame; this->output = frame; - need_reconfigure |= load_configuration(); + float fw = input->get_w(), fh = input->get_h(); + gradient_size = hypotf(fw, fh); + need_reconfigure = load_configuration(); int need_alpha = config.in_a != 0xff || config.out_a != 0xff; - if(need_alpha) - read_frame(frame, - 0, - start_position, - frame_rate, - get_use_opengl()); - if(get_use_opengl()) return run_opengl(); + if( need_alpha ) + read_frame(frame, 0, start_position, frame_rate, get_use_opengl()); + if( get_use_opengl() ) return run_opengl(); int gradient_cmodel = input->get_color_model(); - if(need_alpha && BC_CModels::components(gradient_cmodel) == 3) - { - switch(gradient_cmodel) - { - case BC_RGB888: - gradient_cmodel = BC_RGBA8888; - break; - case BC_RGB_FLOAT: - gradient_cmodel = BC_RGBA_FLOAT; - break; - case BC_YUV888: - gradient_cmodel = BC_YUVA8888; - break; + if( need_alpha && BC_CModels::components(gradient_cmodel) == 3 ) { + switch( gradient_cmodel ) { + case BC_RGB888: gradient_cmodel = BC_RGBA8888; break; + case BC_YUV888: gradient_cmodel = BC_YUVA8888; break; + case BC_RGB_FLOAT: gradient_cmodel = BC_RGBA_FLOAT; break; } } - if(gradient && gradient->get_color_model() != gradient_cmodel) - { + int bpp = BC_CModels::calculate_pixelsize(gradient_cmodel); + int comps = BC_CModels::components(gradient_cmodel); + int grad_size1 = gradient_size + 1; + int sz = 4 * (bpp / comps) * grad_size1; + if( table_size < sz ) { + delete [] table; table = 0; + } + if( !table ) { + table = new uint8_t[table_size = sz]; + need_reconfigure = 1; + } + + if( gradient && gradient->get_color_model() != gradient_cmodel ) { delete gradient; gradient = 0; } - if(!gradient) + if( !gradient ) gradient = new VFrame(input->get_w(), input->get_h(), gradient_cmodel, 0); - if(!engine) engine = new GradientServer(this, - get_project_smp() + 1, - get_project_smp() + 1); + if( !engine ) + engine = new GradientServer(this, + get_project_smp() + 1, get_project_smp() + 1); engine->process_packages(); // Use overlay routine in GradientServer if mismatched colormodels - if(gradient->get_color_model() == output->get_color_model()) - { - if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1); - overlayer->overlay(output, - gradient, - 0, - 0, - input->get_w(), - input->get_h(), - 0, - 0, - input->get_w(), - input->get_h(), - 1.0, - TRANSFER_NORMAL, - NEAREST_NEIGHBOR); + if( gradient->get_color_model() == output->get_color_model() ) { + if( !overlayer ) overlayer = new OverlayFrame(get_project_smp() + 1); + overlayer->overlay(output, gradient, + 0, 0, input->get_w(), input->get_h(), + 0, 0, input->get_w(), input->get_h(), + 1.0, TRANSFER_NORMAL, NEAREST_NEIGHBOR); } - return 0; } @@ -812,30 +670,23 @@ void GradientMain::read_data(KeyFrame *keyframe) int result = 0; - while(!result) - { - result = input.read_tag(); - - if(!result) - { - if(input.tag.title_is("GRADIENT")) - { - config.angle = input.tag.get_property("ANGLE", config.angle); - config.rate = input.tag.get_property("RATE", config.rate); - config.in_radius = input.tag.get_property("IN_RADIUS", config.in_radius); - config.out_radius = input.tag.get_property("OUT_RADIUS", config.out_radius); - config.in_r = input.tag.get_property("IN_R", config.in_r); - config.in_g = input.tag.get_property("IN_G", config.in_g); - config.in_b = input.tag.get_property("IN_B", config.in_b); - config.in_a = input.tag.get_property("IN_A", config.in_a); - config.out_r = input.tag.get_property("OUT_R", config.out_r); - config.out_g = input.tag.get_property("OUT_G", config.out_g); - config.out_b = input.tag.get_property("OUT_B", config.out_b); - config.out_a = input.tag.get_property("OUT_A", config.out_a); - config.shape = input.tag.get_property("SHAPE", config.shape); - config.center_x = input.tag.get_property("CENTER_X", config.center_x); - config.center_y = input.tag.get_property("CENTER_Y", config.center_y); - } + while( !(result = input.read_tag()) ) { + if( input.tag.title_is("GRADIENT") ) { + config.angle = input.tag.get_property("ANGLE", config.angle); + config.rate = input.tag.get_property("RATE", config.rate); + config.in_radius = input.tag.get_property("IN_RADIUS", config.in_radius); + config.out_radius = input.tag.get_property("OUT_RADIUS", config.out_radius); + config.in_r = input.tag.get_property("IN_R", config.in_r); + config.in_g = input.tag.get_property("IN_G", config.in_g); + config.in_b = input.tag.get_property("IN_B", config.in_b); + config.in_a = input.tag.get_property("IN_A", config.in_a); + config.out_r = input.tag.get_property("OUT_R", config.out_r); + config.out_g = input.tag.get_property("OUT_G", config.out_g); + config.out_b = input.tag.get_property("OUT_B", config.out_b); + config.out_a = input.tag.get_property("OUT_A", config.out_a); + config.shape = input.tag.get_property("SHAPE", config.shape); + config.center_x = input.tag.get_property("CENTER_X", config.center_x); + config.center_y = input.tag.get_property("CENTER_Y", config.center_y); } } } @@ -845,13 +696,10 @@ int GradientMain::handle_opengl() #ifdef HAVE_GL const char *head_frag = "uniform sampler2D tex;\n" - "uniform float half_w;\n" - "uniform float half_h;\n" - "uniform float center_x;\n" - "uniform float center_y;\n" - "uniform float half_gradient_size;\n" - "uniform float sin_angle;\n" - "uniform float cos_angle;\n" + "uniform vec2 tex_dimensions;\n" + "uniform vec2 center;\n" + "uniform vec2 angle;\n" + "uniform float gradient_size;\n" "uniform vec4 out_color;\n" "uniform vec4 in_color;\n" "uniform float in_radius;\n" @@ -860,16 +708,14 @@ int GradientMain::handle_opengl() "\n" "void main()\n" "{\n" - " vec2 out_coord = gl_TexCoord[0].st;\n"; + " vec2 out_coord = gl_TexCoord[0].st;\n" + " vec2 in_coord = out_coord * tex_dimensions - center;\n"; const char *linear_shape = - " vec2 in_coord = vec2(out_coord.x - half_w, half_h - out_coord.y);\n" - " float mag = half_gradient_size - \n" - " (in_coord.x * sin_angle + in_coord.y * cos_angle);\n"; + " float mag = 0.5 + dot(in_coord,angle)/gradient_size;\n"; const char *radial_shape = - " vec2 in_coord = vec2(out_coord.x - center_x, out_coord.y - center_y);\n" - " float mag = length(vec2(in_coord.x, in_coord.y));\n"; + " float mag = length(in_coord)/gradient_size;\n"; // No clamp function in NVidia const char *linear_rate = @@ -891,7 +737,7 @@ int GradientMain::handle_opengl() " vec4 color = mix(in_color, out_color, opacity);\n" " vec4 bg_color = texture2D(tex, out_coord);\n" " gl_FragColor.rgb = mix(bg_color.rgb, color.rgb, color.a);\n" - " gl_FragColor.a = max(bg_color.a, color.a);\n" + " gl_FragColor.a = mix(bg_color.a, 1., color.a);\n" "}\n"; @@ -914,7 +760,7 @@ int GradientMain::handle_opengl() shader_stack[current_shader++] = shape_frag; const char *rate_frag = 0; - switch(config.rate) { + switch( config.rate ) { case GradientConfig::LINEAR: rate_frag = linear_rate; break; @@ -944,76 +790,63 @@ int GradientMain::handle_opengl() glUseProgram(shader); float w = get_output()->get_w(); float h = get_output()->get_h(); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); float texture_w = get_output()->get_texture_w(); float texture_h = get_output()->get_texture_h(); - glUniform1i(glGetUniformLocation(shader, "tex"), 0); - glUniform1f(glGetUniformLocation(shader, "half_w"), w / 2 / texture_w); - glUniform1f(glGetUniformLocation(shader, "half_h"), h / 2 / texture_h); - if(config.shape == GradientConfig::LINEAR) - { - glUniform1f(glGetUniformLocation(shader, "center_x"), - w / 2 / texture_w); - glUniform1f(glGetUniformLocation(shader, "center_y"), - h / 2 / texture_h); - } - else - { - glUniform1f(glGetUniformLocation(shader, "center_x"), - (float)config.center_x * w / 100 / texture_w); - glUniform1f(glGetUniformLocation(shader, "center_y"), - (float)config.center_y * h / 100 / texture_h); + glUniform2f(glGetUniformLocation(shader, "tex_dimensions"), + texture_w, texture_h); + float u = config.shape == GradientConfig::LINEAR ? + 0.5f : config.center_x/100.f; + float v = config.shape == GradientConfig::LINEAR ? + 0.5f : config.center_y/100.f; + glUniform2f(glGetUniformLocation(shader, "center"), + u * w, v * h); + glUniform1f(glGetUniformLocation(shader, "gradient_size"), + gradient_size); + glUniform2f(glGetUniformLocation(shader, "angle"), + -sin(config.angle * (M_PI / 180)), cos(config.angle * (M_PI / 180))); + + float in_radius = (float)config.in_radius/100; + float out_radius = (float)config.out_radius/100; + if( in_radius > out_radius ) { + float r = in_radius; + in_radius = out_radius; + out_radius = r; } - float gradient_size = hypotf(w / texture_w, h / texture_h); - glUniform1f(glGetUniformLocation(shader, "half_gradient_size"), - gradient_size / 2); - glUniform1f(glGetUniformLocation(shader, "sin_angle"), - sin(config.angle * (M_PI / 180))); - glUniform1f(glGetUniformLocation(shader, "cos_angle"), - cos(config.angle * (M_PI / 180))); - float in_radius = (float)config.in_radius / 100 * gradient_size; glUniform1f(glGetUniformLocation(shader, "in_radius"), in_radius); - float out_radius = (float)config.out_radius / 100 * gradient_size; glUniform1f(glGetUniformLocation(shader, "out_radius"), out_radius); glUniform1f(glGetUniformLocation(shader, "radius_diff"), out_radius - in_radius); - switch(get_output()->get_color_model()) { + float in_r = (float)config.in_r / 0xff; + float in_g = (float)config.in_g / 0xff; + float in_b = (float)config.in_b / 0xff; + float in_a = (float)config.in_a / 0xff; + float out_r = (float)config.out_r / 0xff; + float out_g = (float)config.out_g / 0xff; + float out_b = (float)config.out_b / 0xff; + float out_a = (float)config.out_a / 0xff; + switch( get_output()->get_color_model() ) { case BC_YUV888: case BC_YUVA8888: { float in1, in2, in3, in4; float out1, out2, out3, out4; - YUV::yuv.rgb_to_yuv_f( - (float)config.in_r / 0xff, - (float)config.in_g / 0xff, - (float)config.in_b / 0xff, - in1, in2, in3); - in4 = (float)config.in_a / 0xff; - YUV::yuv.rgb_to_yuv_f( - (float)config.out_r / 0xff, - (float)config.out_g / 0xff, - (float)config.out_b / 0xff, - out1, out2, out3); - in2 += 0.5; in3 += 0.5; - out2 += 0.5; out3 += 0.5; - out4 = (float)config.out_a / 0xff; + YUV::yuv.rgb_to_yuv_f(in_r,in_g,in_b, in1,in2,in3); + in2 += 0.5; in3 += 0.5; in4 = in_a; + YUV::yuv.rgb_to_yuv_f(out_r,out_g,out_b, out1,out2,out3); + out2 += 0.5; out3 += 0.5; out4 = out_a; glUniform4f(glGetUniformLocation(shader, "out_color"), out1, out2, out3, out4); glUniform4f(glGetUniformLocation(shader, "in_color"), in1, in2, in3, in4); break; } - default: + default: { glUniform4f(glGetUniformLocation(shader, "out_color"), - (float)config.out_r / 0xff, - (float)config.out_g / 0xff, - (float)config.out_b / 0xff, - (float)config.out_a / 0xff); + out_r, out_g, out_b, out_a); glUniform4f(glGetUniformLocation(shader, "in_color"), - (float)config.in_r / 0xff, - (float)config.in_g / 0xff, - (float)config.in_b / 0xff, - (float)config.in_a / 0xff); - break; + in_r, in_g, in_b, in_a); + break; } } } @@ -1040,178 +873,139 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) static float calculate_opacity(float mag, - float in_radius, float out_radius, int rate) + float in_radius, float out_radius, int rate) { + float mag_diff = mag - in_radius; + float radius_diff = out_radius - in_radius; + if( !radius_diff ) return 1.0; float opacity = 0.0; - switch(rate) - { - case GradientConfig::LINEAR: - if(mag < in_radius) - opacity = 0.0; - else - if(mag >= out_radius) - opacity = 1.0; - else - opacity = (float)(mag - in_radius) / (out_radius - in_radius); - break; - - case GradientConfig::LOG: - if(mag < in_radius) - opacity = 0; - else -// Let this one decay beyond out_radius - opacity = 1 - exp(1.0 * -(float)(mag - in_radius) / - (out_radius - in_radius)); - break; - - case GradientConfig::SQUARE: - if(mag < in_radius) - opacity = 0.0; - else - if(mag >= out_radius) - opacity = 1.0; - else - opacity = powf((float)(mag - in_radius) / - (out_radius - in_radius), 2.0); - break; + switch( rate ) { + case GradientConfig::LINEAR: + opacity = mag < in_radius ? 0.0 : mag >= out_radius ? 1.0 : + mag_diff / radius_diff; + break; + case GradientConfig::LOG: + opacity = mag < in_radius ? 0.0 : // Let this one decay beyond out_radius + 1 - exp(1.0 * -mag_diff / radius_diff); + break; + case GradientConfig::SQUARE: + opacity = mag < in_radius ? 0.0 : mag >= out_radius ? 1.0 : + powf(mag_diff / radius_diff, 2.); + break; } - CLAMP(opacity, 0.0, 1.0); return opacity; } -#define CREATE_GRADIENT(type, temp, components, max) \ -{ \ +#define CREATE_GRADIENT(type, temp, components, max) { \ /* Synthesize linear gradient for lookups */ \ + int grad_size = plugin->gradient_size; \ + int n = sizeof(type) * (grad_size+1); \ + void *r_table = (void*) (plugin->table + 0*n); \ + void *g_table = (void*) (plugin->table + 1*n); \ + void *b_table = (void*) (plugin->table + 2*n); \ + void *a_table = (void*) (plugin->table + 3*n); \ + double grad_size2 = grad_size / 2.; \ \ - r_table = malloc(sizeof(type) * gradient_size); \ - g_table = malloc(sizeof(type) * gradient_size); \ - b_table = malloc(sizeof(type) * gradient_size); \ - a_table = malloc(sizeof(type) * gradient_size); \ - \ - for(int i = 0; i < gradient_size; i++) \ - { \ - float opacity = calculate_opacity(i, in_radius, out_radius, plugin->config.rate); \ - float transparency; \ - \ - transparency = 1.0 - opacity; \ - ((type*)r_table)[i] = (type)(out1 * opacity + in1 * transparency); \ - ((type*)g_table)[i] = (type)(out2 * opacity + in2 * transparency); \ - ((type*)b_table)[i] = (type)(out3 * opacity + in3 * transparency); \ - ((type*)a_table)[i] = (type)(out4 * opacity + in4 * transparency); \ + if( plugin->need_reconfigure ) { \ + for( int i = 0; i <= grad_size; i++ ) { \ + float opacity = calculate_opacity(i, in_radius, out_radius, plugin->config.rate); \ + float transparency = 1.0 - opacity; \ + ((type*)r_table)[i] = (type)(out1 * opacity + in1 * transparency); \ + ((type*)g_table)[i] = (type)(out2 * opacity + in2 * transparency); \ + ((type*)b_table)[i] = (type)(out3 * opacity + in3 * transparency); \ + ((type*)a_table)[i] = (type)(out4 * opacity + in4 * transparency); \ + } \ } \ \ - for(int i = pkg->y1; i < pkg->y2; i++) \ - { \ + for( int i = pkg->y1; i < pkg->y2; i++ ) { \ + double y = half_h - i; \ type *gradient_row = (type*)plugin->gradient->get_rows()[i]; \ type *out_row = (type*)plugin->get_output()->get_rows()[i]; \ - \ - switch(plugin->config.shape) \ - { \ - case GradientConfig::LINEAR: \ - for(int j = 0; j < w; j++) \ - { \ - int x = j - half_w; \ - int y = -(i - half_h); \ - \ + switch( plugin->config.shape ) { \ + case GradientConfig::LINEAR: \ + for( int j = 0; j < w; j++ ) { \ + double x = j - half_w; \ /* Rotate by effect angle */ \ - int mag = (int)(gradient_size / 2 - \ - (x * sin_angle + y * cos_angle) + \ - 0.5); \ - \ + int mag = (grad_size2 - (x * sin_angle + y * cos_angle)) + 0.5; \ /* Get gradient value from these coords */ \ - \ - if(sizeof(type) == 4) \ - { \ - float opacity = calculate_opacity(mag, \ - in_radius, \ - out_radius, \ - plugin->config.rate); \ - float transparency = 1.0 - opacity; \ - gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \ - gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \ - gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \ - if(components == 4) gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \ - } \ - else \ - if(mag < 0) \ - { \ - gradient_row[0] = out1; \ - gradient_row[1] = out2; \ - gradient_row[2] = out3; \ - if(components == 4) gradient_row[3] = out4; \ - } \ - else \ - if(mag >= gradient_size) \ - { \ - gradient_row[0] = in1; \ - gradient_row[1] = in2; \ - gradient_row[2] = in3; \ - if(components == 4) gradient_row[3] = in4; \ - } \ - else \ - { \ - gradient_row[0] = ((type*)r_table)[mag]; \ - gradient_row[1] = ((type*)g_table)[mag]; \ - gradient_row[2] = ((type*)b_table)[mag]; \ - if(components == 4) gradient_row[3] = ((type*)a_table)[mag]; \ - } \ - \ -/* Overlay mixed colormodels onto output */ \ - if(gradient_cmodel != output_cmodel) \ - { \ - temp opacity = gradient_row[3]; \ - temp transparency = max - opacity; \ - out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \ - out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \ - out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \ - out_row += 3; \ - } \ - \ - gradient_row += components; \ + if( sizeof(type) == 4 ) { \ + float opacity = calculate_opacity(mag, \ + in_radius, out_radius, plugin->config.rate); \ + float transparency = 1.0 - opacity; \ + gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \ + gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \ + gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \ + if( components == 4 ) \ + gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \ } \ - break; \ - \ - case GradientConfig::RADIAL: \ - for(int j = 0; j < w; j++) \ - { \ - double x = j - center_x; \ - double y = i - center_y; \ - double magnitude = hypot(x, y); \ - int mag = (int)magnitude; \ - if(sizeof(type) == 4) \ - { \ - float opacity = calculate_opacity(mag, \ - in_radius, \ - out_radius, \ - plugin->config.rate); \ - float transparency = 1.0 - opacity; \ - gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \ - gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \ - gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \ - if(components == 4) gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \ - } \ - else \ - { \ - gradient_row[0] = ((type*)r_table)[mag]; \ - gradient_row[1] = ((type*)g_table)[mag]; \ - gradient_row[2] = ((type*)b_table)[mag]; \ - if(components == 4) gradient_row[3] = ((type*)a_table)[mag]; \ - } \ + else if( mag < 0 ) { \ + gradient_row[0] = in1; \ + gradient_row[1] = in2; \ + gradient_row[2] = in3; \ + if( components == 4 ) \ + gradient_row[3] = in4; \ + } \ + else if( mag >= grad_size ) { \ + gradient_row[0] = out1; \ + gradient_row[1] = out2; \ + gradient_row[2] = out3; \ + if( components == 4 ) \ + gradient_row[3] = out4; \ + } \ + else { \ + gradient_row[0] = ((type*)r_table)[mag]; \ + gradient_row[1] = ((type*)g_table)[mag]; \ + gradient_row[2] = ((type*)b_table)[mag]; \ + if( components == 4 ) \ + gradient_row[3] = ((type*)a_table)[mag]; \ + } \ +/* no alpha output, Overlay mixed colormodels */ \ + if( gradient_cmodel != output_cmodel ) { \ + temp opacity = gradient_row[3]; \ + temp transparency = max - opacity; \ + out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \ + out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \ + out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \ + out_row += 3; \ + } \ + gradient_row += components; \ + } \ + break; \ \ + case GradientConfig::RADIAL: \ + for( int j = 0; j < w; j++ ) { \ + double x = j - center_x, y = i - center_y; \ + double magnitude = hypot(x, y); \ + int mag = (int)magnitude; \ + if( sizeof(type) == 4 ) { \ + float opacity = calculate_opacity(mag, \ + in_radius, out_radius, plugin->config.rate); \ + float transparency = 1.0 - opacity; \ + gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \ + gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \ + gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \ + if( components == 4 ) \ + gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \ + } \ + else { \ + gradient_row[0] = ((type*)r_table)[mag]; \ + gradient_row[1] = ((type*)g_table)[mag]; \ + gradient_row[2] = ((type*)b_table)[mag]; \ + if( components == 4 ) \ + gradient_row[3] = ((type*)a_table)[mag]; \ + } \ /* Overlay mixed colormodels onto output */ \ - if(gradient_cmodel != output_cmodel) \ - { \ - temp opacity = gradient_row[3]; \ - temp transparency = max - opacity; \ - out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \ - out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \ - out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \ - out_row += 3; \ - } \ - \ - gradient_row += components; \ + if( gradient_cmodel != output_cmodel ) { \ + temp opacity = gradient_row[3]; \ + temp transparency = max - opacity; \ + out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \ + out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \ + out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \ + out_row += 3; \ } \ - break; \ + gradient_row += components; \ + } \ + break; \ } \ } \ } @@ -1221,147 +1015,110 @@ void GradientUnit::process_package(LoadPackage *package) GradientPackage *pkg = (GradientPackage*)package; int h = plugin->input->get_h(); int w = plugin->input->get_w(); + int grad_size = plugin->gradient_size; int half_w = w / 2; int half_h = h / 2; - int gradient_size = (int)(ceil(hypot(w, h))); - int in_radius = (int)(plugin->config.in_radius / 100 * gradient_size); - int out_radius = (int)(plugin->config.out_radius / 100 * gradient_size); + int in_radius = (int)(plugin->config.in_radius / 100 * grad_size); + int out_radius = (int)(plugin->config.out_radius / 100 * grad_size); double sin_angle = sin(plugin->config.angle * (M_PI / 180)); double cos_angle = cos(plugin->config.angle * (M_PI / 180)); double center_x = plugin->config.center_x * w / 100; double center_y = plugin->config.center_y * h / 100; - void *r_table = 0; - void *g_table = 0; - void *b_table = 0; - void *a_table = 0; int gradient_cmodel = plugin->gradient->get_color_model(); int output_cmodel = plugin->get_output()->get_color_model(); - if(in_radius > out_radius) - { - in_radius ^= out_radius; - out_radius ^= in_radius; - in_radius ^= out_radius; + if( in_radius > out_radius ) { + int r = in_radius; + in_radius = out_radius; + out_radius = r; } - - switch(gradient_cmodel) - { - case BC_RGB888: - { - int in1 = plugin->config.in_r; - int in2 = plugin->config.in_g; - int in3 = plugin->config.in_b; - int in4 = plugin->config.in_a; - int out1 = plugin->config.out_r; - int out2 = plugin->config.out_g; - int out3 = plugin->config.out_b; - int out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, int, 3, 0xff) - break; - } - - case BC_RGBA8888: - { - int in1 = plugin->config.in_r; - int in2 = plugin->config.in_g; - int in3 = plugin->config.in_b; - int in4 = plugin->config.in_a; - int out1 = plugin->config.out_r; - int out2 = plugin->config.out_g; - int out3 = plugin->config.out_b; - int out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, int, 4, 0xff) - break; - } - - case BC_RGB_FLOAT: - { - float in1 = (float)plugin->config.in_r / 0xff; - float in2 = (float)plugin->config.in_g / 0xff; - float in3 = (float)plugin->config.in_b / 0xff; - float in4 = (float)plugin->config.in_a / 0xff; - float out1 = (float)plugin->config.out_r / 0xff; - float out2 = (float)plugin->config.out_g / 0xff; - float out3 = (float)plugin->config.out_b / 0xff; - float out4 = (float)plugin->config.out_a / 0xff; - CREATE_GRADIENT(float, float, 3, 1.0) - break; - } - - case BC_RGBA_FLOAT: - { - float in1 = (float)plugin->config.in_r / 0xff; - float in2 = (float)plugin->config.in_g / 0xff; - float in3 = (float)plugin->config.in_b / 0xff; - float in4 = (float)plugin->config.in_a / 0xff; - float out1 = (float)plugin->config.out_r / 0xff; - float out2 = (float)plugin->config.out_g / 0xff; - float out3 = (float)plugin->config.out_b / 0xff; - float out4 = (float)plugin->config.out_a / 0xff; - CREATE_GRADIENT(float, float, 4, 1.0) - break; - } - - case BC_YUV888: - { - int in1, in2, in3, in4; - int out1, out2, out3, out4; - YUV::yuv.rgb_to_yuv_8(plugin->config.in_r, - plugin->config.in_g, - plugin->config.in_b, - in1, - in2, - in3); - in4 = plugin->config.in_a; - YUV::yuv.rgb_to_yuv_8(plugin->config.out_r, - plugin->config.out_g, - plugin->config.out_b, - out1, - out2, - out3); - out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, int, 3, 0xff) - break; - } - - case BC_YUVA8888: - { - int in1, in2, in3, in4; - int out1, out2, out3, out4; - YUV::yuv.rgb_to_yuv_8(plugin->config.in_r, - plugin->config.in_g, - plugin->config.in_b, - in1, - in2, - in3); - in4 = plugin->config.in_a; - YUV::yuv.rgb_to_yuv_8(plugin->config.out_r, - plugin->config.out_g, - plugin->config.out_b, - out1, - out2, - out3); - out4 = plugin->config.out_a; - CREATE_GRADIENT(unsigned char, int, 4, 0xff) - break; - } + switch( gradient_cmodel ) { + case BC_RGB888: { + int in1 = plugin->config.in_r; + int in2 = plugin->config.in_g; + int in3 = plugin->config.in_b; + int in4 = plugin->config.in_a; + int out1 = plugin->config.out_r; + int out2 = plugin->config.out_g; + int out3 = plugin->config.out_b; + int out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, int, 3, 0xff) + break; } + + case BC_RGBA8888: { + int in1 = plugin->config.in_r; + int in2 = plugin->config.in_g; + int in3 = plugin->config.in_b; + int in4 = plugin->config.in_a; + int out1 = plugin->config.out_r; + int out2 = plugin->config.out_g; + int out3 = plugin->config.out_b; + int out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, int, 4, 0xff) + break; } + + case BC_RGB_FLOAT: { + float in1 = (float)plugin->config.in_r / 0xff; + float in2 = (float)plugin->config.in_g / 0xff; + float in3 = (float)plugin->config.in_b / 0xff; + float in4 = (float)plugin->config.in_a / 0xff; + float out1 = (float)plugin->config.out_r / 0xff; + float out2 = (float)plugin->config.out_g / 0xff; + float out3 = (float)plugin->config.out_b / 0xff; + float out4 = (float)plugin->config.out_a / 0xff; + CREATE_GRADIENT(float, float, 3, 1.0) + break; } + + case BC_RGBA_FLOAT: { + float in1 = (float)plugin->config.in_r / 0xff; + float in2 = (float)plugin->config.in_g / 0xff; + float in3 = (float)plugin->config.in_b / 0xff; + float in4 = (float)plugin->config.in_a / 0xff; + float out1 = (float)plugin->config.out_r / 0xff; + float out2 = (float)plugin->config.out_g / 0xff; + float out3 = (float)plugin->config.out_b / 0xff; + float out4 = (float)plugin->config.out_a / 0xff; + CREATE_GRADIENT(float, float, 4, 1.0) + break; } + + case BC_YUV888: { + int in_r = plugin->config.in_r; + int in_g = plugin->config.in_g; + int in_b = plugin->config.in_b; + int in1, in2, in3, in4; + int out1, out2, out3, out4; + YUV::yuv.rgb_to_yuv_8(in_r,in_g,in_b, in1,in2,in3); + in4 = plugin->config.in_a; + int out_r = plugin->config.in_r; + int out_g = plugin->config.in_g; + int out_b = plugin->config.in_b; + YUV::yuv.rgb_to_yuv_8(out_r,out_g,out_b, out1,out2,out3); + out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, int, 3, 0xff) + break; } + + case BC_YUVA8888: { + int in_r = plugin->config.in_r; + int in_g = plugin->config.in_g; + int in_b = plugin->config.in_b; + int in1, in2, in3, in4; + int out1, out2, out3, out4; + YUV::yuv.rgb_to_yuv_8(in_r,in_g,in_b, in1,in2,in3); + in4 = plugin->config.in_a; + int out_r = plugin->config.in_r; + int out_g = plugin->config.in_g; + int out_b = plugin->config.in_b; + YUV::yuv.rgb_to_yuv_8(out_r,out_g,out_b, out1,out2,out3); + out4 = plugin->config.out_a; + CREATE_GRADIENT(unsigned char, int, 4, 0xff) + break; } } - - if(r_table) free(r_table); - if(g_table) free(g_table); - if(b_table) free(b_table); - if(a_table) free(a_table); } - - - - GradientServer::GradientServer(GradientMain *plugin, - int total_clients, - int total_packages) + int total_clients, int total_packages) : LoadServer(total_clients, total_packages) { this->plugin = plugin; @@ -1369,8 +1126,7 @@ GradientServer::GradientServer(GradientMain *plugin, void GradientServer::init_packages() { - for(int i = 0; i < get_total_packages(); i++) - { + for( int i = 0; i < get_total_packages(); i++ ) { GradientPackage *package = (GradientPackage*)get_package(i); package->y1 = plugin->input->get_h() * i / @@ -1391,7 +1147,3 @@ LoadPackage* GradientServer::new_package() return new GradientPackage; } - - - -