import my3dengine as m3d from OpenGL.GL import * import time import numpy as np class Game: def __init__(self): self.WIDTH, self.HEIGHT = m3d.get_fullscreen() self.window = m3d.Window("3D Game", self.WIDTH, self.HEIGHT) self.keys = m3d.Key self.escape_was_pressed = False self.sources = [ m3d.AudioSource(position=[0, 0, 3], sound_path="assets/dark-atmosphere-background-009-312380.mp3", emit_radius=5, volume=1.0, loop=False, fade_duration=1.0), ] # FPS counter self.last_fps_time = time.time() self.frames = 0 self.camera = m3d.Camera( position=(0, 0, 3), target=(0, 0, 0), up=(0, 1, 0), fov=60, aspect=self.WIDTH / self.HEIGHT, ) self.listener = m3d.AudioListener(self.camera.position) self.ui = m3d.UI(self.WIDTH, self.HEIGHT) self.meshes = [ m3d.Mesh.cube(), m3d.Mesh.sphere(), m3d.Mesh.capsule(), m3d.Mesh.cube(), m3d.Mesh.plane(), m3d.Mesh.from_obj("assets/untitled.obj"), ] # WODA self.water = m3d.Mesh.water( size=20.0, resolution=64, # 🧠 Mniejsze resolution = lepsze FPS wave_speed=0.01, wave_height=0.5, wave_scale=(0.4, 0.6), second_wave=True, color=(0.0, 0.4, 0.8), backface=True ) self.water.set_position(15, 0, 15) self.water.set_texture("assets/water.png") self.water.set_uv_transform((10, 10), (0, 0)) # Pozycje self.meshes[0].set_position(0, 0, 0) self.meshes[1].set_position(0, 0, 5) self.meshes[2].set_position(2, 0, 0) self.meshes[3].set_position(-4, 0, 0) self.meshes[4].set_position(0, -4, 0) self.meshes[5].set_position(-8, 0, 0) # Skale self.meshes[2].scale_uniform(2) self.meshes[3].set_scale(1, 0.2, 1) self.meshes[4].scale_uniform(15) self.meshes[5].scale_uniform(0.5) # Tekstury for i in range(6): self.meshes[i].set_texture("assets/bricksx64.png") # UV self.meshes[5].set_uv_transform(tiling=(10, 10), offset=(0.1, 0.1)) self.meshes[4].set_uv_transform(tiling=(10, 10), offset=(0.1, 0.1)) self.meshes[1].set_uv_transform(tiling=(5, 5), offset=(0.1, 0.1)) self.meshes[2].set_uv_transform(tiling=(5, 5), offset=(0.1, 0.1)) # OpenGL ustawienia glEnable(GL_DEPTH_TEST) glEnable(GL_CULL_FACE) glCullFace(GL_BACK) def update(self, dt, window): self.camera.handle_input(dt, window) glViewport(0, 0, self.WIDTH, self.HEIGHT) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self.listener.position[:] = self.camera.position cam_pos = self.camera.position cam_dir = m3d.normalize(self.camera.target - cam_pos) view_proj = self.camera.view_proj_matrix m3d.update_audio_system(self.listener, self.sources) if ( self.water.is_in_fov(cam_pos, cam_dir, self.camera.fov) and np.linalg.norm(self.water.position - cam_pos) < 150 ): self.water.update_water() self.water.shader.use() self.camera.set_uniforms(self.water.shader) self.water.draw( cam_pos=cam_pos, cam_dir=cam_dir, fov_deg=self.camera.fov, view_proj_matrix=view_proj ) # Rysuj inne meshe for mesh in self.meshes: if ( not mesh.is_in_fov(cam_pos, cam_dir, self.camera.fov) or np.linalg.norm(mesh.position - cam_pos) > 150 ): continue mesh.shader.use() self.camera.set_uniforms(mesh.shader) mesh.draw( cam_pos=cam_pos, cam_dir=cam_dir, fov_deg=self.camera.fov, view_proj_matrix=view_proj, debug=False ) # FPS tracking self.frames += 1 current_time = time.time() if current_time - self.last_fps_time >= 1.0: print(f"FPS: {self.frames}") self.frames = 0 self.last_fps_time = current_time def run(self): try: m3d.init() self.window.run(self.update) finally: self.water.destroy() for mesh in self.meshes: mesh.destroy() if __name__ == "__main__": app = Game() app.run()