Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save EncodeTheCode/a455349f5bb10084d760717b221ecbfb to your computer and use it in GitHub Desktop.
Save EncodeTheCode/a455349f5bb10084d760717b221ecbfb to your computer and use it in GitHub Desktop.
import glfw
from OpenGL.GL import *
import time
# Configuration
INITIAL_WINDOW_WIDTH = 800
INITIAL_WINDOW_HEIGHT = 600
CROSSHAIR_COLOR = (0.2, 1.0, 0.2, 1.0) # Syphon Filter green RGBA
# Ghost settings
GHOST_LIFETIME = 0.5 # seconds before a ghost fully fades
GHOST_SPAWN_INTERVAL = 0.1 # seconds between ghost spawns
MAX_GHOSTS = 50 # cap total ghosts in list
MAX_GHOST_DISTANCE = 150 # pixels: only draw ghosts within this distance
# Crosshair geometry (all in pixels)
CENTER_HALF = 5 # half-length of central crosshair
BOX_GAP = 8 # gap between center cross and box
BOX_EXT = 30 # half-size of outer box from edge of gap
LINE_THICKNESS = 2
# Dynamic state
mouse_x, mouse_y = INITIAL_WINDOW_WIDTH/2, INITIAL_WINDOW_HEIGHT/2
ghosts = [] # list of (x, y, timestamp)
window_width = INITIAL_WINDOW_WIDTH
window_height = INITIAL_WINDOW_HEIGHT
last_spawn_time = 0.0
def mouse_move_callback(window, xpos, ypos):
global mouse_x, mouse_y
mouse_x = xpos
mouse_y = window_height - ypos
def window_size_callback(window, width, height):
global window_width, window_height
window_width, window_height = width, height
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def init_window():
if not glfw.init():
raise Exception("glfw cannot be initialized!")
glfw.window_hint(glfw.RESIZABLE, glfw.TRUE)
window = glfw.create_window(
INITIAL_WINDOW_WIDTH,
INITIAL_WINDOW_HEIGHT,
"Crosshair Ghost Trails",
None, None
)
if not window:
glfw.terminate()
raise Exception("glfw window cannot be created!")
glfw.make_context_current(window)
glfw.set_cursor_pos_callback(window, mouse_move_callback)
glfw.set_window_size_callback(window, window_size_callback)
fb_w, fb_h = glfw.get_framebuffer_size(window)
window_size_callback(window, fb_w, fb_h)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
return window
def draw_crosshair(x, y, color):
"""Draws a Syphon Filter style box crosshair centered at (x,y)."""
r, g, b, a = color
glColor4f(r, g, b, a)
glLineWidth(LINE_THICKNESS)
half_center = CENTER_HALF
half_box = CENTER_HALF + BOX_GAP + BOX_EXT
gap_extent = CENTER_HALF + BOX_GAP
# central crosshair
glBegin(GL_LINES)
glVertex2f(x - half_center, y)
glVertex2f(x + half_center, y)
glVertex2f(x, y - half_center)
glVertex2f(x, y + half_center)
glEnd()
# outer box segments
glBegin(GL_LINES)
# top horizontal
glVertex2f(x - half_box, y + half_box)
glVertex2f(x + half_box, y + half_box)
# bottom horizontal
glVertex2f(x - half_box, y - half_box)
glVertex2f(x + half_box, y - half_box)
# left vertical (two segments leaving gap at middle)
glVertex2f(x - half_box, y + half_box)
glVertex2f(x - half_box, y + gap_extent)
glVertex2f(x - half_box, y - gap_extent)
glVertex2f(x - half_box, y - half_box)
# right vertical
glVertex2f(x + half_box, y + half_box)
glVertex2f(x + half_box, y + gap_extent)
glVertex2f(x + half_box, y - gap_extent)
glVertex2f(x + half_box, y - half_box)
glEnd()
def main():
global last_spawn_time
window = init_window()
while not glfw.window_should_close(window):
glClear(GL_COLOR_BUFFER_BIT)
now = time.time()
# spawn a new ghost at live position, controlled by interval
if now - last_spawn_time >= GHOST_SPAWN_INTERVAL:
ghosts.append((mouse_x, mouse_y, now))
last_spawn_time = now
if len(ghosts) > MAX_GHOSTS:
ghosts.pop(0)
# draw and prune ghosts
alive = []
max_dist_sq = MAX_GHOST_DISTANCE * MAX_GHOST_DISTANCE
for gx, gy, ts in ghosts:
age = now - ts
if age < GHOST_LIFETIME:
dx = gx - mouse_x
dy = gy - mouse_y
if dx*dx + dy*dy <= max_dist_sq:
alpha = a = CROSSHAIR_COLOR[3] * (1 - age / GHOST_LIFETIME)
draw_crosshair(gx, gy,
(CROSSHAIR_COLOR[0],
CROSSHAIR_COLOR[1],
CROSSHAIR_COLOR[2],
alpha))
alive.append((gx, gy, ts))
ghosts[:] = alive
# draw live crosshair on top
draw_crosshair(mouse_x, mouse_y, CROSSHAIR_COLOR)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.terminate()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment