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)