facebook/StyleNeRF
34
1# Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.2#3# NVIDIA CORPORATION and its licensors retain all intellectual property4# and proprietary rights in and to this software, related documentation5# and any modifications thereto. Any use, reproduction, disclosure or6# distribution of this software and related documentation without an express7# license agreement from NVIDIA CORPORATION is strictly prohibited.8 9import time10import glfw11import OpenGL.GL as gl12from . import gl_utils13 14#----------------------------------------------------------------------------15 16class GlfwWindow: # pylint: disable=too-many-public-methods17 def __init__(self, *, title='GlfwWindow', window_width=1920, window_height=1080, deferred_show=True, close_on_esc=True):18 self._glfw_window = None19 self._drawing_frame = False20 self._frame_start_time = None21 self._frame_delta = 022 self._fps_limit = None23 self._vsync = None24 self._skip_frames = 025 self._deferred_show = deferred_show26 self._close_on_esc = close_on_esc27 self._esc_pressed = False28 self._drag_and_drop_paths = None29 self._capture_next_frame = False30 self._captured_frame = None31 32 # Create window.33 glfw.init()34 glfw.window_hint(glfw.VISIBLE, False)35 self._glfw_window = glfw.create_window(width=window_width, height=window_height, title=title, monitor=None, share=None)36 self._attach_glfw_callbacks()37 self.make_context_current()38 39 # Adjust window.40 self.set_vsync(False)41 self.set_window_size(window_width, window_height)42 if not self._deferred_show:43 glfw.show_window(self._glfw_window)44 45 def close(self):46 if self._drawing_frame:47 self.end_frame()48 if self._glfw_window is not None:49 glfw.destroy_window(self._glfw_window)50 self._glfw_window = None51 #glfw.terminate() # Commented out to play it nice with other glfw clients.52 53 def __del__(self):54 try:55 self.close()56 except:57 pass58 59 @property60 def window_width(self):61 return self.content_width62 63 @property64 def window_height(self):65 return self.content_height + self.title_bar_height66 67 @property68 def content_width(self):69 width, _height = glfw.get_window_size(self._glfw_window)70 return width71 72 @property73 def content_height(self):74 _width, height = glfw.get_window_size(self._glfw_window)75 return height76 77 @property78 def title_bar_height(self):79 _left, top, _right, _bottom = glfw.get_window_frame_size(self._glfw_window)80 return top81 82 @property83 def monitor_width(self):84 _, _, width, _height = glfw.get_monitor_workarea(glfw.get_primary_monitor())85 return width86 87 @property88 def monitor_height(self):89 _, _, _width, height = glfw.get_monitor_workarea(glfw.get_primary_monitor())90 return height91 92 @property93 def frame_delta(self):94 return self._frame_delta95 96 def set_title(self, title):97 glfw.set_window_title(self._glfw_window, title)98 99 def set_window_size(self, width, height):100 width = min(width, self.monitor_width)101 height = min(height, self.monitor_height)102 glfw.set_window_size(self._glfw_window, width, max(height - self.title_bar_height, 0))103 if width == self.monitor_width and height == self.monitor_height:104 self.maximize()105 106 def set_content_size(self, width, height):107 self.set_window_size(width, height + self.title_bar_height)108 109 def maximize(self):110 glfw.maximize_window(self._glfw_window)111 112 def set_position(self, x, y):113 glfw.set_window_pos(self._glfw_window, x, y + self.title_bar_height)114 115 def center(self):116 self.set_position((self.monitor_width - self.window_width) // 2, (self.monitor_height - self.window_height) // 2)117 118 def set_vsync(self, vsync):119 vsync = bool(vsync)120 if vsync != self._vsync:121 glfw.swap_interval(1 if vsync else 0)122 self._vsync = vsync123 124 def set_fps_limit(self, fps_limit):125 self._fps_limit = int(fps_limit)126 127 def should_close(self):128 return glfw.window_should_close(self._glfw_window) or (self._close_on_esc and self._esc_pressed)129 130 def skip_frame(self):131 self.skip_frames(1)132 133 def skip_frames(self, num): # Do not update window for the next N frames.134 self._skip_frames = max(self._skip_frames, int(num))135 136 def is_skipping_frames(self):137 return self._skip_frames > 0138 139 def capture_next_frame(self):140 self._capture_next_frame = True141 142 def pop_captured_frame(self):143 frame = self._captured_frame144 self._captured_frame = None145 return frame146 147 def pop_drag_and_drop_paths(self):148 paths = self._drag_and_drop_paths149 self._drag_and_drop_paths = None150 return paths151 152 def draw_frame(self): # To be overridden by subclass.153 self.begin_frame()154 # Rendering code goes here.155 self.end_frame()156 157 def make_context_current(self):158 if self._glfw_window is not None:159 glfw.make_context_current(self._glfw_window)160 161 def begin_frame(self):162 # End previous frame.163 if self._drawing_frame:164 self.end_frame()165 166 # Apply FPS limit.167 if self._frame_start_time is not None and self._fps_limit is not None:168 delay = self._frame_start_time - time.perf_counter() + 1 / self._fps_limit169 if delay > 0:170 time.sleep(delay)171 cur_time = time.perf_counter()172 if self._frame_start_time is not None:173 self._frame_delta = cur_time - self._frame_start_time174 self._frame_start_time = cur_time175 176 # Process events.177 glfw.poll_events()178 179 # Begin frame.180 self._drawing_frame = True181 self.make_context_current()182 183 # Initialize GL state.184 gl.glViewport(0, 0, self.content_width, self.content_height)185 gl.glMatrixMode(gl.GL_PROJECTION)186 gl.glLoadIdentity()187 gl.glTranslate(-1, 1, 0)188 gl.glScale(2 / max(self.content_width, 1), -2 / max(self.content_height, 1), 1)189 gl.glMatrixMode(gl.GL_MODELVIEW)190 gl.glLoadIdentity()191 gl.glEnable(gl.GL_BLEND)192 gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA) # Pre-multiplied alpha.193 194 # Clear.195 gl.glClearColor(0, 0, 0, 1)196 gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)197 198 def end_frame(self):199 assert self._drawing_frame200 self._drawing_frame = False201 202 # Skip frames if requested.203 if self._skip_frames > 0:204 self._skip_frames -= 1205 return206 207 # Capture frame if requested.208 if self._capture_next_frame:209 self._captured_frame = gl_utils.read_pixels(self.content_width, self.content_height)210 self._capture_next_frame = False211 212 # Update window.213 if self._deferred_show:214 glfw.show_window(self._glfw_window)215 self._deferred_show = False216 glfw.swap_buffers(self._glfw_window)217 218 def _attach_glfw_callbacks(self):219 glfw.set_key_callback(self._glfw_window, self._glfw_key_callback)220 glfw.set_drop_callback(self._glfw_window, self._glfw_drop_callback)221 222 def _glfw_key_callback(self, _window, key, _scancode, action, _mods):223 if action == glfw.PRESS and key == glfw.KEY_ESCAPE:224 self._esc_pressed = True225 226 def _glfw_drop_callback(self, _window, paths):227 self._drag_and_drop_paths = paths228 229#----------------------------------------------------------------------------230 