0
\$\begingroup\$

Envrionment:

  • python: 3.6.6
  • pyglet: 1.3.2

Here is my code and results:

import pyglet

images = []
textures = []

with_textures = True
count = 10
for x in range(count):
    image = pyglet.image.load("big.png")  # 2.1 Mb source 2400*2400px
    images.append(image)
    if with_textures:
        texture_grid = pyglet.image.ImageGrid(image, 10, 10).get_texture_sequence()
        textures.append(texture_grid)

# RES in htop result without textures
# count = 10 - 300Mb
# count = 20 - 553Mb
# count = 30 - 753Mb
# count = 40 - 973Mb
# ~23Mb just for each Image

# RES in htop result with textures
# count = 10 - 996Mb
# count = 20 - 1878Mb
# count = 30 - 2716Mb
# count = 40 - 3597Mb
# ~86Mb for Image and prepared grid


input("Press enter to exit")

Questions:

  1. Why each 2.1Mb file leads to 23Mb of memory usage with pyglet.image.AbstractImage?
    • If ImageGrid is used for creating sprite sheet -> it leads to additional ~60Mb
  2. How to deal with it? Because if game contains 50+ big sprites it would be not real to dedicate such many memory only for textures.
  3. Maybe there is some other approach in creating games which is used sprites? Or I should change my stack technology(pyglet as main library, also was trying with pygame) for client side?

PS: First time I've rewritten my application from pygame to pyglet, because I didn't consider some aspects of event loop in pygame, and now I hadn't test resource usage of pyglet library for my use-cases.

Update/clarification:

I'm using ImageGrid as for 3d part in vertices as for 2d part in pyglet.sprite.Sprite

Example of using in 3D part:

# texture_group is created once for each sprite sheet, same as texture_grid
texture_group = pyglet.graphics.TextureGroup(texture_grid, order_group)
...

tex_map = texture_grid[self.texture_grid_index].texture.tex_coords
tex_coords = ('t3f', tex_map)
self.entity = self.batch.add(
    4, pyglet.gl.GL_QUADS,
    texture_group,
    ('v3f', (x, y, z,
             x_, y, z,
             x_, y_, z,
             x, y_, z)
     ),
    tex_coords)

Example of using in 2D part:

pyglet.sprite.Sprite(img=texture_grid[self.texture_grid_index], x=0, y=0,
                     batch=self.batch, group=some_order_group)

Update #2:

As I figure out, allowed sizes for using pyglet.image.CompressedImageData is:

1 True
2 True
4 True
8 True
16 True
32 True
64 True
128 True
256 True
512 True
1024 True
2048 True
4096 True

But can't get texture from CompressedImageData:

big = pyglet.image.load("big.png")  # 2048*2048
compressed_format = pyglet.graphics.GL_COMPRESSED_ALPHA
compressed_image = pyglet.image.CompressedImageData(
    big.width, big.height, compressed_format, big.data)
compressed_image.texture  # exception GLException: b'invalid enumerant'

Tried with all possible GL_COMPRESS in pyglet:

allowed_formats = [x for x in dir(pyglet.graphics) if "GL_COMPRESSED_" in x]
big = pyglet.image.load("big.png")  # 2048*2048
for form in allowed_formats:
    compressed_image = pyglet.image.CompressedImageData(
        big.width, big.height, form, big.data)
    try:
        compressed_image.texture
        print("positive:", form)  # 0 positive prints
    except Exception:
        pass
\$\endgroup\$
  • 5
    \$\begingroup\$ Remember that graphics cards don't speak PNG, so that on-disc compressed data needs to be unpacked to a format the graphics card can draw. The simplest is uncompressed RGBA, 4 bytes per pixel. Multiply that by 2400x2400 pixels and that gives us just about the 23 MB you're seeing (21.97 MiB to be precise). If that's excessive for your application, have you looked into GPU-friendly compression like BCn or ASTC? \$\endgroup\$ – DMGregory Apr 4 at 16:45
  • \$\begingroup\$ @DMGregory Thanks for explanation, I'll read about BCns and ASTC. That is something new for me. \$\endgroup\$ – Yuriy Leonov Apr 4 at 16:48
  • \$\begingroup\$ I've read it, but can't understand, how to convert .png into other formats. Some BCn doesn't support alpha layers. \$\endgroup\$ – Yuriy Leonov Apr 8 at 7:32
  • \$\begingroup\$ Is your question now "How can I compress png images to a GPU format and use those compressed textures in Pyglet?" ? If so, you may want to edit your title and body of your question to reflect this - "how" questions typically attract deeper, more useful answers here than "why" \$\endgroup\$ – DMGregory Apr 8 at 17:02
  • \$\begingroup\$ @DMGregory well, I partially solve my question in this title stackoverflow.com/questions/55574543/… And now I maybe need only some advices. \$\endgroup\$ – Yuriy Leonov Apr 8 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.