|
|
|
|
@ -6,6 +6,7 @@ import signal |
|
|
|
|
import sys |
|
|
|
|
import pyray as rl |
|
|
|
|
import threading |
|
|
|
|
import platform |
|
|
|
|
from contextlib import contextmanager |
|
|
|
|
from collections.abc import Callable |
|
|
|
|
from collections import deque |
|
|
|
|
@ -34,6 +35,43 @@ SCALE = float(os.getenv("SCALE", "1.0")) |
|
|
|
|
PROFILE_RENDER = int(os.getenv("PROFILE_RENDER", "0")) |
|
|
|
|
PROFILE_STATS = int(os.getenv("PROFILE_STATS", "100")) # Number of functions to show in profile output |
|
|
|
|
|
|
|
|
|
GL_VERSION = """ |
|
|
|
|
#version 300 es |
|
|
|
|
precision highp float; |
|
|
|
|
""" |
|
|
|
|
if platform.system() == "Darwin": |
|
|
|
|
GL_VERSION = """ |
|
|
|
|
#version 330 core |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
BURN_IN_MODE = "BURN_IN" in os.environ |
|
|
|
|
BURN_IN_VERTEX_SHADER = GL_VERSION + """ |
|
|
|
|
in vec3 vertexPosition; |
|
|
|
|
in vec2 vertexTexCoord; |
|
|
|
|
uniform mat4 mvp; |
|
|
|
|
out vec2 fragTexCoord; |
|
|
|
|
void main() { |
|
|
|
|
fragTexCoord = vertexTexCoord; |
|
|
|
|
gl_Position = mvp * vec4(vertexPosition, 1.0); |
|
|
|
|
} |
|
|
|
|
""" |
|
|
|
|
BURN_IN_FRAGMENT_SHADER = GL_VERSION + """ |
|
|
|
|
in vec2 fragTexCoord; |
|
|
|
|
uniform sampler2D texture0; |
|
|
|
|
out vec4 fragColor; |
|
|
|
|
void main() { |
|
|
|
|
vec4 sampled = texture(texture0, fragTexCoord); |
|
|
|
|
float intensity = sampled.b; |
|
|
|
|
// Map blue intensity to green -> yellow -> red to highlight burn-in risk. |
|
|
|
|
vec3 start = vec3(0.0, 1.0, 0.0); |
|
|
|
|
vec3 middle = vec3(1.0, 1.0, 0.0); |
|
|
|
|
vec3 end = vec3(1.0, 0.0, 0.0); |
|
|
|
|
vec3 gradient = mix(start, middle, clamp(intensity * 2.0, 0.0, 1.0)); |
|
|
|
|
gradient = mix(gradient, end, clamp((intensity - 0.5) * 2.0, 0.0, 1.0)); |
|
|
|
|
fragColor = vec4(gradient, sampled.a); |
|
|
|
|
} |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
DEFAULT_TEXT_SIZE = 60 |
|
|
|
|
DEFAULT_TEXT_COLOR = rl.WHITE |
|
|
|
|
|
|
|
|
|
@ -155,6 +193,7 @@ class GuiApplication: |
|
|
|
|
self._scaled_width = int(self._width * self._scale) |
|
|
|
|
self._scaled_height = int(self._height * self._scale) |
|
|
|
|
self._render_texture: rl.RenderTexture | None = None |
|
|
|
|
self._burn_in_shader: rl.Shader | None = None |
|
|
|
|
self._textures: dict[str, rl.Texture] = {} |
|
|
|
|
self._target_fps: int = _DEFAULT_FPS |
|
|
|
|
self._last_fps_log_time: float = time.monotonic() |
|
|
|
|
@ -212,8 +251,10 @@ class GuiApplication: |
|
|
|
|
rl.set_config_flags(flags) |
|
|
|
|
|
|
|
|
|
rl.init_window(self._scaled_width, self._scaled_height, title) |
|
|
|
|
needs_render_texture = self._scale != 1.0 or BURN_IN_MODE |
|
|
|
|
if self._scale != 1.0: |
|
|
|
|
rl.set_mouse_scale(1 / self._scale, 1 / self._scale) |
|
|
|
|
if needs_render_texture: |
|
|
|
|
self._render_texture = rl.load_render_texture(self._width, self._height) |
|
|
|
|
rl.set_texture_filter(self._render_texture.texture, rl.TextureFilter.TEXTURE_FILTER_BILINEAR) |
|
|
|
|
rl.set_target_fps(fps) |
|
|
|
|
@ -222,6 +263,8 @@ class GuiApplication: |
|
|
|
|
self._set_styles() |
|
|
|
|
self._load_fonts() |
|
|
|
|
self._patch_text_functions() |
|
|
|
|
if BURN_IN_MODE and self._burn_in_shader is None: |
|
|
|
|
self._burn_in_shader = rl.load_shader_from_memory(BURN_IN_VERTEX_SHADER, BURN_IN_FRAGMENT_SHADER) |
|
|
|
|
|
|
|
|
|
if not PC: |
|
|
|
|
self._mouse.start() |
|
|
|
|
@ -337,6 +380,10 @@ class GuiApplication: |
|
|
|
|
rl.unload_render_texture(self._render_texture) |
|
|
|
|
self._render_texture = None |
|
|
|
|
|
|
|
|
|
if self._burn_in_shader: |
|
|
|
|
rl.unload_shader(self._burn_in_shader) |
|
|
|
|
self._burn_in_shader = None |
|
|
|
|
|
|
|
|
|
if not PC: |
|
|
|
|
self._mouse.stop() |
|
|
|
|
|
|
|
|
|
@ -395,7 +442,14 @@ class GuiApplication: |
|
|
|
|
rl.clear_background(rl.BLACK) |
|
|
|
|
src_rect = rl.Rectangle(0, 0, float(self._width), -float(self._height)) |
|
|
|
|
dst_rect = rl.Rectangle(0, 0, float(self._scaled_width), float(self._scaled_height)) |
|
|
|
|
rl.draw_texture_pro(self._render_texture.texture, src_rect, dst_rect, rl.Vector2(0, 0), 0.0, rl.WHITE) |
|
|
|
|
texture = self._render_texture.texture |
|
|
|
|
if texture: |
|
|
|
|
if BURN_IN_MODE and self._burn_in_shader: |
|
|
|
|
rl.begin_shader_mode(self._burn_in_shader) |
|
|
|
|
rl.draw_texture_pro(texture, src_rect, dst_rect, rl.Vector2(0, 0), 0.0, rl.WHITE) |
|
|
|
|
rl.end_shader_mode() |
|
|
|
|
else: |
|
|
|
|
rl.draw_texture_pro(texture, src_rect, dst_rect, rl.Vector2(0, 0), 0.0, rl.WHITE) |
|
|
|
|
|
|
|
|
|
if self._show_fps: |
|
|
|
|
rl.draw_fps(10, 10) |
|
|
|
|
|