diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-06-29 10:48:51 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-06-29 11:21:53 +0300 |
commit | f021635bd5311bff28d44989f2fc14d3e37215a8 (patch) | |
tree | 70bbaabd9208743d6a79bf14a1adef0b42dcbc6d /source/blender/windowmanager | |
parent | 71086995a552d41be361e49e7c3f3cfbfffa4dac (diff) |
WM: support window context override
This makes it possible to take a screenshot from any window in Python.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 44 |
2 files changed, 46 insertions, 0 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 61b3b8aa2a2..d4fbbd1ecff 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -105,6 +105,8 @@ void WM_init_opengl(struct Main *bmain); void WM_check(struct bContext *C); void WM_reinit_gizmomap_all(struct Main *bmain); +uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, int r_size[2]); + int WM_window_pixels_x(const struct wmWindow *win); int WM_window_pixels_y(const struct wmWindow *win); void WM_window_rect_calc(const struct wmWindow *win, struct rcti *r_rect); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 7558468c3b5..ea3596a2143 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1937,6 +1937,50 @@ bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Window Screen Shot Utility + * + * Include here since it can involve low level buffer switching. + * + * \{ */ + +uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2]) +{ + bool setup_context = wm->windrawable != win; + + if (setup_context) { + GHOST_ActivateWindowDrawingContext(win->ghostwin); + GPU_context_active_set(win->gpuctx); + } + + r_size[0] = WM_window_pixels_x(win); + r_size[1] = WM_window_pixels_y(win); + const uint rect_len = r_size[0] * r_size[1]; + uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__); + + glReadBuffer(GL_FRONT); + glReadPixels(0, 0, r_size[0], r_size[1], GL_RGBA, GL_UNSIGNED_BYTE, rect); + glFinish(); + glReadBuffer(GL_BACK); + + if (setup_context) { + if (wm->windrawable) { + GHOST_ActivateWindowDrawingContext(wm->windrawable->ghostwin); + GPU_context_active_set(wm->windrawable->gpuctx); + } + } + + /* Clear alpha, it is not set to a meaningful value in OpenGL. */ + uchar *cp = (uchar *)rect; + uint i; + for (i = 0, cp += 3; i < rect_len; i++, cp += 4) { + *cp = 0xff; + } + return (uint *)rect; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Initial Window State API * \{ */ |