1

I want to do smooth transitions between different colors(rather than just toggling it) by pressing the keyboard key 't'. Below is my code which toggles the colors at once but i want a smooth transitions of color:

case 't':
        // code for color transition
        changeColor += 1;
        if(changeColor>8) //Toggling between 9 different colors
            changeColor=0;
        break; 

Color storing code:

GLfloat diffColors[9][4] = { {0.3, 0.8, 0.9, 1.0},
                             {1, 0, 0, 1},
                             {0, 1, 0, 1},
                             {0, 0, 1, 1},
                             {0.5, 0.5, 0.9, 1},
                             {0.2, 0.5, 0.5, 1},
                             {0.5, 0.5, 0.9, 1},
                             {0.9, 0.5, 0.5, 1},
                             {0.3, 0.8, 0.5, 1} };


glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffColors[changeColor]);
  • If using float colors like `glColor3f(0.5f, 0.0f, 1.0f)`, then try incrementing in small steps like `changeColor += 0.05f;` – proton Apr 07 '21 at 20:52
  • You want (linear) interpolation between your `n` (8) known colors? or Gradients like these [spectral color](https://stackoverflow.com/a/22681410/2521214) , [BV index](https://stackoverflow.com/a/22630970/2521214) either computed or in form of texture? so which one you want? in what form you store your 8 colors (share code where you have the table or whatever so we can see the color format) – Spektre Apr 08 '21 at 08:39
  • @Spektre I have added the code in my question. – Mahnaz Rafia Islam Apr 08 '21 at 09:03
  • @MahnazRafiaIslam so you want to interpolate between the table entries? – Spektre Apr 08 '21 at 09:08

2 Answers2

1

Change the changeColor parameter to float and instead of increment by 1 add some small value like 0.1 or smaller depends on how quick you want to change the colors and how often your event is firing.

case 't':
        // code for color transition
        changeColor += 0.025;
        break; 

Use linear interpolation to compute the color based on parameter changeColor.

//---------------------------------------------------------------------------
GLfloat diffColors[9][4] =
    {
    {0.3, 0.8, 0.9, 1.0},
    {1.0, 0.0, 0.0, 1.0},
    {0.0, 1.0, 0.0, 1.0},
    {0.0, 0.0, 1.0, 1.0},
    {0.5, 0.5, 0.9, 1.0},
    {0.2, 0.5, 0.5, 1.0},
    {0.5, 0.5, 0.9, 1.0},
    {0.9, 0.5, 0.5, 1.0},
    {0.3, 0.8, 0.5, 1.0}
    };
GLfloat changeColor=0.0; // This must be float !!!
//---------------------------------------------------------------------------
void set_color()
    {
    int i;
    const int N=9;              // colors in your table
    const GLfloat n=N+1.0;      // colors in your table + 1
    float *c0,*c1,c[4],t;
    // bound the parameter
    t=changeColor;              // I renamed it so I do nto need to write too much)
    while (t>= n) t-=n;
    while (t<0.0) t+=n;
    i=floor(t);
    changeColor=t;              // update parameter
    t-=i;                       // leave just the decimal part
    // get neighboring colors to t
    c0=diffColors[i]; i++; if (i>=N) i=0;
    c1=diffColors[i];
    // interpolate
    for (i=0;i<4;i++) c[i]=c0[i]+((c1[i]-c0[i])*t);
    //glColor4fv(c);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, c);
    }
//---------------------------------------------------------------------------

so the idea is to dissect the changeColor to integer and fractional/decimal part. The integer part tells you between which 2 colors in your table you are and the fractional part <0..1> tells how far from the one color to the other one.

Linear interpolation of value x between 2 values x0,x1 and parameter t=<0..1> is like this:

x = x0 + (x1-x0)*t

If you look at the code above it does the same for c,c0,c1,t... In order this to get working the first chunk of code where you add to the parameter starting with case 't': must be executed repetitively like in timer ... and also invoke rendering. If it is just in some onkey handler that is called only once per key hit (no autorepeat) then it will not work and you need to implement the addition in some timer or on redraw event if you continuously redrawing screen... Again if not even that is happening you need to change the architecture of your app.

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

So this is how I solved it.

   case 't':
        // code for color transitioncol
           changeColor=8; //I am doing the color transition at 9th number color
            if(initialValue>=1.0)
                initialValue=0.1;
            initialValue+=0.01;
        break;

Color storing code:

GLfloat diffColors[9][4] = { {initialValue, 0.5, 0.9, 1.0},
                             {initialValue, 1.0, 0.0, 0.0},
                             {initialValue, 0.0, 1.0, 0.0},
                             {initialValue, 0.8, 0.5, 0.8},
                             {initialValue, 0.5, 0.5, 0.9},
                             {initialValue, 0.9, 0.9, 0.5},
                             {initialValue, 0.5, 0.7, 0.9},
                             {initialValue, 0.9, 0.5, 0.5},
                             {initialValue, 0.7, 0.3, 0.5}};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffColors[changeColor]);
  • dismiss my last comment ... I overlooked you shifted the color from { R,G,B,A} to { Initial value , R,G,A } having R channel as interpolated ... however not interpolating between neighbor colors in table ... – Spektre Apr 10 '21 at 11:42