Python+sdl2:list或bytearray到c_void_p

2024-06-06 00:46:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在用Python编写Gameboy模拟器。我想使用pysdl2进行图形输出

我有一个RGB值列表(每个像素3个值,因此列表是256x256x3)。这是背景,而不是实际屏幕将显示的内容

直接像素操作太慢,所以我考虑使用sdl2.SDL_UpdateTexture一次更新整个纹理。但是我无法将我的列表转换为必要的c_void_p-类型。 有没有一个简单的方法可以做到这一点?还是有更好的方法来实现足够的FPS?我不认为每秒更新60次图像会这么困难

举个简单的例子:

import sdl2


pic = [0xff] * 256*256*3

window = sdl2.SDL_CreateWindow(b"Gameboy Emulator", 256, 256, 256, 256, sdl2.SDL_WINDOW_SHOWN)
renderer = sdl2.SDL_CreateRenderer(window, -1, 0)
texture = sdl2.SDL_CreateTexture(renderer, sdl2.SDL_PIXELFORMAT_RGB888, sdl2.SDL_TEXTUREACCESS_STATIC, 256, 256)

我尝试了以下方法:

pic_as_string = "".join(map(chr, pic))
pointer = cast(c_char_p(pic_as_string), c_void_p)

sdl2.SDL_UpdateTexture(texture, None, pointer, 3*256)

如果相关的话,我现在正在使用pypy3


Tags: 方法列表stringas像素windowrenderersdl
1条回答
网友
1楼 · 发布于 2024-06-06 00:46:08

最好将帧缓冲区存储在bytearray()中,而不是列表中的整数,因为这样它会自动成为一个可写的字节数组。您可以使用与列表相同的方式读取/修改它(即pic[0]=255)

pic = bytearray([0xff]*256*256*3)

然后,可以使用相同的缓冲区创建ctypes字符数组:

pointer = (c_char*len(pic)).from_buffer(pic)
sdl2.SDL_UpdateTexture(texture, None, pointer, 3*256)

此外,您可能希望在创建纹理时使用sdl2.SDL_TEXTUREACCESS_流(向SDL指示您打算更新它)

相关问题 更多 >