volray

changeset 8:ae10631bb11b

cleaning up a bit to expand
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 07 Apr 2012 16:07:12 +0300
parents f40e4edfee7e
children a6765984e057
files .hgignore src/volume.c src/volume.h volray.p.glsl
diffstat 4 files changed, 187 insertions(+), 6 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sat Apr 07 16:07:12 2012 +0300
     1.3 @@ -0,0 +1,5 @@
     1.4 +^volray$
     1.5 +\.o$
     1.6 +\.d$
     1.7 +\.swp$
     1.8 +^data
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/volume.c	Sat Apr 07 16:07:12 2012 +0300
     2.3 @@ -0,0 +1,162 @@
     2.4 +#include <stdio.h>
     2.5 +#include <stdlib.h>
     2.6 +#include <string.h>
     2.7 +#include <ctype.h>
     2.8 +
     2.9 +#ifndef __APPLE__
    2.10 +#include <GL/gl.h>
    2.11 +#else
    2.12 +#include <OpenGL/gl.h>
    2.13 +#endif
    2.14 +
    2.15 +#include <imago2.h>
    2.16 +
    2.17 +struct slice {
    2.18 +	char *name;
    2.19 +	struct slice *next;
    2.20 +};
    2.21 +
    2.22 +static struct slice *read_voldesc(const char *fname, struct volume *vol);
    2.23 +static char *trim(char *str);
    2.24 +
    2.25 +struct volume *load_volume(const char *fname)
    2.26 +{
    2.27 +	struct slice *slist;
    2.28 +	struct volume *vol = 0;
    2.29 +
    2.30 +	if(!(vol = malloc(sizeof *vol))) {
    2.31 +		perror("failed to allocate volume");
    2.32 +		return 0;
    2.33 +	}
    2.34 +	memset(vol, 0, sizeof *vol);
    2.35 +	vol->zaspect = 1;
    2.36 +
    2.37 +	if(!(slist = read_voldesc(fname, vol))) {
    2.38 +		goto err;
    2.39 +	}
    2.40 +
    2.41 +	glGenTextures(1, &vol->tex_vol);
    2.42 +	glBindTexture(GL_TEXTURE_3D, vol->tex_vol);
    2.43 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    2.44 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    2.45 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    2.46 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    2.47 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    2.48 +
    2.49 +	for(i=0; i<vol->sz[2]; i++) {
    2.50 +		struct img_pixmap img;
    2.51 +		struct slice *slice = head;
    2.52 +		head = head->next;
    2.53 +
    2.54 +		img_init(&img);
    2.55 +		if(img_load(&img, slice->name) == -1) {
    2.56 +			fprintf(stderr, "failed to load volume slice: %s\n", slice->name);
    2.57 +			goto err;
    2.58 +		}
    2.59 +	}
    2.60 +
    2.61 +	glGenTextures(1, &vol->tex_grad);
    2.62 +	glBindTexture(GL_TEXTURE_3D, vol->tex_grad);
    2.63 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    2.64 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    2.65 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    2.66 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    2.67 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    2.68 +
    2.69 +err:
    2.70 +	while(slist) {
    2.71 +		struct slice *tmp = slist;
    2.72 +		slist = slist->next;
    2.73 +		free(tmp->name);
    2.74 +		free(tmp);
    2.75 +	}
    2.76 +	if(vol) {
    2.77 +		if(vol->tex_vol)
    2.78 +			glDeleteTextures(1, &vol->tex_vol);
    2.79 +		if(vol->tex_grad)
    2.80 +			glDeleteTextures(1, &vol->tex_grad);
    2.81 +		free(vol);
    2.82 +	}
    2.83 +	return 0;
    2.84 +}
    2.85 +
    2.86 +static struct slice *read_voldesc(const char *fname, struct volume *vol)
    2.87 +{
    2.88 +	FILE *fp = 0;
    2.89 +	char buf[512];
    2.90 +	int mode_slices = 0;
    2.91 +	struct slice *head = 0, *tail;
    2.92 +
    2.93 +	if(!(fp = fopen(fname, "r"))) {
    2.94 +		fprintf(stderr, "failed to open volume descriptor: %s\n", fname);
    2.95 +		return 0;
    2.96 +	}
    2.97 +	fgets(buf, sizeof buf, fp);
    2.98 +	if(strstr(buf, "VOLDESC") != buf) {
    2.99 +		fprintf(stderr, "invalid file format while trying to read volume descriptor: %s\n", fname);
   2.100 +		goto err;
   2.101 +	}
   2.102 +
   2.103 +	while(fgets(buf, sizeof buf, fp)) {
   2.104 +		char *line = trim(buf);
   2.105 +
   2.106 +		if(!*line || *line == '#')
   2.107 +			continue;
   2.108 +
   2.109 +		if(mode_slices) {
   2.110 +			/* we're in the part that contains filenames... append to the list */
   2.111 +			struct slice *node = malloc(sizeof *node);
   2.112 +			if(!node || !(node->name = malloc(strlen(line) + 1))) {
   2.113 +				perror("failed to allocate list node");
   2.114 +				free(node);
   2.115 +				goto err;
   2.116 +			}
   2.117 +			strcpy(node->name, line);
   2.118 +			node->next = 0;
   2.119 +
   2.120 +			if(head) {
   2.121 +				tail->next = node;
   2.122 +				tail = node;
   2.123 +			} else {
   2.124 +				head = tail = node;
   2.125 +			}
   2.126 +			vol->sz[2]++;
   2.127 +		} else {
   2.128 +			/* TODO we're in the options part... parse */
   2.129 +		}
   2.130 +	}
   2.131 +	fclose(fp);
   2.132 +
   2.133 +	if(!vol->sz[2]) {
   2.134 +		fprintf(stderr, "file: %s contains no slices\n", fname);
   2.135 +		goto err;
   2.136 +	}
   2.137 +
   2.138 +	return head;
   2.139 +
   2.140 +err:
   2.141 +	while(head) {
   2.142 +		struct slice *tmp = head;
   2.143 +		head = head->next;
   2.144 +		free(tmp->name);
   2.145 +		free(tmp);
   2.146 +	}
   2.147 +	if(fp) {
   2.148 +		fclose(fp);
   2.149 +	}
   2.150 +	return 0;
   2.151 +}
   2.152 +
   2.153 +static char *trim(char *str)
   2.154 +{
   2.155 +	char *tmp = str + strlen(str) - 1;
   2.156 +
   2.157 +	while(isspace(*tmp))
   2.158 +		tmp--;
   2.159 +	tmp[1] = 0;
   2.160 +
   2.161 +	tmp = str;
   2.162 +	while(isspace(*tmp))
   2.163 +		tmp++;
   2.164 +	return tmp;
   2.165 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/volume.h	Sat Apr 07 16:07:12 2012 +0300
     3.3 @@ -0,0 +1,15 @@
     3.4 +#ifndef VOLUME_H_
     3.5 +#define VOLUME_H_
     3.6 +
     3.7 +#include <stdint.h>
     3.8 +
     3.9 +struct volume {
    3.10 +	int sz[3];
    3.11 +	float zaspect;
    3.12 +	unsigned int tex_vol, tex_grad;
    3.13 +};
    3.14 +
    3.15 +struct volume *load_volume(const char *fname);
    3.16 +void free_volume(struct volume *vol);
    3.17 +
    3.18 +#endif	/* VOLUME_H_ */
     4.1 --- a/volray.p.glsl	Thu Apr 05 00:52:11 2012 +0300
     4.2 +++ b/volray.p.glsl	Sat Apr 07 16:07:12 2012 +0300
     4.3 @@ -63,15 +63,14 @@
     4.4  		vec3 pos = ray.origin + ray.dir * t;
     4.5  		t += ray_step;
     4.6  
     4.7 -		float val = eval(pos) * energy;
     4.8 +		float val = eval(pos);
     4.9  		vec3 norm;
    4.10  
    4.11  		norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val;
    4.12  		norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val;
    4.13  		norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val;
    4.14 -		norm = normalize(norm);
    4.15  
    4.16 -		col += shade(ray, pos, norm) * val;
    4.17 +		col += shade(ray, pos, normalize(norm)) * val * energy;
    4.18  		energy -= val;
    4.19  		if(energy < 0.001) {
    4.20  			break;
    4.21 @@ -84,15 +83,15 @@
    4.22  
    4.23  vec3 shade(Ray ray, vec3 pos, vec3 norm)
    4.24  {
    4.25 -	vec3 ldir = normalize(vec3(10.0, 10.0, -10.0) - pos);
    4.26 +	vec3 ldir = -pos;//normalize(vec3(10.0, 10.0, -10.0) - pos);
    4.27  	vec3 vdir = -ray.dir;
    4.28  	vec3 hdir = normalize(ldir + vdir);
    4.29  
    4.30  	float ndotl = dot(ldir, norm);
    4.31  	float ndoth = dot(hdir, norm);
    4.32  
    4.33 -	vec3 dcol = vec3(1.0, 1.0, 1.0) * max(ndotl, 0.0);
    4.34 -	vec3 scol = vec3(0.6, 0.6, 0.6) * pow(max(ndoth, 0.0), 50.0);
    4.35 +	vec3 dcol = vec3(0.9, 0.9, 0.9) * max(ndotl, 0.0);
    4.36 +	vec3 scol = vec3(0.5, 0.5, 0.5) * pow(max(ndoth, 0.0), 50.0);
    4.37  
    4.38  	return vec3(0.01, 0.01, 0.01) + dcol + scol;
    4.39  }