# HG changeset patch # User John Tsiombikas # Date 1333858314 -10800 # Node ID a6765984e057070da44f1006e84876a6a9f03918 # Parent ae10631bb11b45b2c0b515437f75d132059ad21d moved the volume loading to volume.c diff -r ae10631bb11b -r a6765984e057 sdr/slice.p.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/slice.p.glsl Sun Apr 08 07:11:54 2012 +0300 @@ -0,0 +1,8 @@ +uniform sampler3D volume; +uniform sampler1D xfer_tex; + +void main() +{ + float val = texture3D(volume, gl_TexCoord[0].xyz).a; + gl_FragColor = vec4(texture1D(xfer_tex, val).xxx, 1.0); +} diff -r ae10631bb11b -r a6765984e057 sdr/volray.p.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/volray.p.glsl Sun Apr 08 07:11:54 2012 +0300 @@ -0,0 +1,155 @@ +uniform sampler3D volume; +uniform sampler2D ray_tex; +uniform sampler1D xfer_tex; +uniform float ray_step; +uniform float zclip; + +struct Ray { + vec3 origin, dir; +}; + +struct AABBox { + vec3 min, max; +}; + +struct ISect { + bool hit; + float t0, t1; + vec3 pos; + vec3 normal; +}; + +vec3 sky(Ray ray); +vec3 ray_march(Ray ray, float t0, float t1); +vec3 shade(Ray ray, vec3 pos, vec3 norm); +Ray get_primary_ray(); +ISect intersect_aabb(Ray ray, AABBox aabb); + +void main() +{ + const AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0)); + Ray ray = get_primary_ray(); + + vec3 color = vec3(0.0, 0.0, 0.0); + + ISect res = intersect_aabb(ray, aabb); + if(res.hit) { + color = ray_march(ray, res.t0, res.t1); + } + + gl_FragColor = vec4(color, 1.0); +} + +float eval(vec3 pos) +{ + vec3 tc = pos * 0.5 + 0.5; + + if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) { + return 0.0; + } + + return texture1D(xfer_tex, texture3D(volume, tc).a).x; +} + +#define OFFS 0.01 +vec3 ray_march(Ray ray, float t0, float t1) +{ + float energy = 1.0; + float t = t0; + vec3 col = vec3(0.0, 0.0, 0.0); + + + while(t < t1) { + vec3 pos = ray.origin + ray.dir * t; + t += ray_step; + + float val = eval(pos); + vec3 norm; + + norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val; + norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val; + norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val; + + col += shade(ray, pos, normalize(norm)) * val * energy; + energy -= val; + if(energy < 0.001) { + break; + } + pos += ray.dir * ray_step; + } + + return col; +} + +vec3 shade(Ray ray, vec3 pos, vec3 norm) +{ + vec3 ldir = -pos;//normalize(vec3(10.0, 10.0, -10.0) - pos); + vec3 vdir = -ray.dir; + vec3 hdir = normalize(ldir + vdir); + + float ndotl = dot(ldir, norm); + float ndoth = dot(hdir, norm); + + vec3 dcol = vec3(0.9, 0.9, 0.9) * max(ndotl, 0.0); + vec3 scol = vec3(0.5, 0.5, 0.5) * pow(max(ndoth, 0.0), 50.0); + + return vec3(0.01, 0.01, 0.01) + dcol + scol; +} + +Ray get_primary_ray() +{ + Ray ray; + vec2 tc = gl_TexCoord[0].xy; + ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz); + ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz; + return ray; +} + +ISect intersect_aabb(Ray ray, AABBox aabb) +{ + ISect res; + res.hit = false; + res.t0 = res.t1 = 0.0; + + if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z && + ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) { + res.hit = true; + return res; + } + + vec4 bbox[2]; + bbox[0] = vec4(aabb.min.x, aabb.min.y, aabb.min.z, 0); + bbox[1] = vec4(aabb.max.x, aabb.max.y, aabb.max.z, 0); + + int xsign = int(ray.dir.x < 0.0); + float invdirx = 1.0 / ray.dir.x; + float tmin = (bbox[xsign].x - ray.origin.x) * invdirx; + float tmax = (bbox[1 - xsign].x - ray.origin.x) * invdirx; + + int ysign = int(ray.dir.y < 0.0); + float invdiry = 1.0 / ray.dir.y; + float tymin = (bbox[ysign].y - ray.origin.y) * invdiry; + float tymax = (bbox[1 - ysign].y - ray.origin.y) * invdiry; + + if(tmin > tymax || tymin > tmax) { + return res; + } + + if(tymin > tmin) tmin = tymin; + if(tymax < tmax) tmax = tymax; + + int zsign = int(ray.dir.z < 0.0); + float invdirz = 1.0 / ray.dir.z; + float tzmin = (bbox[zsign].z - ray.origin.z) * invdirz; + float tzmax = (bbox[1 - zsign].z - ray.origin.z) * invdirz; + + if(tmin > tzmax || tzmin > tmax) { + return res; + } + + res.t0 = tmin; + res.t1 = tmax; + res.hit = true; + return res; +} + diff -r ae10631bb11b -r a6765984e057 sdr/volray.v.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/volray.v.glsl Sun Apr 08 07:11:54 2012 +0300 @@ -0,0 +1,5 @@ +void main() +{ + gl_Position = gl_Vertex; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +} diff -r ae10631bb11b -r a6765984e057 slice.p.glsl --- a/slice.p.glsl Sat Apr 07 16:07:12 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -uniform sampler3D volume; -uniform sampler1D xfer_tex; - -void main() -{ - float val = texture3D(volume, gl_TexCoord[0].xyz).x; - gl_FragColor = vec4(texture1D(xfer_tex, val).xxx, 1.0); -} diff -r ae10631bb11b -r a6765984e057 src/volray.c --- a/src/volray.c Sat Apr 07 16:07:12 2012 +0300 +++ b/src/volray.c Sun Apr 08 07:11:54 2012 +0300 @@ -12,14 +12,10 @@ #include #include #include "sdr.h" +#include "volume.h" #define XFER_MAP_SZ 512 -struct slice_file { - char *name; - struct slice_file *next; -}; - enum { UIMODE_DEFAULT, UIMODE_XFER, @@ -43,24 +39,26 @@ static int round_pow2(int x); static void create_transfer_map(float mean, float sdev); -float cam_theta = 0, cam_phi = 0, cam_dist = 4.0; -float cam_x, cam_y, cam_z; +static float cam_theta = 0, cam_phi = 0, cam_dist = 4.0; +static float cam_x, cam_y, cam_z; -vec2_t tex_scale; -struct slice_file *flist; -int nslices; -unsigned int vol_sdr, slice_sdr, vol_tex, ray_tex; -int win_xsz, win_ysz; -int raytex_needs_recalc = 1; +static vec2_t tex_scale; +static struct volume *volume; +static unsigned int vol_sdr, slice_sdr, ray_tex; +static int win_xsz, win_ysz; +static int raytex_needs_recalc = 1; -unsigned int xfer_tex; -float xfer_mean = 0.7, xfer_sdev = 0.1; -int xfertex_needs_recalc = 1; +static unsigned int xfer_tex; +static float xfer_mean = 0.7, xfer_sdev = 0.1; +static int xfertex_needs_recalc = 1; static int uimode; static float cur_z = 0.0; static float ray_step = 0.01; +static const char *fname; + + int main(int argc, char **argv) { glutInit(&argc, argv); @@ -92,9 +90,7 @@ int init(void) { - int i, vol_xsz, vol_ysz; - - if(!(vol_sdr = create_program_load("volray.v.glsl", "volray.p.glsl"))) { + if(!(vol_sdr = create_program_load("sdr/volray.v.glsl", "sdr/volray.p.glsl"))) { return -1; } set_uniform_int(vol_sdr, "volume", 0); @@ -103,51 +99,16 @@ set_uniform_float(vol_sdr, "ray_step", ray_step); set_uniform_float(vol_sdr, "zclip", cur_z); - if(!(slice_sdr = create_program_load(0, "slice.p.glsl"))) { + if(!(slice_sdr = create_program_load(0, "sdr/slice.p.glsl"))) { return -1; } set_uniform_int(slice_sdr, "volume", 0); set_uniform_int(slice_sdr, "xfer_tex", 1); - glGenTextures(1, &vol_tex); - glBindTexture(GL_TEXTURE_3D, vol_tex); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + if(!(volume = load_volume(fname))) { + return -1; + } - for(i=0; inext; - - if(!(pix = img_load_pixels(sfile->name, &xsz, &ysz, IMG_FMT_RGBA32))) { - fprintf(stderr, "failed to load image: %s\n", sfile->name); - return -1; - } - - if(i == 0) { - /* allocate storage for the texture */ - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, xsz, ysz, nslices, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - vol_xsz = xsz; - vol_ysz = ysz; - - } else { - if(xsz != vol_xsz || ysz != vol_ysz) { - fprintf(stderr, "%s: inconsistent slice size: %dx%d. expected: %dx%d\n", - sfile->name, xsz, ysz, vol_xsz, vol_ysz); - img_free_pixels(pix); - return -1; - } - } - free(sfile); - - glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, i, xsz, ysz, 1, GL_RGBA, GL_UNSIGNED_BYTE, pix); - img_free_pixels(pix); - } return 0; } @@ -190,7 +151,7 @@ /* tex unit0: volume data 3D texture */ glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_3D, vol_tex); + glBindTexture(GL_TEXTURE_3D, volume->tex_vol); glEnable(GL_TEXTURE_3D); /* tex unit1: primary rays in view space */ @@ -235,7 +196,7 @@ glTranslatef(-1, -1, 0); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_3D, vol_tex); + glBindTexture(GL_TEXTURE_3D, volume->tex_vol); glEnable(GL_TEXTURE_3D); glActiveTexture(GL_TEXTURE1); @@ -426,7 +387,6 @@ int parse_args(int argc, char **argv) { int i; - struct slice_file *tail; char *endp; for(i=1; iname = argv[i]; - sfile->next = 0; - - if(!flist) { - flist = tail = sfile; - } else { - tail->next = sfile; - tail = sfile; - } - nslices++; + fname = argv[i]; } } - if(!nslices) { - fprintf(stderr, "pass the slice filenames\n"); + if(!fname) { + fprintf(stderr, "pass the volume descriptor filename\n"); return -1; } return 0; diff -r ae10631bb11b -r a6765984e057 src/volume.c --- a/src/volume.c Sat Apr 07 16:07:12 2012 +0300 +++ b/src/volume.c Sun Apr 08 07:11:54 2012 +0300 @@ -10,19 +10,24 @@ #endif #include +#include "volume.h" struct slice { char *name; struct slice *next; }; +static void calc_gradients(float *voxels, int xsz, int ysz, int zsz); static struct slice *read_voldesc(const char *fname, struct volume *vol); static char *trim(char *str); struct volume *load_volume(const char *fname) { + int i; struct slice *slist; struct volume *vol = 0; + float *voxels = 0, *vptr; + struct img_pixmap img; if(!(vol = malloc(sizeof *vol))) { perror("failed to allocate volume"); @@ -35,6 +40,60 @@ goto err; } + /* load the first image to determine slice dimensions */ + img_init(&img); + if(img_load(&img, slist->name) == -1) { + fprintf(stderr, "failed to load volume slice: %s\n", slist->name); + goto err; + } + + vol->sz[0] = img.width; + vol->sz[1] = img.height; + printf("volume dimensions: %dx%dx%d\n", img.width, img.height, vol->sz[2]); + + /* allocate the whole volume at once */ + if(!(voxels = malloc(vol->sz[0] * vol->sz[1] * vol->sz[2] * 4 * sizeof *voxels))) { + img_destroy(&img); + goto err; + } + vptr = voxels; + img_destroy(&img); + + /* put the volume data into the alpha component */ + for(i=0; isz[2]; i++) { + int x, y, xsz, ysz; + float *pixels, *src; + struct slice *slice = slist; + slist = slist->next; + + if(!(pixels = img_load_pixels(slice->name, &xsz, &ysz, IMG_FMT_GREYF))) { + fprintf(stderr, "failed to load volume slice: %s\n", slice->name); + goto err; + } + + if(xsz != vol->sz[0] || ysz != vol->sz[1]) { + fprintf(stderr, "inconsistent dimensions for slice %s: %dx%d (%dx%d expected)\n", + slice->name, xsz, ysz, vol->sz[0], vol->sz[1]); + goto err; + } + free(slice->name); + free(slice); + + src = pixels; + for(y=0; ysz[0], vol->sz[1], vol->sz[2]);*/ + + /* create the volume texture */ glGenTextures(1, &vol->tex_vol); glBindTexture(GL_TEXTURE_3D, vol->tex_vol); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -42,26 +101,12 @@ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, vol->sz[0], vol->sz[1], vol->sz[2], 0, + GL_RGBA, GL_FLOAT, voxels); - for(i=0; isz[2]; i++) { - struct img_pixmap img; - struct slice *slice = head; - head = head->next; - - img_init(&img); - if(img_load(&img, slice->name) == -1) { - fprintf(stderr, "failed to load volume slice: %s\n", slice->name); - goto err; - } - } - - glGenTextures(1, &vol->tex_grad); - glBindTexture(GL_TEXTURE_3D, vol->tex_grad); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + /* ... and destroy our copy */ + free(voxels); + return vol; err: while(slist) { @@ -70,20 +115,54 @@ free(tmp->name); free(tmp); } + free_volume(vol); + free(voxels); + return 0; +} + +void free_volume(struct volume *vol) +{ if(vol) { - if(vol->tex_vol) + if(vol->tex_vol) { glDeleteTextures(1, &vol->tex_vol); - if(vol->tex_grad) - glDeleteTextures(1, &vol->tex_grad); + } free(vol); } - return 0; +} + +struct vec4 { float x, y, z, w; }; + +static void calc_gradients(float *voxels, int xsz, int ysz, int zsz) +{ + int x, y, z, slice_pixels = xsz * ysz; + struct vec4 *vptr = (struct vec4*)voxels; + + for(z=0; z 0 ? (vptr - 1)->w : vptr->w; + y0 = y > 0 ? (vptr - xsz)->w : vptr->w; + z0 = z > 0 ? (vptr - slice_pixels)->w : vptr->w; + x1 = x < xsz - 1 ? (vptr + 1)->w : vptr->w; + y1 = y < ysz - 1 ? (vptr + xsz)->w : vptr->w; + z1 = z < zsz - 1 ? (vptr + slice_pixels)->w : vptr->w; + + vptr->x = x1 - x0; + vptr->y = y1 - y0; + vptr->z = z1 - z0; + + vptr++; + } + } + } } static struct slice *read_voldesc(const char *fname, struct volume *vol) { FILE *fp = 0; - char buf[512]; + char buf[512], *slash, *prefix = ""; int mode_slices = 0; struct slice *head = 0, *tail; @@ -97,6 +176,13 @@ goto err; } + if((slash = strrchr(fname, '/'))) { + int len = slash - fname + 1; + prefix = alloca(len + 1); + memcpy(prefix, fname, len); + prefix[len] = 0; + } + while(fgets(buf, sizeof buf, fp)) { char *line = trim(buf); @@ -106,12 +192,12 @@ if(mode_slices) { /* we're in the part that contains filenames... append to the list */ struct slice *node = malloc(sizeof *node); - if(!node || !(node->name = malloc(strlen(line) + 1))) { + if(!node || !(node->name = malloc(strlen(prefix) + strlen(line) + 1))) { perror("failed to allocate list node"); free(node); goto err; } - strcpy(node->name, line); + sprintf(node->name, "%s%s", prefix, line); node->next = 0; if(head) { @@ -123,6 +209,10 @@ vol->sz[2]++; } else { /* TODO we're in the options part... parse */ + + if(strcmp(line, "SLICES") == 0) { + mode_slices = 1; + } } } fclose(fp); diff -r ae10631bb11b -r a6765984e057 src/volume.h --- a/src/volume.h Sat Apr 07 16:07:12 2012 +0300 +++ b/src/volume.h Sun Apr 08 07:11:54 2012 +0300 @@ -6,7 +6,7 @@ struct volume { int sz[3]; float zaspect; - unsigned int tex_vol, tex_grad; + unsigned int tex_vol; }; struct volume *load_volume(const char *fname); diff -r ae10631bb11b -r a6765984e057 volray.p.glsl --- a/volray.p.glsl Sat Apr 07 16:07:12 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -uniform sampler3D volume; -uniform sampler2D ray_tex; -uniform sampler1D xfer_tex; -uniform float ray_step; -uniform float zclip; - -struct Ray { - vec3 origin, dir; -}; - -struct AABBox { - vec3 min, max; -}; - -struct ISect { - bool hit; - float t0, t1; - vec3 pos; - vec3 normal; -}; - -vec3 sky(Ray ray); -vec3 ray_march(Ray ray, float t0, float t1); -vec3 shade(Ray ray, vec3 pos, vec3 norm); -Ray get_primary_ray(); -ISect intersect_aabb(Ray ray, AABBox aabb); - -void main() -{ - const AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0)); - Ray ray = get_primary_ray(); - - vec3 color = vec3(0.0, 0.0, 0.0); - - ISect res = intersect_aabb(ray, aabb); - if(res.hit) { - color = ray_march(ray, res.t0, res.t1); - } - - gl_FragColor = vec4(color, 1.0); -} - -float eval(vec3 pos) -{ - vec3 tc = pos * 0.5 + 0.5; - - if(tc.x < 0.0 || tc.y < 0.0 || tc.z < zclip || tc.x > 1.0 || tc.y > 1.0 || tc.z > 1.0) { - return 0.0; - } - - return texture1D(xfer_tex, texture3D(volume, tc).x).x; -} - -#define OFFS 0.01 -vec3 ray_march(Ray ray, float t0, float t1) -{ - float energy = 1.0; - float t = t0; - vec3 col = vec3(0.0, 0.0, 0.0); - - - while(t < t1) { - vec3 pos = ray.origin + ray.dir * t; - t += ray_step; - - float val = eval(pos); - vec3 norm; - - norm.x = eval(pos + vec3(OFFS, 0.0, 0.0)) - val; - norm.y = eval(pos + vec3(0.0, OFFS, 0.0)) - val; - norm.z = eval(pos + vec3(0.0, 0.0, OFFS)) - val; - - col += shade(ray, pos, normalize(norm)) * val * energy; - energy -= val; - if(energy < 0.001) { - break; - } - pos += ray.dir * ray_step; - } - - return col; -} - -vec3 shade(Ray ray, vec3 pos, vec3 norm) -{ - vec3 ldir = -pos;//normalize(vec3(10.0, 10.0, -10.0) - pos); - vec3 vdir = -ray.dir; - vec3 hdir = normalize(ldir + vdir); - - float ndotl = dot(ldir, norm); - float ndoth = dot(hdir, norm); - - vec3 dcol = vec3(0.9, 0.9, 0.9) * max(ndotl, 0.0); - vec3 scol = vec3(0.5, 0.5, 0.5) * pow(max(ndoth, 0.0), 50.0); - - return vec3(0.01, 0.01, 0.01) + dcol + scol; -} - -Ray get_primary_ray() -{ - Ray ray; - vec2 tc = gl_TexCoord[0].xy; - ray.dir = gl_NormalMatrix * normalize(texture2D(ray_tex, tc).xyz); - ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz; - return ray; -} - -ISect intersect_aabb(Ray ray, AABBox aabb) -{ - ISect res; - res.hit = false; - res.t0 = res.t1 = 0.0; - - if(ray.origin.x >= aabb.min.x && ray.origin.y >= aabb.min.y && ray.origin.z >= aabb.min.z && - ray.origin.x < aabb.max.x && ray.origin.y < aabb.max.y && ray.origin.z < aabb.max.z) { - res.hit = true; - return res; - } - - vec4 bbox[2]; - bbox[0] = vec4(aabb.min.x, aabb.min.y, aabb.min.z, 0); - bbox[1] = vec4(aabb.max.x, aabb.max.y, aabb.max.z, 0); - - int xsign = int(ray.dir.x < 0.0); - float invdirx = 1.0 / ray.dir.x; - float tmin = (bbox[xsign].x - ray.origin.x) * invdirx; - float tmax = (bbox[1 - xsign].x - ray.origin.x) * invdirx; - - int ysign = int(ray.dir.y < 0.0); - float invdiry = 1.0 / ray.dir.y; - float tymin = (bbox[ysign].y - ray.origin.y) * invdiry; - float tymax = (bbox[1 - ysign].y - ray.origin.y) * invdiry; - - if(tmin > tymax || tymin > tmax) { - return res; - } - - if(tymin > tmin) tmin = tymin; - if(tymax < tmax) tmax = tymax; - - int zsign = int(ray.dir.z < 0.0); - float invdirz = 1.0 / ray.dir.z; - float tzmin = (bbox[zsign].z - ray.origin.z) * invdirz; - float tzmax = (bbox[1 - zsign].z - ray.origin.z) * invdirz; - - if(tmin > tzmax || tzmin > tmax) { - return res; - } - - res.t0 = tmin; - res.t1 = tmax; - res.hit = true; - return res; -} - diff -r ae10631bb11b -r a6765984e057 volray.v.glsl --- a/volray.v.glsl Sat Apr 07 16:07:12 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -void main() -{ - gl_Position = gl_Vertex; - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; -}