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:
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);