aboutsummaryrefslogtreecommitdiff
path: root/src/graphics/texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/texture.c')
-rw-r--r--src/graphics/texture.c71
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;
+ }
+}