diff options
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_render.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_render.c | 288 |
1 files changed, 146 insertions, 142 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index 663727285a1..1497ef493cf 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -39,177 +39,181 @@ #include "workbench_private.h" -static void workbench_render_deferred_cache( - void *vedata, struct Object *ob, - struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +static void workbench_render_deferred_cache(void *vedata, + struct Object *ob, + struct RenderEngine *UNUSED(engine), + struct Depsgraph *UNUSED(depsgraph)) { - workbench_deferred_solid_cache_populate(vedata, ob); + workbench_deferred_solid_cache_populate(vedata, ob); } -static void workbench_render_forward_cache( - void *vedata, struct Object *ob, - struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +static void workbench_render_forward_cache(void *vedata, + struct Object *ob, + struct RenderEngine *UNUSED(engine), + struct Depsgraph *UNUSED(depsgraph)) { - workbench_forward_cache_populate(vedata, ob); + workbench_forward_cache_populate(vedata, ob); } static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph) { - /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */ - Scene *scene = DEG_get_evaluated_scene(depsgraph); - struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); - float frame = BKE_scene_frame_get(scene); - - /* Set the persective, view and window matrix. */ - float winmat[4][4], wininv[4][4]; - float viewmat[4][4], viewinv[4][4]; - float persmat[4][4], persinv[4][4]; - - RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat); - RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv); - - invert_m4_m4(viewmat, viewinv); - mul_m4_m4m4(persmat, winmat, viewmat); - invert_m4_m4(persinv, persmat); - invert_m4_m4(wininv, winmat); - - DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); - DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); - DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN); - DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV); - DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); - DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); + /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */ + Scene *scene = DEG_get_evaluated_scene(depsgraph); + struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); + float frame = BKE_scene_frame_get(scene); + + /* Set the persective, view and window matrix. */ + float winmat[4][4], wininv[4][4]; + float viewmat[4][4], viewinv[4][4]; + float persmat[4][4], persinv[4][4]; + + RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat); + RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv); + + invert_m4_m4(viewmat, viewinv); + mul_m4_m4m4(persmat, winmat, viewmat); + invert_m4_m4(persinv, persmat); + invert_m4_m4(wininv, winmat); + + DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN); + DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV); + DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); } static bool workbench_render_framebuffers_init(void) { - /* For image render, allocate own buffers because we don't have a viewport. */ - const float *viewport_size = DRW_viewport_size_get(); - const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; + /* For image render, allocate own buffers because we don't have a viewport. */ + const float *viewport_size = DRW_viewport_size_get(); + const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); - dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); + dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); - if (!(dtxl->depth && dtxl->color)) { - return false; - } + if (!(dtxl->depth && dtxl->color)) { + return false; + } - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - GPU_framebuffer_ensure_config(&dfbl->default_fb, { - GPU_ATTACHMENT_TEXTURE(dtxl->depth), - GPU_ATTACHMENT_TEXTURE(dtxl->color) - }); + GPU_framebuffer_ensure_config( + &dfbl->default_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); - GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, { - GPU_ATTACHMENT_TEXTURE(dtxl->depth), - GPU_ATTACHMENT_NONE - }); + GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE}); - GPU_framebuffer_ensure_config(&dfbl->color_only_fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(dtxl->color) - }); + GPU_framebuffer_ensure_config(&dfbl->color_only_fb, + {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)}); - bool ok = true; - ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); - ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); - ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); + bool ok = true; + ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); - return ok; + return ok; } static void workbench_render_framebuffers_finish(void) { } -void workbench_render(WORKBENCH_Data *data, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect) +void workbench_render(WORKBENCH_Data *data, + RenderEngine *engine, + RenderLayer *render_layer, + const rcti *rect) { - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene = draw_ctx->scene; - Depsgraph *depsgraph = draw_ctx->depsgraph; - workbench_render_matrices_init(engine, depsgraph); - - if (!workbench_render_framebuffers_init()) { - RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers"); - return; - } - - const bool deferred = !XRAY_FLAG_ENABLED(&scene->display); - - if (deferred) { - /* Init engine. */ - workbench_deferred_engine_init(data); - - /* Init objects. */ - workbench_deferred_cache_init(data); - DRW_render_object_iter(data, engine, depsgraph, workbench_render_deferred_cache); - workbench_deferred_cache_finish(data); - DRW_render_instance_buffer_finish(); - - /* Also we weed to have a correct fbo bound for DRW_hair_update */ - GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_hair_update(); - - /* Draw. */ - int num_samples = workbench_taa_calculate_num_iterations(data); - for (int sample = 0; sample < num_samples; sample++) { - if (RE_engine_test_break(engine)) { - break; - } - /* TODO: Save matrices instead of recomputing them for each samples. */ - workbench_render_matrices_init(engine, depsgraph); - - workbench_deferred_draw_background(data); - workbench_deferred_draw_scene(data); - } - - workbench_deferred_draw_finish(data); - } - else { - /* Init engine. */ - workbench_forward_engine_init(data); - - /* Init objects. */ - workbench_forward_cache_init(data); - DRW_render_object_iter(data, engine, depsgraph, workbench_render_forward_cache); - workbench_forward_cache_finish(data); - DRW_render_instance_buffer_finish(); - - /* Also we weed to have a correct fbo bound for DRW_hair_update */ - GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_hair_update(); - - /* Draw. */ - int num_samples = workbench_taa_calculate_num_iterations(data); - for (int sample = 0; sample < num_samples; sample++) { - if (RE_engine_test_break(engine)) { - break; - } - - workbench_forward_draw_background(data); - workbench_forward_draw_scene(data); - } - - workbench_forward_draw_finish(data); - } - - /* Write render output. */ - const char *viewname = RE_GetActiveRenderView(engine->re); - RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname); - - GPU_framebuffer_bind(dfbl->color_only_fb); - GPU_framebuffer_read_color(dfbl->color_only_fb, - rect->xmin, rect->ymin, - BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), - 4, 0, rp->rect); - - workbench_render_framebuffers_finish(); + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene = draw_ctx->scene; + Depsgraph *depsgraph = draw_ctx->depsgraph; + workbench_render_matrices_init(engine, depsgraph); + + if (!workbench_render_framebuffers_init()) { + RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers"); + return; + } + + const bool deferred = !XRAY_FLAG_ENABLED(&scene->display); + + if (deferred) { + /* Init engine. */ + workbench_deferred_engine_init(data); + + /* Init objects. */ + workbench_deferred_cache_init(data); + DRW_render_object_iter(data, engine, depsgraph, workbench_render_deferred_cache); + workbench_deferred_cache_finish(data); + DRW_render_instance_buffer_finish(); + + /* Also we weed to have a correct fbo bound for DRW_hair_update */ + GPU_framebuffer_bind(dfbl->color_only_fb); + DRW_hair_update(); + + /* Draw. */ + int num_samples = workbench_taa_calculate_num_iterations(data); + for (int sample = 0; sample < num_samples; sample++) { + if (RE_engine_test_break(engine)) { + break; + } + /* TODO: Save matrices instead of recomputing them for each samples. */ + workbench_render_matrices_init(engine, depsgraph); + + workbench_deferred_draw_background(data); + workbench_deferred_draw_scene(data); + } + + workbench_deferred_draw_finish(data); + } + else { + /* Init engine. */ + workbench_forward_engine_init(data); + + /* Init objects. */ + workbench_forward_cache_init(data); + DRW_render_object_iter(data, engine, depsgraph, workbench_render_forward_cache); + workbench_forward_cache_finish(data); + DRW_render_instance_buffer_finish(); + + /* Also we weed to have a correct fbo bound for DRW_hair_update */ + GPU_framebuffer_bind(dfbl->color_only_fb); + DRW_hair_update(); + + /* Draw. */ + int num_samples = workbench_taa_calculate_num_iterations(data); + for (int sample = 0; sample < num_samples; sample++) { + if (RE_engine_test_break(engine)) { + break; + } + + workbench_forward_draw_background(data); + workbench_forward_draw_scene(data); + } + + workbench_forward_draw_finish(data); + } + + /* Write render output. */ + const char *viewname = RE_GetActiveRenderView(engine->re); + RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname); + + GPU_framebuffer_bind(dfbl->color_only_fb); + GPU_framebuffer_read_color(dfbl->color_only_fb, + rect->xmin, + rect->ymin, + BLI_rcti_size_x(rect), + BLI_rcti_size_y(rect), + 4, + 0, + rp->rect); + + workbench_render_framebuffers_finish(); } void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) { - RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); } |