【问题标题】:Python + sdl2: list or bytearray to c_void_pPython + sdl2:列表或字节数组到 c_void_p
【发布时间】:2020-05-01 15:08:01
【问题描述】:

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

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

直接像素操作太慢了,所以我想用sdl2.SDL_UpdateTexture一次更新整个纹理。但我无法将我的列表转换为必要的c_void_p-type。 是否有捷径可寻?或者有没有更好的方法来获得足够的 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,如果相关的话。

【问题讨论】:

  • 附注。 pygameSDL 的封装,对于游戏开发中的新手来说更容易。
  • 类似pointer = cast(c_char_p(bytes(pic)), c_void_p)?您还告诉 SDL 您的纹理是静态的,但您正在尝试做与静态相反的操作。

标签: python sdl-2


【解决方案1】:

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

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

然后您可以使用相同的缓冲区创建一个 ctypes char 数组:

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

此外,您可能希望在创建纹理时使用 sdl2.SDL_TEXTUREACCESS_STREAMING(表明您打算更新它的 SDL)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多