Blender  V2.93
wm_xr_draw.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
25 #include <string.h>
26 
27 #include "BLI_math.h"
28 
29 #include "ED_view3d_offscreen.h"
30 
31 #include "GHOST_C-api.h"
32 
33 #include "GPU_viewport.h"
34 
35 #include "WM_api.h"
36 
37 #include "wm_surface.h"
38 #include "wm_xr_intern.h"
39 
40 void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4])
41 {
42  float iquat[4];
43  invert_qt_qt_normalized(iquat, pose->orientation_quat);
44  quat_to_mat4(r_viewmat, iquat);
45  translate_m4(r_viewmat, -pose->position[0], -pose->position[1], -pose->position[2]);
46 }
47 
48 static void wm_xr_draw_matrices_create(const wmXrDrawData *draw_data,
49  const GHOST_XrDrawViewInfo *draw_view,
50  const XrSessionSettings *session_settings,
51  float r_view_mat[4][4],
52  float r_proj_mat[4][4])
53 {
54  GHOST_XrPose eye_pose;
55 
56  copy_qt_qt(eye_pose.orientation_quat, draw_view->eye_pose.orientation_quat);
57  copy_v3_v3(eye_pose.position, draw_view->eye_pose.position);
58  sub_v3_v3(eye_pose.position, draw_data->eye_position_ofs);
59  if ((session_settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) {
60  sub_v3_v3(eye_pose.position, draw_view->local_pose.position);
61  }
62 
63  perspective_m4_fov(r_proj_mat,
64  draw_view->fov.angle_left,
65  draw_view->fov.angle_right,
66  draw_view->fov.angle_up,
67  draw_view->fov.angle_down,
68  session_settings->clip_start,
69  session_settings->clip_end);
70 
71  float eye_mat[4][4];
72  float base_mat[4][4];
73 
74  wm_xr_pose_to_viewmat(&eye_pose, eye_mat);
75  /* Calculate the base pose matrix (in world space!). */
76  wm_xr_pose_to_viewmat(&draw_data->base_pose, base_mat);
77 
78  mul_m4_m4m4(r_view_mat, eye_mat, base_mat);
79 }
80 
82  const wmXrRuntimeData *runtime_data,
83  const wmXrSurfaceData *surface_data,
84  const GHOST_XrDrawViewInfo *draw_view)
85 {
86  const bool is_upside_down = GHOST_XrSessionNeedsUpsideDownDrawing(runtime_data->context);
87  rcti rect = {.xmin = 0, .ymin = 0, .xmax = draw_view->width - 1, .ymax = draw_view->height - 1};
88 
89  wmViewport(&rect);
90 
91  /* For upside down contexts, draw with inverted y-values. */
92  if (is_upside_down) {
93  SWAP(int, rect.ymin, rect.ymax);
94  }
96  surface_data->viewport, 0, &rect, draw_view->expects_srgb_buffer, true);
97 }
98 
105 void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
106 {
107  wmXrDrawData *draw_data = customdata;
108  wmXrData *xr_data = draw_data->xr_data;
109  wmXrSurfaceData *surface_data = draw_data->surface_data;
110  wmXrSessionState *session_state = &xr_data->runtime->session_state;
111  XrSessionSettings *settings = &xr_data->session_settings;
112 
113  const int display_flags = V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS | settings->draw_flags;
114 
115  float viewmat[4][4], winmat[4][4];
116 
118 
119  wm_xr_session_draw_data_update(session_state, settings, draw_view, draw_data);
120  wm_xr_draw_matrices_create(draw_data, draw_view, settings, viewmat, winmat);
121  wm_xr_session_state_update(settings, draw_data, draw_view, session_state);
122 
123  if (!wm_xr_session_surface_offscreen_ensure(surface_data, draw_view)) {
124  return;
125  }
126 
127  /* In case a framebuffer is still bound from drawing the last eye. */
129  /* Some systems have drawing glitches without this. */
130  GPU_clear_depth(1.0f);
131 
132  /* Draws the view into the surface_data->viewport's frame-buffers. */
134  draw_data->scene,
135  &settings->shading,
136  settings->shading.type,
137  draw_view->width,
138  draw_view->height,
139  display_flags,
140  viewmat,
141  winmat,
142  settings->clip_start,
143  settings->clip_end,
144  false,
145  true,
146  NULL,
147  false,
148  surface_data->offscreen,
149  surface_data->viewport);
150 
151  /* The draw-manager uses both GPUOffscreen and GPUViewport to manage frame and texture buffers. A
152  * call to GPU_viewport_draw_to_screen() is still needed to get the final result from the
153  * viewport buffers composited together and potentially color managed for display on screen.
154  * It needs a bound frame-buffer to draw into, for which we simply reuse the GPUOffscreen one.
155  *
156  * In a next step, Ghost-XR will use the currently bound frame-buffer to retrieve the image
157  * to be submitted to the OpenXR swap-chain. So do not un-bind the off-screen yet! */
158 
159  GPU_offscreen_bind(surface_data->offscreen, false);
160 
161  wm_xr_draw_viewport_buffers_to_active_framebuffer(xr_data->runtime, surface_data, draw_view);
162 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
void perspective_m4_fov(float mat[4][4], const float angle_left, const float angle_right, const float angle_up, const float angle_down, const float nearClip, const float farClip)
Definition: math_geom.c:4856
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2325
void invert_qt_qt_normalized(float q1[4], const float q2[4])
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:52
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define SWAP(type, a, b)
@ V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS
@ XR_SESSION_USE_POSITION_TRACKING
Definition: DNA_xr_types.h:52
void ED_view3d_draw_offscreen_simple(struct Depsgraph *depsgraph, struct Scene *scene, struct View3DShading *shading_override, int drawtype, int winx, int winy, unsigned int draw_flags, const float viewmat[4][4], const float winmat[4][4], float clip_start, float clip_end, bool is_image_render, bool draw_background, const char *viewname, const bool do_color_management, struct GPUOffScreen *ofs, struct GPUViewport *viewport)
Definition: view3d_draw.c:1745
GHOST C-API function and type declarations.
void GPU_framebuffer_restore(void)
void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, int view, const rcti *rect, bool display_colorspace, bool do_overlay_merge)
Definition: gpu_viewport.c:805
void GPU_clear_depth(float depth)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
struct View3DShading shading
Definition: DNA_xr_types.h:31
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
XrSessionSettings session_settings
struct wmXrRuntimeData * runtime
wmXrData * xr_data
Definition: wm_xr_intern.h:70
float eye_position_ofs[3]
Definition: wm_xr_intern.h:79
struct Depsgraph * depsgraph
Definition: wm_xr_intern.h:68
GHOST_XrPose base_pose
Definition: wm_xr_intern.h:76
wmXrSurfaceData * surface_data
Definition: wm_xr_intern.h:71
struct Scene * scene
Definition: wm_xr_intern.h:67
GHOST_XrContextHandle context
Definition: wm_xr_intern.h:50
wmXrSessionState session_state
Definition: wm_xr_intern.h:57
struct GPUViewport * viewport
Definition: wm_xr_intern.h:63
struct GPUOffScreen * offscreen
Definition: wm_xr_intern.h:62
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:37
static void wm_xr_draw_viewport_buffers_to_active_framebuffer(const wmXrRuntimeData *runtime_data, const wmXrSurfaceData *surface_data, const GHOST_XrDrawViewInfo *draw_view)
Definition: wm_xr_draw.c:81
static void wm_xr_draw_matrices_create(const wmXrDrawData *draw_data, const GHOST_XrDrawViewInfo *draw_view, const XrSessionSettings *session_settings, float r_view_mat[4][4], float r_proj_mat[4][4])
Definition: wm_xr_draw.c:48
void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4])
Definition: wm_xr_draw.c:40
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
Draw a viewport for a single eye.
Definition: wm_xr_draw.c:105
void wm_xr_session_draw_data_update(const wmXrSessionState *state, const XrSessionSettings *settings, const GHOST_XrDrawViewInfo *draw_view, wmXrDrawData *draw_data)
void wm_xr_session_state_update(const XrSessionSettings *settings, const wmXrDrawData *draw_data, const GHOST_XrDrawViewInfo *draw_view, wmXrSessionState *state)
bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data, const GHOST_XrDrawViewInfo *draw_view)
bool WM_xr_session_is_ready(const wmXrData *xr)