nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@11: #include nuclear@0: #include "opengl.h" nuclear@0: #include "game.h" nuclear@7: #include "camera.h" nuclear@11: #include "sanegl.h" nuclear@17: #include "texture.h" nuclear@21: #include "shader.h" nuclear@22: #include "text.h" nuclear@24: #include "vmath/vmath.h" nuclear@7: nuclear@21: static void draw_quad(float hsz, float vsz); nuclear@0: nuclear@22: int win_width, win_height; nuclear@22: nuclear@9: static float win_aspect; nuclear@9: static int video_width, video_height; nuclear@9: static float video_aspect; nuclear@17: static struct texture *test_tex; nuclear@17: nuclear@21: static SdrProg *sdr_cam, *sdr_tex; nuclear@0: nuclear@24: static Quaternion qrot; nuclear@24: static Vector3 trans; nuclear@24: nuclear@20: extern "C" int game_init(void) nuclear@0: { nuclear@17: //glEnable(GL_DEPTH_TEST); nuclear@22: //glEnable(GL_CULL_FACE); nuclear@0: nuclear@0: glClearColor(0.4, 0.4, 0.4, 1); nuclear@8: nuclear@21: if(!(sdr_cam = get_sdrprog("sdr/vertex.glsl", "sdr/android_cam_preview.p.glsl"))) { nuclear@10: return -1; nuclear@10: } nuclear@21: if(!(sdr_tex = get_sdrprog("sdr/vertex.glsl", "sdr/tex.p.glsl"))) { nuclear@17: return -1; nuclear@17: } nuclear@17: nuclear@17: if(!(test_tex = get_texture("data/opengl.png"))) { nuclear@17: return -1; nuclear@17: } nuclear@10: nuclear@8: cam_start_video(); nuclear@9: cam_video_size(&video_width, &video_height); nuclear@9: if(video_height) { nuclear@9: video_aspect = (float)video_width / (float)video_height; nuclear@9: } else { nuclear@9: video_aspect = 1.0; nuclear@9: } nuclear@9: nuclear@9: printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@20: extern "C" void game_shutdown(void) nuclear@0: { nuclear@8: cam_shutdown(); nuclear@21: delete sdr_cam; nuclear@21: delete sdr_tex; nuclear@0: } nuclear@0: nuclear@20: extern "C" void game_display(unsigned long msec) nuclear@0: { nuclear@9: unsigned int tex; nuclear@9: const float *tex_matrix; nuclear@9: float xscale, yscale; nuclear@9: nuclear@8: cam_update(); nuclear@9: tex = cam_texture(); nuclear@9: tex_matrix = cam_texture_matrix(); nuclear@7: nuclear@4: //float tsec = (float)msec / 1000.0f; nuclear@0: nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@11: gl_matrix_mode(GL_MODELVIEW); nuclear@11: gl_load_identity(); nuclear@11: gl_matrix_mode(GL_TEXTURE); nuclear@11: gl_load_matrixf(tex_matrix); nuclear@11: nuclear@21: sdr_cam->bind(); nuclear@10: glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); nuclear@7: nuclear@9: if(video_aspect > win_aspect) { nuclear@9: xscale = 1.0; nuclear@9: yscale = 1.0 / video_aspect; nuclear@9: } else { nuclear@9: xscale = video_aspect; nuclear@9: yscale = 1.0; nuclear@9: } nuclear@21: draw_quad(xscale, yscale); nuclear@17: nuclear@17: gl_matrix_mode(GL_TEXTURE); nuclear@17: gl_load_identity(); nuclear@17: gl_translatef(0, 1, 0); nuclear@17: gl_scalef(1, -1, 1); nuclear@17: gl_matrix_mode(GL_MODELVIEW); nuclear@17: gl_load_identity(); nuclear@17: gl_scalef((float)test_tex->width / (float)test_tex->height, 1, 1); nuclear@17: nuclear@21: sdr_tex->bind(); nuclear@17: glBindTexture(GL_TEXTURE_2D, test_tex->texid); nuclear@17: nuclear@17: glEnable(GL_BLEND); nuclear@17: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nuclear@22: draw_quad(0.5, 0.5); nuclear@22: glDisable(GL_BLEND); nuclear@17: nuclear@22: gl_matrix_mode(GL_TEXTURE); nuclear@22: gl_load_identity(); nuclear@17: nuclear@22: nuclear@24: // print the rotation quaternion nuclear@22: text_color(1, 1, 1, 1); nuclear@24: text_position(0, 0); nuclear@24: text_printf("translation (% .3f, % .3f, % .3f)", trans.x, trans.y, trans.z); nuclear@24: text_position(0, 1); nuclear@24: text_printf("Rotation quat ([% 1.3f, % 1.3f, % 1.3f], % 1.3f)", qrot.v.x, qrot.v.y, qrot.v.z, qrot.s); nuclear@7: } nuclear@7: nuclear@21: static void draw_quad(float hsz, float vsz) nuclear@7: { nuclear@7: static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; nuclear@9: static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; nuclear@7: nuclear@11: gl_matrix_mode(GL_MODELVIEW); nuclear@11: gl_push_matrix(); nuclear@11: gl_scalef(hsz, vsz, 1); nuclear@11: nuclear@21: if(SdrProg::active) { nuclear@21: gl_apply_xform(SdrProg::active->get_globj()); nuclear@21: } nuclear@7: nuclear@21: glEnableVertexAttribArray(SDR_ATTR_VERTEX); nuclear@21: glEnableVertexAttribArray(SDR_ATTR_TEXCOORD); nuclear@21: glVertexAttribPointer(SDR_ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr); nuclear@21: glVertexAttribPointer(SDR_ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr); nuclear@7: nuclear@8: glDrawArrays(GL_TRIANGLE_FAN, 0, 4); nuclear@7: nuclear@21: glDisableVertexAttribArray(SDR_ATTR_VERTEX); nuclear@21: glDisableVertexAttribArray(SDR_ATTR_TEXCOORD); nuclear@11: nuclear@11: gl_pop_matrix(); nuclear@0: } nuclear@0: nuclear@20: extern "C" void game_reshape(int x, int y) nuclear@0: { nuclear@0: win_width = x; nuclear@0: win_height = y; nuclear@9: win_aspect = y ? (float)x / (float)y : 1.0; nuclear@0: glViewport(0, 0, x, y); nuclear@0: nuclear@11: gl_matrix_mode(GL_PROJECTION); nuclear@11: gl_load_identity(); nuclear@11: gl_scalef((float)win_height / (float)win_width, 1, 1); nuclear@0: } nuclear@0: nuclear@20: extern "C" void game_keyboard(int key, int pressed) nuclear@0: { nuclear@0: if(!pressed) return; nuclear@0: nuclear@0: switch(key) { nuclear@0: case 27: nuclear@0: exit(0); nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: #define MAX_TOUCH_IDS 16 nuclear@0: static struct { nuclear@0: int bnstate[8]; nuclear@0: int prev_x, prev_y; nuclear@0: } mstate[MAX_TOUCH_IDS]; nuclear@0: nuclear@20: extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y) nuclear@0: { nuclear@0: if(id >= MAX_TOUCH_IDS) return; nuclear@0: nuclear@0: mstate[id].prev_x = x; nuclear@0: mstate[id].prev_y = y; nuclear@0: mstate[id].bnstate[bn] = pressed; nuclear@0: } nuclear@0: nuclear@20: extern "C" void game_mouse_motion(int id, int x, int y) nuclear@0: { nuclear@0: /* nuclear@0: int dx, dy, cx, cy; nuclear@0: nuclear@0: if(id >= MAX_TOUCH_IDS) return; nuclear@0: nuclear@0: cx = win_width / 2; nuclear@0: cy = win_height / 2; nuclear@0: nuclear@0: dx = x - mstate[id].prev_x; nuclear@0: dy = y - mstate[id].prev_y; nuclear@0: mstate[id].prev_x = x; nuclear@0: mstate[id].prev_y = y; nuclear@0: nuclear@0: if(!dx && !dy) return; nuclear@0: nuclear@0: if(mouselook || mstate[id].bnstate[0]) { nuclear@0: player_turn(&player, dx * 0.5, dy * 0.5); nuclear@0: } nuclear@0: if(mstate[id].bnstate[2]) { nuclear@0: dbg_cam_dist += 0.1 * dy; nuclear@0: if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0; nuclear@0: } nuclear@0: nuclear@0: if(mouselook) { nuclear@0: warping_mouse = 1; nuclear@0: set_mouse_pos(cx, cy); nuclear@0: mstate[id].prev_x = cx; nuclear@0: mstate[id].prev_y = cy; nuclear@0: } nuclear@0: */ nuclear@0: } nuclear@0: nuclear@24: void game_6dof_translation(float dx, float dy, float dz) nuclear@24: { nuclear@24: trans.x = dx; nuclear@24: trans.y = dy; nuclear@24: trans.z = dz; nuclear@24: } nuclear@24: nuclear@24: void game_6dof_rotation(float qx, float qy, float qz, float qw) nuclear@24: { nuclear@24: qrot.v.x = qx; nuclear@24: qrot.v.y = qy; nuclear@24: qrot.v.z = qz; nuclear@24: qrot.s = qw; nuclear@24: }