[Bf-blender-cvs] [71c7d618089] soc-2019-openxr: Draw OpenGL framebuffer upside down in DirectX windows
Julian Eisel
noreply at git.blender.org
Sun Jun 16 21:48:11 CEST 2019
Commit: 71c7d61808957eb301cdd313feae134b13936942
Author: Julian Eisel
Date: Sun Jun 16 21:34:43 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB71c7d61808957eb301cdd313feae134b13936942
Draw OpenGL framebuffer upside down in DirectX windows
DirectX is Y coordinates top to bottom, while OpenGL is the opposite.
For the final window manager on-screen drawing, draw to a texture first
and draw that upside down if needed.
===================================================================
M intern/ghost/GHOST_C-api.h
M intern/ghost/GHOST_IWindow.h
M intern/ghost/intern/GHOST_C-api.cpp
M intern/ghost/intern/GHOST_Context.h
M intern/ghost/intern/GHOST_ContextD3D.h
M intern/ghost/intern/GHOST_Window.cpp
M intern/ghost/intern/GHOST_Window.h
M source/blender/windowmanager/intern/wm_draw.c
===================================================================
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 2ae94318ed8..fb59918d417 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -212,6 +212,11 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
*/
extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata);
+/**
+ * Returns whether a window is rendered upside down compared to OpenGL.
+ */
+extern int GHOST_isUpsideDownWindow(GHOST_WindowHandle windowhandle);
+
/**
* Dispose a window.
* \param systemhandle The handle to the system
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 902af107bdf..d0ac770d0ac 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -245,6 +245,11 @@ class GHOST_IWindow {
*/
virtual void setUserData(const GHOST_TUserDataPtr userData) = 0;
+ /**
+ * Returns if the window is rendered upside down compared to OpenGL.
+ */
+ virtual bool isUpsideDown() const = 0;
+
/**
* Returns the tablet data (pressure etc).
* \return The tablet data (pressure etc).
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 1de5fee30c7..1d2f5e0c5ed 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -171,6 +171,13 @@ void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr
window->setUserData(userdata);
}
+int GHOST_isUpsideDownWindow(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+
+ return window->isUpsideDown();
+}
+
GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
GHOST_WindowHandle windowhandle)
{
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index 5127aed6c15..cd32f250967 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -120,6 +120,11 @@ class GHOST_Context : public GHOST_IContext {
return m_stereoVisual;
}
+ inline virtual 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_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
index 9223bf52e61..9f067fa23ce 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.h
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -108,6 +108,11 @@ class GHOST_ContextD3D : public GHOST_Context {
GHOST_TInt32 width,
GHOST_TInt32 height);
+ bool isUpsideDown() const
+ {
+ return true;
+ }
+
private:
friend class SharedOpenGLContext;
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index bbeb675524c..12955c252b0 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -124,6 +124,11 @@ GHOST_TSuccess GHOST_Window::blitOpenGLOffscreenContext(GHOST_IContext *offscree
(GHOST_Context *)offscreen_ctx, rect.getWidth(), rect.getHeight());
}
+bool GHOST_Window::isUpsideDown() const
+{
+ return m_context->isUpsideDown();
+}
+
GHOST_TSuccess GHOST_Window::activateDrawingContext()
{
return m_context->activateDrawingContext();
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 4d4501242e6..ec8433b8aa6 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -292,6 +292,8 @@ class GHOST_Window : public GHOST_IWindow {
m_userData = userData;
}
+ bool isUpsideDown() const;
+
float getNativePixelSize(void)
{
if (m_nativePixelSize > 0.0f)
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 0ec35aaeb8c..7fa1b16a425 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -722,6 +722,73 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
}
}
+static void wm_draw_upside_down(wmWindow *win)
+{
+ GPUVertFormat *format = immVertexFormat();
+ uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
+
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
+
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizex;
+
+ immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
+
+ immBegin(GPU_PRIM_TRI_FAN, 4);
+
+ immAttr2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, 0.0f, 0.0f);
+
+ immAttr2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, sizex, 0.0f);
+
+ immAttr2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, sizex, sizey);
+
+ immAttr2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, sizey);
+
+ immEnd();
+
+ immUnbindProgram();
+}
+
+static void wm_draw_window_upside_down_onscreen(bContext *C, wmWindow *win)
+{
+ const int width = WM_window_pixels_x(win);
+ const int height = WM_window_pixels_y(win);
+ GPUOffScreen *offscreen = GPU_offscreen_create(width, height, 0, false, false, NULL);
+
+ /* Upside down rendering only implemented for non-stereo. Easy to add but makes code messy. */
+ BLI_assert(
+ !(WM_stereo3d_enabled(win, false) && GHOST_isUpsideDownWindow(win->offscreen_context)));
+
+ if (offscreen) {
+ GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
+ wm_draw_offscreen_texture_parameters(offscreen);
+
+ /* Draw view into offscreen buffer. */
+ GPU_offscreen_bind(offscreen, false);
+ wm_draw_window_onscreen(C, win, -1);
+ GPU_offscreen_unbind(offscreen, false);
+
+ /* Draw offscreen buffer to screen. */
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+
+ wm_draw_upside_down(win);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ GPU_offscreen_free(offscreen);
+ }
+}
+
static void wm_draw_window(bContext *C, wmWindow *win)
{
bScreen *screen = WM_window_get_active_screen(win);
@@ -733,8 +800,13 @@ static void wm_draw_window(bContext *C, wmWindow *win)
/* Now we draw into the window framebuffer, in full window coordinates. */
if (!stereo) {
- /* Regular mono drawing. */
- wm_draw_window_onscreen(C, win, -1);
+ if (GHOST_isUpsideDownWindow(win->ghostwin)) {
+ wm_draw_window_upside_down_onscreen(C, win);
+ }
+ else {
+ /* Regular mono drawing. */
+ wm_draw_window_onscreen(C, win, -1);
+ }
}
else if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
/* For pageflip we simply draw to both back buffers. */
More information about the Bf-blender-cvs
mailing list