Exemple #1
0
void MusicEffect::RenderMorph(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, std::list<MusicEvent*>& events, int colourTreatment, bool bounce, bool fade)
{
    bool up = true;
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        up = !up;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);

            int length = buffer.BufferHt;
            int start = -1 * length + progress * 2 * length + 1;
            int end = start + length;

            for (int y = std::max(0, start); y < std::min(end, buffer.BufferHt); y++)
            {
                xlColor c = xlWHITE;
                float proportion = ((float)end - (float)y) / (float)length;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = (1.0 -proportion) * 255;
                }

                if (up || !bounce)
                {
                    buffer.SetPixel(x, y, c);
                }
                else
                {
                    buffer.SetPixel(x, buffer.BufferHt - y - 1, c);
                }
            }
        }
    }
}
Exemple #2
0
//update previous bkg:
//if it's a scrolling piano, scroll previous notes up one row
//for eqbars, shorten them
void PianoRenderCache::Piano_update_bkg(RenderBuffer &buffer, int Style, wxSize& canvas, int rowh)
{
    debug_function(10);
    debug(1, "style %d", Style);
    xlColor c;
    //TODO: should use GDI+ functions on Windows
    //TODO: use GetData for better performance; probably doesn't matter since grid is fairly small (as compared to normal images or screen canvas)
    //TODO: speed
    switch (Style)
    {
        case -1: //initialize
            debug_more(5, ", init canvas %d x %d", canvas.x, canvas.y);
            //            PrevRender.clear(); //start with blank canvas
            //            PrevRender.resize(canvas.x * cnavas.y); //set all pixels off
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    buffer.SetPixel(x, y, c); //clear all (background canvas is persistent while piano effect is active)
            return;
        case PIANO_STYLE_SCROLLING: //scroll up one row
            debug_more(5, ", scroll %d x %d up by %d", canvas.x, canvas.y, rowh);
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - rowh) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, canvas.y - y - rowh - 1, x, canvas.y - y - 1);
                        buffer.CopyPixel(x, canvas.y - y - rowh - 1, x, canvas.y - y - 1);
                    } else {
                        debug_more(30, ", (%d,%d)<-0", x, canvas.y - y - 1);
                        buffer.SetPixel(x, canvas.y - y - 1, c);  //clear bottom row, scroll others
                    }
            return;
        case PIANO_STYLE_EQBARS: //scroll down one row (decaying bars)
            debug_more(5, ", scroll %d x %d down by %d", canvas.x, canvas.y, rowh);
            //            c.Set(255, 255, 255); //debug
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - rowh) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, y + rowh, x, y);
                        buffer.CopyPixel(x, y + rowh, x, y);
                    } else {
                        debug_more(30, ", (%d,%d)<-0", x, y);
                        buffer.SetPixel(x, y, c); //clear top row, scroll other rows
                    }
            return;
        case PIANO_STYLE_ICICLES: //scroll down one pixel (drip)
            debug_more(5, ", scroll %d x %d", canvas.x, canvas.y);
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - 1) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, y + 1, x, y);
                        buffer.CopyPixel(x, y + 1, x, y);
                    }
            //      else { debug_more(30, ", (%d,%d)<-0", x, y); buffer.SetPixel(x, y, c); } //clear top pixel, scroll other pixels
            return;
        default:
            debug_more(5, ", no scrolling");
    }
}
Exemple #3
0
void ShimmerEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    float oset = buffer.GetEffectTimeIntervalPosition();
    int Duty_Factor = GetValueCurveInt("Shimmer_Duty_Factor", 50, SettingsMap, oset);
    bool Use_All_Colors = SettingsMap.GetBool("CHECKBOX_Shimmer_Use_All_Colors", false);
    float cycles = GetValueCurveDouble("Shimmer_Cycles", 1.0, SettingsMap, oset);
    int colorcnt=buffer.GetColorCount();
    
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    
    double ColorIdx = round(position * 0.999 * (double)colorcnt);
    
    double pos2 = position * colorcnt;
    while (pos2 > 1.0) {
        pos2 -= 1.0;
    }
    if (pos2 * 100 > Duty_Factor) {
        return;
    }
    
    xlColor color;
    buffer.palette.GetColor(ColorIdx, color);
    for (int y=0; y<buffer.BufferHt; y++) {
        for (int x=0; x<buffer.BufferWi; x++) {
            if(Use_All_Colors) { // Should we randomly assign colors from palette or cycle thru sequentially?
                ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
                buffer.palette.GetColor(ColorIdx, color); // Now go and get the hsv value for this ColorIdx
            }
            
            buffer.SetPixel(x,y,color); // Turn pixel
        }
    }
}
Exemple #4
0
void MusicEffect::RenderOn(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, std::list<MusicEvent*>& events, int colourTreatment, bool fade)
{
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);


            for (int y = 0; y < buffer.BufferHt; y++)
            {
                xlColor c = xlWHITE;
                float proportion = (float)y / (float)buffer.BufferHt;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = (1.0 - progress) * 255;
                }

                buffer.SetPixel(x, y, c);
            }
        }
    }
}
static void set_pixel_if_not_color(RenderBuffer &buffer, int x, int y, xlColor toColor, xlColor notColor, bool wrapx, bool wrapy)
{
    int adjx = x;
    int adjy = y;

    if (x < 0) {
        if (wrapx) {
            adjx += buffer.BufferWi;
        }
        else {
            return;
        }
    }
    else if (x >= buffer.BufferWi) {
        if (wrapx) {
            adjx -= buffer.BufferWi;
        }
        else {
            return;
        }
    }
    if (y < 0) {
        if (wrapy) {
            adjy += buffer.BufferHt;
        }
        else {
            return;
        }
    }
    else if (y >= buffer.BufferHt) {
        if (wrapy) {
            adjy -= buffer.BufferHt;
        }
        else {
            return;
        }
    }

    // strip off alpha when comparing
    if (buffer.GetTempPixel(adjx, adjy).GetRGB() != notColor.GetRGB()) {
        buffer.SetPixel(adjx, adjy, toColor);
    }
}
Exemple #6
0
void PinwheelEffect::Draw_arm(RenderBuffer &buffer,
                              int base_degrees,int max_radius,int pinwheel_twist,
                              const xlColor &rgb,int xc_adj,int yc_adj)
{
    float r,phi;
    int x,y,xc,yc;
    float pi_180 = M_PI/180;
    int degrees_twist,degrees;
    xc= (int)(buffer.BufferWi/2);
    yc= (int)(buffer.BufferHt/2);
    xc = xc + (xc_adj/100.0)*xc; // xc_adj is from -100 to 100
    yc = yc + (yc_adj/100.0)*yc;


    for(r=0.0; r<=max_radius; r+=0.5)
    {
        degrees_twist=(r/max_radius)*pinwheel_twist;
        degrees = base_degrees + degrees_twist;
        phi = degrees * pi_180;
        x = r * buffer.cos (phi) + xc;
        y = r * buffer.sin (phi) + yc;
        buffer.SetPixel(x, y, rgb);
    }
}
Exemple #7
0
void TendrilEffect::Render(RenderBuffer &buffer, int movement,
                            int tunemovement, int movementSpeed, int thickness,
                           float friction, float dampening,
                           float tension, int trails, int length)
{
    buffer.drawingContext->Clear();

    if (friction < 0.4)
    {
        friction = 0.4;
    }
    if (friction > 0.6)
    {
        friction = 0.6;
    }
    if (dampening < 0)
    {
        dampening = 0;
    }
    if (dampening > 0.5)
    {
        dampening = 0.5;
    }
    if (tension < 0.96)
    {
        tension = 0.96;
    }
    if (tension > 0.999)
    {
        tension = 0.999;
    }
    TendrilRenderCache *cache = (TendrilRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new TendrilRenderCache();
        buffer.infoCache[id] = cache;
    }

    int &_movement = cache->_movement;
    int &_tunemovement = cache->_tunemovement;
    int &_mv1 = cache->_mv1;
    int &_mv2 = cache->_mv2;
    int &_mv3 = cache->_mv3;
    int &_mv4 = cache->_mv4;
    int &_thickness = cache->_thickness;
    int &_trails = cache->_trails;
    int &_length = cache->_length;
    float &_friction = cache->_friction;
    float &_dampening = cache->_dampening;
    float &_tension = cache->_tension;
    xlColor &_colour = cache->_colour;
    Tendril* &_tendril = cache->_tendril;
    xlColor color1;
    buffer.palette.GetColor(0, color1);

    if (_tendril == NULL ||
        _movement != movement ||
        _tunemovement != tunemovement ||
        _thickness != thickness ||
        _friction != friction ||
        _dampening != dampening ||
        _tension != tension ||
        _trails != trails ||
        _length != length ||
        _colour != color1)
    {
        if (_tendril != NULL)
        {
            delete _tendril;
        }
        _thickness = thickness;
        _friction = friction;
        _dampening = dampening;
        _tension = tension;
        _trails = trails;
        _length = length;
        _colour = color1;
        wxPoint start(buffer.BufferWi/2, buffer.BufferHt/2);
        _tendril = new Tendril(_friction, _trails, _length, _dampening, _tension, -1, -1, &start, _colour, _thickness, buffer.BufferWi, buffer.BufferHt);

        if (_movement != movement || _tunemovement != tunemovement)
        {
            switch(movement)
            {
            case 1:
                // random
                // no initialisation
                break;
            case 2:
                // corners
                _mv1 = 0; // current x
                _mv2 = 0; // current y
                _mv3 = 0; // corner
                _mv4 = tunemovement; // movement amount
                if (_mv4 == 0)
                {
                    _mv4 = 1;
                }
                break;
            case 3:
                // circles
                _mv1 = 0; // radians
                _mv2 = std::min(buffer.BufferWi, buffer.BufferHt) / 2; // radius
                _mv3 = tunemovement * 3;
                if (_mv3 == 0)
                {
                    _mv3 = 1;
                }
                break;
            case 4:
                // horizontal zig zag
                _mv1 = 0; // current y
                _mv2 = (double)tunemovement * 1.5;
                if (_mv2 == 0)
                {
                    _mv2 = 1;
                }
                _mv3 = 1; // direction
                break;
            case 5:
                // vertical zig zag
                _mv1 = 0; // current x
                _mv2 = (double)tunemovement * 1.5;
                _mv3 = 1; // direction
                break;
            }
        }
        _movement = movement;
        _tunemovement = tunemovement;
    }

    const double PI  = 3.141592653589793238463;
    int speed = 10 - movementSpeed;
    if (speed <= 0 || buffer.curPeriod % speed == 0)
    {
        switch(_movement)
        {
            case 1:
                _tendril->UpdateRandomMove(_tunemovement);
                break;
            case 2:
                switch(_mv3)
                {
                case 0:
                    _mv1+=std::max(buffer.BufferWi/_mv4,1);
                    if (_mv1 >= buffer.BufferWi - buffer.BufferWi / _mv4)
                    {
                        _mv3++;
                    }
                    break;
                case 1:
                    _mv2+=std::max(buffer.BufferHt/_mv4,1);
                    if (_mv2 >= buffer.BufferHt - buffer.BufferHt / _mv4)
                    {
                        _mv3++;
                    }
                    break;
                case 2:
                    _mv1-=std::max(buffer.BufferWi/_mv4,1);
                    if (_mv1 <= buffer.BufferWi / _mv4)
                    {
                        _mv3++;
                    }
                    break;
                case 3:
                    _mv2-=std::max(buffer.BufferHt/_mv4,1);
                    if (_mv2 <= buffer.BufferHt / _mv4)
                    {
                        _mv3 = 0;
                    }
                    break;
                }
                _tendril->Update(_mv1, _mv2);
                break;
            case 3:
                _mv1++;
                if (_mv1 > _mv3)
                {
                    _mv1 = 0;
                }
                {
                    int x = (double)_mv2 * cos((double)_mv1 * 2.0 * PI / (double)_mv3) + (double)buffer.BufferWi / 2.0;
                    int y = (double)_mv2 * sin((double)_mv1 * 2.0 * PI / (double)_mv3) + (double)buffer.BufferHt / 2.0;
                    _tendril->Update(x, y);
                }
                break;
            case 4:
                {
                    _mv1 = _mv1 + _mv3;
                    int x = sin(std::max((double)buffer.BufferHt / (double)_mv2, 0.5) * PI * (double)_mv1 / (double)buffer.BufferHt) * (double)buffer.BufferWi / 2.0 + (double)buffer.BufferWi / 2.0;
                    if (_mv1 >= buffer.BufferHt || _mv1 <= 0)
                    {
                        _mv3 = _mv3 * -1;
                    }
                    if (_mv3 < 0)
                    {
                        x = buffer.BufferWi - x;
                    }
                    _tendril->Update(x, _mv1);
                }
                break;
            case 5:
                {
                    _mv1 = _mv1 + _mv3;
                    int y = sin(std::max((double)buffer.BufferWi / (double)_mv2, 0.5) * PI * (double)_mv1 / (double)buffer.BufferWi) * (double)buffer.BufferHt / 2.0 + (double)buffer.BufferHt / 2.0;
                    if (_mv1 >= buffer.BufferWi || _mv1 <= 0)
                    {
                        _mv3 = _mv3 * -1;
                    }
                    if (_mv3 < 0)
                    {
                        y = buffer.BufferHt - y;
                    }
                    _tendril->Update(_mv1, y);
                }
                break;
        }
    }

    _tendril->Draw(buffer.drawingContext);
    wxImage * image = buffer.drawingContext->FlushAndGetImage();
    bool hasAlpha = image->HasAlpha();

    xlColor c;
    for(int y=0; y<buffer.BufferHt; y++)
    {
        for(int x=0; x< buffer.BufferWi; x++)
        {
            if (hasAlpha)
            {
                c.Set(image->GetRed(x,y),image->GetGreen(x,y),image->GetBlue(x,y),image->GetAlpha(x,y));
            }
            else
            {
                c.Set(image->GetRed(x,y),image->GetGreen(x,y),image->GetBlue(x,y), 255);
            }
            buffer.SetPixel(x, y, c);
        }
    }
}
Exemple #8
0
void GalaxyEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int center_x = SettingsMap.GetInt("SLIDER_Galaxy_CenterX");
    int center_y = SettingsMap.GetInt("SLIDER_Galaxy_CenterY");
    int start_radius = SettingsMap.GetInt("SLIDER_Galaxy_Start_Radius");
    int end_radius = SettingsMap.GetInt("SLIDER_Galaxy_End_Radius");
    int start_angle = SettingsMap.GetInt("SLIDER_Galaxy_Start_Angle");
    int revolutions = SettingsMap.GetInt("SLIDER_Galaxy_Revolutions");
    int start_width = SettingsMap.GetInt("SLIDER_Galaxy_Start_Width");
    int end_width = SettingsMap.GetInt("SLIDER_Galaxy_End_Width");
    int duration = SettingsMap.GetInt("SLIDER_Galaxy_Duration");
    int acceleration = SettingsMap.GetInt("SLIDER_Galaxy_Accel");
    bool reverse_dir = SettingsMap.GetBool("CHECKBOX_Galaxy_Reverse");
    bool blend_edges = SettingsMap.GetBool("CHECKBOX_Galaxy_Blend_Edges");
    bool inward = SettingsMap.GetBool("CHECKBOX_Galaxy_Inward");

    if( revolutions == 0 ) return;
    std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt));
    std::vector< std::vector<double> > pixel_age(buffer.BufferWi, std::vector<double>(buffer.BufferHt));

    double eff_pos = buffer.GetEffectTimeIntervalPosition();
    int num_colors = buffer.palette.Size();
    xlColor color, c_old, c_new;
    HSVValue hsv1;
    double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration);
    double revs = (double)revolutions;

    double pos_x = buffer.BufferWi * center_x/100.0;
    double pos_y = buffer.BufferHt * center_y/100.0;

    double head_duration = duration/100.0;    // time the head is in the frame
    double tail_length = revs * (1.0 - head_duration);
    double color_length = tail_length / num_colors;
    if(color_length < 1.0) color_length = 1.0;


    double tail_end_of_tail = ((revs + tail_length) * eff_pos_adj) - tail_length;
    double head_end_of_tail = tail_end_of_tail + tail_length;

    double radius1 = start_radius;
    double radius2 = end_radius;
    double width1 = start_width;
    double width2 = end_width;

    double step = buffer.GetStepAngle(radius1, radius2);

    for( int x = 0; x < buffer.BufferWi; x++ )
    {
        for( int y = 0; y < buffer.BufferHt; y++ )
        {
            temp_colors_pct[x][y] = 0.0;
            pixel_age[x][y] = 0.0;
        }
    }
    buffer.ClearTempBuf();

    double last_check = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail) ) + (double)start_angle;

    for( double i = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail));
        (inward ? i >= std::max(0.0, tail_end_of_tail) : i <= std::min(head_end_of_tail,revs));
        (inward ? i -= step : i += step) )
    {
        double adj_angle = i + (double)start_angle;
        if( reverse_dir )
        {
            adj_angle *= -1.0;
        }
        double color_val = (head_end_of_tail-i) / color_length;
        int color_int = (int)color_val;
        double color_pct = color_val - (double)color_int;
        int color2 = std::min(color_int+1, num_colors-1);
        if( color_int < color2 )
        {
            buffer.Get2ColorBlend(color_int, color2, std::min( color_pct, 1.0), color);
        }
        else
        {
            buffer.palette.GetColor(color2, color);
        }
        HSVValue hsv(color);
        double full_brightness = hsv.value;
        double pct = i/revs;
        double current_radius = radius2 * pct + radius1 * (1.0 - pct);
        double current_width = width2 * pct + width1 * (1.0 - pct);
        double half_width = current_width / 2.0;
        double inside_radius = current_radius - half_width;
        for( double r = inside_radius; ; r += 0.5 )
        {
            if( r > current_radius ) r = current_radius;
            double x1 = buffer.sin(ToRadians(adj_angle)) * r + (double)pos_x;
            double y1 = buffer.cos(ToRadians(adj_angle)) * r + (double)pos_y;
            double outside_radius = current_radius + (current_radius - r);
            double x2 = buffer.sin(ToRadians(adj_angle)) * outside_radius + (double)pos_x;
            double y2 = buffer.cos(ToRadians(adj_angle)) * outside_radius + (double)pos_y;
            double color_pct2 = (r-inside_radius)/(current_radius-inside_radius);
            if( blend_edges )
            {
                if( hsv.value > 0.0 )
                {
                    if ((int)x1 >= 0 && (int)x1 < buffer.BufferWi && (int)y1 >= 0 && (int)y1 < buffer.BufferHt)
                    {
                        buffer.SetTempPixel((int)x1,(int)y1,color);
                        temp_colors_pct[(int)x1][(int)y1] = color_pct2;
                        pixel_age[(int)x1][(int)y1] = adj_angle;
                    }
                    if ((int)x2 >= 0 && (int)x2 < buffer.BufferWi && (int)y2 >= 0 && (int)y2 < buffer.BufferHt)
                    {
                        buffer.SetTempPixel((int)x2,(int)y2,color);
                        temp_colors_pct[(int)x2][(int)y2] = color_pct2;
                        pixel_age[(int)x2][(int)y2] = adj_angle;
                    }
                }
            }
            else
            {
                hsv.value = full_brightness * color_pct2;
                if( hsv.value > 0.0 )
                {
                    buffer.SetPixel(x1,y1,hsv);
                    buffer.SetPixel(x2,y2,hsv);
                }
            }
            if( r >= current_radius ) break;
        }
        // blend old data down into final buffer
        if( blend_edges && ( (inward ? (last_check-adj_angle) : (adj_angle-last_check)) >= 90.0) )
        {
            for( int x = 0; x < buffer.BufferWi; x++ )
            {
                for( int y = 0; y < buffer.BufferHt; y++ )
                {
                    if( temp_colors_pct[x][y] > 0.0 && ((inward ? (pixel_age[x][y]-adj_angle) : (adj_angle-pixel_age[x][y])) >= 180.0) )
                    {
                        buffer.GetTempPixel(x,y,c_new);
                        buffer.GetPixel(x,y,c_old);
                        buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                        buffer.SetPixel(x,y,color);
                        temp_colors_pct[x][y] = 0.0;
                        pixel_age[x][y] = 0.0;
                    }
                }
            }
            last_check = adj_angle;
        }
    }

    // blend remaining data down into final buffer
    if( blend_edges )
    {
        for( int x = 0; x < buffer.BufferWi; x++ )
        {
            for( int y = 0; y < buffer.BufferHt; y++ )
            {
                if( temp_colors_pct[x][y] > 0.0 )
                {
                    buffer.GetTempPixel(x,y,c_new);
                    buffer.GetPixel(x,y,c_old);
                    buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                    buffer.SetPixel(x,y,color);
                }
            }
        }
    }

}
Exemple #9
0
void GarlandsEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int GarlandType = SettingsMap.GetInt("SLIDER_Garlands_Type", 0);
    int Spacing = SettingsMap.GetInt("SLIDER_Garlands_Spacing", 0);
    float cycles = SettingsMap.GetDouble("TEXTCTRL_Garlands_Cycles", 1.0);

    if (Spacing < 1) {
        Spacing = 1;
    }
    int x,y,yadj,ylimit,ring;
    double ratio;
    xlColor color;
    int dir = GetDirection(SettingsMap.Get("CHOICE_Garlands_Direction", "Up"));
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    if (dir > 3) {
        dir -= 4;
        if (position > 0.5) {
            position = (1.0 - position) * 2.0;
        } else {
            position *= 2.0;
        }
    }
    int buffMax = buffer.BufferHt;
    int garlandWid = buffer.BufferWi;
    if (dir > 1) {
        buffMax = buffer.BufferWi;
        garlandWid = buffer.BufferHt;
    }
    double PixelSpacing=Spacing*buffMax/100.0;
    if (PixelSpacing < 2.0) PixelSpacing=2.0;


    double total = buffMax * PixelSpacing - buffMax + 1;
    double positionOffset = total * position;

    for (ring = 0; ring < buffMax; ring++)
    {
        ratio=double(buffMax-ring-1)/double(buffMax);
        buffer.GetMultiColorBlend(ratio, false, color);

        y = 1.0 + ring*PixelSpacing - positionOffset;


        ylimit=ring;
        for (x=0; x<garlandWid; x++)
        {
            yadj=y;
            switch (GarlandType)
            {
            case 1:
                switch (x%5)
                {
                case 2:
                    yadj-=2;
                    break;
                case 1:
                case 3:
                    yadj-=1;
                    break;
                }
                break;
            case 2:
                switch (x%5)
                {
                case 2:
                    yadj-=4;
                    break;
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            case 3:
                switch (x%6)
                {
                case 3:
                    yadj-=6;
                    break;
                case 2:
                case 4:
                    yadj-=4;
                    break;
                case 1:
                case 5:
                    yadj-=2;
                    break;
                }
                break;
            case 4:
                switch (x%5)
                {
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            }
            if (yadj < ylimit) yadj=ylimit;
            if (yadj < buffMax) {
                if (dir == 1 || dir == 2) {
                    yadj = buffMax - yadj - 1;
                }
                if (dir > 1) {
                    buffer.SetPixel(yadj,x,color);
                } else {
                    buffer.SetPixel(x,yadj,color);
                }
            }
        }
    }
}
Exemple #10
0
void StateEffect::RenderState(RenderBuffer &buffer,
                             SequenceElements *elements, const std::string &faceDefinition,
                             const std::string& Phoneme, const std::string &trackName, const std::string& mode, const std::string& colourmode)
{
    if (buffer.needToInit) {
        buffer.needToInit = false;
        elements->AddRenderDependency(trackName, buffer.cur_model);
    
        if (buffer.isTransformed)
        {
            log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
            logger_base.warn("State effect starting at %dms until %dms on model %s has a transformed buffer. This may not work as expected.", buffer.curEffStartPer * buffer.frameTimeInMs, buffer.curEffEndPer * buffer.frameTimeInMs, (const char *)buffer.cur_model.c_str());
        }
    }

    Element *track = elements->GetElement(trackName);
    std::recursive_mutex tmpLock;
    std::recursive_mutex *lock = &tmpLock;
    if (track != nullptr) {
        lock = &track->GetChangeLock();
    }
    std::unique_lock<std::recursive_mutex> locker(*lock);

    if (buffer.cur_model == "") {
        return;
    }

    Model* model_info = buffer.frame->AllModels[buffer.cur_model];
    if (model_info == nullptr) {
        return;
    }

    std::string definition = faceDefinition;
    bool found = true;
    std::map<std::string, std::map<std::string, std::string> >::iterator it = model_info->stateInfo.find(definition);
    if (it == model_info->stateInfo.end()) {
        //not found
        found = false;
    }
    if (!found) {
        if ("Coro" == definition && model_info->stateInfo.find("SingleNode") != model_info->stateInfo.end()) {
            definition = "SingleNode";
            found = true;
        } else if ("SingleNode" == definition && model_info->stateInfo.find("Coro") != model_info->stateInfo.end()) {
            definition = "Coro";
            found = true;
        }
    }

    if (definition == "")
    {
        return;
    }

    std::string modelType = found ? model_info->stateInfo[definition]["Type"] : definition;
    if (modelType == "") {
        modelType = definition;
    }

    int type = 1;

    if ("SingleNode" == modelType) {
        type = 0;
    } else if ("NodeRange" == modelType) {
        type = 1;
    }

    std::string tstates = Phoneme;
    int intervalnumber = 0;
    //GET label from timing track
    int startms = -1;
    int endms = -1;
    int posms = -1;
    if (tstates == "") {

        // if we dont have a track then exit
        if (track == NULL)
        {
            return;
        }

        EffectLayer *layer = track->GetEffectLayer(0);
        std::unique_lock<std::recursive_mutex> locker(layer->GetLock());
        int time = buffer.curPeriod * buffer.frameTimeInMs + 1;
        posms = buffer.curPeriod * buffer.frameTimeInMs;
        Effect *ef = layer->GetEffectByTime(time);
        if (ef == nullptr) {
            tstates = "";
        }
        else {
            startms = ef->GetStartTimeMS();
            endms = ef->GetEndTimeMS();
            tstates = ef->GetEffectName();
        }

        ef = layer->GetEffectByTime(buffer.curEffStartPer * buffer.frameTimeInMs + 1);
        while (ef != NULL && ef->GetStartTimeMS() <= time)
        {
            intervalnumber++;
            int endtime = ef->GetEndTimeMS();
            ef = layer->GetEffectByTime(endtime + 1);
            if (ef == NULL)
            {
                ef = layer->GetEffectAfterTime(endtime + 1);
            }
        }
    }

    std::vector<std::string> sstates;

    if (mode == "Default" || startms == -1)
    {
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            sstates.push_back(token.Lower().ToStdString());
        }
    }
    else if (mode == "Countdown")
    {
        // tstates should contain the starting number
        int val = wxAtoi(tstates);

        val = val * 1000;
        int subtracttime = (posms - startms);
        val = val - subtracttime;
        val = val / 1000;

        int v = val;
        bool force = false;
        if ((v / 1000) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 1000) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 1000) * 1000;
        if ((v / 100) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 100).ToStdString());
            force = true;
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 10).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("00");
            }
        }
        v = v - (v / 10) * 10;
        sstates.push_back(wxString::Format("%d", v).ToStdString());
    }
    else if (mode == "Time Countdown")
    {
        wxDateTime dt;
        dt.ParseFormat(tstates.c_str(), "%H:%M:%S");

        if (!dt.IsValid())
        {
            dt.ParseFormat(tstates.c_str(), "%M:%S");
        }

        if (dt.IsValid())
        {
            dt.Subtract(wxTimeSpan(0, 0, 0, (buffer.curPeriod - buffer.curEffStartPer) * buffer.frameTimeInMs));
            int m = dt.GetMinute();
            if ((m / 10) * 1000 > 0)
            {
                sstates.push_back(wxString::Format("%d", (m / 10) * 1000).ToStdString());
            }
            else
            {
                sstates.push_back("0000");
            }
            m = m - (m / 10) * 10;
            if (m * 100 > 0)
            {
                sstates.push_back(wxString::Format("%d", m * 100).ToStdString());
            }
            else
            {
                sstates.push_back("000");
            }
            int s = dt.GetSecond();
            if ((s / 10) * 10 > 0)
            {
                sstates.push_back(wxString::Format("%d", (s / 10) * 10).ToStdString());
            }
            else
            {
                sstates.push_back("00");
            }
            s = s - (s / 10) * 10;
            sstates.push_back(wxString::Format("%d", s).ToStdString());
        }
        sstates.push_back("colon");
    }
    else if (mode == "Number") // used for FM frequencies
    {
        double f = wxAtof(tstates);
        sstates.push_back("dot");
        double f2 = f - int(f);
        f2 = (int)(f2 * 10 + 0.5);
        sstates.push_back(wxString::Format("%d", (int)f2).ToStdString());

        int v = f;
        bool force = false;
        if ((v / 100) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 100).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 10) * 10;
        if (v * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", v * 10).ToStdString());
        }
        else
        {
            sstates.push_back("00");
        }
    }
    else if (mode == "Iterate")
    {
        float progressthroughtimeinterval = ((float)posms - (float)startms) / ((float)endms - (float)startms);

        std::vector<std::string> tmpstates;
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            tmpstates.push_back(token.Lower().ToStdString());
        }

        int which = tmpstates.size() * progressthroughtimeinterval;

        if (which < sstates.size())
        {
            sstates.push_back(tmpstates[which]);
        }
    }

    bool customColor = found ? model_info->stateInfo[definition]["CustomColors"] == "1" : false;

    // process each token
    for (size_t i = 0; i < sstates.size(); i++)
    {
        // get the channels
        std::string statename = FindState(model_info->stateInfo[definition], sstates[i]);
        std::string channels = model_info->stateInfo[definition][statename];

        if (statename != "" && channels != "")
        {
            xlColor color;
            if (colourmode == "Graduate")
            {
                buffer.GetMultiColorBlend(buffer.GetEffectTimeIntervalPosition(), false, color);
            }
            else if (colourmode == "Cycle")
            {
                buffer.palette.GetColor((intervalnumber - 1) % buffer.GetColorCount(), color);
            }
            else
            {
                // allocate
                int statenum = wxAtoi(statename.substr(1));
                buffer.palette.GetColor((statenum - 1) % buffer.GetColorCount(), color);
            }
            if (customColor) {
                std::string cname = model_info->stateInfo[definition][statename + "-Color"];
                if (cname == "") {
                    color = xlWHITE;
                }
                else {
                    color = xlColor(cname);
                }
            }

            wxStringTokenizer wtkz(channels, ",");
            while (wtkz.HasMoreTokens())
            {
                wxString valstr = wtkz.GetNextToken();

                if (type == 0) {
                    for (size_t n = 0; n < model_info->GetNodeCount(); n++) {
                        wxString nn = model_info->GetNodeName(n, true);
                        if (nn == valstr) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
                else if (type == 1) {
                    int start, end;
                    if (valstr.Contains("-")) {
                        int idx = valstr.Index('-');
                        start = wxAtoi(valstr.Left(idx));
                        end = wxAtoi(valstr.Right(valstr.size() - idx - 1));
                    }
                    else {
                        start = end = wxAtoi(valstr);
                    }
                    if (start > end) {
                        start = end;
                    }
                    start--;
                    end--;
                    for (int n = start; n <= end; n++) {
                        if (n < buffer.Nodes.size()) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
            }
        }
    }
}
Exemple #11
0
void FireworksEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int Number_Explosions = SettingsMap.GetInt("SLIDER_Fireworks_Explosions", 16);
    int Count = SettingsMap.GetInt("SLIDER_Fireworks_Count", 50);
    float Velocity = SettingsMap.GetDouble("SLIDER_Fireworks_Velocity", 2.0f);
    int Fade = SettingsMap.GetInt("SLIDER_Fireworks_Fade", 50);

    float f = 0.0;
    bool useMusic = SettingsMap.GetBool("CHECKBOX_Fireworks_UseMusic", false);
    float sensitivity = (float)SettingsMap.GetInt("SLIDER_Fireworks_Sensitivity", 50) / 100.0;
    bool useTiming = SettingsMap.GetBool("CHECKBOX_FIRETIMING", false);
    wxString timing = SettingsMap.Get("CHOICE_FIRETIMINGTRACK", "");
    if (timing == "") useTiming = false;
    if (useMusic)
    {
        if (buffer.GetMedia() != nullptr) {
            std::list<float>* pf = buffer.GetMedia()->GetFrameData(buffer.curPeriod, FRAMEDATA_HIGH, "");
            if (pf != nullptr)
            {
                f = *pf->begin();
            }
        }
    }

    FireworksRenderCache *cache = (FireworksRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new FireworksRenderCache();
        buffer.infoCache[id] = cache;
    }
    
    int& next = cache->next;
    int& sincelasttriggered = cache->sincelasttriggered;
    int x25,x75,y25,y75;
    //float velocity = 3.5;
    int ColorIdx;
    float v;
    HSVValue hsv;
    size_t colorcnt = buffer.GetColorCount();
    
    if (buffer.needToInit) {
        SetPanelTimingTracks();
        cache->sincelasttriggered = 0;
        cache->next = 0;
        buffer.needToInit = false;
        for(int i=0; i<maxFlakes; i++) {
            cache->fireworkBursts[i]._bActive = false;
        }
        for (int x = 0; x < Number_Explosions; x++) {
            double start = -1;
            if (!useMusic)
            {
                start = buffer.curEffStartPer + buffer.rand01() * (buffer.curEffEndPer - buffer.curEffStartPer);
            }
            x25=(int)buffer.BufferWi*0.25;
            x75=(int)buffer.BufferWi*0.75;
            y25=(int)buffer.BufferHt*0.25;
            y75=(int)buffer.BufferHt*0.75;
            int startX;
            int startY;
            if((x75-x25)>0) startX = x25 + rand()%(x75-x25); else startX=0;
            if((y75-y25)>0) startY = y25 + rand()%(y75-y25); else startY=0;
            
            // Create a new burst
            ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
            for(int i=0; i<Count; i++) {
                cache->fireworkBursts[x * Count + i].Reset(startX, startY, false, Velocity, ColorIdx, start);
            }
        }

        if (timing != "")
        {
            effect->GetParentEffectLayer()->GetParentElement()->GetSequenceElements()->AddRenderDependency(timing.ToStdString(), buffer.cur_model);
        }
    }

    if (useMusic)
    {
        // only trigger a firework if music is greater than the sensitivity
        if (f > sensitivity)
        {
            // trigger if it was not previously triggered or has been triggered for REPEATTRIGGER frames
            if (sincelasttriggered == 0 || sincelasttriggered > REPEATTRIGGER)
            {
                // activate all the particles in the next firework
                for (int j = 0; j < Count; j++)
                {
                    cache->fireworkBursts[Count*next + j]._bActive = true;
                    buffer.palette.GetHSV(cache->fireworkBursts[Count*next + j]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                    cache->fireworkBursts[Count*next + j]._hsv = hsv;
                }

                // use the next firework next time
                next++;
                if (next == Number_Explosions)
                {
                    next = 0;
                }
            }

            // if music is over the trigger level for REPEATTRIGGER frames then we will trigger another firework
            sincelasttriggered++;
            if (sincelasttriggered > REPEATTRIGGER)
            {
                sincelasttriggered = 0;
            }
        }
        else
        {
            // not triggered so clear last triggered counter
            sincelasttriggered = 0;
        }
    }

    if (useTiming)
    {
        if (mSequenceElements == nullptr)
        {
            // no timing tracks ... this shouldnt happen
        }
        else
        {
            // Load the names of the timing tracks
            Element* t = nullptr;
            for (size_t l = 0; l < mSequenceElements->GetElementCount(); l++)
            {
                Element* e = mSequenceElements->GetElement(l);
                if (e->GetEffectLayerCount() == 1 && e->GetType() == ELEMENT_TYPE_TIMING)
                {
                    if (e->GetName() == timing)
                    {
                        t = e;
                        break;
                    }
                }
            }

            if (t == nullptr)
            {
                // timing track not found ... this shouldnt happen
            }
            else
            {
                sincelasttriggered = 0;
                EffectLayer* el = t->GetEffectLayer(0);
                for (int j = 0; j < el->GetEffectCount(); j++)
                {
                    if (buffer.curPeriod == el->GetEffect(j)->GetStartTimeMS() / buffer.frameTimeInMs ||
                        buffer.curPeriod == el->GetEffect(j)->GetEndTimeMS() / buffer.frameTimeInMs)
                    {
                        // activate all the particles in the next firework
                        for (int k = 0; k < Count; k++)
                        {
                            cache->fireworkBursts[Count*next + k]._bActive = true;
                            buffer.palette.GetHSV(cache->fireworkBursts[Count*next + k]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                            cache->fireworkBursts[Count*next + k]._hsv = hsv;
                        }

                        // use the next firework next time
                        next++;
                        if (next == Number_Explosions)
                        {
                            next = 0;
                        }
                        break;
                    }
                }
            }
        }
    }

    for (int i=0; i<(Count*Number_Explosions); i++) {
        if (!useMusic && !useTiming)
        {
            if (cache->fireworkBursts[i].startPeriod == buffer.curPeriod) {
                cache->fireworkBursts[i]._bActive = true;
                buffer.palette.GetHSV(cache->fireworkBursts[i]._colorindex, hsv); // Now go and get the hsv value for this ColorIdx
                cache->fireworkBursts[i]._hsv = hsv;
            }
        }

        // ... active flakes:
        if (cache->fireworkBursts[i]._bActive)
        {
            // Update position
            cache->fireworkBursts[i]._x += cache->fireworkBursts[i]._dx;
            cache->fireworkBursts[i]._y += (-cache->fireworkBursts[i]._dy - cache->fireworkBursts[i]._cycles*cache->fireworkBursts[i]._cycles/10000000.0);
            // If this flake run for more than maxCycle or this flake is out of bounds, time to switch it off
            cache->fireworkBursts[i]._cycles+=20;
            if (cache->fireworkBursts[i]._cycles >= 10000 || cache->fireworkBursts[i]._y >= buffer.BufferHt || cache->fireworkBursts[i]._y < 0 ||
                cache->fireworkBursts[i]._x < 0. || cache->fireworkBursts[i]._x >= buffer.BufferWi)
            {
                cache->fireworkBursts[i]._bActive = false;
                if (useMusic)
                {
                    cache->fireworkBursts[i].Reset();
                }
                continue;
            }
        }
        if(cache->fireworkBursts[i]._bActive == true)
        {
            v = ((Fade*10.0)-cache->fireworkBursts[i]._cycles)/(Fade*10.0);
            if (v<0) v=0.0;
            if (buffer.allowAlpha) {
                xlColor c(cache->fireworkBursts[i]._hsv);
                c.alpha = 255.0 * v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, c);
            } else {
                hsv=cache->fireworkBursts[i]._hsv;
                hsv.value=v;
                buffer.SetPixel(cache->fireworkBursts[i]._x, cache->fireworkBursts[i]._y, hsv);
            }
        }
    }
}
Exemple #12
0
bool PianoRenderCache::Piano_RenderKey(RenderBuffer &buffer, Sprite* sprite, std::hash_map<wxPoint_, int>& drawn,
                                 int style, wxSize& canvas, wxSize& keywh, const wxString &placement, bool clip)
//bool RgbEffects::Sprite::render(wxSize& keywh, wxSize& BufferWH_int, int yscroll, bool Clipping)
{
    debug_function(9);
    
    //hash_map<pair<wxPoint, wxSize>, int>& drawn)
    //PIANO_STYLE_KEYS sprites have 2 states: on (down) and off (up); draw all sprites; top view or edge view
    int drawstate = sprite->ani_state++; //bump to next active (animation) state
    if (!drawstate) sprite->ani_state = 0; //stay in inactive state
    else
        //    if ((xy.size() == 1) && (drawstate == -1)) return false; //inactive on/off sprite; don't need tp draw anything
        if (drawstate >= sprite->xy.size()) //end of animation
            //				if (it->repeat > 0) drawstate = 0; //loop immediately
            //				else if (it->repeat < 0) drawstate = -rnd(); //loop with delay
        /*else*/ drawstate = sprite->xy.size() - 1; //stay at last state; don't loop
    
    //    wxPoint realxy = sprite->destxy;
    //    realxy.y += yscroll; //scrolling
    debug_more(30, ", dest (%d => %d, %d), #drawn %d", sprite->destxy.x, (clip? sprite->destxy.x: sprite->destxy.x % canvas.x), sprite->destxy.y, drawn.size());
    if (clip)
        if ((sprite->destxy.x >= buffer.BufferWi) || (sprite->destxy.y >= buffer.BufferHt) || (sprite->destxy.x + keywh.x < 0) || (sprite->destxy.y + keywh.y < 0)) return false; //outside of visible rect
    //    debug_more(30, ", here1");
    wxPoint_ where = sprite->destxy.y * 65536 + (clip? sprite->destxy.x: sprite->destxy.x % canvas.x); //wrap on even key boundary
    //    debug_more(30, ", here2");
    if ((style != PIANO_STYLE_ANIMAGE) && (drawn.find(where) != drawn.end()) && (drawstate <= drawn[where])) { debug_more(30, ", already drawn[0x%x]=%d vs %d", where, drawn[where], drawstate); return false; } //do not redraw older states in same location
    drawn[where] = drawstate; //remember highest state drawn in this location
    
    //don't draw overlapping regions more than once
    
    //                    SetPixel(x-xoffset,(state % ((imght+BufferHt)*speedfactor)) / speedfactor-y,c); //moving up
    //                    SetPixel(x-xoffset,BufferHt+imght-y-(state % ((imght+BufferHt)*speedfactor)) / speedfactor,c); //moving down
    //copy sprite image to pixel buffer, scale up/down:
    //iterate thru target pixels and pull from sprite in case sizes don't match (need to set all target pixels, but okay to skip some source pixels)
    float xscale = (float)sprite->wh.x / keywh.x, yscale = (float)sprite->wh.y / keywh.y; //src -> dest scale factor
    //    debug_more(30, ", here3");
    //TODO: use wxImage.GetData for better performance?
    int xofs = !clip? (buffer.BufferWi % (7 * keywh.x)) / 2: 0; //center keys if not clipped
    if (WantHistory(style)) debug(20, "draw sprite '%s': set x/y %d/%d + %d/%d to 0x%x", (const char*)sprite->name.ToStdString().c_str(), sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, drawstate? sprite->on.GetRGB(): sprite->off.GetRGB()); //.Flush(true);
    else debug(20, "draw sprite '%s': copy from x/y[%d/%d] %d/%d + %d/%d => x/y %d/%d + %d/%d, x/y scale = %f/%f", (const char*)sprite->name.ToStdString().c_str(), drawstate, sprite->xy.size(), sprite->xy[drawstate].x, sprite->xy[drawstate].y, sprite->wh.x, sprite->wh.y, sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, 1.0 / xscale, 1.0 / yscale); //.Flush(true);
    for (int x = 0; x < keywh.x; ++x) //copying to it->w columns in dest
        for (int y = 0; y < keywh.y; ++y) //copying to it->h rows in dest; vert scaling is more likely, so make Y the inner loop for better pixel caching
        {
            //            static xlColor cached_rgb; //cached mapped pixel color
            //            static wxPoint cached_xy(-1, -1);
            wxPoint src_xy(sprite->xy[drawstate].x + x * xscale, sprite->xy[drawstate].y + y * yscale);
            //TODO: scale doesn't make sense for all cases
            src_xy.y = Shapes.GetHeight() - src_xy.y - 1; //whoops, origin is top left but wanted bottom left
            bool transparent = 0;
            if (WantHistory(style)) cached_rgb = drawstate? sprite->on: sprite->off; //kludge: fill rect with same color to avoid losing pixels due to scaling
            else if ((src_xy.x != cached_xy.x) || (src_xy.y != cached_xy.y)) //update cached pixel info
            {
                cached_xy = src_xy; //prev_xy.x = src_xy.x; prev_y = srcy; //not sure how expensive wx pixel functions are, so cache current pixel info just in case; aliasing/averaging and color mapping also makes thiss more expensive
                if (Shapes.IsTransparent(src_xy.x, src_xy.y)) transparent = 1; //-1; //-1 matches white, so use + instead
                else
                {
                    //                        xlColor c;
                    //TODO: tile, center, anti-aliasing
                    cached_rgb.Set(Shapes.GetRed(src_xy.x, src_xy.y), Shapes.GetGreen(src_xy.x, src_xy.y), Shapes.GetBlue(src_xy.x, src_xy.y)); //NOTE: need to do pixel merging if scale is not 1:1
                    if (!ColorMap.empty()) cached_rgb = ColorMap[cached_rgb.GetRGB()]; //map to user-selected colors
                }
                debug_more(20, ", LK(%d,%d)", cached_xy.x, cached_xy.y);
            }
            if (transparent == 1 /*-1*/) continue; //don't need to draw pixel
            int wrapx = sprite->destxy.x + x, scrolly = sprite->destxy.y;
            //            if (style == PIANO_STYLE_ANIMAGE) { wrapx *= xscale; scrolly *= yscale; }
            if (!clip) wrapx %= canvas.x; //wrap on even key boundary
            //            if ((style == PIANO_STYLE_ICICLES) || (style == PIANO_STYLE_EQBARS)) scrolly += canvas.y - keywh.y; //draw at top instead of bottom
            if (style == PIANO_STYLE_ICICLES) scrolly += canvas.y - keywh.y; //draw at top instead of bottom
            //            debug_more(20, ", %d+%d vs. %d-%d? %d", xofs, wrapx, BufferWi, xofs, xofs + wrapx < BufferWi - xofs);
            //            if (!clip) wrapx = (wrapx + 2 * xofs) % BufferWi - 2 * xofs; //wrap within reduced area, not expanded area
            debug_more(20, ", (%d,%d)<-0x%x", wrapx, sprite->destxy.y + y, cached_rgb.GetRGB());
            if (xofs + wrapx < buffer.BufferWi - xofs) buffer.SetPixel(xofs + wrapx, sprite->destxy.y + y, cached_rgb); //no vertical wrap, only horizontal wrap
        }
    //    debug.Flush(true);
    return true;
}
Exemple #13
0
void PinwheelEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    float oset = buffer.GetEffectTimeIntervalPosition();

    int pinwheel_arms = SettingsMap.GetInt("SLIDER_Pinwheel_Arms", 3);
    int pinwheel_twist = GetValueCurveInt("Pinwheel_Twist", 0, SettingsMap, oset);
    int pinwheel_thickness = GetValueCurveInt("Pinwheel_Thickness", 0, SettingsMap, oset);
    bool pinwheel_rotation = SettingsMap.GetBool("CHECKBOX_Pinwheel_Rotation");
    const std::string &pinwheel_3d = SettingsMap["CHOICE_Pinwheel_3D"];
    int xc_adj = GetValueCurveInt("PinwheelXC", 0, SettingsMap, oset);
    int yc_adj = GetValueCurveInt("PinwheelYC", 0, SettingsMap, oset);
    int pinwheel_armsize = GetValueCurveInt("Pinwheel_ArmSize", 100, SettingsMap, oset);
    int pspeed = GetValueCurveInt("Pinwheel_Speed", 10, SettingsMap, oset);
    const std::string &pinwheel_style = SettingsMap["CHOICE_Pinwheel_Style"];

    int xc;
    float tmax;
    HSVValue hsv, hsv1;
    double pos = (buffer.curPeriod - buffer.curEffStartPer) * pspeed * buffer.frameTimeInMs / 50;
    int degrees_per_arm = 1;
    if (pinwheel_arms > 0) degrees_per_arm = 360 / pinwheel_arms;
    float armsize = (pinwheel_armsize / 100.0);

    if (pinwheel_style == "New Render Method")
    {
        std::vector<size_t> colorarray;
        colorarray.resize(pinwheel_arms);
        for (int i = 0; i < pinwheel_arms; i++) { colorarray[i] = i%buffer.GetColorCount(); }

        xc = (int)(ceil(std::hypot(buffer.BufferWi, buffer.BufferHt) / 2));
        xc_adj = xc_adj*buffer.BufferWi / 200;
        yc_adj = yc_adj*buffer.BufferHt / 200;


        int max_radius = xc * armsize;
        if (pinwheel_thickness == 0) pinwheel_thickness = 1;
        tmax = (pinwheel_thickness / 100.0)*degrees_per_arm;

        // Force single visible line in case width is narrower than visible
        float pi_180 = M_PI/180;
        for(int a=0; a<pinwheel_arms; a++)
        {
            int ColorIdx = a%pinwheel_arms;
            xlColor color;
            buffer.palette.GetHSV(colorarray[ColorIdx], hsv);
            color = xlColor(hsv);

            int angle = (a*degrees_per_arm);
            if (pinwheel_rotation == 1) // do we have CW rotation
            {
                angle = (270 - angle) + pos;
            } else {
                angle = angle - 90 - pos;
            }
            int x,y, degrees_twist;
            for (float r=0; r<=max_radius; r+=0.5)
            {
                degrees_twist = (r/max_radius) * pinwheel_twist;
                int t2 = (int)angle%degrees_per_arm;
                double round = (float)t2 / (float)tmax;
                x = floor((int)(r * buffer.cos((angle + degrees_twist) * pi_180)) + xc_adj + buffer.BufferWi / 2);
                y = floor((int)(r * buffer.sin((angle + degrees_twist) * pi_180)) + yc_adj + buffer.BufferHt / 2);
                if (buffer.palette.IsSpatial(colorarray[ColorIdx]))
                {
                    buffer.palette.GetSpatialColor(colorarray[ColorIdx], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color);
                }
                buffer.SetPixel(x,y,color);
            }
        }

        // Draw actual pinwheel arms
        for (int x = 0; x < buffer.BufferWi; x++)
        {
            int x1 = x - xc_adj - (buffer.BufferWi / 2);
            for (int y = 0; y < buffer.BufferHt; y++)
            {
                int y1 = y - yc_adj - (buffer.BufferHt / 2);
                double r = std::hypot(x1, y1);
                if (r <= max_radius) {
                    double degrees_twist = (r / max_radius)*pinwheel_twist;
                    double theta = (std::atan2(x1, y1) * 180 / 3.14159) + degrees_twist;
                    if (pinwheel_rotation == 1) // do we have CW rotation
                    {
                        theta = pos + theta + (tmax/2);
                    } else {
                        theta = pos - theta + (tmax/2);
                    }
                    theta = theta + 540.0;
                    int t2 = (int)theta%degrees_per_arm;
                    if (t2 <= tmax) {
                        double round = (float)t2 / (float)tmax;
                        t2 = std::abs(t2 - (tmax/2)) * 2;
                        xlColor color;
                        int ColorIdx2 = ((int)((theta/degrees_per_arm)))%pinwheel_arms;
                        if (buffer.palette.IsSpatial(colorarray[ColorIdx2]))
                        {
                            buffer.palette.GetSpatialColor(colorarray[ColorIdx2], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color);
                            hsv = color.asHSV();
                        } else {
                            buffer.palette.GetHSV(colorarray[ColorIdx2], hsv);
                        }
                        hsv1=hsv;
                        color = xlColor(hsv1);
                        if(pinwheel_3d=="3D")
                        {
                            if (buffer.allowAlpha) {
                                color.alpha = 255.0 * ((tmax - t2) / tmax);
                            }
                            else {
                                hsv1.value = hsv.value * ((tmax - t2) / tmax);
                                color = hsv1;
                            }
                        }
                        else if (pinwheel_3d == "3D Inverted")
                        {
                            if (buffer.allowAlpha) {
                                color.alpha = 255.0 * ((t2) / tmax);
                            }
                            else {
                                hsv1.value = hsv.value * ((t2) / tmax);
                                color = hsv1;
                            }
                        }
                        buffer.SetPixel(x, y, color);
                    }
                }
            }
        }
    } else { // Old Render Method
        int a,xc,ColorIdx,base_degrees;
        float t,tmax;
        float radius;
        HSVValue hsv,hsv0,hsv1;
        size_t colorcnt=buffer.GetColorCount();

        xc= (int)(std::max(buffer.BufferWi, buffer.BufferHt)/2);
        radius = xc/100.0;

        for(a=1; a<=pinwheel_arms; a++)
        {
            ColorIdx=a%colorcnt;
            buffer.palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx
            if(pinwheel_rotation==1) // do we have CW rotation
            {
                base_degrees = (a-1)*degrees_per_arm + pos; // yes
            }
            else
            {
                base_degrees = (a-1)*degrees_per_arm - pos; // no, we are CCW
            }
            Draw_arm(buffer, base_degrees, xc*armsize, pinwheel_twist,hsv,xc_adj,yc_adj);
            if(pinwheel_thickness>0)
            {
                tmax= (pinwheel_thickness/100.0)*degrees_per_arm/2.0;
                hsv1=hsv;
                xlColor color(hsv1);
                for (t=1; t<=tmax; t++)
                {
                    if(pinwheel_3d=="3D")
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * ((tmax-t)/tmax);
                        } else {
                            hsv1.value = hsv.value * ((tmax-t)/tmax);
                            color = hsv1;
                        }
                    }
                    else if(pinwheel_3d=="3D Inverted")
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * ((t)/tmax);
                        } else {
                            hsv1.value = hsv.value * ((t)/tmax);
                            color = hsv1;
                        }
                    }
                    Draw_arm(buffer, base_degrees-t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj);
                    Draw_arm(buffer, base_degrees+t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj);
                }
            }
        }
    }
}
Exemple #14
0
void OnEffect::Render(Effect *eff, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int start = SettingsMap.GetInt(TEXTCTRL_Eff_On_Start, 100);
    int end = SettingsMap.GetInt(TEXTCTRL_Eff_On_End, 100);
    bool shimmer = SettingsMap.GetInt(CHECKBOX_On_Shimmer, 0) > 0;
    float cycles = SettingsMap.GetDouble(TEXTCTRL_On_Cycles, 1.0);
    int x,y;
    int cidx = 0;
    if (shimmer) {
        int tot = buffer.curPeriod - buffer.curEffStartPer;
        if (tot % 2) {
            if (buffer.palette.Size() <= 1) {
                return;
            }
            cidx = 1;
        }
    }

    bool spatialcolour = buffer.palette.IsSpatial(cidx);

    double adjust = buffer.GetEffectTimeIntervalPosition(cycles);

    xlColor color;
    if (start == 100 && end == 100) {
        buffer.palette.GetColor(cidx, color);
    } else {
        HSVValue hsv;
        buffer.palette.GetHSV(cidx,hsv);
        double d = adjust;
        d = start + (end - start) * d;
        d = d / 100.0;
        hsv.value = hsv.value * d;
        color = hsv;
    }
    
    int transparency = GetValueCurveInt("On_Transparency", 0, SettingsMap, adjust);
    if (transparency) {
        transparency *= 255;
        transparency /= 100;
        color.alpha = 255 - transparency;
    }

    ///////////////////////// DMX Support ////////////////////////
    // if the model is a DMX model this will write the color into
    // the proper red, green, and blue channels.
    //////////////////////////////////////////////////////////////
    if (buffer.cur_model != "") {
        Model* model_info = buffer.frame->AllModels[buffer.cur_model];
        if (model_info != nullptr) {
            if( model_info->GetDisplayAs() == "DMX" ) {
                xlColor c;
                DmxModel* dmx = (DmxModel*)model_info;
                int red_channel = dmx->GetRedChannel();
                int grn_channel = dmx->GetGreenChannel();
                int blu_channel = dmx->GetBlueChannel();
                if( red_channel != 0 ) {
                    c.red = color.red;
                    c.green = color.red;
                    c.blue = color.red;
                    buffer.SetPixel(red_channel-1, 0, c);
                }
                if( grn_channel != 0 ) {
                    c.red = color.green;
                    c.green = color.green;
                    c.blue = color.green;
                    buffer.SetPixel(grn_channel-1, 0, c);
                }
                if( blu_channel != 0 ) {
                    c.red = color.blue;
                    c.green = color.blue;
                    c.blue = color.blue;
                    buffer.SetPixel(blu_channel-1, 0, c);
                }
                return;
            }
        }
    }
    //////////////////////////////////////////////////////////////
    ///////////////////// End DMX Support ////////////////////////
    //////////////////////////////////////////////////////////////

    //Every Node set to selected color
    for (x=0; x<buffer.BufferWi; x++)
    {
        for (y=0; y<buffer.BufferHt; y++)
        {
            if (spatialcolour)
            {
                buffer.palette.GetSpatialColor(cidx, (float)x / (float)buffer.BufferWi, (float)y / (float)buffer.BufferHt, color);
                if (start == 100 && end == 100) {
                }
                else {
                    HSVValue hsv = color.asHSV();
                    double d = adjust;
                    d = start + (end - start) * d;
                    d = d / 100.0;
                    hsv.value = hsv.value * d;
                    color = hsv;
                }
                if (transparency) {
                    color.alpha = 255 - transparency;
                }
            }

            buffer.SetPixel(x,y,color);
        }
    }

    if (shimmer || cycles != 1.0) {
        std::lock_guard<std::recursive_mutex> lock(eff->GetBackgroundDisplayList().lock);
        eff->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 6);
        buffer.CopyPixelsToDisplayListX(eff, 0, 0, 0);
    } else if (buffer.needToInit) {
        std::lock_guard<std::recursive_mutex> lock(eff->GetBackgroundDisplayList().lock);
        eff->GetBackgroundDisplayList().resize(6);
        if (start == 100 && end == 100) {
            buffer.palette.GetColor(0, color);
            buffer.SetDisplayListHRect(eff, 0, 0.0, 0.0, 1.0, 1.0, color, color);
        } else {
            HSVValue hsv;
            buffer.palette.GetHSV(cidx,hsv);
            hsv.value = hsv.value * start / 100.0;
            color = hsv;

            buffer.palette.GetHSV(cidx,hsv);
            hsv.value = hsv.value * end / 100.0;
            buffer.SetDisplayListHRect(eff, 0, 0.0, 0.0, 1.0, 1.0, color, xlColor(hsv));
        }
        buffer.needToInit = false;
    }
}
Exemple #15
0
void StrobeEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int Number_Strobes = SettingsMap.GetInt("SLIDER_Number_Strobes", 1);
    int StrobeDuration = SettingsMap.GetInt("SLIDER_Strobe_Duration", 1);
    int Strobe_Type = SettingsMap.GetInt("SLIDER_Strobe_Type", 0);
    
    StrobeRenderCache *cache = (StrobeRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new StrobeRenderCache();
        buffer.infoCache[id] = cache;
    }
    std::vector<StrobeClass> &strobe = cache->strobe;

    
    if (StrobeDuration == 0) {
        StrobeDuration = 1;
    }
    if (buffer.needToInit) {
        buffer.needToInit = false;
        strobe.resize(StrobeDuration * Number_Strobes);
        for (int x = 0; x < strobe.size(); x++) {
            strobe[x].duration = -1;
        }
    }
    int offset = ((buffer.curPeriod-buffer.curEffStartPer) % StrobeDuration) * Number_Strobes;
    
    int ColorIdx;
    StrobeClass m;
    HSVValue hsv;
    size_t colorcnt=buffer.GetColorCount();
    
    // create new strobe, randomly place a strobe
    
    for(int i = 0; i < Number_Strobes; i++)
    {
        strobe[offset + i].x =rand() % buffer.BufferWi; // randomly pick a x,y location for strobe to fire
        strobe[offset + i].y =rand() % buffer.BufferHt;
        strobe[offset + i].duration = StrobeDuration;
        
        ColorIdx=rand()%colorcnt;
        buffer.palette.GetHSV(ColorIdx, strobe[offset + i].hsv); // take first checked color as color of flash
        buffer.palette.GetColor(ColorIdx, strobe[offset + i].color); // take first checked color as color of flash
    }
    
    // render strobe, we go through all storbes and decide if they should be turned on
    
    int x,y,n=0;
    
    for (std::vector<StrobeClass>::iterator it=strobe.begin(); it!=strobe.end(); ++it) {
        n++;
        hsv=it->hsv;
        xlColor color(it->color);
        x=it->x;
        y=it->y;
        if(it->duration > 0)
        {
            buffer.SetPixel(x,y,color);
        }
        
        double v = 1.0;
        if(it->duration==1)
        {
            v = 0.5;
        }
        else if(it->duration==2)
        {
            v = 0.75;
        }
        if (buffer.allowAlpha) {
            color.alpha = 255.0 * v;
        } else {
            hsv.value *= v;
            color = hsv;
        }
        
        if(Strobe_Type==2)
        {
            int r = rand()%2;
            if(r==0)
            {
                buffer.SetPixel(x,y-1,color);
                buffer.SetPixel(x,y+1,color);
            }
            else
            {
                buffer.SetPixel(x-1,y,color);
                buffer.SetPixel(x+1,y,color);
            }
            
        }
        if(Strobe_Type==3)
        {
            buffer.SetPixel(x,y-1,color);
            buffer.SetPixel(x,y+1,color);
            buffer.SetPixel(x-1,y,color);
            buffer.SetPixel(x+1,y,color);
        }
        if(Strobe_Type==4)
        {
            int r = rand()%2;
            if(r==0)
            {
                buffer.SetPixel(x,y-1,color);
                buffer.SetPixel(x,y+1,color);
                buffer.SetPixel(x-1,y,color);
                buffer.SetPixel(x+1,y,color);
            }
            else
            {
                buffer.SetPixel(x+1,y-1,color);
                buffer.SetPixel(x+1,y+1,color);
                buffer.SetPixel(x-1,y-1,color);
                buffer.SetPixel(x-1,y+1,color);
            }
        }
        
        it->duration--;  // decrease the frame counter on this strobe, when it gets to zero we no longer will turn it on
    }

}
Exemple #16
0
void SnowflakesEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {

    int Count = SettingsMap.GetInt("SLIDER_Snowflakes_Count", 5);
    int SnowflakeType = SettingsMap.GetInt("SLIDER_Snowflakes_Type", 1);
    int sSpeed = SettingsMap.GetInt("SLIDER_Snowflakes_Speed", 10);
    std::string falling = SettingsMap.Get("CHOICE_Falling", "Driving");

    int i,n,x,x0,y0,y,check,delta_y;
    xlColor color1,color2, color3;
    bool wrapx = false; // set to true if you want snowflakes to draw wrapped around when near edges in the accumulate effect.


    SnowflakesRenderCache *cache = (SnowflakesRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new SnowflakesRenderCache();
        buffer.infoCache[id] = cache;
    }

    int &LastSnowflakeCount = cache->LastSnowflakeCount;
    int &LastSnowflakeType = cache->LastSnowflakeType;
    int &effectState = cache->effectState;
    std::string& LastFalling = cache->LastFalling;

    buffer.palette.GetColor(0, color1);
    buffer.palette.GetColor(1, color2);

    if (buffer.needToInit ||
        Count != LastSnowflakeCount ||
        SnowflakeType != LastSnowflakeType ||
        falling != LastFalling) {

        // initialize
        buffer.needToInit = false;
        LastSnowflakeCount=Count;
        LastSnowflakeType=SnowflakeType;
        LastFalling = falling;
        buffer.ClearTempBuf();
        effectState = 0;

        // place Count snowflakes
        for (n=0; n < Count; n++) {

            delta_y=buffer.BufferHt/4;
            y0=(n % 4)*delta_y;

            if (y0+delta_y > buffer.BufferHt) delta_y = buffer.BufferHt-y0;
            if (delta_y<1) delta_y=1;

            // find unused space
            for (check=0; check < 20; check++)
            {
                x=rand() % buffer.BufferWi;
                y=y0 + (rand() % delta_y);
                if (buffer.GetTempPixel(x,y) == xlBLACK) {
                    effectState++;
                    break;
                }
            }

            // draw flake, SnowflakeType=0 is random type
            switch (SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1)
            {
                case 0:
                    // single node
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 0);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                    }
                    break;
                case 1:
                    // 5 nodes
                    if (x < 1) x+=1;
                    if (y < 1) y+=1;
                    if (x > buffer.BufferWi-2) x-=1;
                    if (y > buffer.BufferHt-2) y-=1;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x,y,color1, 1);
                    }
                    else {
                        buffer.SetTempPixel(x,y,color1);
                        buffer.SetTempPixel(x-1,y,color2);
                        buffer.SetTempPixel(x+1,y,color2);
                        buffer.SetTempPixel(x,y-1,color2);
                        buffer.SetTempPixel(x,y+1,color2);
                    }
                    break;
                case 2:
                    // 3 nodes
                    if (x < 1) x+=1;
                    if (y < 1) y+=1;
                    if (x > buffer.BufferWi-2) x-=1;
                    if (y > buffer.BufferHt-2) y-=1;
                    if(falling != "Driving")
                    {
                        buffer.SetTempPixel(x,y,color1, 2);
                    }
                    else
                    {
                        buffer.SetTempPixel(x,y,color1);
                        if (rand() % 100 > 50)      // % 2 was not so random
                        {
                            buffer.SetTempPixel(x-1,y,color2);
                            buffer.SetTempPixel(x+1,y,color2);
                        }
                        else
                        {
                            buffer.SetTempPixel(x,y-1,color2);
                            buffer.SetTempPixel(x,y+1,color2);
                        }
                    }
                    break;
                case 3:
                    // 9 nodes
                    if (x < 2) x+=2;
                    if (y < 2) y+=2;
                    if (x > buffer.BufferWi-3) x-=2;
                    if (y > buffer.BufferHt-3) y-=2;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 3);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                        for (i=1; i<=2; i++)
                        {
                            buffer.SetTempPixel(x-i,y,color2);
                            buffer.SetTempPixel(x+i,y,color2);
                            buffer.SetTempPixel(x,y-i,color2);
                            buffer.SetTempPixel(x,y+i,color2);
                        }
                    }
                    break;
                case 4:
                    // 13 nodes
                    if (x < 2) x+=2;
                    if (y < 2) y+=2;
                    if (x > buffer.BufferWi-3) x-=2;
                    if (y > buffer.BufferHt-3) y-=2;
                    if(falling != "Driving") {
                        buffer.SetTempPixel(x, y, color1, 4);
                    }
                    else {
                        buffer.SetTempPixel(x, y, color1);
                        buffer.SetTempPixel(x-1,y,color2);
                        buffer.SetTempPixel(x+1,y,color2);
                        buffer.SetTempPixel(x,y-1,color2);
                        buffer.SetTempPixel(x,y+1,color2);

                        buffer.SetTempPixel(x-1,y+2,color2);
                        buffer.SetTempPixel(x+1,y+2,color2);
                        buffer.SetTempPixel(x-1,y-2,color2);
                        buffer.SetTempPixel(x+1,y-2,color2);
                        buffer.SetTempPixel(x+2,y-1,color2);
                        buffer.SetTempPixel(x+2,y+1,color2);
                        buffer.SetTempPixel(x-2,y-1,color2);
                        buffer.SetTempPixel(x-2,y+1,color2);
                    }
                    break;
                case 5:
                    // 45 nodes (not enabled)
                    break;
            }
        }
    }

    // move snowflakes
    int movement = (buffer.curPeriod - buffer.curEffStartPer) * sSpeed * buffer.frameTimeInMs / 50;
    int new_x,new_y,new_x2,new_y2;
    int starty = 0;
    if (falling == "Falling & Accumulating")
    {
        starty = 1;
    }

    bool driving = falling == "Driving";
    for (x=0; x<buffer.BufferWi; x++) {
        new_x = (x+movement/20) % buffer.BufferWi; // CW
        new_x2 = (x-movement/20) % buffer.BufferWi; // CCW
        if (new_x2 < 0) new_x2 += buffer.BufferWi;

        for (y=starty; y<buffer.BufferHt; y++) {
            if (!driving) {

                // this controls the speed by skipping movement when slow
                if (((buffer.curPeriod-buffer.curEffStartPer) * (sSpeed+1)) / 30 != ((buffer.curPeriod-buffer.curEffStartPer-1) * (sSpeed + 1)) / 30)
                {
                    // if there is a flake to move
                    buffer.GetTempPixel(x, y, color3);
                    if (color3 != xlBLACK) {

                        // check where we can move to?
                        int moves = possible_downward_moves(buffer, x, y);
                        x0 = x;

                        //we have something to move
                        // randomly move the flake left or right
                        if (moves > 0 || (falling == "Falling" && y == 0))
                        {
                            switch(rand() % 5)
                            {
                                case 0:
                                    if (moves & 1) {
                                        x0 = x - 1;
                                    }
                                    else {
                                        if (moves & 2) {
                                            x0 = x;
                                        }
                                        else {
                                            x0 = x + 1;
                                        }
                                    }
                                    break;
                                case 1:
                                    if (moves & 4) {
                                        x0 = x + 1;
                                    }
                                    else {
                                        if (moves & 2) {
                                            x0 = x;
                                        }
                                        else {
                                            x0 = x - 1;
                                        }
                                    }
                                    break;
                                default:  //down more often then left/right to look less "jittery"
                                    if (moves & 2) {
                                        x0 = x;
                                    }
                                    else if ((moves & 5) == 4) {
                                        x0 = x + 1;
                                    }
                                    else if ((moves & 5) == 1) {
                                        x0 = x - 1;
                                    }
                                    else {
                                        switch(rand() % 2)
                                        {
                                            case 0:
                                                x0 = x+1;
                                                break;
                                            default:
                                                x0 = x-1;
                                                break;
                                        }
                                    }
                                    break;
                            }

                            // handle wrap around
                            if (x0 < 0) {
                                x0 += buffer.BufferWi;
                            }
                            else if (x0 >= buffer.BufferWi) {
                                x0 -= buffer.BufferWi;
                            }

                            // and move it down
                            y0 = y - 1;

                            buffer.SetTempPixel(x, y, xlBLACK);
                            if (y0 >= 0)
                            {
                                // move the flake down
                                buffer.SetTempPixel(x0, y0, color3);

                                if (falling == "Falling & Accumulating")
                                {
                                    int nextmoves = possible_downward_moves(buffer, x0, y0);
                                    if (nextmoves == 0) {
                                        // we cant move any further so we can add one at the top
                                        effectState--;
                                    }
                                }
                            }
                            else
                            {
                                // falling should always be just falling ... never accumulate
                                effectState--;
                            }
                        }
                    }
                }
            } else {
                new_y = (y+movement/10) % buffer.BufferHt;
                new_y2 = (new_y+buffer.BufferHt/2) % buffer.BufferHt;
                buffer.GetTempPixel(new_x,new_y,color1);
                if (color1 == xlBLACK) buffer.GetTempPixel(new_x2,new_y2,color1);                // strip off the alpha channel
                buffer.SetPixel(x, y, color1);
            }
        }
    }

    if (!driving)
    {
        // add new flakes to the top
        check = 0;
        int placedFullCount = 0;
        while (effectState < Count && check < 20) {
            // find unused space
            x=rand() % buffer.BufferWi;
            if (buffer.GetTempPixel(x, buffer.BufferHt-1) == xlBLACK) {
                effectState++;
                buffer.SetTempPixel(x, buffer.BufferHt-1, color1, SnowflakeType == 0 ? rand() % 5 : SnowflakeType-1);

                int nextmoves = possible_downward_moves(buffer, x, buffer.BufferHt-1);
                if (nextmoves == 0) {
                    //the placed pixel fills the column, make sure we note that so we can place
                    //another snowflake
                    placedFullCount++;
                }
            }
            check++;
        }
        effectState -= placedFullCount;

        // paint my current state
        for (int y=0; y < buffer.BufferHt; y++) {
            for (int x=0; x < buffer.BufferWi; x++) {

                buffer.GetTempPixel(x, y, color3);
                if (color3 != xlBLACK)
                {
                    // draw flake, SnowflakeType=0 is random type
                    switch (color3.Alpha())
                    {
                        case 0:
                            // single node
                            buffer.SetPixel(x, y, color1);
                            break;
                        case 1:
                            // 5 nodes
                            buffer.SetPixel(x,y,color1);
                            set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                            break;
                        case 2:
                        {
                            // 3 nodes
                            buffer.SetPixel(x,y,color1);
                            bool isAtBottom = true;
                            for (int yt = 0; yt < y - 1; yt++) {
                                if (buffer.GetTempPixel(x, yt) == xlBLACK) {
                                    isAtBottom = false;
                                    break;
                                }
                            }

                            // when flake has settled always paint it horizontally
                            if (isAtBottom)
                            {
                                set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            }
                            else {
                                if (rand() % 100 > 50)      // % 2 was not so random
                                {
                                    set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                                    set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                                }
                                else
                                {
                                    set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);
                                    set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                                }
                            }
                        }
                            break;
                        case 3:
                            // 9 nodes
                            buffer.SetPixel(x,y,color1);
                            for (i=1; i<=2; i++)
                            {
                                set_pixel_if_not_color(buffer, x-i, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x+i, y, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x, y-i, color2, color1, wrapx, false);
                                set_pixel_if_not_color(buffer, x, y+i, color2, color1, wrapx, false);
                            }
                            break;
                        case 4:
                            // 13 nodes
                            buffer.SetPixel(x,y,color1);
                            set_pixel_if_not_color(buffer, x-1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y+1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x, y-1, color2, color1, wrapx, false);

                            set_pixel_if_not_color(buffer, x-1, y+2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y+2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-1, y-2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+1, y-2, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+2, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x+2, y+1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-2, y-1, color2, color1, wrapx, false);
                            set_pixel_if_not_color(buffer, x-2, y+1, color2, color1, wrapx, false);
                            break;
                        case 5:
                            // 45 nodes (not enabled)
                            break;
                    }
                }
            }
        }
    }
}
Exemple #17
0
void MusicEffect::RenderCollide(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, bool in, std::list<MusicEvent*>& events, int colourTreatment, bool fade)
{
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);

            int mid = buffer.BufferHt / 2;
            int length = buffer.BufferHt;
            int leftstart, leftend;

            if (!in)
            {
                progress = 1.0 - progress;
            }

            leftstart = 0 - mid - 1 + progress * length;
            leftend = leftstart + mid;
            if (leftend > mid)
            {
                leftend = mid;
            }

            int loopstart = leftstart;
            if (loopstart < 0)
            {
                loopstart = 0;
            }

            for (int y = loopstart; y < leftend; y++)
            {
                xlColor c = xlWHITE;
                float proportion = ((float)y - (float)leftstart) / (float)mid;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = progress * 255;
                }

                buffer.SetPixel(x, y, c);
                buffer.SetPixel(x, mid - y + mid - 1, c);
            }
        }
    }
}
Exemple #18
0
void ShockwaveEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int center_x = SettingsMap.GetInt("SLIDER_Shockwave_CenterX", 0);
    int center_y = SettingsMap.GetInt("SLIDER_Shockwave_CenterY", 0);
    int start_radius = SettingsMap.GetInt("SLIDER_Shockwave_Start_Radius", 0);
    int end_radius = SettingsMap.GetInt("SLIDER_Shockwave_End_Radius", 0);
    int start_width = SettingsMap.GetInt("SLIDER_Shockwave_Start_Width", 0);
    int end_width = SettingsMap.GetInt("SLIDER_Shockwave_End_Width", 0);
    int acceleration = SettingsMap.GetInt("SLIDER_Shockwave_Accel", 0);
    bool blend_edges = SettingsMap.GetBool("CHECKBOX_Shockwave_Blend_Edges");

    std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt));
    double eff_pos = buffer.GetEffectTimeIntervalPosition();
    int num_colors = buffer.palette.Size();
    if( num_colors == 0 )
        num_colors = 1;
    xlColor color, c_old, c_new;
    double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration);

    double blend_pct = 1.0 / (num_colors-1);
    double color_pct1 = eff_pos_adj / blend_pct;
    int color_index = (int)color_pct1;
    blend_pct = color_pct1 - (double)color_index;
    buffer.Get2ColorBlend(color_index, std::min(color_index+1,num_colors-1), std::min( blend_pct, 1.0), color);

    double pos_x = buffer.BufferWi * center_x/100.0;
    double pos_y = buffer.BufferHt * center_y/100.0;

    double radius1 = start_radius;
    double radius2 = end_radius;
    double radius_center = radius1 + (radius2 - radius1) * eff_pos_adj;
    double half_width = (start_width + (end_width - start_width) * eff_pos_adj) / 2.0;
    radius1 = radius_center - half_width;
    radius2 = radius_center + half_width;

    double step = buffer.GetStepAngle(radius1, radius2);

    for( int x = 0; x < buffer.BufferWi; x++ )
    {
        for( int y = 0; y < buffer.BufferHt; y++ )
        {
            temp_colors_pct[x][y] = 0.0;
        }
    }
    buffer.ClearTempBuf();

    for( double current_angle = 0.0; current_angle <= 360.0; current_angle += step )
    {
        for( double r = std::max(0.0, radius1); r <= radius2; r += 0.5 )
        {
            double x1 = buffer.sin(ToRadians(current_angle)) * r + (double)pos_x;
            double y1 = buffer.cos(ToRadians(current_angle)) * r + (double)pos_y;

            if( blend_edges )
            {
                double color_pct = 1.0 - std::abs(r-radius_center)/half_width;
                if( color_pct > 0.0 )
                {
                    if (x1 >= 0 && x1 < buffer.BufferWi && y1 >= 0 && y1 < buffer.BufferHt)
                    {
                        if (buffer.allowAlpha) {
                            color.alpha = 255.0 * color_pct;
                            buffer.SetPixel((int)x1,(int)y1,color);
                        } else {
                            temp_colors_pct[(int)x1][(int)y1] = color_pct;
                            buffer.SetTempPixel((int)x1,(int)y1,color);
                        }
                    }
                }
            }
            else
            {
                buffer.SetPixel((int)x1,(int)y1,color);
            }
        }
    }

    // blend element data into final buffer
    if( blend_edges && !buffer.allowAlpha )
    {
        for( int x = 0; x < buffer.BufferWi; x++ )
        {
            for( int y = 0; y < buffer.BufferHt; y++ )
            {
                if( temp_colors_pct[x][y] > 0.0 )
                {
                    buffer.GetTempPixel(x,y,c_new);
                    buffer.GetPixel(x,y,c_old);
                    buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color);
                    buffer.SetPixel(x,y,color);
                    temp_colors_pct[x][y] = 0.0;
                }
            }
        }
    }
}
Exemple #19
0
void TwinkleEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    
    int Count = SettingsMap.GetInt("SLIDER_Twinkle_Count", 3);
    int Steps = SettingsMap.GetInt("SLIDER_Twinkle_Steps", 30);
    bool Strobe = SettingsMap.GetBool("CHECKBOX_Twinkle_Strobe", false);
    bool reRandomize = SettingsMap.GetBool("CHECKBOX_Twinkle_ReRandom", false);
    
    int lights = (buffer.BufferHt*buffer.BufferWi)*(Count / 100.0); // Count is in range of 1-100 from slider bar
    int step = 1;
    if (lights > 0) {
        step = buffer.BufferHt*buffer.BufferWi / lights;
    }
    int max_modulo = Steps;
    if (max_modulo<2) 
        max_modulo = 2;  // scm  could we be getting 0 passed in?
    int max_modulo2 = max_modulo / 2;
    if (max_modulo2<1) 
        max_modulo2 = 1;
    
    if(step<1) 
        step=1;
    
    TwinkleRenderCache *cache = (TwinkleRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new TwinkleRenderCache();
        buffer.infoCache[id] = cache;
    }
    std::vector<StrobeClass> &strobe = cache->strobe;
    
    size_t colorcnt=buffer.GetColorCount();

    int i = 0;

    if (buffer.needToInit) {
        buffer.needToInit = false;
        strobe.clear();
        for (int y=0; y < buffer.BufferHt; y++) {
            for (int x=0; x < buffer.BufferWi; x++) {
                i++;
                if (i%step==1 || step==1) {
                    int s = strobe.size();
                    strobe.resize(s + 1);
                    strobe[s].duration = rand() % max_modulo;
                    
                    strobe[s].x = x;
                    strobe[s].y = y;
                    
                    strobe[s].colorindex = rand() % colorcnt;
                }
            }
        }
    }
    
    for (size_t x = 0; x < strobe.size(); x++) {
        strobe[x].duration++;
        if (strobe[x].duration < 0) {
            continue;
        }
        if (strobe[x].duration == max_modulo) {
            strobe[x].duration = 0;
            if (reRandomize) {
                strobe[x].duration -= rand() % max_modulo2;
                strobe[x].colorindex = rand() % colorcnt;
            }
        }
        int i7 = strobe[x].duration;
        HSVValue hsv;
        buffer.palette.GetHSV(strobe[x].colorindex, hsv);
        double v = hsv.value;
        if(i7<=max_modulo2)
        {
            if(max_modulo2>0) v = (1.0*i7)/max_modulo2;
            else v =0;
        }
        else
        {
            if(max_modulo2>0)v = (max_modulo-i7)*1.0/(max_modulo2);
            else v = 0;
        }
        if(v<0.0) v=0.0;
        
        if(Strobe)
        {
            if(i7==max_modulo2)  v = 1.0;
            else v = 0.0;
        }
        if (buffer.allowAlpha) {
            xlColor color;
            buffer.palette.GetColor(strobe[x].colorindex, color);
            color.alpha = 255.0 * v;
            buffer.SetPixel(strobe[x].x,strobe[x].y,color); // Turn pixel on
        } else {
            buffer.palette.GetHSV(strobe[x].colorindex, hsv);
            //  we left the Hue and Saturation alone, we are just modifiying the Brightness Value
            hsv.value = v;
            buffer.SetPixel(strobe[x].x,strobe[x].y,hsv); // Turn pixel on
        }
    }
}
Exemple #20
0
void ColorWashEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    bool HorizFade = SettingsMap.GetBool(CHECKBOX_ColorWash_HFade);
    bool VertFade = SettingsMap.GetBool(CHECKBOX_ColorWash_VFade);
    float cycles = SettingsMap.GetDouble(TEXTCTRL_ColorWash_Cycles, 1.0);
    bool EntireModel = SettingsMap.GetInt(CHECKBOX_ColorWash_EntireModel, 1);
    int x1 = SettingsMap.GetInt(SLIDER_ColorWash_X1, -50);
    int y1 = SettingsMap.GetInt(SLIDER_ColorWash_Y1, -50);
    int x2 = SettingsMap.GetInt(SLIDER_ColorWash_X2, 50);
    int y2 = SettingsMap.GetInt(SLIDER_ColorWash_Y2, 50);
    bool shimmer = SettingsMap.GetInt(CHECKBOX_ColorWash_Shimmer, 0);
    bool circularPalette = SettingsMap.GetInt(CHECKBOX_ColorWash_CircularPalette, 0);
    
    
    int x,y;
    xlColor color, orig;
    
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    buffer.GetMultiColorBlend(position, circularPalette, color);
    
    int startX = 0;
    int startY = 0;
    int endX = buffer.BufferWi - 1;
    int endY = buffer.BufferHt - 1;
    
    if (!EntireModel) {
        startX = std::min(x1, x2);
        endX = std::max(x1, x2);
        startY = std::min(y1, y2);
        endY = std::max(y1, y2);
        startX = std::round(double(buffer.BufferWi - 0.5) * (double)startX / 100.0);
        endX = std::round(double(buffer.BufferWi - 0.5) * (double)endX / 100.0);
        startY = std::round(double(buffer.BufferHt - 0.5) * (double)startY / 100.0);
        endY = std::round(double(buffer.BufferHt - 0.5) * (double)endY / 100.0);
        startX = std::max(startX, 0);
        endX = std::min(endX, buffer.BufferWi - 1);
        startY = std::max(startY, 0);
        endY = std::min(endY, buffer.BufferHt - 1);
    }
    int tot = buffer.curPeriod - buffer.curEffStartPer;
    if (!shimmer || (tot % 2) == 0) {
        double HalfHt=double(endY - startY)/2.0;
        double HalfWi=double(endX - startX)/2.0;
        
        orig = color;
        HSVValue hsvOrig = color.asHSV();
        xlColor color2 = color;
        for (x=startX; x <= endX; x++)
        {
            HSVValue hsv = hsvOrig;
            if (HorizFade) {
                if (buffer.allowAlpha) {
                    color.alpha = (double)orig.alpha*(1.0-std::abs(HalfWi-x-startX)/HalfWi);
                } else {
                    hsv.value*=1.0-std::abs(HalfWi-x-startX)/HalfWi;
                    color = hsv;
                }
            }
            color2.alpha = color.alpha;
            for (y=startY; y<=endY; y++) {
                if (VertFade) {
                    if (buffer.allowAlpha) {
                        color.alpha = (double)color2.alpha*(1.0-std::abs(HalfHt-(y-startY))/HalfHt);
                    } else {
                        HSVValue hsv2 = hsv;
                        hsv2.value*=1.0-std::abs(HalfHt-(y-startY))/HalfHt;
                        color = hsv2;
                    }
                }
                buffer.SetPixel(x, y, color);
            }
        }
    } else {
        orig = xlBLACK;
    }
    wxMutexLocker lock(effect->GetBackgroundDisplayList().lock);
    if (VertFade || HorizFade) {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4 * 2);
        int total = buffer.curEffEndPer - buffer.curEffStartPer + 1;
        double x1 = double(buffer.curPeriod - buffer.curEffStartPer) / double(total);
        double x2 = (buffer.curPeriod - buffer.curEffStartPer + 1.0) / double(total);
        int idx = (buffer.curPeriod - buffer.curEffStartPer) * 8;
        buffer.SetDisplayListVRect(effect, idx, x1, 0.0, x2, 0.5,
                                   xlBLACK, orig);
        buffer.SetDisplayListVRect(effect, idx + 4, x1, 0.5, x2, 1.0,
                                   orig, xlBLACK);
    } else {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4);
        int midX = (startX + endX) / 2;
        int midY = (startY + endY) / 2;
        buffer.CopyPixelsToDisplayListX(effect, midY, midX, midX);
    }

}
Exemple #21
0
void TreeEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int Branches = SettingsMap.GetInt("SLIDER_Tree_Branches", 1);
    int tspeed = SettingsMap.GetInt("SLIDER_Tree_Speed", 10);
    
    int effectState = (buffer.curPeriod - buffer.curEffStartPer) * tspeed * buffer.frameTimeInMs / 50;
    
    int x,y,i,r,ColorIdx,pixels_per_branch;
    int maxFrame,mod,branch,row,b,f_mod,m,frame;
    int number_garlands,f_mod_odd,s_odd_row,odd_even;
    float V,H;
    
    number_garlands=1;
    xlColor color;
    if(Branches<1)  Branches=1;
    pixels_per_branch=(int)(0.5+buffer.BufferHt/Branches);
    if(pixels_per_branch<1) pixels_per_branch=1;
    
    maxFrame=(Branches+1) * buffer.BufferWi;
    if(effectState>0 && maxFrame>0) frame = (effectState/4)%maxFrame;
    else frame=1;
    
    i=0;
    
    for (y=0; y<buffer.BufferHt; y++) // For my 20x120 megatree, BufferHt=120
    {
        for (x=0; x<buffer.BufferWi; x++) // BufferWi=20 in the above example
        {
            if(pixels_per_branch>0) mod=y%pixels_per_branch;
            else mod=0;
            if(mod==0) mod=pixels_per_branch;
            V=1-(1.0*mod/pixels_per_branch)*0.70;
            i++;
            
            ColorIdx=0;
            buffer.palette.GetColor(ColorIdx, color); // Now go and get the hsv value for this ColorIdx
            if (buffer.allowAlpha) {
                color.alpha = 255.0 * V;
            } else {
                HSVValue hsv = color.asHSV();
                hsv.value = V; // we have now set the color for the background tree
                color = hsv;
            }
            
            //   $orig_rgbval=$rgb_val;
            branch = (int)((y-1)/pixels_per_branch);
            row = pixels_per_branch-mod; // now row=0 is bottom of branch, row=1 is one above bottom
            //  mod = which pixel we are in the branch
            //	mod=1,row=pixels_per_branch-1   top picrl in branch
            //	mod=2, second pixel down into branch
            //	mod=pixels_per_branch,row=0  last pixel in branch
            //
            //	row = 0, the $p is in the bottom row of tree
            //	row =1, the $p is in second row from bottom
            b = (int) ((effectState)/buffer.BufferWi)%Branches; // what branch we are on based on frame #
            //
            //	b = 0, we are on bottomow row of tree during frames 1 to BufferWi
            //	b = 1, we are on second row from bottom, frames = BufferWi+1 to 2*BufferWi
            //	b = 2, we are on third row from bottome, frames - 2*BufferWi+1 to 3*BufferWi
            f_mod = (effectState/4)%buffer.BufferWi;
            //   if(f_mod==0) f_mod=BufferWi;
            //	f_mod is  to BufferWi-1 on each row
            //	f_mod == 0, left strand of this row
            //	f_mod==BufferWi, right strand of this row
            //
            m=(x%6);
            if(m==0) m=6;  // use $m to indicate where we are in horizontal pattern
            // m=1, 1sr strand
            // m=2, 2nd strand
            // m=6, last strand in 6 strand pattern
            
            
            
            r=branch%5;
            H = r/4.0;
            
            odd_even=b%2;
            s_odd_row = buffer.BufferWi-x+1;
            f_mod_odd = buffer.BufferWi-f_mod+1;
            
            if(branch<=b && x<=frame && // for branches below or equal to current row
               (((row==3 || (number_garlands==2 && row==6)) && (m==1 || m==6))
                ||
                ((row==2 || (number_garlands==2 && row==5)) && (m==2 || m==5))
                ||
                ((row==1 || (number_garlands==2 && row==4)) && (m==3 || m==4))
                ))
                if((odd_even ==0 && x<=f_mod) || (odd_even ==1 && s_odd_row<=f_mod))
                {
                    HSVValue hsv;
                    hsv.hue = H;
                    hsv.saturation=1.0;
                    hsv.value=1.0;
                    color = hsv;
                }
            //	if(branch>b)
            //	{
            //		return $rgb_val; // for branches below current, dont dont balnk anything out
            //	}
            //	else if(branch==b)
            //	{
            //		if(odd_even ==0 && x>f_mod)
            //		{
            //			$rgb_val=$orig_rgbval;// we are even row ,counting from bottom as zero
            //		}
            //		if(odd_even ==1 && s_odd_row>f_mod)
            //		{
            //			$rgb_val=$orig_rgbval;// we are even row ,counting from bottom as zero
            //		}
            //	}
            //if($branch>$b) $rgb_val=$orig_rgbval; // erase rows above our current row.
            
            
            // Yes, so now decide on what color it should be
            
            
            //  we left the Hue and Saturation alone, we are just modifiying the Brightness Value
            buffer.SetPixel(x,y,color); // Turn pixel on
            
        }
    }
}
Exemple #22
0
void VideoEffect::Render(RenderBuffer &buffer, const std::string& filename,
	double starttime, bool aspectratio, std::string durationTreatment)
{
	VideoRenderCache *cache = (VideoRenderCache*)buffer.infoCache[id];
	if (cache == nullptr) {
		cache = new VideoRenderCache();
		buffer.infoCache[id] = cache;
	}

	std::string &_filename = cache->_filename;
	int &_starttime = cache->_starttime;
	bool &_aspectratio = cache->_aspectratio;
	std::string &_durationTreatment = cache->_durationTreatment;
	int &_loops = cache->_loops;
    int &_frameMS = cache->_frameMS;
	VideoReader* &_videoreader = cache->_videoreader;

	if (_starttime != starttime)
	{
		_starttime = starttime;
	}
    
	// we always reopen video on first frame or if it is not open or if the filename has changed
	if (buffer.needToInit)
	{
        buffer.needToInit = false;
		_filename = filename;
		_aspectratio = aspectratio;
		_durationTreatment = durationTreatment;
		_loops = 0;
        _frameMS = buffer.frameTimeInMs;
		if (_videoreader != NULL)
		{
			delete _videoreader;
			_videoreader = NULL;
		}

        if (buffer.BufferHt == 1)
        {
            log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
            logger_base.warn("VideoEffect::Cannot render video onto a 1 pixel high model. Have you set it to single line?");
        }
        else if (wxFileExists(_filename))
		{
			// have to open the file
			_videoreader = new VideoReader(_filename, buffer.BufferWi, buffer.BufferHt, _aspectratio);

            if (_videoreader == NULL)
            {
                log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
                logger_base.warn("VideoEffect: Failed to load video file %s.", (const char *)_filename.c_str());
            }
            else
            {
                // extract the video length
                int videolen = _videoreader->GetLengthMS();

                VideoPanel *fp = (VideoPanel*)panel;
                if (fp != nullptr)
                {
                    fp->addVideoTime(filename, videolen);
                }

                if (_starttime != 0)
                {
                    _videoreader->Seek(_starttime * 1000);
                }

                if (_durationTreatment == "Slow/Accelerate")
                {
                    int effectFrames = buffer.curEffEndPer - buffer.curEffStartPer + 1;
                    int videoFrames = (videolen - _starttime) / buffer.frameTimeInMs;
                    float speedFactor = (float)videoFrames / (float)effectFrames;
                    _frameMS = (int)((float)buffer.frameTimeInMs * speedFactor);
                }
            }
		}
        else
        {
            log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
            logger_base.warn("VideoEffect: Video file %s not found.", (const char *)_filename.c_str());
        }
	}

	if (_videoreader != NULL)
	{
		// get the image for the current frame
		AVFrame* image = _videoreader->GetNextFrame(_starttime * 1000 + (buffer.curPeriod - buffer.curEffStartPer) * _frameMS - _loops * _videoreader->GetLengthMS());
		
		// if we have reached the end and we are to loop
		if (_videoreader->AtEnd() && _durationTreatment == "Loop")
		{
			_loops++;
			// jump back to start and try to read frame again
			_videoreader->Seek(0);
			image = _videoreader->GetNextFrame(_starttime * 1000 + (buffer.curPeriod - buffer.curEffStartPer) * _frameMS - _loops * _videoreader->GetLengthMS());
		}

		int startx = (buffer.BufferWi - _videoreader->GetWidth()) / 2;
		int starty = (buffer.BufferHt - _videoreader->GetHeight()) / 2;

		// check it looks valid
		if (image != NULL)
		{
			// draw the image
			xlColor c;
			for (int y = 0; y < _videoreader->GetHeight(); y++)
			{
				for (int x = 0; x < _videoreader->GetWidth(); x++)
				{
					try
					{
						c.Set(*(image->data[0] + (_videoreader->GetHeight() - 1 - y) * _videoreader->GetWidth() * 3 + x * 3),
							  *(image->data[0] + (_videoreader->GetHeight() - 1 - y) * _videoreader->GetWidth() * 3 + x * 3 + 1),
							  *(image->data[0] + (_videoreader->GetHeight() - 1 - y) * _videoreader->GetWidth() * 3 + x * 3 + 2), 255);
					}
					catch (...)
					{
						// this shouldnt happen so make it stand out
						c = xlRED;
					}
					buffer.SetPixel(x + startx, y+starty, c);
				}
			}
		}
		else
		{
			// display a blue background to show we have gone past end of video
			for (int y = 0; y < buffer.BufferHt; y++)
			{
				for (int x = 0; x < buffer.BufferWi; x++)
				{
					buffer.SetPixel(x, y, xlBLUE);
				}
			}
		}
	}
    else
    {
        // display a red background to show we have a problem
        for (int y = 0; y < buffer.BufferHt; y++)
        {
            for (int x = 0; x < buffer.BufferWi; x++)
            {
                buffer.SetPixel(x, y, xlRED);
            }
        }
    }
}