# HG changeset patch # User John Tsiombikas # Date 1319517271 -10800 # Node ID 7aa4627e492bb97d5aacc3f0c3b21a84a592c82f first commit diff -r 000000000000 -r 7aa4627e492b .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,7 @@ +\.o$ +\.d$ +\.swp$ +^libmetasurf\.so +^libmetasurf\.a$ +^metasurf\.dylib +^Makefile$ diff -r 000000000000 -r 7aa4627e492b Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.in Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,65 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) + +hdr = metasurf.h + +name = metasurf +lib_a = lib$(name).a +somajor = 0 +sominor = 1 + +ifeq ($(shell uname -s), Darwin) + lib_so = $(name).dylib + shared = -dynamiclib +else + devlink = lib$(name).so + soname = $(devlink).$(somajor) + lib_so = $(soname).$(sominor) + shared = -shared -Wl,-soname=$(soname) + pic = -fPIC +endif + +CC = gcc +AR = ar +CFLAGS = -pedantic -Wall $(dbg) $(opt) $(pic) + +.PHONY: all +all: $(lib_so) $(lib_a) + +$(lib_so): $(obj) + $(CC) -o $@ $(shared) $(LDFLAGS) + +$(lib_a): $(obj) + $(AR) rcs $@ $(obj) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(lib_a) $(lib_so) $(dep) + +.PHONY: cleandep +cleandep: + rm -f $(dep) + +.PHONY: install +install: + mkdir -p $(PREFIX)/include $(PREFIX)/lib + cp src/$(hdr) $(PREFIX)/include/$(hdr) + cp $(lib_so) $(PREFIX)/lib/$(lib_so) + [ -n "$(soname)" ] \ + && ln -s $(PREFIX)/lib/$(lib_so) $(PREFIX)/lib/$(soname) \ + && ln -s $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \ + || true + +.PHONY: uninstall +uninstall: + rm -f $(PREFIX)/include/$(hdr) + rm -f $(PREFIX)/lib/$(lib_so) + [ -n "$(soname)" ] \ + && rm -f $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \ + || true diff -r 000000000000 -r 7aa4627e492b configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configure Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,42 @@ +#!/bin/sh + +prefix=/usr/local +opt=true +dbg=true + +while [ $# -ne 0 ]; do + case "$1" in + --prefix=*) + prefix=`echo $1 | sed 's/--prefix=//'` + ;; + + --enable-debug) + dbg=true + ;; + --disable-debug) + dbg=false + ;; + --enable-opt) + opt=true + ;; + --disable-opt) + opt=false + ;; + esac + shift +done + + +echo 'configuring metasurf...' +echo " prefix: $prefix" +echo 'debugging symbols:' `$dbg && echo yes || echo no` +echo ' optimization:' `$opt && echo yes || echo no` + +echo 'generating makefile...' +echo "# automatically generated by the configure script" >Makefile +echo "PREFIX = $prefix" >>Makefile +$opt && echo "opt = -O3" >>Makefile +$dbg && echo "dbg = -g" >>Makefile +cat Makefile.in >>Makefile + +echo done. diff -r 000000000000 -r 7aa4627e492b examples/metaballs/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/Makefile Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,31 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) +bin = metasurf + +CC = gcc +CFLAGS = -pedantic -Wall -g -O3 +LDFLAGS = $(libgl) + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT -lGLEW +else + libgl = -lGL -lGLU -lglut -lGLEW +endif + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) + + +.PHONY: cleandep +cleandep: + rm -f $(dep) diff -r 000000000000 -r 7aa4627e492b examples/metaballs/sdr/frag.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/sdr/frag.glsl Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,19 @@ +varying vec3 vpos, ldir, norm; + +void main() +{ + vec3 n = normalize(norm); + vec3 l = normalize(ldir); + vec3 v = -normalize(vpos); + vec3 h = normalize(v + l); + + const vec3 kd = vec3(0.42, 0.6, 0.43); + + float diff = abs(dot(n, l)); + float spec = pow(abs(dot(n, h)), 60.0); + + vec3 dcol = kd * diff; + vec3 scol = vec3(0.8, 0.8, 0.8) * spec; + + gl_FragColor = vec4(dcol + scol, 1.0); +} diff -r 000000000000 -r 7aa4627e492b examples/metaballs/sdr/vert.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/sdr/vert.glsl Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,10 @@ +varying vec3 vpos, ldir, norm; + +void main() +{ + gl_Position = ftransform(); + + vpos = (gl_ModelViewMatrix * gl_Vertex).xyz; + norm = gl_NormalMatrix * gl_Normal; + ldir = gl_LightSource[0].position.xyz; +} diff -r 000000000000 -r 7aa4627e492b examples/metaballs/src/cam.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/src/cam.c Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,216 @@ +#include +#include "cam.h" + +#if defined(__APPLE__) && defined(__MACH__) +#include +#else +#include +#endif + +#define DR (M_PI / 180.0) +#define DEG_TO_RAD(x) ((x) * DR) + +typedef struct vec3 { + float x, y, z; +} vec3_t; + +/* viewing parameters */ +#define DEF_THETA 0 +#define DEF_PHI 0 +#define DEF_DIST 0 +#define DEF_X 0 +#define DEF_Y 0 +#define DEF_Z 0 + +static float cam_theta = DEF_THETA, cam_phi = DEF_PHI; +static float cam_dist = DEF_DIST; +static vec3_t cam_pos = {DEF_X, DEF_Y, DEF_Z}; + +/* projection parameters */ +#define DEF_VFOV 45.0 +#define DEF_ASPECT 1.3333333 +#define DEF_NEAR 1.0 +#define DEF_FAR 1000.0 + +static float vfov = DEF_VFOV; +static float aspect = DEF_ASPECT; +static float nearclip = DEF_NEAR, farclip = DEF_FAR; + +/* stereo parameters */ +#define DEF_EYE_SEP 0.1 +#define DEF_FOCUS_DIST 1.0 + +static float eye_sep = DEF_EYE_SEP; +static float focus_dist = DEF_FOCUS_DIST; + +static float pan_speed = 0.001; +static float rot_speed = 0.5; +static float zoom_speed = 0.1; + +static float vmin_deg = -90.0, vmax_deg = 90.0; + +void cam_reset(void) +{ + cam_reset_view(); + cam_reset_proj(); + cam_reset_stereo(); +} + +void cam_reset_view(void) +{ + cam_theta = DEF_THETA; + cam_phi = DEF_PHI; + cam_dist = DEF_DIST; + cam_pos.x = DEF_X; + cam_pos.y = DEF_Y; + cam_pos.z = DEF_Z; +} + +void cam_reset_proj(void) +{ + vfov = DEF_VFOV; + aspect = DEF_ASPECT; + nearclip = DEF_NEAR; + farclip = DEF_FAR; +} + +void cam_reset_stereo(void) +{ + eye_sep = DEF_EYE_SEP; + focus_dist = DEF_FOCUS_DIST; +} + +void cam_set_vrange(float min_deg, float max_deg) +{ + vmin_deg = min_deg; + vmax_deg = max_deg; +} + +void cam_move(float x, float y, float z) +{ + cam_pos.x += x; + cam_pos.y += y; + cam_pos.z += z; +} + +void cam_rotate(float theta, float phi) +{ + cam_phi += phi; + cam_theta += theta; +} + +void cam_dolly(float dist) +{ + cam_dist += dist; +} + +void cam_inp_pan_speed(float speed) +{ + pan_speed = speed; +} + +void cam_inp_rotate_speed(float speed) +{ + rot_speed = speed; +} + +void cam_inp_zoom_speed(float speed) +{ + zoom_speed = speed; +} + + +void cam_inp_pan(int dx, int dy) +{ + float dxf = dx * pan_speed; + float dyf = dy * pan_speed; + float angle = -DEG_TO_RAD(cam_theta); + + cam_pos.x += cos(angle) * dxf + sin(angle) * dyf; + cam_pos.z += -sin(angle) * dxf + cos(angle) * dyf; +} + +void cam_inp_height(int dh) +{ + cam_pos.y += dh * pan_speed; +} + +void cam_inp_rotate(int dx, int dy) +{ + cam_theta += dx * rot_speed; + cam_phi += dy * rot_speed; + + if(cam_phi < vmin_deg) cam_phi = vmin_deg; + if(cam_phi > vmax_deg) cam_phi = vmax_deg; +} + +void cam_inp_zoom(int dz) +{ + cam_dist += dz * zoom_speed; + if(cam_dist < 0.001) { + cam_dist = 0.001; + } +} + +void cam_clip(float n, float f) +{ + nearclip = n; + farclip = f; +} + +void cam_fov(float f) +{ + vfov = f; +} + +void cam_aspect(float a) +{ + aspect = a; +} + +void cam_separation(float s) +{ + eye_sep = s; +} + +void cam_focus_dist(float d) +{ + focus_dist = d; + + cam_separation(d / 30.0); +} + +void cam_view_matrix(void) +{ + cam_stereo_view_matrix(CAM_CENTER); +} + +void cam_stereo_view_matrix(int eye) +{ + static const float offs_sign[] = {0.0f, 0.5f, -0.5f}; /* center, left, right */ + float offs = eye_sep * offs_sign[eye]; + + glTranslatef(offs, 0, 0); + + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); +} + +void cam_proj_matrix(void) +{ + cam_stereo_proj_matrix(CAM_CENTER); +} + +void cam_stereo_proj_matrix(int eye) +{ + float vfov_rad = M_PI * vfov / 180.0; + float top = nearclip * tan(vfov_rad * 0.5); + float right = top * aspect; + + static const float offs_sign[] = {0.0f, 1.0, -1.0}; /* center, left, right */ + float frust_shift = offs_sign[eye] * (eye_sep * 0.5 * nearclip / focus_dist); + + glFrustum(-right + frust_shift, right + frust_shift, -top, top, nearclip, farclip); +} diff -r 000000000000 -r 7aa4627e492b examples/metaballs/src/cam.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/src/cam.h Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,54 @@ +#ifndef CAM_H_ +#define CAM_H_ + +enum { + CAM_CENTER, + CAM_LEFT, + CAM_RIGHT +}; + +/* reset to the initial state */ +void cam_reset(void); /* all */ +void cam_reset_view(void); /* view parameters */ +void cam_reset_proj(void); /* projection parameters */ +void cam_reset_stereo(void); /* stereo parameters */ + +void cam_set_vrange(float min_deg, float max_deg); + +void cam_move(float x, float y, float z); +void cam_rotate(float theta, float phi); +void cam_dolly(float dist); + +/* camera input handling */ +void cam_inp_pan_speed(float speed); +void cam_inp_rotate_speed(float speed); +void cam_inp_zoom_speed(float speed); + +void cam_inp_pan(int dx, int dy); /* pan across X/Z plane */ +void cam_inp_height(int dh); /* move verticaly */ +void cam_inp_rotate(int dx, int dy); /* rotate around local Y and X axis */ +void cam_inp_zoom(int dz); /* dolly the camera fwd/back */ + +/* camera projection parameters */ +void cam_clip(float n, float f); /* set clipping planes */ +void cam_fov(float f); /* vertical field of view in degrees */ +void cam_aspect(float a); /* aspect ratio (width / height) */ + +/* stereo parameters */ +void cam_separation(float s); +void cam_focus_dist(float d); + + +/* multiply the camera view matrix on top of the current matrix stack + * (which should be GL_MODELVIEW) + */ +void cam_view_matrix(void); +void cam_stereo_view_matrix(int eye); + +/* multiply the camera projection matrix on top of the current matrix stack + * (which should be GL_PROJECTION) + */ +void cam_proj_matrix(void); +void cam_stereo_proj_matrix(int eye); + +#endif /* CAM_H_ */ diff -r 000000000000 -r 7aa4627e492b examples/metaballs/src/sdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/src/sdr.c Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,329 @@ +#include +#include +#include +#include +#include +#include + +#if defined(unix) || defined(__unix__) +#include +#include +#endif /* unix */ + +#include "sdr.h" + +unsigned int create_vertex_shader(const char *src) +{ + return create_shader(src, GL_VERTEX_SHADER); +} + +unsigned int create_pixel_shader(const char *src) +{ + return create_shader(src, GL_FRAGMENT_SHADER); +} + +unsigned int create_shader(const char *src, unsigned int sdr_type) +{ + unsigned int sdr; + int success, info_len; + char *info_str = 0; + GLenum err; + + sdr = glCreateShader(sdr_type); + assert(glGetError() == GL_NO_ERROR); + glShaderSource(sdr, 1, &src, 0); + err = glGetError(); + assert(err == GL_NO_ERROR); + glCompileShader(sdr); + assert(glGetError() == GL_NO_ERROR); + + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); + assert(glGetError() == GL_NO_ERROR); + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetShaderInfoLog(sdr, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(success) { + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); + } else { + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); + glDeleteShader(sdr); + sdr = 0; + } + + free(info_str); + return sdr; +} + +void free_shader(unsigned int sdr) +{ + glDeleteShader(sdr); +} + +unsigned int load_vertex_shader(const char *fname) +{ + return load_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int load_pixel_shader(const char *fname) +{ + return load_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int load_shader(const char *fname, unsigned int sdr_type) +{ +#if defined(unix) || defined(__unix__) + struct stat st; +#endif + unsigned int sdr; + size_t filesize; + FILE *fp; + char *src; + + if(!(fp = fopen(fname, "r"))) { + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); + return 0; + } + +#if defined(unix) || defined(__unix__) + fstat(fileno(fp), &st); + filesize = st.st_size; +#else + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); +#endif /* unix */ + + if(!(src = malloc(filesize + 1))) { + fclose(fp); + return 0; + } + fread(src, 1, filesize, fp); + src[filesize] = 0; + fclose(fp); + + fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname); + sdr = create_shader(src, sdr_type); + + free(src); + return sdr; +} + + +unsigned int get_vertex_shader(const char *fname) +{ + return get_shader(fname, GL_VERTEX_SHADER); +} + +unsigned int get_pixel_shader(const char *fname) +{ + return get_shader(fname, GL_FRAGMENT_SHADER); +} + +unsigned int get_shader(const char *fname, unsigned int sdr_type) +{ + unsigned int sdr; + + if(!(sdr = load_shader(fname, sdr_type))) { + return 0; + } + return sdr; +} + + +/* ---- gpu programs ---- */ + +unsigned int create_program(void) +{ + unsigned int prog = glCreateProgram(); + assert(glGetError() == GL_NO_ERROR); + return prog; +} + +unsigned int create_program_link(unsigned int vs, unsigned int ps) +{ + unsigned int prog; + + if(!(prog = create_program())) { + return 0; + } + + if(vs) { + attach_shader(prog, vs); + assert(glGetError() == GL_NO_ERROR); + } + if(ps) { + attach_shader(prog, ps); + assert(glGetError() == GL_NO_ERROR); + } + + if(link_program(prog) == -1) { + free_program(prog); + return 0; + } + return prog; +} + +unsigned int create_program_load(const char *vfile, const char *pfile) +{ + unsigned int vs = 0, ps = 0; + + if(vfile && !(vs = get_vertex_shader(vfile))) { + return 0; + } + if(pfile && !(ps = get_pixel_shader(pfile))) { + return 0; + } + return create_program_link(vs, ps); +} + +void free_program(unsigned int sdr) +{ + glDeleteProgram(sdr); +} + +void attach_shader(unsigned int prog, unsigned int sdr) +{ + glAttachShader(prog, sdr); + assert(glGetError() == GL_NO_ERROR); +} + +int link_program(unsigned int prog) +{ + int linked, info_len, retval = 0; + char *info_str = 0; + + glLinkProgram(prog); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_LINK_STATUS, &linked); + assert(glGetError() == GL_NO_ERROR); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); + assert(glGetError() == GL_NO_ERROR); + + if(info_len) { + if((info_str = malloc(info_len + 1))) { + glGetProgramInfoLog(prog, info_len, 0, info_str); + assert(glGetError() == GL_NO_ERROR); + } + } + + if(linked) { + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); + } else { + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); + retval = -1; + } + + free(info_str); + return retval; +} + +int bind_program(unsigned int prog) +{ + GLenum err; + + glUseProgram(prog); + if(prog && (err = glGetError()) != GL_NO_ERROR) { + /* maybe the program is not linked, try linking first */ + if(err == GL_INVALID_OPERATION) { + if(link_program(prog) == -1) { + return -1; + } + glUseProgram(prog); + return glGetError() == GL_NO_ERROR ? 0 : -1; + } + return -1; + } + return 0; +} + +/* ugly but I'm not going to write the same bloody code over and over */ +#define BEGIN_UNIFORM_CODE \ + int loc, curr_prog; \ + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ + if(curr_prog != prog && bind_program(prog) == -1) { \ + return -1; \ + } \ + if((loc = glGetUniformLocation(prog, name)) != -1) + +#define END_UNIFORM_CODE \ + if(curr_prog != prog) { \ + bind_program(curr_prog); \ + } \ + return loc == -1 ? -1 : 0 + +int set_uniform_int(unsigned int prog, const char *name, int val) +{ + BEGIN_UNIFORM_CODE { + glUniform1i(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float(unsigned int prog, const char *name, float val) +{ + BEGIN_UNIFORM_CODE { + glUniform1f(loc, val); + } + END_UNIFORM_CODE; +} + +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) +{ + BEGIN_UNIFORM_CODE { + glUniform3f(loc, x, y, z); + } + END_UNIFORM_CODE; +} + +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) +{ + BEGIN_UNIFORM_CODE { + glUniform4f(loc, x, y, z, w); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); + } + END_UNIFORM_CODE; +} + +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) +{ + BEGIN_UNIFORM_CODE { + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); + } + END_UNIFORM_CODE; +} + +int get_attrib_loc(unsigned int prog, const char *name) +{ + int loc, curr_prog; + + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); + if(curr_prog != prog && bind_program(prog) == -1) { + return -1; + } + + loc = glGetAttribLocation(prog, (char*)name); + + if(curr_prog != prog) { + bind_program(curr_prog); + } + return loc; +} + +void set_attrib_float3(int attr_loc, float x, float y, float z) +{ + glVertexAttrib3f(attr_loc, x, y, z); +} diff -r 000000000000 -r 7aa4627e492b examples/metaballs/src/sdr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/src/sdr.h Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,49 @@ +#ifndef SDR_H_ +#define SDR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* ---- shaders ---- */ +unsigned int create_vertex_shader(const char *src); +unsigned int create_pixel_shader(const char *src); +unsigned int create_shader(const char *src, unsigned int sdr_type); +void free_shader(unsigned int sdr); + +unsigned int load_vertex_shader(const char *fname); +unsigned int load_pixel_shader(const char *fname); +unsigned int load_shader(const char *src, unsigned int sdr_type); + +unsigned int get_vertex_shader(const char *fname); +unsigned int get_pixel_shader(const char *fname); +unsigned int get_shader(const char *fname, unsigned int sdr_type); + +int add_shader(const char *fname, unsigned int sdr); +int remove_shader(const char *fname); + +/* ---- gpu programs ---- */ +unsigned int create_program(void); +unsigned int create_program_link(unsigned int vs, unsigned int ps); +unsigned int create_program_load(const char *vfile, const char *pfile); +void free_program(unsigned int sdr); + +void attach_shader(unsigned int prog, unsigned int sdr); +int link_program(unsigned int prog); +int bind_program(unsigned int prog); + +int set_uniform_int(unsigned int prog, const char *name, int val); +int set_uniform_float(unsigned int prog, const char *name, float val); +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); + +int get_attrib_loc(unsigned int prog, const char *name); +void set_attrib_float3(int attr_loc, float x, float y, float z); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SDR_H_ */ diff -r 000000000000 -r 7aa4627e492b examples/metaballs/src/test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/metaballs/src/test.c Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,307 @@ +#include +#include +#include +#include + +#include +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include "cam.h" +#include "sdr.h" +#include "metasurf.h" + +#define RES 38 + +struct metaball { + float energy; + float x, y, z; +} mball[] = { + {1.0, 0, 0, 0}, + {0.25, 0.45, 0, 0.25}, + {0.15, -0.3, 0.2, 0.1} +}; + +int num_mballs = sizeof mball / sizeof *mball; + +float eval(float x, float y, float z); +float eval_cached(float x, float y, float z); +void vertex(float x, float y, float z); +void render(void); +void disp(void); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); +void sball_button(int bn, int state); +void sball_motion(int x, int y, int z); +int parse_args(int argc, char **argv); + +int stereo; +struct metasurface *msurf; +float threshold = 12; +unsigned int sdr; +int bidx = 1; + +int main(int argc, char **argv) +{ + float amb[] = {0, 0, 0, 0}; + float lpos[] = {-0.2, 0.2, 1, 0}; + + glutInitWindowSize(1280, 720); + glutInit(&argc, argv); + + if(parse_args(argc, argv) == -1) { + return 1; + } + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (stereo ? GLUT_STEREO : 0)); + glutCreateWindow("metasurf"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutSpaceballButtonFunc(sball_button); + glutSpaceballMotionFunc(sball_motion); + + glewInit(); + + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lpos); + + glEnable(GL_NORMALIZE); + + cam_focus_dist(2.0); + cam_clip(0.1, 200.0); + cam_rotate(0, 0); + cam_dolly(2); + + msurf = msurf_create(); + msurf_eval_func(msurf, eval); + msurf_vertex_func(msurf, vertex); + msurf_threshold(msurf, threshold); + msurf_resolution(msurf, RES, RES, RES); + msurf_bounds(msurf, -1, -1, -1, 1, 1, 1); + + glClearColor(0.8, 0.8, 0.8, 1.0); + + if(!(sdr = create_program_load("sdr/vert.glsl", "sdr/frag.glsl"))) { + return 1; + } + + glutMainLoop(); + return 0; +} + +float eval(float x, float y, float z) +{ + int i; + float val = 0.0f; + + for(i=0; i +#include "metasurf.h" +#include "mcubes.h" + +#undef USE_MTETRA +#define USE_MCUBES + +#if (defined(USE_MTETRA) && defined(USE_MCUBES)) || (!defined(USE_MTETRA) && !defined(USE_MCUBES)) +#error "pick either USE_MTETRA or USE_MCUBES, not both..." +#endif + +typedef float vec3[3]; + +struct metasurface { + vec3 min, max; + int res[3]; + float thres; + + msurf_eval_func_t eval; + msurf_vertex_func_t vertex; + msurf_normal_func_t normal; + + vec3 vbuf[3]; + int nverts; +}; + +static int msurf_init(struct metasurface *ms); +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz); +#ifdef USE_MTETRA +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val); +#endif +#ifdef USE_MCUBES +static void process_cube(struct metasurface *ms, vec3 *pos, float *val); +#endif + + +struct metasurface *msurf_create(void) +{ + struct metasurface *ms; + + if(!(ms = malloc(sizeof *ms))) { + return 0; + } + if(msurf_init(ms) == -1) { + free(ms); + } + return ms; +} + +void msurf_free(struct metasurface *ms) +{ + free(ms); +} + +static int msurf_init(struct metasurface *ms) +{ + ms->thres = 0.0; + ms->eval = 0; + ms->vertex = 0; + ms->normal = 0; + ms->min[0] = ms->min[1] = ms->min[2] = -1.0; + ms->max[0] = ms->max[1] = ms->max[2] = 1.0; + ms->res[0] = ms->res[1] = ms->res[2] = 32; + ms->nverts = 0; + + return 0; +} + +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func) +{ + ms->eval = func; +} + +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func) +{ + ms->vertex = func; +} + +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func) +{ + ms->normal = func; +} + +void msurf_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax) +{ + ms->min[0] = xmin; + ms->min[1] = ymin; + ms->min[2] = zmin; + ms->max[0] = xmax; + ms->max[1] = ymax; + ms->max[2] = zmax; +} + +void msurf_resolution(struct metasurface *ms, int xres, int yres, int zres) +{ + ms->res[0] = xres; + ms->res[1] = yres; + ms->res[2] = zres; +} + +void msurf_threshold(struct metasurface *ms, float thres) +{ + ms->thres = thres; +} + + +void msurf_polygonize(struct metasurface *ms) +{ + int i, j, k; + vec3 pos, delta; + + for(i=0; i<3; i++) { + delta[i] = (ms->max[i] - ms->min[i]) / (float)ms->res[i]; + } + + pos[0] = ms->min[0]; + for(i=0; ires[0] - 1; i++) { + + pos[1] = ms->min[1]; + for(j=0; jres[1] - 1; j++) { + + pos[2] = ms->min[2]; + for(k=0; kres[2] - 1; k++) { + + process_cell(ms, pos, delta); + + pos[2] += delta[2]; + } + pos[1] += delta[1]; + } + pos[0] += delta[0]; + } +} + + +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz) +{ + int i; + vec3 p[8]; + float val[8]; + +#ifdef USE_MTETRA + static int tetra[][4] = { + {0, 2, 3, 7}, + {0, 2, 6, 7}, + {0, 4, 6, 7}, + {0, 6, 1, 2}, + {0, 6, 1, 4}, + {5, 6, 1, 4} + }; +#endif + + static const float offs[][3] = { + {0.0f, 0.0f, 0.0f}, + {1.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + {1.0f, 0.0f, 1.0f}, + {1.0f, 1.0f, 1.0f}, + {0.0f, 1.0f, 1.0f} + }; + + for(i=0; i<8; i++) { + p[i][0] = pos[0] + sz[0] * offs[i][2]; + p[i][1] = pos[1] + sz[1] * offs[i][1]; + p[i][2] = pos[2] + sz[2] * offs[i][0]; + + val[i] = ms->eval(p[i][0], p[i][1], p[i][2]); + } + +#ifdef USE_MTETRA + for(i=0; i<6; i++) { + process_tetra(ms, tetra[i], p, val); + } +#endif +#ifdef USE_MCUBES + process_cube(ms, p, val); +#endif +} + + +/* ---- marching cubes implementation ---- */ +#ifdef USE_MCUBES + +static unsigned int mc_bitcode(float *val, float thres); + +static void process_cube(struct metasurface *ms, vec3 *pos, float *val) +{ + static const int pidx[12][2] = { + {0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, + {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7} + }; + int i, j; + vec3 vert[12]; + unsigned int code = mc_bitcode(val, ms->thres); + + if(mc_edge_table[code] == 0) { + return; + } + + for(i=0; i<12; i++) { + if(mc_edge_table[code] & (1 << i)) { + int p0 = pidx[i][0]; + int p1 = pidx[i][1]; + + float t = (ms->thres - val[p0]) / (val[p1] - val[p0]); + vert[i][0] = pos[p0][0] + (pos[p1][0] - pos[p0][0]) * t; + vert[i][1] = pos[p0][1] + (pos[p1][1] - pos[p0][1]) * t; + vert[i][2] = pos[p0][2] + (pos[p1][2] - pos[p0][2]) * t; + } + } + + for(i=0; mc_tri_table[code][i] != -1; i+=3) { + for(j=0; j<3; j++) { + float *v = vert[mc_tri_table[code][i + j]]; + ms->vertex(v[0], v[1], v[2]); + } + } +} + +static unsigned int mc_bitcode(float *val, float thres) +{ + unsigned int i, res = 0; + + for(i=0; i<8; i++) { + if(val[i] > thres) { + res |= 1 << i; + } + } + return res; +} +#endif /* USE_MCUBES */ + + +/* ---- marching tetrahedra implementation (incomplete) ---- */ +#ifdef USE_MTETRA + +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres); +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev) + + +#define REVBIT(x) ((x) & 8) +#define INV(x) (~(x) & 0xf) +#define EDGE(a, b) emmit(ms, val[idx[a]], val[idx[b]], pos[idx[a]], pos[idx[b]], REVBIT(code)) +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val) +{ + unsigned int code = mt_bitcode(val[idx[0]], val[idx[1]], val[idx[2]], val[idx[3]], ms->thres); + + switch(code) { + /*case 1: + case INV(1):*/ + case 0x0e: + case 0x01: + EDGE(0, 1); + EDGE(0, 2); + EDGE(0, 3); + break; + + /*case 2: + case INV(2):*/ + case 0x0d: + case 0x02: + EDGE(1, 0); + EDGE(1, 3); + EDGE(1, 2); + break; + + /*case 3: + case INV(3):*/ + case 0x0c: + case 0x03: + EDGE(0, 3); + EDGE(0, 2); + EDGE(1, 3); + + EDGE(1, 3); + EDGE(1, 2); + EDGE(0, 2); + break; + + /*case 4: + case INV(4):*/ + case 0x0b: + case 0x04: + EDGE(2, 0); + EDGE(2, 1); + EDGE(2, 3); + break; + + /*case 5: + case INV(5):*/ + case 0x0a: + case 0x05: + EDGE(0, 1); + EDGE(2, 3); + EDGE(0, 3); + + EDGE(0, 1); + EDGE(1, 2); + EDGE(2, 3); + break; + + /*case 6: + case INV(6):*/ + case 0x09: + case 0x06: + EDGE(0, 1); + EDGE(1, 3); + EDGE(2, 3); + + EDGE(0, 1); + EDGE(0, 2); + EDGE(2, 3); + break; + + /*case 7: + case INV(7):*/ + case 0x07: + case 0x08: + EDGE(3, 0); + EDGE(3, 2); + EDGE(3, 1); + break; + + default: + break; /* cases 0 and 15 */ + } +} + +#define BIT(i) ((v##i > thres) ? (1 << i) : 0) +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres) +{ + return BIT(0) | BIT(1) | BIT(2) | BIT(3); +} + +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev) +{ + int i; + float t = (ms->thres - v0) / (v1 - v0); + + vec3 p; + for(i=0; i<3; i++) { + p[i] = p0[i] + (p1[i] - p0[i]) * t; + } + ms->vertex(p[0], p[1], p[2]); + + /*for(i=0; i<3; i++) { + ms->vbuf[ms->nverts][i] = p0[i] + (p1[i] - p0[i]) * t; + } + + if(++ms->nverts >= 3) { + ms->nverts = 0; + + for(i=0; i<3; i++) { + int idx = rev ? (2 - i) : i; + ms->vertex(ms->vbuf[idx][0], ms->vbuf[idx][1], ms->vbuf[idx][2]); + } + }*/ +} + +#endif /* USE_MTETRA */ diff -r 000000000000 -r 7aa4627e492b src/metasurf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/metasurf.h Tue Oct 25 07:34:31 2011 +0300 @@ -0,0 +1,31 @@ +#ifndef METASURF_H_ +#define METASURF_H_ + +struct metasurface; + +typedef float (*msurf_eval_func_t)(float, float, float); +typedef void (*msurf_vertex_func_t)(float, float, float); +typedef void (*msurf_normal_func_t)(float, float, float); + +#ifdef __cplusplus +extern "C" { +#endif + +struct metasurface *msurf_create(void); +void msurf_free(struct metasurface *ms); + +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func); +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func); +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func); + +void msurf_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax); +void msurf_resolution(struct metasurface *ms, int xres, int yres, int zres); +void msurf_threshold(struct metasurface *ms, float thres); + +void msurf_polygonize(struct metasurface *ms); + +#ifdef __cplusplus +} +#endif + +#endif /* METASURF_H_ */