3dphotoshoot
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/texture.c Wed Jun 10 06:56:27 2015 +0300 1.3 @@ -0,0 +1,165 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <errno.h> 1.8 +#include <assert.h> 1.9 +#include "opengl.h" 1.10 +#include "texture.h" 1.11 +#include "imago2.h" 1.12 +#include "rbtree.h" 1.13 +#include "assman.h" 1.14 + 1.15 +static size_t ioread(void *buf, size_t bytes, void *uptr); 1.16 +static long ioseek(long offs, int whence, void *uptr); 1.17 +static unsigned int next_pow2(unsigned int x); 1.18 + 1.19 +static struct rbtree *texdb; 1.20 + 1.21 +int load_texture(struct texture *tex, const char *fname) 1.22 +{ 1.23 + struct img_pixmap img; 1.24 + struct img_io io; 1.25 + ass_file *fp; 1.26 + 1.27 + printf("loading texture: %s\n", fname); 1.28 + 1.29 + if(!(fp = ass_fopen(fname, "rb"))) { 1.30 + fprintf(stderr, "failed to open texture file: %s: %s\n", fname, strerror(errno)); 1.31 + return -1; 1.32 + } 1.33 + io.uptr = fp; 1.34 + io.read = ioread; 1.35 + io.write = 0; 1.36 + io.seek = ioseek; 1.37 + 1.38 + img_init(&img); 1.39 + if(img_read(&img, &io) == -1) { 1.40 + fprintf(stderr, "failed to load texture file: %s\n", fname); 1.41 + ass_fclose(fp); 1.42 + return -1; 1.43 + } 1.44 + img_convert(&img, IMG_FMT_RGBA32); 1.45 + 1.46 + tex->img_width = img.width; 1.47 + tex->img_height = img.height; 1.48 + tex->width = next_pow2(img.width); 1.49 + tex->height = next_pow2(img.height); 1.50 + 1.51 + printf(" %dx%d (tex: %dx%d)\n", tex->img_width, tex->img_height, tex->width, tex->height); 1.52 + 1.53 + glGenTextures(1, &tex->texid); 1.54 + glBindTexture(GL_TEXTURE_2D, tex->texid); 1.55 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 1.56 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.57 + 1.58 +#ifdef __GLEW_H__ 1.59 + if(GLEW_SGIS_generate_mipmap) { 1.60 + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); 1.61 +#endif 1.62 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, 1.63 + GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); 1.64 +#ifdef __GLEW_H__ 1.65 + } else { 1.66 + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tex->width, tex->height, 1.67 + GL_RGBA, GL_UNSIGNED_BYTE, img.pixels); 1.68 + } 1.69 +#endif 1.70 + 1.71 +#ifdef GL_ES_VERSION_2_0 1.72 + glGenerateMipmap(GL_TEXTURE_2D); 1.73 +#endif 1.74 + 1.75 + return 0; 1.76 +} 1.77 + 1.78 +struct texture *get_texture(const char *fname) 1.79 +{ 1.80 + struct texture *tex; 1.81 + struct rbnode *node; 1.82 + 1.83 + if(!(texdb = rb_create(RB_KEY_STRING))) { 1.84 + static int err_printed; 1.85 + if(!err_printed) { 1.86 + fprintf(stderr, "failed to create texture database\n"); 1.87 + err_printed = 1; 1.88 + } 1.89 + return 0; 1.90 + } 1.91 + 1.92 + if((node = rb_find(texdb, (void*)fname))) { 1.93 + return rb_node_data(node); 1.94 + } 1.95 + 1.96 + if(!(tex = malloc(sizeof *tex))) { 1.97 + fprintf(stderr, "failed to load texture \"%s\": %s\n", fname, strerror(errno)); 1.98 + return 0; 1.99 + } 1.100 + if(load_texture(tex, fname) == -1) { 1.101 + free(tex); 1.102 + return 0; 1.103 + } 1.104 + 1.105 + if(rb_insert(texdb, (void*)fname, tex) == -1) { 1.106 + fprintf(stderr, "failed to insert texture into the texture database\n"); 1.107 + } 1.108 + return tex; 1.109 +} 1.110 + 1.111 + 1.112 +#define DBG_TEX_SZ 64 1.113 +int gen_debug_texture(struct texture *tex) 1.114 +{ 1.115 + static unsigned char *pixels; 1.116 + 1.117 + if(!pixels) { 1.118 + int i, j; 1.119 + unsigned char *pptr; 1.120 + pptr = pixels = malloc(DBG_TEX_SZ * DBG_TEX_SZ * 4); 1.121 + assert(pixels); 1.122 + 1.123 + for(i=0; i<DBG_TEX_SZ; i++) { 1.124 + for(j=0; j<DBG_TEX_SZ; j++) { 1.125 + int chess = ((j >> 3) & 1) == ((i >> 3) & 1); 1.126 + *pptr++ = chess ? 255 : 64; 1.127 + *pptr++ = 128; 1.128 + *pptr++ = chess ? 64 : 255; 1.129 + *pptr++ = 255; /* alpha */ 1.130 + } 1.131 + } 1.132 + } 1.133 + 1.134 + if(!tex->texid) { 1.135 + glGenTextures(1, &tex->texid); 1.136 + } 1.137 + 1.138 + glBindTexture(GL_TEXTURE_2D, tex->texid); 1.139 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.140 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.141 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DBG_TEX_SZ, DBG_TEX_SZ, 0, GL_RGBA, 1.142 + GL_UNSIGNED_BYTE, pixels); 1.143 + 1.144 + tex->width = tex->img_width = tex->height = tex->img_height = DBG_TEX_SZ; 1.145 + return 0; 1.146 +} 1.147 + 1.148 + 1.149 +static size_t ioread(void *buf, size_t bytes, void *uptr) 1.150 +{ 1.151 + return ass_fread(buf, 1, bytes, uptr); 1.152 +} 1.153 + 1.154 +static long ioseek(long offs, int whence, void *uptr) 1.155 +{ 1.156 + return ass_fseek(uptr, offs, whence); 1.157 +} 1.158 + 1.159 +static unsigned int next_pow2(unsigned int x) 1.160 +{ 1.161 + x--; 1.162 + x = (x >> 1) | x; 1.163 + x = (x >> 2) | x; 1.164 + x = (x >> 4) | x; 1.165 + x = (x >> 8) | x; 1.166 + x = (x >> 16) | x; 1.167 + return x + 1; 1.168 +}