[Bf-blender-cvs] [5cae096d137] tmp-overlay-engine: Overlay Engine: Camera Background Images

Clément Foucault noreply at git.blender.org
Fri Nov 15 01:35:36 CET 2019


Commit: 5cae096d137c2f4d7b960b3ce73cd9e174f34945
Author: Clément Foucault
Date:   Fri Nov 15 01:31:08 2019 +0100
Branches: tmp-overlay-engine
https://developer.blender.org/rB5cae096d137c2f4d7b960b3ce73cd9e174f34945

Overlay Engine: Camera Background Images

===================================================================

M	source/blender/draw/engines/overlay/overlay_extra.c
M	source/blender/draw/engines/overlay/overlay_image.c
M	source/blender/draw/engines/overlay/overlay_private.h

===================================================================

diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index b89561c9f2d..e0075b34c3f 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -1183,6 +1183,11 @@ void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
   if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) != 0) {
     camera_view3d_reconstruction(cb, scene, v3d, camera_object, ob, color_p);
   }
+
+  /* Background images. */
+  if (look_through && (cam->flag & CAM_SHOW_BG_IMAGE) && !BLI_listbase_is_empty(&cam->bg_images)) {
+    OVERLAY_image_camera_cache_populate(vedata, ob);
+  }
 }
 
 /** \} */
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index 91cb026e8c4..04aa652654a 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -22,8 +22,20 @@
 
 #include "DRW_render.h"
 
+#include "BKE_camera.h"
+#include "BKE_image.h"
+#include "BKE_movieclip.h"
 #include "BKE_object.h"
 
+#include "DNA_camera_types.h"
+#include "DNA_screen_types.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "ED_view3d.h"
+
+#include "IMB_imbuf_types.h"
+
 #include "overlay_private.h"
 
 void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
@@ -80,12 +92,239 @@ static void overlay_image_calc_aspect(Image *ima, const int size[2], float r_ima
   }
 }
 
+static void camera_background_images_stereo_setup(Scene *scene,
+                                                  View3D *v3d,
+                                                  Image *ima,
+                                                  ImageUser *iuser)
+{
+  if (BKE_image_is_stereo(ima)) {
+    iuser->flag |= IMA_SHOW_STEREO;
+
+    if ((scene->r.scemode & R_MULTIVIEW) == 0) {
+      iuser->multiview_eye = STEREO_LEFT_ID;
+    }
+    else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+      /* show only left or right camera */
+      iuser->multiview_eye = v3d->stereo3d_camera;
+    }
+
+    BKE_image_multiview_index(ima, iuser);
+  }
+  else {
+    iuser->flag &= ~IMA_SHOW_STEREO;
+  }
+}
+
+static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgpic,
+                                                              const DRWContextState *draw_ctx,
+                                                              OVERLAY_PrivateData *pd,
+                                                              float *r_aspect,
+                                                              bool *r_use_alpha_premult)
+{
+  Image *image = bgpic->ima;
+  ImageUser *iuser = &bgpic->iuser;
+  MovieClip *clip = NULL;
+  GPUTexture *tex = NULL;
+  Scene *scene = draw_ctx->scene;
+  float aspect_x, aspect_y, width, height;
+  int ctime = (int)DEG_get_ctime(draw_ctx->depsgraph);
+  *r_use_alpha_premult = false;
+
+  switch (bgpic->source) {
+    case CAM_BGIMG_SOURCE_IMAGE:
+      if (image == NULL) {
+        return NULL;
+      }
+      *r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
+
+      BKE_image_user_frame_calc(image, iuser, ctime);
+      if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
+        /* Frame is out of range, dont show. */
+        return NULL;
+      }
+      else {
+        camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
+      }
+
+      ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, NULL);
+      if (ibuf == NULL) {
+        return NULL;
+      }
+
+      tex = GPU_texture_from_blender(image, iuser, GL_TEXTURE_2D);
+      if (tex == NULL) {
+        return NULL;
+      }
+
+      aspect_x = bgpic->ima->aspx;
+      aspect_y = bgpic->ima->aspy;
+
+      width = ibuf->x;
+      height = ibuf->y;
+
+      BKE_image_release_ibuf(image, ibuf, NULL);
+      break;
+
+    case CAM_BGIMG_SOURCE_MOVIE:
+      if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
+        if (scene->camera) {
+          clip = BKE_object_movieclip_get(scene, scene->camera, true);
+        }
+      }
+      else {
+        clip = bgpic->clip;
+      }
+
+      if (clip == NULL) {
+        return NULL;
+      }
+
+      BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
+      tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D);
+      if (tex == NULL) {
+        return NULL;
+      }
+
+      aspect_x = clip->aspx;
+      aspect_y = clip->aspy;
+
+      BKE_movieclip_get_size(clip, &bgpic->cuser, &width, &height);
+
+      /* Save for freeing. */
+      BLI_addtail(&pd->bg_movie_clips, BLI_genericNodeN(clip));
+      break;
+
+    default:
+      /* Unsupported type. */
+      return NULL;
+  }
+
+  *r_aspect = (width * aspect_x) / (height * aspect_y);
+  return tex;
+}
+
+static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
+{
+  /* Free Movie clip textures after rendering */
+  LinkData *link;
+  while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
+    MovieClip *clip = (MovieClip *)link->data;
+    GPU_free_texture_movieclip(clip);
+    MEM_freeN(link);
+  }
+}
+
+static void image_camera_background_matrix_get(const Camera *cam,
+                                               const CameraBGImage *bgpic,
+                                               const DRWContextState *draw_ctx,
+                                               const float image_aspect,
+                                               float rmat[4][4])
+{
+  float rotate[4][4], scale[4][4], translate[4][4];
+
+  axis_angle_to_mat4_single(rotate, 'Z', -bgpic->rotation);
+  unit_m4(scale);
+  unit_m4(translate);
+
+  /*  Normalized Object space camera frame corners. */
+  float cam_corners[4][3];
+  BKE_camera_view_frame(draw_ctx->scene, cam, cam_corners);
+  float cam_width = fabsf(cam_corners[0][0] - cam_corners[3][0]);
+  float cam_height = fabsf(cam_corners[0][1] - cam_corners[1][1]);
+  float cam_aspect = cam_width / cam_height;
+
+  if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) {
+    /* Crop. */
+    if (image_aspect > cam_aspect) {
+      scale[0][0] *= cam_height * image_aspect;
+      scale[1][1] *= cam_height;
+    }
+    else {
+      scale[0][0] *= cam_width;
+      scale[1][1] *= cam_width / image_aspect;
+    }
+  }
+  else if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
+    /* Fit. */
+    if (image_aspect > cam_aspect) {
+      scale[0][0] *= cam_width;
+      scale[1][1] *= cam_width / image_aspect;
+    }
+    else {
+      scale[0][0] *= cam_height * image_aspect;
+      scale[1][1] *= cam_height;
+    }
+  }
+  else {
+    /* Stretch. */
+    scale[0][0] *= cam_width;
+    scale[1][1] *= cam_height;
+  }
+
+  translate[3][0] = bgpic->offset[0];
+  translate[3][1] = bgpic->offset[1];
+  translate[3][2] = cam_corners[0][2];
+  /* These lines are for keeping 2.80 behavior and could be removed to keep 2.79 behavior. */
+  translate[3][0] *= min_ff(1.0f, cam_aspect);
+  translate[3][1] /= max_ff(1.0f, cam_aspect) * (image_aspect / cam_aspect);
+  /* quad is -1..1 so divide by 2. */
+  scale[0][0] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0);
+  scale[1][1] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0);
+  /* Camera shift. (middle of cam_corners) */
+  translate[3][0] += (cam_corners[0][0] + cam_corners[2][0]) * 0.5f;
+  translate[3][1] += (cam_corners[0][1] + cam_corners[2][1]) * 0.5f;
+
+  mul_m4_series(rmat, translate, rotate, scale);
+}
+
 void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
 {
-  // OVERLAY_PrivateData *pd = vedata->stl->pd;
-  // DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->image_background);
-  // DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
-  // DRW_shgroup_call_obmat(grp, batch, NULL);
+  OVERLAY_PrivateData *pd = vedata->stl->pd;
+  OVERLAY_PassList *psl = vedata->psl;
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  Camera *cam = ob->data;
+
+  const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, draw_ctx->rv3d);
+
+  if (!show_frame || DRW_state_is_select()) {
+    return;
+  }
+
+  float norm_obmat[4][4];
+  normalize_m4_m4(norm_obmat, ob->obmat);
+
+  for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
+    if (bgpic->flag & CAM_BGIMG_FLAG_DISABLED) {
+      continue;
+    }
+
+    float aspect = 1.0;
+    bool use_alpha_premult;
+    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);
+
+    if (tex) {
+      image_camera_background_matrix_get(cam, bgpic, draw_ctx, aspect, mat);
+
+      mul_m4_m4m4(mat, norm_obmat, mat);
+
+      DRWPass *pass = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? psl->image_foreground_ps :
+                                                                  psl->image_background_ps;
+      GPUShader *sh = OVERLAY_shader_image();
+      DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+      float color[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
+      DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
+      DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
+      DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
+      DRW_shgroup_uniform_bool_copy(grp, "imgLinear", !DRW_state_do_color_management());
+      DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
+      DRW_shgroup_uniform_vec4_copy(grp, "color", color);
+      DRW_shgroup_call_obmat(grp, DRW_cache_empty_image_plane_get(), mat);
+    }
+  }
 }
 
 void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
@@ -182,4 +421,6 @@ void OVERLAY_image_draw(OVERLAY_Data *vedata)
 
   DRW_draw_pass(psl->image_empties_front_ps);
   DRW_draw_pass(psl->image_foreground_ps);
+
+  OVERLAY_image_free_movieclips_textures(vedata);
 }
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 6ed539419ca..6e0fb4bc86f 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engin

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list