smeighan
Dedicated elf
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 Spirograph
void 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!
thanks
sean
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 Spirograph
void 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!
thanks
sean