From 3f85eeddaa8c6ab076c3d6e59b43d9915bcd9592 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 27 Oct 2015 11:27:26 -0200 Subject: [PATCH] View3D offscreen buffer was interferring with view navigation the RegionView3D matrices need to be re-set after drawing. Review and touch ups by Campbell Barton --- source/blender/editors/include/ED_view3d.h | 3 ++ .../editors/space_view3d/view3d_draw.c | 44 +++++++++++++++++++ source/blender/python/intern/gpu_offscreen.c | 8 ++++ 3 files changed, 55 insertions(+) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 5cd73e4efb5..9da12211daa 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -319,6 +319,9 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d); #endif int ED_view3d_scene_layer_set(int lay, const int *values, int *active); +void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d); +void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt); + bool ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d); void ED_view3d_draw_offscreen( diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 3e0ea5fac07..01398c8335b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2643,6 +2643,9 @@ CustomDataMask ED_view3d_screen_datamask(const bScreen *screen) return mask; } +/** + * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore + */ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2916,6 +2919,47 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, glLoadMatrixf(rv3d->viewmat); } +/** + * Store values from #RegionView3D, set when drawing. + * This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example). + * + * Values set by #ED_view3d_update_viewmat should be handled here. + */ +struct RV3DMatrixStore { + float winmat[4][4]; + float viewmat[4][4]; + float viewinv[4][4]; + float persmat[4][4]; + float persinv[4][4]; + float viewcamtexcofac[4]; + float pixsize; +}; + +void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d) +{ + struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__); + copy_m4_m4(rv3dmat->winmat, rv3d->winmat); + copy_m4_m4(rv3dmat->viewmat, rv3d->viewmat); + copy_m4_m4(rv3dmat->persmat, rv3d->persmat); + copy_m4_m4(rv3dmat->persinv, rv3d->persinv); + copy_m4_m4(rv3dmat->viewinv, rv3d->viewinv); + copy_v4_v4(rv3dmat->viewcamtexcofac, rv3d->viewcamtexcofac); + rv3dmat->pixsize = rv3d->pixsize; + return (void *)rv3dmat; +} + +void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt) +{ + struct RV3DMatrixStore *rv3dmat = rv3dmat_pt; + copy_m4_m4(rv3d->winmat, rv3dmat->winmat); + copy_m4_m4(rv3d->viewmat, rv3dmat->viewmat); + copy_m4_m4(rv3d->persmat, rv3dmat->persmat); + copy_m4_m4(rv3d->persinv, rv3dmat->persinv); + copy_m4_m4(rv3d->viewinv, rv3dmat->viewinv); + copy_v4_v4(rv3d->viewcamtexcofac, rv3dmat->viewcamtexcofac); + rv3d->pixsize = rv3dmat->pixsize; +} + void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) { /* shadow buffers, before we setup matrices */ diff --git a/source/blender/python/intern/gpu_offscreen.c b/source/blender/python/intern/gpu_offscreen.c index f8285c6139f..ed31ac052c6 100644 --- a/source/blender/python/intern/gpu_offscreen.c +++ b/source/blender/python/intern/gpu_offscreen.c @@ -29,6 +29,8 @@ #include +#include "MEM_guardedalloc.h" + #include "BLI_utildefines.h" #include "WM_types.h" @@ -200,6 +202,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a ARegion *ar; GPUFX *fx; GPUFXSettings fx_settings; + void *rv3d_mats; BPY_GPU_OFFSCREEN_CHECK_OBJ(self); @@ -221,6 +224,8 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a ED_view3d_draw_offscreen_init(scene, v3d); + rv3d_mats = ED_view3d_mats_rv3d_backup(ar->regiondata); + GPU_offscreen_bind(self->ofs, true); /* bind */ ED_view3d_draw_offscreen( @@ -233,6 +238,9 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a GPU_fx_compositor_destroy(fx); GPU_offscreen_unbind(self->ofs, true); /* unbind */ + ED_view3d_mats_rv3d_restore(ar->regiondata, rv3d_mats); + MEM_freeN(rv3d_mats); + Py_RETURN_NONE; }