# HG changeset patch # User John Tsiombikas # Date 1335054918 -10800 # Node ID 94d4c60af43552520e323654a7bc95bdf2ac1c9c # Parent 472c28b8b875ee353844128926cbaf43a86e22d5 some progress diff -r 472c28b8b875 -r 94d4c60af435 sdr/vein.p.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/vein.p.glsl Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,15 @@ +varying vec3 vpos, vnorm; +varying vec3 ldir, vdir; + +void main() +{ + vec3 n = normalize(vnorm); + vec3 l = normalize(ldir); + vec3 v = normalize(vdir); + vec3 h = normalize(l + v); + + vec3 diff = vec3(0.8, 0.25, 0.2) * max(dot(l, n), 0.0); + vec3 spec = vec3(0.6, 0.4, 0.32) * pow(max(dot(h, n), 0.0), 60.0); + + gl_FragColor = vec4(diff + spec, 1.0); +} diff -r 472c28b8b875 -r 94d4c60af435 sdr/vein.v.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdr/vein.v.glsl Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,26 @@ +attribute vec3 attr_tang; + +varying vec3 vpos, vnorm; +varying vec3 ldir, vdir; + +void main() +{ + gl_Position = ftransform(); + vpos = (gl_ModelViewMatrix * gl_Vertex).xyz; + vec3 norm = gl_NormalMatrix * gl_Normal; + vec3 tang = gl_NormalMatrix * attr_tang; + + vec3 n = normalize(norm); + vec3 t = normalize(tang); + vec3 b = cross(n, t); + + mat3 tbn_mat = mat3( + t.x, b.x, n.x, + t.y, b.y, n.y, + t.z, b.z, n.z); + ldir = tbn_mat * (gl_LightSource[0].position.xyz - vpos); + vdir = tbn_mat * -vpos; + vnorm = n; + + gl_TexCoord[0] = gl_MultiTexCoord0; +} diff -r 472c28b8b875 -r 94d4c60af435 src/cockpit.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cockpit.cc Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,52 @@ +#include "opengl.h" +#include "cockpit.h" +#include "tex.h" + +static unsigned int tex; + +bool cockpit_init() +{ + if(!(tex = load_texture("data/cockpit.png"))) { + return false; + } + return true; +} + +void cockpit_destroy() +{ + free_texture(tex); +} + +void cockpit_draw() +{ + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + bind_texture(tex); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_QUADS); + glColor3f(1, 1, 1); + glTexCoord2f(0, 1); glVertex2f(-1, -1); + glTexCoord2f(1, 1); glVertex2f(1, -1); + glTexCoord2f(1, 0); glVertex2f(1, 1); + glTexCoord2f(0, 0); glVertex2f(-1, 1); + glEnd(); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + bind_texture(0); + + glPopAttrib(); +} diff -r 472c28b8b875 -r 94d4c60af435 src/cockpit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cockpit.h Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,9 @@ +#ifndef COCKPIT_H_ +#define COCKPIT_H_ + +bool cockpit_init(); +void cockpit_destroy(); + +void cockpit_draw(); + +#endif // COCKPIT_H_ diff -r 472c28b8b875 -r 94d4c60af435 src/game.cc --- a/src/game.cc Sat Apr 21 23:03:36 2012 +0300 +++ b/src/game.cc Sun Apr 22 03:35:18 2012 +0300 @@ -4,6 +4,7 @@ #include "vein.h" #include "ship.h" #include "camera.h" +#include "cockpit.h" static Vein *vein; static Ship ship; @@ -19,20 +20,28 @@ { glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); float lpos[] = {-1, 1, 1, 0}; glLightfv(GL_LIGHT0, GL_POSITION, lpos); - // initialize the only level (vein) + // initialize the cockpit + if(!cockpit_init()) { + return false; + } + + // initialize the only level vein = new Vein; + if(!vein->init()) { + return false; + } return true; } void game_shutdown() { + delete vein; + cockpit_destroy(); exit(0); } @@ -54,19 +63,18 @@ if(keystate['s'] || keystate['S']) { ship.accelerate(-1.0 * dt); } - // XXX change to mouselook if(keystate['d'] || keystate['D']) { - ship.turn(-1.0 * dt, 0.0); + ship.accelerate_side(1.0 * dt); } if(keystate['a'] || keystate['A']) { - ship.turn(1.0 * dt, 0.0); + ship.accelerate_side(-1.0 * dt); } - if(keystate['e'] || keystate['E']) { + /*if(keystate['e'] || keystate['E']) { ship.turn(0.0, 1.0 * dt); } if(keystate['c'] || keystate['C']) { ship.turn(0.0, -1.0 * dt); - } + }*/ ship.update(dt); @@ -76,14 +84,20 @@ void game_draw() { glMatrixMode(GL_MODELVIEW); - dbgcam.use(); if(dbg_inside) { load_gl_matrix(ship.get_matrix().inverse()); + } else { + dbgcam.use(); } vein->draw(ship.get_position()); - ship.dbg_draw(); + + if(!dbg_inside) { + ship.dbg_draw(); + } else { + cockpit_draw(); + } } void game_input_keyb(int key, int state) @@ -96,6 +110,13 @@ case '\b': dbg_inside = !dbg_inside; + if(dbg_inside) { + glutPassiveMotionFunc(game_input_mmotion); + glutSetCursor(GLUT_CURSOR_NONE); + } else { + glutPassiveMotionFunc(0); + glutSetCursor(GLUT_CURSOR_INHERIT); + } break; default: @@ -122,15 +143,28 @@ void game_input_mmotion(int x, int y) { + static bool ignore_next; int dx = x - prev_x; int dy = y - prev_y; prev_x = x; prev_y = y; - if(bnstate[0]) { - dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0); + if(ignore_next) { + ignore_next = false; + return; } - if(bnstate[2]) { - dbgcam.input_zoom(10.0 * dy / win_ysz); + + if(dbg_inside) { + ship.turn((float)-dx / win_xsz, (float)-dy / win_ysz); + + ignore_next = true; + glutWarpPointer(win_xsz / 2, win_ysz / 2); + } else { + if(bnstate[0]) { + dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0); + } + if(bnstate[2]) { + dbgcam.input_zoom(10.0 * dy / win_ysz); + } } } diff -r 472c28b8b875 -r 94d4c60af435 src/geom.cc --- a/src/geom.cc Sat Apr 21 23:03:36 2012 +0300 +++ b/src/geom.cc Sun Apr 22 03:35:18 2012 +0300 @@ -7,7 +7,7 @@ #define ELEM_TYPE GL_DOUBLE #endif -void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf) +void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf, int attr_tang_loc) { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, ELEM_TYPE, sizeof *vbuf, &vbuf->pos); @@ -18,6 +18,11 @@ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, ELEM_TYPE, sizeof *vbuf, &vbuf->tc); + if(attr_tang_loc >= 0) { + glEnableVertexAttribArrayARB(attr_tang_loc); + glVertexAttribPointerARB(attr_tang_loc, 3, ELEM_TYPE, GL_FALSE, sizeof *vbuf, &vbuf->tang); + } + if(ibuf) { glDrawElements(prim, num_verts, GL_UNSIGNED_INT, ibuf); } else { @@ -27,6 +32,10 @@ glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if(attr_tang_loc >= 0) { + glDisableVertexAttribArrayARB(attr_tang_loc); + } #if 0 glBegin(GL_QUADS); for(int i=0; i #endif +#ifdef __cplusplus #include void load_gl_matrix(const Matrix4x4 &mat); void mult_gl_matrix(const Matrix4x4 &mat); +#endif /* __cplusplus */ #endif /* OPENGL_H_ */ diff -r 472c28b8b875 -r 94d4c60af435 src/sdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.c Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,328 @@ +#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((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ + return -1; \ + } \ + if((loc = glGetUniformLocation(prog, name)) != -1) + +#define END_UNIFORM_CODE \ + if((unsigned int)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((unsigned int)curr_prog != prog && bind_program(prog) == -1) { + return -1; + } + + loc = glGetAttribLocation(prog, (char*)name); + + if((unsigned int)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 472c28b8b875 -r 94d4c60af435 src/sdr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdr.h Sun Apr 22 03:35:18 2012 +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 472c28b8b875 -r 94d4c60af435 src/ship.cc --- a/src/ship.cc Sat Apr 21 23:03:36 2012 +0300 +++ b/src/ship.cc Sun Apr 22 03:35:18 2012 +0300 @@ -11,6 +11,11 @@ velocity += get_direction() * a; } +void Ship::accelerate_side(double a) +{ + velocity += get_right() * a; +} + void Ship::turn(double yaw, double pitch) { Quaternion qyaw(Vector3(0, 1, 0), yaw); @@ -37,6 +42,12 @@ return dir.transformed(rot); } +Vector3 Ship::get_right() const +{ + static const Vector3 dir{1, 0, 0}; + return dir.transformed(rot); +} + Matrix4x4 Ship::get_matrix() const { Matrix3x3 rmat = rot.get_rotation_matrix().transposed(); diff -r 472c28b8b875 -r 94d4c60af435 src/ship.h --- a/src/ship.h Sat Apr 21 23:03:36 2012 +0300 +++ b/src/ship.h Sun Apr 22 03:35:18 2012 +0300 @@ -8,19 +8,20 @@ private: Vector3 pos, velocity; Quaternion rot; - //double theta, phi; double friction; public: Ship(); void accelerate(double a); + void accelerate_side(double a); void turn(double yaw, double pitch); void update(time_sec_t dt); const Vector3 &get_position() const; Vector3 get_direction() const; + Vector3 get_right() const; Matrix4x4 get_matrix() const; diff -r 472c28b8b875 -r 94d4c60af435 src/sys.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sys.c Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,20 @@ +#include "sys.h" + +#if defined(__unix__) +#include +#elif defined(WIN32) +#include +#elif defined(__APPLE__) +#error "not ported to mac yet" +#else +#error "unrecognized or unsupported platform" +#endif + +int sys_lock_mouse(void) +{ + return -1; +} + +void sys_unlock_mouse(void) +{ +} diff -r 472c28b8b875 -r 94d4c60af435 src/sys.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sys.h Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,15 @@ +#ifndef SYS_H_ +#define SYS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int sys_lock_mouse(void); +void sys_unlock_mouse(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYS_H_ */ diff -r 472c28b8b875 -r 94d4c60af435 src/tex.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tex.c Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,65 @@ +#include +#include "opengl.h" + +static void bind_common(GLenum type, unsigned int tex, int tex_unit); + +unsigned int load_texture(const char *fname) +{ + unsigned int tex; + struct img_pixmap img; + int intfmt, fmt, type; + + img_init(&img); + if(img_load(&img, fname) == -1) { + fprintf(stderr, "failed to load texture: %s\n", fname); + return 0; + } + intfmt = img_glintfmt(&img); + fmt = img_glfmt(&img); + type = img_gltype(&img); + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, 0, intfmt, img.width, img.height, 0, fmt, type, img.pixels); + img_destroy(&img); + return tex; +} + +unsigned int load_texture_cube(const char *fname) +{ + /* TODO implement */ + return 0; +} + +void free_texture(unsigned int tex) +{ + if(tex && glIsTexture(tex)) { + glDeleteTextures(1, &tex); + } +} + +void bind_texture(unsigned int tex, int tex_unit) +{ + bind_common(GL_TEXTURE_2D, tex, tex_unit); +} + +void bind_texture_cube(unsigned int tex, int tex_unit) +{ + bind_common(GL_TEXTURE_CUBE_MAP, tex, tex_unit); +} + +static void bind_common(GLenum type, unsigned int tex, int tex_unit) +{ + glActiveTextureARB(GL_TEXTURE0 + (GLenum)tex_unit); + if(tex) { + glBindTexture(type, tex); + glEnable(type); + } else { + glDisable(type); + } + glActiveTextureARB(GL_TEXTURE0); +} diff -r 472c28b8b875 -r 94d4c60af435 src/tex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tex.h Sun Apr 22 03:35:18 2012 +0300 @@ -0,0 +1,21 @@ +#ifndef TEX_H_ +#define TEX_H_ + +#ifdef __cplusplus +extern "C" { +#define TEX_DEFARG(arg, val) arg = val +#else +#define TEX_DEFARG(arg, val) arg +#endif + +unsigned int load_texture(const char *fname); +void free_texture(unsigned int tex); + +void bind_texture(unsigned int tex, int TEX_DEFARG(tex_unit, 0)); +void bind_texture_cube(unsigned int tex, int TEX_DEFARG(tex_unit, 0)); + +#ifdef __cplusplus +} +#endif + +#endif /* TEX_H_ */ diff -r 472c28b8b875 -r 94d4c60af435 src/vein.cc --- a/src/vein.cc Sat Apr 21 23:03:36 2012 +0300 +++ b/src/vein.cc Sun Apr 22 03:35:18 2012 +0300 @@ -1,3 +1,4 @@ +#include #ifndef _MSC_VER #include #else @@ -5,11 +6,12 @@ #endif #include "vein.h" #include "geom.h" +#include "sdr.h" Vein::Vein() { - gen_dist = 8.0; - subdiv = 8; + gen_dist = 16.0; + subdiv = 16; ring_subdiv = 16; rad = 1.0; @@ -23,14 +25,16 @@ Vector3 Vein::calc_center(const Vector3 &ppos) const { - // TODO add variation - return Vector3(0.0, 0.0, ppos.z); + Vector3 pt{0, 0, ppos.z}; + pt.x = sin(ppos.z * 0.75); + pt.y = cos(ppos.z * 0.2) * 0.6; + return pt; } Vector3 Vein::calc_dir(const Vector3 &ppos) const { - // TODO add variation - return Vector3(0, 0, 1); + Vector3 dir = calc_center(ppos + Vector3(0, 0, 0.01)) - calc_center(ppos - Vector3(0, 0, 0.01)); + return dir.normalized(); } void Vein::build_idxbuf() @@ -53,6 +57,18 @@ } } +bool Vein::init() +{ + if(!(sdr = create_program_load("sdr/vein.v.glsl", "sdr/vein.p.glsl"))) { + fprintf(stderr, "failed to load vein shaders\n"); + return false; + } + if((attr_tang_loc = get_attrib_loc(sdr, "attr_tang")) == -1) { + fprintf(stderr, "can't find tangent attribute!\n"); + } + return true; +} + void Vein::draw(const Vector3 &ppos) const { float start_z = ppos.z - gen_dist / 2.0; @@ -75,16 +91,17 @@ up = cross_product(dir, right); Matrix3x3 vrot{right, up, dir}; - //Quaternion vrot(dri, dtheta); + vrot.transpose(); float theta = 0.0, dtheta = 2.0 * M_PI / ring_subdiv; for(int j=0; jpos = vec; vptr->norm = cent - vec; - vptr->tang = Vector3(); // TODO + vptr->tang = dir; vptr->tc = Vector2(); // TODO vptr++; @@ -100,5 +117,7 @@ } // awesome, now draw it - draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf); + bind_program(sdr); + draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf, attr_tang_loc); + bind_program(0); } diff -r 472c28b8b875 -r 94d4c60af435 src/vein.h --- a/src/vein.h Sat Apr 21 23:03:36 2012 +0300 +++ b/src/vein.h Sun Apr 22 03:35:18 2012 +0300 @@ -10,6 +10,8 @@ int subdiv, ring_subdiv; unsigned int *idxbuf; + unsigned int sdr; + int attr_tang_loc; Vector3 calc_center(const Vector3 &ppos) const; Vector3 calc_dir(const Vector3 &ppos) const; @@ -20,6 +22,8 @@ Vein(); ~Vein(); + bool init(); + void draw(const Vector3 &player_pos) const; };