66import sys
77import pyray as rl
88import threading
9+ import platform
910from contextlib import contextmanager
1011from collections .abc import Callable
1112from collections import deque
3435PROFILE_RENDER = int (os .getenv ("PROFILE_RENDER" , "0" ))
3536PROFILE_STATS = int (os .getenv ("PROFILE_STATS" , "100" )) # Number of functions to show in profile output
3637
38+ GL_VERSION = """
39+ #version 300 es
40+ precision highp float;
41+ """
42+ if platform .system () == "Darwin" :
43+ GL_VERSION = """
44+ #version 330 core
45+ """
46+
47+ BURN_IN_MODE = "BURN_IN" in os .environ
48+ BURN_IN_VERTEX_SHADER = GL_VERSION + """
49+ in vec3 vertexPosition;
50+ in vec2 vertexTexCoord;
51+ uniform mat4 mvp;
52+ out vec2 fragTexCoord;
53+ void main() {
54+ fragTexCoord = vertexTexCoord;
55+ gl_Position = mvp * vec4(vertexPosition, 1.0);
56+ }
57+ """
58+ BURN_IN_FRAGMENT_SHADER = GL_VERSION + """
59+ in vec2 fragTexCoord;
60+ uniform sampler2D texture0;
61+ out vec4 fragColor;
62+ void main() {
63+ vec4 sampled = texture(texture0, fragTexCoord);
64+ float intensity = sampled.b;
65+ // Map blue intensity to green -> yellow -> red to highlight burn-in risk.
66+ vec3 start = vec3(0.0, 1.0, 0.0);
67+ vec3 middle = vec3(1.0, 1.0, 0.0);
68+ vec3 end = vec3(1.0, 0.0, 0.0);
69+ vec3 gradient = mix(start, middle, clamp(intensity * 2.0, 0.0, 1.0));
70+ gradient = mix(gradient, end, clamp((intensity - 0.5) * 2.0, 0.0, 1.0));
71+ fragColor = vec4(gradient, sampled.a);
72+ }
73+ """
74+
3775DEFAULT_TEXT_SIZE = 60
3876DEFAULT_TEXT_COLOR = rl .WHITE
3977
@@ -155,6 +193,7 @@ def __init__(self, width: int, height: int):
155193 self ._scaled_width = int (self ._width * self ._scale )
156194 self ._scaled_height = int (self ._height * self ._scale )
157195 self ._render_texture : rl .RenderTexture | None = None
196+ self ._burn_in_shader : rl .Shader | None = None
158197 self ._textures : dict [str , rl .Texture ] = {}
159198 self ._target_fps : int = _DEFAULT_FPS
160199 self ._last_fps_log_time : float = time .monotonic ()
@@ -212,8 +251,10 @@ def _close(sig, frame):
212251 rl .set_config_flags (flags )
213252
214253 rl .init_window (self ._scaled_width , self ._scaled_height , title )
254+ needs_render_texture = self ._scale != 1.0 or BURN_IN_MODE
215255 if self ._scale != 1.0 :
216256 rl .set_mouse_scale (1 / self ._scale , 1 / self ._scale )
257+ if needs_render_texture :
217258 self ._render_texture = rl .load_render_texture (self ._width , self ._height )
218259 rl .set_texture_filter (self ._render_texture .texture , rl .TextureFilter .TEXTURE_FILTER_BILINEAR )
219260 rl .set_target_fps (fps )
@@ -222,6 +263,8 @@ def _close(sig, frame):
222263 self ._set_styles ()
223264 self ._load_fonts ()
224265 self ._patch_text_functions ()
266+ if BURN_IN_MODE and self ._burn_in_shader is None :
267+ self ._burn_in_shader = rl .load_shader_from_memory (BURN_IN_VERTEX_SHADER , BURN_IN_FRAGMENT_SHADER )
225268
226269 if not PC :
227270 self ._mouse .start ()
@@ -337,6 +380,10 @@ def close(self):
337380 rl .unload_render_texture (self ._render_texture )
338381 self ._render_texture = None
339382
383+ if self ._burn_in_shader :
384+ rl .unload_shader (self ._burn_in_shader )
385+ self ._burn_in_shader = None
386+
340387 if not PC :
341388 self ._mouse .stop ()
342389
@@ -395,7 +442,14 @@ def render(self):
395442 rl .clear_background (rl .BLACK )
396443 src_rect = rl .Rectangle (0 , 0 , float (self ._width ), - float (self ._height ))
397444 dst_rect = rl .Rectangle (0 , 0 , float (self ._scaled_width ), float (self ._scaled_height ))
398- rl .draw_texture_pro (self ._render_texture .texture , src_rect , dst_rect , rl .Vector2 (0 , 0 ), 0.0 , rl .WHITE )
445+ texture = self ._render_texture .texture
446+ if texture :
447+ if BURN_IN_MODE and self ._burn_in_shader :
448+ rl .begin_shader_mode (self ._burn_in_shader )
449+ rl .draw_texture_pro (texture , src_rect , dst_rect , rl .Vector2 (0 , 0 ), 0.0 , rl .WHITE )
450+ rl .end_shader_mode ()
451+ else :
452+ rl .draw_texture_pro (texture , src_rect , dst_rect , rl .Vector2 (0 , 0 ), 0.0 , rl .WHITE )
399453
400454 if self ._show_fps :
401455 rl .draw_fps (10 , 10 )
0 commit comments