def main(): cairoSavePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'carpark.pdf') # cairoSavePath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'carpark.pdf') # cairoSavePath = os.path.join(os.path.basename(__file__), 'carpark.pdf') # cairoSavePath = os.path.join(os.getcwd(), 'carpark.pdf') if not glfw.Init(): exit() window = CbWindow(640, 480, 'window') if not window.window: glfw.Terminate() print('GLFW: Failed to create window') exit() print glGetString(GL_VERSION) parkingLot = buildParkingLot() mainRender = ParkingLotRender(parkingLot) window.mainRender = mainRender window.cairoSavePath = cairoSavePath mainRender.renderCairo(window.playerCamera, cairoSavePath) # mainScene = Scene() glfw.MakeContextCurrent(window.window) while not glfw.WindowShouldClose(window.window): # Render here # mainScene.renderModels(window.playerCamera) # mainRender.renderOpenGL(window.playerCamera) mainRender.renderOpenGL(window.currentCamera, window.playerCamera) # Swap front and back buffers glfw.SwapBuffers(window.window) # Poll for and process events glfw.PollEvents() processCameraSelectInput(window, parkingLot) if not window.cameraLocked: window.currentCamera.processPlayerInput(window.window) glfw.DestroyWindow(window.window) glfw.Terminate()
def setup_glfw(title="poolvr.py 0.0.1", window_size=(800,600), double_buffered=False, multisample=4, fullscreen=False): if not glfw.Init(): raise Exception('failed to initialize glfw') if not double_buffered: glfw.WindowHint(glfw.DOUBLEBUFFER, False) glfw.SwapInterval(0) if multisample: glfw.WindowHint(glfw.SAMPLES, multisample) width, height = window_size if fullscreen: window = glfw.CreateWindow(width, height, title, glfw.GetPrimaryMonitor()) else: window = glfw.CreateWindow(width, height, title) if not window: glfw.Terminate() raise Exception('failed to create glfw window') glfw.MakeContextCurrent(window) _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION)) renderer = OpenGLRenderer(window_size=(width, height), znear=0.1, zfar=1000) def on_resize(renderer, window, width, height): gl.glViewport(0, 0, width, height) renderer.window_size[:] = (width, height) renderer.update_projection_matrix() from functools import partial on_resize = partial(on_resize, renderer) glfw.SetWindowSizeCallback(window, on_resize) renderer.init_gl() on_resize(window, window_size[0], window_size[1]) return window, renderer
def setup_glfw(width=800, height=600, double_buffered=False, title="poolvr.py 0.0.1", multisample=0): if not glfw.Init(): raise Exception('failed to initialize glfw') if not double_buffered: glfw.WindowHint(glfw.DOUBLEBUFFER, False) glfw.SwapInterval(0) if multisample: glfw.WindowHint(glfw.SAMPLES, multisample) window = glfw.CreateWindow(width, height, title) if not window: glfw.Terminate() raise Exception('failed to create glfw window') glfw.MakeContextCurrent(window) _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION)) renderer = OpenGLRenderer(window_size=(width, height), znear=0.1, zfar=1000) def on_resize(window, width, height): gl.glViewport(0, 0, width, height) renderer.window_size = (width, height) renderer.update_projection_matrix() glfw.SetWindowSizeCallback(window, on_resize) return window, renderer
def dispose_gl(self): if self.window is not None: glfw.MakeContextCurrent(self.window) if self.renderer is not None: self.renderer.dispose_gl() glfw.Terminate() self._is_initialized = False
def __call__(self, scene, camera, callbacks): while not glfw.WindowShouldClose(self.window) or self.should_quit: callbacks(self.window) if callbacks.draw: camera.compute_matrices() scene.set_camera(camera) scene.render() glfw.SwapBuffers(self.window) callbacks.draw = False glfw.PollEvents() yield self glfw.Terminate()
def setup_glfw(width=800, height=600, double_buffered=False): if not glfw.Init(): raise Exception('failed to initialize glfw') if not double_buffered: glfw.WindowHint(glfw.DOUBLEBUFFER, False) glfw.SwapInterval(0) window = glfw.CreateWindow(width, height, "gltfview") if not window: glfw.Terminate() raise Exception('failed to create glfw window') glfw.MakeContextCurrent(window) _logger.info('GL_VERSION: %s' % gl.glGetString(gl.GL_VERSION)) return window
def test_vcgl(frame_block=None): # save current working directory cwd = os.getcwd() # initialize glfw - this changes cwd glfw.Init() # restore cwd os.chdir(cwd) # version hints glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2) glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # make a window win = glfw.CreateWindow(WIDTH, HEIGHT, TITLE) # make context current glfw.MakeContextCurrent(win) glClearColor(0.5, 0.5, 0.5, 1.0) renderer = TextureRenderer() renderer.prepare() fps_checker = FPSChecker() webcam = Webcam() with webcam: while not glfw.WindowShouldClose(win): frame = webcam.frame if frame_block: frame = frame_block(frame) fps_checker.lab(frame) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = frame[::-1, ...] renderer.image = frame glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) renderer.render() glfw.SwapBuffers(win) # Poll for and process events glfw.PollEvents() glfw.Terminate()
def main(): appName = 'First App' glfw.Init() glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3) # glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE) # glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.CreateWindow(800, 800, appName) glfw.SetWindowSizeCallback(window, window_size_callback) glfw.SetKeyCallback(window, key_callback) glfw.MakeContextCurrent(window) glfw.SwapInterval(1) try: initOpenGL() except Exception as e: print(e) exit(1) prevTime = time() frameCount = 0 frameTimeSum = 0 lastUpdateTime = prevTime while not glfw.WindowShouldClose(window): glfw.PollEvents() display(window) glfw.SwapBuffers(window) curTime = time() frameTime = (curTime - prevTime) # if frameTime != 0: print(1 / frameTime) sleep(0.016) if curTime - lastUpdateTime > 1: glfw.SetWindowTitle( window, '%s, FPS: %s' % (appName, str(round(frameCount / frameTimeSum)))) frameCount = 0 frameTimeSum = 0 lastUpdateTime = curTime frameTimeSum += frameTime frameCount += 1 prevTime = curTime glfw.DestroyWindow(window) glfw.Terminate()
def _view(self, meshes=None, window_size=(800,600)): if meshes is None: meshes = [] title = traceback.extract_stack(None, 2)[0][2] window, renderer = setup_glfw(width=window_size[0], height=window_size[1], double_buffered=True, title=title) camera_world_matrix = renderer.camera_matrix camera_position = camera_world_matrix[3,:3] gl.glViewport(0, 0, window_size[0], window_size[1]) gl.glClearColor(*BG_COLOR) gl.glEnable(gl.GL_DEPTH_TEST) for mesh in meshes: mesh.init_gl(force=True) def on_resize(window, width, height): gl.glViewport(0, 0, width, height) renderer.window_size = (width, height) renderer.update_projection_matrix() glfw.SetWindowSizeCallback(window, on_resize) process_keyboard_input = init_keyboard(window) _logger.info('entering render loop...') stdout.flush() nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() while not glfw.WindowShouldClose(window): t = glfw.GetTime() dt = t - lt lt = t glfw.PollEvents() renderer.process_input() process_keyboard_input(dt, camera_world_matrix) with renderer.render(meshes=meshes): pass max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) _logger.info('...exited render loop: average FPS: %f, maximum frame time: %f', (nframes - 1) / (t - st), max_frame_time) renderer.shutdown() _logger.info('...shut down renderer') glfw.DestroyWindow(window) glfw.Terminate()
def main(): # save current working directory cwd = os.getcwd() # initialize glfw - this changes cwd glfw.Init() # restore cwd os.chdir(cwd) # version hints glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2) glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) # make a window win = glfw.CreateWindow(512, 512, b'simpleglfw') # make context current glfw.MakeContextCurrent(win) glClearColor(0.5, 0.5, 0.5, 1.0) # renderer = TriangleRenderer() # renderer = RectangleRenderer() with Image.open('./image/psh.jpg') as img: data = np.asarray(img, dtype='uint8') data = data[::-1, ...] renderer = TextureRenderer(image=data) renderer.prepare() while not glfw.WindowShouldClose(win): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) renderer.render() glfw.SwapBuffers(win) # Poll for and process events glfw.PollEvents() glfw.Terminate()
def __init__(self, width=1024, height=1024, title="vol_render"): curdir = os.getcwd() glfw.Init() # glfw sometimes changes the current working directory, see # https://github.com/adamlwgriffiths/cyglfw3/issues/21 os.chdir(curdir) glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3) glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) self.window = glfw.CreateWindow(width, height, title) if not self.window: glfw.Terminate() exit() glfw.MakeContextCurrent(self.window) GL.glClearColor(0.0, 0.0, 0.0, 0.0) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) glfw.SwapBuffers(self.window) glfw.PollEvents()
def init_gl(self): if self._is_initialized: return if not glfw.Init(): raise RuntimeError("GLFW Initialization failed") glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 1) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.WindowHint(glfw.DOUBLEBUFFER, False) glfw.SwapInterval(0) self.window = glfw.CreateWindow(self.renderer.window_size[0], self.renderer.window_size[1], self.title) if self.window is None: glfw.Terminate() raise RuntimeError("GLFW Window creation failed") glfw.SetKeyCallback(self.window, self.key_callback) glfw.MakeContextCurrent(self.window) if self.renderer is not None: self.renderer.init_gl() self._is_initialized = True
def run_window(self): last_time = glfw.GetTime() frames = 0 while glfw.GetKey( self.window, glfw.KEY_ESCAPE) != glfw.PRESS and not glfw.WindowShouldClose( self.window): current_time = glfw.GetTime() if current_time - last_time >= 1.0: glfw.SetWindowTitle(self.window, "Loaded! Running at FPS: %d" % (frames)) frames = 0 last_time = current_time self.render() frames += 1 for object in self._render_objects: object.delete() glDeleteProgram(self._mapping['program_id']) glDeleteVertexArrays(1, [self._mapping['vertex_array_id']]) glfw.Terminate()
def close(self): glfw.Terminate()
def main(window_size=(800, 600), novr=False, ball_collision_model='simple', use_ode=False, multisample=0, fullscreen=False, cube_map=None, speed=1.0, glyphs=False, balls_on_table=None, use_quartic_solver=False, render_method='raycast', **kwargs): """ The main routine. Performs initializations/setups; starts the render loop; performs shutdowns on exit. """ _logger.debug( 'configuration:\n%s', '\n'.join('%s: %s' % it for it in chain(dict(locals()).items(), kwargs.items()))) window, fallback_renderer = setup_glfw(window_size=window_size, double_buffered=novr, multisample=multisample, fullscreen=fullscreen) if not novr and OpenVRRenderer is not None: try: renderer = OpenVRRenderer(window_size=window_size, multisample=multisample) renderer.init_gl() global _window_renderer _window_renderer = renderer except Exception as err: renderer = fallback_renderer _logger.error('could not initialize OpenVRRenderer: %s', err) else: renderer = fallback_renderer init_sound() table = PoolTable() if use_ode: try: from .ode_physics import ODEPoolPhysics physics = ODEPoolPhysics(num_balls=16, table=table, balls_on_table=balls_on_table) except ImportError as err: _logger.error('could not import ode_physics:\n%s', err) ODEPoolPhysics = None physics = PoolPhysics(num_balls=16, table=table, ball_collision_model=ball_collision_model, enable_sanity_check=False, enable_occlusion=True, balls_on_table=balls_on_table, use_quartic_solver=use_quartic_solver, **kwargs) else: physics = PoolPhysics(num_balls=16, table=table, ball_collision_model=ball_collision_model, enable_sanity_check=False, enable_occlusion=True, balls_on_table=balls_on_table, use_quartic_solver=use_quartic_solver, **kwargs) game = PoolGame(table=table, physics=physics) cue = PoolCue() game.physics.add_cue(cue) game.reset(balls_on_table=balls_on_table) table_mesh = game.table.export_mesh(surface_technique=LAMBERT_TECHNIQUE, cushion_technique=LAMBERT_TECHNIQUE) ball_meshes = game.table.export_ball_meshes( technique=LAMBERT_TECHNIQUE, use_bb_particles=render_method == 'billboards') # textured_text = TexturedText() # if use_bb_particles: if render_method == 'billboards': billboard_particles = ball_meshes[0] ball_mesh_positions = billboard_particles.primitive.attributes[ 'translate'] ball_mesh_rotations = np.array(game.num_balls * [np.eye(3)]) meshes = [floor_mesh, table_mesh ] + ball_meshes + [cue.shadow_mesh, cue] elif render_method == 'raycast': ball_mesh_positions = np.zeros((game.num_balls, 3), dtype=np.float32) ball_quaternions = np.zeros((game.num_balls, 4), dtype=np.float32) ball_quaternions[:, 3] = 1 from poolvr.gl_rendering import FragBox def on_use(material, camera_matrix=None, znear=None, projection_lrbt=None, window_size=None, **frame_data): material.values['u_camera'] = camera_matrix material.values['u_projection_lrbt'] = projection_lrbt material.values['u_znear'] = znear material.values['iResolution'] = window_size import poolvr fragbox = FragBox(os.path.join(os.path.dirname(poolvr.__file__), 'shaders', 'sphere_projection_fs.glsl'), on_use=on_use) fragbox.material.values['ball_positions'] = ball_mesh_positions fragbox.material.values['ball_quaternions'] = ball_quaternions fragbox.material.values['cue_world_matrix'] = cue.world_matrix fragbox.material.values['cue_length'] = cue.length fragbox.material.values['cue_radius'] = cue.radius meshes = [table_mesh, fragbox] else: ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes] ball_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_meshes ] ball_mesh_rotations = [ mesh.world_matrix[:3, :3].T for mesh in ball_meshes ] ball_shadow_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes ] meshes = [ floor_mesh, table_mesh ] + ball_meshes + ball_shadow_meshes + [cue.shadow_mesh, cue] if cube_map: from .room import skybox_mesh meshes.insert(0, skybox_mesh) for mesh in meshes: mesh.init_gl() cue.shadow_mesh.update(c=table.H + 0.001) cue.position[1] = game.table.H + 0.001 cue.position[2] += game.table.L * 0.1 for i, mesh in enumerate(ball_meshes): if i not in balls_on_table: mesh.visible = False ball_shadow_meshes[i].visible = False camera_world_matrix = fallback_renderer.camera_matrix camera_position = camera_world_matrix[3, :3] camera_position[1] = game.table.H + 0.6 camera_position[2] = game.table.L - 0.1 last_contact_t = float('-inf') def reset(): nonlocal last_contact_t nonlocal balls_on_table game.reset(balls_on_table=balls_on_table) last_contact_t = float('-inf') cue.position[0] = 0 cue.position[1] = game.table.H + 0.001 cue.position[2] = game.table.L * 0.3 process_mouse_input = init_mouse(window) init_keyboard(window) def on_keydown(window, key, scancode, action, mods): if key == glfw.KEY_R and action == glfw.PRESS: reset() set_on_keydown_callback(window, on_keydown) theta = 0.0 def process_keyboard_input(dt, camera_world_matrix): nonlocal theta theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] - key_state[KEY_RIGHT]) sin, cos = np.sin(theta), np.cos(theta) camera_world_matrix[0, 0] = cos camera_world_matrix[0, 2] = -sin camera_world_matrix[2, 0] = sin camera_world_matrix[2, 2] = cos dist = dt * KB_MOVE_SPEED camera_world_matrix[3,:3] += \ dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \ + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \ + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3] def process_input(dt): glfw.PollEvents() process_keyboard_input(dt, camera_world_matrix) process_mouse_input(dt, cue) if isinstance(renderer, OpenVRRenderer): from .vr_input import calc_cue_transformation, calc_cue_contact_velocity, axis_callbacks, button_press_callbacks button_press_callbacks[openvr.k_EButton_ApplicationMenu] = reset if use_ode and ODEPoolPhysics is not None: def on_cue_ball_collision(renderer=renderer, game=game, physics=physics, impact_speed=None): if impact_speed > 0.0015: renderer.vr_system.triggerHapticPulse( renderer._controller_indices[0], 0, int( max(0.8, impact_speed**2 / 4.0 + impact_speed**3 / 16.0) * 2750)) physics.set_cue_ball_collision_callback(on_cue_ball_collision) # def on_cue_surface_collision(renderer=renderer, game=game, physics=physics, impact_speed=None): # if impact_speed > 0.003: # renderer.vr_system.triggerHapticPulse(renderer._controller_indices[0], 0, # int(max(0.75, 0.2*impact_speed**2 + 0.07*impact_speed**3) * 2500)) # physics.set_cue_surface_collision_callback(on_cue_surface_collision) _logger.info('entering render loop...') sys.stdout.flush() import gc gc.collect() last_contact_t = float('-inf') contact_last_frame = False nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() glyph_meshes = [] while not glfw.WindowShouldClose(window): t = glfw.GetTime() dt = t - lt lt = t process_input(dt) if glyphs: glyph_meshes = physics.glyph_meshes(game.t) with renderer.render(meshes=meshes + glyph_meshes) as frame_data: if isinstance(renderer, OpenVRRenderer) and frame_data: renderer.process_input( dt, button_press_callbacks=button_press_callbacks, axis_callbacks=axis_callbacks) hmd_pose = frame_data['hmd_pose'] camera_position[:] = hmd_pose[:, 3] controller_poses = frame_data['controller_poses'] if len(controller_poses) > 0: if len(controller_poses) == 2: pose_0, pose_1 = controller_poses else: controller_indices = frame_data['controller_indices'] if controller_indices[0] == 0: pose_0 = controller_poses[0] pose_1 = np.zeros((3, 4), dtype=np.float64) pose_1[0, 0] = pose_1[1, 1] = pose_1[2, 2] = 1 else: pose_0 = np.zeros((3, 4), dtype=np.float64) pose_0[0, 0] = pose_0[1, 1] = pose_0[2, 2] = 1 pose_1 = controller_poses[0] calc_cue_transformation(pose_0, pose_1, out=cue.world_matrix) cue.velocity = frame_data['controller_velocities'][0] cue.angular_velocity = frame_data[ 'controller_angular_velocities'][0] if use_ode and isinstance(physics, ODEPoolPhysics): set_quaternion_from_matrix(pose_0[:, :3], cue.quaternion) elif isinstance(renderer, OpenGLRenderer): if use_ode and isinstance(physics, ODEPoolPhysics): set_quaternion_from_matrix( cue.rotation.dot(cue.world_matrix[:3, :3].T), cue.quaternion) if render_method == 'billboards': billboard_particles.update_gl() elif render_method == 'raycast': for i, (pos, quat) in enumerate( zip(game.ball_positions, game.ball_quaternions)): ball_mesh_positions[i][:] = pos ball_quaternions[i][:] = quat else: for i, (pos, quat) in enumerate( zip(game.ball_positions, game.ball_quaternions)): ball_mesh_positions[i][:] = pos ball_shadow_mesh_positions[i][0::2] = pos[0::2] set_matrix_from_quaternion(quat, ball_mesh_rotations[i]) cue.shadow_mesh.update() # sdf_text.set_text("%9.3f" % dt) # sdf_text.update_gl() if not contact_last_frame: if game.t - last_contact_t >= 2: for i, position in cue.aabb_check(game.ball_positions[:1], physics.ball_radius): r_c = cue.contact(position, physics.ball_radius) if r_c is not None: if isinstance(renderer, OpenVRRenderer) and frame_data and len( frame_data['controller_poses']) == 2: pose_0, pose_1 = frame_data['controller_poses'] r_0, r_1 = pose_0[:, 3], pose_1[:, 3] v_0, v_1 = frame_data['controller_velocities'] v_c = calc_cue_contact_velocity( r_c, r_0, r_1, v_0, v_1) else: v_c = cue.velocity physics.strike_ball(game.t, i, game.ball_positions[i], r_c, v_c, cue.mass) last_contact_t = game.t contact_last_frame = True if isinstance(renderer, OpenVRRenderer): renderer.vr_system.triggerHapticPulse( renderer._controller_indices[0], 0, int( np.linalg.norm(cue.velocity)**2 / 1.7 * 2700)) break else: contact_last_frame = False game.step(speed * dt) max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) if nframes > 1: _logger.info( '...exited render loop: average FPS: %f, maximum frame time: %f, average frame time: %f', (nframes - 1) / (t - st), max_frame_time, (t - st) / (nframes - 1)) from .physics.events import PhysicsEvent _logger.debug(PhysicsEvent.events_str(physics.events)) renderer.shutdown() _logger.info('...shut down renderer') glfw.DestroyWindow(window) glfw.Terminate() _logger.info('GOODBYE')
def tearDown(self): self.renderer.shutdown() glfw.DestroyWindow(self.window) glfw.Terminate()
def generate_binary_mask(faces, vertices_2d, width, height): if not glfw.Init(): print('glfw not initialized') sys.exit() version = 3, 3 glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, version[0]) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, version[1]) glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, 1) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) glfw.WindowHint(glfw.VISIBLE, 1) window = glfw.CreateWindow(width, height, 'Quad') if not window: print('glfw window not created') glfw.Terminate() sys.exit() glfw.MakeContextCurrent(window) strVS = """ #version 330 layout(location = 0) in vec2 aPosition; void main() { gl_Position = vec4(vec3(aPosition, 0), 1.0); } """ strFS = """ #version 330 out vec3 fragColor; void main() { fragColor = vec3(0, 1, 0); } """ program = glutils.loadShaders(strVS, strFS) glUseProgram(program) element_array = np.reshape(faces, -1) elementData = np.array(element_array, np.uint32) vertex_array = np.reshape(vertices_2d, -1) vertexData = np.array(vertex_array, np.float32) vao = glGenVertexArrays(1) glBindVertexArray(vao) ebo = glGenBuffers(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * len(elementData), elementData, GL_STATIC_DRAW) vbo = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, 4 * len(vertexData), vertexData, GL_STATIC_DRAW) glEnableVertexAttribArray(0) glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None) glBindVertexArray(0) GL.glClearColor(0, 0, 0, 1.0) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) glUseProgram(program) glBindVertexArray(vao) glDrawElements(GL_TRIANGLES, len(element_array), GL_UNSIGNED_INT, None) glBindVertexArray(0) glPixelStorei(GL_PACK_ALIGNMENT, 1) pixel_data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, outputType=None) im = np.array(pixel_data) mask = Image.frombuffer('RGB', (width, height), im, 'raw', 'RGB') mask = np.array(mask) glfw.Terminate() return mask
def view_gltf(gltf, uri_path, scene_name=None, openvr=False, window_size=None, clear_color=(0.01, 0.01, 0.013, 0.0), multisample=None, nframes=None, screenshot=None, camera_position=None, camera_rotation=None, zfar=1000.0, znear=0.01, yfov=0.660593, window_title='gltfview', screen_capture_prefix=None, display_fps=False, move_speed=None): _t0 = time.time() if window_size is None: window_size = [800, 600] else: window_size = list(window_size) window = setup_glfw(width=window_size[0], height=window_size[1], double_buffered=not openvr, multisample=multisample, window_title=window_title) gl.glClearColor(*clear_color) camera = {'type': 'perspective', 'perspective': {"aspectRatio": window_size[0]/window_size[1], "yfov": yfov, "zfar": zfar, "znear": znear}} projection_matrix = np.zeros((4,4), dtype=np.float32) def on_resize(window, width, height): window_size[:] = width, height gl.glViewport(0, 0, window_size[0], window_size[1]) gltfu.calc_projection_matrix(camera, out=projection_matrix, aspectRatio=window_size[0] / max(5, window_size[1])) glfw.SetWindowSizeCallback(window, on_resize) scene = gltfu.init_scene(gltf, uri_path, scene_name=scene_name) scene_bounds = gltfu.find_scene_bounds(scene, gltf) _logger.debug('scene bounds:\n%s', '\n'.join(['%20s: min = %s , max = %s' % (semantic, bounds[0], bounds[1]) for semantic, bounds in scene_bounds.items()])) root_nodes = [gltf['nodes'][n] for n in scene.get('nodes', [])] nodes = gltfu.flatten_nodes(root_nodes, gltf) camera_node = next((node for node in nodes if 'camera' in node), None) if camera_node is not None: camera = gltf['cameras'][camera_node['camera']] _logger.info('found camera: %s', camera) camera_world_matrix = camera_node['world_matrix'] else: _logger.info('no camera specified, using default') camera_world_matrix = np.eye(4, dtype=np.float32) if camera_position is not None: _logger.info('setting camera position to %s', camera_position) camera_world_matrix[3, :3] = camera_position camera_position = camera_world_matrix[3, :3] if camera_node is None and 'POSITION' in scene_bounds: bounds = scene_bounds['POSITION'] centroid = 0.5 * (bounds[0] + bounds[1]) r_max = max(np.linalg.norm(bounds[0] - centroid), np.linalg.norm(bounds[1] - centroid)) camera_position[:] = centroid camera_position[2] += r_max / np.tan(0.5*camera['perspective']['yfov']) _logger.debug('camera_position = %s', camera_position) if camera_rotation is not None: if camera_rotation[1]: s, c = np.sin(camera_rotation[1]), np.cos(camera_rotation[1]) r = np.array([[c, -s], [s, c]], dtype=np.float32) camera_world_matrix[:3:2,:3:2] = camera_world_matrix[:3:2,:3:2].dot(r.T) # sort nodes from front to back to avoid overdraw (assuming opaque objects): nodes = sorted(nodes, key=lambda node: np.linalg.norm(camera_world_matrix[3, :3] - node['world_matrix'][3, :3])) on_resize(window, window_size[0], window_size[1]) if 'POSITION' in scene_bounds: bounds = scene_bounds['POSITION'] scene_centroid = 0.5 * (bounds[0] + bounds[1]) move_speed = 0.125 * max(np.linalg.norm(bounds[0] - scene_centroid), np.linalg.norm(bounds[1] - scene_centroid)) process_input = setup_controls(camera_world_matrix=camera_world_matrix, window=window, screen_capture_prefix=screen_capture_prefix, move_speed=move_speed) text_renderer = None if display_fps: text_renderer = TextRenderer() text_renderer.init_gl() _t1 = time.time() _logger.info('''...INITIALIZATION COMPLETE (took %s seconds)''', _t1 - _t0); # BURNER FRAME: gltfu.num_draw_calls = 0 process_input(0.0) lt = glfw.GetTime() render(gltf, nodes, window_size, camera_world_matrix=camera_world_matrix, projection_matrix=projection_matrix) num_draw_calls_per_frame = gltfu.num_draw_calls _logger.info("NUM DRAW CALLS PER FRAME: %d", num_draw_calls_per_frame) _draw_text(fps=1/(glfw.GetTime()-lt), display_fps=display_fps, text_renderer=text_renderer) if screenshot: save_screen(window, screenshot) _logger.info('''STARTING RENDER LOOP...''') if nframes: _logger.info(""" * * * WILL RENDER %s FRAMES * * * """, nframes) stdout.flush() import gc; gc.collect() # does it do anything? if openvr and OpenVRRenderer is not None: vr_renderer = OpenVRRenderer(multisample=multisample, poll_tracked_device_frequency=90) setup_vr_controls() render_stats = vr_render_loop(vr_renderer=vr_renderer, process_input=process_input, window=window, window_size=window_size, gltf=gltf, nodes=nodes) vr_renderer.shutdown() else: render_stats = render_loop(process_input=process_input, window=window, window_size=window_size, gltf=gltf, nodes=nodes, camera_world_matrix=camera_world_matrix, projection_matrix=projection_matrix, nframes=nframes, display_fps=display_fps, text_renderer=text_renderer) _logger.info('''QUITING... %s ''', '\n'.join(' %21s: %s' % (k, v) for k, v in render_stats.items())) glfw.DestroyWindow(window) glfw.Terminate()
def main(window_size=(800, 600), novr=False, use_simple_ball_collisions=False, use_ode=False, multisample=0, use_bb_particles=False): """ The main routine. Performs initializations, setups, kicks off the render loop. """ _logger.info('HELLO') game = PoolGame(use_simple_ball_collisions=use_simple_ball_collisions) cue = PoolCue() if use_ode and ODEPoolPhysics is not None: game.physics = ODEPoolPhysics(num_balls=game.num_balls, ball_radius=game.ball_radius, initial_positions=game.ball_positions, table=game.table) cue_body, cue_geom = game.physics.add_cue(cue) physics = game.physics cue.position[1] = game.table.height + 0.1 cue_quaternion = np.zeros(4, dtype=np.float32) cue_quaternion[3] = 1 game.reset() ball_meshes = game.table.setup_balls(game.ball_radius, game.ball_colors[:9], game.ball_positions, striped_balls=set( range(9, game.num_balls)), use_bb_particles=use_bb_particles) window, fallback_renderer = setup_glfw(width=window_size[0], height=window_size[1], double_buffered=novr, multisample=multisample) if not novr and OpenVRRenderer is not None: try: renderer = OpenVRRenderer(window_size=window_size, multisample=multisample) button_press_callbacks = { openvr.k_EButton_Grip: game.reset, openvr.k_EButton_ApplicationMenu: game.advance_time } if ODEPoolPhysics is not None: def on_cue_ball_collision(renderer=renderer, game=game, physics=physics, impact_speed=None): if impact_speed > 0.0015: renderer.vr_system.triggerHapticPulse( renderer._controller_indices[0], 0, int( max( 0.8, impact_speed**2 / 4.0 + impact_speed**3 / 16.0) * 2750)) game.ntt = physics.next_turn_time() physics.set_cue_ball_collision_callback(on_cue_ball_collision) def on_cue_surface_collision(renderer=renderer, game=game, physics=physics, impact_speed=None): if impact_speed > 0.003: renderer.vr_system.triggerHapticPulse( renderer._controller_indices[0], 0, int( max( 0.75, 0.2 * impact_speed**2 + 0.07 * impact_speed**3) * 2500)) except Exception as err: renderer = fallback_renderer _logger.error('could not initialize OpenVRRenderer: %s', err) else: renderer = fallback_renderer camera_world_matrix = fallback_renderer.camera_matrix camera_position = camera_world_matrix[3, :3] camera_position[1] = game.table.height + 0.6 camera_position[2] = game.table.length - 0.1 process_keyboard_input = init_keyboard(window) def on_keydown(window, key, scancode, action, mods): if key == glfw.KEY_R and action == glfw.PRESS: game.reset() set_on_keydown(window, on_keydown) process_mouse_input = init_mouse(window) def process_input(dt): glfw.PollEvents() process_keyboard_input(dt, camera_world_matrix, cue) process_mouse_input(dt, cue) # textured_text = TexturedText() if use_bb_particles: ball_shadow_meshes = [] else: ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes] meshes = [skybox_mesh, floor_mesh, game.table.mesh ] + ball_meshes + ball_shadow_meshes + [cue.shadow_mesh, cue] for mesh in meshes: mesh.init_gl() ball_positions = game.ball_positions.copy() ball_quaternions = game.ball_quaternions if use_bb_particles: billboard_particles = ball_meshes[0] ball_mesh_positions = billboard_particles.primitive.attributes[ 'translate'] ball_mesh_rotations = np.array(game.num_balls * [np.eye(3)]) else: ball_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_meshes ] ball_mesh_rotations = [ mesh.world_matrix[:3, :3].T for mesh in ball_meshes ] ball_shadow_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes ] gl.glViewport(0, 0, window_size[0], window_size[1]) gl.glClearColor(*BG_COLOR) gl.glEnable(gl.GL_DEPTH_TEST) init_sound() _logger.info('entering render loop...') sys.stdout.flush() nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() while not glfw.WindowShouldClose(window): t = glfw.GetTime() dt = t - lt lt = t process_input(dt) with renderer.render(meshes=meshes) as frame_data: ##### VR mode: ##### if isinstance(renderer, OpenVRRenderer) and frame_data: renderer.process_input( button_press_callbacks=button_press_callbacks) hmd_pose = frame_data['hmd_pose'] camera_position[:] = hmd_pose[:, 3] for i, pose in enumerate(frame_data['controller_poses'][:1]): velocity = frame_data['controller_velocities'][i] angular_velocity = frame_data[ 'controller_angular_velocities'][i] cue.world_matrix[:3, :3] = pose[:, :3].dot(cue.rotation).T cue.world_matrix[3, :3] = pose[:, 3] cue.velocity[:] = velocity cue.angular_velocity = angular_velocity set_quaternion_from_matrix(pose[:, :3], cue_quaternion) # if game.t >= game.ntt: # for i, position in cue.aabb_check(ball_positions, ball_radius): # if game.t - last_contact_t[i] < 0.02: # continue # poc = cue.contact(position, ball_radius) # if poc is not None: # renderer.vr_system.triggerHapticPulse(renderer._controller_indices[-1], # 0, int(np.linalg.norm(cue.velocity + np.cross(position, cue.angular_velocity))**2 / 2.0 * 2700)) # poc[:] = [0.0, 0.0, ball_radius] # # physics.strike_ball(game.t, i, poc, cue.velocity, cue.mass) # game.ntt = physics.next_turn_time() # break ##### desktop mode: ##### elif isinstance(renderer, OpenGLRenderer): set_quaternion_from_matrix( cue.rotation.dot(cue.world_matrix[:3, :3].T), cue_quaternion) #frame_data['view_matrix'].T.dot(light_position, out=u_light_position) # if game.t >= game.ntt: # for i, position in cue.aabb_check(ball_positions, ball_radius): # poc = cue.contact(position, ball_radius) # if poc is not None: # poc[:] = [0.0, 0.0, ball_radius] # physics.strike_ball(game.t, i, poc, cue.velocity, cue.mass) # game.ntt = physics.next_turn_time() # break cue_body.setPosition(cue.world_position) # x, y, z, w = cue_quaternion w = cue_quaternion[3] cue_quaternion[1:] = cue_quaternion[:3] cue_quaternion[0] = w # cue_body.setQuaternion((w, x, y, z)) # cue_geom.setQuaternion((w, x, y, z)) cue_body.setQuaternion(cue_quaternion) cue_geom.setQuaternion(cue_quaternion) cue_body.setLinearVel(cue.velocity) cue_body.setAngularVel(cue.angular_velocity) cue.shadow_mesh.update() physics.eval_positions(game.t, out=ball_positions) physics.eval_quaternions(game.t, out=ball_quaternions) ball_positions[ ~physics. on_table] = camera_position # hacky way to only show balls that are on table for i, quat in enumerate(ball_quaternions): set_matrix_from_quaternion(quat, ball_mesh_rotations[i]) if use_bb_particles: billboard_particles.update_gl() else: for i, pos in enumerate(ball_positions): ball_mesh_positions[i][:] = pos ball_shadow_mesh_positions[i][0::2] = pos[0::2] # sdf_text.set_text("%9.3f" % dt) # sdf_text.update_gl() game.t += dt physics.step(dt) max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) if nframes > 1: _logger.info( '...exited render loop: average FPS: %f, maximum frame time: %f, average frame time: %f', (nframes - 1) / (t - st), max_frame_time, (t - st) / (nframes - 1)) renderer.shutdown() _logger.info('...shut down renderer') glfw.DestroyWindow(window) glfw.Terminate() _logger.info('GOODBYE')
def tearDownClass(cls): glfw.DestroyWindow(cls.window) glfw.Terminate()
def on_exit(): glfw.Terminate()
def render_meshes(request): should_render = request.config.getoption('--render') should_screenshot = request.config.getoption('--screenshot') if not (should_render or should_screenshot): yield None return xres, yres = [ int(n) for n in request.config.getoption('--resolution').split('x') ] msaa = int(request.config.getoption('--msaa')) vr = request.config.getoption('--vr') import numpy as np import OpenGL OpenGL.ERROR_CHECKING = False OpenGL.ERROR_LOGGING = False OpenGL.ERROR_ON_COPY = True import cyglfw3 as glfw from poolvr.glfw_app import setup_glfw, capture_window from poolvr.app import KB_MOVE_SPEED, KB_TURN_SPEED from poolvr.keyboard_controls import (init_keyboard, key_state, KEY_LEFT, KEY_RIGHT, KEY_W, KEY_S, KEY_A, KEY_D, KEY_Q, KEY_Z) window_size = [xres, yres] title = request.function.__name__ window, renderer = setup_glfw(window_size=window_size, double_buffered=not vr, multisample=msaa, title=title) camera_world_matrix = renderer.camera_matrix if vr: from poolvr.pyopenvr_renderer import OpenVRRenderer renderer = OpenVRRenderer(multisample=msaa, window_size=window_size) class Yielded(list): def __init__(self, renderer, window): self.renderer = renderer self.window = window meshes = Yielded(renderer, window) yield meshes camera_position = camera_world_matrix[3, :3] camera_position[1] = 0.5 camera_position[2] = 0.75 for mesh in meshes: mesh.init_gl(force=True) init_keyboard(window) theta = 0.0 def process_keyboard_input(dt, camera_world_matrix): nonlocal theta theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] - key_state[KEY_RIGHT]) sin, cos = np.sin(theta), np.cos(theta) camera_world_matrix[0, 0] = cos camera_world_matrix[0, 2] = -sin camera_world_matrix[2, 0] = sin camera_world_matrix[2, 2] = cos dist = dt * KB_MOVE_SPEED camera_world_matrix[3,:3] += \ dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \ + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \ + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3] def process_input(dt): glfw.PollEvents() process_keyboard_input(dt, camera_world_matrix) _logger.info('entering render loop...') stdout.flush() nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() while not glfw.WindowShouldClose(window): t = glfw.GetTime() dt = t - lt lt = t process_input(dt) with renderer.render(meshes=meshes, dt=dt): pass max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) if nframes > 1: _logger.info( '''...exited render loop: average FPS: %f minimum FPS: %f average frame time: %f maximum frame time: %f ''', (nframes - 1) / (t - st), 1 / max_frame_time, (t - st) / (nframes - 1), max_frame_time) if should_screenshot: with renderer.render(meshes=meshes, dt=0.0): pass glfw.SwapBuffers(window) capture_window(window, filename=os.path.join(os.path.dirname(__file__), 'screenshots', title.replace(' ', '_') + '.png')) renderer.shutdown() glfw.DestroyWindow(window) glfw.Terminate()
def gl_rendering(pool_physics, pool_table, request, meshes): should_render = request.config.getoption('--render') should_screenshot = request.config.getoption('--screenshot') if not (should_render or should_screenshot): yield return xres, yres = [ int(n) for n in request.config.getoption('--resolution').split('x') ] msaa = request.config.getoption('--msaa') glyphs = request.config.getoption('--glyphs') speed = float(request.config.getoption('--speed')) keep_render_window = request.config.getoption('--keep-render-window') render_method = request.config.getoption('--render-method') yield import numpy as np import OpenGL OpenGL.ERROR_CHECKING = False OpenGL.ERROR_LOGGING = False OpenGL.ERROR_ON_COPY = True import cyglfw3 as glfw from poolvr.glfw_app import setup_glfw, capture_window from poolvr.app import KB_MOVE_SPEED, KB_TURN_SPEED from poolvr.keyboard_controls import (init_keyboard, key_state, KEY_LEFT, KEY_RIGHT, KEY_W, KEY_S, KEY_A, KEY_D, KEY_Q, KEY_Z) from poolvr.game import PoolGame from poolvr.gl_rendering import set_matrix_from_quaternion logging.getLogger('poolvr.gl_rendering').setLevel(logging.WARNING) if render_method == 'ega': from poolvr.gl_techniques import EGA_TECHNIQUE as technique elif render_method == 'lambert': from poolvr.gl_techniques import LAMBERT_TECHNIQUE as technique physics = pool_physics table = pool_table game = PoolGame(physics=pool_physics, table=table) title = '_'.join( [request.function.__name__, pool_physics.ball_collision_model]) window, renderer = setup_glfw(window_size=[xres, yres], double_buffered=True, multisample=int(msaa), title=title) camera_world_matrix = renderer.camera_matrix camera_position = camera_world_matrix[3, :3] camera_position[1] = table.H + 0.6 camera_position[2] = table.L - 0.1 table_mesh = table.export_mesh(surface_technique=technique, cushion_technique=technique, rail_technique=technique) ball_meshes = table.export_ball_meshes(technique=technique) ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes] for ball_mesh, shadow_mesh, on_table in zip(ball_meshes, ball_shadow_meshes, physics._on_table): if not on_table: ball_mesh.visible = False shadow_mesh.visible = False if not meshes: meshes = [table_mesh] + ball_meshes + ball_shadow_meshes else: glyphs = False for mesh in meshes: mesh.init_gl(force=True) ball_mesh_positions = [mesh.world_matrix[3, :3] for mesh in ball_meshes] ball_mesh_rotations = [mesh.world_matrix[:3, :3].T for mesh in ball_meshes] ball_shadow_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes ] init_keyboard(window) theta = 0.0 def process_keyboard_input(dt, camera_world_matrix): nonlocal theta theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] - key_state[KEY_RIGHT]) sin, cos = np.sin(theta), np.cos(theta) camera_world_matrix[0, 0] = cos camera_world_matrix[0, 2] = -sin camera_world_matrix[2, 0] = sin camera_world_matrix[2, 2] = cos dist = dt * KB_MOVE_SPEED camera_world_matrix[3,:3] += \ dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \ + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \ + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3] def process_input(dt): glfw.PollEvents() process_keyboard_input(dt, camera_world_matrix) _logger.info('entering render loop...') stdout.flush() nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() if should_render: t_end = physics.events[-1].t if physics.events else 5.0 else: t_end = game.t while not glfw.WindowShouldClose(window) and (keep_render_window or game.t < t_end): t = glfw.GetTime() dt = t - lt lt = t process_input(dt) if glyphs: glyph_meshes = physics.glyph_meshes(game.t) else: glyph_meshes = [] game.step(speed * dt) with renderer.render(meshes=meshes + glyph_meshes, dt=dt): for i, pos in enumerate(game.ball_positions): ball_mesh_positions[i][:] = pos set_matrix_from_quaternion(game.ball_quaternions[i], out=ball_mesh_rotations[i]) ball_shadow_mesh_positions[i][0::2] = pos[0::2] max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) if nframes > 1: _logger.info( '''...exited render loop: average FPS: %f minimum FPS: %f average frame time: %f maximum frame time: %f ''', (nframes - 1) / (t - st), 1 / max_frame_time, (t - st) / (nframes - 1), max_frame_time) if should_screenshot: if physics.events: t_end = physics.events[-1].t with renderer.render(meshes=meshes): physics.eval_positions(t_end, out=game.ball_positions) for i, pos in enumerate(game.ball_positions): ball_mesh_positions[i][:] = pos set_matrix_from_quaternion(game.ball_quaternions[i], out=ball_mesh_rotations[i]) ball_shadow_mesh_positions[i][0::2] = pos[0::2] glfw.SwapBuffers(window) capture_window(window, filename=os.path.join(os.path.dirname(__file__), 'screenshots', title.replace(' ', '_') + '.png')) renderer.shutdown() glfw.DestroyWindow(window) glfw.Terminate()
def view_gltf(gltf, uri_path, scene_name=None, openvr=False, window_size=None): if scene_name is None: scene_name = gltf['scene'] if window_size is None: window_size = [800, 600] window = setup_glfw(width=window_size[0], height=window_size[1], double_buffered=not openvr) def on_resize(window, width, height): window_size[0], window_size[1] = width, height glfw.SetWindowSizeCallback(window, on_resize) if openvr and OpenVRRenderer is not None: vr_renderer = OpenVRRenderer() # text_drawer = TextDrawer() gl.glClearColor(0.01, 0.01, 0.17, 1.0); shader_ids = gltfu.setup_shaders(gltf, uri_path) gltfu.setup_programs(gltf, shader_ids) gltfu.setup_textures(gltf, uri_path) gltfu.setup_buffers(gltf, uri_path) scene = gltf.scenes[scene_name] nodes = [gltf.nodes[n] for n in scene.nodes] for node in nodes: gltfu.update_world_matrices(node, gltf) camera_world_matrix = np.eye(4, dtype=np.float32) projection_matrix = np.array(matrix44.create_perspective_projection_matrix(np.rad2deg(55), window_size[0]/window_size[1], 0.1, 1000), dtype=np.float32) for node in nodes: if 'camera' in node: camera = gltf['cameras'][node['camera']] if 'perspective' in camera: perspective = camera['perspective'] projection_matrix = np.array(matrix44.create_perspective_projection_matrix(np.rad2deg(perspective['yfov']), perspective['aspectRatio'], perspective['znear'], perspective['zfar']), dtype=np.float32) elif 'orthographic' in camera: raise Exception('TODO') camera_world_matrix = node['world_matrix'] break camera_position = camera_world_matrix[3, :3] camera_rotation = camera_world_matrix[:3, :3] dposition = np.zeros(3, dtype=np.float32) rotation = np.eye(3, dtype=np.float32) key_state = defaultdict(bool) def on_keydown(window, key, scancode, action, mods): if key == glfw.KEY_ESCAPE and action == glfw.PRESS: glfw.SetWindowShouldClose(window, gl.GL_TRUE) elif action == glfw.PRESS: key_state[key] = True elif action == glfw.RELEASE: key_state[key] = False glfw.SetKeyCallback(window, on_keydown) def on_mousedown(window, button, action, mods): pass glfw.SetMouseButtonCallback(window, on_mousedown) move_speed = 2.0 turn_speed = 0.5 def process_input(dt): glfw.PollEvents() dposition[:] = 0.0 if key_state[glfw.KEY_W]: dposition[2] -= dt * move_speed if key_state[glfw.KEY_S]: dposition[2] += dt * move_speed if key_state[glfw.KEY_A]: dposition[0] -= dt * move_speed if key_state[glfw.KEY_D]: dposition[0] += dt * move_speed if key_state[glfw.KEY_Q]: dposition[1] += dt * move_speed if key_state[glfw.KEY_Z]: dposition[1] -= dt * move_speed theta = 0.0 if key_state[glfw.KEY_LEFT]: theta -= dt * turn_speed if key_state[glfw.KEY_RIGHT]: theta += dt * turn_speed rotation[0,0] = np.cos(theta) rotation[2,2] = rotation[0,0] rotation[0,2] = np.sin(theta) rotation[2,0] = -rotation[0,2] camera_rotation[...] = rotation.dot(camera_world_matrix[:3,:3]) camera_position[:] += camera_rotation.T.dot(dposition) # sort nodes from front to back to avoid overdraw (assuming opaque objects): nodes = sorted(nodes, key=lambda node: np.linalg.norm(camera_position - node['world_matrix'][3, :3])) _logger.info('starting render loop...') sys.stdout.flush() gltfu.num_draw_calls = 0 nframes = 0 lt = glfw.GetTime() dt_max = 0.0 while not glfw.WindowShouldClose(window): t = glfw.GetTime() dt = t - lt dt_max = max(dt, dt_max) lt = t process_input(dt) if openvr: vr_renderer.process_input() vr_renderer.render(gltf, nodes, window_size) else: gl.glViewport(0, 0, window_size[0], window_size[1]) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) view_matrix = np.linalg.inv(camera_world_matrix) gltfu.set_material_state.current_material = None gltfu.set_technique_state.current_technique = None for node in nodes: gltfu.draw_node(node, gltf, projection_matrix=projection_matrix, view_matrix=view_matrix) # text_drawer.draw_text("%f" % dt, color=(1.0, 1.0, 0.0, 0.0), # view_matrix=view_matrix, # projection_matrix=projection_matrix) if nframes == 0: _logger.info("num draw calls per frame: %d", gltfu.num_draw_calls) sys.stdout.flush() gltfu.num_draw_calls = 0 st = glfw.GetTime() nframes += 1 glfw.SwapBuffers(window) _logger.info('FPS (avg): %f', ((nframes - 1) / (t - st))) _logger.info('MAX FRAME RENDER TIME: %f', dt_max) sys.stdout.flush() if openvr: vr_renderer.shutdown() glfw.DestroyWindow(window) glfw.Terminate()
def close(self): glfw.DestroyWindow(self._window) glfw.Terminate()
def show(game, title='poolvr.py *** GLViewer', window_size=(800, 600), gl_clear_color=(0.24, 0.18, 0.08, 0.0), before_frame_cb=None, after_frame_cb=None, double_buffered=True, playback_rate=1.0, screenshots_dir='', use_billboards=False): if not glfw.Init(): raise Exception('failed to initialize glfw') if not double_buffered: glfw.WindowHint(glfw.DOUBLEBUFFER, False) glfw.SwapInterval(0) window = glfw.CreateWindow(window_size[0], window_size[1], title) if not window: raise Exception('failed to create glfw window') glfw.MakeContextCurrent(window) _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION)) renderer = OpenGLRenderer(window_size=window_size, znear=0.1, zfar=1000) def on_resize(window, width, height): gl.glViewport(0, 0, width, height) renderer.window_size = (width, height) renderer.update_projection_matrix() glfw.SetWindowSizeCallback(window, on_resize) table = game.table physics = game.physics ball_meshes = table.setup_balls(game.ball_radius, game.ball_colors[:9], game.ball_positions, striped_balls=set(range(9, game.num_balls)), use_bb_particles=use_billboards) ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes] camera_world_matrix = renderer.camera_matrix camera_position = camera_world_matrix[3, :3] camera_position[1] = table.height + 0.19 camera_position[2] = 0.183 * table.length cue = PoolCue() cue.position[1] = table.height + 0.1 process_keyboard_input = init_keyboard(window) meshes = [table.mesh, floor_mesh, skybox_mesh] + ball_meshes #+ [cue] for mesh in meshes: mesh.init_gl(force=True) ball_positions = game.ball_positions ball_quaternions = game.ball_quaternions ball_mesh_positions = [mesh.world_matrix[3, :3] for mesh in ball_meshes] ball_mesh_rotations = [mesh.world_matrix[:3, :3].T for mesh in ball_meshes] ball_shadow_mesh_positions = [ mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes ] gl.glViewport(0, 0, window_size[0], window_size[1]) gl.glClearColor(*gl_clear_color) gl.glEnable(gl.GL_DEPTH_TEST) _logger.info('entering render loop...') stdout.flush() nframes = 0 max_frame_time = 0.0 lt = glfw.GetTime() t0 = physics.events[0].t t1 = physics.events[-1].t + min(2.0, physics.events[-1].T) pt = t0 while not glfw.WindowShouldClose(window) and pt <= t1: t = glfw.GetTime() dt = t - lt lt = t glfw.PollEvents() process_keyboard_input(dt, camera_world_matrix, cue=cue) renderer.process_input() with renderer.render(meshes=meshes) as frame_data: camera_position = frame_data.get('camera_position', renderer.camera_position) physics.eval_positions(pt, out=ball_positions) physics.eval_quaternions(pt, out=ball_quaternions) ball_positions[ ~physics. on_table] = camera_position # hacky way to only show balls that are on table for i, pos in enumerate(ball_positions): ball_mesh_positions[i][:] = pos ball_shadow_mesh_positions[i][0::2] = pos[0::2] for i, quat in enumerate(ball_quaternions): set_matrix_from_quaternion(quat, ball_mesh_rotations[i]) physics.step(dt) max_frame_time = max(max_frame_time, dt) if nframes == 0: st = glfw.GetTime() nframes += 1 pt += dt * playback_rate glfw.SwapBuffers(window) _logger.info( '...exited render loop: average FPS: %f, maximum frame time: %f', (nframes - 1) / (t - st), max_frame_time) mWidth, mHeight = glfw.GetWindowSize(window) gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1) pixels = gl.glReadPixels(0, 0, mWidth, mHeight, gl.GL_RGB, gl.GL_UNSIGNED_BYTE) pil_image = PIL.Image.frombytes('RGB', (mWidth, mHeight), pixels) pil_image = pil_image.transpose(PIL.Image.FLIP_TOP_BOTTOM) filename = title.replace(' ', '_') + '-screenshot.png' filepath = os.path.join(screenshots_dir, filename) pil_image.save(filepath) _logger.info('..saved screen capture to "%s"', filepath) try: renderer.shutdown() _logger.info('...shut down renderer') except Exception as err: _logger.error(err) glfw.DestroyWindow(window) glfw.Terminate()
Some platforms may not support backward compatibility mode, notably OS-X. If this crashes, your system does not support this mode. Unfortunately PyOpenGL doesn't always handle error cases well. """) version = 3,2 glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, version[0]) glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, version[1]) glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, 0) glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) window = glfw.CreateWindow(640, 480, 'Hello World') if not window: glfw.Terminate() print('Failed to create window') exit() glfw.MakeContextCurrent(window) print('GL:',GL.glGetString(GL.GL_VERSION)) print('GLFW3:',glfw.GetVersionString()) for iteration in range(100): if glfw.WindowShouldClose(window): break GL.glClearColor(0.2, 0.2, 0.2, 1.0) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) glfw.SwapBuffers(window) glfw.PollEvents()
def __del__(self): glfw.MakeContextCurrent(self._win) if self._renderer: self._renderer.dispose() glfw.Terminate() debug('GLView is being deleted: {}'.format(self))