diff options
Diffstat (limited to 'source/blender')
23 files changed, 401 insertions, 63 deletions
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 270ab60c02b..adccfda8e25 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -156,6 +156,7 @@ bool BKE_scene_use_shading_nodes_custom(struct Scene *scene); bool BKE_scene_use_spherical_stereo(struct Scene *scene); bool BKE_scene_uses_blender_eevee(const struct Scene *scene); +bool BKE_scene_uses_blender_opengl(const struct Scene *scene); bool BKE_scene_uses_cycles(const struct Scene *scene); void BKE_scene_disable_color_management(struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 60981c6e76e..c74170becb4 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -45,6 +45,7 @@ struct ScrVert; struct SpaceType; struct TransformOrientation; struct View3D; +struct View3DShading; struct bContext; struct bContextDataResult; struct bScreen; @@ -355,6 +356,8 @@ bool BKE_screen_is_used(const struct bScreen *screen) ATTR_WARN_UNUSED_RESULT AT float BKE_screen_view3d_zoom_to_fac(float camzoom); float BKE_screen_view3d_zoom_from_fac(float zoomfac); +void BKE_screen_view3d_shading_init(struct View3DShading *shading); + /* screen */ void BKE_screen_free(struct bScreen *sc); void BKE_screen_area_map_free(struct ScrAreaMap *area_map) ATTR_NONNULL(); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 3b1416d2881..f99a30b75d0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -113,7 +113,7 @@ #include "bmesh.h" const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; -const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH"; +const char *RE_engine_id_BLENDER_OPENGL = "BLENDER_OPENGL"; const char *RE_engine_id_CYCLES = "CYCLES"; void free_avicodecdata(AviCodecData *acd) @@ -361,6 +361,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) curvemapping_copy_data(&sce_copy->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve); + /* viewport display settings */ + sce_copy->display = sce->display; + /* tool settings */ sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0); @@ -820,6 +823,9 @@ void BKE_scene_init(Scene *sce) sce->display.matcap_ssao_attenuation = 1.0f; sce->display.matcap_ssao_samples = 16; + /* OpenGL Render. */ + BKE_screen_view3d_shading_init(&sce->display.shading); + /* SceneEEVEE */ sce->eevee.gi_diffuse_bounces = 3; sce->eevee.gi_cubemap_resolution = 512; @@ -1541,6 +1547,11 @@ bool BKE_scene_uses_blender_eevee(const Scene *scene) return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE); } +bool BKE_scene_uses_blender_opengl(const Scene *scene) +{ + return STREQ(scene->r.engine, RE_engine_id_BLENDER_OPENGL); +} + bool BKE_scene_uses_cycles(const Scene *scene) { return STREQ(scene->r.engine, RE_engine_id_CYCLES); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 448b97c63b3..f8d926a13ed 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -45,9 +45,10 @@ #include "DNA_view3d_types.h" #include "DNA_workspace_types.h" +#include "BLI_math_vector.h" #include "BLI_listbase.h" -#include "BLI_utildefines.h" #include "BLI_rect.h" +#include "BLI_utildefines.h" #include "BKE_icons.h" #include "BKE_idprop.h" @@ -855,6 +856,21 @@ void BKE_screen_view3d_scene_sync(bScreen *sc, Scene *scene) } } +void BKE_screen_view3d_shading_init(View3DShading *shading) +{ + memset(shading, 0, sizeof(*shading)); + + shading->type = OB_SOLID; + shading->prev_type = OB_SOLID; + shading->flag = V3D_SHADING_SPECULAR_HIGHLIGHT; + shading->light = V3D_LIGHTING_STUDIO; + shading->shadow_intensity = 0.5f; + shading->xray_alpha = 0.5f; + shading->cavity_valley_factor = 1.0f; + shading->cavity_ridge_factor = 1.0f; + copy_v3_fl(shading->single_color, 0.8f); +} + /* magic zoom calculation, no idea what * it signifies, if you find out, tell me! -zr */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 5855b9d39de..d1ed166ba89 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1615,5 +1615,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "View3DShading", "shading")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + BKE_screen_view3d_shading_init(&scene->display.shading); + } + } } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index e4c6a372d34..6ec7b03501b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -117,6 +117,7 @@ set(SRC engines/workbench/workbench_effect_taa.c engines/workbench/workbench_forward.c engines/workbench/workbench_materials.c + engines/workbench/workbench_render.c engines/workbench/workbench_studiolight.c engines/workbench/workbench_volume.c engines/workbench/solid_mode.c diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c index b28263d48cf..5c64cebd981 100644 --- a/source/blender/draw/engines/workbench/solid_mode.c +++ b/source/blender/draw/engines/workbench/solid_mode.c @@ -30,6 +30,8 @@ #include "GPU_shader.h" +#include "RE_pipeline.h" + #include "workbench_private.h" /* Functions */ @@ -69,6 +71,7 @@ static void workbench_solid_draw_scene(void *vedata) { WORKBENCH_Data *data = vedata; workbench_deferred_draw_scene(data); + workbench_deferred_draw_finish(data); } static void workbench_solid_engine_free(void) @@ -82,6 +85,11 @@ static void workbench_solid_view_update(void *vedata) workbench_taa_view_updated(data); } +static void workbench_render_to_image(void *vedata, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect) +{ + workbench_render(vedata, engine, render_layer, rect); +} + static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data); DrawEngineType draw_engine_workbench_solid = { @@ -97,5 +105,5 @@ DrawEngineType draw_engine_workbench_solid = { &workbench_solid_draw_scene, &workbench_solid_view_update, NULL, - NULL, + &workbench_render_to_image, }; diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index ede1bd7fcb5..07df067f324 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -19,37 +19,37 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->user_preferences = &U; View3D *v3d = draw_ctx->v3d; - if (v3d) { + if (!v3d) { + wpd->shading = scene->display.shading; + } + else if (v3d->shading.type == OB_RENDER && + BKE_scene_uses_blender_opengl(scene)) + { + wpd->shading = scene->display.shading; + } + else { wpd->shading = v3d->shading; - if (wpd->shading.light == V3D_LIGHTING_MATCAP) { - wpd->studio_light = BKE_studiolight_find( - wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); - } - else { - wpd->studio_light = BKE_studiolight_find( - wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); - } + } + + if (wpd->shading.light == V3D_LIGHTING_MATCAP) { + wpd->studio_light = BKE_studiolight_find( + wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); } else { - memset(&wpd->shading, 0, sizeof(wpd->shading)); - wpd->shading.light = V3D_LIGHTING_STUDIO; - wpd->shading.shadow_intensity = 0.5; - copy_v3_fl(wpd->shading.single_color, 0.8f); - wpd->studio_light = BKE_studiolight_find_first(STUDIOLIGHT_INTERNAL); + wpd->studio_light = BKE_studiolight_find( + wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); } wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity; WORKBENCH_UBO_World *wd = &wpd->world_data; wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0; - wd->background_alpha = 1.0f; + wd->background_alpha = (v3d || scene->r.alphamode == R_ADDSKY) ? 1.0f : 0.0f; - if ((v3d->flag3 & V3D_SHOW_WORLD) && - (scene->world != NULL)) - { + if (!v3d || ((v3d->flag3 & V3D_SHOW_WORLD) && (scene->world != NULL))) { copy_v3_v3(wd->background_color_low, &scene->world->horr); copy_v3_v3(wd->background_color_high, &scene->world->horr); } - else { + else if (v3d) { UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low); UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high); @@ -58,6 +58,10 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high); srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low); } + else { + zero_v3(wd->background_color_low); + zero_v3(wd->background_color_high); + } studiolight_update_world(wpd->studio_light, wd); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index d17c48b0360..0ad755049b1 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -842,6 +842,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + /* TODO. */ if (TAA_ENABLED(wpd)) { workbench_taa_draw_scene_start(vedata); } @@ -885,7 +886,15 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->volume_pass); } + /* TODO */ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); +} + +void workbench_deferred_draw_finish(WORKBENCH_Data *vedata) +{ + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; + workbench_private_data_free(wpd); workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c index f1d5d5d6078..66f1de7f9fc 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_aa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -45,6 +45,18 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) } } +static void workspace_aa_draw_transform(GPUTexture *tx) +{ + if (DRW_state_is_image_render()) { + /* Linear result for render. */ + DRW_transform_none(tx); + } + else { + /* Display space result for viewport. */ + DRW_transform_to_display(tx); + } +} + void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) { WORKBENCH_StorageList *stl = vedata->stl; @@ -56,7 +68,7 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (FXAA_ENABLED(wpd)) { GPU_framebuffer_bind(fbl->effect_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -69,11 +81,11 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) */ if (effect_info->jitter_index == 1) { GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); } else { GPU_framebuffer_bind(fbl->effect_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -81,6 +93,6 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) } else { GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); } } diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c index fbeccc19660..403338d55c4 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_taa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c @@ -93,15 +93,19 @@ int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; int result = 1; if (TAA_ENABLED(wpd)) { - if (IN_RANGE_INCL( + if (DRW_state_is_image_render()) { + const Scene *scene = DRW_context_state_get()->scene; + result = (scene->r.mode & R_OSA) ? scene->r.osa : 1; + } + else if (IN_RANGE_INCL( wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_TAA8, GPU_VIEWPORT_QUALITY_TAA16)) { result = 8; } else if (IN_RANGE_INCL( - wpd->user_preferences->gpu_viewport_quality, - GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32)) + wpd->user_preferences->gpu_viewport_quality, + GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32)) { result = 16; } @@ -276,10 +280,12 @@ void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata) GPU_framebuffer_blit(dfbl->color_only_fb, 0, fbl->effect_taa_fb, 0, GPU_COLOR_BIT); - DRW_viewport_matrix_override_unset_all(); + if (!DRW_state_is_image_render()) { + DRW_viewport_matrix_override_unset_all(); + } copy_m4_m4(effect_info->last_mat, effect_info->curr_mat); - if (effect_info->jitter_index != 0) { + if (effect_info->jitter_index != 0 && !DRW_state_is_image_render()) { DRW_viewport_request_redraw(); } } diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 26ae1c289c8..642c5820895 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -29,16 +29,16 @@ #include "DRW_render.h" #include "workbench_engine.h" -/* Shaders */ - -#define WORKBENCH_ENGINE "BLENDER_WORKBENCH" +#include "workbench_private.h" +#define OPENGL_ENGINE "BLENDER_OPENGL" /* Note: currently unused, we may want to register so we can see this when debugging the view. */ -RenderEngineType DRW_engine_viewport_workbench_type = { +RenderEngineType DRW_engine_viewport_opengl_type = { NULL, NULL, - WORKBENCH_ENGINE, N_("Workbench"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + OPENGL_ENGINE, N_("OpenGL"), RE_INTERNAL, + NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, + &workbench_render_update_passes, &draw_engine_workbench_solid, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/workbench/workbench_engine.h b/source/blender/draw/engines/workbench/workbench_engine.h index a7f168db093..24f68cacd21 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.h +++ b/source/blender/draw/engines/workbench/workbench_engine.h @@ -28,6 +28,6 @@ extern DrawEngineType draw_engine_workbench_solid; extern DrawEngineType draw_engine_workbench_transparent; -extern RenderEngineType DRW_engine_viewport_workbench_type; +extern RenderEngineType DRW_engine_viewport_opengl_type; #endif /* __WORKBENCH_ENGINE_H__ */ diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 13e9686aa85..99d1b7060fd 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -36,6 +36,7 @@ #include "DRW_render.h" +#include "workbench_engine.h" #define WORKBENCH_ENGINE "BLENDER_WORKBENCH" #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895 @@ -51,7 +52,7 @@ #define CAVITY_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_CAVITY) #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) -#define IS_NAVIGATING(wpd) (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING) +#define IS_NAVIGATING(wpd) ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING)) #define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && (IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || ((wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8) && IS_NAVIGATING(wpd)))) #define TAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd)) #define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd))) @@ -61,6 +62,11 @@ #define NORMAL_ENCODING_ENABLED() (true) +struct RenderEngine; +struct RenderLayer; +struct rcti; + + typedef struct WORKBENCH_FramebufferList { /* Deferred render buffers */ struct GPUFrameBuffer *prepass_fb; @@ -231,6 +237,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata); void workbench_deferred_engine_free(void); void workbench_deferred_draw_background(WORKBENCH_Data *vedata); void workbench_deferred_draw_scene(WORKBENCH_Data *vedata); +void workbench_deferred_draw_finish(WORKBENCH_Data *vedata); void workbench_deferred_cache_init(WORKBENCH_Data *vedata); void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob); void workbench_deferred_cache_finish(WORKBENCH_Data *vedata); @@ -293,8 +300,8 @@ void workbench_volume_cache_init(WORKBENCH_Data *vedata); void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, struct ModifierData *md); void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd); - -extern DrawEngineType draw_engine_workbench_solid; -extern DrawEngineType draw_engine_workbench_transparent; +/* workbench_render.c */ +void workbench_render(WORKBENCH_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect); +void workbench_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); #endif diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c new file mode 100644 index 00000000000..1b25d4c875c --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -0,0 +1,172 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file workbench_render.c + * \ingroup draw_engine + * + * Render functions for final render output. + */ + +#include "BLI_rect.h" + +#include "BKE_report.h" + +#include "DRW_render.h" + +#include "GPU_shader.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "RE_pipeline.h" + +#include "workbench_private.h" + +static void workbench_render_cache( + void *vedata, struct Object *ob, + struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +{ + workbench_deferred_solid_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); +} + +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]}; + + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + dtxl->color = GPU_texture_create_2D(size[0], size[1], GPU_RGBA8, NULL, NULL); + dtxl->depth = GPU_texture_create_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); + + if (!(dtxl->depth && dtxl->color)) { + return false; + } + + 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->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) + }); + + 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; +} + +static void workbench_render_framebuffers_finish(void) +{ +} + +void workbench_render(WORKBENCH_Data *data, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + + 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; + } + + /* Init engine. */ + workbench_deferred_engine_init(data); + + /* Init objects. */ + workbench_deferred_cache_init(data); + DRW_render_object_iter(data, engine, depsgraph, workbench_render_cache); + workbench_deferred_cache_finish(data); + DRW_render_instance_buffer_finish(); + + /* 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_deferred_draw_background(data); + workbench_deferred_draw_scene(data); + } + + workbench_deferred_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); + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + 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); +} diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index a4a933250c9..16a17f4f21d 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -226,6 +226,7 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } while (0) void DRW_transform_to_display(struct GPUTexture *tex); +void DRW_transform_none(struct GPUTexture *tex); void DRW_multisamples_resolve( struct GPUTexture *src_depth, struct GPUTexture *src_color); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 707aadbc229..d23b9e693ce 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -51,6 +51,7 @@ static struct DRWShapeCache { Gwn_Batch *drw_cursor; Gwn_Batch *drw_cursor_only_circle; Gwn_Batch *drw_fullscreen_quad; + Gwn_Batch *drw_fullscreen_quad_texcoord; Gwn_Batch *drw_quad; Gwn_Batch *drw_sphere; Gwn_Batch *drw_screenspace_circle; @@ -287,6 +288,35 @@ Gwn_Batch *DRW_cache_fullscreen_quad_get(void) return SHC.drw_fullscreen_quad; } +Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void) +{ + if (!SHC.drw_fullscreen_quad_texcoord) { + /* Use a triangle instead of a real quad */ + /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */ + float pos[3][2] = {{-1.0f, -1.0f}, { 3.0f, -1.0f}, {-1.0f, 3.0f}}; + float texCoord[3][2] = {{ 0.0f, 0.0f}, { 2.0f, 0.0f}, { 0.0f, 2.0f}}; + + /* Position Only 2D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos, texCoord; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.texCoord = GWN_vertformat_attr_add(&format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + } + + Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(vbo, 3); + + for (int i = 0; i < 3; ++i) { + GWN_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); + GWN_vertbuf_attr_set(vbo, attr_id.texCoord, i, texCoord[i]); + } + + SHC.drw_fullscreen_quad_texcoord = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_fullscreen_quad_texcoord; +} + /* Just a regular quad with 4 vertices. */ Gwn_Batch *DRW_cache_quad_get(void) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index c1c80d2c5bf..07c8a571256 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -40,6 +40,7 @@ struct Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); +struct Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void); struct Gwn_Batch *DRW_cache_quad_get(void); struct Gwn_Batch *DRW_cache_cube_get(void); struct Gwn_Batch *DRW_cache_sphere_get(void); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 556f02c2899..58ce9dd5218 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -283,6 +283,29 @@ void DRW_transform_to_display(GPUTexture *tex) } } +/* Draw texture to framebuffer without any color transforms */ +void DRW_transform_none(GPUTexture *tex) +{ + /* Draw as texture for final render (without immediate mode). */ + Gwn_Batch *geom = DRW_cache_fullscreen_quad_texcoord_get(); + GWN_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); + + GPU_texture_bind(tex, 0); + + const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + GWN_batch_uniform_4fv(geom, "color", white); + + float mat[4][4]; + unit_m4(mat); + GWN_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); + + GWN_batch_program_use_begin(geom); + GWN_batch_draw_range_ex(geom, 0, 0, false); + GWN_batch_program_use_end(geom); + + GPU_texture_unbind(tex); +} + /** \} */ @@ -2217,8 +2240,8 @@ void DRW_engine_register(DrawEngineType *draw_engine_type) void DRW_engines_register(void) { + RE_engines_register(&DRW_engine_viewport_opengl_type); RE_engines_register(&DRW_engine_viewport_eevee_type); - RE_engines_register(&DRW_engine_viewport_workbench_type); DRW_engine_register(&draw_engine_workbench_solid); DRW_engine_register(&draw_engine_workbench_transparent); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 188ee928f3c..71bdd2e20c2 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -324,15 +324,7 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) v3d->grid = 1.0f; v3d->gridlines = 16; v3d->gridsubdiv = 10; - v3d->shading.type = OB_SOLID; - v3d->shading.prev_type = OB_SOLID; - v3d->shading.flag = V3D_SHADING_SPECULAR_HIGHLIGHT; - v3d->shading.light = V3D_LIGHTING_STUDIO; - v3d->shading.shadow_intensity = 0.5f; - v3d->shading.xray_alpha = 0.5f; - v3d->shading.cavity_valley_factor = 1.0f; - v3d->shading.cavity_ridge_factor = 1.0f; - copy_v3_fl(v3d->shading.single_color, 0.8f); + BKE_screen_view3d_shading_init(&v3d->shading); v3d->overlay.wireframe_threshold = 0.5f; v3d->overlay.bone_select_alpha = 0.5f; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0c4c0a00f1a..16c8d8875c7 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1381,6 +1381,9 @@ typedef struct SceneDisplay { float matcap_ssao_attenuation; int matcap_ssao_samples; int pad; + + /* OpenGL render engine settings. */ + View3DShading shading; } SceneDisplay; typedef struct SceneEEVEE { @@ -1707,7 +1710,7 @@ enum { /* RenderData.engine (scene.c) */ extern const char *RE_engine_id_BLENDER_EEVEE; -extern const char *RE_engine_id_BLENDER_WORKBENCH; +extern const char *RE_engine_id_BLENDER_OPENGL; extern const char *RE_engine_id_CYCLES; /* **************** SCENE ********************* */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f8d6757c601..339d3841b30 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5753,6 +5753,10 @@ static void rna_def_scene_display(BlenderRNA *brna) RNA_def_property_int_default(prop, 16); RNA_def_property_ui_text(prop, "Samples", "Number of samples"); RNA_def_property_range(prop, 1, 500); + + /* OpenGL render engine settings. */ + prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Shading Settings", "Shading settings for OpenGL render engine"); } static void rna_def_scene_eevee(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 66ff29a8c16..e670d3c31a5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -679,8 +679,12 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - bScreen *screen = ptr->id.data; + ID *id = ptr->id.data; + if (GS(id->name) == ID_SCE) { + return; + } + bScreen *screen = ptr->id.data; for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { @@ -694,20 +698,40 @@ static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), Poi } } +static Scene *rna_3DViewShading_scene(PointerRNA *ptr) +{ + /* Get scene, depends if using 3D view or OpenGL render settings. */ + ID *id = ptr->id.data; + if (GS(id->name) == ID_SCE) { + return (Scene *)id; + } + else { + bScreen *screen = ptr->id.data; + return WM_windows_scene_get_from_screen(G_MAIN->wm.first, screen); + } +} + static int rna_3DViewShading_type_get(PointerRNA *ptr) { - bScreen *screen = ptr->id.data; - Scene *scene = WM_windows_scene_get_from_screen(G_MAIN->wm.first, screen); + /* Available shading types depend on render engine. */ + Scene *scene = rna_3DViewShading_scene(ptr); RenderEngineType *type = RE_engines_find(scene->r.engine); View3DShading *shading = (View3DShading *)ptr->data; - if (!BKE_scene_uses_blender_eevee(scene) && shading->type == OB_RENDER) { - if (!(type && type->view_draw)) { + if (BKE_scene_uses_blender_eevee(scene)) { + return shading->type; + } + else if (BKE_scene_uses_blender_opengl(scene)) { + return (shading->type == OB_MATERIAL) ? OB_RENDER : shading->type; + } + else { + if (shading->type == OB_RENDER && !(type && type->view_draw)) { return OB_MATERIAL; } + else { + return shading->type; + } } - - return shading->type; } static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) @@ -720,11 +744,10 @@ static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) } static const EnumPropertyItem *rna_3DViewShading_type_itemf( - bContext *C, PointerRNA *UNUSED(ptr), + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { - wmWindow *win = CTX_wm_window(C); - Scene *scene = WM_window_get_active_scene(win); + Scene *scene = rna_3DViewShading_scene(ptr); RenderEngineType *type = RE_engines_find(scene->r.engine); EnumPropertyItem *item = NULL; @@ -736,6 +759,9 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf( RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL); RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER); } + else if (BKE_scene_uses_blender_opengl(scene)) { + RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER); + } else { RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL); if (type && type->view_draw) { @@ -2401,6 +2427,8 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + /* Note these settings are used for both 3D viewport and the OpenGL render + * engine in the scene, so can't assume to always be part of a screen. */ srna = RNA_def_struct(brna, "View3DShading", NULL); RNA_def_struct_path_func(srna, "rna_View3DShading_path"); RNA_def_struct_ui_text(srna, "3D View Shading Settings", "Settings for shading in the 3D viewport"); |