3dphotoshoot

annotate src/texture.c @ 17:aef7f51f6397

resource loading works
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 10 Jun 2015 06:56:27 +0300
parents
children
rev   line source
nuclear@17 1 #include <stdio.h>
nuclear@17 2 #include <stdlib.h>
nuclear@17 3 #include <string.h>
nuclear@17 4 #include <errno.h>
nuclear@17 5 #include <assert.h>
nuclear@17 6 #include "opengl.h"
nuclear@17 7 #include "texture.h"
nuclear@17 8 #include "imago2.h"
nuclear@17 9 #include "rbtree.h"
nuclear@17 10 #include "assman.h"
nuclear@17 11
nuclear@17 12 static size_t ioread(void *buf, size_t bytes, void *uptr);
nuclear@17 13 static long ioseek(long offs, int whence, void *uptr);
nuclear@17 14 static unsigned int next_pow2(unsigned int x);
nuclear@17 15
nuclear@17 16 static struct rbtree *texdb;
nuclear@17 17
nuclear@17 18 int load_texture(struct texture *tex, const char *fname)
nuclear@17 19 {
nuclear@17 20 struct img_pixmap img;
nuclear@17 21 struct img_io io;
nuclear@17 22 ass_file *fp;
nuclear@17 23
nuclear@17 24 printf("loading texture: %s\n", fname);
nuclear@17 25
nuclear@17 26 if(!(fp = ass_fopen(fname, "rb"))) {
nuclear@17 27 fprintf(stderr, "failed to open texture file: %s: %s\n", fname, strerror(errno));
nuclear@17 28 return -1;
nuclear@17 29 }
nuclear@17 30 io.uptr = fp;
nuclear@17 31 io.read = ioread;
nuclear@17 32 io.write = 0;
nuclear@17 33 io.seek = ioseek;
nuclear@17 34
nuclear@17 35 img_init(&img);
nuclear@17 36 if(img_read(&img, &io) == -1) {
nuclear@17 37 fprintf(stderr, "failed to load texture file: %s\n", fname);
nuclear@17 38 ass_fclose(fp);
nuclear@17 39 return -1;
nuclear@17 40 }
nuclear@17 41 img_convert(&img, IMG_FMT_RGBA32);
nuclear@17 42
nuclear@17 43 tex->img_width = img.width;
nuclear@17 44 tex->img_height = img.height;
nuclear@17 45 tex->width = next_pow2(img.width);
nuclear@17 46 tex->height = next_pow2(img.height);
nuclear@17 47
nuclear@17 48 printf(" %dx%d (tex: %dx%d)\n", tex->img_width, tex->img_height, tex->width, tex->height);
nuclear@17 49
nuclear@17 50 glGenTextures(1, &tex->texid);
nuclear@17 51 glBindTexture(GL_TEXTURE_2D, tex->texid);
nuclear@17 52 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
nuclear@17 53 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@17 54
nuclear@17 55 #ifdef __GLEW_H__
nuclear@17 56 if(GLEW_SGIS_generate_mipmap) {
nuclear@17 57 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
nuclear@17 58 #endif
nuclear@17 59 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0,
nuclear@17 60 GL_RGBA, GL_UNSIGNED_BYTE, img.pixels);
nuclear@17 61 #ifdef __GLEW_H__
nuclear@17 62 } else {
nuclear@17 63 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tex->width, tex->height,
nuclear@17 64 GL_RGBA, GL_UNSIGNED_BYTE, img.pixels);
nuclear@17 65 }
nuclear@17 66 #endif
nuclear@17 67
nuclear@17 68 #ifdef GL_ES_VERSION_2_0
nuclear@17 69 glGenerateMipmap(GL_TEXTURE_2D);
nuclear@17 70 #endif
nuclear@17 71
nuclear@17 72 return 0;
nuclear@17 73 }
nuclear@17 74
nuclear@17 75 struct texture *get_texture(const char *fname)
nuclear@17 76 {
nuclear@17 77 struct texture *tex;
nuclear@17 78 struct rbnode *node;
nuclear@17 79
nuclear@17 80 if(!(texdb = rb_create(RB_KEY_STRING))) {
nuclear@17 81 static int err_printed;
nuclear@17 82 if(!err_printed) {
nuclear@17 83 fprintf(stderr, "failed to create texture database\n");
nuclear@17 84 err_printed = 1;
nuclear@17 85 }
nuclear@17 86 return 0;
nuclear@17 87 }
nuclear@17 88
nuclear@17 89 if((node = rb_find(texdb, (void*)fname))) {
nuclear@17 90 return rb_node_data(node);
nuclear@17 91 }
nuclear@17 92
nuclear@17 93 if(!(tex = malloc(sizeof *tex))) {
nuclear@17 94 fprintf(stderr, "failed to load texture \"%s\": %s\n", fname, strerror(errno));
nuclear@17 95 return 0;
nuclear@17 96 }
nuclear@17 97 if(load_texture(tex, fname) == -1) {
nuclear@17 98 free(tex);
nuclear@17 99 return 0;
nuclear@17 100 }
nuclear@17 101
nuclear@17 102 if(rb_insert(texdb, (void*)fname, tex) == -1) {
nuclear@17 103 fprintf(stderr, "failed to insert texture into the texture database\n");
nuclear@17 104 }
nuclear@17 105 return tex;
nuclear@17 106 }
nuclear@17 107
nuclear@17 108
nuclear@17 109 #define DBG_TEX_SZ 64
nuclear@17 110 int gen_debug_texture(struct texture *tex)
nuclear@17 111 {
nuclear@17 112 static unsigned char *pixels;
nuclear@17 113
nuclear@17 114 if(!pixels) {
nuclear@17 115 int i, j;
nuclear@17 116 unsigned char *pptr;
nuclear@17 117 pptr = pixels = malloc(DBG_TEX_SZ * DBG_TEX_SZ * 4);
nuclear@17 118 assert(pixels);
nuclear@17 119
nuclear@17 120 for(i=0; i<DBG_TEX_SZ; i++) {
nuclear@17 121 for(j=0; j<DBG_TEX_SZ; j++) {
nuclear@17 122 int chess = ((j >> 3) & 1) == ((i >> 3) & 1);
nuclear@17 123 *pptr++ = chess ? 255 : 64;
nuclear@17 124 *pptr++ = 128;
nuclear@17 125 *pptr++ = chess ? 64 : 255;
nuclear@17 126 *pptr++ = 255; /* alpha */
nuclear@17 127 }
nuclear@17 128 }
nuclear@17 129 }
nuclear@17 130
nuclear@17 131 if(!tex->texid) {
nuclear@17 132 glGenTextures(1, &tex->texid);
nuclear@17 133 }
nuclear@17 134
nuclear@17 135 glBindTexture(GL_TEXTURE_2D, tex->texid);
nuclear@17 136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@17 137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@17 138 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DBG_TEX_SZ, DBG_TEX_SZ, 0, GL_RGBA,
nuclear@17 139 GL_UNSIGNED_BYTE, pixels);
nuclear@17 140
nuclear@17 141 tex->width = tex->img_width = tex->height = tex->img_height = DBG_TEX_SZ;
nuclear@17 142 return 0;
nuclear@17 143 }
nuclear@17 144
nuclear@17 145
nuclear@17 146 static size_t ioread(void *buf, size_t bytes, void *uptr)
nuclear@17 147 {
nuclear@17 148 return ass_fread(buf, 1, bytes, uptr);
nuclear@17 149 }
nuclear@17 150
nuclear@17 151 static long ioseek(long offs, int whence, void *uptr)
nuclear@17 152 {
nuclear@17 153 return ass_fseek(uptr, offs, whence);
nuclear@17 154 }
nuclear@17 155
nuclear@17 156 static unsigned int next_pow2(unsigned int x)
nuclear@17 157 {
nuclear@17 158 x--;
nuclear@17 159 x = (x >> 1) | x;
nuclear@17 160 x = (x >> 2) | x;
nuclear@17 161 x = (x >> 4) | x;
nuclear@17 162 x = (x >> 8) | x;
nuclear@17 163 x = (x >> 16) | x;
nuclear@17 164 return x + 1;
nuclear@17 165 }