[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