diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 11 | ||||
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 42 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 21 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 89 |
5 files changed, 136 insertions, 29 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index b62d9960117..e6434a19952 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -61,6 +61,10 @@ struct rcti; struct wmOperator; struct wmOperatorType; struct wmWindow; +struct GPUFX; +struct GPUOffScreen; +struct GPUFXSettings; +enum eGPUFXFlags; /* for derivedmesh drawing callbacks, for view3d_select, .... */ typedef struct ViewContext { @@ -303,8 +307,11 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); 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(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky); +void ED_view3d_draw_offscreen( + struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], + float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, + struct GPUOffScreen *ofs, + struct GPUFX *fx, struct GPUFXSettings *fx_settings); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, bool draw_background, int alpha_mode, char err_out[256]); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index fc6ff4eb0c0..402e72db217 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -33,6 +33,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_camera_types.h" #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_blenlib.h" @@ -42,6 +43,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -68,6 +70,7 @@ #include "GPU_extensions.h" #include "GPU_glew.h" +#include "GPU_compositing.h" #include "render_intern.h" @@ -92,6 +95,7 @@ typedef struct OGLRender { ImageUser iuser; GPUOffScreen *ofs; + GPUFX *fx; int sizex, sizey; int write_still; @@ -180,7 +184,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) int i; unsigned char *gp_rect; - GPU_offscreen_bind(oglrender->ofs); + GPU_offscreen_bind(oglrender->ofs, true); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -200,22 +204,27 @@ static void screen_opengl_render_apply(OGLRender *oglrender) rgba_uchar_to_float(col_src, &gp_rect[i]); blend_color_mix_float(&rr->rectf[i], &rr->rectf[i], col_src); } - GPU_offscreen_unbind(oglrender->ofs); + GPU_offscreen_unbind(oglrender->ofs, true); MEM_freeN(gp_rect); } } else if (view_context) { + bool is_persp; + /* full copy */ + GPUFXSettings fx_settings = v3d->fx_settings; + ED_view3d_draw_offscreen_init(scene, v3d); - GPU_offscreen_bind(oglrender->ofs); /* bind */ + GPU_offscreen_bind(oglrender->ofs, true); /* bind */ /* render 3d view */ if (rv3d->persp == RV3D_CAMOB && v3d->camera) { /*int is_ortho = scene->r.mode & R_ORTHO;*/ camera = v3d->camera; RE_GetCameraWindow(oglrender->re, camera, scene->r.cfra, winmat); - + is_persp = true; + BKE_camera_to_gpu_dof(camera, &fx_settings); } else { rctf viewplane; @@ -224,12 +233,17 @@ static void screen_opengl_render_apply(OGLRender *oglrender) bool is_ortho = ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend, NULL); if (is_ortho) orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend); else perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); + + is_persp = !is_ortho; } rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); if ((scene->r.mode & R_OSA) == 0) { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky); + ED_view3d_draw_offscreen( + scene, v3d, ar, sizex, sizey, NULL, winmat, + draw_bgpic, draw_sky, is_persp, + oglrender->ofs, oglrender->fx, &fx_settings); GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect); } else { @@ -242,7 +256,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender) BLI_jitter_init(jit_ofs, scene->r.osa); /* first sample buffer, also initializes 'rv3d->persmat' */ - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky); + ED_view3d_draw_offscreen( + scene, v3d, ar, sizex, sizey, NULL, winmat, + draw_bgpic, draw_sky, is_persp, + oglrender->ofs, oglrender->fx, &fx_settings); GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect); for (i = 0; i < sizex * sizey * 4; i++) @@ -255,7 +272,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender) (jit_ofs[j][0] * 2.0f) / sizex, (jit_ofs[j][1] * 2.0f) / sizey); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, draw_bgpic, draw_sky); + ED_view3d_draw_offscreen( + scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, + draw_bgpic, draw_sky, is_persp, + oglrender->ofs, oglrender->fx, &fx_settings); GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect); for (i = 0; i < sizex * sizey * 4; i++) @@ -268,7 +288,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) MEM_freeN(accum_buffer); } - GPU_offscreen_unbind(oglrender->ofs); /* unbind */ + GPU_offscreen_unbind(oglrender->ofs, true); /* unbind */ } else { /* shouldnt suddenly give errors mid-render but possible */ @@ -448,6 +468,9 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) * running notifiers again will overwrite */ oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal; + if (oglrender->v3d->fx_settings.fx_flag & (GPU_FX_FLAG_DOF | GPU_FX_FLAG_SSAO)) { + oglrender->fx = GPU_fx_compositor_create(); + } } /* create render */ @@ -497,6 +520,9 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); + if (oglrender->fx) + GPU_fx_compositor_destroy(oglrender->fx); + GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6ac2f426ed7..01a70d36eda 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -7392,7 +7392,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { if (ob->type == OB_MESH) { if (dt < OB_SOLID) { - zbufoff = 1; + zbufoff = true; dt = OB_SOLID; } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 25085368dac..ff212a1d74e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -56,6 +56,7 @@ #include "GPU_extensions.h" #include "GPU_material.h" +#include "GPU_compositing.h" #include "BIF_gl.h" @@ -418,6 +419,11 @@ static void view3d_free(SpaceLink *sl) BKE_previewimg_free(&vd->defmaterial->preview); MEM_freeN(vd->defmaterial); } + + if (vd->fx_settings.ssao) + MEM_freeN(vd->fx_settings.ssao); + if (vd->fx_settings.dof) + MEM_freeN(vd->fx_settings.dof); } @@ -459,7 +465,11 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) } v3dn->properties_storage = NULL; - + if (v3dn->fx_settings.dof) + v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof); + if (v3dn->fx_settings.ssao) + v3dn->fx_settings.ssao = MEM_dupallocN(v3do->fx_settings.ssao); + return (SpaceLink *)v3dn; } @@ -559,6 +569,11 @@ static void view3d_main_area_exit(wmWindowManager *wm, ARegion *ar) GPU_offscreen_free(rv3d->gpuoffscreen); rv3d->gpuoffscreen = NULL; } + + if (rv3d->compositor) { + GPU_fx_compositor_destroy(rv3d->compositor); + rv3d->compositor = NULL; + } } static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) @@ -713,6 +728,9 @@ static void view3d_main_area_free(ARegion *ar) if (rv3d->gpuoffscreen) { GPU_offscreen_free(rv3d->gpuoffscreen); } + if (rv3d->compositor) { + GPU_fx_compositor_destroy(rv3d->compositor); + } MEM_freeN(rv3d); ar->regiondata = NULL; @@ -736,6 +754,7 @@ static void *view3d_main_area_duplicate(void *poin) new->render_engine = NULL; new->sms = NULL; new->smooth_timer = NULL; + new->compositor = NULL; return new; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 929929c7dd0..94d0ffcc9ee 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -94,6 +94,7 @@ #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" +#include "GPU_compositing.h" #include "view3d_intern.h" /* own include */ @@ -1374,7 +1375,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) } if (rv3d->gpuoffscreen) - GPU_offscreen_bind(rv3d->gpuoffscreen); + GPU_offscreen_bind(rv3d->gpuoffscreen, true); else glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); @@ -1397,7 +1398,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) draw_object_backbufsel(scene, v3d, rv3d, base->object); if (rv3d->gpuoffscreen) - GPU_offscreen_unbind(rv3d->gpuoffscreen); + GPU_offscreen_unbind(rv3d->gpuoffscreen, true); else ar->swap = 0; /* mark invalid backbuf for wm draw */ @@ -1423,10 +1424,10 @@ void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int form RegionView3D *rv3d = ar->regiondata; if (rv3d->gpuoffscreen) { - GPU_offscreen_bind(rv3d->gpuoffscreen); + GPU_offscreen_bind(rv3d->gpuoffscreen, true); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadPixels(x, y, w, h, format, type, data); - GPU_offscreen_unbind(rv3d->gpuoffscreen); + GPU_offscreen_unbind(rv3d->gpuoffscreen, true); } else { glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); @@ -2532,7 +2533,10 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) invert_m4_m4(rv3d.persinv, rv3d.viewinv); /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, false, false); + ED_view3d_draw_offscreen( + scene, v3d, &ar, winsize, winsize, viewmat, winmat, + false, false, true, + NULL, NULL, NULL); GPU_lamp_shadow_buffer_unbind(shadow->lamp); v3d->drawtype = drawtype; @@ -3049,13 +3053,18 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar, bool /* ED_view3d_draw_offscreen_init should be called before this to initialize * stuff like shadow buffers */ -void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, - float viewmat[4][4], float winmat[4][4], - bool do_bgpic, bool do_sky) +void ED_view3d_draw_offscreen( + Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, + float viewmat[4][4], float winmat[4][4], + bool do_bgpic, bool do_sky, bool is_persp, + GPUOffScreen *ofs, + GPUFX *fx, GPUFXSettings *fx_settings) { struct bThemeState theme_state; int bwinx, bwiny; rcti brect; + bool do_compositing = false; + RegionView3D *rv3d = ar->regiondata; glPushMatrix(); @@ -3082,9 +3091,15 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); } - /* setup view matrices */ + + /* setup view matrices before fx or unbinding the offscreen buffers will cause issues */ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); - + + /* framebuffer fx needed, we need to draw offscreen first */ + if (v3d->fx_settings.fx_flag && fx) { + do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings); + } + /* clear opengl buffers */ if (do_sky) { view3d_main_area_clear(scene, v3d, ar, true); @@ -3097,6 +3112,13 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* main drawing call */ view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true); + /* post process */ + if (do_compositing) { + if (!winmat) + is_persp = rv3d->is_persp; + GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs); + } + if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { /* draw grease-pencil stuff */ ED_region_pixelspace(ar); @@ -3131,7 +3153,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in ImBuf *ibuf; GPUOffScreen *ofs; bool draw_sky = (alpha_mode == R_ADDSKY); - + /* state changes make normal drawing go weird otherwise */ glPushAttrib(GL_LIGHTING_BIT); @@ -3144,11 +3166,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in ED_view3d_draw_offscreen_init(scene, v3d); - GPU_offscreen_bind(ofs); + GPU_offscreen_bind(ofs, true); /* render 3d view */ if (rv3d->persp == RV3D_CAMOB && v3d->camera) { CameraParams params; + GPUFXSettings fx_settings = {0}; + Object *camera = v3d->camera; BKE_camera_params_init(¶ms); /* fallback for non camera objects */ @@ -3158,10 +3182,18 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, draw_sky); + BKE_camera_to_gpu_dof(camera, &fx_settings); + + ED_view3d_draw_offscreen( + scene, v3d, ar, sizex, sizey, NULL, params.winmat, + draw_background, draw_sky, !params.is_ortho, + ofs, NULL, &fx_settings); } else { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, draw_sky); + ED_view3d_draw_offscreen( + scene, v3d, ar, sizex, sizey, NULL, NULL, + draw_background, draw_sky, true, + ofs, NULL, NULL); } /* read in pixels & stamp */ @@ -3173,7 +3205,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); /* unbind */ - GPU_offscreen_unbind(ofs); + GPU_offscreen_unbind(ofs, true); GPU_offscreen_free(ofs); glPopAttrib(); @@ -3451,13 +3483,15 @@ static void update_lods(Scene *scene, float camera_pos[3]) } #endif - static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar, const char **grid_unit) { RegionView3D *rv3d = ar->regiondata; unsigned int lay_used = v3d->lay_used; - + + /* post processing */ + bool do_compositing = false; + /* shadow buffers, before we setup matrices */ if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) gpu_update_lamps_shadows(scene, v3d); @@ -3481,6 +3515,22 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3 } #endif + /* framebuffer fx needed, we need to draw offscreen first */ + if (v3d->fx_settings.fx_flag) { + GPUFXSettings fx_settings; + BKE_screen_gpu_fx_validate(&v3d->fx_settings); + fx_settings = v3d->fx_settings; + if (!rv3d->compositor) + rv3d->compositor = GPU_fx_compositor_create(); + + if (rv3d->persp == RV3D_CAMOB && v3d->camera) + BKE_camera_to_gpu_dof(v3d->camera, &fx_settings); + else { + fx_settings.dof = NULL; + } + do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings); + } + /* clear the background */ view3d_main_area_clear(scene, v3d, ar, false); @@ -3492,6 +3542,11 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3 /* main drawing call */ view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false); + /* post process */ + if (do_compositing) { + GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL); + } + /* Disable back anti-aliasing */ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { glDisable(GL_MULTISAMPLE_ARB); |