3

When I generate a gradient using the following code it produces a strange crack like gradient near the center of the image.

The generation code:

void getRgb(GLfloat* pixels1,GLubyte* out)//convert fractional values into color
{
  for (int i = 0;i < 90*90;i++)
  {
    out[(i*3)+0] = pixels1[i]*255;
    out[(i*3)+1] = pixels1[i]*255;
    out[(i*3)+2] = pixels1[i]*255;
  }
}

//gradient generation
multiplier = new GLfloat[90*90];// calc multiplier map

for(int i = 0;i < 90;i++)//2d to 1d
{
  for (int j = 0;j < 90;j++)
  multiplier[i*90 + j] = cos((j)*(3.14/180));
}



SDL_Surface * image = SDL_CreateRGBSurface(SDL_SWSURFACE, 89, 89, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
GLubyte* save = new GLubyte[90*90*3];
getRgb(multiplier,save);
image->pixels = save;


std::string path = "map.bmp";
SDL_SaveBMP(image, path.c_str());
delete save;
image->pixels = NULL;
SDL_FreeSurface(image);

The resulting artifact.

qxz
  • 3,814
  • 1
  • 14
  • 29
J. H
  • 96
  • 8
  • You could reduce round-off errors on the cosine, which is possibly related to your problem since you maybe be getting cosine values < 0, by using the double precision value of pi already in the C++ libraries. See http://stackoverflow.com/questions/1727881/how-to-use-the-pi-constant-in-c – Brick Aug 31 '16 at 03:24
  • I just tried that and it produced the same image. – J. H Aug 31 '16 at 03:31

3 Answers3

2

That's because you're getting negative values from the cosine. Those are not playing well with the unsigned integer pixel values, which should be in the range [0, 255].

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
1

The problem is that you've created a 89x89 image and you're filling it with a 90x90 array. At the end of every line there's a mismatch, and since each pixel is an odd number of bytes it shifts the next line off by a byte. Most of your pixels are nearly gray so you don't see the discrepancy, but it shows up at the transition between light and dark.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • When I changed the image size to 90x90, it produced the same image but fliped and with extra colors at the bottom of the screen. – J. H Aug 31 '16 at 03:43
  • @J.H "extra colors at the bottom of the screen" makes it sound like uninitialized data or buffer overrun. Maybe `image->pixels` has 4 byte pixels even when you tell it to use a depth of 24 bits? – Mark Ransom Aug 31 '16 at 04:07
1

Ok, it can be fixed by replacing:

SDL_Surface * image = SDL_CreateRGBSurface(SDL_SWSURFACE, 89, 89, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
GLubyte* save = new GLubyte[90*90*3];
getRgb(multiplier,save);
image->pixels = save;

with:

   GLubyte* save = new GLubyte[90*90*3];
   getRgb(multiplier,save);
   SDL_Surface* image =  SDL_CreateRGBSurfaceFrom(save,
                                      90,
                                      90,
                                      24,
                                      90*3,
                                      0x000000FF, 0x0000FF00, 0x00FF0000, 0);
J. H
  • 96
  • 8