[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