Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2020-11-04 16:14:38 +0300
committerJeroen Bakker <jeroen@blender.org>2020-11-04 16:14:38 +0300
commit5af9b9f45be08368a7fa3965805f53f012401631 (patch)
tree9b44b9d69a635eda95d3da236c0ea05de4a73123 /source/blender
parent17ccda4fe1c4bcc206024af3244c44678791a685 (diff)
parent3ffa0452af9ac0a08b321e9504c9e080ab1ce47d (diff)
Merge branch 'blender-v2.91-release'
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c5
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.c40
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h3
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c12
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c3
-rw-r--r--source/blender/gpu/GPU_state.h1
-rw-r--r--source/blender/gpu/opengl/gl_state.cc7
8 files changed, 63 insertions, 10 deletions
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 30b39e5d5e1..e49b2e45580 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -509,6 +509,11 @@ static void OVERLAY_draw_scene(void *vedata)
OVERLAY_FramebufferList *fbl = data->fbl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ /* Needs to be done first as it modifies the scene color and depth buffer. */
+ if (!pd->is_image_editor) {
+ OVERLAY_image_scene_background_draw(vedata);
+ }
+
if (DRW_state_is_fbo()) {
const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(dfbl->overlay_only_fb);
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index 08cddf4e185..9695f8616a5 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -57,6 +57,8 @@ void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_PREMUL;
DRW_PASS_CREATE(psl->image_background_ps, state);
+ state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL;
+ DRW_PASS_CREATE(psl->image_background_scene_ps, state);
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
DRW_PASS_CREATE(psl->image_empties_ps, state | pd->clipping_state);
@@ -68,6 +70,7 @@ void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL;
DRW_PASS_CREATE(psl->image_empties_front_ps, state);
DRW_PASS_CREATE(psl->image_foreground_ps, state);
+ DRW_PASS_CREATE(psl->image_foreground_scene_ps, state);
}
static void overlay_image_calc_aspect(Image *ima, const int size[2], float r_image_aspect[2])
@@ -136,7 +139,8 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
const DRWContextState *draw_ctx,
OVERLAY_PrivateData *pd,
float *r_aspect,
- bool *r_use_alpha_premult)
+ bool *r_use_alpha_premult,
+ bool *r_use_view_transform)
{
void *lock;
Image *image = bgpic->ima;
@@ -148,6 +152,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
int width, height;
int ctime = (int)DEG_get_ctime(draw_ctx->depsgraph);
*r_use_alpha_premult = false;
+ *r_use_view_transform = false;
switch (bgpic->source) {
case CAM_BGIMG_SOURCE_IMAGE:
@@ -155,6 +160,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
return NULL;
}
*r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
+ *r_use_view_transform = (image->flag & IMA_VIEW_AS_RENDER) != 0;
BKE_image_user_frame_calc(image, iuser, ctime);
if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
@@ -183,7 +189,6 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
aspect_x = bgpic->ima->aspx;
aspect_y = bgpic->ima->aspy;
-
break;
case CAM_BGIMG_SOURCE_MOVIE:
@@ -208,6 +213,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
aspect_x = clip->aspx;
aspect_y = clip->aspy;
+ *r_use_view_transform = true;
BKE_movieclip_get_size(clip, &bgpic->cuser, &width, &height);
@@ -328,21 +334,27 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
float aspect = 1.0;
bool use_alpha_premult;
+ bool use_view_transform = false;
float mat[4][4];
/* retrieve the image we want to show, continue to next when no image could be found */
GPUTexture *tex = image_camera_background_texture_get(
- bgpic, draw_ctx, pd, &aspect, &use_alpha_premult);
+ bgpic, draw_ctx, pd, &aspect, &use_alpha_premult, &use_view_transform);
if (tex) {
image_camera_background_matrix_get(cam, bgpic, draw_ctx, aspect, mat);
mul_m4_m4m4(mat, modelmat, mat);
const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0;
+ /* Alpha is clamped just below 1.0 to fix background images to intefere with foreground
+ * images. Without this a background image with 1.0 will be rendered on top of a transparent
+ * foreground image due to the differnet blending modes they use. */
+ const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, MIN2(bgpic->alpha, 0.999999)};
- const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
-
- DRWPass *pass = is_foreground ? psl->image_foreground_ps : psl->image_background_ps;
+ DRWPass *pass = is_foreground ? (use_view_transform ? psl->image_foreground_scene_ps :
+ psl->image_foreground_ps) :
+ (use_view_transform ? psl->image_background_scene_ps :
+ psl->image_background_ps);
GPUShader *sh = OVERLAY_shader_image();
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -449,6 +461,22 @@ void OVERLAY_image_cache_finish(OVERLAY_Data *vedata)
DRW_pass_sort_shgroup_z(psl->image_empties_back_ps);
}
+/* This function draws images that needs the view transform applied.
+ * It draws these images directly into the scene color buffer. */
+void OVERLAY_image_scene_background_draw(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+
+ if (DRW_state_is_fbo() && (!DRW_pass_is_empty(psl->image_background_scene_ps) ||
+ !DRW_pass_is_empty(psl->image_foreground_scene_ps))) {
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ GPU_framebuffer_bind(dfbl->default_fb);
+
+ DRW_draw_pass(psl->image_background_scene_ps);
+ DRW_draw_pass(psl->image_foreground_scene_ps);
+ }
+}
+
void OVERLAY_image_background_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index ef7a2db476c..d5ba0a5423f 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -103,11 +103,13 @@ typedef struct OVERLAY_PassList {
DRWPass *fade_ps[2];
DRWPass *grid_ps;
DRWPass *image_background_ps;
+ DRWPass *image_background_scene_ps;
DRWPass *image_empties_ps;
DRWPass *image_empties_back_ps;
DRWPass *image_empties_blend_ps;
DRWPass *image_empties_front_ps;
DRWPass *image_foreground_ps;
+ DRWPass *image_foreground_scene_ps;
DRWPass *metaball_ps[2];
DRWPass *motion_paths_ps;
DRWPass *outlines_prepass_ps;
@@ -592,6 +594,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_image_cache_finish(OVERLAY_Data *vedata);
void OVERLAY_image_draw(OVERLAY_Data *vedata);
void OVERLAY_image_background_draw(OVERLAY_Data *vedata);
+void OVERLAY_image_scene_background_draw(OVERLAY_Data *vedata);
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata);
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 6f40e04ab7e..336e6e75659 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -347,6 +347,8 @@ typedef enum {
/** Use dual source blending. WARNING: Only one color buffer allowed. */
DRW_STATE_BLEND_CUSTOM = (9 << 11),
DRW_STATE_LOGIC_INVERT = (10 << 11),
+ DRW_STATE_BLEND_ALPHA_UNDER_PREMUL = (11 << 11),
+
DRW_STATE_IN_FRONT_SELECT = (1 << 27),
DRW_STATE_SHADOW_OFFSET = (1 << 28),
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index ff1efccd507..7766ce906b8 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -902,12 +902,16 @@ static void extract_tris_finish(const MeshRenderData *mr,
MeshExtract_Tri_Data *data = _data;
GPU_indexbuf_build_in_place(&data->elb, ibo);
- /* HACK: Create ibo sub-ranges and assign them to each #GPUBatch. */
- /* The `surface_per_mat` tests are there when object shading type is set to Wire or Bounds. In
- * these cases there isn't a surface per material. */
- if (mr->use_final_mesh && cache->surface_per_mat && cache->surface_per_mat[0]) {
+ /* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch
+ * is created before the surfaces-per-material. */
+ if (mr->use_final_mesh && cache->final.tris_per_mat) {
MeshBufferCache *mbc = &cache->final;
for (int i = 0; i < mr->mat_len; i++) {
+ /* Theses IBOs have not been queried yet but we create them just in case they are needed
+ * later since they are not tracked by mesh_buffer_cache_create_requested(). */
+ if (mbc->tris_per_mat[i] == NULL) {
+ mbc->tris_per_mat[i] = GPU_indexbuf_calloc();
+ }
/* Multiply by 3 because these are triangle indices. */
const int mat_start = data->tri_mat_start[i];
const int mat_end = data->tri_mat_end[i];
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 21bcaa2d2b2..749e9e6bafb 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -206,6 +206,9 @@ void drw_state_set(DRWState state)
case DRW_STATE_LOGIC_INVERT:
blend = GPU_BLEND_INVERT;
break;
+ case DRW_STATE_BLEND_ALPHA_UNDER_PREMUL:
+ blend = GPU_BLEND_ALPHA_UNDER_PREMUL;
+ break;
default:
blend = GPU_BLEND_NONE;
break;
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index b7bea4b0a08..f5a1ccbc40b 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -71,6 +71,7 @@ typedef enum eGPUBlend {
/** Custom blend parameters using dual source blending : SRC0 + SRC1 * DST
* NOTE: Can only be used with _ONE_ Draw Buffer and shader needs to be specialized. */
GPU_BLEND_CUSTOM,
+ GPU_BLEND_ALPHA_UNDER_PREMUL,
} eGPUBlend;
typedef enum eGPUDepthTest {
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 27c9b501add..3a474da8b8e 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -421,6 +421,13 @@ void GLStateManager::set_blend(const eGPUBlend value)
dst_alpha = GL_SRC_ALPHA;
break;
}
+ case GPU_BLEND_ALPHA_UNDER_PREMUL: {
+ src_rgb = GL_ONE_MINUS_DST_ALPHA;
+ dst_rgb = GL_ONE;
+ src_alpha = GL_ONE_MINUS_DST_ALPHA;
+ dst_alpha = GL_ONE;
+ break;
+ }
case GPU_BLEND_CUSTOM: {
src_rgb = GL_ONE;
dst_rgb = GL_SRC1_COLOR;