#define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" texture_t load_texture(arena_t *arena, const char *filename, i32 gamma) { texture_t texture = {0}; i32 nchannels; stbi_set_flip_vertically_on_load(1); u8 *data = stbi_load(filename, &texture.width, &texture.height, &nchannels, 0); if (!data) { printf("error: \"%s\" failed to load\n", filename); return texture; } u32 internal_format, data_format; switch (nchannels) { case 1: texture.type = texture_type_r; internal_format = data_format = GL_RED; break; case 3: texture.type = texture_type_rgb; internal_format = gamma ? GL_SRGB : GL_RGB; data_format = GL_RGB; break; case 4: texture.type = texture_type_rgba; internal_format = gamma ? GL_SRGB_ALPHA : GL_RGBA; data_format = GL_RGBA; break; default: printf("error: \"%s\" unsupported type\n", filename); goto end; } u64 size = texture.type * texture.width * texture.height; texture.data = push_arena(arena, size); prb_memmove(texture.data, data, size); glGenTextures(1, &texture.id); glBindTexture(GL_TEXTURE_2D, texture.id); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, data_format, GL_UNSIGNED_BYTE, texture.data); glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); printf("info: \"%s\" loaded successfully\n", filename); end: stbi_image_free(data); return texture; }