Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-02-12 20:54:41 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-02-12 20:54:41 +0300
commit5e613198e59124986ab3e4bdb8829f77e2284450 (patch)
tree6659b06236acf73a8c687ea15867a83f1c63983c /source/blender/editors
parentd40ac45610edef50885ce73034f7c035f48cc9c1 (diff)
Viewport compositing - first code
This commit introduces a few ready made effects for the 3D viewport and OpenGL rendering. Included effects are Depth of Field, accessible from camera view and screen space ambient occlusion. Those effects can be turned on and tweaked from the shading panel in the 3D viewport. Off screen rendering will use the settings of the current camera. WIP documentation can be found here: http://wiki.blender.org/index.php/User:Psy-Fi/Framebuffer_Post-processing
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_view3d.h11
-rw-r--r--source/blender/editors/render/render_opengl.c42
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c89
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(&params);
/* 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(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
- 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);