Hello everyone,
can someone point me to a good and fast routine for getting and setting pixel either in a surface or texture?
Something like GetPixel(surface, x,y, colorRGBA) and SetPixel(surface, x,y,colorRGBA).
I tried many functions and tutorials with few results
Thank you very much
Kind regards
For a texture it depends on its access type. If it’s SDL_TEXTUREACCESS_TARGET
you can make the texture the target of a renderer (SDL_SetRenderTarget
) then set a pixel using SDL_RenderDrawPoint()
and read a pixel using SDL_RenderReadPixels()
with a one-pixel-square rectangle. Reading a texture won’t be fast though.
1 Like
Thank you very much.
Is there any example code around?
I have this code that is working and it’s quite fast.
The problem is that i can’t create a getPixel(x,y,color) putPixel(x,y,color) routine out of this.
How to calculate x and y in the pixels and pixelCount?
//Lock texture
if( !gFooTexture.lockTexture() ) {
printf( "Unable to lock Foo' texture!\n" );
} else {
//Manual color key
//Allocate format from window
Uint32 format = SDL_GetWindowPixelFormat( gWindow );
SDL_PixelFormat* mappingFormat = SDL_AllocFormat( format );
//Get pixel data
Uint32* pixels = (Uint32*)gFooTexture.getPixels();
int pixelCount = ( gFooTexture.getPitch() / 4 ) * gFooTexture.getHeight();
//Map colors
Uint32 colorKey = SDL_MapRGB( mappingFormat, 0, 0x00, 0x00 );
Uint32 vertexPoint = SDL_MapRGB( mappingFormat, 255, 0, 0);
Uint32 transparent = SDL_MapRGBA( mappingFormat, 0xFF, 0xFF, 0xFF, 0x00 );
bool newTransp = false;
//Color key pixels
for( int i = 0; i < pixelCount; ++i ) {
if( pixels[ i ] == colorKey ) {
pixels[ i ] = transparent;
newTransp = true;
} else {
if (newTransp==true) {
pixels[ i-1 ] = vertexPoint;
newTransp=false;
}
}
}
//Unlock texture
gFooTexture.unlockTexture();
//Free format
SDL_FreeFormat( mappingFormat );
Please note this comment at the docs for SDL_LockTexture()
: “As an optimization, the pixels made available for editing don’t necessarily contain the old texture data. This is a write-only operation”. So if you’re using it to implement GetPixel it’s not guaranteed to work.
I see, thank you.
Btw i need to getpixel(x,y,color) including alpha and then putpixel(x,y,color).
As i said this code works fast and i can read the the pixel and change the color with this line: pixels[ i-1 ] = vertexPoint;
I need to do this in a loop but having the x,y coordinates of the pixel
Like you said, you can change any pixel using pixels[i]
where the index i
is in the range [0, width * height).
This works because the pixels
array is essentially a 1-dimensional array with all the pixels sequentially from left to right, top to bottom.
If you want to be able to use x
and y
instead of i
, you simply to need to use x
and y
together to calculate the corresponding i
index.
Generally, this is: i = y * width + x
Or more specifically in this case, pixels[i]
could be replaced with:
pixels[y * (gFooTexture.getPitch() / 4) + x]
Let me know if I misunderstood your question.
Thank you very much Danny-E33.
The formula seems works quite well. I can get the setPixel function out of it. Don’t know if the speed will be good enough, but i will do some test.
Edit: i can set the pixel using the formula, but how do i get the pixel? I mean the pixel at x,y position and the color information (RGBA)?
Here how i managed to get the pixel values:
Uint8 r, g, b, a;
for (x=0; x<= gFooTexture.getWidth(); x++) {
SDL_GetRGBA(pixels[y * (gFooTexture.getPitch() / 4) + x], mappingFormat, &b, &g, &r, &a);
printf("i = %u, r = %u, g = %u, b = %u, a = %u\n", pixels[y * (gFooTexture.getPitch() / 4) + x], r, g, b, a);
}
Have to test for the correctness of the code, tho.
@rtrussell @Danny-E33
The code for putpixel works, while the other for getpixel seems not to correct.
I can try with SDL_GFX that offers function for pixelColor() to get a pixel and pixelRGBA to put a pixel on screen. Can’t find a pixecColorexample, tho.