metasurf
changeset 3:52664d3451ad
added volume rendering example
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 25 Oct 2011 13:30:03 +0300 |
parents | 9ab057fba0c5 |
children | 2c575855f707 |
files | examples/metaballs/src/metaballs.c examples/volume/Makefile examples/volume/sdr/frag.glsl examples/volume/sdr/vert.glsl examples/volume/src/cam.c examples/volume/src/cam.h examples/volume/src/sdr.c examples/volume/src/sdr.h examples/volume/src/volume.c |
diffstat | 9 files changed, 1106 insertions(+), 1 deletions(-) [+] |
line diff
1.1 --- a/examples/metaballs/src/metaballs.c Tue Oct 25 08:59:07 2011 +0300 1.2 +++ b/examples/metaballs/src/metaballs.c Tue Oct 25 13:30:03 2011 +0300 1.3 @@ -31,7 +31,6 @@ 1.4 int num_mballs = sizeof mball / sizeof *mball; 1.5 1.6 float eval(float x, float y, float z); 1.7 -float eval_cached(float x, float y, float z); 1.8 void vertex(float x, float y, float z); 1.9 void render(void); 1.10 void disp(void);
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/examples/volume/Makefile Tue Oct 25 13:30:03 2011 +0300 2.3 @@ -0,0 +1,34 @@ 2.4 +src = $(wildcard src/*.c) 2.5 +obj = $(src:.c=.o) 2.6 +dep = $(obj:.o=.d) 2.7 +bin = volume 2.8 + 2.9 +# uncomment the following line to disable shaders (for old systems like SGI or whatever) 2.10 +#nosdr = -DNO_SHADERS 2.11 + 2.12 +CC = gcc 2.13 +CFLAGS = -pedantic -Wall -g -I../../src $(nosdr) 2.14 +LDFLAGS = -L../.. -lmetasurf $(libgl) -limago 2.15 + 2.16 +ifeq ($(shell uname -s), Darwin) 2.17 + libgl = -framework OpenGL -framework GLUT -lGLEW 2.18 +else 2.19 + libgl = -lGL -lGLU -lglut -lGLEW 2.20 +endif 2.21 + 2.22 +$(bin): $(obj) 2.23 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.24 + 2.25 +-include $(dep) 2.26 + 2.27 +%.d: %.c 2.28 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 2.29 + 2.30 +.PHONY: clean 2.31 +clean: 2.32 + rm -f $(obj) $(bin) 2.33 + 2.34 + 2.35 +.PHONY: cleandep 2.36 +cleandep: 2.37 + rm -f $(dep)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/examples/volume/sdr/frag.glsl Tue Oct 25 13:30:03 2011 +0300 3.3 @@ -0,0 +1,19 @@ 3.4 +varying vec3 vpos, ldir, norm; 3.5 + 3.6 +void main() 3.7 +{ 3.8 + vec3 n = normalize(norm); 3.9 + vec3 l = normalize(ldir); 3.10 + vec3 v = -normalize(vpos); 3.11 + vec3 h = normalize(v + l); 3.12 + 3.13 + const vec3 kd = vec3(0.87, 0.82, 0.74); 3.14 + 3.15 + float diff = abs(dot(n, l)); 3.16 + float spec = pow(abs(dot(n, h)), 60.0); 3.17 + 3.18 + vec3 dcol = kd * diff; 3.19 + vec3 scol = vec3(0.8, 0.8, 0.8) * spec; 3.20 + 3.21 + gl_FragColor = vec4(dcol + scol, 1.0); 3.22 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/examples/volume/sdr/vert.glsl Tue Oct 25 13:30:03 2011 +0300 4.3 @@ -0,0 +1,10 @@ 4.4 +varying vec3 vpos, ldir, norm; 4.5 + 4.6 +void main() 4.7 +{ 4.8 + gl_Position = ftransform(); 4.9 + 4.10 + vpos = (gl_ModelViewMatrix * gl_Vertex).xyz; 4.11 + norm = gl_NormalMatrix * gl_Normal; 4.12 + ldir = gl_LightSource[0].position.xyz; 4.13 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/examples/volume/src/cam.c Tue Oct 25 13:30:03 2011 +0300 5.3 @@ -0,0 +1,216 @@ 5.4 +#include <math.h> 5.5 +#include "cam.h" 5.6 + 5.7 +#if defined(__APPLE__) && defined(__MACH__) 5.8 +#include <OpenGL/gl.h> 5.9 +#else 5.10 +#include <GL/gl.h> 5.11 +#endif 5.12 + 5.13 +#define DR (M_PI / 180.0) 5.14 +#define DEG_TO_RAD(x) ((x) * DR) 5.15 + 5.16 +typedef struct vec3 { 5.17 + float x, y, z; 5.18 +} vec3_t; 5.19 + 5.20 +/* viewing parameters */ 5.21 +#define DEF_THETA 0 5.22 +#define DEF_PHI 0 5.23 +#define DEF_DIST 0 5.24 +#define DEF_X 0 5.25 +#define DEF_Y 0 5.26 +#define DEF_Z 0 5.27 + 5.28 +static float cam_theta = DEF_THETA, cam_phi = DEF_PHI; 5.29 +static float cam_dist = DEF_DIST; 5.30 +static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z}; 5.31 + 5.32 +/* projection parameters */ 5.33 +#define DEF_VFOV 45.0 5.34 +#define DEF_ASPECT 1.3333333 5.35 +#define DEF_NEAR 1.0 5.36 +#define DEF_FAR 1000.0 5.37 + 5.38 +static float vfov = DEF_VFOV; 5.39 +static float aspect = DEF_ASPECT; 5.40 +static float nearclip = DEF_NEAR, farclip = DEF_FAR; 5.41 + 5.42 +/* stereo parameters */ 5.43 +#define DEF_EYE_SEP 0.1 5.44 +#define DEF_FOCUS_DIST 1.0 5.45 + 5.46 +static float eye_sep = DEF_EYE_SEP; 5.47 +static float focus_dist = DEF_FOCUS_DIST; 5.48 + 5.49 +static float pan_speed = 0.001; 5.50 +static float rot_speed = 0.5; 5.51 +static float zoom_speed = 0.1; 5.52 + 5.53 +static float vmin_deg = -90.0, vmax_deg = 90.0; 5.54 + 5.55 +void cam_reset(void) 5.56 +{ 5.57 + cam_reset_view(); 5.58 + cam_reset_proj(); 5.59 + cam_reset_stereo(); 5.60 +} 5.61 + 5.62 +void cam_reset_view(void) 5.63 +{ 5.64 + cam_theta = DEF_THETA; 5.65 + cam_phi = DEF_PHI; 5.66 + cam_dist = DEF_DIST; 5.67 + cam_pos.x = DEF_X; 5.68 + cam_pos.y = DEF_Y; 5.69 + cam_pos.z = DEF_Z; 5.70 +} 5.71 + 5.72 +void cam_reset_proj(void) 5.73 +{ 5.74 + vfov = DEF_VFOV; 5.75 + aspect = DEF_ASPECT; 5.76 + nearclip = DEF_NEAR; 5.77 + farclip = DEF_FAR; 5.78 +} 5.79 + 5.80 +void cam_reset_stereo(void) 5.81 +{ 5.82 + eye_sep = DEF_EYE_SEP; 5.83 + focus_dist = DEF_FOCUS_DIST; 5.84 +} 5.85 + 5.86 +void cam_set_vrange(float min_deg, float max_deg) 5.87 +{ 5.88 + vmin_deg = min_deg; 5.89 + vmax_deg = max_deg; 5.90 +} 5.91 + 5.92 +void cam_move(float x, float y, float z) 5.93 +{ 5.94 + cam_pos.x += x; 5.95 + cam_pos.y += y; 5.96 + cam_pos.z += z; 5.97 +} 5.98 + 5.99 +void cam_rotate(float theta, float phi) 5.100 +{ 5.101 + cam_phi += phi; 5.102 + cam_theta += theta; 5.103 +} 5.104 + 5.105 +void cam_dolly(float dist) 5.106 +{ 5.107 + cam_dist += dist; 5.108 +} 5.109 + 5.110 +void cam_inp_pan_speed(float speed) 5.111 +{ 5.112 + pan_speed = speed; 5.113 +} 5.114 + 5.115 +void cam_inp_rotate_speed(float speed) 5.116 +{ 5.117 + rot_speed = speed; 5.118 +} 5.119 + 5.120 +void cam_inp_zoom_speed(float speed) 5.121 +{ 5.122 + zoom_speed = speed; 5.123 +} 5.124 + 5.125 + 5.126 +void cam_inp_pan(int dx, int dy) 5.127 +{ 5.128 + float dxf = dx * pan_speed; 5.129 + float dyf = dy * pan_speed; 5.130 + float angle = -DEG_TO_RAD(cam_theta); 5.131 + 5.132 + cam_pos.x += cos(angle) * dxf + sin(angle) * dyf; 5.133 + cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf; 5.134 +} 5.135 + 5.136 +void cam_inp_height(int dh) 5.137 +{ 5.138 + cam_pos.y += dh * pan_speed; 5.139 +} 5.140 + 5.141 +void cam_inp_rotate(int dx, int dy) 5.142 +{ 5.143 + cam_theta += dx * rot_speed; 5.144 + cam_phi += dy * rot_speed; 5.145 + 5.146 + if(cam_phi < vmin_deg) cam_phi = vmin_deg; 5.147 + if(cam_phi > vmax_deg) cam_phi = vmax_deg; 5.148 +} 5.149 + 5.150 +void cam_inp_zoom(int dz) 5.151 +{ 5.152 + cam_dist += dz * zoom_speed; 5.153 + if(cam_dist < 0.001) { 5.154 + cam_dist = 0.001; 5.155 + } 5.156 +} 5.157 + 5.158 +void cam_clip(float n, float f) 5.159 +{ 5.160 + nearclip = n; 5.161 + farclip = f; 5.162 +} 5.163 + 5.164 +void cam_fov(float f) 5.165 +{ 5.166 + vfov = f; 5.167 +} 5.168 + 5.169 +void cam_aspect(float a) 5.170 +{ 5.171 + aspect = a; 5.172 +} 5.173 + 5.174 +void cam_separation(float s) 5.175 +{ 5.176 + eye_sep = s; 5.177 +} 5.178 + 5.179 +void cam_focus_dist(float d) 5.180 +{ 5.181 + focus_dist = d; 5.182 + 5.183 + cam_separation(d / 30.0); 5.184 +} 5.185 + 5.186 +void cam_view_matrix(void) 5.187 +{ 5.188 + cam_stereo_view_matrix(CAM_CENTER); 5.189 +} 5.190 + 5.191 +void cam_stereo_view_matrix(int eye) 5.192 +{ 5.193 + static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */ 5.194 + float offs = eye_sep * offs_sign[eye]; 5.195 + 5.196 + glTranslatef(offs, 0, 0); 5.197 + 5.198 + glTranslatef(0, 0, -cam_dist); 5.199 + glRotatef(cam_phi, 1, 0, 0); 5.200 + glRotatef(cam_theta, 0, 1, 0); 5.201 + glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); 5.202 +} 5.203 + 5.204 +void cam_proj_matrix(void) 5.205 +{ 5.206 + cam_stereo_proj_matrix(CAM_CENTER); 5.207 +} 5.208 + 5.209 +void cam_stereo_proj_matrix(int eye) 5.210 +{ 5.211 + float vfov_rad = M_PI * vfov / 180.0; 5.212 + float top = nearclip * tan(vfov_rad * 0.5); 5.213 + float right = top * aspect; 5.214 + 5.215 + static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */ 5.216 + float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist); 5.217 + 5.218 + glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip); 5.219 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/examples/volume/src/cam.h Tue Oct 25 13:30:03 2011 +0300 6.3 @@ -0,0 +1,54 @@ 6.4 +#ifndef CAM_H_ 6.5 +#define CAM_H_ 6.6 + 6.7 +enum { 6.8 + CAM_CENTER, 6.9 + CAM_LEFT, 6.10 + CAM_RIGHT 6.11 +}; 6.12 + 6.13 +/* reset to the initial state */ 6.14 +void cam_reset(void); /* all */ 6.15 +void cam_reset_view(void); /* view parameters */ 6.16 +void cam_reset_proj(void); /* projection parameters */ 6.17 +void cam_reset_stereo(void); /* stereo parameters */ 6.18 + 6.19 +void cam_set_vrange(float min_deg, float max_deg); 6.20 + 6.21 +void cam_move(float x, float y, float z); 6.22 +void cam_rotate(float theta, float phi); 6.23 +void cam_dolly(float dist); 6.24 + 6.25 +/* camera input handling */ 6.26 +void cam_inp_pan_speed(float speed); 6.27 +void cam_inp_rotate_speed(float speed); 6.28 +void cam_inp_zoom_speed(float speed); 6.29 + 6.30 +void cam_inp_pan(int dx, int dy); /* pan across X/Z plane */ 6.31 +void cam_inp_height(int dh); /* move verticaly */ 6.32 +void cam_inp_rotate(int dx, int dy); /* rotate around local Y and X axis */ 6.33 +void cam_inp_zoom(int dz); /* dolly the camera fwd/back */ 6.34 + 6.35 +/* camera projection parameters */ 6.36 +void cam_clip(float n, float f); /* set clipping planes */ 6.37 +void cam_fov(float f); /* vertical field of view in degrees */ 6.38 +void cam_aspect(float a); /* aspect ratio (width / height) */ 6.39 + 6.40 +/* stereo parameters */ 6.41 +void cam_separation(float s); 6.42 +void cam_focus_dist(float d); 6.43 + 6.44 + 6.45 +/* multiply the camera view matrix on top of the current matrix stack 6.46 + * (which should be GL_MODELVIEW) 6.47 + */ 6.48 +void cam_view_matrix(void); 6.49 +void cam_stereo_view_matrix(int eye); 6.50 + 6.51 +/* multiply the camera projection matrix on top of the current matrix stack 6.52 + * (which should be GL_PROJECTION) 6.53 + */ 6.54 +void cam_proj_matrix(void); 6.55 +void cam_stereo_proj_matrix(int eye); 6.56 + 6.57 +#endif /* CAM_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/examples/volume/src/sdr.c Tue Oct 25 13:30:03 2011 +0300 7.3 @@ -0,0 +1,333 @@ 7.4 +#ifndef NO_SHADERS 7.5 + 7.6 +#include <stdio.h> 7.7 +#include <stdlib.h> 7.8 +#include <string.h> 7.9 +#include <errno.h> 7.10 +#include <assert.h> 7.11 +#include <GL/glew.h> 7.12 + 7.13 +#if defined(unix) || defined(__unix__) 7.14 +#include <unistd.h> 7.15 +#include <sys/stat.h> 7.16 +#endif /* unix */ 7.17 + 7.18 +#include "sdr.h" 7.19 + 7.20 +unsigned int create_vertex_shader(const char *src) 7.21 +{ 7.22 + return create_shader(src, GL_VERTEX_SHADER); 7.23 +} 7.24 + 7.25 +unsigned int create_pixel_shader(const char *src) 7.26 +{ 7.27 + return create_shader(src, GL_FRAGMENT_SHADER); 7.28 +} 7.29 + 7.30 +unsigned int create_shader(const char *src, unsigned int sdr_type) 7.31 +{ 7.32 + unsigned int sdr; 7.33 + int success, info_len; 7.34 + char *info_str = 0; 7.35 + GLenum err; 7.36 + 7.37 + sdr = glCreateShader(sdr_type); 7.38 + assert(glGetError() == GL_NO_ERROR); 7.39 + glShaderSource(sdr, 1, &src, 0); 7.40 + err = glGetError(); 7.41 + assert(err == GL_NO_ERROR); 7.42 + glCompileShader(sdr); 7.43 + assert(glGetError() == GL_NO_ERROR); 7.44 + 7.45 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 7.46 + assert(glGetError() == GL_NO_ERROR); 7.47 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 7.48 + assert(glGetError() == GL_NO_ERROR); 7.49 + 7.50 + if(info_len) { 7.51 + if((info_str = malloc(info_len + 1))) { 7.52 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 7.53 + assert(glGetError() == GL_NO_ERROR); 7.54 + } 7.55 + } 7.56 + 7.57 + if(success) { 7.58 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 7.59 + } else { 7.60 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 7.61 + glDeleteShader(sdr); 7.62 + sdr = 0; 7.63 + } 7.64 + 7.65 + free(info_str); 7.66 + return sdr; 7.67 +} 7.68 + 7.69 +void free_shader(unsigned int sdr) 7.70 +{ 7.71 + glDeleteShader(sdr); 7.72 +} 7.73 + 7.74 +unsigned int load_vertex_shader(const char *fname) 7.75 +{ 7.76 + return load_shader(fname, GL_VERTEX_SHADER); 7.77 +} 7.78 + 7.79 +unsigned int load_pixel_shader(const char *fname) 7.80 +{ 7.81 + return load_shader(fname, GL_FRAGMENT_SHADER); 7.82 +} 7.83 + 7.84 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 7.85 +{ 7.86 +#if defined(unix) || defined(__unix__) 7.87 + struct stat st; 7.88 +#endif 7.89 + unsigned int sdr; 7.90 + size_t filesize; 7.91 + FILE *fp; 7.92 + char *src; 7.93 + 7.94 + if(!(fp = fopen(fname, "r"))) { 7.95 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 7.96 + return 0; 7.97 + } 7.98 + 7.99 +#if defined(unix) || defined(__unix__) 7.100 + fstat(fileno(fp), &st); 7.101 + filesize = st.st_size; 7.102 +#else 7.103 + fseek(fp, 0, SEEK_END); 7.104 + filesize = ftell(fp); 7.105 + fseek(fp, 0, SEEK_SET); 7.106 +#endif /* unix */ 7.107 + 7.108 + if(!(src = malloc(filesize + 1))) { 7.109 + fclose(fp); 7.110 + return 0; 7.111 + } 7.112 + fread(src, 1, filesize, fp); 7.113 + src[filesize] = 0; 7.114 + fclose(fp); 7.115 + 7.116 + fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname); 7.117 + sdr = create_shader(src, sdr_type); 7.118 + 7.119 + free(src); 7.120 + return sdr; 7.121 +} 7.122 + 7.123 + 7.124 +unsigned int get_vertex_shader(const char *fname) 7.125 +{ 7.126 + return get_shader(fname, GL_VERTEX_SHADER); 7.127 +} 7.128 + 7.129 +unsigned int get_pixel_shader(const char *fname) 7.130 +{ 7.131 + return get_shader(fname, GL_FRAGMENT_SHADER); 7.132 +} 7.133 + 7.134 +unsigned int get_shader(const char *fname, unsigned int sdr_type) 7.135 +{ 7.136 + unsigned int sdr; 7.137 + 7.138 + if(!(sdr = load_shader(fname, sdr_type))) { 7.139 + return 0; 7.140 + } 7.141 + return sdr; 7.142 +} 7.143 + 7.144 + 7.145 +/* ---- gpu programs ---- */ 7.146 + 7.147 +unsigned int create_program(void) 7.148 +{ 7.149 + unsigned int prog = glCreateProgram(); 7.150 + assert(glGetError() == GL_NO_ERROR); 7.151 + return prog; 7.152 +} 7.153 + 7.154 +unsigned int create_program_link(unsigned int vs, unsigned int ps) 7.155 +{ 7.156 + unsigned int prog; 7.157 + 7.158 + if(!(prog = create_program())) { 7.159 + return 0; 7.160 + } 7.161 + 7.162 + if(vs) { 7.163 + attach_shader(prog, vs); 7.164 + assert(glGetError() == GL_NO_ERROR); 7.165 + } 7.166 + if(ps) { 7.167 + attach_shader(prog, ps); 7.168 + assert(glGetError() == GL_NO_ERROR); 7.169 + } 7.170 + 7.171 + if(link_program(prog) == -1) { 7.172 + free_program(prog); 7.173 + return 0; 7.174 + } 7.175 + return prog; 7.176 +} 7.177 + 7.178 +unsigned int create_program_load(const char *vfile, const char *pfile) 7.179 +{ 7.180 + unsigned int vs = 0, ps = 0; 7.181 + 7.182 + if(vfile && !(vs = get_vertex_shader(vfile))) { 7.183 + return 0; 7.184 + } 7.185 + if(pfile && !(ps = get_pixel_shader(pfile))) { 7.186 + return 0; 7.187 + } 7.188 + return create_program_link(vs, ps); 7.189 +} 7.190 + 7.191 +void free_program(unsigned int sdr) 7.192 +{ 7.193 + glDeleteProgram(sdr); 7.194 +} 7.195 + 7.196 +void attach_shader(unsigned int prog, unsigned int sdr) 7.197 +{ 7.198 + glAttachShader(prog, sdr); 7.199 + assert(glGetError() == GL_NO_ERROR); 7.200 +} 7.201 + 7.202 +int link_program(unsigned int prog) 7.203 +{ 7.204 + int linked, info_len, retval = 0; 7.205 + char *info_str = 0; 7.206 + 7.207 + glLinkProgram(prog); 7.208 + assert(glGetError() == GL_NO_ERROR); 7.209 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 7.210 + assert(glGetError() == GL_NO_ERROR); 7.211 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 7.212 + assert(glGetError() == GL_NO_ERROR); 7.213 + 7.214 + if(info_len) { 7.215 + if((info_str = malloc(info_len + 1))) { 7.216 + glGetProgramInfoLog(prog, info_len, 0, info_str); 7.217 + assert(glGetError() == GL_NO_ERROR); 7.218 + } 7.219 + } 7.220 + 7.221 + if(linked) { 7.222 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 7.223 + } else { 7.224 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 7.225 + retval = -1; 7.226 + } 7.227 + 7.228 + free(info_str); 7.229 + return retval; 7.230 +} 7.231 + 7.232 +int bind_program(unsigned int prog) 7.233 +{ 7.234 + GLenum err; 7.235 + 7.236 + glUseProgram(prog); 7.237 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 7.238 + /* maybe the program is not linked, try linking first */ 7.239 + if(err == GL_INVALID_OPERATION) { 7.240 + if(link_program(prog) == -1) { 7.241 + return -1; 7.242 + } 7.243 + glUseProgram(prog); 7.244 + return glGetError() == GL_NO_ERROR ? 0 : -1; 7.245 + } 7.246 + return -1; 7.247 + } 7.248 + return 0; 7.249 +} 7.250 + 7.251 +/* ugly but I'm not going to write the same bloody code over and over */ 7.252 +#define BEGIN_UNIFORM_CODE \ 7.253 + int loc, curr_prog; \ 7.254 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 7.255 + if(curr_prog != prog && bind_program(prog) == -1) { \ 7.256 + return -1; \ 7.257 + } \ 7.258 + if((loc = glGetUniformLocation(prog, name)) != -1) 7.259 + 7.260 +#define END_UNIFORM_CODE \ 7.261 + if(curr_prog != prog) { \ 7.262 + bind_program(curr_prog); \ 7.263 + } \ 7.264 + return loc == -1 ? -1 : 0 7.265 + 7.266 +int set_uniform_int(unsigned int prog, const char *name, int val) 7.267 +{ 7.268 + BEGIN_UNIFORM_CODE { 7.269 + glUniform1i(loc, val); 7.270 + } 7.271 + END_UNIFORM_CODE; 7.272 +} 7.273 + 7.274 +int set_uniform_float(unsigned int prog, const char *name, float val) 7.275 +{ 7.276 + BEGIN_UNIFORM_CODE { 7.277 + glUniform1f(loc, val); 7.278 + } 7.279 + END_UNIFORM_CODE; 7.280 +} 7.281 + 7.282 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 7.283 +{ 7.284 + BEGIN_UNIFORM_CODE { 7.285 + glUniform3f(loc, x, y, z); 7.286 + } 7.287 + END_UNIFORM_CODE; 7.288 +} 7.289 + 7.290 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 7.291 +{ 7.292 + BEGIN_UNIFORM_CODE { 7.293 + glUniform4f(loc, x, y, z, w); 7.294 + } 7.295 + END_UNIFORM_CODE; 7.296 +} 7.297 + 7.298 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 7.299 +{ 7.300 + BEGIN_UNIFORM_CODE { 7.301 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 7.302 + } 7.303 + END_UNIFORM_CODE; 7.304 +} 7.305 + 7.306 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 7.307 +{ 7.308 + BEGIN_UNIFORM_CODE { 7.309 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 7.310 + } 7.311 + END_UNIFORM_CODE; 7.312 +} 7.313 + 7.314 +int get_attrib_loc(unsigned int prog, const char *name) 7.315 +{ 7.316 + int loc, curr_prog; 7.317 + 7.318 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 7.319 + if(curr_prog != prog && bind_program(prog) == -1) { 7.320 + return -1; 7.321 + } 7.322 + 7.323 + loc = glGetAttribLocation(prog, (char*)name); 7.324 + 7.325 + if(curr_prog != prog) { 7.326 + bind_program(curr_prog); 7.327 + } 7.328 + return loc; 7.329 +} 7.330 + 7.331 +void set_attrib_float3(int attr_loc, float x, float y, float z) 7.332 +{ 7.333 + glVertexAttrib3f(attr_loc, x, y, z); 7.334 +} 7.335 + 7.336 +#endif /* !NO_SHADERS */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/examples/volume/src/sdr.h Tue Oct 25 13:30:03 2011 +0300 8.3 @@ -0,0 +1,49 @@ 8.4 +#ifndef SDR_H_ 8.5 +#define SDR_H_ 8.6 + 8.7 +#ifdef __cplusplus 8.8 +extern "C" { 8.9 +#endif /* __cplusplus */ 8.10 + 8.11 +/* ---- shaders ---- */ 8.12 +unsigned int create_vertex_shader(const char *src); 8.13 +unsigned int create_pixel_shader(const char *src); 8.14 +unsigned int create_shader(const char *src, unsigned int sdr_type); 8.15 +void free_shader(unsigned int sdr); 8.16 + 8.17 +unsigned int load_vertex_shader(const char *fname); 8.18 +unsigned int load_pixel_shader(const char *fname); 8.19 +unsigned int load_shader(const char *src, unsigned int sdr_type); 8.20 + 8.21 +unsigned int get_vertex_shader(const char *fname); 8.22 +unsigned int get_pixel_shader(const char *fname); 8.23 +unsigned int get_shader(const char *fname, unsigned int sdr_type); 8.24 + 8.25 +int add_shader(const char *fname, unsigned int sdr); 8.26 +int remove_shader(const char *fname); 8.27 + 8.28 +/* ---- gpu programs ---- */ 8.29 +unsigned int create_program(void); 8.30 +unsigned int create_program_link(unsigned int vs, unsigned int ps); 8.31 +unsigned int create_program_load(const char *vfile, const char *pfile); 8.32 +void free_program(unsigned int sdr); 8.33 + 8.34 +void attach_shader(unsigned int prog, unsigned int sdr); 8.35 +int link_program(unsigned int prog); 8.36 +int bind_program(unsigned int prog); 8.37 + 8.38 +int set_uniform_int(unsigned int prog, const char *name, int val); 8.39 +int set_uniform_float(unsigned int prog, const char *name, float val); 8.40 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 8.41 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 8.42 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 8.43 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 8.44 + 8.45 +int get_attrib_loc(unsigned int prog, const char *name); 8.46 +void set_attrib_float3(int attr_loc, float x, float y, float z); 8.47 + 8.48 +#ifdef __cplusplus 8.49 +} 8.50 +#endif /* __cplusplus */ 8.51 + 8.52 +#endif /* SDR_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/examples/volume/src/volume.c Tue Oct 25 13:30:03 2011 +0300 9.3 @@ -0,0 +1,391 @@ 9.4 +#include <stdio.h> 9.5 +#include <stdlib.h> 9.6 +#include <math.h> 9.7 +#include <assert.h> 9.8 + 9.9 +#ifndef NO_SHADERS 9.10 +#include <GL/glew.h> 9.11 +#include "sdr.h" 9.12 +#endif 9.13 + 9.14 +#ifndef __APPLE__ 9.15 +#include <GL/glut.h> 9.16 +#else 9.17 +#include <GLUT/glut.h> 9.18 +#endif 9.19 + 9.20 +#include <imago2.h> 9.21 + 9.22 +#include "cam.h" 9.23 +#include "metasurf.h" 9.24 + 9.25 +float eval(float x, float y, float z); 9.26 +void vertex(float x, float y, float z); 9.27 +void render(void); 9.28 +void disp(void); 9.29 +void reshape(int x, int y); 9.30 +void keyb(unsigned char key, int x, int y); 9.31 +void mouse(int bn, int state, int x, int y); 9.32 +void motion(int x, int y); 9.33 +int parse_args(int argc, char **argv); 9.34 + 9.35 +int stereo, fullscreen; 9.36 +int orig_xsz, orig_ysz; 9.37 + 9.38 +struct metasurface *msurf; 9.39 +float threshold = 0.5; 9.40 +#ifndef NO_SHADERS 9.41 +unsigned int sdr; 9.42 +#endif 9.43 + 9.44 +struct img_pixmap *volume; 9.45 +int xres, yres, num_slices; 9.46 + 9.47 +int dlist, need_update = 1; 9.48 + 9.49 +int main(int argc, char **argv) 9.50 +{ 9.51 + float amb[] = {0, 0, 0, 0}; 9.52 + float lpos[] = {-0.2, 0.2, 1, 0}; 9.53 + 9.54 + glutInitWindowSize(1280, 720); 9.55 + glutInit(&argc, argv); 9.56 + 9.57 + if(parse_args(argc, argv) == -1) { 9.58 + return 1; 9.59 + } 9.60 + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); 9.61 + glutCreateWindow("metasurf - volume rendering"); 9.62 + 9.63 + orig_xsz = glutGet(GLUT_WINDOW_WIDTH); 9.64 + orig_ysz = glutGet(GLUT_WINDOW_HEIGHT); 9.65 + 9.66 + if(fullscreen) { 9.67 + glutFullScreen(); 9.68 + } 9.69 + 9.70 + glutDisplayFunc(disp); 9.71 + glutReshapeFunc(reshape); 9.72 + glutKeyboardFunc(keyb); 9.73 + glutMouseFunc(mouse); 9.74 + glutMotionFunc(motion); 9.75 + 9.76 +#ifndef NO_SHADERS 9.77 + glewInit(); 9.78 + if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) { 9.79 + return 1; 9.80 + } 9.81 +#endif 9.82 + 9.83 + glEnable(GL_CULL_FACE); 9.84 + glEnable(GL_DEPTH_TEST); 9.85 + 9.86 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 9.87 + 9.88 + glEnable(GL_LIGHTING); 9.89 + glEnable(GL_LIGHT0); 9.90 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 9.91 + 9.92 + glEnable(GL_NORMALIZE); 9.93 + 9.94 + cam_focus_dist(3.0); 9.95 + cam_clip(0.1, 200.0); 9.96 + cam_rotate(0, 0); 9.97 + cam_dolly(2); 9.98 + 9.99 + msurf = msurf_create(); 9.100 + msurf_eval_func(msurf, eval); 9.101 + msurf_vertex_func(msurf, vertex); 9.102 + msurf_threshold(msurf, threshold); 9.103 + msurf_resolution(msurf, xres, yres, num_slices); 9.104 + msurf_bounds(msurf, -1, -1, -1, 1, 1, 1); 9.105 + 9.106 + glClearColor(0.6, 0.6, 0.6, 1.0); 9.107 + 9.108 + dlist = glGenLists(1); 9.109 + 9.110 + glutMainLoop(); 9.111 + return 0; 9.112 +} 9.113 + 9.114 +float eval(float x, float y, float z) 9.115 +{ 9.116 + int px, py, slice; 9.117 + struct img_pixmap *img; 9.118 + 9.119 + px = round((x * 0.5 + 0.5) * xres); 9.120 + py = round((y * 0.5 + 0.5) * yres); 9.121 + slice = round((z * 0.5 + 0.5) * num_slices); 9.122 + 9.123 + if(px < 0) px = 0; 9.124 + if(px >= xres) px = xres - 1; 9.125 + 9.126 + if(py < 0) py = 0; 9.127 + if(py >= yres) py = yres - 1; 9.128 + 9.129 + if(slice < 0) slice = 0; 9.130 + if(slice >= num_slices) slice = num_slices - 1; 9.131 + 9.132 + img = volume + slice; 9.133 + return *((unsigned char*)img->pixels + py * img->width + px) / 255.0; 9.134 +} 9.135 + 9.136 +void vertex(float x, float y, float z) 9.137 +{ 9.138 + float dx = 1.0 / xres; 9.139 + float dy = 1.0 / yres; 9.140 + float dz = 1.0 / num_slices; 9.141 + float dfdx = eval(x - dx, y, z) - eval(x + dx, y, z); 9.142 + float dfdy = eval(x, y - dy, z) - eval(x, y + dy, z); 9.143 + float dfdz = eval(x, y, z - dz) - eval(x, y, z + dz); 9.144 + 9.145 + glNormal3f(dfdx, dfdy, dfdz); 9.146 + glVertex3f(x, y, z); 9.147 +} 9.148 + 9.149 +void render(void) 9.150 +{ 9.151 + float kd[] = {0.87, 0.82, 0.74, 1.0}; 9.152 + float ks[] = {0.9, 0.9, 0.9, 1.0}; 9.153 + 9.154 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, kd); 9.155 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ks); 9.156 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 9.157 + 9.158 +#ifndef NO_SHADERS 9.159 + bind_program(sdr); 9.160 +#endif 9.161 + 9.162 + glMatrixMode(GL_MODELVIEW); 9.163 + glPushMatrix(); 9.164 + glRotatef(90, 1, 0, 0); 9.165 + 9.166 + if(need_update) { 9.167 + glNewList(dlist, GL_COMPILE); 9.168 + glBegin(GL_TRIANGLES); 9.169 + printf("generating mesh... "); 9.170 + fflush(stdout); 9.171 + msurf_polygonize(msurf); 9.172 + glEnd(); 9.173 + glEndList(); 9.174 + need_update = 0; 9.175 + printf("done\n"); 9.176 + } 9.177 + glCallList(dlist); 9.178 + 9.179 + glPopMatrix(); 9.180 + 9.181 + assert(glGetError() == GL_NO_ERROR); 9.182 +} 9.183 + 9.184 +void disp(void) 9.185 +{ 9.186 + if(stereo) { 9.187 + glDrawBuffer(GL_BACK_LEFT); 9.188 + } 9.189 + 9.190 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 9.191 + 9.192 + glMatrixMode(GL_PROJECTION); 9.193 + glLoadIdentity(); 9.194 + cam_stereo_proj_matrix(stereo ? CAM_LEFT : CAM_CENTER); 9.195 + 9.196 + glMatrixMode(GL_MODELVIEW); 9.197 + glLoadIdentity(); 9.198 + cam_stereo_view_matrix(stereo ? CAM_LEFT : CAM_CENTER); 9.199 + 9.200 + render(); 9.201 + 9.202 + if(stereo) { 9.203 + glDrawBuffer(GL_BACK_RIGHT); 9.204 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 9.205 + 9.206 + glMatrixMode(GL_PROJECTION); 9.207 + glLoadIdentity(); 9.208 + cam_stereo_proj_matrix(CAM_RIGHT); 9.209 + 9.210 + glMatrixMode(GL_MODELVIEW); 9.211 + glLoadIdentity(); 9.212 + cam_stereo_view_matrix(CAM_RIGHT); 9.213 + 9.214 + render(); 9.215 + } 9.216 + glutSwapBuffers(); 9.217 +} 9.218 + 9.219 +void reshape(int x, int y) 9.220 +{ 9.221 + glViewport(0, 0, x, y); 9.222 + cam_aspect((float)x / (float)y); 9.223 +} 9.224 + 9.225 +void keyb(unsigned char key, int x, int y) 9.226 +{ 9.227 + static int wire; 9.228 + 9.229 + switch(key) { 9.230 + case 27: 9.231 + exit(0); 9.232 + 9.233 + case 'f': 9.234 + fullscreen = !fullscreen; 9.235 + if(fullscreen) { 9.236 + glutFullScreen(); 9.237 + } else { 9.238 + glutReshapeWindow(orig_xsz, orig_ysz); 9.239 + } 9.240 + break; 9.241 + 9.242 + case 's': 9.243 + stereo = !stereo; 9.244 + glutPostRedisplay(); 9.245 + break; 9.246 + 9.247 + case 'w': 9.248 + wire = !wire; 9.249 + glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); 9.250 + glutPostRedisplay(); 9.251 + break; 9.252 + 9.253 + case '=': 9.254 + threshold += 0.05; 9.255 + msurf_threshold(msurf, threshold); 9.256 + printf("threshold: %f\n", threshold); 9.257 + glutPostRedisplay(); 9.258 + need_update = 1; 9.259 + break; 9.260 + 9.261 + case '-': 9.262 + threshold -= 0.05; 9.263 + msurf_threshold(msurf, threshold); 9.264 + printf("threshold: %f\n", threshold); 9.265 + glutPostRedisplay(); 9.266 + need_update = 1; 9.267 + break; 9.268 + 9.269 + default: 9.270 + break; 9.271 + } 9.272 +} 9.273 + 9.274 +int bnstate[32]; 9.275 +int prev_x, prev_y; 9.276 + 9.277 +void mouse(int bn, int state, int x, int y) 9.278 +{ 9.279 + bnstate[bn] = state == GLUT_DOWN; 9.280 + prev_x = x; 9.281 + prev_y = y; 9.282 +} 9.283 + 9.284 +void motion(int x, int y) 9.285 +{ 9.286 + int dx, dy; 9.287 + 9.288 + dx = x - prev_x; 9.289 + dy = y - prev_y; 9.290 + prev_x = x; 9.291 + prev_y = y; 9.292 + 9.293 + if(bnstate[GLUT_LEFT_BUTTON]) { 9.294 + cam_inp_rotate(dx, dy); 9.295 + } 9.296 + if(bnstate[GLUT_RIGHT_BUTTON]) { 9.297 + cam_inp_zoom(dy); 9.298 + } 9.299 + glutPostRedisplay(); 9.300 +} 9.301 + 9.302 +struct list_node { 9.303 + struct img_pixmap img; 9.304 + struct list_node *next; 9.305 +}; 9.306 + 9.307 +int parse_args(int argc, char **argv) 9.308 +{ 9.309 + int i; 9.310 + struct list_node *head = 0, *tail = 0; 9.311 + 9.312 + for(i=1; i<argc; i++) { 9.313 + if(argv[i][0] == '-' && argv[i][2] == 0) { 9.314 + switch(argv[i][1]) { 9.315 + case 'f': 9.316 + fullscreen = !fullscreen; 9.317 + break; 9.318 + 9.319 + case 's': 9.320 + stereo = !stereo; 9.321 + break; 9.322 + 9.323 + case 'h': 9.324 + printf("usage: %s [opt]\n", argv[0]); 9.325 + printf("options:\n"); 9.326 + printf(" -f start in fullscreen\n"); 9.327 + printf(" -s enable stereoscopic rendering\n"); 9.328 + printf(" -h print usage and exit\n"); 9.329 + exit(0); 9.330 + 9.331 + default: 9.332 + fprintf(stderr, "unrecognized option: %s\n", argv[i]); 9.333 + return -1; 9.334 + } 9.335 + } else { 9.336 + struct list_node *slice; 9.337 + 9.338 + if(!(slice = malloc(sizeof *slice))) { 9.339 + fprintf(stderr, "failed to allocate volume slice: %d\n", num_slices); 9.340 + return -1; 9.341 + } 9.342 + slice->next = 0; 9.343 + 9.344 + img_init(&slice->img); 9.345 + if(img_load(&slice->img, argv[i]) == -1) { 9.346 + fprintf(stderr, "failed to load volume slice %d: %s\n", num_slices, argv[i]); 9.347 + free(slice); 9.348 + return -1; 9.349 + } 9.350 + img_convert(&slice->img, IMG_FMT_GREY8); 9.351 + 9.352 + if(num_slices > 0 && (xres != slice->img.width || yres != slice->img.height)) { 9.353 + fprintf(stderr, "error: slice %d (%s) is %dx%d, up to now we had %dx%d images\n", num_slices, argv[i], 9.354 + slice->img.width, slice->img.height, xres, yres); 9.355 + img_destroy(&slice->img); 9.356 + free(slice); 9.357 + return -1; 9.358 + } 9.359 + xres = slice->img.width; 9.360 + yres = slice->img.height; 9.361 + 9.362 + if(head) { 9.363 + tail->next = slice; 9.364 + tail = slice; 9.365 + } else { 9.366 + head = tail = slice; 9.367 + } 9.368 + printf("loaded volume slice %d: %s\n", num_slices++, argv[i]); 9.369 + } 9.370 + } 9.371 + 9.372 + if(!head) { 9.373 + fprintf(stderr, "you must specify a list of images for the volume data slices\n"); 9.374 + return -1; 9.375 + } 9.376 + 9.377 + if(!(volume = malloc(num_slices * sizeof *volume))) { 9.378 + fprintf(stderr, "failed to allocate volume data (%d slices)\n", num_slices); 9.379 + return -1; 9.380 + } 9.381 + 9.382 + for(i=0; i<num_slices; i++) { 9.383 + void *tmp; 9.384 + 9.385 + assert(head); 9.386 + volume[i] = head->img; 9.387 + 9.388 + tmp = head; 9.389 + head = head->next; 9.390 + free(tmp); 9.391 + } 9.392 + 9.393 + return 0; 9.394 +}