from OpenGL.GL import shaders from libs import * from player import Player from entity import Entity from mesh import SquareMesh VS = """ #version 120 attribute vec3 position; attribute vec4 colIn; varying vec4 colOut; uniform mat4 MVP; void main() { gl_Position = MVP * vec4(position, 1.0); colOut = colIn; } """ FS = """ #version 120 varying vec4 colOut; void main() { gl_FragColor = colOut; } """ WORLD_SIZE = 8 world = np.zeros((WORLD_SIZE, WORLD_SIZE, WORLD_SIZE), dtype=np.uint8) for i in range(2): for j in range(2): for k in range(2): world[-i % WORLD_SIZE, -j % WORLD_SIZE, -k % WORLD_SIZE] = 1 cubes = [] def place_voxel(mesh, ind): a = mesh.faces[ind][0] p = cubes[ind // 12] + np.sign(a) * np.roll([0, 0, 1], abs(a)) world[p] = 1 mesh.add_cube(1, p) cubes.append(p) mesh.update_attr(0) mesh.update_attr(1) def break_voxel(mesh, ind): p = cubes[ind // 12] world[p] = 0 mesh.del_cube((ind // 12) * 12) del cubes[ind // 12] def click_mesh(self, button, ind): if button == 1: break_voxel(self, ind) elif button == 3: place_voxel(self, ind) def build_scene(): box = SquareMesh() for i in range(world.shape[0]): for j in range(world.shape[1]): for k in range(world.shape[2]): if world[i, j, k] == 1: box.add_cube(1, [i, j, k]) cubes.append(np.array((i, j, k), dtype=np.uint8)) box.onclick = click_mesh return [box] def main(): pygame.init() pygame.display.set_mode((640, 480), pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE) pygame.display.set_caption("OpenGL") sp = shaders.compileProgram( shaders.compileShader(VS, GL_VERTEX_SHADER), shaders.compileShader(FS, GL_FRAGMENT_SHADER) ) glUseProgram(sp) glEnable(GL_DEPTH_TEST) loc_mvp = glGetUniformLocation(sp, "MVP") glClearColor(0.1, 0.1, 0.1, 1.0) scene = build_scene() clock = pygame.time.Clock() cam = Player() cam.set_focus(True) n = 0 while True: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) for ent in scene: cam.draw(ent, loc_mvp) for ev in pygame.event.get(): if ev.type == pygame.QUIT or ev.type == pygame.KEYUP and ev.unicode == "q": pygame.quit() return cam.handle_event(ev, scene) cam.update_pos() pygame.display.flip() clock.tick(240) n += 1 if n % 120 == 0: pygame.display.set_caption(f"fps {round(clock.get_fps())}") main()