Skip to content

Commit

Permalink
Merge pull request #1989 from pupil-labs/develop
Browse files Browse the repository at this point in the history
Pupil v2.2 Release Candidate 1
Patrick Faion authored Aug 4, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents ec61718 + 35fa2d1 commit aec6a18
Showing 36 changed files with 555 additions and 262 deletions.
205 changes: 125 additions & 80 deletions pupil_src/launchables/eye.py
Original file line number Diff line number Diff line change
@@ -126,6 +126,7 @@ def eye(
from pyglui import ui, graph, cygl
from pyglui.cygl.utils import draw_points, RGBA, draw_polyline
from pyglui.cygl.utils import Named_Texture
import gl_utils
from gl_utils import basic_gl_setup, adjust_gl_view, clear_gl_screen
from gl_utils import make_coord_system_pixel_based
from gl_utils import make_coord_system_norm_based
@@ -175,7 +176,7 @@ def interrupt_handler(sig, frame):

icon_bar_width = 50
window_size = None
hdpi_factor = 1.0
content_scale = 1.0

# g_pool holds variables for this process
g_pool = SimpleNamespace()
@@ -213,7 +214,7 @@ def get_timestamp():
default_capture_name = "UVC_Source"
default_capture_settings = {
"preferred_names": preferred_names,
"frame_size": (320, 240),
"frame_size": (192, 192),
"frame_rate": 120,
}

@@ -231,25 +232,95 @@ def get_timestamp():
("Roi", {}),
]

def consume_events_and_render_buffer():
glfw.glfwMakeContextCurrent(main_window)
clear_gl_screen()

glViewport(0, 0, *g_pool.camera_render_size)
for p in g_pool.plugins:
p.gl_display()

glViewport(0, 0, *window_size)
# render graphs
fps_graph.draw()
cpu_graph.draw()

# render GUI
try:
clipboard = glfw.glfwGetClipboardString(main_window).decode()
except AttributeError: # clipboard is None, might happen on startup
clipboard = ""
g_pool.gui.update_clipboard(clipboard)
user_input = g_pool.gui.update()
if user_input.clipboard != clipboard:
# only write to clipboard if content changed
glfw.glfwSetClipboardString(main_window, user_input.clipboard.encode())

for button, action, mods in user_input.buttons:
x, y = glfw.glfwGetCursorPos(main_window)
pos = glfw.window_coordinate_to_framebuffer_coordinate(
main_window, x, y, cached_scale=None
)
pos = normalize(pos, g_pool.camera_render_size)
if g_pool.flip:
pos = 1 - pos[0], 1 - pos[1]
# Position in img pixels
pos = denormalize(pos, g_pool.capture.frame_size)

for plugin in g_pool.plugins:
if plugin.on_click(pos, button, action):
break

for key, scancode, action, mods in user_input.keys:
for plugin in g_pool.plugins:
if plugin.on_key(key, scancode, action, mods):
break

for char_ in user_input.chars:
for plugin in g_pool.plugins:
if plugin.on_char(char_):
break

# update screen
glfw.glfwSwapBuffers(main_window)

# Callback functions
def on_resize(window, w, h):
nonlocal window_size
nonlocal hdpi_factor
nonlocal content_scale

# Always clear buffers on resize to make sure that there are no overlapping
# artifacts from previous frames.
gl_utils.glClear(gl_utils.GL_COLOR_BUFFER_BIT)
gl_utils.glClearColor(0, 0, 0, 1)

active_window = glfw.glfwGetCurrentContext()
glfw.glfwMakeContextCurrent(window)
hdpi_factor = glfw.getHDPIFactor(window)
g_pool.gui.scale = g_pool.gui_user_scale * hdpi_factor
content_scale = glfw.get_content_scale(window)
framebuffer_scale = glfw.get_framebuffer_scale(window)
g_pool.gui.scale = content_scale
window_size = w, h
g_pool.camera_render_size = w - int(icon_bar_width * g_pool.gui.scale), h
g_pool.gui.update_window(w, h)
g_pool.gui.collect_menus()
for g in g_pool.graphs:
g.scale = hdpi_factor
g.scale = content_scale
g.adjust_window_size(w, h)
adjust_gl_view(w, h)
glfw.glfwMakeContextCurrent(active_window)

# Minimum window size required, otherwise parts of the UI can cause openGL
# issues with permanent effects. Depends on the content scale, which can
# potentially be dynamically modified, so we re-adjust the size limits every
# time here.
min_size = int(2 * icon_bar_width * g_pool.gui.scale / framebuffer_scale)
glfw.glfwSetWindowSizeLimits(
window, min_size, min_size, glfw.GLFW_DONT_CARE, glfw.GLFW_DONT_CARE
)

# Needed, to update the window buffer while resizing
consume_events_and_render_buffer()

def on_window_key(window, key, scancode, action, mods):
g_pool.gui.update_key(key, scancode, action, mods)

@@ -263,7 +334,9 @@ def on_window_mouse_button(window, button, action, mods):
g_pool.gui.update_button(button, action, mods)

def on_pos(window, x, y):
x, y = x * hdpi_factor, y * hdpi_factor
x, y = glfw.window_coordinate_to_framebuffer_coordinate(
window, x, y, cached_scale=None
)
g_pool.gui.update_mouse(x, y)

pos = x, y
@@ -321,31 +394,31 @@ def toggle_general_settings(collapsed):

# Initialize glfw
glfw.glfwInit()
glfw.glfwWindowHint(glfw.GLFW_SCALE_TO_MONITOR, glfw.GLFW_TRUE)
if hide_ui:
glfw.glfwWindowHint(glfw.GLFW_VISIBLE, 0) # hide window
title = "Pupil Capture - eye {}".format(eye_id)

width, height = session_settings.get("window_size", (640 + icon_bar_width, 480))
# Pupil Cam1 uses 4:3 resolutions. Pupil Cam2 and Cam3 use 1:1 resolutions.
# As all Pupil Core and VR/AR add-ons are shipped with Pupil Cam2 and Cam3
# cameras, we adjust the default eye window size to a 1:1 content aspect ratio.
# The size of 500 was chosen s.t. the menu still fits.
default_window_size = 500 + icon_bar_width, 500
width, height = session_settings.get("window_size", default_window_size)

main_window = glfw.glfwCreateWindow(width, height, title, None, None)
window_pos = session_settings.get("window_position", window_position_default)
glfw.glfwSetWindowPos(main_window, window_pos[0], window_pos[1])
glfw.glfwMakeContextCurrent(main_window)
cygl.utils.init()

# UI callback functions
def set_scale(new_scale):
g_pool.gui_user_scale = new_scale
on_resize(main_window, *glfw.glfwGetFramebufferSize(main_window))

# gl_state settings
basic_gl_setup()
g_pool.image_tex = Named_Texture()
g_pool.image_tex.update_from_ndarray(np.ones((1, 1), dtype=np.uint8) + 125)

# setup GUI
g_pool.gui = ui.UI()
g_pool.gui_user_scale = session_settings.get("gui_scale", 1.0)
g_pool.menubar = ui.Scrolling_Menu(
"Settings", pos=(-500, 0), size=(-icon_bar_width, 0), header_pos="left"
)
@@ -356,22 +429,30 @@ def set_scale(new_scale):
g_pool.gui.append(g_pool.iconbar)

general_settings = ui.Growing_Menu("General", header_pos="headline")
general_settings.append(
ui.Selector(
"gui_user_scale",
g_pool,
setter=set_scale,
selection=[0.8, 0.9, 1.0, 1.1, 1.2],
label="Interface Size",
)
)

def set_window_size():
# Get current capture frame size
f_width, f_height = g_pool.capture.frame_size
f_width *= 2
f_height *= 2
f_width += int(icon_bar_width * g_pool.gui.scale)
glfw.glfwSetWindowSize(main_window, f_width, f_height)
# Eye camera resolutions are too small to be used as default window sizes.
# We use double their size instead.
frame_scale_factor = 2
f_width *= frame_scale_factor
f_height *= frame_scale_factor

# Get current display scale factor
content_scale = glfw.get_content_scale(main_window)
framebuffer_scale = glfw.get_framebuffer_scale(main_window)
display_scale_factor = content_scale / framebuffer_scale

# Scale the capture frame size by display scale factor
f_width *= display_scale_factor
f_height *= display_scale_factor

# Increas the width to account for the added scaled icon bar width
f_width += icon_bar_width * display_scale_factor

# Set the newly calculated size (scaled capture frame size + scaled icon bar width)
glfw.glfwSetWindowSize(main_window, int(f_width), int(f_height))

general_settings.append(ui.Button("Reset window size", set_window_size))
general_settings.append(ui.Switch("flip", g_pool, label="Flip image display"))
@@ -403,7 +484,6 @@ def set_window_size():
)
icon.tooltip = "General Settings"
g_pool.iconbar.append(icon)
toggle_general_settings(False)

plugins_to_load = session_settings.get("loaded_plugins", default_plugins)
if overwrite_cap_settings:
@@ -420,6 +500,8 @@ def set_window_size():
g_pool.plugin_by_name[default_capture_name], default_capture_settings
)

toggle_general_settings(True)

g_pool.writer = None

# Register callbacks main_window
@@ -434,6 +516,11 @@ def set_window_size():

# load last gui configuration
g_pool.gui.configuration = session_settings.get("ui_config", {})
# If previously selected plugin was not loaded this time, we will have an
# expanded menubar without any menu selected. We need to ensure the menubar is
# collapsed in this case.
if all(submenu.collapsed for submenu in g_pool.menubar.elements):
g_pool.menubar.collapsed = True

# set up performance graphs
pid = os.getpid()
@@ -603,56 +690,7 @@ def window_should_update():
# GL drawing
if window_should_update():
if is_window_visible(main_window):
glfw.glfwMakeContextCurrent(main_window)
clear_gl_screen()

glViewport(0, 0, *g_pool.camera_render_size)
for p in g_pool.plugins:
p.gl_display()

glViewport(0, 0, *window_size)
# render graphs
fps_graph.draw()
cpu_graph.draw()

# render GUI
try:
clipboard = glfw.glfwGetClipboardString(main_window).decode()
except AttributeError: # clipboard is None, might happen on startup
clipboard = ""
g_pool.gui.update_clipboard(clipboard)
user_input = g_pool.gui.update()
if user_input.clipboard != clipboard:
# only write to clipboard if content changed
glfw.glfwSetClipboardString(
main_window, user_input.clipboard.encode()
)

for button, action, mods in user_input.buttons:
x, y = glfw.glfwGetCursorPos(main_window)
pos = x * hdpi_factor, y * hdpi_factor
pos = normalize(pos, g_pool.camera_render_size)
if g_pool.flip:
pos = 1 - pos[0], 1 - pos[1]
# Position in img pixels
pos = denormalize(pos, g_pool.capture.frame_size)

for plugin in g_pool.plugins:
if plugin.on_click(pos, button, action):
break

for key, scancode, action, mods in user_input.keys:
for plugin in g_pool.plugins:
if plugin.on_key(key, scancode, action, mods):
break

for char_ in user_input.chars:
for plugin in g_pool.plugins:
if plugin.on_char(char_):
break

# update screen
glfw.glfwSwapBuffers(main_window)
consume_events_and_render_buffer()
glfw.glfwPollEvents()

# END while running
@@ -665,7 +703,6 @@ def window_should_update():

session_settings["loaded_plugins"] = g_pool.plugins.get_initializers()
# save session persistent settings
session_settings["gui_scale"] = g_pool.gui_user_scale
session_settings["flip"] = g_pool.flip
session_settings["display_mode"] = g_pool.display_mode
session_settings["ui_config"] = g_pool.gui.configuration
@@ -676,7 +713,15 @@ def window_should_update():
session_settings["window_position"] = glfw.glfwGetWindowPos(main_window)
session_window_size = glfw.glfwGetWindowSize(main_window)
if 0 not in session_window_size:
session_settings["window_size"] = session_window_size
f_width, f_height = session_window_size
if platform.system() in ("Windows", "Linux"):
# Store unscaled window size as the operating system will scale the
# windows appropriately during launch on Windows and Linux.
f_width, f_height = (
f_width / content_scale,
f_height / content_scale,
)
session_settings["window_size"] = int(f_width), int(f_height)

session_settings.close()

Loading

0 comments on commit aec6a18

Please sign in to comment.