0

I currently am trying to code a small game which involves moving a dot around a maze. Rather than building the maze with rectangles, I decided to simply create a PNG image of the maze and load it as a surface and I also got the dot to move around the screen as well.

Now, I have been trying to make sure that the dot (which is more like a small box) to stay on a certain color and prevent it from moving into the walls. I am trying to read the pixel ahead of the movement and see whether it's black (a wall) or it's white (empty space). I have noticed the function SDL_RenderReadPixels, however I can't seem to make it work:

        int w, h, access;
        void* pixels;
        Uint32 format;
        const char* s; 

        SDL_QueryTexture(map->texture, &format, &access, &w, &h);
        // Access = 0; width = 900; height = 720
        s = SDL_GetPixelFormatName(format);
        // Format: ARGB8888
        SDL_Log("%s", s);

        // Now I got pitch as: 900 * 32 = 28800
        w = SDL_RenderReadPixels(map->renderer, NULL, 0, pixels, 28800);

I keep getting a segmentation fault. Now, I am not entirely sure if this would be the easiest method to achieve what I am trying to do. I can't seem to find an easier function within the SDL2 library that accomplishes this either, and I haven't found a solution searching around.

  1. Is there a reason why this is causing seg faults?
  2. Is there an easier and more efficient way for me to achieve this in SDL2?

I would like some feedback on my approach. I am still a beginner. The code is in C.

Thanks,

2
  • Edit in a minimal reproducible example. Commented Dec 22, 2017 at 3:46
  • 3
    If you're just rendering a PNG texture for the background, I think far better if you're going to check for collision on the CPU is just keep a copy of the image on the CPU instead of stalling the pipeline with glReadPixels. Commented Dec 22, 2017 at 4:31

1 Answer 1

4

SDL_RenderReadPixels saves result to fourth argument (pixels), which is uninitialised. SDL then writes pixels "somewhere", which luckly causes segmentation fault. You have to provide space for resulting pixels (static buffer, stack buffer, malloc, anything).

Also note this operation is quite slow.

Sign up to request clarification or add additional context in comments.

3 Comments

You are absolutely right to point the issue with pixels, I just tried replacing pixels with NULL and there is no segmentation fault. However, even when I try to allocate space by : pixels = (void *)malloc(30000); --- Still getting seg. fault. Not sure how else to allocate this, I have tried several variations.
Your pitch looks incorrect (should be width*bytes_per_pixel+padding, and I highly doubt RGBA8 is 32 bytes per pixel - should be 4), and 30000 is too little - you requested entire texture, so you need at least pitch*height bytes (e.g. 2592000 in my half-minded calculations).
Just as a comment on the call to malloc(): You shouldn't need to cast. Even when you're allocating say an int * you don't need to cast but malloc() returns a void * so there's no need to cast at all. Maybe not relevant here but something to keep in mind. With C++ I believe you have to use cast but then they say you ought to use new all the time in C++ anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.