qvolray

changeset 1:57072295eb83

progress
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 02 Apr 2012 02:11:35 +0300
parents b050ce167ff1
children 0b73aa7317e1
files src/volray.c volray.p.glsl
diffstat 2 files changed, 72 insertions(+), 55 deletions(-) [+]
line diff
     1.1 --- a/src/volray.c	Sat Mar 31 02:08:42 2012 +0300
     1.2 +++ b/src/volray.c	Mon Apr 02 02:11:35 2012 +0300
     1.3 @@ -26,7 +26,7 @@
     1.4  void motion(int x, int y);
     1.5  int parse_args(int argc, char **argv);
     1.6  
     1.7 -unsigned int create_ray_texture(int xsz, int ysz, float vfov, vec2_t *tex_scale);
     1.8 +static void create_ray_texture(int xsz, int ysz, float vfov, vec2_t *tex_scale);
     1.9  static vec3_t get_primary_ray_dir(int x, int y, int w, int h, float vfov_deg);
    1.10  static int round_pow2(int x);
    1.11  
    1.12 @@ -38,6 +38,7 @@
    1.13  int nslices;
    1.14  unsigned int sdr, vol_tex, ray_tex;
    1.15  int win_xsz, win_ysz;
    1.16 +int raytex_needs_recalc = 1;
    1.17  
    1.18  int main(int argc, char **argv)
    1.19  {
    1.20 @@ -72,16 +73,18 @@
    1.21  	int i, vol_xsz, vol_ysz;
    1.22  
    1.23  	if(!(sdr = create_program_load("volray.v.glsl", "volray.p.glsl"))) {
    1.24 -		return 1;
    1.25 +		return -1;
    1.26  	}
    1.27 +	set_uniform_int(sdr, "volume", 0);
    1.28 +	set_uniform_int(sdr, "ray_tex", 1);
    1.29  
    1.30  	glGenTextures(1, &vol_tex);
    1.31  	glBindTexture(GL_TEXTURE_3D, vol_tex);
    1.32  	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1.33  	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.34 -	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    1.35 -	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    1.36 -	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    1.37 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    1.38 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    1.39 +	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
    1.40  
    1.41  	for(i=0; i<nslices; i++) {
    1.42  		int xsz, ysz;
    1.43 @@ -114,51 +117,52 @@
    1.44  		glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_UNSIGNED_BYTE, pix);
    1.45  		img_free_pixels(pix);
    1.46  	}
    1.47 -
    1.48  	return 0;
    1.49  }
    1.50  
    1.51  void disp(void)
    1.52  {
    1.53 +	if(raytex_needs_recalc) {
    1.54 +		create_ray_texture(win_xsz, win_ysz, 50.0, &tex_scale);
    1.55 +	}
    1.56 +
    1.57  	glMatrixMode(GL_MODELVIEW);
    1.58  	glLoadIdentity();
    1.59 +	glRotatef(-90, 1, 0, 0);
    1.60  	glTranslatef(cam_x, cam_y, -cam_z);
    1.61  	glRotatef(cam_theta, 0, 1, 0);
    1.62  	glRotatef(cam_phi, 1, 0, 0);
    1.63  	glTranslatef(0, 0, -cam_dist);
    1.64  
    1.65  	glMatrixMode(GL_TEXTURE);
    1.66 -	glPushMatrix();
    1.67 +	glLoadIdentity();
    1.68  	glScalef(tex_scale.x, tex_scale.y, 1.0);
    1.69  
    1.70  	glActiveTexture(GL_TEXTURE0);
    1.71 +	glBindTexture(GL_TEXTURE_3D, vol_tex);
    1.72  	glEnable(GL_TEXTURE_3D);
    1.73 -	glBindTexture(GL_TEXTURE_3D, vol_tex);
    1.74  
    1.75  	glActiveTexture(GL_TEXTURE1);
    1.76 +	glBindTexture(GL_TEXTURE_2D, ray_tex);
    1.77  	glEnable(GL_TEXTURE_2D);
    1.78 -	glBindTexture(GL_TEXTURE_2D, ray_tex);
    1.79  
    1.80  	bind_program(sdr);
    1.81  	glBegin(GL_QUADS);
    1.82  	glColor3f(1, 1, 1);
    1.83 -	glTexCoord2f(0, 1);
    1.84 -	glVertex2f(-1, -1);
    1.85 -	glTexCoord2f(1, 1);
    1.86 -	glVertex2f(1, -1);
    1.87 -	glTexCoord2f(1, 0);
    1.88 -	glVertex2f(1, 1);
    1.89 -	glTexCoord2f(0, 0);
    1.90 -	glVertex2f(-1, 1);
    1.91 +	glTexCoord2f(0, 1); glVertex2f(-1, -1);
    1.92 +	glTexCoord2f(1, 1); glVertex2f(1, -1);
    1.93 +	glTexCoord2f(1, 0); glVertex2f(1, 1);
    1.94 +	glTexCoord2f(0, 0); glVertex2f(-1, 1);
    1.95  	glEnd();
    1.96  	bind_program(0);
    1.97  
    1.98 +	glActiveTexture(GL_TEXTURE1);
    1.99  	glDisable(GL_TEXTURE_2D);
   1.100  	glActiveTexture(GL_TEXTURE0);
   1.101  	glDisable(GL_TEXTURE_3D);
   1.102  
   1.103  	glMatrixMode(GL_TEXTURE);
   1.104 -	glPopMatrix();
   1.105 +	glLoadIdentity();
   1.106  
   1.107  	glutSwapBuffers();
   1.108  	assert(glGetError() == GL_NO_ERROR);
   1.109 @@ -166,10 +170,11 @@
   1.110  
   1.111  void reshape(int x, int y)
   1.112  {
   1.113 +	printf("reshape: %dx%d\n", x, y);
   1.114  	glViewport(0, 0, x, y);
   1.115  
   1.116  	if(x != win_xsz || y != win_ysz) {
   1.117 -		ray_tex = create_ray_texture(x, y, 50.0, &tex_scale);
   1.118 +		raytex_needs_recalc = 1;
   1.119  		win_xsz = x;
   1.120  		win_ysz = y;
   1.121  	}
   1.122 @@ -205,19 +210,20 @@
   1.123  		cam_theta += dx * 0.5;
   1.124  		cam_phi += dy * 0.5;
   1.125  
   1.126 -		if(cam_phi < -90) cam_phi = -90;
   1.127 -		if(cam_phi > 90) cam_phi = 90;
   1.128 +		if(cam_phi <= -90) cam_phi = -89;
   1.129 +		if(cam_phi >= 90) cam_phi = 89;
   1.130  
   1.131  		glutPostRedisplay();
   1.132  	}
   1.133  
   1.134  	if(bnstate[1]) {
   1.135 -		cam_y += dy * 0.1;
   1.136 +		cam_x += dx * 0.025;
   1.137 +		cam_y += dy * 0.025;
   1.138  		glutPostRedisplay();
   1.139  	}
   1.140  
   1.141  	if(bnstate[2]) {
   1.142 -		cam_dist += dy * 0.1;
   1.143 +		cam_dist += dy * 0.025;
   1.144  		if(cam_dist < 0.0) cam_dist = 0.0;
   1.145  		glutPostRedisplay();
   1.146  	}
   1.147 @@ -257,49 +263,52 @@
   1.148  }
   1.149  
   1.150  
   1.151 -unsigned int create_ray_texture(int xsz, int ysz, float vfov, vec2_t *tex_scale)
   1.152 +static void create_ray_texture(int xsz, int ysz, float vfov, vec2_t *tex_scale)
   1.153  {
   1.154  	int i, j;
   1.155 -	unsigned int tex;
   1.156 +	int cur_tex_xsz, cur_tex_ysz;
   1.157  	int tex_xsz = round_pow2(xsz);
   1.158  	int tex_ysz = round_pow2(ysz);
   1.159  	float *teximg, *dir;
   1.160  
   1.161 -	if(!(teximg = malloc(3 * tex_xsz * tex_ysz * sizeof *teximg))) {
   1.162 -		return 0;
   1.163 +	if(!(teximg = malloc(3 * xsz * ysz * sizeof *teximg))) {
   1.164 +		return;
   1.165  	}
   1.166  	dir = teximg;
   1.167  
   1.168 -	for(i=0; i<tex_ysz; i++) {
   1.169 -		for(j=0; j<tex_xsz; j++) {
   1.170 -			if(j < xsz && i < ysz) {
   1.171 -				vec3_t rdir = get_primary_ray_dir(j, i, xsz, ysz, vfov);
   1.172 -				dir[0] = rdir.x;
   1.173 -				dir[1] = rdir.y;
   1.174 -				dir[2] = rdir.z;
   1.175 -			} else {
   1.176 -				dir[0] = dir[1] = 0.0f;
   1.177 -				dir[2] = 1.0f;
   1.178 -			}
   1.179 -
   1.180 -			dir += 3;
   1.181 +	for(i=0; i<ysz; i++) {
   1.182 +		for(j=0; j<xsz; j++) {
   1.183 +			vec3_t rdir = get_primary_ray_dir(j, i, xsz, ysz, vfov);
   1.184 +			*dir++ = rdir.x;
   1.185 +			*dir++ = rdir.y;
   1.186 +			*dir++ = rdir.z;
   1.187  		}
   1.188  	}
   1.189  
   1.190 -	glGenTextures(1, &tex);
   1.191 -	glBindTexture(GL_TEXTURE_2D, tex);
   1.192 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1.193 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1.194 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   1.195 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
   1.196 -	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, tex_xsz, tex_ysz, 0, GL_RGB, GL_FLOAT, teximg);
   1.197 +	if(!ray_tex) {
   1.198 +		glGenTextures(1, &ray_tex);
   1.199 +	}
   1.200 +
   1.201 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cur_tex_xsz);
   1.202 +	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cur_tex_ysz);
   1.203 +
   1.204 +	if(tex_xsz > cur_tex_xsz || tex_ysz > cur_tex_ysz) {
   1.205 +		glBindTexture(GL_TEXTURE_2D, ray_tex);
   1.206 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1.207 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1.208 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   1.209 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
   1.210 +		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, tex_xsz, tex_ysz, 0, GL_RGB, GL_FLOAT, 0);
   1.211 +	}
   1.212 +
   1.213 +	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, xsz, ysz, GL_RGB, GL_FLOAT, teximg);
   1.214  	free(teximg);
   1.215  
   1.216  	if(tex_scale) {
   1.217  		tex_scale->x = (float)xsz / (float)tex_xsz;
   1.218  		tex_scale->y = (float)ysz / (float)tex_ysz;
   1.219  	}
   1.220 -	return tex;
   1.221 +	raytex_needs_recalc = 0;
   1.222  }
   1.223  
   1.224  static vec3_t get_primary_ray_dir(int x, int y, int w, int h, float vfov_deg)
     2.1 --- a/volray.p.glsl	Sat Mar 31 02:08:42 2012 +0300
     2.2 +++ b/volray.p.glsl	Mon Apr 02 02:11:35 2012 +0300
     2.3 @@ -12,6 +12,7 @@
     2.4  	vec3 normal;
     2.5  };
     2.6  
     2.7 +vec3 sky(Ray ray);
     2.8  vec3 ray_march(Ray ray);
     2.9  vec3 shade(Ray ray, ISect isect);
    2.10  Ray get_primary_ray();
    2.11 @@ -21,30 +22,37 @@
    2.12  	Ray ray = get_primary_ray();
    2.13  
    2.14  	gl_FragColor = vec4(ray_march(ray), 1.0);
    2.15 +	//gl_FragColor = vec4(sky(ray), 1.0);
    2.16  }
    2.17  
    2.18 -/*vec3 sky(Ray ray)
    2.19 +vec3 sky(Ray ray)
    2.20  {
    2.21  	vec3 col1 = vec3(0.75, 0.78, 0.8);
    2.22  	vec3 col2 = vec3(0.56, 0.7, 1.0);
    2.23  
    2.24  	float t = max(ray.dir.y, -0.5);
    2.25  	return mix(col1, col2, t);
    2.26 -}*/
    2.27 +}
    2.28  
    2.29  vec3 ray_march(Ray ray)
    2.30  {
    2.31 -	const float ray_step = 0.05;
    2.32 +	const float ray_step = 0.1;
    2.33  	float energy = 1.0;
    2.34  	vec3 pos = ray.origin;
    2.35 +	float col = 0.0;
    2.36  
    2.37 -	// assuming view space
    2.38 -	while(pos.z < 1.0) {
    2.39 -		energy -= texture3D(volume, pos).x;
    2.40 +	for(int i=0; i<40; i++) {
    2.41 +		float val = texture3D(volume, pos).x;
    2.42 +		val *= energy;
    2.43 +		col += val;
    2.44 +		energy -= val;
    2.45 +		if(energy < 0.001) {
    2.46 +			break;
    2.47 +		}
    2.48  		pos += ray.dir * ray_step;
    2.49  	}
    2.50  
    2.51 -	return vec3(energy, energy, energy);
    2.52 +	return vec3(col, col, col);
    2.53  }
    2.54  
    2.55  vec3 shade(Ray ray, ISect isect)