diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-10-10 17:29:31 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-10-10 17:29:31 +0200 |
commit | 4aa7273eea642bff78477b0b220c7056628b13a8 (patch) | |
tree | 014430c208905164f99b37d663944192b8d6fd8c /src/graphics | |
parent | b81aff95e7924c38dbd1cf639011be1848af6967 (diff) |
Add texture loading (and render in test)
Diffstat (limited to 'src/graphics')
-rw-r--r-- | src/graphics/texture.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/graphics/texture.c b/src/graphics/texture.c new file mode 100644 index 0000000..3d3ea6f --- /dev/null +++ b/src/graphics/texture.c @@ -0,0 +1,71 @@ +#include "../../include/mgl/graphics/texture.h" +#include "../../include/mgl/mgl.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 int mgl_texture_format_to_opengl_format(mgl_texture_format format) { + switch(format) { + case MGL_TEXTURE_GRAY: return GL_LUMINANCE8; + case MGL_TEXTURE_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_RGB: return GL_RGB8; + case MGL_TEXTURE_RGB_ALPHA: return GL_RGBA8; + } + return 0; +} + +static int mgl_texture_format_to_source_opengl_format(mgl_texture_format format) { + switch(format) { + case MGL_TEXTURE_GRAY: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_RGB: return GL_RGB; + case MGL_TEXTURE_RGB_ALPHA: return GL_RGBA; + } + return 0; +} + +/* TODO: Ensure texture is power of 2 if the hardware doesn't support non power of two textures */ +int mgl_texture_load_from_file(mgl_texture *self, const char *filepath) { + self->id = 0; + + int format; + stbi_uc *image_data = stbi_load(filepath, &self->width, &self->height, &format, 0); + if(!image_data) { + fprintf(stderr, "Error: failed to load image %s, error: %s\n", filepath, stbi_failure_reason()); + return -1; + } + self->format = format; + + mgl_context *context = mgl_get_context(); + context->gl.glGenTextures(1, &self->id); + if(self->id == 0) { + stbi_image_free(image_data); + return -1; + } + + const int opengl_texture_format = mgl_texture_format_to_opengl_format(self->format); + + context->gl.glBindTexture(GL_TEXTURE_2D, self->id); + context->gl.glTexImage2D(GL_TEXTURE_2D, 0, opengl_texture_format, self->width, self->height, 0, mgl_texture_format_to_source_opengl_format(self->format), GL_UNSIGNED_BYTE, image_data); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + context->gl.glBindTexture(GL_TEXTURE_2D, 0); + + stbi_image_free(image_data); + return 0; +} + +void mgl_texture_unload(mgl_texture *self) { + mgl_context *context = mgl_get_context(); + if(self->id) { + context->gl.glDeleteTextures(1, &self->id); + self->id = 0; + } +} |