#define STB_IMAGE_IMPLEMENTATION // #define STBI_NO_JPEG // #define STBI_NO_PNG #define STBI_NO_BMP #define STBI_NO_PSD #define STBI_NO_TGA #define STBI_NO_GIF #define STBI_NO_HDR #define STBI_NO_PIC #define STBI_NO_PNM #include "commons/commons_stb_image.h" static uint8_t* Image_Load(const char* filename, uint32_t* width, uint32_t* height, uint32_t* channels) { // should be good enough because release version will anyway use gpu optimized textures which are much easier to decode int x, y, n; unsigned char* data = stbi_load(filename, &x, &y, &n, 0); if (!data) ASSERT(false, "stbi failed: %s", stbi_failure_reason()); *width = x; *height = y; *channels = n; return data; } static void LoadTexture(rhi_cmdlist cmd, const char* name, const char* path) { uint64_t TextureId = HashBytes64(name, strlen(name)); uint64_t lo = 0; for (uint64_t hi = Game->TexturesCount; lo < hi; ) { uint32_t mid = lo + (hi - lo) / 2; DASSERT(Game->Textures[mid].id != TextureId, "hash collision"); if (Game->Textures[mid].id < TextureId) lo = mid + 1; else hi = mid; } texture_data* Texture = INSERT(Game->Textures, COUNT(Game->Textures), Game->TexturesCount, lo); Texture->id = TextureId; uint8_t* pixelData = Image_Load(path, &Texture->width, &Texture->height, &Texture->channels); uint64_t pixelDataSize = Texture->width * Texture->height * Texture->channels; Texture->GpuTextureFormat = B8G8R8A8_sRGB; Texture->Texture = Rhi_CreateTexture(name, Texture->width, Texture->height, MemoryUsage_GpuOnly, (rhi_texture_usage)(TextureUsage_TransferSrc | TextureUsage_TransferDst | TextureUsage_ShaderSampled), Texture->GpuTextureFormat); char* viewName = PUSH_ALLOC(&PermanentAlloc, char, strlen(name) + strlen("View")); memcpy(viewName + strlen(name), "View", strlen("View")); Texture->TextureView = Rhi_CreateSampledTextureView(viewName, Texture->Texture, TextureFormatNone); Rhi_CmdTransitionTexture(cmd, Texture->Texture, TextureState_TransferDst); uint8_t* uploadMemory = GpuCmdCopyTexture(cmd, Texture->Texture, pixelDataSize); memcpy(uploadMemory, pixelData, pixelDataSize); // TODO: this is suboptimal - move to where it's used Rhi_CmdTransitionTexture(cmd, Texture->Texture, TextureState_ShaderRead); }