pythonarcade / arcade

Easy to use Python library for creating 2D arcade games.
http://arcade.academy
Other
1.71k stars 324 forks source link

GL texture write method should accept all ByteStrings, not just bytes #703

Closed pushfoo closed 4 years ago

pushfoo commented 4 years ago

Enhancement request:

What should be added/changed?

ByteStrings in general should be accepted by the write function of the GL texture abstraction . For example, bytearrays and memoryviews.

I'm pretty sure the other ByteStrings (bytearray, memoryview) work in the exact same way as bytes for read operations, so the change should only require altering the type check.

What would it help with?

Any situation where someone wants to load texture data from a bytearray or memoryview rather than converting to plain bytes beforehand. This would spare users extra copy operations and result in cleaner code by removing the need to call bytes() to convert from other types of ByteStrings.

One situation where this would be helpful is for beginner emulator developers that are extracting and converting sprite data from ROMs. I've been told that NES and GameBoy are both simple enough that a playable implementation in python isn't out of the question. NumPy arrays and arrays seem to get recommended for use as a backing storage structure for RAM, and they readily convert to memoryviews. Passing sprite data to update a texture should only require passing a sprite-length slice of system memory memoryview to the texture write() function. Slicing them doesn't copy any data, so nothing will get copied until the texture update method is called.

As another example using Chip-8, @einarf wrote a display example stub for the platform (ty!). It would be possible to keep the backing array around as well as a memoryview of its contents, and pass the memoryview to the write function to update the texture every frame. It would also be possible to do the same from a memoryview representation of a bitarray. I"m using the bitarray module as the backing for the display in my Chip-8 implementation to make drawing easier to read, and wouldn't be surprised if others will too.

pushfoo commented 4 years ago

If the maintainers are ok with this issue, i might take a crack at it after #704 gets closed

einarf commented 4 years ago

Buffers do support the buffer protocol. It's just about passing the data into a utility function. I can fix that relatively quick. (Adding buffer protocol support for the other objects as well)

einarf commented 4 years ago

Fixed. You can write any object supporting the buffer protocol. c95cf5ea859c1b31c12081c6b89ea7e14a4de3e2

That probably means you can just pass in the bitarray directly. Arcade will wrap it in a memoryview and convert that to a ctypes pointer pyglet's gl wrapper will understand. This is all happens without copying any data.

einarf commented 4 years ago

FYI: I also fixed the issue on OS X (chip8 example)