class Viewer(Node): """ GLFW viewer window, with classic initialization & graphics loop """ def __init__(self, width=640, height=480, map_width=60, map_height=60, map_depth=60): # 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) # glfw.maximize_window(self.win) # self.add(self.terrain.create()) # make win's OpenGL context current; no OpenGL calls can happen before glfw.make_context_current(self.win) # register event handlersVertexProf glfw.set_key_callback(self.win, self.on_key) # 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, 1) GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_CULL_FACE) # compile and initialize shader programs once globally #self.color_shader = Shader(COLOR_VERT, COLOR_FRAG) # initially empty list of object to draw self.drawables = [] self.trackball = GLFWTrackball(self.win) self.fill_modes = cycle([GL.GL_LINE, GL.GL_POINT, GL.GL_FILL]) GL.glEnable(GL.GL_DEPTH_TEST) #Maxime t super().__init__() #Init du node self.x = 0 self.y = 0 self.z = 10 self.terrain = Map(map_width, map_height, map_depth) self.add(self.terrain.create()) def run(self): """ 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 projection = self.trackball.projection_matrix( glfw.get_window_size(self.win)) view = self.trackball.view_matrix() model = identity() # NodeStorage.get("cube1") super().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 on_key(self, _win, key, _scancode, action, _mods): """ 'Q' or 'Escape' quits """ if action == glfw.PRESS or action == glfw.REPEAT: if key == glfw.KEY_ESCAPE: glfw.set_window_should_close(self.win, True) if key == glfw.KEY_Z: #W GL.glPolygonMode(GL.GL_FRONT_AND_BACK, next(self.fill_modes)) if key == glfw.KEY_O: NodeStorage.get("player").reset_time() if key == glfw.KEY_W: self.trackball.translate_easy(0, 0, 1) if key == glfw.KEY_S: self.trackball.translate_easy(0, 0, -1) if key == glfw.KEY_DOWN: self.trackball.translate_easy(0, 1, 0) if key == glfw.KEY_UP: self.trackball.translate_easy(0, -1, 0) if key == glfw.KEY_A: self.trackball.rotate_easy((0, 1, 0), -2) if key == glfw.KEY_D: self.trackball.rotate_easy((0, 1, 0), 2) if key == glfw.KEY_LEFT: self.trackball.rotate_easy((1, 0, 0), -2) if key == glfw.KEY_RIGHT: self.trackball.rotate_easy((1, 0, 0), 2) if key == glfw.KEY_N: self.trackball.reset_rotation() if key == glfw.KEY_M: self.trackball.reset_hard() if key == glfw.KEY_Y: NodeStorage.get("player_node").translate(0, 0, -1) self.terrain.elevate(NodeStorage.get("player_node")) NodeStorage.get("player").reset_time() if key == glfw.KEY_G: NodeStorage.get("player_node").translate(-1, 0, 0) self.terrain.elevate(NodeStorage.get("player_node")) NodeStorage.get("player").reset_time() if key == glfw.KEY_H: NodeStorage.get("player_node").translate(0, 0, 1) self.terrain.elevate(NodeStorage.get("player_node")) NodeStorage.get("player").reset_time() if key == glfw.KEY_J: NodeStorage.get("player_node").translate(1, 0, 0) self.terrain.elevate(NodeStorage.get("player_node")) NodeStorage.get("player").reset_time() def set_terrain(self, terrain): """ Set the terrain Warning : do immediately after the initialization. Not before because to create the map we need first to create the viewer """ self.terrain = terrain