[Bf-blender-cvs] [be7b41df3ff] soc-2019-openxr: Bring back vertically mirrored drawing for DirectX compatibility
Julian Eisel
noreply at git.blender.org
Mon Mar 2 17:13:47 CET 2020
Commit: be7b41df3ff45c08ce79d4d4c8aca8416ac39a9d
Author: Julian Eisel
Date: Wed Feb 19 14:48:23 2020 +0100
Branches: soc-2019-openxr
https://developer.blender.org/rBbe7b41df3ff45c08ce79d4d4c8aca8416ac39a9d
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 b1a038a48c3..a3a0b692ac5 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -240,6 +240,7 @@ void wm_xr_session_toggle(bContext *C, void *xr_context_ptr)
*/
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)) {
@@ -247,7 +248,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)
@@ -399,6 +400,22 @@ static void wm_xr_draw_matrices_create(const Scene *scene,
}
}
+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.
*
@@ -412,11 +429,7 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
wmXrSurfaceData *surface_data = g_xr_surface->customdata;
bXrSessionSettings *settings = &wm->xr.session_settings;
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;
View3DShading shading;
float viewmat[4][4], winmat[4][4];
@@ -427,9 +440,6 @@ 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();
@@ -438,6 +448,7 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
shading.flag &= ~V3D_SHADING_SPECULAR_HIGHLIGHT;
shading.background_type = V3D_SHADING_BACKGROUND_WORLD;
+ /* Draws the view into the surface_data->viewport's framebuffers */
ED_view3d_draw_offscreen_simple(CTX_data_ensure_evaluated_depsgraph(C),
CTX_data_scene(C),
&shading,
@@ -453,22 +464,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