Closed ghost closed 1 year ago
As far as I know, the above function as written will never cause the image to be flipped unless (a) you're manipulating stbi_set_flip_vertically_on_load
or (b) you have a memory write error and are randomly writing into the variable set by stbi_set_flip_vertically_on_load
. Without knowing more info, it's impossible to know if this is a bug in stb_image or a bug in your code.
I found that using stbi_set_flip_vertically_on_load(0)
and stbi_set_flip_vertically_on_load_thread(0)
before stbi_load_from_memory
will not randomly flip the texture.
#define STB_IMAGE_IMPLEMENTATION
#define STBI_NO_STDIO
#define STBI_ONLY_JPEG
#define STBI_ONLY_PNG
#include "stb_image.h"
...
stbi_set_flip_vertically_on_load(0);
stbi_set_flip_vertically_on_load_thread(0);
unsigned char* image_data = stbi_load_from_memory(buffer, buffer_size, &image_width, &image_height, NULL, 4);
But if I don't add these codes, the texture is randomly flipped.
Both of those default to 0. So most likely you're either using another library that is using stb_image and setting that value, or you're randomly trashing memory.
Either way it seems unlikely to be a bug in stb_image, so I'm closing this issue, but you can continue to post here if you gather additional data.
I pointed the user over here from the Dear ImGui issue where they first reported the problem. There I suggested this as a further avenue of investigation:
If it's varying per-run, a wild guess is that the code might be expecting thread-local variables to be zero-initialized but your platform's thread-local variables might not give that guarantee, or it might differ based on whether your STB_IMAGE_IMPLEMENTATION inclusion is in a C or C++ source file.
It would be interesting if @git-xiaocao could tell more about what platform and compiler this is and which implementation of STBI_THREAD_LOCAL
is used there. While the workarounds are likely sufficient to mask the problem, there's definitely an underlying problem at hand, may it be overwritten variables or insufficient platform guarantees.
It might also be worthwhile to inspect it in a debugger to see what values the three implementation variables have in runs without the workarounds - that would help to tell if they seem to be legitimately set or have indeterminate or overwritten values.
I used stb_image
like this before.
#include "imgui/imgui.h"
#include "imgui/imgui_impl_win32.h"
#include "imgui/imgui_impl_dx11.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
bool LoadTextureFromMemory(unsigned char* buffer, unsigned int buffer_size, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height)
{
// Load from memory into a raw RGBA buffer
int image_width = 0;
int image_height = 0;
unsigned char* image_data = stbi_load_from_memory(buffer, buffer_size, &image_width, &image_height, NULL, 4);
if (image_data == NULL)
return false;
// Create texture
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = image_width;
desc.Height = image_height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D* pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = image_data;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
if (device->CreateTexture2D(&desc, &subResource, &pTexture) != S_OK)
{
*out_width = 0;
*out_height = 0;
stbi_image_free(image_data);
return false;
}
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
device->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
pTexture->Release();
*out_width = image_width;
*out_height = image_height;
stbi_image_free(image_data);
return true;
}
Dear ImGui Platform see include header file.
Development Platform is Visual Studio 2022
MSVC
C++17
Windows 11 SDK 10.0.22621.0
The texture orientation that this code loads from memory is random, restarting the program multiple times will see the texture facing a different orientation (flipped)
https://github.com/ocornut/imgui/issues/6530