diff options
Diffstat (limited to 'src/graphics/image.c')
-rw-r--r-- | src/graphics/image.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/graphics/image.c b/src/graphics/image.c new file mode 100644 index 0000000..430f03a --- /dev/null +++ b/src/graphics/image.c @@ -0,0 +1,67 @@ +#include "../../include/mgl/graphics/image.h" + +#define STBI_NO_PSD +#define STBI_NO_TGA +#define STBI_NO_HDR +#define STBI_NO_PIC +#define STBI_NO_PNM +#define STB_IMAGE_IMPLEMENTATION +#include "../../external/stb_image.h" + +static mgl_image_format stbi_format_to_mgl_image_format(int stbi_format) { + switch(stbi_format) { + case STBI_grey: + return MGL_IMAGE_FORMAT_GRAY; + case STBI_grey_alpha: + return MGL_IMAGE_FORMAT_GRAY_ALPHA; + case STBI_rgb: + return MGL_IMAGE_FORMAT_RGB; + case STBI_rgb_alpha: + return MGL_IMAGE_FORMAT_RGBA; + } + return 0; +} + +static size_t mgl_image_format_num_channels(mgl_image_format image_format) { + switch(image_format) { + case MGL_IMAGE_FORMAT_ALPHA: return 1; + case MGL_IMAGE_FORMAT_GRAY: return 1; + case MGL_IMAGE_FORMAT_GRAY_ALPHA: return 2; + case MGL_IMAGE_FORMAT_RGB: return 3; + case MGL_IMAGE_FORMAT_RGBA: return 4; + } + return 0; +} + +/* TODO: Ensure texture is power of 2 if the hardware doesn't support non power of two textures */ +/* TODO: Verify if source format should always be 4 components (RGBA) because apparently if its another format then opengl will internally convert it to RGBA */ +int mgl_image_load_from_file(mgl_image *self, const char *filepath) { + self->data = NULL; + self->width = 0; + self->height = 0; + + int format; + self->data = stbi_load(filepath, &self->width, &self->height, &format, 0); + if(!self->data) { + fprintf(stderr, "Error: failed to load image %s, error: %s\n", filepath, stbi_failure_reason()); + mgl_image_unload(self); + return -1; + } + self->format = stbi_format_to_mgl_image_format(format); + + return 0; +} + +void mgl_image_unload(mgl_image *self) { + if(self->data) { + stbi_image_free(self->data); + self->data = NULL; + } + self->width = 0; + self->height = 0; + self->format = 0; +} + +size_t mgl_image_get_size(mgl_image *self) { + return (size_t)self->width * (size_t)self->height * mgl_image_format_num_channels(self->format); +} |