def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp = self.loadWindoProperites() #open the window base.openMainWindow(props=wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused = base.win.getProperties().getForeground() self.window_x = base.win.getXSize() self.window_y = base.win.getYSize() self.window_minimized = base.win.getProperties().getMinimized() #filter manager, post process self.filters = Filters() #audio sound effects (sfx) + music self.audio = Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights = LightManager() #setup the user interface (gui+key/mouse bind) self.ui = UserInterface() #skybox self.sun_and_sky = Skybox(self.lights) #player (character) droid self.droid = PCDroid(self.ui) #some vars used later self.map_name = None self.loading_status = set() self.level_root = render.attachNewNode('level_root') self.level_root.hide() self.is_in_game = False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event', self.onClientExit) self.accept('window-event', self.onWindowEvent) self.accept('window-reset', self.onWindowReset) self.accept('client-mouselock', self.setMouseLock) self.accept('load-level', self.onLevelLoad) self.accept('loading-done', self.onLoadingDone) self.accept('reload-shaders', self.onShaderReload) self.accept('client-set-team', self.onTeamCahnge) self.accept('client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started')
def game(window: Window, ctx: Context): """Run game.""" # load assets in the default vao ctx.use_vao("default") entities = [] textbox = Text(ctx, [-0.25, 7, -9], "<score>") cam = GameCamera() player = Player() skybox = Skybox(ctx, "assets/skybox") # mainloop old_time = glfw.get_time() spawn_timer = 0.0 spawn_delay = 4.0 while window and player: hits = [0, 0, 0] new_time = glfw.get_time() dt = new_time - old_time cam.wobble(dt) cam.set_target_y(player.pos[1] * 0.2 + 5) skybox.rot[2] += dt * 0.01 spawn_timer += dt if spawn_timer > spawn_delay: # Spawn new Obstacle spawn_timer = 0.0 entities.append(Obstacle([0, 0, 200])) if spawn_delay > 0.8: spawn_delay -= dt * 0.1 for e in entities: e.update(dt, ctx, window) if e and abs(e.pos[2] - player.pos[2]) < 1.0: hits = list(map(max, zip(hits, e.hitogram))) entities = [e for e in entities if e] player.update(dt, ctx, window, hits) old_time = new_time # Render ctx.clear() ctx.use_vao("default") for entity in entities: entity.draw(ctx, cam) player.draw(ctx, cam) skybox.draw(ctx, cam) textbox.draw(ctx, cam) textbox.update( str(new_time)[:str(new_time).find(".") + 2] + f"\n hp{player.hp}") window.swap_buffers() ctx.clear() return str(new_time)[:str(new_time).find(".") + 2]
def loadGame(self): self.exitStartMenu() print("Loading game") self.state = 'Loading' if(self.debug == False): self.hide_cursor self.setLights() self.terrain.load() self.hud = Hud() self.hud.show() self.loadEntities() #positionate the camera if(self.debug == False): self.camera.lookAt(self.slime.model) # Load Skybox Skybox(self.render) #register events self.ydelta = 300 self.zdelta = 60 self.accept("wheel_up", self.camzoom,[True]) self.accept("wheel_down", self.camzoom,[False]) #register tasks self.task_mgr.add(self.mainLoop, "MainTask") if(self.debug == False): self.task_mgr.add(self.updateCamera, "CameraTask") self.startGame()
def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp=self.loadWindoProperites() #open the window base.openMainWindow(props = wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused=base.win.getProperties().getForeground() self.window_x=base.win.getXSize() self.window_y=base.win.getYSize() self.window_minimized=base.win.getProperties().getMinimized() #filter manager, post process self.filters=Filters() #audio sound effects (sfx) + music self.audio=Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights=LightManager() #setup the user interface (gui+key/mouse bind) self.ui=UserInterface() #skybox self.sun_and_sky=Skybox(self.lights) #player (character) droid self.droid=PCDroid(self.ui) #some vars used later self.map_name=None self.loading_status=set() self.level_root=render.attachNewNode('level_root') self.level_root.hide() self.is_in_game=False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event',self.onClientExit) self.accept( 'window-event', self.onWindowEvent) self.accept( 'window-reset', self.onWindowReset) self.accept( 'client-mouselock', self.setMouseLock) self.accept( 'load-level', self.onLevelLoad) self.accept( 'loading-done', self.onLoadingDone) self.accept( 'reload-shaders', self.onShaderReload) self.accept( 'client-set-team', self.onTeamCahnge) self.accept( 'client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started')
def load_new_level(self, level, areas=True): if self.in_intro: self.in_intro = False self.exclusive_mouse = True self.set_exclusive_mouse(self.exclusive_mouse) self.pop_handlers() self.push_handlers(self.camera.input_handler) self.current_level = level self.set_start_pos() self.level_batch = self.level_geometry.load_level(level) ## Reset camera position to the new start_pos. self.camera.position = self.start_pos self.camera.yaw = self.start_yaw self.camera.pitch = 0.0 if self.skybox_dict[level]: self.skybox = Skybox(self.skybox_dict[level], self.mario_graphics_dir) self.skybox.skybox_set_fov(self.fov) self.skybox_present = True else: self.skybox_present = False
def __init__(self, width=1000, height=1000, skybox=None): self.y_angle = 0 self.x_angle = 0 self.fill_modes = cycle([GL.GL_LINE, GL.GL_POINT, GL.GL_FILL]) # version hints: create GL window with >= OpenGL 3.3 and core profile glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL.GL_TRUE) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.window_hint(glfw.RESIZABLE, False) self.win = glfw.create_window(width, height, 'Viewer', None, None) # make win's OpenGL context current; no OpenGL calls can happen before glfw.make_context_current(self.win) # register event handl ers glfw.set_key_callback(self.win, self.on_key) self.trackball = GLFWTrackball(self.win) # useful message to check OpenGL renderer characteristics print( 'OpenGL', GL.glGetString(GL.GL_VERSION).decode() + ', GLSL', GL.glGetString(GL.GL_SHADING_LANGUAGE_VERSION).decode() + ', Renderer', GL.glGetString(GL.GL_RENDERER).decode()) # initialize GL by setting viewport and default render characteristics GL.glClearColor(0.1, 0.1, 0.1, 0.1) GL.glEnable(GL.GL_CULL_FACE) GL.glEnable(GL.GL_DEPTH_TEST) self.skybox = Skybox("skybox2.jpg") # initially empty list of object to draw self.drawables = []
def __init__( self , fov , ratio , near , far , skybox_img , duck_img ) : self.fov = fov self.far = far self.near = near self.ratio = ratio self.last_time = timer() self.water = Water( 128 ) self.box = Skybox( skybox_img ) self.duck = Mesh( 'data/duck.gpt' , duck_img , 'shad/anisotropic' ) self.path = BSpline( (-1,1) , (-1,1) ) self.light = np.array( (0,2,0) ) self.water.drop_rnd()
def __init__(self): if Window.__instance is None: Window.__instance = self super().__init__() self.bind = {} self.load_bind() self.option = {} self.load_option() self.properties() self.setFrameRateMeter(True) self.skybox = Skybox() self.accept(self.bind[Bind.EXIT.value], sys.exit) self.world = BulletWorld() self.world_node = None self.debug_node_path = None self.setup_world()
class Scene : def __init__( self , fov , ratio , near , far , skybox_img , duck_img ) : self.fov = fov self.far = far self.near = near self.ratio = ratio self.last_time = timer() self.water = Water( 128 ) self.box = Skybox( skybox_img ) self.duck = Mesh( 'data/duck.gpt' , duck_img , 'shad/anisotropic' ) self.path = BSpline( (-1,1) , (-1,1) ) self.light = np.array( (0,2,0) ) self.water.drop_rnd() def gfx_init( self ) : self.camera = Camera( ( 0 , 5 , 0 ) , ( 1 , 1 , 0 ) , ( 1 , 0 , 0 ) ) self._update_proj() self.water.gfx_init() self.box .gfx_init() self.duck .gfx_init() def draw( self ) : self.time = timer() dt = self.time - self.last_time glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.camera.look() self.box.draw() self.path.next( dt ) self.water.drop( *((self.path.value+1.0)*self.water.n/2.0) , force = np.linalg.norm(self.path.tangent)*25 ) self.water.step( dt * .5 ) self.water.draw( self.box.texture , self.camera.matrix ) self.duck.draw( self.path.value , self.path.tangent , self.light ) self.last_time = self.time def set_fov( self , fov ) : self.fov = fov self._update_proj() def set_near( self , near ) : self.near = near self._update_proj() def set_ratio( self , ratio ) : self.ratio = ratio self._update_proj() def set_screen_size( self , w , h ) : self.width = w self.height = h self.set_ratio( float(w)/float(h) ) def set_fov( self , fov ) : self.fov = fov self._update_proj() def set_near( self , near ) : self.near = near self._update_proj() def set_ratio( self , ratio ) : self.ratio = ratio self._update_proj() def set_screen_size( self , w , h ) : self.width = w self.height = h self.set_ratio( float(w)/float(h) ) def mouse_move( self , df ) : self.camera.rot( *map( lambda x : -x*.2 , df ) ) def key_pressed( self , mv ) : self.camera.move( *map( lambda x : x*.05 , mv ) ) def _update_proj( self ) : glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective( self.fov , self.ratio , self.near , self.far ) glMatrixMode(GL_MODELVIEW)
class GameWindow(pyglet.window.Window): """Main game class. Contains main game parameters as well as the level geometry, camera, level batch (for the drawing of levels and objects), and fps display.""" def __init__(self, mario_graphics_dir, fullscreen=False, resolution=None, y_inv=False, vsync=False, msaa=1, resizable=True, show_fps=False, font=None): self.mario_graphics_dir = mario_graphics_dir self.screenshot_dir = mario_graphics_dir / 'screenshots' os.makedirs(self.screenshot_dir, exist_ok=True) self.y_inv = y_inv self.fov = 45 self.font = font self.paused = False self.full_res = fullscreen self.resolution = resolution self.current_level = None self.mouse_sensitivity = 0.08 self.min_mouse_sensitivity = 0.01 self.max_mouse_sensitivity = 0.15143 ## Graphics setings self.wireframe = False self.load_textures = True self.load_skyboxes = True ## MSAA. config = self.get_config(msaa) ## Set screen resolution and window border type. self.max_x_res = pyglet.canvas.get_display().get_default_screen().width self.max_y_res = pyglet.canvas.get_display().get_default_screen( ).height self.set_resolution() border_style = self.get_border_style(fullscreen) ## Init pyglet window. super().__init__(self.x_res, self.y_res, "Mario 64", resizable=resizable, vsync=vsync, fullscreen=False, config=config, style=border_style) if fullscreen: self.set_location(0, 0) ## Set mouse. self.exclusive_mouse = False self.set_exclusive_mouse(self.exclusive_mouse) ## Set OpenGL state. self.set_opengl_state() ## Geometry self.level_geometry = Geometry(self.mario_graphics_dir) self.level_geometry.toggle_group_textures(self.load_textures) self.skybox_dict = { 'wdw': 'wdw', 'ttm': 'water', 'thi': 'water', 'ddd': 'water', 'hmc': None, 'bits': 'bits', 'ccm': 'ccm', 'pss': None, 'jrb': 'clouds', 'rr': 'cloud_floor', 'bitfs': 'bitfs', 'cotmc': None, 'bowser_1': 'bidw', 'wmotr': 'cloud_floor', 'ttc': None, 'lll': 'bitfs', 'totwc': 'cloud_floor', 'wf': 'cloud_floor', 'ssl': 'ssl', 'sa': 'cloud_floor', 'vcutm': None, 'bob': 'water', 'castle_courtyard': 'water', 'sl': 'ccm', 'bitdw': 'bidw', 'bbh': 'bbh', 'castle_inside': None, 'bowser_3': 'bits', 'bowser_2': 'bitfs', 'castle_grounds': 'water' } ## FPS Display self.show_fps = show_fps self.fps_display = pyglet.window.FPSDisplay(self) self.fps_display.update_period = 0.2 ## Camera self.start_area = None self.start_yaw = None self.start_pos = None self.draw_distance = 100000 self.camera = FirstPersonCamera(y_inv=self.y_inv) ## Create menus. self.register_menu_event_types() self.pause_menu = PauseMenu(self.x_res, self.y_res, self.width, self.height, self.wireframe, font=self.font) self.set_menu_handlers() ## Load intro. self.in_intro = True self.level_batch = self.load_intro() self.push_handlers(self.pause_menu) pyglet.clock.schedule(self.on_update) def set_resolution(self): if self.full_res: self.x_res = self.max_x_res self.y_res = self.max_y_res else: self.x_res, self.y_res = self.resolution if self.x_res > self.max_x_res: self.x_res = self.max_x_res if self.y_res > self.max_y_res: self.y_res = self.max_y_res def get_border_style(self, fullscreen): if fullscreen: border_style = pyglet.window.Window.WINDOW_STYLE_BORDERLESS else: border_style = pyglet.window.Window.WINDOW_STYLE_DEFAULT return border_style def get_config(self, msaa): if msaa > 1: screen = pyglet.canvas.get_display().get_default_screen() template = pyglet.gl.Config(sample_buffers=1, samples=msaa) try: config = screen.get_best_config(template) except: config = None else: config = None return config def set_opengl_state(self): ## Set global OpenGL state based on GameWindow attributes. if self.wireframe: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) else: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glEnable(GL_DEPTH_TEST) glDepthMask(GL_TRUE) material_reflectance = (ctypes.c_float * 4)(*(1.0, 1.0, 1.0, 1.0)) light_direction = (ctypes.c_float * 4)(*(1 / math.sqrt(3), 1 / math.sqrt(3), 1 / math.sqrt(3), 0.0)) glLightfv(GL_LIGHT0, GL_POSITION, light_direction) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material_reflectance) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) def set_start_pos(self): self.start_area, self.start_yaw, *self.start_pos = self.level_geometry.level_scripts[ self.current_level].mario_pos for i in range(3): self.start_pos[i] = -1 * self.start_pos[i] ## We'll load partially inside the floor if we don't add some height. But because the camera has negative coordinates, we actually subtract 300 to add 300 height. self.start_pos[1] -= 300 def load_intro(self): self.current_level = 'intro' level_batch = self.level_geometry.load_intro() self.camera.position = [0, 130, -2300] self.camera.yaw = 0.0 self.camera.pitch = 0.0 self.skybox_present = False return level_batch def load_new_level(self, level, areas=True): if self.in_intro: self.in_intro = False self.exclusive_mouse = True self.set_exclusive_mouse(self.exclusive_mouse) self.pop_handlers() self.push_handlers(self.camera.input_handler) self.current_level = level self.set_start_pos() self.level_batch = self.level_geometry.load_level(level) ## Reset camera position to the new start_pos. self.camera.position = self.start_pos self.camera.yaw = self.start_yaw self.camera.pitch = 0.0 if self.skybox_dict[level]: self.skybox = Skybox(self.skybox_dict[level], self.mario_graphics_dir) self.skybox.skybox_set_fov(self.fov) self.skybox_present = True else: self.skybox_present = False def on_mouse_press(self, x, y, button, modifiers): if button == pyglet.window.mouse.RIGHT: time_str = time.strftime("%Y_%m_%d_%H%M%S", time.localtime()) + '.png' buf = (GLubyte * (4 * self.width * self.height))(0) glReadPixels(0, 0, self.width, self.height, GL_RGBA, GL_UNSIGNED_BYTE, buf) with open(str((self.screenshot_dir / time_str).resolve()), 'wb') as f: f.write( util_math.write_png(bytearray(buf), self.width, self.height)) return True def on_key_press(self, symbol, modifiers): ## Pause/unpause the game. if symbol == pyglet.window.key.ESCAPE: self.pause_game() return True def on_resize(self, width, height): glViewport(0, 0, width, height) if hasattr(self, 'pause_menu'): self.pause_menu.on_screen_resize(width, height) def on_activate(self): self.set_exclusive_mouse(self.exclusive_mouse) def on_deactivate(self): self.set_exclusive_mouse(False) def on_draw(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ## Draw skybox first. if self.load_skyboxes: if self.skybox_present: self.skybox.update_and_draw(self.camera.yaw, self.camera.pitch) """ Set the scene based on the camera's pitch, yaw, and position. Applies transforms. We first rotate and then translate. Note that glRotatef( angle, x, y, z ) rotates by angle degrees around the vector ( x, y, z ). Since pitch is a rotation around the x-axis, we want to use ( 1, 0, 0 ). Since yaw is a rotation around the y-axis, we want to use ( 0, 1 , 0 ). Then we translate by the camera's position. Note that the camera's position is already the negative of its actual worldview position. Thus, we don't have to multiply by -1 when we're moving the world. Finally, we perform a 3D projection based on the fov and the resolution. """ glMatrixMode(GL_MODELVIEW) glLoadIdentity() glRotatef(self.camera.pitch, 1.0, 0.0, 0.0) glRotatef(self.camera.yaw, 0.0, 1.0, 0.0) glTranslatef(*self.camera.position) #print( self.camera.pitch, self.camera.yaw, self.camera.position ) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(self.fov, self.x_res / self.y_res, 10, self.draw_distance) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ## Draw the actual level. self.level_batch.draw() ## Draw the menu, if applicable. if self.paused or self.in_intro: self.pause_menu.draw() ## Draw the FPS display, if applicable. if self.show_fps: if self.wireframe: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) self.fps_display.draw() if self.wireframe: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) def on_update(self, dt): if not self.paused: self.camera.update(dt) def register_menu_event_types(self): ## Button Events Menu.register_event_type('exit_game') Menu.register_event_type('go_back') Menu.register_event_type('enter_submenu') LevelSelectMenu.register_event_type('load_new_level') OptionsMenu.register_event_type('toggle_skyboxes') OptionsMenu.register_event_type('toggle_wireframe') OptionsMenu.register_event_type('toggle_textures') OptionsMenu.register_event_type('toggle_fps') ## Slider Events OptionsMenu.register_event_type('set_fov') OptionsMenu.register_event_type('set_mouse_sensitivity') def set_menu_handlers(self): ## OptionsMenu Buttons self.pause_menu.options_menu.set_handler('toggle_skyboxes', self.toggle_skyboxes) self.pause_menu.options_menu.set_handler('toggle_wireframe', self.toggle_wireframe) self.pause_menu.options_menu.set_handler('toggle_textures', self.toggle_textures) self.pause_menu.options_menu.set_handler('toggle_fps', self.toggle_fps) self.pause_menu.options_menu.set_handler('go_back', self.pause_menu.go_back) ## OptionsMenu Sliders self.pause_menu.options_menu.set_handler('set_fov', self.set_fov) self.pause_menu.options_menu.set_handler('set_mouse_sensitivity', self.set_mouse_sensitivity) ## IntroMenu self.pause_menu.intro_menu.set_handler('exit_game', self.exit_game) self.pause_menu.intro_menu.set_handler('enter_submenu', self.pause_menu.enter_submenu) ## MainPauseMenu self.pause_menu.main_pause_menu.set_handler('exit_game', self.exit_game) self.pause_menu.main_pause_menu.set_handler( 'enter_submenu', self.pause_menu.enter_submenu) ## LevelSelectMenu self.pause_menu.level_select_menu.set_handler('load_new_level', self.load_new_level) self.pause_menu.level_select_menu.set_handler('go_back', self.pause_menu.go_back) self.pause_menu.level_select_menu.set_handler( 'enter_submenu', self.pause_menu.enter_submenu) self.pause_menu.level_select_menu_2.set_handler( 'load_new_level', self.load_new_level) self.pause_menu.level_select_menu_2.set_handler( 'go_back', self.pause_menu.go_back) self.pause_menu.level_select_menu_2.set_handler( 'enter_submenu', self.pause_menu.enter_submenu) def pause_game(self): if self.paused == True: self.paused = False self.exclusive_mouse = True self.set_exclusive_mouse(self.exclusive_mouse) ## Stop PauseMenu from receiving user input and instead send the input to the camera's input_handler. self.pop_handlers() self.push_handlers(self.camera.input_handler) self.pause_menu.current_menu = self.pause_menu.main_pause_menu self.pause_menu.menu_stack = [self.pause_menu.main_pause_menu] elif self.paused == False: if self.in_intro == True: self.in_intro = False self.exclusive_mouse = True self.set_exclusive_mouse(self.exclusive_mouse) self.pop_handlers() self.push_handlers(self.camera.input_handler) else: self.paused = True self.exclusive_mouse = False self.set_exclusive_mouse(self.exclusive_mouse) self.set_mouse_position(int(self.width / 2), int(self.height / 2)) self.pop_handlers() self.pause_menu.current_menu = self.pause_menu.main_pause_menu self.pause_menu.menu_stack = [self.pause_menu.main_pause_menu] self.push_handlers(self.pause_menu) def exit_game(self): self.on_close() def toggle_bool(self, attribute): if getattr(self, attribute) == False: setattr(self, attribute, True) else: setattr(self, attribute, False) def toggle_textures(self): self.toggle_bool('load_textures') self.level_geometry.toggle_group_textures(self.load_textures) def toggle_wireframe(self): if self.wireframe == False: self.wireframe = True glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glDisable(GL_DEPTH_TEST) glDisable(GL_ALPHA_TEST) glDisable(GL_BLEND) else: self.wireframe = False glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glEnable(GL_DEPTH_TEST) glEnable(GL_ALPHA_TEST) glEnable(GL_BLEND) self.pause_menu.set_wireframe(self.wireframe) def toggle_fps(self): self.toggle_bool('show_fps') def toggle_skyboxes(self): self.toggle_bool('load_skyboxes') def set_fov(self, fov): self.fov = fov if hasattr(self, 'skybox'): self.skybox.skybox_set_fov(self.fov) def percent_to_sensitivity(self, percent): """For user experience, the mouse sensitivity slider goes from 1 to 100. However, the actual mouse sensitivity used will vary from self.min_mouse_sensitivity (corresponds to 1) to self.max_mouse_sensitivity (corresponds to 100). This function takes a number between 1 and 100 inclusive and converts it to the actual mouse sensitivity used.""" return (((percent - 1) / 99) * (self.max_mouse_sensitivity - self.min_mouse_sensitivity) + self.min_mouse_sensitivity) def set_mouse_sensitivity(self, sensitivity): self.mouse_sensitivity = self.percent_to_sensitivity(sensitivity) self.camera.mouse_sensitivity = self.mouse_sensitivity
def main(): """ create a window, add scene objects, then run rendering loop """ viewer = Viewer() # environment node environment = Node() # set skybox shader = Shader("./shaders/skybox.vert", "./shaders/skybox.frag") environment.add(Skybox(shader, "./../assets/skybox/underwater/")) # set seabed shader = Shader("./shaders/texture.vert", "./shaders/texture.frag") src = './../assets/models/seabed/seabed.fbx' texFile = './../assets/models/seabed/seabed.jpg' seabed = Node(transform=scale(0.008, 0.01, 0.008) @ translate(0, -100, 0)) model = Model(src, shader) for m in model.load_phong_textured_skinned(texFile): seabed.add(m) # plants node plants = Node() # add seaweed shader = Shader("./shaders/texture.vert", "./shaders/texture.frag") src = './../assets/models/plants/seaweed/seaweed.fbx' texFile = './../assets/models/plants/seaweed/seaweed.png' seaweed = Node(transform=scale(2, 2, 2)) seaweed_density = 80 for i in range(seaweed_density): model = Model(src, shader) temp = Node( transform=translate(randrange(-50, 50), 3.5, randrange(-50, 50))) temp2 = Node( transform=translate(randrange(-20, 20), 15, randrange(-20, 0))) for m in model.load_textured(texFile): temp.add(m) if (i % 2 == 0): temp2.add(m) seaweed.add(temp) if (i % 2 == 0): seaweed.add(temp2) plants.add(seaweed) # add coral coral_count = 7 src = './../assets/models/plants/coral/coral.obj' texFile = './../assets/models/plants/coral/coral.jpg' coral = Node(transform=scale(0.1, 0.1, 0.1)) for i in range(coral_count): model = Model(src, shader) temp = Node(transform=translate(randrange(-300, 300), 350, randrange(-300, -100))) for m in model.load_textured(texFile): temp.add(m) coral.add(temp) plants.add(coral) seabed.add(plants) environment.add(seabed) # add fish models shader = Shader("./shaders/phong_texture_skinning.vert", "./shaders/phong_texture_skinning.frag") fishes = [] fish_count = 20 fish_no = randint(1, 24) src = './../assets/models/fish/%d/model.fbx' % fish_no texFile = './../assets/models/fish/%d/texture.png' % fish_no fish = Node(transform=scale(0.0001, 0.0001, 0.0001)) model = Model(src, shader) control_node = ControlNode(KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, 30) for m in model.load_phong_textured_skinned(texFile): control_node.add(m) fish.add(control_node) fishes.append(fish) for i in range(0, fish_count + 1): fish_no = randint(1, 24) src = './../assets/models/fish/%d/model.fbx' % fish_no texFile = './../assets/models/fish/%d/texture.png' % fish_no fish = Node(transform=scale(0.0001, 0.0001, 0.0001)) model = Model(src, shader) for m in model.load_phong_textured_skinned(texFile): fish.add(m) fishanimation = FishAnimation() animated_node = KeyFrameControlNode(fishanimation.get_translate_keys(), fishanimation.get_rotate_keys(), { 0: 1, 2: 1, 4: 1 }, loop=True) animated_node.add(fish) fishes.append(animated_node) for fish in fishes: environment.add(fish) scene = Node() scene.add(environment) viewer.add(scene) print( "Controls : Use the mouse to change the scene view. Press spacebar to restart the scene animations. Press W to see polygons and ESC or Q to Quit." ) # start rendering loop viewer.run()
class Client(DirectObject): """ Client class handels gui/input audio and rendering """ def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp = self.loadWindoProperites() #open the window base.openMainWindow(props=wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused = base.win.getProperties().getForeground() self.window_x = base.win.getXSize() self.window_y = base.win.getYSize() self.window_minimized = base.win.getProperties().getMinimized() #filter manager, post process self.filters = Filters() #audio sound effects (sfx) + music self.audio = Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights = LightManager() #setup the user interface (gui+key/mouse bind) self.ui = UserInterface() #skybox self.sun_and_sky = Skybox(self.lights) #player (character) droid self.droid = PCDroid(self.ui) #some vars used later self.map_name = None self.loading_status = set() self.level_root = render.attachNewNode('level_root') self.level_root.hide() self.is_in_game = False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event', self.onClientExit) self.accept('window-event', self.onWindowEvent) self.accept('window-reset', self.onWindowReset) self.accept('client-mouselock', self.setMouseLock) self.accept('load-level', self.onLevelLoad) self.accept('loading-done', self.onLoadingDone) self.accept('reload-shaders', self.onShaderReload) self.accept('client-set-team', self.onTeamCahnge) self.accept('client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started') def doSomeStuffTsk(self, task): x = deque(range(5000)) for i in xrange(999): random.shuffle(x) #print i, x[0] #print 'done' return task.done def setMouseLock(self, lock): wp = WindowProperties.getDefault() if lock: wp.setMouseMode(WindowProperties.M_confined) else: wp.setMouseMode(WindowProperties.M_relative) if not cfg['use-os-cursor']: wp.setCursorHidden(True) base.win.requestProperties(wp) def loadWindoProperites(self): #check if we can open a fullscreen window at the requested size if cfg['fullscreen']: mods = [] for mode in base.pipe.getDisplayInformation().getDisplayModes(): mods.append([mode.width, mode.height]) if list(cfg['win-size']) not in mods: cfg['fullscreen'] = False log.warning('Can not open fullscreen window at ' + str(cfg['win-size'])) #the window props should be set by this time, but make sure wp = WindowProperties.getDefault() try: wp.setUndecorated(cfg['undecorated']) wp.setFullscreen(cfg['fullscreen']) wp.setSize(cfg['win-size'][0], cfg['win-size'][1]) wp.setFixedSize(cfg['win-fixed-size']) except: log.warning('Failed to set window properties, Traceback:') for error in traceback.format_exc().splitlines()[1:]: log.warning(error.strip()) #these probably won't be in the config (?) wp.setOrigin(-2, -2) wp.setTitle('A4P') if not cfg['use-os-cursor']: wp.setCursorHidden(True) return wp def loadLevel(self, task): log.debug('Client loading level...') with open(path + 'maps/' + self.map_name + '.json') as f: values = json.load(f) #set the time self.sun_and_sky.setTime(values['level']['time']) #self.sun_and_sky.show() #load visible objects for id, obj in enumerate(values['objects']): mesh = loader.loadModel(path + obj['model']) mesh.reparentTo(self.level_root) mesh.setPosHpr(tuple(obj['pos']), tuple(obj['hpr'])) mesh.setTag( 'id_' + str(id), str(id) ) #we may need to find this mesh later to link it to a Bullet object for name, value in obj['shader_inputs'].items(): if isinstance(value, basestring): mesh.setShaderInput(str(name), loader.loadTexture(path + value)) if isinstance(value, float): mesh.setShaderInput(str(name), value) if isinstance(value, list): if len(value) == 2: mesh.setShaderInput(str(name), Vec2(value[0], value[1])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec3(value[0], value[1], value[2])) elif len(value) == 3: mesh.setShaderInput( str(name), Vec4(value[0], value[1], value[2], value[3])) mesh.setShader( Shader.load(Shader.SLGLSL, obj['vertex_shader'], obj['fragment_shader'])) #set the music self.audio.setMusic(values['level']['music']) #self.level_root.prepareScene(base.win.getGsg()) messenger.send('loading-done', ['client']) return task.done #events def onQuit(self): self.level_root.removeNode() self.level_root = render.attachNewNode('level_root') self.level_root.hide() if self.ui.is_zoomed: self.ui.zoom() self.sun_and_sky.hide() self.droid.disable() self.ui.unbindKeys() self.ui.in_game_menu.hide() self.ui.main_menu.show() self.audio.setMusic('background') self.loading_status = set() self.is_in_game = False messenger.send('world-clear-level') def onTeamCahnge(self, team): self.droid.setTeam(team) def onShaderReload(self): log.debug('Client: Reloading shaders') for mesh in self.level_root.getChildren(): shader = mesh.getShader() v_shader = shader.getFilename(Shader.ST_vertex) f_shader = shader.getFilename(Shader.ST_fragment) mesh.setShader(Shader.load(Shader.SLGLSL, v_shader, f_shader)) self.ui.main_menu.setShader(path + 'shaders/gui_v.glsl', path + 'shaders/gui_f.glsl') self.filters.reset() def onLoadingDone(self, target): log.debug(str(target) + ' loading done') self.loading_status.add(target) if self.loading_status == set(['client', 'server', 'world']): self.ui.main_menu.hide() self.level_root.show() self.sun_and_sky.show() self.ui.bindKeys() self.droid.node.setPos(render, 20, 0, 2) self.droid.lockCamera() self.droid.model.show() self.droid.rig.show() self.droid.gun.show() self.ui.in_game_menu.showElements('hud_') self.ui.hideSoftCursor() self.ui.is_main_menu = False self.is_in_game = True messenger.send('world-link-objects', [self.droid.node, 'pc_droid_node']) def onLevelLoad(self, map_name): self.map_name = map_name #we wait 1.0 sec for the loading animation to finish just in case if loading takes < 1.0 sec. taskMgr.doMethodLater(1.0, self.loadLevel, 'client_loadLevel_task', taskChain='background_chain') #taskMgr.add(self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #the client needs to load/setup: # -visible geometry # -enviroment (skybox/dome + sunlight diection + fog + ???) # -water plane # -unmovable (point)light sources # -unmovable vfx # -the player droid def onClientExit(self): log.debug('Client exit') self.audio.cleanup() app.exit() def onWindowReset(self): wp = self.loadWindoProperites() base.win.requestProperties(wp) def onWindowMinimize(self): self.window_minimized = base.win.getProperties().getMinimized() log.debug('window-event: Minimize is ' + str(self.window_minimized)) def onWindowFocus(self): self.window_focused = base.win.getProperties().getForeground() log.debug('window-event: Focus set to ' + str(self.window_focused)) if self.is_in_game: self.ui.in_game_menu.showMenu(self.window_focused) if not self.window_focused: self.ui.cursor_pos = (0, 0, 0) if cfg['pause-on-focus-lost']: if not self.window_focused: self.audio.pauseMusic() base.win.setActive(False) else: self.audio.resumeMusic() base.win.setActive(True) def onWindowResize(self): self.window_x = base.win.getXSize() self.window_y = base.win.getYSize() log.debug('window-event: Resize') self.filters.update() self.ui.updateGuiNodes() def onWindowEvent(self, window=None): if window is not None: # window is none if panda3d is not started if self.window_x != base.win.getXSize( ) or self.window_y != base.win.getYSize(): self.onWindowResize() elif window.getProperties().getMinimized( ) != self.window_minimized: self.onWindowMinimize() elif window.getProperties().getForeground() != self.window_focused: self.onWindowFocus() #tasks def update(self, task): dt = globalClock.getDt() render.setShaderInput('camera_pos', base.cam.getPos(render)) return task.cont
def __init__(self, showbase): # Initialise Window self.showbase = showbase # total time since start of game, to keep ticks updating on time (rather, not before) self.total_time = 0 # packets queue self.incoming = deque() # this is unnecessary lol but meh ill comment it anyway self.hp = OnscreenText(text="HP: " + str(100.0), pos=(0.95, -0.95), scale=0.07, fg=(1, 1, 1, 1), align=TextNode.ACenter, mayChange=1) # Keys array (down if 1, up if 0) self.keys = {"left": 0, "right": 0, "up": 0, "down": 0, "c": 0, "x": 0} self.skybox = Skybox(self.showbase) self.ch = CameraHandler() # maybe this shit too, or this can stay here and just pass in an array of spells self.showbase.spell_man = SpellManager( self.showbase.num_warlocks ) # until the Game() class is created in here which i think it should for i in self.showbase.spells: self.showbase.spell_man.add_spell(i) self.game = Game(self.showbase, game_tick) self.warlock = self.game.warlock[self.showbase.which] self.warlock.attach_ring(self.showbase) self.tick = 0 self.temp_tick = 0 # Set event handlers for keys self.showbase.accept("escape", sys.exit) # holding c will focus the camera on clients warlock self.showbase.accept("c", set_value, [self.keys, "c", 1]) self.showbase.accept("c-up", set_value, [self.keys, "c", 0]) # variable to track which spell has been requested self.current_spell = -1 # keys to change spell self.showbase.accept("q", self.set_spell, [0]) self.showbase.accept("w", self.set_spell, [1]) self.showbase.accept("e", self.set_spell, [2]) self.showbase.accept("r", self.set_spell, [3]) # mouse 1 is for casting the spell set by the keys self.showbase.accept("mouse1", self.cast_spell) # mouse 3 is for movement, or canceling keys for casting spell self.showbase.accept("mouse3", self.update_destination) # sets the camera up behind clients warlock looking down on it from angle follow = self.warlock.model self.ch.setTarget(follow.getPos().getX(), follow.getPos().getY(), follow.getPos().getZ()) self.ch.turnCameraAroundPoint(follow.getH(), 0) # Add the game loop procedure to the task manager. self.showbase.taskMgr.add(self.game_loop, "Game Loop")
class Client(DirectObject): """ Client class handels gui/input audio and rendering """ def __init__(self): log.debug('Starting Client') #open a window... but first set all the needed props wp=self.loadWindoProperites() #open the window base.openMainWindow(props = wp) #base.setBackgroundColor(0.06, 0.1, 0.12, 1) base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.disableMouse() base.enableParticles() #needed to determine what window event fired self.window_focused=base.win.getProperties().getForeground() self.window_x=base.win.getXSize() self.window_y=base.win.getYSize() self.window_minimized=base.win.getProperties().getMinimized() #filter manager, post process self.filters=Filters() #audio sound effects (sfx) + music self.audio=Audio() self.audio.setMusic('background') self.audio.playMusic() #light manager self.lights=LightManager() #setup the user interface (gui+key/mouse bind) self.ui=UserInterface() #skybox self.sun_and_sky=Skybox(self.lights) #player (character) droid self.droid=PCDroid(self.ui) #some vars used later self.map_name=None self.loading_status=set() self.level_root=render.attachNewNode('level_root') self.level_root.hide() self.is_in_game=False #events base.win.setCloseRequestEvent('exit-event') self.accept('exit-event',self.onClientExit) self.accept( 'window-event', self.onWindowEvent) self.accept( 'window-reset', self.onWindowReset) self.accept( 'client-mouselock', self.setMouseLock) self.accept( 'load-level', self.onLevelLoad) self.accept( 'loading-done', self.onLoadingDone) self.accept( 'reload-shaders', self.onShaderReload) self.accept( 'client-set-team', self.onTeamCahnge) self.accept( 'client-quit', self.onQuit) # Task taskMgr.add(self.update, 'client_update') log.debug('Client started') def doSomeStuffTsk(self, task): x=deque(range(5000)) for i in xrange(999): random.shuffle(x) #print i, x[0] #print 'done' return task.done def setMouseLock(self, lock): wp = WindowProperties.getDefault() if lock: wp.setMouseMode(WindowProperties.M_confined) else: wp.setMouseMode(WindowProperties.M_relative) if not cfg['use-os-cursor']: wp.setCursorHidden(True) base.win.requestProperties(wp) def loadWindoProperites(self): #check if we can open a fullscreen window at the requested size if cfg['fullscreen']: mods=[] for mode in base.pipe.getDisplayInformation().getDisplayModes(): mods.append([mode.width, mode.height]) if list(cfg['win-size']) not in mods: cfg['fullscreen']=False log.warning('Can not open fullscreen window at '+str(cfg['win-size'])) #the window props should be set by this time, but make sure wp = WindowProperties.getDefault() try: wp.setUndecorated(cfg['undecorated']) wp.setFullscreen(cfg['fullscreen']) wp.setSize(cfg['win-size'][0],cfg['win-size'][1]) wp.setFixedSize(cfg['win-fixed-size']) except: log.warning('Failed to set window properties, Traceback:') for error in traceback.format_exc().splitlines()[1:]: log.warning(error.strip()) #these probably won't be in the config (?) wp.setOrigin(-2,-2) wp.setTitle('A4P') if not cfg['use-os-cursor']: wp.setCursorHidden(True) return wp def loadLevel(self, task): log.debug('Client loading level...') with open(path+'maps/'+self.map_name+'.json') as f: values=json.load(f) #set the time self.sun_and_sky.setTime(values['level']['time']) #self.sun_and_sky.show() #load visible objects for id, obj in enumerate(values['objects']): mesh=loader.loadModel(path+obj['model']) mesh.reparentTo(self.level_root) mesh.setPosHpr(tuple(obj['pos']), tuple(obj['hpr'])) mesh.setTag('id_'+str(id), str(id)) #we may need to find this mesh later to link it to a Bullet object for name, value in obj['shader_inputs'].items(): if isinstance(value, basestring): mesh.setShaderInput(str(name), loader.loadTexture(path+value)) if isinstance(value, float): mesh.setShaderInput(str(name), value) if isinstance(value, list): if len(value) == 2: mesh.setShaderInput(str(name), Vec2(value[0], value[1])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec3(value[0], value[1], value[2])) elif len(value) == 3: mesh.setShaderInput(str(name), Vec4(value[0], value[1], value[2], value[3])) mesh.setShader(Shader.load(Shader.SLGLSL, obj['vertex_shader'],obj['fragment_shader'])) #set the music self.audio.setMusic(values['level']['music']) #self.level_root.prepareScene(base.win.getGsg()) messenger.send('loading-done', ['client']) return task.done #events def onQuit(self): self.level_root.removeNode() self.level_root=render.attachNewNode('level_root') self.level_root.hide() if self.ui.is_zoomed: self.ui.zoom() self.sun_and_sky.hide() self.droid.disable() self.ui.unbindKeys() self.ui.in_game_menu.hide() self.ui.main_menu.show() self.audio.setMusic('background') self.loading_status=set() self.is_in_game=False messenger.send('world-clear-level') def onTeamCahnge(self, team): self.droid.setTeam(team) def onShaderReload(self): log.debug('Client: Reloading shaders') for mesh in self.level_root.getChildren(): shader=mesh.getShader() v_shader=shader.getFilename(Shader.ST_vertex) f_shader=shader.getFilename(Shader.ST_fragment) mesh.setShader(Shader.load(Shader.SLGLSL, v_shader,f_shader)) self.ui.main_menu.setShader(path+'shaders/gui_v.glsl', path+'shaders/gui_f.glsl') self.filters.reset() def onLoadingDone(self, target): log.debug(str(target)+' loading done') self.loading_status.add(target) if self.loading_status == set(['client', 'server', 'world']): self.ui.main_menu.hide() self.level_root.show() self.sun_and_sky.show() self.ui.bindKeys() self.droid.node.setPos(render, 20,0,2) self.droid.lockCamera() self.droid.model.show() self.droid.rig.show() self.droid.gun.show() self.ui.in_game_menu.showElements('hud_') self.ui.hideSoftCursor() self.ui.is_main_menu=False self.is_in_game=True messenger.send('world-link-objects', [self.droid.node, 'pc_droid_node']) def onLevelLoad(self, map_name): self.map_name=map_name #we wait 1.0 sec for the loading animation to finish just in case if loading takes < 1.0 sec. taskMgr.doMethodLater(1.0, self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #taskMgr.add(self.loadLevel, 'client_loadLevel_task', taskChain = 'background_chain') #the client needs to load/setup: # -visible geometry # -enviroment (skybox/dome + sunlight diection + fog + ???) # -water plane # -unmovable (point)light sources # -unmovable vfx # -the player droid def onClientExit(self): log.debug('Client exit') self.audio.cleanup() app.exit() def onWindowReset(self): wp=self.loadWindoProperites() base.win.requestProperties(wp) def onWindowMinimize(self): self.window_minimized=base.win.getProperties().getMinimized() log.debug('window-event: Minimize is '+str(self.window_minimized)) def onWindowFocus(self): self.window_focused=base.win.getProperties().getForeground() log.debug('window-event: Focus set to '+str(self.window_focused)) if self.is_in_game: self.ui.in_game_menu.showMenu(self.window_focused) if not self.window_focused: self.ui.cursor_pos=(0,0,0) if cfg['pause-on-focus-lost']: if not self.window_focused: self.audio.pauseMusic() base.win.setActive(False) else: self.audio.resumeMusic() base.win.setActive(True) def onWindowResize(self): self.window_x=base.win.getXSize() self.window_y=base.win.getYSize() log.debug('window-event: Resize') self.filters.update() self.ui.updateGuiNodes() def onWindowEvent(self,window=None): if window is not None: # window is none if panda3d is not started if self.window_x!=base.win.getXSize() or self.window_y!=base.win.getYSize(): self.onWindowResize() elif window.getProperties().getMinimized() != self.window_minimized: self.onWindowMinimize() elif window.getProperties().getForeground() != self.window_focused: self.onWindowFocus() #tasks def update(self, task): dt = globalClock.getDt() render.setShaderInput('camera_pos', base.cam.getPos(render)) return task.cont
def __init__(self, window, camera, options): ''' Constructor ''' # Options self.options = options # Register the renderer for control input self.keys = key.KeyStateHandler() self.pressedKeys = {} self.window = window self.window.push_handlers(self.on_key_press) self.window.push_handlers(self.on_key_release) self.window.push_handlers(self.on_mouse_motion) self.window.push_handlers(self.keys) # Window size (szx, szy) = self.window.get_size() self.windowWidth = szx self.windowHeight = szy self.camera = camera self.time = 0.0 # Ocean Render Parameters self.wireframe = False self.oceanDepth = self.options.getfloat('Scene', 'oceandepth') self.enableUpdates = True self.oceanWind = Vector2(self.options.getfloat('Scene', 'oceanwindx'), self.options.getfloat('Scene', 'oceanwindy')) self.oceanWaveHeight = self.options.getfloat('Scene', 'oceanwaveheight') self.oceanTileSize = self.options.getint('Scene', 'oceantilesize') self.oceanTiles = Vector2(self.options.getint('Scene', 'oceantilesx'), self.options.getint('Scene', 'oceantilesy')) self.period = self.options.getfloat('Scene', 'period') self.env_path = self.options.get('Scene', 'env_path') self.frame = 0 self.skyboxScale = 640.0 self.skyboxOffset = Vector3(0.0, 0.0, 0.0) # Compile the shader self.skyboxShader = shader.openfiles('shaders/skybox.vertex', 'shaders/skybox.fragment') # Renderables self.scene = [] self.skybox = Skybox( self.skyboxShader, self.camera, self.skyboxScale, self.skyboxOffset, xpos_path=self.env_path + '/xpos.tga', ypos_path=self.env_path + '/ypos.tga', zpos_path=self.env_path + '/zpos.tga', xneg_path=self.env_path + '/xneg.tga', yneg_path=self.env_path + '/yneg.tga', zneg_path=self.env_path + '/zneg.tga', ) self.scene.append(self.skybox) self.ocean = Ocean(self.camera, cubemap=self.skybox, depth=self.oceanDepth, waveHeight=self.oceanWaveHeight, wind=self.oceanWind, tileSize=self.oceanTileSize, tilesX=self.oceanTiles.x, tilesZ=self.oceanTiles.y, period=self.period) self.scene.append(self.ocean)
class Viewer: """ GLFW viewer window, with classic initialization & graphics loop """ def __init__(self, width=1000, height=1000, skybox=None): self.y_angle = 0 self.x_angle = 0 self.fill_modes = cycle([GL.GL_LINE, GL.GL_POINT, GL.GL_FILL]) # version hints: create GL window with >= OpenGL 3.3 and core profile glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL.GL_TRUE) glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.window_hint(glfw.RESIZABLE, False) self.win = glfw.create_window(width, height, 'Viewer', None, None) # make win's OpenGL context current; no OpenGL calls can happen before glfw.make_context_current(self.win) # register event handl ers glfw.set_key_callback(self.win, self.on_key) self.trackball = GLFWTrackball(self.win) # useful message to check OpenGL renderer characteristics print( 'OpenGL', GL.glGetString(GL.GL_VERSION).decode() + ', GLSL', GL.glGetString(GL.GL_SHADING_LANGUAGE_VERSION).decode() + ', Renderer', GL.glGetString(GL.GL_RENDERER).decode()) # initialize GL by setting viewport and default render characteristics GL.glClearColor(0.1, 0.1, 0.1, 0.1) GL.glEnable(GL.GL_CULL_FACE) GL.glEnable(GL.GL_DEPTH_TEST) self.skybox = Skybox("skybox2.jpg") # initially empty list of object to draw self.drawables = [] def run(self, observable): """ Main render loop for this OpenGL window """ while not glfw.window_should_close(self.win): # clear draw buffer GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) # draw our scene objects winsize = glfw.get_window_size(self.win) view = self.trackball.view_matrix() projection = self.trackball.projection_matrix(winsize) model = translate(0, -100, -100) @ np.linalg.inv( observable.mesh.transform) if self.skybox is not None: self.skybox.drawskybox(projection, view) for drawable in self.drawables: drawable.draw(projection, view, model, win=self.win) # flush render commands, and swap draw buffers glfw.swap_buffers(self.win) # Poll for and process events glfw.poll_events() def add(self, *drawables): """ add objects to draw in this window """ self.drawables.extend(drawables) def on_key(self, _win, key, _scancode, action, _mods): """ 'Q' or 'Escape' quits """ rotation_step = 5 for drawable in self.drawables: drawable.on_key(_win, key, _scancode, action, _mods) if action == glfw.PRESS or action == glfw.REPEAT: if key == glfw.KEY_ESCAPE or key == glfw.KEY_Q: glfw.set_window_should_close(self.win, True) if key == glfw.KEY_W: GL.glPolygonMode(GL.GL_FRONT_AND_BACK, next(self.fill_modes)) if key == glfw.KEY_SPACE: pass