diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c4229428cd7..776b1a0bbb3 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2776,8 +2776,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in /* bind */ ofs = GPU_offscreen_create(sizex, sizey, err_out); - if (ofs == NULL) + if (ofs == NULL) { + glPopAttrib(); return NULL; + } ED_view3d_draw_offscreen_init(scene, v3d); diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 5d645a5545b..7909213e793 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -900,8 +900,7 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex) void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, int w, int h) { /* push attributes */ - glPushAttrib(GL_ENABLE_BIT); - glPushAttrib(GL_VIEWPORT_BIT); + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT); glDisable(GL_SCISSOR_TEST); /* bind framebuffer */ @@ -927,7 +926,6 @@ void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUS /* restore attributes */ glPopAttrib(); - glPopAttrib(); glEnable(GL_SCISSOR_TEST); } diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index f7b7aa87cf8..0e1e41b0149 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -384,7 +384,7 @@ void wm_add_default(bContext *C) wm->winactive = win; wm->file_saved = 1; - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); } diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 396c827fe25..005d02647a4 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -828,7 +828,7 @@ void wm_draw_update(bContext *C) CTX_wm_window_set(C, win); /* sets context window+screen */ - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); /* notifiers for screen redraw */ if (win->screen->do_refresh) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index fcacfbbb686..098fe72688c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2130,7 +2130,7 @@ void wm_event_do_handlers(bContext *C) CTX_wm_region_set(C, region_event_inside(C, &event->x)); /* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */ - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); wm_region_mouse_co(C, event); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 70cb10476d7..fe419010780 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -677,10 +677,8 @@ static int query_qual(modifierKeyType qual) return val; } -void wm_window_make_drawable(bContext *C, wmWindow *win) +void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) { - wmWindowManager *wm = CTX_wm_manager(C); - if (win != wm->windrawable && win->ghostwin) { // win->lmbut = 0; /* keeps hanging when mousepressed while other window opened */ @@ -786,7 +784,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr win->addmousemove = 1; /* enables highlighted buttons */ - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); /* window might be focused by mouse click in configuration of window manager * when focus is not following mouse @@ -817,7 +815,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr printf("%s: ghost redraw %d\n", __func__, win->winid); } - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); WM_event_add_notifier(C, NC_WINDOW, NULL); break; @@ -898,7 +896,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr } } - wm_window_make_drawable(C, win); + wm_window_make_drawable(wm, win); wm_draw_window_clear(win); WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL); diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index a0546c88b78..22fa2423f61 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -51,7 +51,7 @@ void wm_window_add_ghostwindows (wmWindowManager *wm); void wm_window_process_events (const bContext *C); void wm_window_process_events_nosleep(void); -void wm_window_make_drawable(bContext *C, wmWindow *win); +void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win); void wm_window_raise (wmWindow *win); void wm_window_lower (wmWindow *win); diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 38302a51a45..dbb7cbc1816 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -210,6 +210,7 @@ static int BL_KetsjiPyNextFrame(void *state0) extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing) { /* context values */ + struct wmWindowManager *wm= CTX_wm_manager(C); struct wmWindow *win= CTX_wm_window(C); struct Scene *startscene= CTX_data_scene(C); struct Main* maggie1= CTX_data_main(C); @@ -276,7 +277,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */ // create the canvas, rasterizer and rendertools - RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar); + RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar); // default mouse state set on render panel if (mouse_state) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index b6c41064282..3bd1c02f12e 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -37,7 +37,8 @@ #include -KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) : +KX_BlenderCanvas::KX_BlenderCanvas(wmWindowManager *wm, wmWindow *win, RAS_Rect &rect, struct ARegion *ar) : +m_wm(wm), m_win(win), m_frame_rect(rect) { @@ -81,20 +82,29 @@ bool KX_BlenderCanvas::GetFullScreen() return false; } +bool KX_BlenderCanvas::BeginDraw() +{ + // in case of multi-window we need to ensure we are drawing to the correct + // window always, because it may change in window event handling + BL_MakeDrawable(m_wm, m_win); + return true; +} + + +void KX_BlenderCanvas::EndDraw() +{ + // nothing needs to be done here +} + void KX_BlenderCanvas::BeginFrame() { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); - } void KX_BlenderCanvas::EndFrame() { - // this is needed, else blender distorts a lot - glPopAttrib(); - glPushAttrib(GL_ALL_ATTRIB_BITS); - glDisable(GL_FOG); } diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index bc487504eeb..c201d866efe 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -49,6 +49,7 @@ struct ARegion; struct wmWindow; +struct wmWindowManager; /** * 2D Blender device context abstraction. @@ -69,7 +70,7 @@ public: * * \param area The Blender ARegion to run the game within. */ - KX_BlenderCanvas(struct wmWindow* win, class RAS_Rect &rect, struct ARegion* ar); + KX_BlenderCanvas(struct wmWindowManager *wm, struct wmWindow* win, class RAS_Rect &rect, struct ARegion* ar); ~KX_BlenderCanvas(); void @@ -186,25 +187,17 @@ public: const char* filename ); - /** - * Nothing needs be done for BlenderCanvas - * Begin/End Draw, as the game engine GL context - * is always current/active. - */ - bool BeginDraw( - ) { - return true; - }; + ); void EndDraw( - ) { - }; + ); private: /** Blender area the game engine is running within */ + struct wmWindowManager *m_wm; struct wmWindow* m_win; RAS_Rect m_frame_rect; RAS_Rect m_area_rect; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index f43f8c30d57..61598995040 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -93,6 +93,11 @@ void BL_SwapBuffers(wmWindow *win) wm_window_swap_buffers(win); } +void BL_MakeDrawable(wmWindowManager *wm, wmWindow *win) +{ + wm_window_make_drawable(wm, win); +} + static void DisableForText() { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 0f35494c73a..54e76ff6489 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -36,13 +36,16 @@ extern "C" { #endif /* __cplusplus */ -struct wmWindow; struct ARegion; struct bScreen; +struct wmWindow; +struct wmWindowManager; // special swapbuffers, that takes care of which area (viewport) needs to be swapped void BL_SwapBuffers(struct wmWindow *win); +void BL_MakeDrawable(struct wmWindowManager *wm, struct wmWindow *win); + void BL_warp_pointer(struct wmWindow *win,int x,int y); void BL_MakeScreenShot(struct bScreen *screen, struct ScrArea *curarea, const char *filename);