vkf_window Module

Windows showing a scene of frames, with its simulation time, as OpenFrames' FrameManager and WindowProxy (for now with a single viewport, which holds the views as OpenFrames' RenderRectangle does; OpenFrames' grid of viewports comes later).

A FrameManager holds the root frame of a scene. A WindowProxy shows one: in a window of its own, or in a host's native window (e.g. a Qt QWindow's winId()), in which case the host forwards the window's events (mouse, scroll, key, resize, close). Each frame() advances the simulation clock, updates the frames (followed trajectories), copies their positions and attitudes to the renderer, places the camera for the current View and draws.

Several windows can show one scene (its render nodes are shared). The scene is updated once per simulation time: a window whose time is the one the scene was last updated for, by another window since this one's last frame, doesn't update it again (update). Windows whose clocks are synchronized (synchronize) render the same time, their master's at its last frame, so they show the scene in the same state and update it once per round of frames, also while the time is paused (then each round still updates once, for data added meanwhile).

A window has a list of views (add_view, select_view, next_view, ...); each keeps its own camera (the trackball) while another one is shown. Without views, a default view of the scene's root frame is used.

Keyboard and mouse (OpenFrames' WindowProxy callbacks, setKeyPressCallback, setMouseMotionCallback, setButtonPressCallback, setButtonReleaseCallback): a program's WindowEventHandler, an extension overriding the procedures it wants (key_press, key_release, mouse_motion, button_press, button_release), is given the window's events (set_event_handler), also those a host forwards. They're passed on after the frame in which they arrived (from frame()), so a handler may change anything, the window included (its views, its time, closing it). Positions are in -1 to 1 across the window, y up, as OpenFrames'. The built-in keys, as OpenFrames': v the next view, V the previous one, the space bar resets the view (unless the handler's key_press says it handled the key, or set_default_keys(.false.)). The mouse moves the camera (the trackball); the keys don't.

Each frame, the handler's before_update(window, t) is called first, with the frame's time, before the scene is updated for it and the camera placed: the data a program computes for time t (trajectories' points, frames' positions, colors) changed there is uploaded, and followed by the views, in this frame. Then before_draw(window, t) is called once the scene is at the frame's time and the camera is placed (the trackball's moves included), just before drawing: what it changes (HUD text, labels, frames' positions) is in this frame, e.g. a callout kept next to a moving object (screen_position) without lagging a frame behind, whoever runs the frame loop (the program or a host GUI). (Trajectories' points changed in before_draw are drawn from the next frame: change them in before_update.)

The camera (OpenFrames' trackball getTransformation / setTransformation): get_camera and set_camera (eye, center, up in the shown view's frame, or in its root frame with in_root). Smooth transitions (not in OpenFrames): set_camera with a duration flies there, and with set_view_transition(seconds) (default 0: a cut, as OpenFrames) changing the view (select_view, next_view, previous_view, the keys v and V; or with their own duration) and resetting it (the space bar) fly from the camera shown to the new one. A flight moves the center along a straight line, the distance geometrically and the orientation by the shortest rotation, eased in and out, in the root frame (both views' frames as they move), over the wall-clock time given (the video's while recording); a mouse press, stop_transition or another flight ends it.

Video recording (not in OpenFrames, which has only screenshots): start_recording(file, fps) ... stop_recording() records the frames drawn to a video file, encoded by ffmpeg (conda-forge's, in the pixi environment; or ffmpeg, or VKFRAMES_FFMPEG): the frames are piped to it as raw pixels (no image files; see vkf_viewer_record_start in src/vsg/vkf_layer.cpp). While recording, the window's time is the video's: each frame advances the simulation time by exactly scale/fps, and camera flights and animated shaders (pulsing markers, highlighted lines) by 1/fps s, so the video plays smoothly at its own speed however long a frame takes to draw (or to encode). Stopping goes back to the wall clock from where the video was. A watermark (e.g. a logo) can be drawn over the video by ffmpeg (watermark). The video's size is its first frame's (a window resized while recording is cropped or padded).

The mouse's sensitivity: set_zoom_speed (the zoom per wheel or trackpad step and per right drag; default 1, VSG's) and set_camera_throw (the camera keeps moving after a drag released while moving; default on).

Picking (not in OpenFrames): pick(x, y, hits) gives what is under a point of the window (x, y as the event handler's: -1 to 1, y up), nearest first, as drawn at the last frame: trajectory curves (the point and the time there), segments and markers (within a few pixels: tolerance, plus half a line's width or a marker's size), bodies (the point on the surface, with latitude and longitude) and frames' origins. Each frame of the scene tests its own contents (pick, vkf_pick); nothing is done until pick is called. cursor_ray(x, y, origin, direction) gives the ray from the eye through a point of the window (root frame), e.g. to place something where the cursor points (vkf_pick's ray_plane, ray_sphere, ray_line).

Handles (vkf_handles: DragHandle, e.g. VectorHandle): while a scene shown in a window has handles, the window looks for one under the cursor at each mouse move (a pick of PICK_HANDLE only), hovers it (drawn brighter) and arms a grab: a left button press then grabs the handle instead of moving the camera, the moves drag it (drag, with the cursor's ray) and the release lets it go. The handler is told (handle_drag: DRAG_START, DRAG_MOVE, DRAG_END), not given those presses, moves and releases (button_press, mouse_motion, button_release). A handle is dragged from the frame after the event's, as other events are handled. The middle and right buttons move the camera over handles too.


Uses

  • module~~vkf_window~~UsesGraph module~vkf_window vkf_window iso_c_binding iso_c_binding module~vkf_window->iso_c_binding iso_fortran_env iso_fortran_env module~vkf_window->iso_fortran_env module~vkf_clock vkf_clock module~vkf_window->module~vkf_clock module~vkf_diagnostics vkf_diagnostics module~vkf_window->module~vkf_diagnostics module~vkf_frames vkf_frames module~vkf_window->module~vkf_frames module~vkf_gui vkf_gui module~vkf_window->module~vkf_gui module~vkf_handles vkf_handles module~vkf_window->module~vkf_handles module~vkf_hud vkf_hud module~vkf_window->module~vkf_hud module~vkf_layer vkf_layer module~vkf_window->module~vkf_layer module~vkf_math vkf_math module~vkf_window->module~vkf_math module~vkf_pick vkf_pick module~vkf_window->module~vkf_pick module~vkf_sky vkf_sky module~vkf_window->module~vkf_sky module~vkf_text vkf_text module~vkf_window->module~vkf_text module~vkf_view vkf_view module~vkf_window->module~vkf_view module~vkf_clock->iso_fortran_env module~vkf_clock->module~vkf_math module~vkf_diagnostics->iso_c_binding module~vkf_diagnostics->iso_fortran_env module~vkf_diagnostics->module~vkf_layer module~vkf_diagnostics->module~vkf_math module~vkf_frames->iso_c_binding module~vkf_frames->module~vkf_layer module~vkf_frames->module~vkf_math module~vkf_frames->module~vkf_pick module~vkf_frames->module~vkf_text module~vkf_follower vkf_follower module~vkf_frames->module~vkf_follower module~vkf_geometry vkf_geometry module~vkf_frames->module~vkf_geometry module~vkf_trajectory vkf_trajectory module~vkf_frames->module~vkf_trajectory module~vkf_gui->iso_c_binding module~vkf_gui->module~vkf_layer module~vkf_gui->module~vkf_math module~vkf_handles->iso_c_binding module~vkf_handles->module~vkf_frames module~vkf_handles->module~vkf_layer module~vkf_handles->module~vkf_math module~vkf_handles->module~vkf_pick module~vkf_artists vkf_artists module~vkf_handles->module~vkf_artists module~vkf_handles->module~vkf_geometry module~vkf_handles->module~vkf_trajectory module~vkf_hud->module~vkf_frames module~vkf_hud->module~vkf_math module~vkf_layer->iso_c_binding module~vkf_math->iso_fortran_env module~vkf_pick->module~vkf_math module~vkf_sky->iso_c_binding module~vkf_sky->module~vkf_layer module~vkf_sky->module~vkf_math module~vkf_sky->module~vkf_text module~vkf_files vkf_files module~vkf_sky->module~vkf_files module~vkf_text->iso_c_binding module~vkf_text->module~vkf_layer module~vkf_text->module~vkf_math module~vkf_text->module~vkf_files module~vkf_view->module~vkf_frames module~vkf_view->module~vkf_math module~vkf_artists->iso_c_binding module~vkf_artists->module~vkf_frames module~vkf_artists->module~vkf_layer module~vkf_artists->module~vkf_math module~vkf_artists->module~vkf_pick module~vkf_artists->module~vkf_trajectory module~vkf_line_chain vkf_line_chain module~vkf_artists->module~vkf_line_chain module~vkf_follower->module~vkf_math module~vkf_follower->module~vkf_trajectory module~vkf_geometry->iso_c_binding module~vkf_geometry->module~vkf_layer module~vkf_geometry->module~vkf_math module~vkf_trajectory->iso_c_binding module~vkf_trajectory->iso_fortran_env module~vkf_trajectory->module~vkf_math module~vkf_line_chain->iso_c_binding module~vkf_line_chain->module~vkf_layer module~vkf_line_chain->module~vkf_math

Used by

  • module~~vkf_window~~UsedByGraph module~vkf_window vkf_window module~vkframes vkframes module~vkframes->module~vkf_window

Variables

Type Visibility Attributes Name Initial
integer, public, parameter :: DRAG_END = 3

a handle's drag (handle_drag): grabbed, moved, released

integer, public, parameter :: DRAG_MOVE = 2

a handle's drag (handle_drag): grabbed, moved, released

integer, public, parameter :: DRAG_START = 1

a handle's drag (handle_drag): grabbed, moved, released

integer, public, parameter :: KEY_BACKSPACE = int(z'FF08')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_DELETE = int(z'FFFF')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_DOWN = int(z'FF54')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_END = int(z'FF57')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_ESCAPE = int(z'FF1B')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_F1 = int(z'FFBE')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_HOME = int(z'FF50')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_INSERT = int(z'FF63')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_LEFT = int(z'FF51')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_PAGE_DOWN = int(z'FF56')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_PAGE_UP = int(z'FF55')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_RETURN = int(z'FF0D')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_RIGHT = int(z'FF53')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_SPACE = 32

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_TAB = int(z'FF09')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: KEY_UP = int(z'FF52')

keys (WindowEventHandler): printable keys are their characters, iachar('a'), iachar('A') with shift; the others (VSG's key symbols): F2 to F12: KEY_F1 + 1 to 11

integer, public, parameter :: MOD_ALT = 8

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOD_CAPS_LOCK = 2

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOD_CONTROL = 4

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOD_META = 128

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOD_NUM_LOCK = 16

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOD_SHIFT = 1

modifier keys held (bits of modifiers: iand(modifiers, MOD_SHIFT) /= 0) bits of modifiers

integer, public, parameter :: MOUSE_LEFT = 1

mouse buttons (WindowEventHandler, mouse) button numbers

integer, public, parameter :: MOUSE_MIDDLE = 2

mouse buttons (WindowEventHandler, mouse) button numbers

integer, public, parameter :: MOUSE_MOVE = 1

mouse event kinds for mouse mouse kind

integer, public, parameter :: MOUSE_PRESS = 2

mouse event kinds for mouse mouse kind

integer, public, parameter :: MOUSE_RELEASE = 3

mouse event kinds for mouse mouse kind

integer, public, parameter :: MOUSE_RIGHT = 3

mouse buttons (WindowEventHandler, mouse) button numbers


Interfaces

public interface FrameManager

The FrameManager constructor: FrameManager(...) makes one (see new_frame_manager for its arguments).

  • private function new_frame_manager(frame) result(fm)

    A frame manager for the scene with root frame (optional).

    Arguments

    Type IntentOptional Attributes Name
    class(ReferenceFrame), intent(in), optional, target :: frame

    the root frame (not owned)

    Return Value type(FrameManager)


Derived Types

type, private ::  CameraFlight

A camera flight (see the module documentation): from camera start (in view from's frame) to camera finish (in view to's).

Components

Type Visibility Attributes Name Initial
logical, public :: active = .false.

flying

real(kind=wp), public :: duration = 0.0_wp

s

real(kind=wp), public :: finish(3,3) = 0.0_wp

(columns: eye, center, up)

type(View), public, pointer :: from => null()

the views flown from and to

real(kind=wp), public :: start(3,3) = 0.0_wp

(columns: eye, center, up)

real(kind=wp), public :: started = 0.0_wp

the window's wall time at the start (s; window_wall)

type(View), public, pointer :: to => null()

the views flown from and to

type, public ::  FrameManager

The root frame of a scene (OpenFrames' FrameManager). The frame is not owned: it must stay alive while managed.

Components

Type Visibility Attributes Name Initial
class(ReferenceFrame), private, pointer :: root => null()

the scene's root frame (not owned)

real(kind=wp), private :: updated_time = 0.0_wp

the time of the last one

integer, private :: updates = 0

scene updates so far

Constructor

The FrameManager constructor: FrameManager(...) makes one (see new_frame_manager for its arguments).

private function new_frame_manager (frame)

A frame manager for the scene with root frame (optional).

Type-Bound Procedures

procedure, public :: frame => fm_frame
procedure, public :: num_updates => fm_num_updates
procedure, public :: set_frame => fm_set_frame
procedure, public :: update => fm_update

type, private ::  HUDEntry

A HUD text shown in a window, with the window's node for it.

Components

Type Visibility Attributes Name Initial
character(len=:), public, allocatable :: font

the font its node was made with

type(c_ptr), public :: node = c_null_ptr

the window's label node for it (null until made)

type(HUDText), public, pointer :: p => null()

the HUD text (not owned)

integer, public :: revision = -1

the text's revision last shown

type, private ::  ViewPointer

One of a window's views: a pointer to it (Fortran has no arrays of pointers).

Components

Type Visibility Attributes Name Initial
type(View), public, pointer :: p => null()

the view (not owned)

type, public ::  WindowEventHandler

A program's handler of a window's keyboard and mouse events (see the module documentation): extend it and override the procedures wanted (the others do nothing).

Type-Bound Procedures

procedure, public :: before_draw => handler_before_draw
procedure, public :: before_update => handler_before_update
procedure, public :: button_press => handler_button_press
procedure, public :: button_release => handler_button_release
procedure, public :: handle_drag => handler_handle_drag
procedure, public :: key_press => handler_key_press
procedure, public :: key_release => handler_key_release
procedure, public :: mouse_motion => handler_mouse_motion

type, public ::  WindowProxy

A window showing a scene (see the module documentation).

Components

Type Visibility Attributes Name Initial
real(kind=wp), private :: background(3) = [0.0_wp, 0.0_wp, 0.0_wp]

background color [r, g, b] (0 to 1)

logical, private :: camera_throw_ = .true.

the camera keeps moving after a drag released while moving

type(SimulationClock), private :: clock_

the window's simulation clock

integer, private :: current = 0

number of views; the current one (0: none)

logical, private :: default_keys_ = .true.

the built-in keys on

type(View), private :: default_view

used when there are no views

class(DragHandle), private, pointer :: dragged_handle => null()

the handle grabbed (not owned)

type(CameraFlight), private :: flight

the camera flight (when active)

real(kind=wp), private :: fps_ = 0.0_wp

frames per second (the last count's)

real(kind=wp), private :: frame_ms_ = 0.0_wp

milliseconds between frames (the last count's)

class(WindowEventHandler), private, pointer :: handler => null()

the program's event handler (not owned)

integer, private :: height_ = 1

logical size (for the views' aspect ratio)

logical, private :: hosted = .false.

in a host's window (its size from resize)

class(DragHandle), private, pointer :: hovered_handle => null()

the handle under the cursor (not owned)

type(HUDEntry), private, allocatable :: huds(:)

the HUD texts shown (first n_huds used)

real(kind=wp), private :: last_frame_ms = 0.0_wp

the last frame()'s duration (ms)

real(kind=wp), private :: light_ambient_(3) = 0.2_wp

[r, g, b]

real(kind=wp), private :: light_diffuse_(3) = 1.0_wp

[r, g, b]

logical, private :: light_on = .true.

the window's light enabled (no frame's light source)

real(kind=wp), private :: light_position_(4) = [0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp]

eye coordinates (w 0: directional)

real(kind=wp), private :: light_specular_(3) = 0.0_wp

[r, g, b]

integer, private :: n_huds = 0

number of HUD texts

integer, private :: n_views = 0

number of views; the current one (0: none)

real(kind=wp), private :: pixel_ratio_ = 1.0_wp

framebuffer pixels per window unit (a host's window)

integer, private :: rate_frames = 0

frames since then

real(kind=wp), private :: rate_start = -1.0_wp

the wall time the frames are counted from (s; -1: none)

real(kind=wp), private :: record_fps = 30.0_wp

the video's frames per second

integer(kind=int64), private :: record_frames = 0_int64

frames drawn while recording

real(kind=wp), private :: record_wall = 0.0_wp

the wall time at the start (s)

logical, private :: recording_ = .false.

recording (start_recording)

logical, private :: running = .false.

open, and not closed by the user

type(FrameManager), private, pointer :: scene => null()

the scene shown (not owned)

logical, private :: scene_added = .false.

scene, sky, HUD texts given to the viewer

integer, private :: scene_seen = -1

the scene's updates at this window's last frame

type(View), private, pointer :: shown => null()

the view whose camera is in the renderer

type(SkySphere), private, pointer :: sky_ => null()

the background sky

real(kind=wp), private :: switch_duration = -1.0_wp

s, for the next view change (< 0: transition_)

real(kind=wp), private :: transition_ = 0.0_wp

s, for view changes and resets

type(c_ptr), private :: viewer_ = c_null_ptr

the rendering layer's viewer (null while closed)

type(ViewPointer), private, allocatable :: views(:)

not owned (first n_views used)

integer, private :: width_ = 1

logical size (for the views' aspect ratio)

real(kind=wp), private :: zoom_speed_ = 1.0_wp

the trackball's zoom per scroll step and drag (1: VSG's)

Type-Bound Procedures

procedure, public :: add_hud_text
procedure, public :: add_view
procedure, public :: background_color
procedure, public :: camera_throw
procedure, public :: capture
procedure, public :: clear_event_handler
procedure, public :: clock
procedure, public :: close
procedure, public :: current_view
procedure, public :: cursor_ray
procedure, public :: default_keys
procedure, public :: device_info
procedure, public :: event_handler
procedure, public :: frame
procedure, public :: get_camera
procedure, public :: gui => window_gui
procedure, public :: in_transition
procedure, public :: is_open
procedure, public :: is_recording
procedure, public :: is_time_paused
procedure, public :: key
procedure, public :: light_ambient
procedure, public :: light_diffuse
procedure, public :: light_position
procedure, public :: light_specular
procedure, public :: mouse
procedure, public :: next_view
procedure, public :: num_views
procedure, public :: open
procedure, public :: pause_time
procedure, public :: pick => window_pick
procedure, public :: pixel_ratio
procedure, public :: previous_view
procedure, public :: recorded_frames
procedure, public :: remove_all_views
procedure, public :: remove_hud_text
procedure, public :: remove_view
procedure, public :: render_stats
procedure, public :: resize
procedure, public :: run
procedure, public :: scene_counts
procedure, public :: screen_position
procedure, public :: scroll
procedure, public :: select_view
procedure, public :: set_background_color
procedure, public :: set_camera
procedure, public :: set_camera_throw
procedure, public :: set_default_keys
procedure, public :: set_event_handler
procedure, public :: set_light_ambient
procedure, public :: set_light_diffuse
procedure, public :: set_light_position
procedure, public :: set_light_specular
procedure, public :: set_scene
procedure, public :: set_sky
procedure, public :: set_time
procedure, public :: set_time_range
procedure, public :: set_time_scale
procedure, public :: set_view_transition
procedure, public :: set_zoom_speed
procedure, public :: sky
procedure, public :: start_recording
procedure, public :: stop_recording
procedure, public :: stop_transition
procedure, public :: time
procedure, public :: time_range
procedure, public :: time_scale
procedure, public :: view => window_view
procedure, public :: view_transition
procedure, public :: viewer => window_viewer
procedure, public :: zoom_speed

Functions

private function aspect_ratio(self)

The width / height of the window drawn: a host's (from resize), or of the window's own, as it is now.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private pure function background_color(self) result(rgb)

The background color [r, g, b].

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp), (3)

private pure function camera_throw(self)

Whether the camera keeps moving after a released drag (set_camera_throw).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private function capture(self, file) result(ok)

Save the last frame as an image (format from the file extension, e.g. .png). Returns false on failure.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
character(len=*), intent(in) :: file

image file name (e.g. .png)

Return Value logical

private function clock(self) result(c)

The window's simulation clock (e.g. to synchronize it with another window's).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in), target :: self

Return Value type(SimulationClock), pointer

private function current_view(self) result(v)

The view shown (the default view of the scene's root if none were added).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in), target :: self

Return Value type(View), pointer

private function cursor_ray(self, x, y, origin, direction) result(ok)

The ray from the eye through point (x, y) of the window (-1 to 1 across it, y up: as the event handler's positions), in the root frame, as at the last frame: its origin (the eye; in an orthographic view, on the eye's plane) and its direction (a unit vector). False before the first frame. E.g. where the cursor points on a plane: vkf_pick's ray_plane.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
real(kind=wp), intent(in) :: x

-1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

-1 to 1 across the window, y up

real(kind=wp), intent(out) :: origin(3)

root frame (direction: a unit vector)

real(kind=wp), intent(out) :: direction(3)

root frame (direction: a unit vector)

Return Value logical

private pure function default_keys(self)

Whether the built-in keys are on (set_default_keys).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private function device_info(self) result(info)

The window's Vulkan device and driver (see vkf_diagnostics); '' while it isn't open.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value type(DeviceInfo)

private function encoder_options(codec, quality) result(args)

ffmpeg's encoder options for codec and quality (see start_recording).

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in), optional :: codec

an ffmpeg encoder (default libx264)

integer, intent(in), optional :: quality

the CRF (default 18; limited to 0 to 63)

Return Value character(len=:), allocatable

private function event_handler(self) result(handler)

The event handler (null if none).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value class(WindowEventHandler), pointer

private function fm_frame(self) result(root)

The root frame (null if none).

Arguments

Type IntentOptional Attributes Name
class(FrameManager), intent(in) :: self

Return Value class(ReferenceFrame), pointer

private pure function fm_num_updates(self) result(n)

Number of scene updates so far (update).

Arguments

Type IntentOptional Attributes Name
class(FrameManager), intent(in) :: self

Return Value integer

private function frame(self) result(running)

Render one frame: advance the clock, update the frames and draw. Returns false once the window has been closed (or on failure).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

Return Value logical

private pure function in_transition(self)

True while the camera is flying (a transition).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private pure function is_open(self)

Whether the window is open (not closed, by the program or the user).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private pure function is_recording(self)

Whether the window is recording a video.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private function is_time_paused(self)

Whether the simulation time is paused.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value logical

private pure function light_ambient(self) result(rgb)

The ambient color of the window's light [r, g, b].

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp), (3)

private pure function light_diffuse(self) result(rgb)

The diffuse color of the window's light [r, g, b].

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp), (3)

private pure function light_position(self) result(p)

The position of the window's light (see set_light_position).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp), (4)

private pure function light_specular(self) result(rgb)

The specular color of the window's light [r, g, b].

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp), (3)

private function new_frame_manager(frame) result(fm)

A frame manager for the scene with root frame (optional).

Arguments

Type IntentOptional Attributes Name
class(ReferenceFrame), intent(in), optional, target :: frame

the root frame (not owned)

Return Value type(FrameManager)

private pure function num_views(self)

Number of views added.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value integer

private function open(self, width, height, title, native_window, pixel_ratio, vsync) result(ok)

Open the window: width x height (logical pixels) titled title, or, with native_window (a host window's native handle) and its pixel_ratio, render into that window. vsync (default true): frames are presented at the display's refresh; false: as soon as they are ready (where the driver allows it), e.g. to measure frame times. Returns false on failure.

Read more…

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer, intent(in) :: width

window units (logical pixels)

integer, intent(in) :: height

window units (logical pixels)

character(len=*), intent(in), optional :: title

default 'vkframes'

integer(kind=c_long_long), intent(in), optional :: native_window

host window's handle (0: own window)

real(kind=wp), intent(in), optional :: pixel_ratio

framebuffer pixels per window unit (default 1)

logical, intent(in), optional :: vsync

default true: at the display's refresh; false: when ready

Return Value logical

private pure function pixel_ratio(self)

Framebuffer pixels per window unit of a host's window (as given to open or resize; 1 for a window of its own).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private pure function recorded_frames(self)

Frames recorded since recording started (the video's length: frames / fps).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value integer(kind=int64)

private function render_stats(self) result(stats)

The window's frame rate and frame times (see vkf_diagnostics); zeros while it isn't open.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value type(RenderStats)

private function scene_counts(self) result(counts)

The size of the window's scene graph (see vkf_diagnostics): traverses it all, for an occasional update, not every frame. Zeros while it isn't open.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value type(SceneCounts)

private function screen_position(self, p, position) result(visible)

Where point p (root frame) is in the window, as HUD text positions: (x, y) from 0 to 1, left to right and bottom to top (as at the last frame). False if it is behind the eye (or before the first frame). E.g. to keep HUD text next to a moving object, each frame: a callout.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
real(kind=wp), intent(in) :: p(3)

root frame

real(kind=wp), intent(out) :: position(2)

(x, y), 0 to 1 from the bottom left

Return Value logical

private function sky(self) result(s)

The sky drawn behind the scene (null if none).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value type(SkySphere), pointer

private function start_recording(self, file, fps, quality, codec, scale, options, watermark, watermark_width, watermark_opacity, ffmpeg) result(ok)

Start recording the frames drawn to the video file (see the module documentation), fps frames per second (default 30). Encoded by codec (an ffmpeg encoder; default libx264, H.264) at quality (for libx264, libx265 and libvpx-vp9 the CRF: 0 lossless to 51, default 18, visually lossless), scaled by scale (default 1; e.g. 0.5 for half the size of a Retina window's pixels), the size made even. options replaces the encoder options (codec, quality; and the scale, unless there is a watermark), e.g. '-c:v prores_ks -profile:v 3'. watermark: an image (e.g. a logo; PNG, SVG, ... with transparency) drawn over the video's bottom right corner by ffmpeg, watermark_width of the video's width (default 0.2), watermark_opacity opaque (default 0.6). ffmpeg: the program (default: VKFRAMES_FFMPEG, else ffmpeg on the path). Returns false if the window isn't open, is already recording or the watermark doesn't exist; ffmpeg's errors (e.g. an unknown encoder) show when it starts, at the next frame, and end the recording.

Read more…

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
character(len=*), intent(in) :: file

the video file (e.g. .mp4, .mov, .webm)

real(kind=wp), intent(in), optional :: fps

frames per second of the video (default 30)

integer, intent(in), optional :: quality

the CRF (default 18; lower is better)

character(len=*), intent(in), optional :: codec

an ffmpeg encoder (default libx264)

real(kind=wp), intent(in), optional :: scale

of the window's pixels (default 1)

character(len=*), intent(in), optional :: options

ffmpeg's encoder options, instead of those above

character(len=*), intent(in), optional :: watermark

an image file drawn at the bottom right

real(kind=wp), intent(in), optional :: watermark_width

its width, of the video's (default 0.2)

real(kind=wp), intent(in), optional :: watermark_opacity

0 to 1 (default 0.6)

character(len=*), intent(in), optional :: ffmpeg

the ffmpeg program

Return Value logical

private function stop_recording(self, frames) result(ok)

Stop recording: ffmpeg finishes the file. The window's time goes on from where the video was, on the wall clock again. frames: the frames written. Returns false if not recording or if the recording failed (ffmpeg's messages are on the standard error).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer(kind=int64), intent(out), optional :: frames

frames written to the video

Return Value logical

private function time(self)

The simulation time (at the last frame).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private function time_scale(self)

Simulation seconds per wall-clock second.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private function view_camera(self, x, y, cam) result(ok)

The pick camera of the view shown, with the cursor at (x, y) (-1 to 1, y up) and no tolerance. False before the first frame (or closed).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
real(kind=wp), intent(in) :: x

the cursor: -1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

the cursor: -1 to 1 across the window, y up

type(PickCamera), intent(out) :: cam

the view's camera, the cursor there

Return Value logical

private pure function view_transition(self)

The time (s) a change of view or a reset flies (set_view_transition).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private function window_gui(self, font, size) result(g)

The window's GUI panels (vkf_gui), made on first use: with font (a font file name or path, as labels'; default DejaVu Sans) of size window units (default 15), which apply then. Not valid unless open.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
character(len=*), intent(in), optional :: font

file name or path (default DejaVu Sans)

real(kind=wp), intent(in), optional :: size

window units (default 15)

Return Value type(Gui)

private function window_view(self, i) result(v)

View i (1 to num_views).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
integer, intent(in) :: i

1 to num_views

Return Value type(View), pointer

private function window_viewer(self) result(v)

The window's viewer handle in the rendering layer (null until open), for adding low-level nodes (src/vsg/vkf_layer.f90).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value type(c_ptr)

private function window_wall(self)

The window's wall time (s): the wall clock's, or while recording the video's (its start, plus a frame's time per frame drawn).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(in) :: self

Return Value real(kind=wp)

private pure function zoom_speed(self)

The zoom speed (set_zoom_speed).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self

Return Value real(kind=wp)


Subroutines

private subroutine add_hud_text(self, h)

Show h in the window, on top of the scene (it must stay alive while shown), from the next frame.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(HUDText), intent(in), target :: h

the text (not owned)

private subroutine add_view(self, v)

Add v to the end of the window's views (it must stay alive while added).

Read more…

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(View), intent(in), target :: v

the view (not owned)

private subroutine apply_camera_controls(self)

Give the zoom speed and throw to the trackball (if open).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self

private subroutine apply_window_light(self)

Give the renderer's window light its colors and position (if open).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self

private subroutine clear_event_handler(self)

Give the events to no handler (the built-in keys remain).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

private subroutine close(self)

Close the window (waiting for the GPU). The scene is kept, and can be shown again in another window. So are the window's settings (views, HUD texts, sky, handler, time): open again (e.g. on a host's new native window, after Qt destroyed the old one) shows them as before.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

private subroutine count_frame(self, started)

Count a frame for the frame rate (render_stats): its duration, and the rate over about half a second.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: started

the wall time frame() started (s)

private subroutine create_hud(self, k)

The node of HUD text k, added to the window (compiled if it runs).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
integer, intent(in) :: k

index in huds

private subroutine create_huds(self)

Create the window's nodes for its HUD texts (before its first frame).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self

private subroutine default_key(self, key, modifiers)

The built-in keys (OpenFrames'): v the next view, V the previous one, the space bar resets the view; not with control, alt or meta held.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
integer, intent(in) :: key

a character code or KEY_; MOD_ bits

integer, intent(in) :: modifiers

a character code or KEY_; MOD_ bits

private subroutine dispatch_event(self, e)

One event (see vkf_viewer_events): kind, key, key base, modifiers, button, buttons held, x, y (framebuffer pixels from the top left), the render area (x, y, width, height).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
integer, intent(in) :: e(12)

the event (see above)

private subroutine dispatch_events(self)

The keyboard and mouse events of the last frame, to the handler and the built-in keys (stopping if the window is closed meanwhile).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self

private subroutine drag_handle(self, x, y)

The grabbed handle dragged to (x, y).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
real(kind=wp), intent(in) :: x

the cursor: -1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

the cursor: -1 to 1 across the window, y up

private subroutine fly(self, v)

The camera of an active flight to view v, at this moment: both cameras in the root frame (their views' frames as they are now), in between by the eased fraction of the time passed, back in v's frame.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
type(View), intent(in), target :: v

the view flown to

private subroutine fm_set_frame(self, frame)

Set the root frame of the scene (not owned: it must stay alive while managed). (The scene is for a window: this also starts loading the Vulkan driver for the first one, in the background, which can take a few tenths of a second.)

Arguments

Type IntentOptional Attributes Name
class(FrameManager), intent(inout) :: self
class(ReferenceFrame), intent(in), target :: frame

the root frame (not owned)

private subroutine fm_update(self, t, seen)

Update the scene for time t (followed trajectories, artists) and copy the frames' positions and attitudes to the renderer, unless another window already did for this time since this window's last frame. seen is the window's own: the number of updates at its last frame.

Arguments

Type IntentOptional Attributes Name
class(FrameManager), intent(inout) :: self
real(kind=wp), intent(in) :: t

simulation time

integer, intent(inout) :: seen

the window's own: updates at its last frame (updated)

private subroutine forget_handles(self)

No handle hovered or grabbed (the scene or the window changes).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

private subroutine get_camera(self, eye, center, up, in_root)

The camera of the view shown (from the last frame): eye, center and up in the view frame's coordinates (OpenFrames' trackball getTransformation), or in its root frame's if in_root. Zero before the window's first frame.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
real(kind=wp), intent(out) :: eye(3)

view frame's coordinates (or root's)

real(kind=wp), intent(out) :: center(3)

view frame's coordinates (or root's)

real(kind=wp), intent(out) :: up(3)

view frame's coordinates (or root's)

logical, intent(in), optional :: in_root

true: in the root frame's coordinates (default: the view frame's)

private subroutine grab_handle(self, x, y)

A left press grabbed the mouse (the grab armed): the hovered handle grabbed.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
real(kind=wp), intent(in) :: x

the cursor: -1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

the cursor: -1 to 1 across the window, y up

private subroutine handler_before_draw(self, window, t)

Called each frame just before drawing, the scene at time t and the camera placed (see the module documentation): e.g. to move HUD text next to a moving object, or frames. A view following a frame moved here follows it in this frame's drawing (its transform is taken again after); trajectories' points changed here are drawn from the next frame (change them in before_update).

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window about to draw

real(kind=wp), intent(in) :: t

simulation time

private subroutine handler_before_update(self, window, t)

Called each frame with its time t, before the scene is updated for it and the camera placed (see the module documentation): to change the data for time t (trajectories' points, frames' positions), drawn and followed by the views in this frame.

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window about to update

real(kind=wp), intent(in) :: t

simulation time

private subroutine handler_button_press(self, window, x, y, button)

A mouse button (MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT) was pressed at (x, y) (see mouse_motion).

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window of the event

real(kind=wp), intent(in) :: x

-1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

-1 to 1 across the window, y up

integer, intent(in) :: button

MOUSE_LEFT, MOUSE_MIDDLE or MOUSE_RIGHT

private subroutine handler_button_release(self, window, x, y, button)

A mouse button was released at (x, y) (see button_press).

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window of the event

real(kind=wp), intent(in) :: x

-1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

-1 to 1 across the window, y up

integer, intent(in) :: button

as button_press's

private subroutine handler_handle_drag(self, window, handle, stage)

A handle (vkf_handles) was grabbed (DRAG_START), dragged (DRAG_MOVE: it has moved) or released (DRAG_END) with the mouse: e.g. compute again what depends on it (see the module documentation).

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window the handle is dragged in

class(DragHandle), intent(inout), target :: handle

the handle (select type for its kind)

integer, intent(in) :: stage

DRAG_START, DRAG_MOVE or DRAG_END

private subroutine handler_key_press(self, window, key, modifiers, handled)

A key was pressed: key (a character's code, iachar('v'), or KEY_), with the modifier keys held (MOD_ bits). Set handled (false on entry) to skip the built-in key's action.

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window of the event

integer, intent(in) :: key

a character code or KEY_; MOD_ bits

integer, intent(in) :: modifiers

a character code or KEY_; MOD_ bits

logical, intent(inout) :: handled

(true: skip the built-in key)

private subroutine handler_key_release(self, window, key, modifiers)

A key was released (see key_press).

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window of the event

integer, intent(in) :: key

as key_press's

integer, intent(in) :: modifiers

as key_press's

private subroutine handler_mouse_motion(self, window, x, y, buttons)

The mouse moved to (x, y) (-1 to 1 across the window, y up), with the buttons held (left, middle, right): moving (none held, OpenFrames' mouse motion) or dragging.

Arguments

Type IntentOptional Attributes Name
class(WindowEventHandler), intent(inout) :: self
class(WindowProxy), intent(inout) :: window

the window of the event

real(kind=wp), intent(in) :: x

-1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

-1 to 1 across the window, y up

logical, intent(in) :: buttons(3)

(held: left, middle, right)

private subroutine hover_handle(self, x, y)

The handle under (x, y), if any, hovered (the one before not), and the grab armed for it. Of handles on the same spot: the nearest on the screen; within same_spot pixels of it, the highest priority, then the nearest to the eye (vkf_handles).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
real(kind=wp), intent(in) :: x

the cursor: -1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

the cursor: -1 to 1 across the window, y up

private subroutine key(self, pressed, symbol, modified_symbol, modifier)

A key press (pressed true) or release, as VSG key symbols and modifiers (ASCII for printable keys; vsg/ui/KeyEvent.h).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
logical, intent(in) :: pressed

true: pressed; false: released

integer, intent(in) :: symbol

the key without modifiers (VSG's keyBase)

integer, intent(in) :: modified_symbol

the key with the modifiers (VSG's keyModified, e.g. 'A')

integer, intent(in) :: modifier

the modifier keys held (MOD_* bits)

private subroutine mouse(self, kind, x, y, mask, button)

A mouse event: kind MOUSE_MOVE, MOUSE_PRESS or MOUSE_RELEASE.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer, intent(in) :: kind

MOUSE_MOVE, MOUSE_PRESS or MOUSE_RELEASE

integer, intent(in) :: x

framebuffer pixels from the top left

integer, intent(in) :: y

framebuffer pixels from the top left

integer, intent(in) :: mask

buttons held (ior: 256 left, 512 middle, 1024 right)

integer, intent(in) :: button

button pressed or released (1 left, 2 middle, 3 right)

private subroutine next_view(self, duration)

Show the next view (wrapping around); duration as select_view's.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in), optional :: duration

s, as select_view's

private subroutine pause_time(self, paused)

Pause (true) or resume (false) the simulation time.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
logical, intent(in) :: paused

true: pause; false: resume

private subroutine place_camera(self)

Set the renderer's camera for the current view: keep the previous view's trackball state and restore (or reset) the current one's when the view changes, then set its world-to-view transform and projection.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout), target :: self

private subroutine previous_view(self, duration)

Show the previous view (wrapping around); duration as select_view's.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in), optional :: duration

s, as select_view's

private subroutine put_camera(self, cam)

The renderer's camera (columns: eye, center, up; the shown view's frame).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: cam(3,3)

(columns: eye, center, up)

private subroutine release_handle(self, x, y)

The grabbed handle released at (x, y); then the handle under the cursor hovered.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
real(kind=wp), intent(in) :: x

the cursor: -1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

the cursor: -1 to 1 across the window, y up

private subroutine remove_all_views(self)

Remove all the window's views (the default view is then used).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

private subroutine remove_hud_text(self, h)

Stop showing h in the window.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(HUDText), intent(in), target :: h

the text to stop showing

private subroutine remove_view(self, v)

Remove all instances of v from the window's views.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(View), intent(in), target :: v

the view to remove

private subroutine resize(self, width, height, pixel_ratio)

The host window was resized (framebuffer pixels), and pixel_ratio: its framebuffer pixels per window unit (Qt's devicePixelRatio), if it may have changed (the window moved to a screen of another scale, or the display's scaling changed: sizes in window units, such as line widths, markers and labels, are scaled by it). Once the scene is shown, a frame of the new size is rendered at once (call this from the host's resize event), so that the window isn't shown stretched or blank while it is resized.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer, intent(in) :: width

framebuffer pixels

integer, intent(in) :: height

framebuffer pixels

real(kind=wp), intent(in), optional :: pixel_ratio

framebuffer pixels per window unit

private subroutine run(self, max_frames)

Render frames until the window is closed (or for max_frames frames).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer, intent(in), optional :: max_frames

default: until the window is closed

private subroutine scroll(self, dy)

The scroll wheel: dy > 0 away from the user.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: dy

wheel steps (> 0: away from the user; fractions for a trackpad's small steps: Qt's angleDelta / 120)

private subroutine select_view(self, i, duration)

Show view i (1 to num_views), flying there over duration s (default: the view transition, set_view_transition; 0: a cut).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
integer, intent(in) :: i

1 to num_views

real(kind=wp), intent(in), optional :: duration

s (default: the view transition; 0: a cut)

private subroutine set_background_color(self, rgb)

The background color [r, g, b] (0 to 1; default black).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: rgb(3)

[r, g, b], 0 to 1

private subroutine set_camera(self, eye, center, up, duration, in_root)

Set the camera of the current view: eye, center and up in the view frame's coordinates (OpenFrames' trackball setTransformation), or in its root frame's if in_root (as the frames are now). With duration (s), fly there from the camera shown. Before the view is shown, it is its camera when it is (set_camera).

Read more…

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout), target :: self
real(kind=wp), intent(in) :: eye(3)

view frame's coordinates (or root's)

real(kind=wp), intent(in) :: center(3)

view frame's coordinates (or root's)

real(kind=wp), intent(in) :: up(3)

view frame's coordinates (or root's)

real(kind=wp), intent(in), optional :: duration

s (default: at once)

logical, intent(in), optional :: in_root

true: eye, center and up are in the root frame's coordinates

private subroutine set_camera_throw(self, enabled)

Whether the camera keeps moving (turning, zooming, panning) after a drag is released while the mouse moves (default true, VSG's and OSG's throw); false: it stops where it is released.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
logical, intent(in) :: enabled

true: keeps moving; false: stops where released

private subroutine set_default_keys(self, on)

The built-in keys (default on): v the next view, V the previous one, the space bar resets the view.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
logical, intent(in) :: on

true: the built-in keys on

private subroutine set_event_handler(self, handler)

Give the window's keyboard and mouse events to handler (not owned: it must stay alive while set), in place of any handler set before.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
class(WindowEventHandler), intent(in), target :: handler

not owned

private subroutine set_light_ambient(self, rgb)

The ambient, diffuse and specular colors ([r, g, b], 0 to 1) of the window's light (OpenFrames' defaults: 0.2 gray, white, none). The window's light is used while no frame of the scene has a light source (set_light_source_enabled).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: rgb(3)

[r, g, b], 0 to 1 (default 0.2 gray)

private subroutine set_light_diffuse(self, rgb)

The diffuse color of the window's light (see set_light_ambient).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: rgb(3)

[r, g, b], 0 to 1 (default white)

private subroutine set_light_position(self, position)

The light's position in eye coordinates (x right, y up, z toward the viewer): [x, y, z, 0] for a directional light from direction (x, y, z), [x, y, z, 1] for a point light (OpenFrames' setLightPosition; default [0, 0, 1, 0], a headlight).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: position(4)

[x, y, z, w], eye coordinates (not all 0)

private subroutine set_light_specular(self, rgb)

The specular color of the window's light (see set_light_ambient).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: rgb(3)

[r, g, b], 0 to 1 (default black: none)

private subroutine set_scene(self, fm)

Show the scene of fm (which must stay alive while shown). For now, set it before the window's first frame.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(FrameManager), intent(in), target :: fm

the scene (not owned; must stay alive while shown)

private subroutine set_sky(self, sky)

Draw sky behind the scene (it must stay alive while shown; it can be shown in several windows), in place of the window's sky so far; at any time (its texture and stars can change too).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
type(SkySphere), intent(inout), target :: sky

the sky (not owned; can be shown in several windows)

private subroutine set_time(self, t)

Set the simulation time (limited to the time range).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: t

simulation time

private subroutine set_time_range(self, t_min, t_max)

Limit the simulation time to [t_min, t_max] (ignored if t_max < t_min).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: t_min

simulation times

real(kind=wp), intent(in) :: t_max

simulation times

private subroutine set_time_scale(self, scale)

Simulation seconds per wall-clock second (may be 0 or negative).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: scale

simulation s per wall-clock s (may be 0 or negative)

private subroutine set_view_transition(self, seconds)

The time (s) a change of view or a reset flies from one camera to the other (default 0: a cut, as OpenFrames).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: seconds

wall-clock s (0: a cut)

private subroutine set_zoom_speed(self, speed)

How fast the mouse zooms (default 1, VSG's: 10% per wheel step, and a right drag's rate): e.g. 0.3 for a gentler zoom. Scales scroll steps however they come (a mouse wheel, a trackpad, a host's scroll).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self
real(kind=wp), intent(in) :: speed

(> 0; 1: the default)

private subroutine start_flight(self, from, start, to, finish, duration)

Fly from camera start (in view from's frame) to finish (in view to's) over duration s, from now.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
type(View), intent(in), target :: from

the views whose frames start and finish are in

real(kind=wp), intent(in) :: start(3,3)

(columns: eye, center, up; duration: s)

type(View), intent(in), target :: to

the views whose frames start and finish are in

real(kind=wp), intent(in) :: finish(3,3)

(columns: eye, center, up; duration: s)

real(kind=wp), intent(in) :: duration

(columns: eye, center, up; duration: s)

private subroutine stop_transition(self)

End a flight where the camera is now.

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(inout) :: self

private subroutine time_range(self, t_min, t_max)

The simulation time range (set_time_range).

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in) :: self
real(kind=wp), intent(out) :: t_min

simulation times

real(kind=wp), intent(out) :: t_max

simulation times

private subroutine track_view(self)

The view's frame (the frame it follows) where it is now: the renderer's world-to-view transform (the camera stays where it is in that frame).

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout), target :: self

private subroutine update_huds(self)

Show the HUD texts' changes: text, color, position, size and alignment in place; a new font makes the text's node again.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self

private subroutine update_window_light(self, root)

The window's light on while no frame of the scene has a light source.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout) :: self
class(ReferenceFrame), intent(in), pointer :: root

the scene's root (may be null)

private subroutine window_pick(self, x, y, hits, tolerance, kinds, nearest)

What is under point (x, y) of the window (-1 to 1 across it, y up: as the event handler's positions), nearest first (see the module documentation): none before the first frame. tolerance: how close lines, markers and frames' origins must be, in window units (logical pixels; default 4), beyond half a line's width or a marker's size. kinds: only hits of these kinds (PICK_*; the others aren't tested). nearest: only the nearest hit (cheaper: what is deeper than a hit found is skipped, e.g. to pick on every mouse move). Frames and artists can be left out (set_pickable(.false.)).

Read more…

Arguments

Type IntentOptional Attributes Name
class(WindowProxy), intent(in), target :: self
real(kind=wp), intent(in) :: x

-1 to 1 across the window, y up

real(kind=wp), intent(in) :: y

-1 to 1 across the window, y up

type(PickHit), intent(out), allocatable :: hits(:)

what is there, nearest first

real(kind=wp), intent(in), optional :: tolerance

window units (default 4)

integer, intent(in), optional :: kinds(:)

PICK_* (default: all)

logical, intent(in), optional :: nearest

default false