forked from bartvdbraak/blender
Fix #34997: when starting the game engine in one window and switching to a second
window, the game would stop drawing in the first and mess up the OpenGL state of the second. Also fixes glPushAttrib/glPopAttrib getting out of sync in some cases.
This commit is contained in:
parent
fb2b3155f7
commit
feeab1ad53
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -37,7 +37,8 @@
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user