Better crosshair and FPS indicator
dkl9

dkl9 commited on 2025-172 06:27:28
Showing 4 changed files, with 28 additions and 13 deletions.

... ...
@@ -55,7 +55,9 @@ class Camera:
55 55
 
56 56
     def mvp(self, ent):
57 57
         if ent.hud:
58
-            return ent.translate() @ ent.orient
58
+            am = np.identity(4, dtype=FLOAT)
59
+            am[0, 0] = 1 / self.aspect
60
+            return ent.translate() @ am @ ent.orient
59 61
         else:
60 62
             return self.persp_mat() @ self.view_mat() @ ent.translate() @ ent.orient
61 63
 
... ...
@@ -1,4 +1,5 @@
1 1
 from OpenGL.GL import *
2
+import itertools
2 3
 import numpy as np
3 4
 import pygame
4 5
 
... ...
@@ -8,6 +9,10 @@ VOXEL_TYPE = np.uint8
8 9
 def vec(l):
9 10
     return np.array(l, dtype=FLOAT)
10 11
 
12
+RED = vec([1.0, 0.0, 0.0, 1.0])
13
+YELLOW = vec([1.0, 1.0, 0.0, 1.0])
14
+GREEN = vec([0.0, 1.0, 0.0, 1.0])
15
+
11 16
 def normalize(v):
12 17
     norm = np.linalg.norm(v)
13 18
     return v / norm if norm > 0 else v
... ...
@@ -24,6 +24,8 @@ void main() {
24 24
 }
25 25
 """
26 26
 
27
+FPS = 240
28
+
27 29
 def click_mesh(self, button, ind):
28 30
     a, p = self.faces[ind]
29 31
     match button:
... ...
@@ -44,11 +46,7 @@ def build_scene():
44 46
             for k in range(2):
45 47
                 box.add_voxel((-i % 16, -j % 16, -k % 16))
46 48
     box.onclick = click_mesh
47
-    cross = Entity(
48
-        [[-0.05, 0.0, 0.0], [0.05, 0.0, 0.0], [0.0, -0.05, 0.0], [0.0, 0.05, 0.0]],
49
-        [0.9, 0.9, 0.9, 1.0], [0.0, 0.0, 0.0], mode=GL_LINES, hud=True
50
-    )
51
-    return [box, cross]
49
+    return [box]
52 50
 
53 51
 def main():
54 52
     pygame.init()
... ...
@@ -66,21 +64,20 @@ def main():
66 64
     clock = pygame.time.Clock()
67 65
     cam = Player()
68 66
     cam.set_focus(True)
69
-    n = 0
70 67
     while True:
71
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
72
-        for ent in scene:
73
-            cam.draw(ent, loc_mvp)
74 68
         for ev in pygame.event.get():
75 69
             if ev.type == pygame.QUIT or ev.type == pygame.KEYUP and ev.unicode == "q":
76 70
                 pygame.quit()
77 71
                 return
78 72
             cam.handle_event(ev, scene)
79 73
         cam.update_pos()
74
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
75
+        perf = clock.get_fps() / FPS
76
+        cam.hud["fps"].col = GREEN if 0.9 < perf < 1.1 else YELLOW if perf > 0.5 else RED
77
+        cam.hud["fps"].update_attr(1)
78
+        for ent in itertools.chain(scene, cam.hud.values()):
79
+            cam.draw(ent, loc_mvp)
80 80
         pygame.display.flip()
81 81
         clock.tick(240)
82
-        n += 1
83
-        if n % 120 == 0:
84
-            pygame.display.set_caption(f"fps {round(clock.get_fps())}")
85 82
 
86 83
 main()
... ...
@@ -1,5 +1,6 @@
1 1
 from libs import *
2 2
 import camera
3
+import entity
3 4
 
4 5
 ARROWS = [pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT, pygame.K_SPACE, pygame.K_LSHIFT]
5 6
 
... ...
@@ -13,6 +14,16 @@ class Player(camera.Camera):
13 14
         self.sensitivity = kwargs.get("sensitivity", 0.005)
14 15
         self.rv = vec([0, 0, 0])
15 16
         self.speed = kwargs.get("speed", 0.05)
17
+        self.hud = {
18
+            "crosshair": entity.Entity(
19
+                [[-0.03, 0.0, 0.0], [0.03, 0.0, 0.0], [0.0, -0.03, 0.0], [0.0, 0.03, 0.0]],
20
+                [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0], mode=GL_LINES, hud=True
21
+            ),
22
+            "fps": entity.Entity(
23
+                [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0], [0.0, -0.1, 0.0], [0.1, -0.1, 0.0]],
24
+                YELLOW, [-1.0, 1.0, 0.0], mode=GL_TRIANGLE_STRIP, hud=True
25
+            ),
26
+        }
16 27
 
17 28
     def set_focus(self, f): 
18 29
         pygame.event.set_grab(f)
19 30