Fix stereoscopy drawing for camera background
authorDalai Felinto <dalai@blender.org>
Thu, 12 Mar 2020 16:21:58 +0000 (17:21 +0100)
committerDalai Felinto <dalai@blender.org>
Fri, 13 Mar 2020 14:40:20 +0000 (15:40 +0100)
Part of the fix was to get gputexture to use an array to accomodate each
eye. This takes care of viewports showing individual Left or Right
views.

For the combined view the fix was in overlay_image.c:camera_background_images_stereo_setup.

Note 1: Referece images are still not supporting stereo.

Note 2: For painting, and getting image bindcode I'm hardcording a
single-view experience.

Note 3: Without D6922 stereo is too broken to even test this patch.
With D6922 + this patch the fullscreen modes work (anaglyph/interlace
not yet).

Differential Revision: D7143

source/blender/blenkernel/intern/image.c
source/blender/blenloader/intern/readfile.c
source/blender/draw/engines/overlay/overlay_image.c
source/blender/gpu/intern/gpu_draw.c
source/blender/makesdna/DNA_image_types.h
source/blender/makesrna/intern/rna_image.c

index 37e059774504ca36d5c5cef5cde15edefb1ca2da..22ec1fe1b98367575218477d990264f989554dff 100644 (file)
@@ -145,8 +145,10 @@ static void image_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
 
   BLI_duplicatelist(&image_dst->tiles, &image_src->tiles);
 
-  for (int i = 0; i < TEXTARGET_COUNT; i++) {
-    image_dst->gputexture[i] = NULL;
+  for (int eye = 0; eye < 2; eye++) {
+    for (int i = 0; i < TEXTARGET_COUNT; i++) {
+      image_dst->gputexture[i][eye] = NULL;
+    }
   }
 
   if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
@@ -529,9 +531,11 @@ bool BKE_image_scale(Image *image, int width, int height)
 
 bool BKE_image_has_opengl_texture(Image *ima)
 {
-  for (int i = 0; i < TEXTARGET_COUNT; i++) {
-    if (ima->gputexture[i] != NULL) {
-      return true;
+  for (int eye = 0; eye < 2; eye++) {
+    for (int i = 0; i < TEXTARGET_COUNT; i++) {
+      if (ima->gputexture[i][eye] != NULL) {
+        return true;
+      }
     }
   }
   return false;
@@ -3318,9 +3322,11 @@ static void image_free_tile(Image *ima, ImageTile *tile)
       continue;
     }
 
-    if (ima->gputexture[i] != NULL) {
-      GPU_texture_free(ima->gputexture[i]);
-      ima->gputexture[i] = NULL;
+    for (int eye = 0; eye < 2; eye++) {
+      if (ima->gputexture[i][eye] != NULL) {
+        GPU_texture_free(ima->gputexture[i][eye]);
+        ima->gputexture[i][eye] = NULL;
+      }
     }
   }
 
@@ -3587,14 +3593,16 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
     BLI_strncpy(tile->label, label, sizeof(tile->label));
   }
 
-  /* Reallocate GPU tile array. */
-  if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY] != NULL) {
-    GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY]);
-    ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY] = NULL;
-  }
-  if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING] != NULL) {
-    GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING]);
-    ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING] = NULL;
+  for (int eye = 0; eye < 2; eye++) {
+    /* Reallocate GPU tile array. */
+    if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] != NULL) {
+      GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye]);
+      ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] = NULL;
+    }
+    if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] != NULL) {
+      GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye]);
+      ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] = NULL;
+    }
   }
 
   return tile;
index dadae3a938afba34a667bdbe16312ed3e15a7b08..322abc2ec604899ed1dbe015f9882d8d276a2afb 100644 (file)
@@ -1891,9 +1891,11 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
     if (ima->cache) {
       oldnewmap_insert(fd->imamap, ima->cache, ima->cache, 0);
     }
-    for (a = 0; a < TEXTARGET_COUNT; a++) {
-      if (ima->gputexture[a] != NULL) {
-        oldnewmap_insert(fd->imamap, ima->gputexture[a], ima->gputexture[a], 0);
+    for (int eye = 0; eye < 2; eye++) {
+      for (a = 0; a < TEXTARGET_COUNT; a++) {
+        if (ima->gputexture[a][eye] != NULL) {
+          oldnewmap_insert(fd->imamap, ima->gputexture[a][eye], ima->gputexture[a][eye], 0);
+        }
       }
     }
     if (ima->rr) {
@@ -1937,8 +1939,10 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
     if (ima->cache == NULL) {
       ima->gpuflag = 0;
       ima->gpuframenr = INT_MAX;
-      for (i = 0; i < TEXTARGET_COUNT; i++) {
-        ima->gputexture[i] = NULL;
+      for (int eye = 0; eye < 2; eye++) {
+        for (i = 0; i < TEXTARGET_COUNT; i++) {
+          ima->gputexture[i][eye] = NULL;
+        }
       }
       ima->rr = NULL;
     }
@@ -1946,8 +1950,10 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
       slot->render = newimaadr(fd, slot->render);
     }
 
-    for (i = 0; i < TEXTARGET_COUNT; i++) {
-      ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
+    for (int eye = 0; eye < 2; eye++) {
+      for (i = 0; i < TEXTARGET_COUNT; i++) {
+        ima->gputexture[i][eye] = newimaadr(fd, ima->gputexture[i][eye]);
+      }
     }
     ima->rr = newimaadr(fd, ima->rr);
   }
@@ -4140,14 +4146,18 @@ static void direct_link_image(FileData *fd, Image *ima)
   if (!ima->cache) {
     ima->gpuflag = 0;
     ima->gpuframenr = INT_MAX;
-    for (int i = 0; i < TEXTARGET_COUNT; i++) {
-      ima->gputexture[i] = NULL;
+    for (int eye = 0; eye < 2; eye++) {
+      for (int i = 0; i < TEXTARGET_COUNT; i++) {
+        ima->gputexture[i][eye] = NULL;
+      }
     }
     ima->rr = NULL;
   }
   else {
-    for (int i = 0; i < TEXTARGET_COUNT; i++) {
-      ima->gputexture[i] = newimaadr(fd, ima->gputexture[i]);
+    for (int eye = 0; eye < 2; eye++) {
+      for (int i = 0; i < TEXTARGET_COUNT; i++) {
+        ima->gputexture[i][eye] = newimaadr(fd, ima->gputexture[i][eye]);
+      }
     }
     ima->rr = newimaadr(fd, ima->rr);
   }
index 8536c642cb68558b416320da1d7e391e53972f01..02f315e4e8ec397ff0fdf27ca5f828065383f3a2 100644 (file)
@@ -117,6 +117,9 @@ static void camera_background_images_stereo_setup(Scene *scene,
       /* show only left or right camera */
       iuser->multiview_eye = v3d->stereo3d_camera;
     }
+    else {
+      iuser->multiview_eye = v3d->multiview_eye;
+    }
 
     BKE_image_multiview_index(ima, iuser);
   }
index 33bc3ced5b28c19145cbcb350d0bdea9c90104e3..348b9dddba909bcf655682fe8b33b1d9dc084be4 100644 (file)
@@ -180,27 +180,28 @@ float GPU_get_anisotropic(void)
 
 /* Set OpenGL state for an MTFace */
 
-static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget)
+static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget, const int multiview_eye)
 {
   if (textarget == GL_TEXTURE_2D) {
-    return &ima->gputexture[TEXTARGET_TEXTURE_2D];
+    return &(ima->gputexture[TEXTARGET_TEXTURE_2D][multiview_eye]);
   }
   else if (textarget == GL_TEXTURE_CUBE_MAP) {
-    return &ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP];
+    return &(ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP][multiview_eye]);
   }
   else if (textarget == GL_TEXTURE_2D_ARRAY) {
-    return &ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY];
+    return &(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye]);
   }
   else if (textarget == GL_TEXTURE_1D_ARRAY) {
-    return &ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING];
+    return &(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][multiview_eye]);
   }
 
   return NULL;
 }
 
-static uint gpu_texture_create_tile_mapping(Image *ima)
+static uint gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
 {
-  GPUTexture *tilearray = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY];
+  GPUTexture *tilearray = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye];
+
   if (tilearray == NULL) {
     return 0;
   }
@@ -876,7 +877,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf,
   BKE_image_tag_time(ima);
 
   /* Test if we already have a texture. */
-  GPUTexture **tex = gpu_get_image_gputexture(ima, textarget);
+  GPUTexture **tex = gpu_get_image_gputexture(ima, textarget, iuser->multiview_eye);
   if (*tex) {
     return *tex;
   }
@@ -904,7 +905,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf,
     bindcode = gpu_texture_create_tile_array(ima, ibuf_intern);
   }
   else if (textarget == GL_TEXTURE_1D_ARRAY) {
-    bindcode = gpu_texture_create_tile_mapping(ima);
+    bindcode = gpu_texture_create_tile_mapping(ima, iuser->multiview_eye);
   }
   else {
     bindcode = gpu_texture_create_from_ibuf(ima, ibuf_intern, textarget);
@@ -1288,14 +1289,16 @@ void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
     for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
       if (BKE_image_has_opengl_texture(ima)) {
         if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
-          for (int a = 0; a < TEXTARGET_COUNT; a++) {
-            if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
-              GPUTexture *tex = ima->gputexture[a];
-              if (tex != NULL) {
-                GPU_texture_bind(tex, 0);
-                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
-                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
-                GPU_texture_unbind(tex);
+          for (int eye = 0; eye < 2; eye++) {
+            for (int a = 0; a < TEXTARGET_COUNT; a++) {
+              if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
+                GPUTexture *tex = ima->gputexture[a][eye];
+                if (tex != NULL) {
+                  GPU_texture_bind(tex, 0);
+                  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                  GPU_texture_unbind(tex);
+                }
               }
             }
           }
@@ -1312,14 +1315,16 @@ void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
   else {
     for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
       if (BKE_image_has_opengl_texture(ima)) {
-        for (int a = 0; a < TEXTARGET_COUNT; a++) {
-          if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
-            GPUTexture *tex = ima->gputexture[a];
-            if (tex != NULL) {
-              GPU_texture_bind(tex, 0);
-              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
-              GPU_texture_unbind(tex);
+        for (int eye = 0; eye < 2; eye++) {
+          for (int a = 0; a < TEXTARGET_COUNT; a++) {
+            if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
+              GPUTexture *tex = ima->gputexture[a][eye];
+              if (tex != NULL) {
+                GPU_texture_bind(tex, 0);
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
+                GPU_texture_unbind(tex);
+              }
             }
           }
         }
@@ -1343,14 +1348,14 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
     GPU_free_image(ima);
   }
 
-  GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D];
+  GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
   /* Check if we need to update the main gputexture. */
   if (tex != NULL && tile == ima->tiles.first) {
     gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
   }
 
   /* Check if we need to update the array gputexture. */
-  tex = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY];
+  tex = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][0];
   if (tex != NULL) {
     gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
   }
@@ -1395,11 +1400,13 @@ void GPU_free_unused_buffers(Main *bmain)
 
 static void gpu_free_image_immediate(Image *ima)
 {
-  for (int i = 0; i < TEXTARGET_COUNT; i++) {
-    /* free glsl image binding */
-    if (ima->gputexture[i] != NULL) {
-      GPU_texture_free(ima->gputexture[i]);
-      ima->gputexture[i] = NULL;
+  for (int eye = 0; eye < 2; eye++) {
+    for (int i = 0; i < TEXTARGET_COUNT; i++) {
+      /* free glsl image binding */
+      if (ima->gputexture[i][eye] != NULL) {
+        GPU_texture_free(ima->gputexture[i][eye]);
+        ima->gputexture[i][eye] = NULL;
+      }
     }
   }
 
index 03de4fb04739698d879af624863f7176a11bd221..d443d7806ad20fecc75a5dcdcc96495b3c1f8aff 100644 (file)
@@ -133,8 +133,8 @@ typedef struct Image {
 
   /** Not written in file. */
   struct MovieCache *cache;
-  /** Not written in file 4 = TEXTARGET_COUNT. */
-  struct GPUTexture *gputexture[4];
+  /** Not written in file 4 = TEXTARGET_COUNT, 2 = stereo eyes. */
+  struct GPUTexture *gputexture[4][2];
 
   /* sources from: */
   ListBase anims;
index b8174f094ecb98c86eefa04d23bcd8f357b0ea0d..8f2a841b55ca3a19907b7ea6874738c19e7279af 100644 (file)
@@ -398,7 +398,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
 static int rna_Image_bindcode_get(PointerRNA *ptr)
 {
   Image *ima = (Image *)ptr->data;
-  GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D];
+  GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
   return (tex) ? GPU_texture_opengl_bindcode(tex) : 0;
 }