[Bf-blender-cvs] [8dd6f89a5d1] vr_scene_inspection: Bring back vertically mirrored drawing for DirectX compatibility

Julian Eisel noreply at git.blender.org
Wed Feb 19 21:17:48 CET 2020


Commit: 8dd6f89a5d1468524a26c350cd5f393c723aa905
Author: Julian Eisel
Date:   Wed Feb 19 14:48:23 2020 +0100
Branches: vr_scene_inspection
https://developer.blender.org/rB8dd6f89a5d1468524a26c350cd5f393c723aa905

Bring back vertically mirrored drawing for DirectX compatibility

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

M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/windowmanager/intern/wm_xr.c

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

diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index a3ee2d11e56..8db9102de7c 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -532,6 +532,13 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
   }
 }
 
+/**
+ * Merge and draw the buffers of \a viewport into the currently active framebuffer, performing
+ * color transform to display space.
+ *
+ * \param rect: Coordinates to draw into. By swapping min and max values, drawing can be done with
+ *              inversed axis coordinates (upside down or sideways).
+ */
 void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
 {
   DefaultFramebufferList *dfbl = viewport->fbl;
@@ -545,18 +552,22 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
   const float w = (float)GPU_texture_width(color);
   const float h = (float)GPU_texture_height(color);
 
-  BLI_assert(w == BLI_rcti_size_x(rect) + 1);
-  BLI_assert(h == BLI_rcti_size_y(rect) + 1);
+  /* We allow rects with min/max swapped, but we also need coorectly assigned coordinates. */
+  rcti sanitized_rect = *rect;
+  BLI_rcti_sanitize(&sanitized_rect);
+
+  BLI_assert(w == BLI_rcti_size_x(&sanitized_rect) + 1);
+  BLI_assert(h == BLI_rcti_size_y(&sanitized_rect) + 1);
 
   /* wmOrtho for the screen has this same offset */
   const float halfx = GLA_PIXEL_OFS / w;
   const float halfy = GLA_PIXEL_OFS / h;
 
   rctf pos_rect = {
-      .xmin = rect->xmin,
-      .ymin = rect->ymin,
-      .xmax = rect->xmin + w,
-      .ymax = rect->ymin + h,
+      .xmin = sanitized_rect.xmin,
+      .ymin = sanitized_rect.ymin,
+      .xmax = sanitized_rect.xmin + w,
+      .ymax = sanitized_rect.ymin + h,
   };
 
   rctf uv_rect = {
@@ -565,6 +576,14 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
       .xmax = halfx + 1.0f,
       .ymax = halfy + 1.0f,
   };
+  /* Mirror the UV rect in case axis-swapped drawing is requested (by passing a rect with min and
+   * max values swapped). */
+  if (BLI_rcti_size_x(rect) < 0) {
+    SWAP(int, uv_rect.xmin, uv_rect.xmax);
+  }
+  if (BLI_rcti_size_y(rect) < 0) {
+    SWAP(int, uv_rect.ymin, uv_rect.ymax);
+  }
 
   gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, true);
 }
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 19ec92de26d..bb5a8c4d0a1 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -374,6 +374,7 @@ bool WM_xr_is_session_running(const wmXrData *xr)
  */
 static void wm_xr_session_surface_draw(bContext *C)
 {
+  wmXrSurfaceData *surface_data = g_xr_surface->customdata;
   wmWindowManager *wm = CTX_wm_manager(C);
 
   if (!GHOST_XrSessionIsRunning(wm->xr.context)) {
@@ -381,7 +382,7 @@ static void wm_xr_session_surface_draw(bContext *C)
   }
   GHOST_XrSessionDrawViews(wm->xr.context, C);
 
-  GPU_framebuffer_restore();
+  GPU_offscreen_unbind(surface_data->offscreen, false);
 }
 
 static void wm_xr_session_free_data(wmSurface *surface)
@@ -534,6 +535,22 @@ static void wm_xr_draw_matrices_create(const GHOST_XrDrawViewInfo *draw_view,
   mul_m4_m4m4(r_view_mat, eye_mat, base_mat);
 }
 
+static void wm_xr_draw_viewport_buffers_to_active_framebuffer(
+    const wmXrSurfaceData *surface_data, const GHOST_XrDrawViewInfo *draw_view)
+{
+  const bool is_upside_down = surface_data->secondary_ghost_ctx &&
+                              GHOST_isUpsideDownContext(surface_data->secondary_ghost_ctx);
+  rcti rect = {.xmin = 0, .ymin = 0, .xmax = draw_view->width - 1, .ymax = draw_view->height - 1};
+
+  wmViewport(&rect);
+
+  /* For upside down contexts, draw with inverted y-values. */
+  if (is_upside_down) {
+    SWAP(int, rect.ymin, rect.ymax);
+  }
+  GPU_viewport_draw_to_screen(surface_data->viewport, &rect);
+}
+
 /**
  * \brief Draw a viewport for a single eye.
  *
@@ -549,11 +566,7 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
   Scene *scene = CTX_data_scene(C);
 
   const float display_flags = V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS | settings->draw_flags;
-  const rcti rect = {
-      .xmin = 0, .ymin = 0, .xmax = draw_view->width - 1, .ymax = draw_view->height - 1};
 
-  GPUOffScreen *offscreen;
-  GPUViewport *viewport;
   float viewmat[4][4], winmat[4][4];
 
   /* The runtime may still trigger drawing while a session-end request is pending. */
@@ -568,12 +581,10 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
     return;
   }
 
-  offscreen = surface_data->offscreen;
-  viewport = surface_data->viewport;
-  glClear(GL_DEPTH_BUFFER_BIT);
   /* In case a framebuffer is still bound from drawing the last eye. */
   GPU_framebuffer_restore();
 
+  /* Draws the view into the surface_data->viewport's framebuffers */
   ED_view3d_draw_offscreen_simple(CTX_data_ensure_evaluated_depsgraph(C),
                                   scene,
                                   &wm->xr.session_settings.shading,
@@ -589,22 +600,14 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
                                   true,
                                   NULL,
                                   false,
-                                  offscreen,
-                                  viewport);
+                                  surface_data->offscreen,
+                                  surface_data->viewport);
 
-  BLI_assert(GPU_context_active_get() == DRW_gpu_context_get());
+  /* Re-use the offscreen framebuffer to render the composited viewport into. Keep it bound,
+   * Ghost-XR will then blit from the currently bound framebuffer into the OpenXR swapchain. */
+  GPU_offscreen_bind(surface_data->offscreen, false);
 
-  // TODO
-  //  const bool is_upside_down = surface_data->secondary_ghost_ctx &&
-  //                              GHOST_isUpsideDownContext(surface_data->secondary_ghost_ctx);
-
-  DefaultFramebufferList *dfl = GPU_viewport_framebuffer_list_get(viewport);
-
-  /* Draw into viewport default framebuffer and leave it bound when exiting this function. Ghost-XR
-   * will blit from the currently bound framebuffer into the OpenXR swapchain. */
-  GPU_framebuffer_bind(dfl->default_fb);
-  wmViewport(&rect);
-  GPU_viewport_draw_to_screen(viewport, &rect);
+  wm_xr_draw_viewport_buffers_to_active_framebuffer(surface_data, draw_view);
 }
 
 /** \} */ /* XR Drawing */



More information about the Bf-blender-cvs mailing list