diff options
Diffstat (limited to 'source/blender/draw')
36 files changed, 371 insertions, 211 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 5836983dda8..bcf48748f4b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -51,7 +51,7 @@ set(INC set(SRC intern/draw_cache.c intern/draw_cache_extract_mesh.c - intern/draw_cache_impl_curve.c + intern/draw_cache_impl_curve.cc intern/draw_cache_impl_displist.c intern/draw_cache_impl_gpencil.c intern/draw_cache_impl_hair.c @@ -479,6 +479,7 @@ add_dependencies(bf_draw bf_dna) if(WITH_GTESTS) if(WITH_OPENGL_DRAW_TESTS) set(TEST_SRC + tests/draw_testing.cc tests/shaders_test.cc ) set(TEST_INC diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c index 0cb2d55d1eb..7fe984b4397 100644 --- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c +++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c @@ -121,7 +121,7 @@ void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata) ViewLayer *view_layer = draw_ctx->view_layer; /* Cryptomatte is only rendered for final image renders */ - if (!DRW_state_is_image_render()) { + if (!DRW_state_is_scene_render()) { return; } const eViewLayerCryptomatteFlags active_layers = eevee_cryptomatte_active_layers(view_layer); @@ -265,8 +265,7 @@ void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata, Object *ob) { BLI_assert(ob->type == OB_HAIR); - Hair *hair = ob->data; - Material *material = hair->mat ? hair->mat[HAIR_MATERIAL_NR - 1] : NULL; + Material *material = BKE_object_material_get_eval(ob, HAIR_MATERIAL_NR); eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, NULL, NULL, material); } @@ -291,8 +290,7 @@ void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata, if (draw_as != PART_DRAW_PATH) { continue; } - Mesh *mesh = ob->data; - Material *material = part->omat - 1 < mesh->totcol ? NULL : mesh->mat[part->omat - 1]; + Material *material = BKE_object_material_get_eval(ob, part->omat); eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, psys, md, material); } } @@ -318,7 +316,7 @@ void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *s if (geom == NULL) { continue; } - Material *material = BKE_object_material_get(ob, i + 1); + Material *material = BKE_object_material_get_eval(ob, i + 1); DRWShadingGroup *grp = eevee_cryptomatte_shading_group_create( vedata, sldata, ob, material, false); DRW_shgroup_call(grp, geom, ob); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index ae726d7af9a..88fd823bc72 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -494,12 +494,7 @@ static void eevee_render_to_image(void *vedata, /* Previous motion step. */ if (do_motion_blur_fx) { - if (i > 0) { - /* The previous step of this iteration N is exactly the next step of iteration N - 1. - * So we just swap the resources to avoid too much re-evaluation. */ - EEVEE_motion_blur_swap_data(vedata); - } - else { + if (i == 0) { EEVEE_motion_blur_step_set(ved, MB_PREV); DRW_render_set_time(engine, depsgraph, floorf(time_prev), fractf(time_prev)); EEVEE_render_modules_init(vedata, engine, depsgraph); @@ -561,6 +556,11 @@ static void eevee_render_to_image(void *vedata, EEVEE_renderpasses_output_init( sldata, vedata, g_data->render_sample_count_per_timestep * time_steps_tot); + if (scene->world) { + /* Update world in case of animated world material. */ + eevee_id_world_update(vedata, scene->world); + } + EEVEE_temporal_sampling_create_view(vedata); EEVEE_render_draw(vedata, engine, render_layer, rect); @@ -570,6 +570,14 @@ static void eevee_render_to_image(void *vedata, DRW_cache_restart(); } } + + if (do_motion_blur_fx) { + /* The previous step of next iteration N is exactly the next step of this iteration N - 1. + * So we just swap the resources to avoid too much re-evaluation. + * Note that this also clears the VBO references from the GPUBatches of deformed + * geometries. */ + EEVEE_motion_blur_swap_data(vedata); + } } EEVEE_volumes_free_smoke_textures(); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index f05aa562e6b..d2e0c8308c5 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -623,6 +623,11 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata, /* This GPUShader has already been used by another material. * Add new shading group just after to avoid shader switching cost. */ grp = DRW_shgroup_create_sub(*grp_p); + + /* Per material uniforms. */ + if (use_ssrefract) { + DRW_shgroup_uniform_float_copy(grp, "refractionDepth", ma->refract_depth); + } } else { *grp_p = grp = DRW_shgroup_create(sh, shading_pass); @@ -718,7 +723,7 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot, bool holdou if (holdout) { return BKE_material_default_holdout(); } - Material *ma = BKE_object_material_get(ob, slot + 1); + Material *ma = BKE_object_material_get_eval(ob, slot + 1); if (ma == NULL) { if (ob->type == OB_VOLUME) { ma = BKE_material_default_volume(); @@ -765,12 +770,15 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata, if (matcache.depth_grp) { *matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp); + DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat); } if (matcache.shading_grp) { *matcache.shading_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shading_grp); + DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat); } if (matcache.shadow_grp) { *matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shadow_grp); + DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat); *cast_shadow = true; } @@ -958,22 +966,9 @@ void EEVEE_material_renderpasses_init(EEVEE_Data *vedata) } } -static void material_renderpass_init(EEVEE_FramebufferList *fbl, - GPUTexture **output_tx, - const eGPUTextureFormat format, - const bool do_clear) +static void material_renderpass_init(GPUTexture **output_tx, const eGPUTextureFormat format) { DRW_texture_ensure_fullscreen_2d(output_tx, format, 0); - /* Clear texture. */ - if (do_clear) { - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* TODO(fclem): replace by GPU_texture_clear once it is fast. */ - GPU_framebuffer_texture_attach(fbl->material_accum_fb, *output_tx, 0, 0); - GPU_framebuffer_bind(fbl->material_accum_fb); - GPU_framebuffer_clear_color(fbl->material_accum_fb, clear); - GPU_framebuffer_bind(fbl->main_fb); - GPU_framebuffer_texture_detach(fbl->material_accum_fb, *output_tx); - } } void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples) @@ -988,33 +983,32 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, /* Should be enough precision for many samples. */ const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F; - const bool do_clear = (effects->taa_current_sample == 1); /* Create FrameBuffer. */ GPU_framebuffer_ensure_config(&fbl->material_accum_fb, {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_LEAVE}); if (pd->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) { - material_renderpass_init(fbl, &txl->env_accum, texture_format, do_clear); + material_renderpass_init(&txl->env_accum, texture_format); } if (pd->render_passes & EEVEE_RENDER_PASS_EMIT) { - material_renderpass_init(fbl, &txl->emit_accum, texture_format, do_clear); + material_renderpass_init(&txl->emit_accum, texture_format); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_COLOR) { - material_renderpass_init(fbl, &txl->diff_color_accum, texture_format, do_clear); + material_renderpass_init(&txl->diff_color_accum, texture_format); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) { - material_renderpass_init(fbl, &txl->diff_light_accum, texture_format, do_clear); + material_renderpass_init(&txl->diff_light_accum, texture_format); } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) { - material_renderpass_init(fbl, &txl->spec_color_accum, texture_format, do_clear); + material_renderpass_init(&txl->spec_color_accum, texture_format); } if (pd->render_passes & EEVEE_RENDER_PASS_AOV) { for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) { - material_renderpass_init(fbl, &txl->aov_surface_accum[aov_index], texture_format, do_clear); + material_renderpass_init(&txl->aov_surface_accum[aov_index], texture_format); } } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) { - material_renderpass_init(fbl, &txl->spec_light_accum, texture_format, do_clear); + material_renderpass_init(&txl->spec_light_accum, texture_format); if (effects->enabled_effects & EFFECT_SSR) { EEVEE_reflection_output_init(sldata, vedata, tot_samples); @@ -1022,7 +1016,8 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, } } -static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl, +static void material_renderpass_accumulate(EEVEE_EffectsInfo *effects, + EEVEE_FramebufferList *fbl, DRWPass *renderpass, DRWPass *renderpass2, EEVEE_PrivateData *pd, @@ -1032,6 +1027,11 @@ static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl, GPU_framebuffer_texture_attach(fbl->material_accum_fb, output_tx, 0, 0); GPU_framebuffer_bind(fbl->material_accum_fb); + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->material_accum_fb, clear); + } + pd->renderpass_ubo = renderpass_option_ubo; DRW_draw_pass(renderpass); if (renderpass2) { @@ -1053,15 +1053,21 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRWPass *material_accum_ps = psl->material_accum_ps; DRWPass *background_accum_ps = psl->background_accum_ps; if (pd->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) { - material_renderpass_accumulate( - fbl, background_accum_ps, NULL, pd, txl->env_accum, sldata->renderpass_ubo.environment); + material_renderpass_accumulate(effects, + fbl, + background_accum_ps, + NULL, + pd, + txl->env_accum, + sldata->renderpass_ubo.environment); } if (pd->render_passes & EEVEE_RENDER_PASS_EMIT) { material_renderpass_accumulate( - fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit); + effects, fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_COLOR) { - material_renderpass_accumulate(fbl, + material_renderpass_accumulate(effects, + fbl, material_accum_ps, NULL, pd, @@ -1069,7 +1075,8 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v sldata->renderpass_ubo.diff_color); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) { - material_renderpass_accumulate(fbl, + material_renderpass_accumulate(effects, + fbl, material_accum_ps, NULL, pd, @@ -1087,7 +1094,8 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v sldata->common_data.ssr_toggle = false; GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data); } - material_renderpass_accumulate(fbl, + material_renderpass_accumulate(effects, + fbl, material_accum_ps, NULL, pd, @@ -1099,7 +1107,8 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v } } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) { - material_renderpass_accumulate(fbl, + material_renderpass_accumulate(effects, + fbl, material_accum_ps, NULL, pd, @@ -1112,7 +1121,8 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v } if (pd->render_passes & EEVEE_RENDER_PASS_AOV) { for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) { - material_renderpass_accumulate(fbl, + material_renderpass_accumulate(effects, + fbl, material_accum_ps, background_accum_ps, pd, diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c index 2b448695528..d4490d6fd4c 100644 --- a/source/blender/draw/engines/eevee/eevee_mist.c +++ b/source/blender/draw/engines/eevee/eevee_mist.c @@ -40,12 +40,9 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_TextureList *txl = vedata->txl; EEVEE_StorageList *stl = vedata->stl; EEVEE_PassList *psl = vedata->psl; - EEVEE_EffectsInfo *effects = stl->effects; EEVEE_PrivateData *g_data = stl->g_data; Scene *scene = draw_ctx->scene; - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* Create FrameBuffer. */ /* Should be enough precision for many samples. */ DRW_texture_ensure_fullscreen_2d(&txl->mist_accum, GPU_R32F, 0); @@ -53,12 +50,6 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) GPU_framebuffer_ensure_config(&fbl->mist_accum_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->mist_accum)}); - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->mist_accum_fb); - GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear); - } - /* Mist settings. */ if (scene && scene->world) { g_data->mist_start = scene->world->miststa; @@ -103,9 +94,17 @@ void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; + EEVEE_EffectsInfo *effects = vedata->stl->effects; if (fbl->mist_accum_fb != NULL) { GPU_framebuffer_bind(fbl->mist_accum_fb); + + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear); + } + DRW_draw_pass(psl->mist_accum_ps); /* Restore */ diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index 19f34fa6108..4c2024a6f65 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -120,7 +120,6 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Should be enough precision for many samples. */ DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0); @@ -128,12 +127,6 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata GPU_framebuffer_ensure_config(&fbl->ao_accum_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)}); - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->ao_accum_fb); - GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); - } - /* Accumulation pass */ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD; DRW_PASS_CREATE(psl->ao_accum_ps, state); @@ -246,6 +239,7 @@ void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data * { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; + EEVEE_EffectsInfo *effects = vedata->stl->effects; if (fbl->ao_accum_fb != NULL) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); @@ -255,6 +249,13 @@ void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data * EEVEE_occlusion_compute(sldata, vedata); GPU_framebuffer_bind(fbl->ao_accum_fb); + + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); + } + DRW_draw_pass(psl->ao_accum_ps); /* Restore */ diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 54f23073bd0..7af0f60748b 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -234,10 +234,6 @@ void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata), { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; - EEVEE_StorageList *stl = vedata->stl; - EEVEE_EffectsInfo *effects = stl->effects; - - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; /* Create FrameBuffer. */ const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F; @@ -245,12 +241,6 @@ void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata), GPU_framebuffer_ensure_config(&fbl->ssr_accum_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ssr_accum)}); - - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->ssr_accum_fb); - GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear); - } } void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) @@ -258,9 +248,17 @@ void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; EEVEE_StorageList *stl = vedata->stl; + EEVEE_EffectsInfo *effects = vedata->stl->effects; if (stl->g_data->valid_double_buffer) { GPU_framebuffer_bind(fbl->ssr_accum_fb); + + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear); + } + DRW_draw_pass(psl->ssr_resolve); } } diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c index 51fd1cad41e..6a98c3316f3 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows.c +++ b/source/blender/draw/engines/eevee/eevee_shadows.c @@ -361,12 +361,8 @@ void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_PassList *psl = vedata->psl; - EEVEE_StorageList *stl = vedata->stl; - EEVEE_EffectsInfo *effects = stl->effects; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* Create FrameBuffer. */ const eGPUTextureFormat texture_format = GPU_R32F; DRW_texture_ensure_fullscreen_2d(&txl->shadow_accum, texture_format, 0); @@ -374,12 +370,6 @@ void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, GPU_framebuffer_ensure_config(&fbl->shadow_accum_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->shadow_accum)}); - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->shadow_accum_fb); - GPU_framebuffer_clear_color(fbl->shadow_accum_fb, clear); - } - /* Create Pass and shgroup. */ DRW_PASS_CREATE(psl->shadow_accum_pass, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ADD_FULL); @@ -404,9 +394,17 @@ void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_D { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; + EEVEE_EffectsInfo *effects = vedata->stl->effects; if (fbl->shadow_accum_fb != NULL) { GPU_framebuffer_bind(fbl->shadow_accum_fb); + + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->shadow_accum_fb, clear); + } + DRW_draw_pass(psl->shadow_accum_pass); /* Restore */ diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index d228d26cd52..eed36221fcb 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -501,7 +501,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, Scene *scene, Object *ob) { - Material *ma = BKE_object_material_get(ob, 1); + Material *ma = BKE_object_material_get_eval(ob, 1); if (ma == NULL) { if (ob->type == OB_VOLUME) { @@ -800,8 +800,6 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl = vedata->psl; EEVEE_EffectsInfo *effects = stl->effects; - const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* Create FrameBuffer. */ /* Should be enough precision for many samples. */ @@ -814,12 +812,6 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_accum), GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_accum)}); - /* Clear texture. */ - if (effects->taa_current_sample == 1) { - GPU_framebuffer_bind(fbl->volumetric_accum_fb); - GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear); - } - /* Create Pass and shgroup. */ DRW_PASS_CREATE(psl->volumetric_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL); DRWShadingGroup *grp = NULL; @@ -843,10 +835,18 @@ void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_ { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; + EEVEE_EffectsInfo *effects = vedata->stl->effects; if (fbl->volumetric_accum_fb != NULL) { /* Accum pass */ GPU_framebuffer_bind(fbl->volumetric_accum_fb); + + /* Clear texture. */ + if (effects->taa_current_sample == 1) { + const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear); + } + DRW_draw_pass(psl->volumetric_accum_ps); /* Restore */ diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl index b554fd113df..94dd1a439db 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl @@ -51,53 +51,72 @@ closure_##t2##_##subroutine(in_##t2##_2, eval_##t2##_2, cl_common, sub_data, out_##t2##_2); \ closure_##t3##_##subroutine(in_##t3##_3, eval_##t3##_3, cl_common, sub_data, out_##t3##_3); +#ifndef DEPTH_SHADER /* Inputs are inout so that callers can get the final inputs used for evaluation. */ -#define CLOSURE_EVAL_FUNCTION_DECLARE(name, t0, t1, t2, t3) \ - void closure_##name##_eval(ClosureInputCommon in_common, \ - inout ClosureInput##t0 in_##t0##_0, \ - inout ClosureInput##t1 in_##t1##_1, \ - inout ClosureInput##t2 in_##t2##_2, \ - inout ClosureInput##t3 in_##t3##_3, \ - out ClosureOutput##t0 out_##t0##_0, \ - out ClosureOutput##t1 out_##t1##_1, \ - out ClosureOutput##t2 out_##t2##_2, \ - out ClosureOutput##t3 out_##t3##_3) \ - { \ - CLOSURE_EVAL_DECLARE(t0, t1, t2, t3); \ +# define CLOSURE_EVAL_FUNCTION_DECLARE(name, t0, t1, t2, t3) \ + void closure_##name##_eval(ClosureInputCommon in_common, \ + inout ClosureInput##t0 in_##t0##_0, \ + inout ClosureInput##t1 in_##t1##_1, \ + inout ClosureInput##t2 in_##t2##_2, \ + inout ClosureInput##t3 in_##t3##_3, \ + out ClosureOutput##t0 out_##t0##_0, \ + out ClosureOutput##t1 out_##t1##_1, \ + out ClosureOutput##t2 out_##t2##_2, \ + out ClosureOutput##t3 out_##t3##_3) \ + { \ + CLOSURE_EVAL_DECLARE(t0, t1, t2, t3); \ \ - /* Starts at 1 because 0 is world cubemap. */ \ - for (int i = 1; cl_common.specular_accum > 0.0 && i < prbNumRenderCube && i < MAX_PROBE; \ - i++) { \ - ClosureCubemapData cube = closure_cubemap_eval_init(i, cl_common); \ - if (cube.attenuation > 1e-8) { \ - CLOSURE_META_SUBROUTINE_DATA(cubemap_eval, cube, t0, t1, t2, t3); \ + /* Starts at 1 because 0 is world cubemap. */ \ + for (int i = 1; cl_common.specular_accum > 0.0 && i < prbNumRenderCube && i < MAX_PROBE; \ + i++) { \ + ClosureCubemapData cube = closure_cubemap_eval_init(i, cl_common); \ + if (cube.attenuation > 1e-8) { \ + CLOSURE_META_SUBROUTINE_DATA(cubemap_eval, cube, t0, t1, t2, t3); \ + } \ } \ - } \ \ - /* Starts at 1 because 0 is world irradiance. */ \ - for (int i = 1; cl_common.diffuse_accum > 0.0 && i < prbNumRenderGrid && i < MAX_GRID; i++) { \ - ClosureGridData grid = closure_grid_eval_init(i, cl_common); \ - if (grid.attenuation > 1e-8) { \ - CLOSURE_META_SUBROUTINE_DATA(grid_eval, grid, t0, t1, t2, t3); \ + /* Starts at 1 because 0 is world irradiance. */ \ + for (int i = 1; cl_common.diffuse_accum > 0.0 && i < prbNumRenderGrid && i < MAX_GRID; \ + i++) { \ + ClosureGridData grid = closure_grid_eval_init(i, cl_common); \ + if (grid.attenuation > 1e-8) { \ + CLOSURE_META_SUBROUTINE_DATA(grid_eval, grid, t0, t1, t2, t3); \ + } \ } \ - } \ \ - CLOSURE_META_SUBROUTINE(indirect_end, t0, t1, t2, t3); \ + CLOSURE_META_SUBROUTINE(indirect_end, t0, t1, t2, t3); \ \ - ClosurePlanarData planar = closure_planar_eval_init(cl_common); \ - if (planar.attenuation > 1e-8) { \ - CLOSURE_META_SUBROUTINE_DATA(planar_eval, planar, t0, t1, t2, t3); \ - } \ + ClosurePlanarData planar = closure_planar_eval_init(cl_common); \ + if (planar.attenuation > 1e-8) { \ + CLOSURE_META_SUBROUTINE_DATA(planar_eval, planar, t0, t1, t2, t3); \ + } \ \ - for (int i = 0; i < laNumLight && i < MAX_LIGHT; i++) { \ - ClosureLightData light = closure_light_eval_init(cl_common, i); \ - if (light.vis > 1e-8) { \ - CLOSURE_META_SUBROUTINE_DATA(light_eval, light, t0, t1, t2, t3); \ + for (int i = 0; i < laNumLight && i < MAX_LIGHT; i++) { \ + ClosureLightData light = closure_light_eval_init(cl_common, i); \ + if (light.vis > 1e-8) { \ + CLOSURE_META_SUBROUTINE_DATA(light_eval, light, t0, t1, t2, t3); \ + } \ } \ - } \ \ - CLOSURE_META_SUBROUTINE(eval_end, t0, t1, t2, t3); \ - } + CLOSURE_META_SUBROUTINE(eval_end, t0, t1, t2, t3); \ + } + +#else +/* Inputs are inout so that callers can get the final inputs used for evaluation. */ +# define CLOSURE_EVAL_FUNCTION_DECLARE(name, t0, t1, t2, t3) \ + void closure_##name##_eval(ClosureInputCommon in_common, \ + inout ClosureInput##t0 in_##t0##_0, \ + inout ClosureInput##t1 in_##t1##_1, \ + inout ClosureInput##t2 in_##t2##_2, \ + inout ClosureInput##t3 in_##t3##_3, \ + out ClosureOutput##t0 out_##t0##_0, \ + out ClosureOutput##t1 out_##t1##_1, \ + out ClosureOutput##t2 out_##t2##_2, \ + out ClosureOutput##t3 out_##t3##_3) \ + { \ + CLOSURE_EVAL_DECLARE(t0, t1, t2, t3); \ + } +#endif #define CLOSURE_EVAL_FUNCTION(name, t0, t1, t2, t3) \ closure_##name##_eval(in_common, \ diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl index faac216480b..dac53719149 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl @@ -136,7 +136,7 @@ const float layer_offset_fg = 0.5 + 1.0; /* Extra offset for convolution layers to avoid light leaking from background. */ const float layer_offset = 0.5 + 0.5; -#define DOF_MAX_SLIGHT_FOCUS_RADIUS 5 +#define DOF_MAX_SLIGHT_FOCUS_RADIUS 16 float dof_layer_weight(float coc, const bool is_foreground) { diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl index cd69a0e2ab1..32841b7749c 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl @@ -40,7 +40,7 @@ void dof_slight_focus_gather(float radius, out vec4 out_color, out float out_wei DofGatherData fg_accum = GATHER_DATA_INIT; DofGatherData bg_accum = GATHER_DATA_INIT; - int i_radius = clamp(int(radius), 0, int(layer_threshold)); + int i_radius = clamp(int(radius + 0.5), 0, int(layer_threshold)); const int resolve_ring_density = DOF_SLIGHT_FOCUS_DENSITY; ivec2 texel = ivec2(gl_FragCoord.xy); diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl index 737ef7dc509..356ed102928 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl @@ -183,16 +183,70 @@ vec3 light_translucent(LightData ld, vec3 P, vec3 N, vec4 l_vector, vec2 rand, f #undef scube #undef scsmd +/* Similar to https://atyuwen.github.io/posts/normal-reconstruction/. + * This samples the depth buffer 4 time for each direction to get the most correct + * implicit normal reconstruction out of the depth buffer. */ +vec3 view_position_derivative_from_depth(vec2 uvs, vec2 ofs, vec3 vP, float depth_center) +{ + vec2 uv1 = uvs - ofs * 2.0; + vec2 uv2 = uvs - ofs; + vec2 uv3 = uvs + ofs; + vec2 uv4 = uvs + ofs * 2.0; + vec4 H; + H.x = textureLod(depthBuffer, uv1, 0.0).r; + H.y = textureLod(depthBuffer, uv2, 0.0).r; + H.z = textureLod(depthBuffer, uv3, 0.0).r; + H.w = textureLod(depthBuffer, uv4, 0.0).r; + /* Fix issue with depth precision. Take even larger diff. */ + vec4 diff = abs(vec4(depth_center, H.yzw) - H.x); + if (max_v4(diff) < 2.4e-7 && all(lessThan(diff.xyz, diff.www))) { + return 0.25 * (get_view_space_from_depth(uv3, H.w) - get_view_space_from_depth(uv1, H.x)); + } + /* Simplified (H.xw + 2.0 * (H.yz - H.xw)) - depth_center */ + vec2 deltas = abs((2.0 * H.yz - H.xw) - depth_center); + if (deltas.x < deltas.y) { + return vP - get_view_space_from_depth(uv2, H.y); + } + else { + return get_view_space_from_depth(uv3, H.z) - vP; + } +} + +/* TODO(fclem) port to a common place for other effects to use. */ +bool reconstruct_view_position_and_normal_from_depth(vec2 uvs, out vec3 vP, out vec3 vNg) +{ + vec2 texel_size = vec2(abs(dFdx(uvs.x)), abs(dFdy(uvs.y))); + float depth_center = textureLod(depthBuffer, uvs, 0.0).r; + + vP = get_view_space_from_depth(uvs, depth_center); + + vec3 dPdx = view_position_derivative_from_depth(uvs, texel_size * vec2(1, 0), vP, depth_center); + vec3 dPdy = view_position_derivative_from_depth(uvs, texel_size * vec2(0, 1), vP, depth_center); + + vNg = safe_normalize(cross(dPdx, dPdy)); + + /* Background case. */ + if (depth_center == 1.0) { + return false; + } + + return true; +} + void main(void) { vec2 uvs = uvcoordsvar.xy; float sss_scale = texture(sssRadius, uvs).r; - vec3 P = get_world_space_from_depth(uvs, texture(depthBuffer, uvs).r); - vec3 N = normalize(cross(dFdx(P), dFdy(P))); vec3 rand = texelfetch_noise_tex(gl_FragCoord.xy).zwy; rand.xy *= fast_sqrt(rand.z); + vec3 vP, vNg; + reconstruct_view_position_and_normal_from_depth(uvs, vP, vNg); + + vec3 P = point_view_to_world(vP); + vec3 Ng = normal_view_to_world(vNg); + vec3 accum = vec3(0.0); for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) { LightData ld = lights_data[i]; @@ -211,7 +265,7 @@ void main(void) continue; } - accum += att * ld.l_color * light_translucent(ld, P, -N, l_vector, rand.xy, sss_scale); + accum += att * ld.l_color * light_translucent(ld, P, -Ng, l_vector, rand.xy, sss_scale); } FragColor = vec4(accum, 1.0); diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c index 121c95e95f6..c9a8942f18c 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c @@ -60,7 +60,8 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob) /* Check if any material with holdout flag enabled. */ tgp_ob->do_mat_holdout = false; - for (int i = 0; i < ob->totcol; i++) { + const int tot_materials = BKE_object_material_count_eval(ob); + for (int i = 0; i < tot_materials; i++) { MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, i + 1); if (((gp_style != NULL) && (gp_style->flag & GP_MATERIAL_IS_STROKE_HOLDOUT)) || ((gp_style->flag & GP_MATERIAL_IS_FILL_HOLDOUT))) { diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c index 526f553329e..e3e84dd4c8c 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c @@ -186,7 +186,7 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje { GPENCIL_MaterialPool *matpool = pd->last_material_pool; - int mat_len = max_ii(1, ob->totcol); + int mat_len = max_ii(1, BKE_object_material_count_eval(ob)); bool reuse_matpool = matpool && ((matpool->used_count + mat_len) <= GP_MATERIAL_BUFFER_LEN); diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index c14159b5432..f0ede19f8ec 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -844,7 +844,10 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL } GPENCIL_tLayer *mask_layer = gpencil_layer_cache_get(ob, i); - BLI_assert(mask_layer); + /* When filtering by viewlayer, the mask could be null and must be ignored. */ + if (mask_layer == NULL) { + continue; + } DRW_draw_pass(mask_layer->geom_ps); diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 2bc687397a1..35a7d5679d9 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -302,7 +302,9 @@ typedef struct GPENCIL_PrivateData { int v3d_color_type; /* Current frame */ int cfra; - /* If we are rendering for final render (F12). */ + /* If we are rendering for final render (F12). + * NOTE: set to false for viewport and opengl rendering (including VSE scene rendering), but set + * to true when rendering in `OB_RENDER` shading mode (viewport or opengl rendering) */ bool is_render; /* If we are in viewport display (used for VFX). */ bool is_viewport; diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c index 0b66141e51a..21d55357a2a 100644 --- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c @@ -424,22 +424,26 @@ static void gpencil_vfx_glow(GlowShaderFxData *fx, Object *UNUSED(ob), gpIterVfx GPUShader *sh = GPENCIL_shader_fx_glow_get(); - float ref_col[3]; + float ref_col[4]; if (fx->mode == eShaderFxGlowMode_Luminance) { + /* Only pass in the first value for luminance. */ ref_col[0] = fx->threshold; ref_col[1] = -1.0f; ref_col[2] = -1.0f; + ref_col[3] = -1.0f; } else { + /* First three values are the RGB for the selected color, last value the threshold. */ copy_v3_v3(ref_col, fx->select_color); + ref_col[3] = fx->threshold; } DRWState state = DRW_STATE_WRITE_COLOR; grp = gpencil_vfx_pass_create("Fx Glow H", state, iter, sh); DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){fx->blur[0] * c, fx->blur[0] * s}); DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, fx->blur[0]))); - DRW_shgroup_uniform_vec3_copy(grp, "threshold", ref_col); + DRW_shgroup_uniform_vec4_copy(grp, "threshold", ref_col); DRW_shgroup_uniform_vec4_copy(grp, "glowColor", fx->glow_color); DRW_shgroup_uniform_bool_copy(grp, "glowUnder", use_glow_under); DRW_shgroup_uniform_bool_copy(grp, "firstPass", true); @@ -473,7 +477,7 @@ static void gpencil_vfx_glow(GlowShaderFxData *fx, Object *UNUSED(ob), gpIterVfx grp = gpencil_vfx_pass_create("Fx Glow V", state, iter, sh); DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){-fx->blur[1] * s, fx->blur[1] * c}); DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, fx->blur[0]))); - DRW_shgroup_uniform_vec3_copy(grp, "threshold", (float[3]){-1.0f, -1.0f, -1.0f}); + DRW_shgroup_uniform_vec4_copy(grp, "threshold", (float[4]){-1.0f, -1.0f, -1.0f, -1.0}); DRW_shgroup_uniform_vec4_copy(grp, "glowColor", (float[4]){1.0f, 1.0f, 1.0f, fx->glow_color[3]}); DRW_shgroup_uniform_bool_copy(grp, "firstPass", false); DRW_shgroup_uniform_int_copy(grp, "blendMode", fx->blend_mode); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl index bb905f8694b..269ed49c4d0 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_vfx_frag.glsl @@ -145,7 +145,7 @@ void main() uniform vec4 glowColor; uniform vec2 offset; uniform int sampCount; -uniform vec3 threshold; +uniform vec4 threshold; uniform bool firstPass; uniform bool glowUnder; uniform int blendMode; @@ -168,7 +168,7 @@ void main() vec3 rev = texture(revealBuf, uv).rgb; if (threshold.x > -1.0) { if (threshold.y > -1.0) { - if (any(greaterThan(abs(col - threshold), vec3(0.05)))) { + if (any(greaterThan(abs(col - vec3(threshold)), vec3(threshold.w)))) { weight = 0.0; } } diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index 54224071d23..fbad60ff4ab 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -1031,7 +1031,7 @@ static void pchan_draw_data_init(bPoseChannel *pchan) static void draw_bone_update_disp_matrix_default(EditBone *eBone, bPoseChannel *pchan) { float ebmat[4][4]; - float length; + float bone_scale[3]; float(*bone_mat)[4]; float(*disp_mat)[4]; float(*disp_tail_mat)[4]; @@ -1040,23 +1040,23 @@ static void draw_bone_update_disp_matrix_default(EditBone *eBone, bPoseChannel * * and not be tight to the draw pass creation. * This would refresh armature without invalidating the draw cache */ if (pchan) { - length = pchan->bone->length; bone_mat = pchan->pose_mat; disp_mat = pchan->disp_mat; disp_tail_mat = pchan->disp_tail_mat; + copy_v3_fl(bone_scale, pchan->bone->length); } else { eBone->length = len_v3v3(eBone->tail, eBone->head); ED_armature_ebone_to_mat4(eBone, ebmat); - length = eBone->length; + copy_v3_fl(bone_scale, eBone->length); bone_mat = ebmat; disp_mat = eBone->disp_mat; disp_tail_mat = eBone->disp_tail_mat; } copy_m4_m4(disp_mat, bone_mat); - rescale_m4(disp_mat, (float[3]){length, length, length}); + rescale_m4(disp_mat, bone_scale); copy_m4_m4(disp_tail_mat, disp_mat); translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f); } @@ -1255,19 +1255,27 @@ static void draw_bone_update_disp_matrix_bbone(EditBone *eBone, bPoseChannel *pc static void draw_bone_update_disp_matrix_custom(bPoseChannel *pchan) { - float length; + float bone_scale[3]; float(*bone_mat)[4]; float(*disp_mat)[4]; float(*disp_tail_mat)[4]; + float rot_mat[3][3]; /* See TODO above */ - length = PCHAN_CUSTOM_DRAW_SIZE(pchan); + mul_v3_v3fl(bone_scale, pchan->custom_scale_xyz, PCHAN_CUSTOM_BONE_LENGTH(pchan)); bone_mat = pchan->custom_tx ? pchan->custom_tx->pose_mat : pchan->pose_mat; disp_mat = pchan->disp_mat; disp_tail_mat = pchan->disp_tail_mat; + eulO_to_mat3(rot_mat, pchan->custom_rotation_euler, ROT_MODE_XYZ); + copy_m4_m4(disp_mat, bone_mat); - rescale_m4(disp_mat, (float[3]){length, length, length}); + translate_m4(disp_mat, + pchan->custom_translation[0], + pchan->custom_translation[1], + pchan->custom_translation[2]); + mul_m4_m4m3(disp_mat, disp_mat, rot_mat); + rescale_m4(disp_mat, bone_scale); copy_m4_m4(disp_tail_mat, disp_mat); translate_m4(disp_tail_mat, 0.0f, 1.0f, 0.0f); } diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index e9736402ae7..b8f721946f2 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -285,10 +285,6 @@ static bool overlay_should_fade_object(Object *ob, Object *active_object) return false; } - if (ob->base_flag & BASE_FROM_DUPLI) { - return false; - } - return true; } diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.c index 891142fe0a2..aa26aa47faa 100644 --- a/source/blender/draw/engines/overlay/overlay_gpencil.c +++ b/source/blender/draw/engines/overlay/overlay_gpencil.c @@ -382,7 +382,7 @@ static void overlay_gpencil_draw_stroke_color_name(bGPDlayer *UNUSED(gpl), void *thunk) { Object *ob = (Object *)thunk; - Material *ma = BKE_object_material_get(ob, gps->mat_nr + 1); + Material *ma = BKE_object_material_get_eval(ob, gps->mat_nr + 1); if (ma == NULL) { return; } diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c index 89e724bcfcc..d52640ed174 100644 --- a/source/blender/draw/engines/overlay/overlay_paint.c +++ b/source/blender/draw/engines/overlay/overlay_paint.c @@ -48,7 +48,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob) v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) { Mesh *me = ob->data; for (int i = 0; i < me->totcol; i++) { - Material *mat = me->mat[i]; + Material *mat = BKE_object_material_get_eval(ob, i + 1); if (mat && mat->a < 1.0f) { return true; } diff --git a/source/blender/draw/engines/overlay/overlay_particle.c b/source/blender/draw/engines/overlay/overlay_particle.c index 71064e7ff47..5fa74a8c3a6 100644 --- a/source/blender/draw/engines/overlay/overlay_particle.c +++ b/source/blender/draw/engines/overlay/overlay_particle.c @@ -186,7 +186,7 @@ void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob) /* TODO(fclem): Here would be a good place for preemptive culling. */ /* NOTE(fclem): Is color even useful in our modern context? */ - Material *ma = BKE_object_material_get(ob, part->omat); + Material *ma = BKE_object_material_get_eval(ob, part->omat); float color[4] = {0.6f, 0.6f, 0.6f, part->draw_size}; if (ma != NULL) { copy_v3_v3(color, &ma->r); diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index 6e9118bfe46..800d1085505 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -93,7 +93,7 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd, /* Return correct material or empty default material if slot is empty. */ BLI_INLINE Material *workbench_object_material_get(Object *ob, int mat_nr) { - Material *ma = BKE_object_material_get(ob, mat_nr); + Material *ma = BKE_object_material_get_eval(ob, mat_nr); if (ma == NULL) { ma = BKE_material_default_empty(); } diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 525a81b5581..ddda6d7b58e 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -202,7 +202,7 @@ static void workbench_volume_material_color(WORKBENCH_PrivateData *wpd, eV3DShadingColorType color_type, float color[3]) { - Material *ma = BKE_object_material_get(ob, VOLUME_MATERIAL_NR); + Material *ma = BKE_object_material_get_eval(ob, VOLUME_MATERIAL_NR); WORKBENCH_UBO_Material ubo_data; workbench_material_ubo_data(wpd, ob, ma, &ubo_data, color_type); copy_v3_v3(color, ubo_data.base_color); diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index c929fe7dfd3..bbb97fc09a3 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -88,6 +88,10 @@ typedef enum eMRExtractType { BLI_INLINE int mesh_render_mat_len_get(Mesh *me) { + /* In edit mode, the displayed mesh is stored in the edit-mesh. */ + if (me->edit_mesh && me->edit_mesh->mesh_eval_final) { + return MAX2(1, me->edit_mesh->mesh_eval_final->totcol); + } return MAX2(1, me->totcol); } diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 7b97ce43558..5743f39f7da 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -43,6 +43,10 @@ struct bGPdata; #include "BKE_mesh_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Expose via BKE callbacks */ void DRW_mball_batch_cache_dirty_tag(struct MetaBall *mb, int mode); void DRW_mball_batch_cache_validate(struct MetaBall *mb); @@ -262,3 +266,6 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_inner_points(struct Object * struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.cc index e9558fb320c..ddafc7205bb 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -144,7 +144,8 @@ static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_ int normal_len = 0; const BevList *bl; const Nurb *nu; - for (bl = ob_curve_cache->bev.first, nu = lb->first; nu && bl; bl = bl->next, nu = nu->next) { + for (bl = (const BevList *)ob_curve_cache->bev.first, nu = (const Nurb *)lb->first; nu && bl; + bl = bl->next, nu = nu->next) { int nr = bl->nr; int skip = nu->resolu / 16; #if 0 @@ -163,7 +164,7 @@ static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_ /* ---------------------------------------------------------------------- */ /* Curve Interface, indirect, partially cached access to complex data. */ -typedef struct CurveRenderData { +struct CurveRenderData { int types; struct { @@ -198,7 +199,7 @@ typedef struct CurveRenderData { int actnu; /* edit, index in active nurb (BPoint or BezTriple) */ int actvert; -} CurveRenderData; +}; enum { /* Wire center-line */ @@ -220,7 +221,7 @@ static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve_cache, const int types) { - CurveRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__); + CurveRenderData *rdata = (CurveRenderData *)MEM_callocN(sizeof(*rdata), __func__); rdata->types = types; ListBase *nurbs; @@ -314,7 +315,7 @@ static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers, { for (int i = 0; i < gpumat_array_len; i++) { struct GPUMaterial *gpumat = gpumat_array[i]; - if (gpumat == NULL) { + if (gpumat == nullptr) { continue; } @@ -354,7 +355,7 @@ static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers, /* ---------------------------------------------------------------------- */ /* Curve GPUBatch Cache */ -typedef struct CurveBatchCache { +struct CurveBatchCache { struct { GPUVertBuf *pos_nor; GPUVertBuf *edge_fac; @@ -406,15 +407,15 @@ typedef struct CurveBatchCache { /* Valid only if edge_detection is up to date. */ bool is_manifold; -} CurveBatchCache; +}; /* GPUBatch cache management. */ static bool curve_batch_cache_valid(Curve *cu) { - CurveBatchCache *cache = cu->batch_cache; + CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache; - if (cache == NULL) { + if (cache == nullptr) { return false; } @@ -426,7 +427,7 @@ static bool curve_batch_cache_valid(Curve *cu) return false; } - if (cache->is_editmode != ((cu->editnurb != NULL) || (cu->editfont != NULL))) { + if (cache->is_editmode != ((cu->editnurb != nullptr) || (cu->editfont != nullptr))) { return false; } @@ -441,10 +442,11 @@ static bool curve_batch_cache_valid(Curve *cu) static void curve_batch_cache_init(Curve *cu) { - CurveBatchCache *cache = cu->batch_cache; + CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache; if (!cache) { - cache = cu->batch_cache = MEM_callocN(sizeof(*cache), __func__); + cache = (CurveBatchCache *)MEM_callocN(sizeof(*cache), __func__); + cu->batch_cache = cache; } else { memset(cache, 0, sizeof(*cache)); @@ -463,11 +465,12 @@ static void curve_batch_cache_init(Curve *cu) cache->cd_used = 0; cache->mat_len = DRW_curve_material_count_get(cu); - cache->surf_per_mat_tris = MEM_callocN(sizeof(*cache->surf_per_mat_tris) * cache->mat_len, - __func__); - cache->surf_per_mat = MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, __func__); + cache->surf_per_mat_tris = (GPUIndexBuf **)MEM_callocN( + sizeof(*cache->surf_per_mat_tris) * cache->mat_len, __func__); + cache->surf_per_mat = (GPUBatch **)MEM_callocN(sizeof(*cache->surf_per_mat) * cache->mat_len, + __func__); - cache->is_editmode = (cu->editnurb != NULL) || (cu->editfont != NULL); + cache->is_editmode = (cu->editnurb != nullptr) || (cu->editfont != nullptr); cache->is_dirty = false; } @@ -482,13 +485,13 @@ void DRW_curve_batch_cache_validate(Curve *cu) static CurveBatchCache *curve_batch_cache_get(Curve *cu) { - return cu->batch_cache; + return (CurveBatchCache *)cu->batch_cache; } void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode) { - CurveBatchCache *cache = cu->batch_cache; - if (cache == NULL) { + CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache; + if (cache == nullptr) { return; } switch (mode) { @@ -508,7 +511,7 @@ void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode) static void curve_batch_cache_clear(Curve *cu) { - CurveBatchCache *cache = cu->batch_cache; + CurveBatchCache *cache = (CurveBatchCache *)cu->batch_cache; if (!cache) { return; } @@ -553,7 +556,7 @@ void DRW_curve_batch_cache_free(Curve *cu) /* GPUBatch cache usage. */ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curves_pos) { - BLI_assert(rdata->ob_curve_cache != NULL); + BLI_assert(rdata->ob_curve_cache != nullptr); static GPUVertFormat format = {0}; static struct { @@ -589,7 +592,7 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines) { - BLI_assert(rdata->ob_curve_cache != NULL); + BLI_assert(rdata->ob_curve_cache != nullptr); const int vert_len = curve_render_data_wire_verts_len_get(rdata); const int edge_len = curve_render_data_wire_edges_len_get(rdata); @@ -677,7 +680,9 @@ static void curve_create_edit_curves_nor(CurveRenderData *rdata, const uint tan_id = do_hq_normals ? attr_id.tan_hq : attr_id.tan; const uint rad_id = do_hq_normals ? attr_id.rad_hq : attr_id.rad; - for (bl = rdata->ob_curve_cache->bev.first, nu = rdata->nurbs->first; nu && bl; + for (bl = (const BevList *)rdata->ob_curve_cache->bev.first, + nu = (const Nurb *)rdata->nurbs->first; + nu && bl; bl = bl->next, nu = nu->next) { const BevPoint *bevp = bl->bevpoints; int nr = bl->nr; @@ -773,8 +778,8 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata, GPU_vertbuf_data_alloc(vbo_data, verts_len_capacity); } - GPUIndexBufBuilder elb_verts, *elbp_verts = NULL; - GPUIndexBufBuilder elb_lines, *elbp_lines = NULL; + GPUIndexBufBuilder elb_verts, *elbp_verts = nullptr; + GPUIndexBufBuilder elb_lines, *elbp_lines = nullptr; if (DRW_TEST_ASSIGN_IBO(ibo_edit_verts_points)) { elbp_verts = &elb_verts; GPU_indexbuf_init(elbp_verts, GPU_PRIM_POINTS, verts_len_capacity, verts_len_capacity); @@ -785,13 +790,13 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata, } int nu_id = 0; - for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, nu_id++) { + for (Nurb *nu = (Nurb *)rdata->nurbs->first; nu; nu = nu->next, nu_id++) { const BezTriple *bezt = nu->bezt; const BPoint *bp = nu->bp; if (bezt) { for (int a = 0; a < nu->pntsu; a++, bezt++) { - if (bezt->hide == true) { + if (bezt->hide != 0) { continue; } const bool handle_selected = BEZT_ISSEL_ANY(bezt); @@ -826,7 +831,7 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata, else if (bp) { int pt_len = nu->pntsu * nu->pntsv; for (int a = 0; a < pt_len; a++, bp++, vbo_len_used += 1) { - if (bp->hide == true) { + if (bp->hide != 0) { continue; } int u = (a % nu->pntsu); @@ -837,8 +842,8 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata, GPU_indexbuf_add_point_vert(elbp_verts, vbo_len_used); } if (elbp_lines) { - const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : NULL; - const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : NULL; + const BPoint *bp_next_u = (u < (nu->pntsu - 1)) ? &nu->bp[a + 1] : nullptr; + const BPoint *bp_next_v = (v < (nu->pntsv - 1)) ? &nu->bp[a + nu->pntsu] : nullptr; if (bp_next_u && (bp_next_u->hide == false)) { GPU_indexbuf_add_line_verts(elbp_lines, vbo_len_used, vbo_len_used + 1); } @@ -858,17 +863,17 @@ static void curve_create_edit_data_and_handles(CurveRenderData *rdata, } /* Resize & Finish */ - if (elbp_verts != NULL) { + if (elbp_verts != nullptr) { GPU_indexbuf_build_in_place(elbp_verts, ibo_edit_verts_points); } - if (elbp_lines != NULL) { + if (elbp_lines != nullptr) { GPU_indexbuf_build_in_place(elbp_lines, ibo_edit_lines); } if (vbo_len_used != verts_len_capacity) { - if (vbo_pos != NULL) { + if (vbo_pos != nullptr) { GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } - if (vbo_data != NULL) { + if (vbo_data != nullptr) { GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } } @@ -932,7 +937,7 @@ GPUVertBuf *DRW_curve_batch_cache_pos_vertbuf_get(struct Curve *cu) /* Request surface to trigger the vbo filling. Otherwise it may do nothing. */ DRW_batch_request(&cache->batch.surfaces); - DRW_vbo_request(NULL, &cache->ordered.loop_pos_nor); + DRW_vbo_request(nullptr, &cache->ordered.loop_pos_nor); return cache->ordered.loop_pos_nor; } @@ -968,7 +973,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen { BLI_assert(ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)); - Curve *cu = ob->data; + Curve *cu = (Curve *)ob->data; CurveBatchCache *cache = curve_batch_cache_get(cu); /* Verify that all surface batches have needed attribute layers. */ @@ -1118,7 +1123,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen #ifdef DEBUG /* Make sure all requested batches have been setup. */ for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); i++) { - BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0)); + BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], (GPUPrimType)0)); } #endif } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index f11fd0f3906..af54b57b162 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -557,12 +557,18 @@ static void mesh_batch_cache_discard_surface_batches(MeshBatchCache *cache) static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) { FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) { - GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.tan); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.vcol); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.orco); } + /* Discard batches using vbo.uv. */ + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_area); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_angle); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts); + mesh_batch_cache_discard_surface_batches(cache); mesh_cd_layers_type_clear(&cache->cd_used); } @@ -659,8 +665,17 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.lnor); } GPU_BATCH_DISCARD_SAFE(cache->batch.surface); + /* Discard batches using vbo.pos_nor. */ GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops); GPU_BATCH_DISCARD_SAFE(cache->batch.wire_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.all_verts); + GPU_BATCH_DISCARD_SAFE(cache->batch.all_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.loose_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.edge_detection); + GPU_BATCH_DISCARD_SAFE(cache->batch.surface_weights); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_mesh_analysis); + /* Discard batches using vbo.lnor. */ + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_lnor); mesh_batch_cache_discard_surface_batches(cache); cache->batch_ready &= ~(MBC_SURFACE | MBC_WIRE_EDGES | MBC_WIRE_LOOPS); break; diff --git a/source/blender/draw/intern/draw_cache_inline.h b/source/blender/draw/intern/draw_cache_inline.h index ebe97b4e7c4..bfc714e5d6a 100644 --- a/source/blender/draw/intern/draw_cache_inline.h +++ b/source/blender/draw/intern/draw_cache_inline.h @@ -53,13 +53,13 @@ BLI_INLINE GPUBatch *DRW_batch_request(GPUBatch **batch) return *batch; } -BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, int prim_type) +BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, GPUPrimType prim_type) { /* Batch has been requested if it has been created but not initialized. */ if (batch != NULL && batch->verts[0] == NULL) { /* HACK. We init without a valid VBO and let the first vbo binding * fill verts[0]. */ - GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, 0); + GPU_batch_init_ex(batch, prim_type, (GPUVertBuf *)1, NULL, (eGPUBatchFlag)0); batch->verts[0] = NULL; return true; } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index c09b4719f3a..37f6bbf52b5 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1473,6 +1473,14 @@ void DRW_draw_callbacks_post_scene(void) GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } + else { + if (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0)) { + GPU_depth_test(GPU_DEPTH_NONE); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, region, true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); + } + } } struct DRWTextStore *DRW_text_cache_ensure(void) diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index c93cbf16a30..2aad1f10154 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -606,10 +606,10 @@ static uint32_t drw_shader_dependencies_get(const DRWShaderLibrary *lib, const c haystack += 16; int dep = drw_shader_library_search(lib, haystack); if (dep == -1) { - char dbg_name[32]; + char dbg_name[33]; int i = 0; - while ((haystack[0] != ')') && (i < 31)) { - dbg_name[i] = haystack[0]; + while ((*haystack != ')') && (i < (sizeof(dbg_name) - 2))) { + dbg_name[i] = *haystack; haystack++; i++; } diff --git a/source/blender/draw/tests/draw_testing.cc b/source/blender/draw/tests/draw_testing.cc new file mode 100644 index 00000000000..0104437e921 --- /dev/null +++ b/source/blender/draw/tests/draw_testing.cc @@ -0,0 +1,18 @@ +/* Apache License, Version 2.0 */ + +#include "draw_testing.hh" + +#include "GPU_shader.h" + +#include "draw_manager_testing.h" + +namespace blender::draw { + +/* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ +void DrawTest::SetUp() +{ + GPUTest::SetUp(); + DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); +} + +} // namespace blender::draw diff --git a/source/blender/draw/tests/draw_testing.hh b/source/blender/draw/tests/draw_testing.hh new file mode 100644 index 00000000000..ec0b15b611e --- /dev/null +++ b/source/blender/draw/tests/draw_testing.hh @@ -0,0 +1,13 @@ +/* Apache License, Version 2.0 */ + +#include "gpu_testing.hh" + +namespace blender::draw { + +/* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ +class DrawTest : public blender::gpu::GPUTest { + public: + void SetUp() override; +}; + +} // namespace blender::draw diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index 96d544fd855..c96f22859ca 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -2,12 +2,12 @@ #include "testing/testing.h" +#include "draw_testing.hh" #include "intern/draw_manager_testing.h" #include "GPU_context.h" #include "GPU_init_exit.h" #include "GPU_shader.h" -#include "gpu_testing.hh" #include "engines/eevee/eevee_private.h" #include "engines/gpencil/gpencil_engine.h" @@ -17,19 +17,9 @@ namespace blender::draw { -/* Base class for draw test cases. It will setup and tear down the GPU part around each test. */ -class DrawTest : public blender::gpu::GPUTest { - void SetUp() override - { - GPUTest::SetUp(); - DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); - } -}; - TEST_F(DrawTest, workbench_glsl_shaders) { workbench_shader_library_ensure(); - DRW_draw_state_init_gtests(GPU_SHADER_CFG_DEFAULT); const int MAX_WPD = 6; WORKBENCH_PrivateData wpds[MAX_WPD]; |