smeighan Posted March 6, 2013 Posted March 6, 2013 Are you a C++ developer? If not, skip the rest of this post.Want to make a new cool effect for Nutcracker? I have written 3 tutorials to help you. Remember that I am not a C++ programmer, now a windows developer. I have learned enough to know how to add new effects to the Nutcracker code that Matt wrote. Part1: Setting up your machine to be able to build the xLights project file.You need just 3 parts to build xlights/nutcracker, Code::Blocks, mingw and wxWidgets.https://vimeo.com/61068045 Part2: Now that you can compile the current copy of xLights, we need to add our new effect into the wxWidgets gui. After this tutorial you should know how to add a pnale, a slider bar and stuff.https://vimeo.com/61068046 Part3: Now that we have added the gui stuff, lets actually modify the code to make an effect. We will use the spirograph effect as our straw man.https://vimeo.com/61153242 The source files can be downloaded from https://github.com/smeighan/nutcracker_c in the nutcracker/docs directory is a document, "How_To_Add_effects_To_Nutcracker.pdf". This is referenced in the 3rd tutorial. Check out the code, build a project, add an effect. Here are two examples of the C++ code that makes effects you have used. You will notice they are not that complicated. First the Twinkle effect void RgbEffects::RenderTwinkle(int Count){ int x,y,i,i7,r,ColorIdx; int lights = (BufferHt*BufferWi)*(Count/100.0); // Count is in range of 1-100 from slider bar int step=BufferHt*BufferWi/lights; if(step<1) step=1; srand(1); // always have the same random numbers for each frame (state) wxImage::HSVValue hsv; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); i=0; for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120 { for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example { i++; if(i%step==0) // Should we draw a light? { // Yes, so now decide on what color it should be ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx i7=(state/4+rand())%9; // Our twinkle is 9 steps. 4 ramping up, 5th at full brightness and then 4 more ramping down // Note that we are adding state to this calculation, this causes a different blink rate for each light if(i7==0 || i7==8) hsv.value = 0.1; if(i7==1 || i7==7) hsv.value = 0.3; if(i7==2 || i7==6) hsv.value = 0.5; if(i7==3 || i7==5) hsv.value = 0.7; if(i7==4 ) hsv.value = 1.0; // we left the Hue and Saturation alone, we are just modifiying the Brightness Value SetPixel(x,y,hsv); // Turn pixel on } } }} The second effect is Spirographvoid RgbEffects::RenderSpirograph(int int_R, int int_r, int int_d){#define PI 3.14159265 int i,x,y,k,xc,yc,ColorIdx; int mod1440,state360; srand(1); float R,r,d,d_orig,t; wxImage::HSVValue hsv,hsv0,hsv1; // we will define an hsv color model. The RGB colot model would have been "wxColour color;" size_t colorcnt=GetColorCount(); xc= (int)(BufferWi/2); // 20x100 flex strips with 2 fols per strip = 40x50 yc= (int)(BufferHt/2); R=xc*(int_R/100.0); // Radius of the large circle just fits in the width of model r=xc*(int_r/100.0); // start little circle at 1/4 of max width if(r>R) r=R; d=xc*(int_d/100.0); ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx palette.GetHSV(0, hsv0); palette.GetHSV(1, hsv1);//// A hypotrochoid is a roulette traced by a point attached to a circle of radius r rolling around the inside of a fixed circle of radius R, where the point is a distance d from the center of the interior circle.//The parametric equations for a hypotrochoid are:[citation needed]//// more info: http://en.wikipedia.org/wiki/Hypotrochoid////x(t) = (R-r) * cos t + d*cos ((R-r/r)*t);//y(t) = (R-r) * sin t + d*sin ((R-r/r)*t); mod1440=state%1440; state360 = state%360; d_orig=d; for(i=1; i<=360; i++) { d = (int)(d_orig+state/2)%100; t = (i+mod1440)*PI/180; x = (R-r) * cos (t) + d*cos ((R-r/r)*t) + xc; y = (R-r) * sin (t) + d*sin ((R-r/r)*t) + yc; if(i<=state360) SetPixel(x,y,hsv0); // Turn pixel on else SetPixel(x,y,hsv1); }}I would ask that you NOT check back your changes without contacting me first. So, go ahead, try out some effects! thankssean
Recommended Posts