nuclear@2: #include nuclear@18: #include nuclear@2: #include nuclear@3: #include nuclear@1: #include "opengl.h" nuclear@0: #include "istereo.h" nuclear@2: #include "sanegl.h" nuclear@2: #include "sdr.h" nuclear@4: #include "respath.h" nuclear@14: #include "tex.h" nuclear@19: #include "cam.h" nuclear@27: #include "vmath.h" nuclear@18: #include "config.h" nuclear@4: nuclear@19: static void render(float t); nuclear@19: static void draw_tunnel(float t); nuclear@27: static void tunnel_vertex(float u, float v, float du, float dv, int tang_loc, float t); nuclear@27: static vec3_t calc_text_pos(float sec); nuclear@27: static void draw_text(float idx, vec3_t tpos, float alpha); nuclear@19: static void worm(float t, float z, float *tx, float *ty); nuclear@4: static unsigned int get_shader_program(const char *vfile, const char *pfile); nuclear@18: static float get_sec(void); nuclear@2: nuclear@27: unsigned int prog, prog_simple, prog_tunnel, prog_text; nuclear@26: unsigned int tex, tex_stones, tex_normal, tex_text; nuclear@0: nuclear@21: int view_xsz, view_ysz; nuclear@21: nuclear@24: #ifdef IPHONE nuclear@21: int stereo = 1; nuclear@24: #else nuclear@24: int stereo = 0; nuclear@24: #endif nuclear@30: int use_bump = 0; nuclear@18: nuclear@18: /* construction parameters */ nuclear@18: int sides = 24; nuclear@18: int segm = 20; nuclear@27: float tunnel_speed = 0.75; nuclear@18: float ring_height = 0.5; nuclear@27: float text_period = 13.0; nuclear@27: float text_speed = 2.2; nuclear@18: nuclear@30: float split = 0.5275; nuclear@18: nuclear@0: int init(void) nuclear@0: { nuclear@4: add_resource_path("sdr"); nuclear@14: add_resource_path("data"); nuclear@3: nuclear@27: if(!(prog_simple = get_shader_program("test.v.glsl", "test.p.glsl"))) { nuclear@27: return -1; nuclear@27: } nuclear@27: if(!(prog_tunnel = get_shader_program("tunnel.v.glsl", "tunnel.p.glsl"))) { nuclear@27: return -1; nuclear@27: } nuclear@27: if(!(prog_text = get_shader_program("text.v.glsl", "text.p.glsl"))) { nuclear@2: return -1; nuclear@2: } nuclear@14: nuclear@26: if(!(tex = load_texture(find_resource("tiles.jpg", 0, 0)))) { nuclear@27: return -1; nuclear@27: } nuclear@27: if(!(tex_stones = load_texture(find_resource("stonewall.jpg", 0, 0)))) { nuclear@27: return -1; nuclear@27: } nuclear@27: if(!(tex_normal = load_texture(find_resource("stonewall_normal.jpg", 0, 0)))) { nuclear@27: return -1; nuclear@27: } nuclear@27: if(!(tex_text = load_texture(find_resource("text.png", 0, 0)))) { nuclear@14: return -1; nuclear@14: } nuclear@14: nuclear@27: glEnable(GL_DEPTH_TEST); nuclear@27: glEnable(GL_CULL_FACE); nuclear@27: nuclear@30: cam_fov(42.5); nuclear@30: cam_clip(0.5, 250.0); nuclear@21: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void cleanup(void) nuclear@0: { nuclear@2: free_program(prog); nuclear@0: } nuclear@0: nuclear@0: void redraw(void) nuclear@0: { nuclear@19: float pan_x, pan_y, z; nuclear@19: float tsec = get_sec(); nuclear@18: nuclear@21: z = ring_height * segm; nuclear@19: worm(tsec, z, &pan_x, &pan_y); nuclear@19: nuclear@27: if(use_bump) { nuclear@27: glClearColor(0.01, 0.01, 0.01, 1.0); nuclear@27: tunnel_speed = 0.5; nuclear@27: } else { nuclear@27: glClearColor(0.6, 0.6, 0.6, 1.0); nuclear@27: tunnel_speed = 0.75; nuclear@27: } nuclear@27: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@21: nuclear@19: if(stereo) { nuclear@21: int split_pt = (int)((float)view_ysz * split); nuclear@21: nuclear@23: /* right eye */ nuclear@21: glViewport(0, 0, view_xsz, split_pt); nuclear@21: cam_aspect((float)split_pt / (float)view_xsz); nuclear@19: nuclear@21: gl_matrix_mode(GL_PROJECTION); nuclear@21: gl_load_identity(); nuclear@23: cam_stereo_proj_matrix(CAM_RIGHT); nuclear@23: gl_rotatef(-90, 0, 0, 1); nuclear@23: nuclear@23: gl_matrix_mode(GL_MODELVIEW); nuclear@23: gl_load_identity(); nuclear@23: cam_stereo_view_matrix(CAM_RIGHT); nuclear@23: gl_translatef(-pan_x, -pan_y, -1.1 * ring_height * segm); nuclear@23: /*gl_rotatef(-90, 0, 0, 1);*/ nuclear@23: nuclear@23: render(tsec); nuclear@23: nuclear@23: /* left eye */ nuclear@23: glViewport(0, split_pt, view_xsz, view_ysz - split_pt); nuclear@23: cam_aspect((float)(view_ysz - split_pt) / (float)view_xsz); nuclear@23: nuclear@23: gl_matrix_mode(GL_PROJECTION); nuclear@23: gl_load_identity(); nuclear@19: cam_stereo_proj_matrix(CAM_LEFT); nuclear@21: gl_rotatef(-90, 0, 0, 1); nuclear@19: nuclear@21: gl_matrix_mode(GL_MODELVIEW); nuclear@21: gl_load_identity(); nuclear@19: cam_stereo_view_matrix(CAM_LEFT); nuclear@21: gl_translatef(-pan_x, -pan_y, -1.1 * ring_height * segm); nuclear@21: /*gl_rotatef(-90, 0, 0, 1);*/ nuclear@19: nuclear@19: render(tsec); nuclear@19: } else { nuclear@19: gl_matrix_mode(GL_MODELVIEW); nuclear@19: gl_load_identity(); nuclear@19: cam_view_matrix(); nuclear@19: gl_translatef(-pan_x, -pan_y, -1.1 * ring_height * segm); nuclear@19: nuclear@19: render(tsec); nuclear@19: } nuclear@19: nuclear@2: assert(glGetError() == GL_NO_ERROR); nuclear@0: } nuclear@2: nuclear@19: static void render(float t) nuclear@19: { nuclear@27: int i; nuclear@27: float text_line; nuclear@27: nuclear@19: draw_tunnel(t); nuclear@27: nuclear@30: if(use_bump) { nuclear@30: glDepthMask(0); nuclear@30: text_line = floor((text_speed * t) / text_period); nuclear@30: for(i=0; i<8; i++) { nuclear@30: vec3_t tpos = calc_text_pos(t - (float)i * 0.015); nuclear@30: draw_text(text_line, tpos, 1.5 / (float)i); nuclear@30: } nuclear@30: glDepthMask(1); nuclear@27: } nuclear@19: } nuclear@19: nuclear@19: static void draw_tunnel(float t) nuclear@19: { nuclear@19: static const float uoffs[] = {0.0, 0.0, 1.0, 1.0}; nuclear@19: static const float voffs[] = {0.0, 1.0, 1.0, 0.0}; nuclear@27: int i, j, k, tang_loc = -1; nuclear@19: float du, dv; nuclear@19: nuclear@27: prog = use_bump ? prog_tunnel : prog_simple; nuclear@27: nuclear@19: bind_program(prog); nuclear@19: set_uniform_float(prog, "t", t); nuclear@27: nuclear@27: if(use_bump) { nuclear@27: vec3_t ltpos = calc_text_pos(t); nuclear@27: nuclear@30: bind_texture(tex_normal, 1); nuclear@27: set_uniform_int(prog, "tex_norm", 1); nuclear@30: bind_texture(tex_stones, 0); nuclear@30: set_uniform_int(prog, "tex", 0); nuclear@30: nuclear@27: set_uniform_float4(prog, "light_pos", ltpos.x, ltpos.y, ltpos.z, 1.0); nuclear@27: tang_loc = get_attrib_loc(prog, "attr_tangent"); nuclear@30: } else { nuclear@30: bind_texture(tex, 0); nuclear@30: set_uniform_int(prog, "tex", 0); nuclear@27: } nuclear@19: nuclear@24: gl_matrix_mode(GL_TEXTURE); nuclear@24: gl_load_identity(); nuclear@32: gl_translatef(0, -fmod(t * tunnel_speed, 1.0), 0); nuclear@19: nuclear@19: gl_begin(GL_QUADS); nuclear@19: gl_color3f(1.0, 1.0, 1.0); nuclear@19: nuclear@19: du = 1.0 / sides; nuclear@19: dv = 1.0 / segm; nuclear@19: nuclear@19: for(i=0; i 1.0 ? 1.0 : alpha); nuclear@27: nuclear@27: gl_texcoord2f(0, 1); nuclear@27: gl_vertex3f(-1, -0.2, 0); nuclear@27: nuclear@27: gl_texcoord2f(1, 1); nuclear@27: gl_vertex3f(1, -0.2, 0); nuclear@27: nuclear@27: gl_texcoord2f(1, 0); nuclear@27: gl_vertex3f(1, 0.2, 0); nuclear@27: nuclear@27: gl_texcoord2f(0, 0); nuclear@27: gl_vertex3f(-1, 0.2, 0); nuclear@27: gl_end(); nuclear@27: nuclear@27: bind_texture(0, 0); nuclear@27: glDisable(GL_BLEND); nuclear@27: nuclear@27: gl_pop_matrix(); nuclear@27: } nuclear@19: nuclear@19: nuclear@19: static void worm(float t, float z, float *tx, float *ty) nuclear@19: { nuclear@19: float x, y; nuclear@19: x = sin(t) + cos(t + z) + sin(t * 2.0 + z) / 2.0; nuclear@19: y = cos(t) + sin(t + z) + cos(t * 2.0 + z) / 2.0; nuclear@19: nuclear@19: *tx = x * 0.5; nuclear@19: *ty = y * 0.5; nuclear@19: } nuclear@19: nuclear@19: nuclear@2: void reshape(int x, int y) nuclear@2: { nuclear@2: glViewport(0, 0, x, y); nuclear@2: nuclear@2: gl_matrix_mode(GL_PROJECTION); nuclear@2: gl_load_identity(); nuclear@21: glu_perspective(40.0, (float)x / (float)y, 0.5, 500.0); nuclear@21: nuclear@21: view_xsz = x; nuclear@21: view_ysz = y; nuclear@2: } nuclear@4: nuclear@4: static unsigned int get_shader_program(const char *vfile, const char *pfile) nuclear@4: { nuclear@4: unsigned int prog, vs, ps; nuclear@4: nuclear@4: if(!(vs = get_vertex_shader(find_resource(vfile, 0, 0)))) { nuclear@27: return 0; nuclear@4: } nuclear@4: if(!(ps = get_pixel_shader(find_resource(pfile, 0, 0)))) { nuclear@27: return 0; nuclear@4: } nuclear@4: nuclear@4: if(!(prog = create_program_link(vs, ps))) { nuclear@27: return 0; nuclear@4: } nuclear@4: return prog; nuclear@4: } nuclear@18: nuclear@18: nuclear@18: #ifdef IPHONE nuclear@18: #include nuclear@18: nuclear@18: static float get_sec(void) nuclear@18: { nuclear@18: static float first; nuclear@18: static int init; nuclear@18: nuclear@18: if(!init) { nuclear@18: init = 1; nuclear@18: first = CACurrentMediaTime(); nuclear@18: return 0.0f; nuclear@18: } nuclear@18: return CACurrentMediaTime() - first; nuclear@18: } nuclear@18: nuclear@18: #else nuclear@18: nuclear@18: static float get_sec(void) nuclear@18: { nuclear@18: return (float)glutGet(GLUT_ELAPSED_TIME) / 1000.0f; nuclear@18: } nuclear@18: #endif