textures, overlay images, libimago
[demo_prior] / src / texture.c
diff --git a/src/texture.c b/src/texture.c
new file mode 100644 (file)
index 0000000..c0a80b2
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "opengl.h"
+#include "texture.h"
+#include "imago2.h"
+#include "opt.h"
+
+static unsigned int gl_ifmt[2][NUM_IMG_FMT] = {
+       /* opt.srgb == 0 */
+       {GL_LUMINANCE, GL_RGB, GL_RGBA, GL_LUMINANCE16F_ARB, GL_RGB16F, GL_RGBA16F, GL_RGBA, GL_RGB},
+       /* opt.srgb == 1 */
+       {GL_SLUMINANCE, GL_SRGB, GL_SRGB_ALPHA, GL_LUMINANCE16F_ARB, GL_RGB16F, GL_RGBA16F, GL_SRGB_ALPHA, GL_SRGB}
+};
+static unsigned int gl_fmt[] = {
+       GL_LUMINANCE, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_RGB, GL_RGBA, GL_BGRA, GL_RGB
+};
+static unsigned int gl_type[] = {
+       GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5
+};
+
+struct texture *load_texture(const char *fname)
+{
+       struct img_pixmap img;
+       struct texture *tex;
+       int ifmt;
+
+       img_init(&img);
+       if(img_load(&img, fname) == -1) {
+               fprintf(stderr, "failed to load texture: %s\n", fname);
+               return 0;
+       }
+       ifmt = gl_ifmt[opt.srgb][img.fmt];
+
+       if(!(tex = malloc(sizeof *tex))) {
+               img_destroy(&img);
+               fprintf(stderr, "failed to allocate texture\n");
+               return 0;
+       }
+
+       glGenTextures(1, &tex->id);
+       glBindTexture(GL_TEXTURE_2D, tex->id);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
+       glTexImage2D(GL_TEXTURE_2D, 0, ifmt, img.width, img.height, 0, gl_fmt[img.fmt],
+                       gl_type[img.fmt], img.pixels);
+
+       tex->width = img.width;
+       tex->height = img.height;
+       tex->pixels = img.pixels;
+       return tex;
+}
+
+void free_texture(struct texture *tex)
+{
+       if(!tex) return;
+
+       if(tex->id) {
+               glDeleteTextures(1, &tex->id);
+       }
+
+       free(tex->pixels);
+       free(tex);
+}