pyglet / pyglet

pyglet is a cross-platform windowing and multimedia library for Python, for developing games and other visually rich applications.
http://pyglet.org
BSD 3-Clause "New" or "Revised" License
1.89k stars 305 forks source link

Screenshoting on headless window results in blank image #720

Open Belissimo-T opened 1 year ago

Belissimo-T commented 1 year ago

Describe the bug When executing the code below, I get shown the following image: tmphmnhieti I expected this image: tmpuppq5dxo wich is exactly what I get, when I comment line 3 (pyglet.options["headless"] = True).

I expect the headless and not-headless outputs to be identical (at least that's what I think is intuitive).

Let me know if the functionality in the make_screenshot function supported in headless mode or how I can get an image of the frame buffer of a headless window, if they even have that.

How To Reproduce I used the following code:

import pyglet

pyglet.options["headless"] = True

from pyglet.graphics import Batch
from pyglet.window import Window

import PIL.Image
import io

batch = Batch()
window = Window(500, 500)

circle = pyglet.shapes.Circle(250, 250, 100, color=(255, 255, 0), batch=batch)

@window.event
def on_draw():
    window.clear()
    batch.draw()

def make_screenshot(_):
    out = io.BytesIO()

    pyglet.image.get_buffer_manager().get_color_buffer().save(file=out)

    pil_img = PIL.Image.open(out, formats=("png",))
    pil_img.show()

    pyglet.app.exit()

pyglet.clock.schedule_once(make_screenshot, 2)
pyglet.app.run()

System Information:

Platform
------------------------------------------------------------------------------
platform:  Linux-5.15.78-1-MANJARO-x86_64-with-glibc2.36
release:   5.15.78-1-MANJARO
machine:   x86_64

Python
------------------------------------------------------------------------------
implementation: CPython
sys.version: 3.10.8 (main, Nov  1 2022, 14:18:21) [GCC 12.2.0]
sys.maxint: 9223372036854775807
os.getcwd(): /run/media/bela/Belas_SSD/PycharmProjects/music_align

pyglet
------------------------------------------------------------------------------
pyglet.version: 1.5.27
pyglet.compat_platform: linux
pyglet.__file__: /home/bela/venv310/lib/python3.10/site-packages/pyglet/__init__.py
pyglet.options['audio'] = ('xaudio2', 'directsound', 'openal', 'pulse', 'silent')
pyglet.options['debug_font'] = False
pyglet.options['debug_gl'] = True
pyglet.options['debug_gl_trace'] = False
pyglet.options['debug_gl_trace_args'] = False
pyglet.options['debug_graphics_batch'] = False
pyglet.options['debug_lib'] = False
pyglet.options['debug_media'] = False
pyglet.options['debug_texture'] = False
pyglet.options['debug_trace'] = False
pyglet.options['debug_trace_args'] = False
pyglet.options['debug_trace_depth'] = 1
pyglet.options['debug_trace_flush'] = True
pyglet.options['debug_win32'] = False
pyglet.options['debug_x11'] = False
pyglet.options['graphics_vbo'] = True
pyglet.options['shadow_window'] = True
pyglet.options['vsync'] = None
pyglet.options['xsync'] = True
pyglet.options['xlib_fullscreen_override_redirect'] = False
pyglet.options['darwin_cocoa'] = True
pyglet.options['search_local_libs'] = True
pyglet.options['advanced_font_features'] = False
pyglet.options['headless'] = False
pyglet.options['headless_device'] = 0
pyglet.options['win32_disable_shaping'] = False

pyglet.window
------------------------------------------------------------------------------
display: <pyglet.canvas.xlib.XlibDisplay object at 0x7ff057217cd0>
screens[0]: XlibScreen(display=<pyglet.canvas.xlib.XlibDisplay object at 0x7ff057217cd0>, x=0, y=0, width=1920, height=1080, xinerama=0)
config['double_buffer'] = 1
config['stereo'] = 0
config['buffer_size'] = 24
config['aux_buffers'] = 4
config['sample_buffers'] = 0
config['samples'] = 0
config['red_size'] = 8
config['green_size'] = 8
config['blue_size'] = 8
config['alpha_size'] = 0
config['depth_size'] = 24
config['stencil_size'] = 0
config['accum_red_size'] = 16
config['accum_green_size'] = 16
config['accum_blue_size'] = 16
config['accum_alpha_size'] = 16
config['major_version'] = None
config['minor_version'] = None
config['forward_compatible'] = None
config['debug'] = None
context: XlibContextARB()

window.context._info
------------------------------------------------------------------------------
gl_info.get_version(): 4.6.0 NVIDIA 520.56.06
gl_info.get_vendor(): NVIDIA Corporation
gl_info.get_renderer(): NVIDIA GeForce GTX 1650/PCIe/SSE2
gl_info.get_extensions():
   GL_AMD_multi_draw_indirect
   GL_AMD_seamless_cubemap_per_texture
   GL_AMD_vertex_shader_layer
   GL_AMD_vertex_shader_viewport_index
   GL_ARB_ES2_compatibility
   GL_ARB_ES3_1_compatibility
   GL_ARB_ES3_2_compatibility
   GL_ARB_ES3_compatibility
   GL_ARB_arrays_of_arrays
   GL_ARB_base_instance
   GL_ARB_bindless_texture
   GL_ARB_blend_func_extended
   GL_ARB_buffer_storage
   GL_ARB_clear_buffer_object
   GL_ARB_clear_texture
   GL_ARB_clip_control
   GL_ARB_color_buffer_float
   GL_ARB_compatibility
   GL_ARB_compressed_texture_pixel_storage
   GL_ARB_compute_shader
   GL_ARB_compute_variable_group_size
   GL_ARB_conditional_render_inverted
   GL_ARB_conservative_depth
   GL_ARB_copy_buffer
   GL_ARB_copy_image
   GL_ARB_cull_distance
   GL_ARB_debug_output
   GL_ARB_depth_buffer_float
   GL_ARB_depth_clamp
   GL_ARB_depth_texture
   GL_ARB_derivative_control
   GL_ARB_direct_state_access
   GL_ARB_draw_buffers
   GL_ARB_draw_buffers_blend
   GL_ARB_draw_elements_base_vertex
   GL_ARB_draw_indirect
   GL_ARB_draw_instanced
   GL_ARB_enhanced_layouts
   GL_ARB_explicit_attrib_location
   GL_ARB_explicit_uniform_location
   GL_ARB_fragment_coord_conventions
   GL_ARB_fragment_layer_viewport
   GL_ARB_fragment_program
   GL_ARB_fragment_program_shadow
   GL_ARB_fragment_shader
   GL_ARB_fragment_shader_interlock
   GL_ARB_framebuffer_no_attachments
   GL_ARB_framebuffer_object
   GL_ARB_framebuffer_sRGB
   GL_ARB_geometry_shader4
   GL_ARB_get_program_binary
   GL_ARB_get_texture_sub_image
   GL_ARB_gl_spirv
   GL_ARB_gpu_shader5
   GL_ARB_gpu_shader_fp64
   GL_ARB_gpu_shader_int64
   GL_ARB_half_float_pixel
   GL_ARB_half_float_vertex
   GL_ARB_imaging
   GL_ARB_indirect_parameters
   GL_ARB_instanced_arrays
   GL_ARB_internalformat_query
   GL_ARB_internalformat_query2
   GL_ARB_invalidate_subdata
   GL_ARB_map_buffer_alignment
   GL_ARB_map_buffer_range
   GL_ARB_multi_bind
   GL_ARB_multi_draw_indirect
   GL_ARB_multisample
   GL_ARB_multitexture
   GL_ARB_occlusion_query
   GL_ARB_occlusion_query2
   GL_ARB_parallel_shader_compile
   GL_ARB_pipeline_statistics_query
   GL_ARB_pixel_buffer_object
   GL_ARB_point_parameters
   GL_ARB_point_sprite
   GL_ARB_polygon_offset_clamp
   GL_ARB_post_depth_coverage
   GL_ARB_program_interface_query
   GL_ARB_provoking_vertex
   GL_ARB_query_buffer_object
   GL_ARB_robust_buffer_access_behavior
   GL_ARB_robustness
   GL_ARB_sample_locations
   GL_ARB_sample_shading
   GL_ARB_sampler_objects
   GL_ARB_seamless_cube_map
   GL_ARB_seamless_cubemap_per_texture
   GL_ARB_separate_shader_objects
   GL_ARB_shader_atomic_counter_ops
   GL_ARB_shader_atomic_counters
   GL_ARB_shader_ballot
   GL_ARB_shader_bit_encoding
   GL_ARB_shader_clock
   GL_ARB_shader_draw_parameters
   GL_ARB_shader_group_vote
   GL_ARB_shader_image_load_store
   GL_ARB_shader_image_size
   GL_ARB_shader_objects
   GL_ARB_shader_precision
   GL_ARB_shader_storage_buffer_object
   GL_ARB_shader_subroutine
   GL_ARB_shader_texture_image_samples
   GL_ARB_shader_texture_lod
   GL_ARB_shader_viewport_layer_array
   GL_ARB_shading_language_100
   GL_ARB_shading_language_420pack
   GL_ARB_shading_language_include
   GL_ARB_shading_language_packing
   GL_ARB_shadow
   GL_ARB_sparse_buffer
   GL_ARB_sparse_texture
   GL_ARB_sparse_texture2
   GL_ARB_sparse_texture_clamp
   GL_ARB_spirv_extensions
   GL_ARB_stencil_texturing
   GL_ARB_sync
   GL_ARB_tessellation_shader
   GL_ARB_texture_barrier
   GL_ARB_texture_border_clamp
   GL_ARB_texture_buffer_object
   GL_ARB_texture_buffer_object_rgb32
   GL_ARB_texture_buffer_range
   GL_ARB_texture_compression
   GL_ARB_texture_compression_bptc
   GL_ARB_texture_compression_rgtc
   GL_ARB_texture_cube_map
   GL_ARB_texture_cube_map_array
   GL_ARB_texture_env_add
   GL_ARB_texture_env_combine
   GL_ARB_texture_env_crossbar
   GL_ARB_texture_env_dot3
   GL_ARB_texture_filter_anisotropic
   GL_ARB_texture_filter_minmax
   GL_ARB_texture_float
   GL_ARB_texture_gather
   GL_ARB_texture_mirror_clamp_to_edge
   GL_ARB_texture_mirrored_repeat
   GL_ARB_texture_multisample
   GL_ARB_texture_non_power_of_two
   GL_ARB_texture_query_levels
   GL_ARB_texture_query_lod
   GL_ARB_texture_rectangle
   GL_ARB_texture_rg
   GL_ARB_texture_rgb10_a2ui
   GL_ARB_texture_stencil8
   GL_ARB_texture_storage
   GL_ARB_texture_storage_multisample
   GL_ARB_texture_swizzle
   GL_ARB_texture_view
   GL_ARB_timer_query
   GL_ARB_transform_feedback2
   GL_ARB_transform_feedback3
   GL_ARB_transform_feedback_instanced
   GL_ARB_transform_feedback_overflow_query
   GL_ARB_transpose_matrix
   GL_ARB_uniform_buffer_object
   GL_ARB_vertex_array_bgra
   GL_ARB_vertex_array_object
   GL_ARB_vertex_attrib_64bit
   GL_ARB_vertex_attrib_binding
   GL_ARB_vertex_buffer_object
   GL_ARB_vertex_program
   GL_ARB_vertex_shader
   GL_ARB_vertex_type_10f_11f_11f_rev
   GL_ARB_vertex_type_2_10_10_10_rev
   GL_ARB_viewport_array
   GL_ARB_window_pos
   GL_ATI_draw_buffers
   GL_ATI_texture_float
   GL_ATI_texture_mirror_once
   GL_EXTX_framebuffer_mixed_formats
   GL_EXT_Cg_shader
   GL_EXT_abgr
   GL_EXT_bgra
   GL_EXT_bindable_uniform
   GL_EXT_blend_color
   GL_EXT_blend_equation_separate
   GL_EXT_blend_func_separate
   GL_EXT_blend_minmax
   GL_EXT_blend_subtract
   GL_EXT_compiled_vertex_array
   GL_EXT_depth_bounds_test
   GL_EXT_direct_state_access
   GL_EXT_draw_buffers2
   GL_EXT_draw_instanced
   GL_EXT_draw_range_elements
   GL_EXT_fog_coord
   GL_EXT_framebuffer_blit
   GL_EXT_framebuffer_multisample
   GL_EXT_framebuffer_multisample_blit_scaled
   GL_EXT_framebuffer_object
   GL_EXT_framebuffer_sRGB
   GL_EXT_geometry_shader4
   GL_EXT_gpu_program_parameters
   GL_EXT_gpu_shader4
   GL_EXT_import_sync_object
   GL_EXT_memory_object
   GL_EXT_memory_object_fd
   GL_EXT_multi_draw_arrays
   GL_EXT_multiview_texture_multisample
   GL_EXT_multiview_timer_query
   GL_EXT_packed_depth_stencil
   GL_EXT_packed_float
   GL_EXT_packed_pixels
   GL_EXT_pixel_buffer_object
   GL_EXT_point_parameters
   GL_EXT_polygon_offset_clamp
   GL_EXT_post_depth_coverage
   GL_EXT_provoking_vertex
   GL_EXT_raster_multisample
   GL_EXT_rescale_normal
   GL_EXT_secondary_color
   GL_EXT_semaphore
   GL_EXT_semaphore_fd
   GL_EXT_separate_shader_objects
   GL_EXT_separate_specular_color
   GL_EXT_shader_image_load_formatted
   GL_EXT_shader_image_load_store
   GL_EXT_shader_integer_mix
   GL_EXT_shadow_funcs
   GL_EXT_sparse_texture2
   GL_EXT_stencil_two_side
   GL_EXT_stencil_wrap
   GL_EXT_texture3D
   GL_EXT_texture_array
   GL_EXT_texture_buffer_object
   GL_EXT_texture_compression_dxt1
   GL_EXT_texture_compression_latc
   GL_EXT_texture_compression_rgtc
   GL_EXT_texture_compression_s3tc
   GL_EXT_texture_cube_map
   GL_EXT_texture_edge_clamp
   GL_EXT_texture_env_add
   GL_EXT_texture_env_combine
   GL_EXT_texture_env_dot3
   GL_EXT_texture_filter_anisotropic
   GL_EXT_texture_filter_minmax
   GL_EXT_texture_integer
   GL_EXT_texture_lod
   GL_EXT_texture_lod_bias
   GL_EXT_texture_mirror_clamp
   GL_EXT_texture_object
   GL_EXT_texture_sRGB
   GL_EXT_texture_sRGB_R8
   GL_EXT_texture_sRGB_decode
   GL_EXT_texture_shadow_lod
   GL_EXT_texture_shared_exponent
   GL_EXT_texture_storage
   GL_EXT_texture_swizzle
   GL_EXT_timer_query
   GL_EXT_transform_feedback2
   GL_EXT_vertex_array
   GL_EXT_vertex_array_bgra
   GL_EXT_vertex_attrib_64bit
   GL_EXT_window_rectangles
   GL_EXT_x11_sync_object
   GL_IBM_rasterpos_clip
   GL_IBM_texture_mirrored_repeat
   GL_KHR_blend_equation_advanced
   GL_KHR_blend_equation_advanced_coherent
   GL_KHR_context_flush_control
   GL_KHR_debug
   GL_KHR_no_error
   GL_KHR_parallel_shader_compile
   GL_KHR_robust_buffer_access_behavior
   GL_KHR_robustness
   GL_KHR_shader_subgroup
   GL_KTX_buffer_region
   GL_NVX_blend_equation_advanced_multi_draw_buffers
   GL_NVX_conditional_render
   GL_NVX_gpu_memory_info
   GL_NVX_nvenc_interop
   GL_NVX_progress_fence
   GL_NV_ES1_1_compatibility
   GL_NV_ES3_1_compatibility
   GL_NV_alpha_to_coverage_dither_control
   GL_NV_bindless_multi_draw_indirect
   GL_NV_bindless_multi_draw_indirect_count
   GL_NV_bindless_texture
   GL_NV_blend_equation_advanced
   GL_NV_blend_equation_advanced_coherent
   GL_NV_blend_minmax_factor
   GL_NV_blend_square
   GL_NV_clip_space_w_scaling
   GL_NV_command_list
   GL_NV_compute_program5
   GL_NV_compute_shader_derivatives
   GL_NV_conditional_render
   GL_NV_conservative_raster
   GL_NV_conservative_raster_dilate
   GL_NV_conservative_raster_pre_snap
   GL_NV_conservative_raster_pre_snap_triangles
   GL_NV_conservative_raster_underestimation
   GL_NV_copy_depth_to_color
   GL_NV_copy_image
   GL_NV_depth_buffer_float
   GL_NV_depth_clamp
   GL_NV_draw_texture
   GL_NV_draw_vulkan_image
   GL_NV_explicit_multisample
   GL_NV_feature_query
   GL_NV_fence
   GL_NV_fill_rectangle
   GL_NV_float_buffer
   GL_NV_fog_distance
   GL_NV_fragment_coverage_to_color
   GL_NV_fragment_program
   GL_NV_fragment_program2
   GL_NV_fragment_program_option
   GL_NV_fragment_shader_barycentric
   GL_NV_fragment_shader_interlock
   GL_NV_framebuffer_mixed_samples
   GL_NV_framebuffer_multisample_coverage
   GL_NV_geometry_shader4
   GL_NV_geometry_shader_passthrough
   GL_NV_gpu_multicast
   GL_NV_gpu_program4
   GL_NV_gpu_program4_1
   GL_NV_gpu_program5
   GL_NV_gpu_program5_mem_extended
   GL_NV_gpu_program_fp64
   GL_NV_gpu_shader5
   GL_NV_half_float
   GL_NV_internalformat_sample_query
   GL_NV_light_max_exponent
   GL_NV_memory_attachment
   GL_NV_memory_object_sparse
   GL_NV_mesh_shader
   GL_NV_multisample_coverage
   GL_NV_multisample_filter_hint
   GL_NV_occlusion_query
   GL_NV_packed_depth_stencil
   GL_NV_parameter_buffer_object
   GL_NV_parameter_buffer_object2
   GL_NV_path_rendering
   GL_NV_path_rendering_shared_edge
   GL_NV_pixel_data_range
   GL_NV_point_sprite
   GL_NV_primitive_restart
   GL_NV_query_resource
   GL_NV_query_resource_tag
   GL_NV_register_combiners
   GL_NV_register_combiners2
   GL_NV_representative_fragment_test
   GL_NV_robustness_video_memory_purge
   GL_NV_sample_locations
   GL_NV_sample_mask_override_coverage
   GL_NV_scissor_exclusive
   GL_NV_shader_atomic_counters
   GL_NV_shader_atomic_float
   GL_NV_shader_atomic_float64
   GL_NV_shader_atomic_fp16_vector
   GL_NV_shader_atomic_int64
   GL_NV_shader_buffer_load
   GL_NV_shader_storage_buffer_object
   GL_NV_shader_subgroup_partitioned
   GL_NV_shader_texture_footprint
   GL_NV_shader_thread_group
   GL_NV_shader_thread_shuffle
   GL_NV_shading_rate_image
   GL_NV_stereo_view_rendering
   GL_NV_texgen_reflection
   GL_NV_texture_barrier
   GL_NV_texture_compression_vtc
   GL_NV_texture_env_combine4
   GL_NV_texture_multisample
   GL_NV_texture_rectangle
   GL_NV_texture_rectangle_compressed
   GL_NV_texture_shader
   GL_NV_texture_shader2
   GL_NV_texture_shader3
   GL_NV_timeline_semaphore
   GL_NV_transform_feedback
   GL_NV_transform_feedback2
   GL_NV_uniform_buffer_unified_memory
   GL_NV_vdpau_interop
   GL_NV_vdpau_interop2
   GL_NV_vertex_array_range
   GL_NV_vertex_array_range2
   GL_NV_vertex_attrib_integer_64bit
   GL_NV_vertex_buffer_unified_memory
   GL_NV_vertex_program
   GL_NV_vertex_program1_1
   GL_NV_vertex_program2
   GL_NV_vertex_program2_option
   GL_NV_vertex_program3
   GL_NV_viewport_array2
   GL_NV_viewport_swizzle
   GL_OVR_multiview
   GL_OVR_multiview2
   GL_S3_s3tc
   GL_SGIS_generate_mipmap
   GL_SGIS_texture_lod
   GL_SGIX_depth_texture
   GL_SGIX_shadow
   GL_SUN_slice_accum

pyglet.gl.glu_info
------------------------------------------------------------------------------
glu_info.get_version(): 1.3
glu_info.get_extensions():
   GLU_EXT_nurbs_tessellator
   GLU_EXT_object_space_tess

pyglet.gl.glx_info
------------------------------------------------------------------------------
context.is_direct(): 1
glx_info.get_server_vendor(): NVIDIA Corporation
glx_info.get_server_version(): 1.4
glx_info.get_server_extensions():
   GLX_EXT_visual_info
   GLX_EXT_visual_rating
   GLX_EXT_import_context
   GLX_SGIX_fbconfig
   GLX_SGIX_pbuffer
   GLX_SGI_video_sync
   GLX_SGI_swap_control
   GLX_EXT_swap_control
   GLX_EXT_swap_control_tear
   GLX_EXT_texture_from_pixmap
   GLX_EXT_buffer_age
   GLX_ARB_create_context
   GLX_ARB_create_context_profile
   GLX_EXT_create_context_es_profile
   GLX_EXT_create_context_es2_profile
   GLX_ARB_create_context_no_error
   GLX_ARB_create_context_robustness
   GLX_NV_delay_before_swap
   GLX_EXT_stereo_tree
   GLX_EXT_libglvnd
   GLX_ARB_context_flush_control
   GLX_NV_robustness_video_memory_purge
   GLX_NV_multigpu_context
   GLX_ARB_multisample
   GLX_NV_float_buffer
   GLX_ARB_fbconfig_float
   GLX_EXT_framebuffer_sRGB
   GLX_NV_copy_image
glx_info.get_client_vendor(): NVIDIA Corporation
glx_info.get_client_version(): 1.4
glx_info.get_client_extensions():
   GLX_ARB_get_proc_address
   GLX_ARB_multisample
   GLX_EXT_visual_info
   GLX_EXT_visual_rating
   GLX_EXT_import_context
   GLX_SGI_video_sync
   GLX_NV_swap_group
   GLX_SGIX_fbconfig
   GLX_SGIX_pbuffer
   GLX_SGI_swap_control
   GLX_EXT_swap_control
   GLX_EXT_swap_control_tear
   GLX_EXT_buffer_age
   GLX_ARB_create_context
   GLX_ARB_create_context_profile
   GLX_NV_float_buffer
   GLX_ARB_fbconfig_float
   GLX_EXT_fbconfig_packed_float
   GLX_EXT_texture_from_pixmap
   GLX_EXT_framebuffer_sRGB
   GLX_NV_copy_image
   GLX_NV_copy_buffer
   GLX_NV_multisample_coverage
   GLX_EXT_create_context_es_profile
   GLX_EXT_create_context_es2_profile
   GLX_ARB_create_context_no_error
   GLX_ARB_create_context_robustness
   GLX_NV_delay_before_swap
   GLX_EXT_stereo_tree
   GLX_ARB_context_flush_control
   GLX_NV_robustness_video_memory_purge
   GLX_NV_multigpu_context
glx_info.get_extensions():
   GLX_ARB_get_proc_address
   GLX_ARB_multisample
   GLX_EXT_visual_info
   GLX_EXT_visual_rating
   GLX_EXT_import_context
   GLX_SGI_video_sync
   GLX_SGIX_fbconfig
   GLX_SGIX_pbuffer
   GLX_SGI_swap_control
   GLX_EXT_swap_control
   GLX_EXT_swap_control_tear
   GLX_EXT_buffer_age
   GLX_ARB_create_context
   GLX_ARB_create_context_profile
   GLX_NV_float_buffer
   GLX_ARB_fbconfig_float
   GLX_EXT_texture_from_pixmap
   GLX_EXT_framebuffer_sRGB
   GLX_NV_copy_image
   GLX_EXT_create_context_es_profile
   GLX_EXT_create_context_es2_profile
   GLX_ARB_create_context_no_error
   GLX_ARB_create_context_robustness
   GLX_NV_delay_before_swap
   GLX_EXT_stereo_tree
   GLX_ARB_context_flush_control
   GLX_NV_robustness_video_memory_purge
   GLX_NV_multigpu_context

pyglet.media
------------------------------------------------------------------------------
audio driver: <pyglet.media.drivers.openal.adaptation.OpenALDriver object at 0x7ff0572179d0>

pyglet.media.ffmpeg
------------------------------------------------------------------------------
FFmpeg version: n5.1.2

pyglet.media.drivers.openal
------------------------------------------------------------------------------
Library: <CDLL 'libopenal.so.1', handle 55940f4c54a0 at 0x7ff051c09f30>
Version: 1.1
Extensions:
   ALC_ENUMERATE_ALL_EXT
   ALC_ENUMERATION_EXT
   ALC_EXT_CAPTURE
   ALC_EXT_DEDICATED
   ALC_EXT_disconnect
   ALC_EXT_EFX
   ALC_EXT_thread_local_context
   ALC_SOFT_device_clock
   ALC_SOFT_HRTF
   ALC_SOFT_loopback
   ALC_SOFT_loopback_bformat
   ALC_SOFT_output_limiter
   ALC_SOFT_output_mode
   ALC_SOFT_pause_device
   ALC_SOFT_reopen_device

pyglet.input.wintab
------------------------------------------------------------------------------
WinTab not available.
einarf commented 1 year ago

It's probably because get_color_buffer() reads the back buffer by default. It would work in the next frame.

eschan145 commented 1 year ago

@BelTol3011 you should probably add most of the example reproducible code before all the pyglet.info. It's kind of long. People might use the scrollbar to go past it accidentally, seeing the giant pyglet.info output. Just a suggestion.,

Belissimo-T commented 1 year ago

It would work in the next frame.

Sadly can't be. I added a call to pyglet.clock.schedule_interval() such that the on_draw method gets called repeatedly until the screenshot is made. It still doesn't work.

I hope that's what you mean with next frame.


import pyglet

pyglet.options["headless"] = True

from pyglet.graphics import Batch
from pyglet.window import Window

import PIL.Image
import io

batch = Batch()
window = Window(500, 500)

circle = pyglet.shapes.Circle(250, 250, 100, color=(255, 255, 0), batch=batch)

@window.event
def on_draw():
    print("on_draw")
    window.clear()
    batch.draw()

def make_screenshot(_):
    out = io.BytesIO()

    pyglet.image.get_buffer_manager().get_color_buffer().save(file=out)

    pil_img = PIL.Image.open(out, formats=("png",))
    pil_img.show()

    pyglet.app.exit()

pyglet.clock.schedule_interval(lambda _: None, 1 / 60)
pyglet.clock.schedule_once(make_screenshot, 2)
pyglet.app.run()
benmoran56 commented 1 year ago

You can try changing the buffer which ColorBuffer is taking from. For example:

pyglet.image.ColorBufferImage.gl_buffer = pyglet.gl.GL_FRONT

On my Linux machine (AMD, Mesa stack) your example works. In my case it works with either GL_FRONT or GL_BACK buffers.

Belissimo-T commented 1 year ago

@benmoran56 I included your line in my program:

import pyglet

pyglet.options["headless"] = True

from pyglet.graphics import Batch
from pyglet.window import Window

import PIL.Image
import io

batch = Batch()
window = Window(500, 500)
window.set_caption("Transparent Window")

circle = pyglet.shapes.Circle(250, 250, 100, color=(255, 255, 0), batch=batch)

@window.event
def on_draw():
    print("on_draw")
    window.clear()
    batch.draw()

def make_screenshot(_):
    out = io.BytesIO()

    pyglet.image.ColorBufferImage.gl_buffer = pyglet.gl.GL_FRONT
    pyglet.image.get_buffer_manager().get_color_buffer().save(file=out)

    pil_img = PIL.Image.open(out, formats=("png",))
    pil_img.show()

    pyglet.app.exit()

pyglet.clock.schedule_interval(lambda _: None, 1 / 60)
pyglet.clock.schedule_once(make_screenshot, 2)
pyglet.app.run()

I now get the following exception when the make_screenshot()-function is called:

Traceback (most recent call last):
  File "/home/bela/.config/JetBrains/PyCharm2022.3/scratches/scratch_29.py", line 40, in <module>
    pyglet.app.run()
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/app/__init__.py", line 107, in run
    event_loop.run()
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/app/base.py", line 169, in run
    timeout = self.idle()
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/app/base.py", line 239, in idle
    redraw_all = self.clock.call_scheduled_functions(dt)
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/clock.py", line 292, in call_scheduled_functions
    item.func(now - item.last_ts, *item.args, **item.kwargs)
  File "/home/bela/.config/JetBrains/PyCharm2022.3/scratches/scratch_29.py", line 29, in make_screenshot
    pyglet.image.get_buffer_manager().get_color_buffer().save(file=out)
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/image/__init__.py", line 500, in save
    encoder.encode(self, file, filename)
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/image/codecs/pil.py", line 129, in encode
    image = image.get_image_data()
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/image/__init__.py", line 2046, in get_image_data
    glReadBuffer(self.gl_buffer)
  File "/home/bela/venv310/lib/python3.10/site-packages/pyglet/gl/lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'invalid operation'

With pyglet.gl.GL_BACK I still get the same blank image as in the initial bug report.