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 +}