[Bf-blender-cvs] [dc2df8307f4] master: VR: Initial Virtual Reality support - Milestone 1, Scene Inspection

Julian Eisel noreply at git.blender.org
Tue Mar 17 21:43:29 CET 2020


Commit: dc2df8307f41888bab722f75fa9e73adecf86b72
Author: Julian Eisel
Date:   Tue Mar 17 20:20:55 2020 +0100
Branches: master
https://developer.blender.org/rBdc2df8307f41888bab722f75fa9e73adecf86b72

VR: Initial Virtual Reality support - Milestone 1, Scene Inspection

NOTE: While most of the milestone 1 goals are there, a few smaller features and
improvements are still to be done.

Big picture of this milestone: Initial, OpenXR-based virtual reality support
for users and foundation for advanced use cases.
Maniphest Task: https://developer.blender.org/T71347
The tasks contains more information about this milestone.

To be clear: This is not a feature rich VR implementation, it's focused on the
initial scene inspection use case. We intentionally focused on that, further
features like controller support are part of the next milestone.

- How to use?
Instructions on how to use this are here:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/How_to_Test
These will be updated and moved to a more official place (likely the manual) soon.

Currently Windows Mixed Reality and Oculus devices are usable. Valve/HTC
headsets don't support the OpenXR standard yet and hence, do not work with this
implementation.

---------------

This is the C-side implementation of the features added for initial VR
support as per milestone 1. A "VR Scene Inspection" Add-on will be
committed separately, to expose the VR functionality in the UI. It also
adds some further features for milestone 1, namely a landmarking system
(stored view locations in the VR space)

Main additions/features:
* Support for rendering viewports to an HMD, with good performance.
* Option to sync the VR view perspective with a fully interactive,
  regular 3D View (VR-Mirror).
* Option to disable positional tracking. Keeps the current position (calculated
  based on the VR eye center pose) when enabled while a VR session is running.
* Some regular viewport settings for the VR view
* RNA/Python-API to query and set VR session state information.
* WM-XR: Layer tying Ghost-XR to the Blender specific APIs/data
* wmSurface API: drawable, non-window container (manages Ghost-OpenGL and GPU
  context)
* DNA/RNA for management of VR session settings
* `--debug-xr` and `--debug-xr-time` commandline options
* Utility batch & config file for using the Oculus runtime on Windows.
* Most VR data is runtime only. The exception is user settings which are saved
  to files (`XrSessionSettings`).
* VR support can be disabled through the `WITH_XR_OPENXR` compiler flag.

For architecture and code documentation, see
https://wiki.blender.org/wiki/Source/Interface/XR.

---------------

A few thank you's:
* A huge shoutout to Ray Molenkamp for his help during the project - it would
  have not been that successful without him!
* Sebastian Koenig and Simeon Conzendorf for testing and feedback!
* The reviewers, especially Brecht Van Lommel!
* Dalai Felinto for pushing and managing me to get this done ;)
* The OpenXR working group for providing an open standard. I think we're the
  first bigger application to adopt OpenXR. Congratulations to them and
  ourselves :)

This project started as a Google Summer of Code 2019 project - "Core Support of
Virtual Reality Headsets through OpenXR" (see
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/).
Some further information, including ideas for further improvements can be found
in the final GSoC report:
https://wiki.blender.org/wiki/User:Severin/GSoC-2019/Final_Report

Differential Revisions: D6193, D7098

Reviewed by: Brecht Van Lommel, Jeroen Bakker

===================================================================

M	CMakeLists.txt
M	intern/ghost/CMakeLists.txt
M	intern/ghost/GHOST_C-api.h
M	intern/ghost/GHOST_IContext.h
M	intern/ghost/GHOST_Types.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_Context.h
M	intern/ghost/intern/GHOST_IXrGraphicsBinding.h
M	intern/ghost/intern/GHOST_XrContext.cpp
M	intern/ghost/intern/GHOST_XrContext.h
M	intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
M	intern/ghost/intern/GHOST_XrSession.cpp
M	intern/ghost/intern/GHOST_XrSession.h
A	release/windows/batch/blender_oculus.cmd
A	release/windows/batch/oculus.json
M	source/blender/CMakeLists.txt
M	source/blender/blenkernel/BKE_global.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenlib/BLI_math_geom.h
M	source/blender/blenlib/intern/math_geom.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/DRW_engine.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/include/ED_view3d_offscreen.h
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/sculpt_paint/paint_cursor.c
M	source/blender/editors/space_view3d/CMakeLists.txt
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/editors/space_view3d/view3d_edit.c
M	source/blender/editors/space_view3d/view3d_fly.c
M	source/blender/editors/space_view3d/view3d_gizmo_navigate.c
M	source/blender/editors/space_view3d/view3d_utils.c
M	source/blender/editors/space_view3d/view3d_view.c
M	source/blender/editors/space_view3d/view3d_walk.c
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/makesdna/DNA_view3d_enums.h
M	source/blender/makesdna/DNA_view3d_types.h
M	source/blender/makesdna/DNA_windowmanager_types.h
A	source/blender/makesdna/DNA_xr_types.h
M	source/blender/makesdna/intern/makesdna.c
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/CMakeLists.txt
M	source/blender/makesrna/intern/makesrna.c
M	source/blender/makesrna/intern/rna_internal.h
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/makesrna/intern/rna_wm.c
M	source/blender/makesrna/intern/rna_wm_gizmo.c
A	source/blender/makesrna/intern/rna_xr.c
M	source/blender/python/gpu/gpu_py_offscreen.c
M	source/blender/windowmanager/CMakeLists.txt
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/gizmo/WM_gizmo_types.h
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
M	source/blender/windowmanager/intern/wm.c
M	source/blender/windowmanager/intern/wm_draw.c
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/intern/wm_operators.c
A	source/blender/windowmanager/intern/wm_surface.c
M	source/blender/windowmanager/intern/wm_window.c
A	source/blender/windowmanager/intern/wm_xr.c
M	source/blender/windowmanager/wm.h
A	source/blender/windowmanager/wm_surface.h
M	source/creator/CMakeLists.txt
M	source/creator/creator_args.c
M	tests/python/bl_load_addons.py
M	tests/python/bl_load_py_modules.py

===================================================================

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b78b0e7d647..9f4d0c20886 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,8 +186,7 @@ if(APPLE)
   option(WITH_XR_OPENXR   "Enable VR features through the OpenXR specification" OFF)
   mark_as_advanced(WITH_XR_OPENXR)
 else()
-  # Disabled until there's more than just the build system stuff. Should be enabled soon.
-  option(WITH_XR_OPENXR   "Enable VR features through the OpenXR specification" OFF)
+  option(WITH_XR_OPENXR   "Enable VR features through the OpenXR specification" ON)
 endif()
 
 # Compositor
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 07d98475c00..611da8d6a44 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -377,6 +377,9 @@ if(WITH_XR_OPENXR)
   list(APPEND INC_SYS
     ${XR_OPENXR_SDK_INCLUDE_DIR}
   )
+  list(APPEND LIB
+    ${XR_OPENXR_SDK_LIBRARIES}
+  )
 
   set(XR_PLATFORM_DEFINES -DXR_USE_GRAPHICS_API_OPENGL)
 
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index aafe374a93b..aba5b5f733b 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -756,6 +756,18 @@ extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthan
  */
 extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle);
 
+/**
+ * Get the OpenGL framebuffer handle that serves as a default framebuffer.
+ */
+extern unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle);
+
+/**
+ * Returns whether a context is rendered upside down compared to OpenGL. This only needs to be
+ * called if there's a non-OpenGL context, which is really the exception.
+ * So generally, this does not need to be called.
+ */
+extern int GHOST_isUpsideDownContext(GHOST_ContextHandle contexthandle);
+
 /**
  * Get the OpenGL framebuffer handle that serves as a default framebuffer.
  */
diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h
index a341e18ca0a..33422b8e351 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -56,6 +56,15 @@ class GHOST_IContext {
    */
   virtual GHOST_TSuccess releaseDrawingContext() = 0;
 
+  virtual unsigned int getDefaultFramebuffer() = 0;
+
+  virtual GHOST_TSuccess swapBuffers() = 0;
+
+  /**
+   * Returns if the window is rendered upside down compared to OpenGL.
+   */
+  virtual bool isUpsideDown() const = 0;
+
 #ifdef WITH_CXX_GUARDEDALLOC
   MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
 #endif
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index adda782b96d..70c4d3ef00c 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -598,6 +598,8 @@ typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_T
 
 #ifdef WITH_XR_OPENXR
 
+struct GHOST_XrError;
+struct GHOST_XrDrawViewInfo;
 /**
  * The XR view (i.e. the OpenXR runtime) may require a different graphics library than OpenGL. An
  * offscreen texture of the viewport will then be drawn into using OpenGL, but the final texture
@@ -605,7 +607,7 @@ typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, GHOST_T
  *
  * This enum defines the possible graphics bindings to attempt to enable.
  */
-typedef enum {
+typedef enum GHOST_TXrGraphicsBinding {
   GHOST_kXrGraphicsUnknown = 0,
   GHOST_kXrGraphicsOpenGL,
 #  ifdef WIN32
@@ -614,6 +616,16 @@ typedef enum {
   /* For later */
   //  GHOST_kXrGraphicsVulkan,
 } GHOST_TXrGraphicsBinding;
+
+typedef void (*GHOST_XrErrorHandlerFn)(const struct GHOST_XrError *);
+
+typedef void (*GHOST_XrSessionExitFn)(void *customdata);
+
+typedef void *(*GHOST_XrGraphicsContextBindFn)(enum GHOST_TXrGraphicsBinding graphics_lib);
+typedef void (*GHOST_XrGraphicsContextUnbindFn)(enum GHOST_TXrGraphicsBinding graphics_lib,
+                                                GHOST_ContextHandle graphics_context);
+typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
+
 /* An array of GHOST_TXrGraphicsBinding items defining the candidate bindings to use. The first
  * available candidate will be chosen, so order defines priority. */
 typedef const GHOST_TXrGraphicsBinding *GHOST_XrGraphicsBindingCandidates;
@@ -638,13 +650,17 @@ typedef struct {
 
 typedef struct {
   GHOST_XrPose base_pose;
+
+  GHOST_XrSessionExitFn exit_fn;
+  void *exit_customdata;
 } GHOST_XrSessionBeginInfo;
 
-typedef struct {
+typedef struct GHOST_XrDrawViewInfo {
   int ofsx, ofsy;
   int width, height;
 
-  GHOST_XrPose pose;
+  GHOST_XrPose eye_pose;
+  GHOST_XrPose local_pose;
 
   struct {
     float angle_left, angle_right;
@@ -655,19 +671,12 @@ typedef struct {
   char expects_srgb_buffer;
 } GHOST_XrDrawViewInfo;
 
-typedef struct {
+typedef struct GHOST_XrError {
   const char *user_message;
 
   void *customdata;
 } GHOST_XrError;
 
-typedef void (*GHOST_XrErrorHandlerFn)(const GHOST_XrError *);
-
-typedef void *(*GHOST_XrGraphicsContextBindFn)(GHOST_TXrGraphicsBinding graphics_lib);
-typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_TXrGraphicsBinding graphics_lib,
-                                                void *graphics_context);
-typedef void (*GHOST_XrDrawViewFn)(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
-
 #endif
 
 #endif  // __GHOST_TYPES_H__
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 60d20474a5a..d43a2637ad3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -709,6 +709,20 @@ GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
   return context->releaseDrawingContext();
 }
 
+unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
+{
+  GHOST_IContext *context = (GHOST_IContext *)contexthandle;
+
+  return context->getDefaultFramebuffer();
+}
+
+int GHOST_isUpsideDownContext(GHOST_ContextHandle contexthandle)
+{
+  GHOST_IContext *context = (GHOST_IContext *)contexthandle;
+
+  return context->isUpsideDown();
+}
+
 unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
 {
   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index bbf6d6a510d..0bd6f63d07e 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -119,6 +119,14 @@ class GHOST_Context : public GHOST_IContext {
     return m_stereoVisual;
   }
 
+  /**
+   * Returns if the window is rendered upside down compared to OpenGL.
+   */
+  inline bool isUpsideDown() const
+  {
+    return false;
+  }
+
   /**
    * Gets the OpenGL framebuffer associated with the OpenGL context
    * \return The ID of an OpenGL framebuffer object.
diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index 19fe00cdad5..25281d3d0ba 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -41,6 +41,8 @@ class GHOST_IXrGraphicsBinding {
 #endif
   } oxr_binding;
 
+  virtual ~GHOST_IXrGraphicsBinding() = default;
+
   /**
    * Does __not__ require this object is initialized (can be called prior to
    * #initFromGhostContext). It's actually meant to be called first.
diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp
index 410837e9805..d7b83114c85 100644
--- a/intern/ghost/intern/GHOST_XrContext.cpp
+++ b/intern/ghost/intern/GHOST_XrContext.cpp
@@ -454,10 +454,12 @@ GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable(
 
 void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info)
 {
+  m_custom_funcs.session_exit_fn = begin_info->exit_fn;
+  m_custom_funcs.session_exit_customdata = begin_info->exit_customdata;
+
   if (m_session == nullptr) {
     m_session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(this));
   }
-
   m_session->start(begin_info);
 }
 
diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h
index b361fb5caf8..5140ad7ea27 100644
--- a/intern/ghost/intern/GHOST_XrContext.h
+++ b/intern/ghost/intern/GHOST_XrContext.h
@@ -33,6 +33,9 @@ struct GHOST_XrCustomFuncs {
   /** Function to release (possibly free) a graphics context. */
   GHOST_XrGraphicsContextUnbindFn gpu_ctx_unbind_fn = nullptr;
 
+  GHOST_XrSessionExitFn session_exit_fn = nullptr;
+  void *session_exit_customdata = nullptr;
+
   /** Custom per-view draw function for Blender side drawing. */
   GHOST_XrDrawViewFn draw_view_fn = nullptr;
 };
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index ddc757b8f8a..f094b0744a2 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -116,6 +116,8 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
     oxr_binding.glx.glxDrawable = ctx_glx->m_window;
     oxr_binding.glx.glxContext = ctx_glx->m_context;
     oxr_binding.glx.visualid = visual_info->visualid;
+
+    XFree(visual_info);
 #elif defined(WIN32)
     GHOST_ContextWGL *ctx_wgl = static_cast<GHOST_ContextWGL *>(ghost_ctx);
 
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 1e2b8c0bc9d..a85bde3cab6 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -43,6 +43,7 @@ struct OpenXRSessionData {
   /* Only stereo rendering supported now. */
   const XrViewConfigurationType view_type = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
   XrSpace reference_space;
+  XrSpace view_space;
   std::vector<XrView> views;
   std::vector<std::unique_ptr<GHOST_XrSwapchain>> swapchains;
 };
@@ -81,6 +82,8 @@ GHOST_XrSession::~GHOST_XrSession()
 
   m_oxr->session = XR_NULL_HANDLE;
   m_oxr->session_state = XR_SESSION_STATE_UNKNOWN;
+
+  m_context->getCustomFuncs().session_exit_fn(m_context->getCustomFuncs().session_exit_customdata);
 }
 
 /**
@@ -107,7 +110,7 @@ void GHOST_XrSession::initSystem()
  *
  * \{ */
 
-static void create_reference_space(OpenXRSessionData

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list