SDL 2.0 - Edit Renderer Pixels

Started by
6 comments, last by Tolito 10 years, 2 months ago

When I was storing the screen as an SDL_Surface, I could multiply colors to it like so:


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

    unsigned int x, y;

    for(y=0;y<screen->h;y++) {

        for(x=0;x<screen->w;x++) {

            // Code to edit each pixel here.

        }

    }

I am migrating my code to work with SDL_Textures again, which requires using an SDL_Renderer. I am familiar with using SDL_RenderCopy and all of those functions, but I'm not sure how to go about editing the individual pixels rendered to an SDL_Renderer, and this is necessary. Does anyone have any suggestions on how to do this? Thanks!

Advertisement

You could keep a copy of the texture in an SDL_Surface, modify the surface as you used to, then SDL_UpdateTexture to get the pixels into the final texture. You should create the texture with SDL_TEXTUREACCESS_STREAMING to tell SDL that you plan on updating the texture frequently.

Thanks for the reply! Actually, I am using SDL_RenderCopy to copy textures to the screen, which is of type SDL_Renderer. Instead of updating every texture each frame, I want to edit the pixels of the renderer itself, basically the final version of the screen. I am trying to avoid using an SDL_Surface since this will be calculated each frame and I want to do all of this in the GPU. Creating a surface that is a copy of the renderer, multiplying the colors there, converting the surface to a texture, and using SDL_RenderCopy again to put the edited colors back on the renderer would work, but it seems like there is a more efficient way of doing that. Is there a way to access and edit the pixels of an SDL_Renderer itself? Thanks again!

The only way to do this all on the GPU would be to use the OpenGL renderer and do the post-processing in a shader.

There's no way to get at the pixels of the current frame outside of a shader. All the details of what a frame looks like are hidden behind the abstract SDL_Renderer. It could be a pixel buffer for software rendering, or a set of VBOs, etc., which would mean there is no pixel representation of the final image until it's actually flushed to the GPU.

Thanks again! Since no pixel representation can be found, it sounds like my idea of storing said pixels as an SDL_Surface after they have been copied to the renderer is not a possibility. The only efficient possibility for doing this may be copying the to-be-blitted region of each texture, multiplying to the copy, rendering the copy to the SDL_Renderer, and destroying the copy. Doing this effectively is all over my head, though. Should I keep using SDL_Surfaces for everything and do the multiplication and rendering there, then storing as a texture and rendering that to the renderer at whatever scale?

Update:

For my new multiplication function, I simply did this:

    SDL_Rect r={0,0,XRES,YRES};
    SDL_SetRenderDrawBlendMode(screen,SDL_BLENDMODE_MOD);
    FillRect(screen,&r,color);
This multiplies the new color to the screen without the need for accessing and editing the screen pixels, multiplying to them one by one. Since this is why I was needing to access the renderer pixels, this is no longer a problem.

Excellent solution. That will keep all the work on the GPU. I didn't realize you were multiplying all pixels by the same value, or I might have thought to suggest something like that.

Glad you got it sorted!

Thanks! Hopefully others with this question will come across this post!

This topic is closed to new replies.

Advertisement