Page MenuHome

Image Empty: Wrong aspect ratio if Texture Size Limit is used
Closed, ResolvedPublic

Description

System Information
Operating system: Windows 10 64 bit
Graphics card: Nvidia GTX 750 Ti

Blender Version
Broken: blender-2.80.0-git.81b68f7279cd-windows64
Working: 2.79

Short description of error
Reference Images have the wrong aspect ratio, if the Limit Size in the user preferences is set lower than the longest side of the image.

Exact steps for others to reproduce the error


Set the Limit Size in the user preferences, under Viewport > Textures to a value greater or less than 1024.
With values greater or equal to 1024, the reference image is rectangular.
With values less than 1024 the image becomes square.

Optionally, file working in Blender 2.79

Event Timeline

Dalai Felinto (dfelinto) renamed this task from Reference Image Aspect Ratio Wrong If Texture Size Limit Is Used to Image Empty: Wrong aspect ratio if Texture Size Limit is used.Jun 14 2019, 8:31 PM
Dalai Felinto (dfelinto) lowered the priority of this task from Needs Triage by Developer to Normal.
Dalai Felinto (dfelinto) updated the task description. (Show Details)

Confirmed. And in 2.79 it was working fine.

Actually although 2.79 doesn't have *this* issue, it is clearly not reducing the texture limit, which is why this works.

Dalai Felinto (dfelinto) triaged this task as Confirmed, Medium priority.

@Campbell Barton (campbellbarton) we have a problem here.

Manually reverting rB9e82499d2d1c (i.e., P1005) would fix this, but the original bug (T59347) comes back.

It's not great that we cant access the size of a loaded texture without freeing the previously loaded textures.
AFAICS supporting this would mean larger changes to the image API.

Looked into storing the original size of the GPUTexture before it's clamped.

Here are two patches that do this, I'm thinking the first one is probably better since:

  • It doesn't store more data in DNA.
  • It doesn't risk values becoming out-of-sync.
  • 1diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
    2index e8c600ee545..1fb56f2f072 100644
    3--- a/source/blender/draw/modes/object_mode.c
    4+++ b/source/blender/draw/modes/object_mode.c
    5@@ -979,8 +979,8 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
    6 if (ima != NULL) {
    7 tex = GPU_texture_from_blender(ima, ob->iuser, GL_TEXTURE_2D);
    8 if (tex) {
    9- size[0] = GPU_texture_width(tex);
    10- size[1] = GPU_texture_height(tex);
    11+ size[0] = GPU_texture_orig_width(tex);
    12+ size[1] = GPU_texture_orig_height(tex);
    13 }
    14 }
    15
    16diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
    17index 3fb7dfc6331..c798788724f 100644
    18--- a/source/blender/gpu/GPU_texture.h
    19+++ b/source/blender/gpu/GPU_texture.h
    20@@ -237,6 +237,9 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, struct GPUFrameBuffer *fb);
    21 int GPU_texture_target(const GPUTexture *tex);
    22 int GPU_texture_width(const GPUTexture *tex);
    23 int GPU_texture_height(const GPUTexture *tex);
    24+int GPU_texture_orig_width(const GPUTexture *tex);
    25+int GPU_texture_orig_height(const GPUTexture *tex);
    26+void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h);
    27 int GPU_texture_layers(const GPUTexture *tex);
    28 eGPUTextureFormat GPU_texture_format(const GPUTexture *tex);
    29 int GPU_texture_samples(const GPUTexture *tex);
    30diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
    31index 7813ae68371..e48f14a6894 100644
    32--- a/source/blender/gpu/intern/gpu_draw.c
    33+++ b/source/blender/gpu/intern/gpu_draw.c
    34@@ -469,6 +469,9 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
    35 BKE_image_release_ibuf(ima, ibuf, NULL);
    36
    37 *tex = GPU_texture_from_bindcode(textarget, bindcode);
    38+
    39+ GPU_texture_orig_size_set(*tex, ibuf->x, ibuf->y);
    40+
    41 return *tex;
    42 }
    43
    44diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
    45index 58d0dd5576f..54e93c361ca 100644
    46--- a/source/blender/gpu/intern/gpu_texture.c
    47+++ b/source/blender/gpu/intern/gpu_texture.c
    48@@ -68,6 +68,7 @@ typedef enum eGPUTextureFormatFlag {
    49 /* GPUTexture */
    50 struct GPUTexture {
    51 int w, h, d; /* width/height/depth */
    52+ int orig_w, orig_h; /* width/height (of source data), optional. */
    53 int number; /* number for multitexture binding */
    54 int refcount; /* reference count */
    55 GLenum target; /* GL_TEXTURE_* */
    56@@ -1778,6 +1779,22 @@ int GPU_texture_height(const GPUTexture *tex)
    57 return tex->h;
    58 }
    59
    60+int GPU_texture_orig_width(const GPUTexture *tex)
    61+{
    62+ return tex->orig_w;
    63+}
    64+
    65+int GPU_texture_orig_height(const GPUTexture *tex)
    66+{
    67+ return tex->orig_h;
    68+}
    69+
    70+void GPU_texture_orig_size_set(GPUTexture *tex, int w, int h)
    71+{
    72+ tex->orig_w = w;
    73+ tex->orig_h = h;
    74+}
    75+
    76 int GPU_texture_layers(const GPUTexture *tex)
    77 {
    78 return tex->d;
  • 1diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
    2index e8c600ee545..1ee23c95d38 100644
    3--- a/source/blender/draw/modes/object_mode.c
    4+++ b/source/blender/draw/modes/object_mode.c
    5@@ -979,8 +979,9 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
    6 if (ima != NULL) {
    7 tex = GPU_texture_from_blender(ima, ob->iuser, GL_TEXTURE_2D);
    8 if (tex) {
    9- size[0] = GPU_texture_width(tex);
    10- size[1] = GPU_texture_height(tex);
    11+ const int *gpu_size = ima->gputexture_orig_size[TEXTARGET_TEXTURE_2D];
    12+ size[0] = gpu_size[0];
    13+ size[1] = gpu_size[1];
    14 }
    15 }
    16
    17diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
    18index 7813ae68371..8a7f9ade969 100644
    19--- a/source/blender/gpu/intern/gpu_draw.c
    20+++ b/source/blender/gpu/intern/gpu_draw.c
    21@@ -196,16 +196,15 @@ float GPU_get_anisotropic(void)
    22
    23 /* Set OpenGL state for an MTFace */
    24
    25-static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget)
    26+static int gpu_get_index_from_textarget(GLenum textarget)
    27 {
    28 if (textarget == GL_TEXTURE_2D) {
    29- return &ima->gputexture[TEXTARGET_TEXTURE_2D];
    30+ return TEXTARGET_TEXTURE_2D;
    31 }
    32 else if (textarget == GL_TEXTURE_CUBE_MAP) {
    33- return &ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP];
    34+ return TEXTARGET_TEXTURE_CUBE_MAP;
    35 }
    36-
    37- return NULL;
    38+ return -1;
    39 }
    40
    41 static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
    42@@ -443,12 +442,23 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
    43 ima->gpuflag &= ~IMA_GPU_REFRESH;
    44 }
    45
    46+ const int tex_index = gpu_get_index_from_textarget(textarget);
    47+ if (tex_index == -1) {
    48+ BLI_assert(0);
    49+ return NULL;
    50+ }
    51+
    52 /* Test if we already have a texture. */
    53- GPUTexture **tex = gpu_get_image_gputexture(ima, textarget);
    54+ GPUTexture **tex = &(ima->gputexture[tex_index]);
    55 if (*tex) {
    56 return *tex;
    57 }
    58
    59+ int *gputexture_orig_size = ima->gputexture_orig_size[tex_index];
    60+
    61+ gputexture_orig_size[0] = 0;
    62+ gputexture_orig_size[1] = 0;
    63+
    64 /* Check if we have a valid image. If not, we return a dummy
    65 * texture with zero bindcode so we don't keep trying. */
    66 uint bindcode = 0;
    67@@ -469,6 +479,10 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget
    68 BKE_image_release_ibuf(ima, ibuf, NULL);
    69
    70 *tex = GPU_texture_from_bindcode(textarget, bindcode);
    71+
    72+ gputexture_orig_size[0] = ibuf->x;
    73+ gputexture_orig_size[1] = ibuf->y;
    74+
    75 return *tex;
    76 }
    77
    78diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
    79index 5e4ed16d28e..6b4bcec6057 100644
    80--- a/source/blender/makesdna/DNA_image_types.h
    81+++ b/source/blender/makesdna/DNA_image_types.h
    82@@ -112,6 +112,9 @@ typedef struct Image {
    83 /** Not written in file 2 = TEXTARGET_COUNT. */
    84 struct GPUTexture *gputexture[2];
    85
    86+ /** 2 = TEXTARGET_COUNT. */
    87+ int gputexture_orig_size[2][2];
    88+
    89 /* sources from: */
    90 ListBase anims;
    91 struct RenderResult *rr;

First patch seems less intrusive as well +1 for it imho.