0
\$\begingroup\$

So basically what i want to do is create a 2D tile based rendering system in C++ that renders each pixel on the screen manually. Rendering an individual pixel on the screen works just fine (or render the whole screen blue for example). But i want to load the individual pixel colours of my sprites out of a spritesheet image and heres my problem:

I am able to create the image and access the pixels of the image, however the individual pixel values seem to be wrong. (I compared the pixel values with the supposed hexadecimals on paint.net)

Heres my code for the spritesheet:

    SpriteSheet::SpriteSheet(std::string path, int tileWidth, int tileHeight)
    :
    path(path),
    tileWidth(tileWidth),
    tileHeight(tileHeight)
{
    image = IMG_Load(path.c_str());

    if (image != NULL){
        width = image->w;
        height = image->h;
        pixels = (Uint32 *) image->pixels;
        std::cout <<std::hex <<  pixels[17] << std::dec << std::endl;

        //this prints out: 3030303 when it should be FF007F46

    } 
    else{
        std::cout << "SpriteSheet couldnt be loaded!" << std::endl;
    }
}

Note that the pixel format is: AARRGGBB

Edit: I tried using a ".jpg" instead of a ".png" and i got different colour values again, but still not the right ones.

Edit2: I'm pretty sure the pixel format in which my image is getting loaded in is wrong. Any ideas how to get it to ARGB8888? I tried using SDL_ConvertSurface and SDL_ConvertSurfaceFormatbut i can't seem to get it right.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Don't assume the pixel format that IMG_Load gives you. Check its value; chances are it isn't ARGB8888 like you expected.

Instead, if you want that pixel format specifically, then use SDL_ConvertSurface on the loaded surface. Pass in your spritesheet surface's pixel format to guarantee that the two match.

\$\endgroup\$
1
  • \$\begingroup\$ Yeah, I'm trying to change the pixel format right now, but i can't seem to figure out what to pass in as a second parameter SDL_PIXELFORMAT_ARGB8888 isn't accepted. And do I have to change the format before the image is loaded into the surface or afterwards? I'm assuming before. \$\endgroup\$ Commented Feb 3, 2015 at 23:40
0
\$\begingroup\$

I'm doing it using the following code:

BufferRef LoadImage(std::string filename, bool &success)
{
 SDL_Surface *surf = IMG_Load(filename.c_str());
 if (!surf) 
  {
    success = false;
    std::cout << "Cannot load " << filename << std::endl;
    BufferRef r;
    return r;
  }
SDL_PixelFormat format;
format.palette = 0;
format.BitsPerPixel = 32;
format.BytesPerPixel = 4;
format.Rloss = 0;
format.Gloss = 0;
format.Bloss = 0;
format.Aloss = 0;
format.Rshift = 24;
format.Gshift = 16;
format.Bshift = 8;
format.Ashift = 0;
format.Rmask = 0x00ff0000;
format.Gmask = 0x0000ff00;
format.Bmask = 0x000000ff;
format.Amask = 0xff000000;

SDL_Surface *surf2 = SDL_ConvertSurface(surf, &format, 0);
BufferRef ref = CopyFromSDLSurface(surf2);
SDL_FreeSurface(surf);  
success = true;
return ref;
}
BufferRef CopyFromSDLSurface(SDL_Surface *surf)
{
BufferRef buf = BufferRef::NewBuffer(surf->w, surf->h);
SDL_LockSurface(surf);
for(int y=0;y<surf->h;y++)
  for(int x=0;x<surf->w;x++)
    {
    Uint32 *ptr = (Uint32*)surf->pixels;
    int color = ptr[(surf->format->BytesPerPixel*x+y*surf->pitch)/sizeof(Uint32)];
    buf.buffer[x+buf.ydelta*y] = color;
    }
 SDL_UnlockSurface(surf);
 return buf;
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .