1
\$\begingroup\$

I added code to check the rgb values of my surface, and whenever i call the function it seems to work fine! the only problem is that whenever the mouse goes under y = 400 the entire window crashes... Right now the program outputs the rgb color of the pixel on the screen, and when it goes below 400 one or all of the pixel values are 0, and then the program crashes. I have no ideas why this is happening. Any help is appreciated! Heres the github repo! https://github.com/jcsq6/SDLGame not much has been done except a couple classes to make my life easier in SDL :)

int* texture::getPixel(int x, int y){
    static int Color[4];
    SDL_PixelFormat *fmt;
    Uint32 temp, pixel;
    Uint32 *pixels = (Uint32 *)Surface->pixels;
    Uint8 red, green, blue, alpha;

    fmt = Surface->format;
    SDL_LockSurface(Surface);
    pixel = pixels[(y * Surface->w) + x];
    SDL_UnlockSurface(Surface);

    temp = pixel & fmt->Rmask;  
    temp = temp >> fmt->Rshift;
    temp = temp << fmt->Rloss;
    red = (Uint8)temp;

    temp = pixel & fmt->Gmask; 
    temp = temp >> fmt->Gshift;
    temp = temp << fmt->Gloss;
    green = (Uint8)temp;

    temp = pixel & fmt->Bmask; 
    temp = temp >> fmt->Bshift; 
    temp = temp << fmt->Bloss; 
    blue = (Uint8)temp;

    temp = pixel & fmt->Amask;
    temp = temp >> fmt->Ashift;
    temp = temp << fmt->Aloss; 
    alpha = (Uint8)temp;

    Color[0] = red;
    Color[1] = green;
    Color[2] = blue;
    Color[3] = alpha;

    return Color;

}

it's worth noting that when I call this function, the input y and x values are the mouse's position.

\$\endgroup\$
12
  • \$\begingroup\$ Are you sure that surface->format->BytesPerPixel == 4? \$\endgroup\$ – JohnFilleau Mar 18 '20 at 2:09
  • \$\begingroup\$ i checked, and i think the bits per pixel was 24, so no that'd make the bytes = 3, why is that important? \$\endgroup\$ – Jcsq6 Mar 18 '20 at 2:11
  • \$\begingroup\$ Use BytesPerPixel I think, and use that to inform what you need to cast the Surface->pixels to. \$\endgroup\$ – JohnFilleau Mar 18 '20 at 2:13
  • \$\begingroup\$ If you only have 24 bits per pixel, you may not have an alpha value. Check what Amask is. If it's 0, that makes sense. You only have RGB. \$\endgroup\$ – JohnFilleau Mar 18 '20 at 2:15
  • \$\begingroup\$ why would that be causing a crash? \$\endgroup\$ – Jcsq6 Mar 18 '20 at 2:16
0
\$\begingroup\$

According to the SDL Documentation, your casting of

Uint32 *pixels = (Uint32 *)Surface->pixels;

only works if your surface->format->BytesPerPixel == 4. Your BytesPerPixel appears to be 3. Another clue as to it being only 3 bytes is that your aMask == 0.

Your pixel array is only 3*N bytes wide, where N is the number of pixels. Since you're casting to a Uint32*, any accesses into the array assume that each pixel is 4 bytes wide, and you'll access elements between [pixels, pixels + 4*N). Your actual array only takes up space between [pixels, pixels + 3*N).

According to the SDL Doc linked above, your bytes should therefore be accessed as 3-tuples of Uint8. Change your code like this:

int* texture::getPixel(int x, int y){
    static int Color[4];
    Uint8 *pixels = (Uint8 *)Surface->pixels;
    Uint8 red, green, blue;

    SDL_LockSurface(Surface);
    red   = pixels[(y * Surface->w) + x    ];
    green = pixels[(y * Surface->w) + x + 1];
    blue  = pixels[(y * Surface->w) + x + 2];
    SDL_UnlockSurface(Surface);

    // since each R, G, B value takes up a full Uint8, I'm not
    // sure if you need to mask, downshift, then upshift the values
    // at all.

    // setting opacity to 0xff, for full-opacity

    Color[0] = red;
    Color[1] = green;
    Color[2] = blue;
    Color[3] = 0xff;

    return Color;
}

Let me know how this works. I don't have any experience with SDL, so this may need adjustment.

Your use of a static array to return the colors is suspect, but I kept that to mimic your code. It's also strange to stick color values: Uint8s, into an array of ints, but I kept that as well to match your code. I didn't know what you were using this array for, and wanted to change as little as possible.

\$\endgroup\$
10
  • \$\begingroup\$ This works perfectly, thanks for your help! \$\endgroup\$ – Jcsq6 Mar 18 '20 at 2:38
  • \$\begingroup\$ Good to know. I'm curious what values your R/G/BMask/Shift/Loss have, if any. \$\endgroup\$ – JohnFilleau Mar 18 '20 at 2:38
  • \$\begingroup\$ Yeah that'd be interresting. idk \$\endgroup\$ – Jcsq6 Mar 18 '20 at 2:39
  • \$\begingroup\$ Well I mean you can inspect them in your debugger or output them Surface->format->Rmask; etc \$\endgroup\$ – JohnFilleau Mar 18 '20 at 2:42
  • 1
    \$\begingroup\$ you are correct they have no value \$\endgroup\$ – Jcsq6 Mar 18 '20 at 3:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.