dkl9 commited on 2025-177 00:03:49
Showing 8 changed files, with 46 additions and 66 deletions.
| ... | ... |
@@ -18,7 +18,7 @@ class Entity: |
| 18 | 18 |
|
| 19 | 19 |
def norm_list(self): |
| 20 | 20 |
l = [] |
| 21 |
- if self.draw_mode == GL_TRIANGLE_STRIP: |
|
| 21 |
+ if self.draw_mode == GL_TRIANGLE_STRIP or self.draw_mode == GL_TRIANGLE_FAN: |
|
| 22 | 22 |
l.append(norm_tri(self.verts[:3])) |
| 23 | 23 |
for i in range(1, len(self.verts) - 1): |
| 24 | 24 |
l.append(norm_tri(self.verts[i - 1:i + 2])) |
| ... | ... |
@@ -60,7 +60,7 @@ class Entity: |
| 60 | 60 |
]) @ self.orient |
| 61 | 61 |
|
| 62 | 62 |
def click(self, button, face, hand=1): |
| 63 |
- self.onclick(self, button, face, hand) |
|
| 63 |
+ return self.onclick(self, button, face, hand) |
|
| 64 | 64 |
|
| 65 | 65 |
def raycast(self, ro, rd): |
| 66 | 66 |
if self.hud or self.draw_mode == GL_LINES: |
| ... | ... |
@@ -1,51 +0,0 @@ |
| 1 |
-from OpenGL.GL import * |
|
| 2 |
-from OpenGL.GLU import * |
|
| 3 |
-from OpenGL.GLUT import * |
|
| 4 |
-import sys |
|
| 5 |
-import time |
|
| 6 |
- |
|
| 7 |
-lf = time.time() |
|
| 8 |
-fc = 0 |
|
| 9 |
- |
|
| 10 |
-def reshape(width, height): |
|
| 11 |
- glViewport(0, 0, width, height) |
|
| 12 |
- glMatrixMode(GL_PROJECTION) |
|
| 13 |
- glLoadIdentity() |
|
| 14 |
- gluPerspective(45, width / float(height or 1), 1, 50) |
|
| 15 |
- glMatrixMode(GL_MODELVIEW) |
|
| 16 |
- |
|
| 17 |
-def draw_cube(): |
|
| 18 |
- glutWireCube(1) |
|
| 19 |
- |
|
| 20 |
-def display(): |
|
| 21 |
- global lf, fc |
|
| 22 |
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
|
| 23 |
- glLoadIdentity() |
|
| 24 |
- glTranslatef(0, 0, -5) |
|
| 25 |
- glRotatef((60 * time.time()) % 360, 2, 1, 0) |
|
| 26 |
- draw_cube() |
|
| 27 |
- glutSwapBuffers() |
|
| 28 |
- fc += 1 |
|
| 29 |
- now = time.time() |
|
| 30 |
- if now - lf >= 1.0: |
|
| 31 |
- print(f"{fc} FPS")
|
|
| 32 |
- fc = 0 |
|
| 33 |
- lf = now |
|
| 34 |
- |
|
| 35 |
-def keyboard(key, x, y): |
|
| 36 |
- if key == b'\x1b': # ESC |
|
| 37 |
- glutLeaveMainLoop() |
|
| 38 |
- |
|
| 39 |
-glutInit(sys.argv) |
|
| 40 |
-glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) |
|
| 41 |
-glutInitWindowSize(500, 500) |
|
| 42 |
-glutInitWindowPosition(100, 100) |
|
| 43 |
-glutCreateWindow("PyOpenGL Cube")
|
|
| 44 |
-glEnable(GL_DEPTH_TEST) |
|
| 45 |
- |
|
| 46 |
-glutDisplayFunc(display) |
|
| 47 |
-glutIdleFunc(display) |
|
| 48 |
-glutReshapeFunc(reshape) |
|
| 49 |
-glutKeyboardFunc(keyboard) |
|
| 50 |
- |
|
| 51 |
-glutMainLoop() |
| ... | ... |
@@ -8,6 +8,8 @@ VOXEL_TYPE = np.uint8 |
| 8 | 8 |
VERTEX_ATTRS = ["vec3 position", "vec4 col", "vec3 normal", "vec4 refls"] |
| 9 | 9 |
UNIFORMS = {"MVP": ["vert", "mat4", None], "lightPos": ["frag", "vec4", None], "camPos": ["frag", "vec3", None]}
|
| 10 | 10 |
|
| 11 |
+LIGHT_POS = [5, 30, 10] |
|
| 12 |
+GRAVITY = 1 |
|
| 11 | 13 |
VIEW_DIST = 30 |
| 12 | 14 |
FPS = 60 |
| 13 | 15 |
ARROWS = [pygame.K_RIGHT, pygame.K_LEFT, pygame.K_SPACE, pygame.K_LSHIFT, pygame.K_UP, pygame.K_DOWN] |
| ... | ... |
@@ -5,6 +5,7 @@ from mapgen import MapGen |
| 5 | 5 |
from mesh import SquareMesh |
| 6 | 6 |
from player import Player |
| 7 | 7 |
from region import WorldRegion |
| 8 |
+import os |
|
| 8 | 9 |
|
| 9 | 10 |
VS = f""" |
| 10 | 11 |
#version 120 |
| ... | ... |
@@ -49,7 +50,7 @@ def in_view(wr, cam): |
| 49 | 50 |
|
| 50 | 51 |
def main(): |
| 51 | 52 |
pygame.init() |
| 52 |
- pygame.display.set_mode((640, 480), pygame.DOUBLEBUF | pygame.OPENGL | pygame.FULLSCREEN | pygame.SCALED, vsync=1) |
|
| 53 |
+ pygame.display.set_mode((640, 480), pygame.DOUBLEBUF | pygame.OPENGL | (pygame.FULLSCREEN | pygame.SCALED if os.environ.get("FULLSCREEN") else pygame.RESIZABLE), vsync=1)
|
|
| 53 | 54 |
pygame.event.set_allowed([pygame.KEYDOWN, pygame.KEYUP, pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION, pygame.QUIT, pygame.WINDOWRESIZED, pygame.WINDOWSIZECHANGED]) |
| 54 | 55 |
pygame.display.set_caption("Voxels")
|
| 55 | 56 |
sp = shaders.compileProgram( |
| ... | ... |
@@ -63,7 +64,7 @@ def main(): |
| 63 | 64 |
glEnable(GL_BLEND) |
| 64 | 65 |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) |
| 65 | 66 |
glClearColor(0.1, 0.1, 0.1, 1.0) |
| 66 |
- glUniform4fv(UNIFORMS["lightPos"][2], 1, vec([5, 30, 10, 100])) |
|
| 67 |
+ glUniform4fv(UNIFORMS["lightPos"][2], 1, vec([*LIGHT_POS, 100])) |
|
| 67 | 68 |
mg = build_scene() |
| 68 | 69 |
clock = pygame.time.Clock() |
| 69 | 70 |
cam = Player(speed=6/FPS) |
| ... | ... |
@@ -38,8 +38,8 @@ class SquareMesh(entity.Entity): |
| 38 | 38 |
case 1: |
| 39 | 39 |
return (vec([*np.add(0.5, axis2offset(axis, 0.5)), 1.0]), vec([1.0, 0.0, 0.1, 128.0])) |
| 40 | 40 |
case 2: |
| 41 |
- top = (vec([0.5, 0.5, 1.0, 1.0]), vec([1.0, 0.0, 0.0, 1.0])) |
|
| 42 |
- bottom = (vec([0.0, 0.0, 0.5, 1.0]), vec([1.0, 0.0, 0.0, 1.0])) |
|
| 41 |
+ top = (vec([0.2, 0.2, 1.0, 1.0]), vec([1.0, 0.0, 0.0, 1.0])) |
|
| 42 |
+ bottom = (vec([0.0, 0.0, 0.2, 1.0]), vec([1.0, 0.0, 0.0, 1.0])) |
|
| 43 | 43 |
match axis: |
| 44 | 44 |
case 2: |
| 45 | 45 |
return top |
| ... | ... |
@@ -58,7 +58,7 @@ class SquareMesh(entity.Entity): |
| 58 | 58 |
case -2: |
| 59 | 59 |
return bottom |
| 60 | 60 |
case a: |
| 61 |
- return bottom if corner & (2 >> ((a % 4) // 2)) else top |
|
| 61 |
+ return bottom if corner & (1 << ((a % 4) // 2)) else top |
|
| 62 | 62 |
return |
| 63 | 63 |
case 5: |
| 64 | 64 |
core = (vec([1.0, 1.0, 0.8, 1.0]), vec([0.4, 1.6, 0.0, 1.0])) |
| ... | ... |
@@ -16,12 +16,26 @@ class Player(interactive.InteractiveCamera): |
| 16 | 16 |
roll_vec3(offset, 1) |
| 17 | 17 |
for s in range(2): |
| 18 | 18 |
self.hud["skybox"].add_sq((d + 1) * (-1) ** s, 2 * VIEW_DIST, (-1) ** s * vec(offset), 2) |
| 19 |
+ self.hud["sun"] = entity.Entity( |
|
| 20 |
+ [[0.0, 0.0, 0.0], *[[2 * np.cos(2 * np.pi * k), 0, 2 * np.sin(2 * np.pi * k)] for k in np.arange(0, 1.01, 0.05)]], |
|
| 21 |
+ [1.0, 1.0, 0.8, 1.0], normalise(LIGHT_POS) * VIEW_DIST, mode=GL_TRIANGLE_FAN |
|
| 22 |
+ ) |
|
| 23 |
+ h = mesh.SquareMesh(hud=True) |
|
| 24 |
+ self.hud["hand"] = h |
|
| 25 |
+ h.add_sq(1, 1, [0.5, 0, 0], 1) |
|
| 26 |
+ h.add_sq(2, 1, [0, 0.5, 0], 1) |
|
| 27 |
+ h.add_sq(3, 1, [0, 0, 0.5], 1) |
|
| 28 |
+ h.pos = [0.8, -0.8, 0.5] |
|
| 29 |
+ h.rotate(2, [0, 1, 0]) |
|
| 30 |
+ h.rotate(-0.1, [1, 0, 0]) |
|
| 31 |
+ h.orient[:3, :3] *= 0.2 |
|
| 19 | 32 |
self.hud["shl"] = mesh.SquareMesh() |
| 20 | 33 |
self.hud["shl"].draw_mode = GL_LINE_STRIP |
| 21 |
- self.hud["shl"].add_sq(2, 0.96, [0, 0, 0], 2) |
|
| 34 |
+ self.hud["shl"].add_sq(-2, 0.96, [0, 0, 0], 2) |
|
| 22 | 35 |
self.hud["shl"].verts[:] = self.hud["shl"].verts[[0, 1, 3, 2, 0, 3]] |
| 23 | 36 |
self.hand = 1 |
| 24 | 37 |
self.collides = True |
| 38 |
+ self.falls = True |
|
| 25 | 39 |
|
| 26 | 40 |
def update_motion(self, pk, mg): |
| 27 | 41 |
netv = [pk[a] - pk[b] for (a, b) in zip(ARROWS[::2], ARROWS[1::2])] |
| ... | ... |
@@ -29,10 +43,20 @@ class Player(interactive.InteractiveCamera): |
| 29 | 43 |
for i in range(len(netv)): |
| 30 | 44 |
for s in range(2): |
| 31 | 45 |
o = (-1) ** s * self.vdof()[i] |
| 32 |
- if mg.voxel_at(self.pos + o): |
|
| 46 |
+ va = mg.voxel_at(self.pos + o) |
|
| 47 |
+ if va: |
|
| 33 | 48 |
netv[i] = (max if s else min)(netv[i], 0) |
| 49 |
+ elif self.falls and i == 1 and s == 1: |
|
| 50 |
+ netv[i] = self.rv[i] - GRAVITY / FPS |
|
| 34 | 51 |
self.rv = vec(netv) |
| 35 | 52 |
|
| 53 |
+ def set_hand(self, nh): |
|
| 54 |
+ nh = int(nh) |
|
| 55 |
+ self.hand = nh |
|
| 56 |
+ self.hud["hand"].faces = [(a, self.hand) for (a, _) in self.hud["hand"].faces] |
|
| 57 |
+ for i in range(1, 4, 2): |
|
| 58 |
+ update_attr(self.hud["hand"], i) |
|
| 59 |
+ |
|
| 36 | 60 |
def handle_event(self, ev, mg, scene): |
| 37 | 61 |
super().handle_event(ev, mg) |
| 38 | 62 |
match ev.type: |
| ... | ... |
@@ -40,15 +64,19 @@ class Player(interactive.InteractiveCamera): |
| 40 | 64 |
if ev.unicode == "\x1b": |
| 41 | 65 |
self.set_focus(False) |
| 42 | 66 |
elif "1" <= ev.unicode <= "9": |
| 43 |
- self.hand = int(ev.unicode) |
|
| 67 |
+ self.set_hand(int(ev.unicode)) |
|
| 44 | 68 |
elif ev.unicode == "n": |
| 45 | 69 |
self.collides = not self.collides |
| 70 |
+ elif ev.unicode == "f": |
|
| 71 |
+ self.falls = not self.falls |
|
| 46 | 72 |
case pygame.MOUSEBUTTONUP if ev.button == 1: |
| 47 | 73 |
self.set_focus(True) |
| 48 | 74 |
case pygame.MOUSEBUTTONDOWN if self.get_focus(): |
| 49 | 75 |
t, n = self.target(scene) |
| 50 | 76 |
if t: |
| 51 |
- t.click(ev.button, n, self.hand) |
|
| 77 |
+ cr = t.click(ev.button, n, self.hand) |
|
| 78 |
+ if cr is not None: |
|
| 79 |
+ cr(self) |
|
| 52 | 80 |
|
| 53 | 81 |
def draw_hud(self, wrs, perf): |
| 54 | 82 |
self.hud["skybox"].pos = self.pos |
| ... | ... |
@@ -57,8 +57,8 @@ class WorldRegion(mesh.SquareMesh): |
| 57 | 57 |
bp, bc = bool(prev), bool(curr) |
| 58 | 58 |
if bp ^ bc: |
| 59 | 59 |
sq = vec([ |
| 60 |
- [0, 1, 1], [0, -1, 1], [0, 1, -1], |
|
| 61 |
- [0, -1, -1], [0, 1, -1], [0, -1, 1] |
|
| 60 |
+ [0, 1, 1], [0, 1, -1], [0, -1, 1], |
|
| 61 |
+ [0, -1, -1], [0, -1, 1], [0, 1, -1] |
|
| 62 | 62 |
]) |
| 63 | 63 |
sq /= 2 |
| 64 | 64 |
if bp: |
| ... | ... |
@@ -15,7 +15,7 @@ class WorldHolder(): |
| 15 | 15 |
self.regions[pos] = wr |
| 16 | 16 |
self.world_natural(wr) |
| 17 | 17 |
wr.remesh() |
| 18 |
- wr.onclick = lambda s, b, c, h: self.click_region(s, b, c, h) |
|
| 18 |
+ wr.onclick = (lambda s, b, c, h: self.click_region(s, b, c, h)) |
|
| 19 | 19 |
return wr |
| 20 | 20 |
|
| 21 | 21 |
def voxel_at(self, pos, vt=None): |
| ... | ... |
@@ -36,7 +36,7 @@ class WorldHolder(): |
| 36 | 36 |
case 1: |
| 37 | 37 |
wr.set_voxel(coords[1]) |
| 38 | 38 |
case 2: |
| 39 |
- print(f"coords {coords}")
|
|
| 39 |
+ return (lambda pl: pl.set_hand(wr.grid[*coords[1]])) |
|
| 40 | 40 |
case 3: |
| 41 | 41 |
offset = axis2offset(coords[0]) |
| 42 | 42 |
p = wr.set_voxel(coords[1] + offset, hand) |
| 43 | 43 |