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/render/render_opengl.c')
-rw-r--r--source/blender/editors/render/render_opengl.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 1133b5f79d1..6e969067985 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -55,6 +55,8 @@
#include "BKE_sequencer.h"
#include "BKE_writeavi.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -70,9 +72,10 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_glew.h"
#include "GPU_compositing.h"
#include "GPU_framebuffer.h"
+#include "GPU_glew.h"
+#include "GPU_matrix.h"
#include "render_intern.h"
@@ -91,6 +94,9 @@ typedef struct OGLRender {
Main *bmain;
Render *re;
Scene *scene;
+ WorkSpace *workspace;
+ ViewLayer *view_layer;
+ Depsgraph *depsgraph;
View3D *v3d;
RegionView3D *rv3d;
@@ -148,17 +154,6 @@ typedef struct OGLRender {
#endif
} OGLRender;
-/* added because v3d is not always valid */
-static unsigned int screen_opengl_layers(OGLRender *oglrender)
-{
- if (oglrender->v3d) {
- return oglrender->scene->lay | oglrender->v3d->lay;
- }
- else {
- return oglrender->scene->lay;
- }
-}
-
static bool screen_opengl_is_multiview(OGLRender *oglrender)
{
View3D *v3d = oglrender->v3d;
@@ -271,9 +266,10 @@ static void screen_opengl_views_setup(OGLRender *oglrender)
RE_ReleaseResult(oglrender->re);
}
-static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
+static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr)
{
Scene *scene = oglrender->scene;
+ ViewLayer *view_layer = oglrender->view_layer;
ARegion *ar = oglrender->ar;
View3D *v3d = oglrender->v3d;
RegionView3D *rv3d = oglrender->rv3d;
@@ -283,9 +279,12 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
const short view_context = (v3d != NULL);
bool draw_bgpic = true;
bool draw_sky = (scene->r.alphamode == R_ADDSKY);
- unsigned char *rect = NULL;
+ float *rectf = NULL;
const char *viewname = RE_GetActiveRenderView(oglrender->re);
ImBuf *ibuf_result = NULL;
+ EvaluationContext eval_ctx;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
if (oglrender->is_sequencer) {
SpaceSeq *sseq = oglrender->sseq;
@@ -330,7 +329,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
wmOrtho2(0, sizex, 0, sizey);
- glTranslatef(sizex / 2, sizey / 2, 0.0f);
+ gpuTranslate2f(sizex / 2, sizey / 2);
G.f |= G_RENDER_OGL;
ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
@@ -360,8 +359,8 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
draw_flags |= (draw_bgpic) ? V3D_OFSDRAW_USE_BACKGROUND : 0;
ibuf_view = ED_view3d_draw_offscreen_imbuf(
- scene, v3d, ar, sizex, sizey,
- IB_rect, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
+ &eval_ctx, scene, view_layer, v3d, ar, sizex, sizey,
+ IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
/* for stamp only */
@@ -372,8 +371,8 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
else {
draw_flags |= (V3D_OFSDRAW_USE_GPENCIL | V3D_OFSDRAW_USE_BACKGROUND);
ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(
- scene, scene->camera, oglrender->sizex, oglrender->sizey,
- IB_rect, draw_flags, OB_SOLID,
+ &eval_ctx, scene, view_layer, scene->camera, oglrender->sizex, oglrender->sizey,
+ IB_rectfloat, draw_flags, OB_SOLID,
alpha_mode, oglrender->ofs_samples, viewname,
oglrender->fx, oglrender->ofs, err_out);
camera = scene->camera;
@@ -381,7 +380,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
if (ibuf_view) {
ibuf_result = ibuf_view;
- rect = (unsigned char *)ibuf_view->rect;
+ rectf = (float *)ibuf_view->rect_float;
}
else {
fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
@@ -390,7 +389,7 @@ static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
if (ibuf_result != NULL) {
if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
- BKE_image_stamp_buf(scene, camera, NULL, rect, NULL, rr->rectx, rr->recty, 4);
+ BKE_image_stamp_buf(scene, camera, NULL, NULL, rectf, rr->rectx, rr->recty, 4);
}
RE_render_result_rect_from_ibuf(rr, &scene->r, ibuf_result, oglrender->view_id);
IMB_freeImBuf(ibuf_result);
@@ -435,7 +434,7 @@ static void addAlphaOverFloat(float dest[4], const float source[4])
}
/* add renderlayer and renderpass for each grease pencil layer for using in composition */
-static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, RenderView *rv)
+static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv)
{
bGPdata *gpd = oglrender->scene->gpd;
Scene *scene = oglrender->scene;
@@ -479,7 +478,7 @@ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, Rende
}
/* render this gp layer */
- screen_opengl_render_doit(oglrender, rr);
+ screen_opengl_render_doit(C, oglrender, rr);
/* add RendePass composite */
RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name);
@@ -519,7 +518,7 @@ static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, Rende
scene->r.alphamode = oldalphamode;
}
-static void screen_opengl_render_apply(OGLRender *oglrender)
+static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
{
RenderResult *rr;
RenderView *rv;
@@ -557,10 +556,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* add grease pencil passes. For sequencer, the render does not include renderpasses
* TODO: The sequencer render of grease pencil should be rethought */
if (!oglrender->is_sequencer) {
- add_gpencil_renderpass(oglrender, rr, rv);
+ add_gpencil_renderpass(C, oglrender, rr, rv);
}
/* render composite */
- screen_opengl_render_doit(oglrender, rr);
+ screen_opengl_render_doit(C, oglrender, rr);
}
RE_ReleaseResult(oglrender->re);
@@ -576,11 +575,30 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
}
}
+static bool screen_opengl_fullsample_enabled(Scene *scene)
+{
+ if (scene->r.scemode & R_FULL_SAMPLE) {
+ return true;
+ }
+ else {
+ /* XXX TODO:
+ * Technically if the hardware supports MSAA we could keep using Blender 2.7x approach.
+ * However anti-aliasing without full_sample is not playing well even in 2.7x.
+ *
+ * For example, if you enable depth of field, there is aliasing, even if the viewport is fine.
+ * For 2.8x this is more complicated because so many things rely on shader.
+ * So until we fix the gpu_framebuffer anti-aliasing suupport we need to force full sample.
+ */
+ return true;
+ }
+}
+
static bool screen_opengl_render_init(bContext *C, wmOperator *op)
{
/* new render clears all callbacks */
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
Scene *scene = CTX_data_scene(C);
ScrArea *prevsa = CTX_wm_area(C);
@@ -589,7 +607,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
OGLRender *oglrender;
int sizex, sizey;
const int samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0;
- const bool full_samples = (samples != 0) && (scene->r.scemode & R_FULL_SAMPLE);
+ const bool full_samples = (samples != 0) && screen_opengl_fullsample_enabled(scene);
bool is_view_context = RNA_boolean_get(op->ptr, "view_context");
const bool is_animation = RNA_boolean_get(op->ptr, "animation");
const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
@@ -634,7 +652,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
sizey = (scene->r.size * scene->r.ysch) / 100;
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
- ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, err_out);
+ ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, err_out);
if (!ofs) {
BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
@@ -652,6 +670,9 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->sizey = sizey;
oglrender->bmain = CTX_data_main(C);
oglrender->scene = scene;
+ oglrender->workspace = workspace;
+ oglrender->view_layer = CTX_data_view_layer(C);
+ oglrender->depsgraph = CTX_data_depsgraph(C);
oglrender->cfrao = scene->r.cfra;
oglrender->write_still = is_write_still && !is_animation;
@@ -696,6 +717,8 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* create render */
oglrender->re = RE_NewSceneRender(scene);
+ ViewRender *view_render = BKE_viewrender_get(scene, workspace);
+ RE_SetEngineByID(oglrender->re, view_render->engine_id);
/* create image and image user */
oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
@@ -706,7 +729,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->iuser.ok = 1;
/* create render result */
- RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
+ RE_InitState(oglrender->re, NULL, &scene->r, &scene->view_layers, scene->active_view_layer, view_render, NULL, sizex, sizey, NULL);
/* create render views */
screen_opengl_views_setup(oglrender);
@@ -803,8 +826,10 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
}
if (oglrender->timer) { /* exec will not have a timer */
+ Depsgraph *depsgraph = oglrender->depsgraph;
+ ViewLayer *view_layer = oglrender->view_layer;
scene->r.cfra = oglrender->cfrao;
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
+ BKE_scene_graph_update_for_newframe(bmain->eval_ctx, depsgraph, bmain, scene, view_layer);
WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
}
@@ -1004,6 +1029,8 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
OGLRender *oglrender = op->customdata;
Scene *scene = oglrender->scene;
+ ViewLayer *view_layer = oglrender->view_layer;
+ Depsgraph *depsgraph = oglrender->depsgraph;
char name[FILE_MAX];
bool ok = false;
const bool view_context = (oglrender->v3d != NULL);
@@ -1014,12 +1041,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (CFRA < oglrender->nfra)
CFRA++;
while (CFRA < oglrender->nfra) {
- unsigned int lay = screen_opengl_layers(oglrender);
-
- if (lay & 0xFF000000)
- lay &= 0xFF000000;
-
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
+ BKE_scene_graph_update_for_newframe(bmain->eval_ctx, depsgraph, bmain, scene, view_layer);
CFRA++;
}
@@ -1041,11 +1063,11 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
WM_cursor_time(oglrender->win, scene->r.cfra);
- BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
+ BKE_scene_graph_update_for_newframe(bmain->eval_ctx, depsgraph, bmain, scene, view_layer);
if (view_context) {
if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
- /* since BKE_scene_update_for_newframe() is used rather
+ /* since BKE_scene_graph_update_for_newframe() is used rather
* then ED_update_for_newframe() the camera needs to be set */
if (BKE_scene_camera_switch_update(scene)) {
oglrender->v3d->camera = scene->camera;
@@ -1057,7 +1079,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
}
/* render into offscreen buffer */
- screen_opengl_render_apply(oglrender);
+ screen_opengl_render_apply(C, oglrender);
/* save to disk */
rr = RE_AcquireResultRead(oglrender->re);
@@ -1107,7 +1129,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
if (anim == 0) {
- screen_opengl_render_apply(op->customdata);
+ screen_opengl_render_apply(C, op->customdata);
screen_opengl_render_end(C, op->customdata);
return OPERATOR_FINISHED;
}
@@ -1158,7 +1180,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
if (!is_animation) { /* same as invoke */
/* render image */
- screen_opengl_render_apply(op->customdata);
+ screen_opengl_render_apply(C, op->customdata);
screen_opengl_render_end(C, op->customdata);
return OPERATOR_FINISHED;
@@ -1175,7 +1197,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
}
/* no redraw needed, we leave state as we entered it */
-// ED_update_for_newframe(C, 1);
+// ED_update_for_newframe(C);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, CTX_data_scene(C));
return OPERATOR_FINISHED;