Commit: 16366724bd7f7c7e6904ba96ec27d86054c4cb65
Author: Julian Eisel
Date:   Fri Jun 14 02:33:53 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB16366724bd7f7c7e6904ba96ec27d86054c4cb65

Draw into OpenGL offscreen context in the DirectX window.

The window doesn't show anything of course. However we draw (at least I
assume it does) as regular, just into a window offscreen context.

A valid 3D view is created in the window. It's not visible but you see
cursor changes as you move over the window. So handling works.

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

M       intern/ghost/GHOST_C-api.h
M       intern/ghost/GHOST_IContext.h
M       intern/ghost/intern/GHOST_C-api.cpp
M       source/blender/makesdna/DNA_windowmanager_types.h
M       source/blender/windowmanager/intern/wm_operators.c
M       source/blender/windowmanager/intern/wm_window.c
M       source/blender/windowmanager/wm_window.h

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

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 0dff8209966..8acfa8ec943 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -733,6 +733,11 @@ 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);
+
 /**
  * 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..5f213601e6b 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -56,6 +56,8 @@ class GHOST_IContext {
    */
   virtual GHOST_TSuccess releaseDrawingContext() = 0;
 
+  virtual unsigned int getDefaultFramebuffer() = 0;
+
 #ifdef WITH_CXX_GUARDEDALLOC
   MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
 #endif
diff --git a/intern/ghost/intern/GHOST_C-api.cpp 
b/intern/ghost/intern/GHOST_C-api.cpp
index 73442ae6e01..a326742bfe8 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -649,6 +649,13 @@ 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();
+}
+
 unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
 {
   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h 
b/source/blender/makesdna/DNA_windowmanager_types.h
index e94670249b9..c219e25b470 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -205,6 +205,8 @@ typedef struct wmWindow {
 
   /** Don't want to include ghost.h stuff. */
   void *ghostwin;
+  /** Ghost context for rendering the window offscreen (usually unused). */
+  void *offscreen_context;
   /** Don't want to include gpu stuff. */
   void *gpuctx;
 
diff --git a/source/blender/windowmanager/intern/wm_operators.c 
b/source/blender/windowmanager/intern/wm_operators.c
index 074d03de93b..4f8ef594937 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -75,6 +75,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h" /* BKE_ST_MAXNAME */
+#include "BKE_workspace.h"
 #include "BKE_unit.h"
 
 #include "BKE_idcode.h"
@@ -3563,6 +3564,69 @@ static void 
xr_session_gpu_binding_context_destroy(eWM_xrGraphicsBinding graphic
   }
 }
 
+#  ifdef WIN32
+static void xr_session_window_create(bContext *C)
+{
+  Main *bmain = CTX_data_main(C);
+  Scene *scene = CTX_data_scene(C);
+  ViewLayer *view_layer = CTX_data_view_layer(C);
+  wmWindow *win_prev = CTX_wm_window(C);
+
+  rcti rect;
+  wmWindow *win;
+  bScreen *screen;
+  ScrArea *sa;
+  int screen_size[2];
+
+  wm_get_screensize(&screen_size[0], &screen_size[1]);
+  BLI_rcti_init(&rect, 0, screen_size[0], 0, screen_size[1]);
+  BLI_rcti_scale(&rect, 0.8f);
+  wm_window_check_position(&rect);
+
+  win = WM_window_open_directx(C, &rect);
+
+  if (WM_window_get_active_workspace(win) == NULL) {
+    WorkSpace *workspace = WM_window_get_active_workspace(win_prev);
+    BKE_workspace_active_set(win->workspace_hook, workspace);
+  }
+
+  /* add new screen layout */
+  WorkSpace *workspace = WM_window_get_active_workspace(win);
+  WorkSpaceLayout *layout = ED_workspace_layout_add(bmain, workspace, win, "VR 
Session");
+
+  screen = BKE_workspace_layout_screen_get(layout);
+  WM_window_set_active_layout(win, workspace, layout);
+
+  /* Set scene and view layer to match original window. */
+  STRNCPY(win->view_layer_name, view_layer->name);
+  if (WM_window_get_active_scene(win) != scene) {
+    ED_screen_scene_change(C, win, scene);
+  }
+
+  WM_check(C);
+
+  CTX_wm_window_set(C, win);
+  sa = screen->areabase.first;
+  CTX_wm_area_set(C, sa);
+  ED_area_newspace(C, sa, SPACE_VIEW3D, false);
+
+  ED_screen_change(C, screen);
+  ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
+
+  if (win->ghostwin) {
+    GHOST_SetTitle(win->ghostwin, "Blender VR Session View");
+    return win;
+  }
+  else {
+    /* very unlikely! but opening a new window can fail */
+    wm_window_close(C, CTX_wm_manager(C), win);
+    CTX_wm_window_set(C, win_prev);
+
+    return NULL;
+  }
+}
+#  endif /* WIN32 */
+
 static int xr_session_toggle_exec(bContext *C, wmOperator *UNUSED(op))
 {
   wmWindowManager *wm = CTX_wm_manager(C);
@@ -3572,10 +3636,8 @@ static int xr_session_toggle_exec(bContext *C, 
wmOperator *UNUSED(op))
     wm_xr_session_end(xr_context);
   }
   else {
-#  if defined(WIN32) && 0
-    rcti rect;
-    BLI_rcti_init(&rect, 20, 1000, 20, 1200);
-    wmWindow *win = WM_window_open_directx(C, &rect);
+#  if defined(WIN32)
+    xr_session_window_create(C);
 #  endif
 
     wm_xr_graphics_context_bind_funcs(
diff --git a/source/blender/windowmanager/intern/wm_window.c 
b/source/blender/windowmanager/intern/wm_window.c
index 46a1f99c5ca..533c234c92b 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -158,7 +158,7 @@ void wm_get_desktopsize(int *r_width, int *r_height)
 
 /* keeps offset and size within monitor bounds */
 /* XXX solve dual screen... */
-static void wm_window_check_position(rcti *rect)
+void wm_window_check_position(rcti *rect)
 {
   int width, height, d;
 
@@ -191,6 +191,19 @@ static void wm_window_check_position(rcti *rect)
   }
 }
 
+static void wm_window_drawing_context_activate(wmWindow *win)
+{
+  if (WM_window_is_non_opengl(win)) {
+    BLI_assert(win->offscreen_context);
+
+    /* If this is not an OpenGL window, use the offscreen OpenGL context. */
+    GHOST_ActivateOpenGLContext(win->offscreen_context);
+  }
+  else {
+    GHOST_ActivateWindowDrawingContext(win->ghostwin);
+  }
+}
+
 static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win)
 {
   if (win->ghostwin) {
@@ -205,7 +218,7 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, 
wmWindow *win)
     }
 
     /* We need this window's opengl context active to discard it. */
-    GHOST_ActivateWindowDrawingContext(win->ghostwin);
+    wm_window_drawing_context_activate(win);
     GPU_context_active_set(win->gpuctx);
 
     /* Delete local gpu context.  */
@@ -586,16 +599,17 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
 
   if (ghostwin) {
     GHOST_RectangleHandle bounds;
+    GLuint default_fb;
 
     if (context_type == GHOST_kDrawingContextTypeOpenGL) {
-      GLuint default_fb = GHOST_GetDefaultOpenGLFramebuffer(ghostwin);
+      default_fb = GHOST_GetDefaultOpenGLFramebuffer(ghostwin);
       win->gpuctx = GPU_context_create(default_fb);
     }
     else {
-      GHOST_ContextHandle *gl_context = WM_opengl_context_create();
-      WM_opengl_context_activate(gl_context);
-      win->gpuctx = GPU_context_create(0);
-      // wm_window_reset_drawable();
+      win->offscreen_context = WM_opengl_context_create();
+      default_fb = 
GHOST_GetContextDefaultOpenGLFramebuffer(win->offscreen_context);
+      win->gpuctx = GPU_context_create(default_fb);
+      wm_window_reset_drawable();
     }
 
     /* needed so we can detect the graphics card below */
@@ -1092,8 +1106,9 @@ static void wm_window_set_drawable(wmWindowManager *wm, 
wmWindow *win, bool acti
 
   wm->windrawable = win;
   if (activate) {
-    GHOST_ActivateWindowDrawingContext(win->ghostwin);
+    wm_window_drawing_context_activate(win);
   }
+
   GPU_context_active_set(win->gpuctx);
   immActivate();
 }
diff --git a/source/blender/windowmanager/wm_window.h 
b/source/blender/windowmanager/wm_window.h
index 90c580818c9..504353ec429 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -61,6 +61,7 @@ void wm_window_reset_drawable(void);
 void wm_window_raise(wmWindow *win);
 void wm_window_lower(wmWindow *win);
 void wm_window_set_size(wmWindow *win, int width, int height);
+void wm_window_check_position(rcti *rect);
 void wm_window_get_position(wmWindow *win, int *r_pos_x, int *r_pos_y);
 void wm_window_swap_buffers(wmWindow *win);
 void wm_window_set_swap_interval(wmWindow *win, int interval);

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to