Why would you Lock the Texture if you want to modefy the Surface pixeldata? Perhaps you wanted to change the texture and i hope i can help you with that:
So sdl2.SDL_LockTexture doesn't work as you would expect. It locks the texture but the last two arguments are for returning the pitch and pixeldata of the texture. Which is weird. You would usually expect the function to look like this:
pixels, pitch = sdl2.SDL_LockTexture(texture, None)
So insead of surface.contents.pixels and surface.contents.pitch, you should pass empty variables, which should be assign as ctype variables. Example:
pixels = ctypes.c_void_p()
pitch = ctypes.c_int()
sdl2.SDL_LockTexture(texture, None, ctypes.byref(pixels), ctypes.byref(pitch))
So after SDL_LockTexture you got the pixeldata and the pitch in these variables.
And if we change the pixels, the texture automaticaly saves the changes when Unlocking the texture.
However the pixels are in are not in the right format. So in order to change it we have to convert it:
actual_pixels = ctypes.cast(pixels, ctypes.POINTER(ctypes.c_ubyte * (pitch.value * size[1]))).contents
Now we have something we can work with.
Note that actual_pixels is now a one dimensional array and to change it you use this:
for x in range(0, size[0] * 4, 4):
for y in range(0, size[1]):
actual_pixels[x + (y * pitch.value) ] = 255 # Red
actual_pixels[x + (y * pitch.value) + 1] = 255 # Green
actual_pixels[x + (y * pitch.value) + 2] = 255 # Blue
actual_pixels[x + (y * pitch.value) + 3] = 255 # Alpha
You then can just unlock the texture and it saves it.
If texture displays something diffrent from what you want, you might change PIXELFORMAT( i have sdl2.SDL_PIXELFORMAT_RGBA32) of the texture or if alpha is not working use sdl2.SDL_SetTextureBlendMode(texture, sdl2.SDL_BLENDMODE_BLEND).
Your funtion would look something like this:
def run():
sdl2.ext.init()
window = SDL_CreateWindow(b"test", sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED, 1024, 768, sdl2.SDL_WINDOW_SHOWN)
renderer = SDL_CreateRenderer(window, -1, sdl2.SDL_RENDERER_ACCELERATED)
size = (100, 100)
texture = SDL_CreateTexture(renderer, sdl2.SDL_PIXELFORMAT_RGB888, sdl2.SDL_TEXTUREACCESS_STREAMING, size[0], size[1])
#surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000)
running = True
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT or event.type == sdl2.SDL_MOUSEBUTTONDOWN:
running = False
break
pixels = ctypes.c_void_p()
pitch = ctypes.c_int()
sdl2.SDL_LockTexture(texture, None, ctypes.byref(pixels), ctypes.byref(pitch))
actual_pixels = ctypes.cast(pixels, ctypes.POINTER(ctypes.c_ubyte * (pitch.value * size[1]))).contents
for x in range(0, size[0] * 4, 4):
for y in range(0, size[1]):
actual_pixels[x + (y * pitch.value) ] = randint(0,255) # Red
actual_pixels[x + (y * pitch.value) + 1] = randint(0,255) # Green
actual_pixels[x + (y * pitch.value) + 2] = randint(0,255) # Blue
actual_pixels[x + (y * pitch.value) + 3] = randint(0,255) # Alpha
sdl2.SDL_UnlockTexture(texture)
sdl2.SDL_RenderCopy(
renderer,
texture,
sdl2.SDL_Rect(
0,
0,
size[0],
size[1]
),
sdl2.SDL_Rect(
0,
0,
size[0],
size[1]
))
sdl2.SDL_RenderPresent(renderer)
This is just an example but you can modefy the pixels in any way.
Important to note that that it is not recommended to use such function in every frame and the bigger the image, the more performance it needs. In my example i have an Texture with a size of 100, 100 which works fast enought.
If you however wanted to change the surface then there is no reason to do it. Textures are just much faster.