void VideoEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { Render(buffer, SettingsMap["FILEPICKERCTRL_Video_Filename"], SettingsMap.GetDouble("TEXTCTRL_Video_Starttime", 0.0), SettingsMap.GetBool("CHECKBOX_Video_AspectRatio", false), SettingsMap.Get("CHOICE_Video_DurationTreatment", "Normal") ); }
void PixelBufferClass::SetLayerSettings(int layer, const SettingsMap &settingsMap) { LayerInfo *inf = layers[layer]; inf->persistent = settingsMap.GetBool(CHECKBOX_OverlayBkg); inf->mask.clear(); inf->fadeInSteps = (int)(settingsMap.GetDouble(TEXTCTRL_Fadein, 0.0)*1000)/frameTimeInMs; inf->fadeOutSteps = (int)(settingsMap.GetDouble(TEXTCTRL_Fadeout, 0.0)*1000)/frameTimeInMs; inf->inTransitionType = settingsMap.Get(CHOICE_In_Transition_Type, STR_FADE); inf->outTransitionType = settingsMap.Get(CHOICE_Out_Transition_Type, STR_FADE); inf->inTransitionAdjust = settingsMap.GetInt(SLIDER_In_Transition_Adjust, 0); inf->outTransitionAdjust = settingsMap.GetInt(SLIDER_Out_Transition_Adjust, 0); inf->inTransitionReverse = settingsMap.GetBool(CHECKBOX_In_Transition_Reverse); inf->outTransitionReverse = settingsMap.GetBool(CHECKBOX_Out_Transition_Reverse); inf->blur = settingsMap.GetInt(SLIDER_EffectBlur, 1); inf->sparkle_count = settingsMap.GetInt(SLIDER_SparkleFrequency, 0); inf->RotoZoom = settingsMap.GetInt(CHECKBOX_RotoZoom, 0) ; inf->ZoomCycles = settingsMap.GetInt(SLIDER_ZoomCycles, 1); inf->ZoomRotation = settingsMap.GetInt(SLIDER_ZoomRotation, 0); inf->ZoomInOut = settingsMap.GetInt(SLIDER_ZoomInOut, 0); inf->brightness = settingsMap.GetInt(SLIDER_Brightness, 100); inf->contrast=settingsMap.GetInt(SLIDER_Contrast, 0); SetMixType(layer, settingsMap.Get(CHOICE_LayerMethod, STR_NORMAL)); inf->effectMixThreshold = (float)settingsMap.GetInt(SLIDER_EffectLayerMix, 0)/100.0; inf->effectMixVaries = settingsMap.GetBool(CHECKBOX_LayerMorph); const std::string &type = settingsMap.Get(CHOICE_BufferStyle, STR_DEFAULT); const std::string &transform = settingsMap.Get(CHOICE_BufferTransform, STR_NONE); if (inf->bufferType != type || inf->bufferTransform != transform) { inf->Nodes.clear(); model->InitRenderBufferNodes(type, transform, inf->Nodes, inf->BufferWi, inf->BufferHt); inf->bufferType = type; inf->bufferTransform = transform; inf->buffer.InitBuffer(inf->BufferHt, inf->BufferWi); } }
double RenderableEffect::GetValueCurveDouble(wxString name, double def, const SettingsMap &SettingsMap, float offset) { double res = SettingsMap.GetDouble("TEXTCTRL_" + name, def); wxString vc = SettingsMap.Get("VALUECURVE_" + name, ""); if (vc != "") { ValueCurve valc(vc.ToStdString()); if (valc.IsActive()) { res = valc.GetOutputValueAt(offset); } } return res; }
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); } } } } }
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); } }
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; } }
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); } } } }