nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: #include "opengl.h" nuclear@0: #include "game.h" nuclear@0: #include "input.h" nuclear@0: #include "datapath.h" nuclear@0: #include "shader.h" nuclear@0: #include "sdrman.h" nuclear@0: #include "unistate.h" nuclear@0: #include "scr_debug.h" nuclear@0: #include "scr_game.h" nuclear@0: #include "logger.h" nuclear@0: #include "mesh.h" nuclear@0: #include "audio/audio.h" nuclear@0: #include "timer.h" nuclear@0: nuclear@0: static void toggle_debug(); nuclear@0: nuclear@0: static char *def_argv[] = { (char*)"game", 0 }; nuclear@0: nuclear@0: static int argc = 1; nuclear@0: static char **argv = def_argv; nuclear@0: static int width, height; nuclear@0: nuclear@0: static std::vector screens; nuclear@0: static Screen *debug_screen; nuclear@0: nuclear@0: static void standard_state_uniforms(); nuclear@0: static bool create_screens(); nuclear@0: nuclear@0: ShaderProg *defsdr; nuclear@0: Timer timer; nuclear@0: nuclear@0: void game_set_args(int argc, char **argv) nuclear@0: { nuclear@0: ::argc = argc; nuclear@0: ::argv = argv; nuclear@0: } nuclear@0: nuclear@0: bool game_init() nuclear@0: { nuclear@0: init_opengl(); nuclear@0: CHECKGLERR; nuclear@0: nuclear@0: /* nuclear@0: #ifdef __GLEW_H__ nuclear@0: if(GLEW_ARB_multisample) { nuclear@0: info_log("enabling multisampling\n"); nuclear@0: glEnable(GL_MULTISAMPLE); nuclear@0: } else { nuclear@0: info_log("no multisampling support, will try old-style smoothing\n"); nuclear@0: // line smoothing enabled when needed (mostly by tools) nuclear@0: } nuclear@0: #endif nuclear@0: */ nuclear@0: nuclear@0: // The configuration file is expected to be on the root nuclear@0: // of our data archive. nuclear@0: add_data_path("data"); nuclear@0: add_data_path("sdr"); nuclear@0: nuclear@0: standard_state_uniforms(); nuclear@0: nuclear@0: if(!(defsdr = get_sdrprog("default.v.glsl", "default.p.glsl"))) { nuclear@0: error_log("failed to load default shader, aborting\n"); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: glEnable(GL_DEPTH_TEST); nuclear@0: glEnable(GL_CULL_FACE); nuclear@0: nuclear@0: init_audio(); nuclear@0: nuclear@0: if(!create_screens()) { nuclear@0: error_log("failed to create scenes\n"); nuclear@0: return false; nuclear@0: } nuclear@0: #if defined(TARGET_IPHONE) && !defined(NDEBUG) nuclear@0: //toggle_debug(); nuclear@0: #endif nuclear@0: nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: void game_cleanup() nuclear@0: { nuclear@0: destroy_audio(); nuclear@0: nuclear@0: delete defsdr; nuclear@0: nuclear@0: // pop all screens nuclear@0: while(current_screen()) { nuclear@0: pop_screen(); nuclear@0: } nuclear@0: // and then destroy them nuclear@0: for(size_t i=0; iupdate(msec); nuclear@0: nuclear@0: glClearColor(0, 0, 0, 1); nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@0: current_screen()->pre_draw(); nuclear@0: current_screen()->display(); nuclear@0: current_screen()->post_draw(); nuclear@0: nuclear@0: swap_buffers(); nuclear@0: CHECKGLERR; nuclear@0: } nuclear@0: nuclear@0: void game_reshape(int x, int y) nuclear@0: { nuclear@0: width = x; nuclear@0: height = y; nuclear@0: nuclear@0: // set framebuffer size uniform nuclear@0: static int st_fbsize_idx = -1; nuclear@0: if(st_fbsize_idx == -1) { nuclear@0: st_fbsize_idx = get_unistate_index("st_fbsize"); nuclear@0: } nuclear@0: set_unistate(st_fbsize_idx, Vector2(x, y)); nuclear@0: nuclear@0: glViewport(0, 0, x, y); nuclear@0: current_screen()->reshape(x, y); nuclear@0: } nuclear@0: nuclear@0: void game_key(int key, bool pressed) nuclear@0: { nuclear@0: // special key processing nuclear@0: if(pressed) { nuclear@0: switch(key) { nuclear@0: case 27: nuclear@0: exit(0); nuclear@0: nuclear@0: case '`': nuclear@0: toggle_debug(); nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: set_key_state(key, pressed); nuclear@0: current_screen()->keyboard(key, pressed); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: int get_screen_width() nuclear@0: { nuclear@0: return width; nuclear@0: } nuclear@0: nuclear@0: int get_screen_height() nuclear@0: { nuclear@0: return height; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: static void standard_state_uniforms() nuclear@0: { nuclear@0: // setup all the standard state uniforms nuclear@0: add_unistate("st_world_matrix", ST_MATRIX4); nuclear@0: add_unistate("st_world_matrix_transpose", ST_MATRIX4); nuclear@0: //add_unistate("st_world_matrix_inverse", ST_MATRIX4); nuclear@0: add_unistate("st_world_matrix3", ST_MATRIX3); nuclear@0: nuclear@0: add_unistate("st_view_matrix", ST_MATRIX4); nuclear@0: add_unistate("st_view_matrix_transpose", ST_MATRIX4); nuclear@0: //add_unistate("st_view_matrix_inverse", ST_MATRIX4); nuclear@0: add_unistate("st_view_matrix3", ST_MATRIX3); nuclear@0: nuclear@0: add_unistate("st_proj_matrix", ST_MATRIX4); nuclear@0: //add_unistate("st_proj_matrix_inverse", ST_MATRIX4); nuclear@0: nuclear@0: add_unistate("st_tex_matrix", ST_MATRIX4); nuclear@0: //add_unistate("st_tex_matrix_inverse", ST_MATRIX4); nuclear@0: nuclear@0: //add_unistate("st_mvp_matrix", ST_MATRIX4); nuclear@0: //add_unistate("st_mvp_matrix_inverse", ST_MATRIX4); nuclear@0: nuclear@0: add_unistate("st_fbsize", ST_FLOAT2); nuclear@0: nuclear@0: add_unistate("st_time", ST_FLOAT); nuclear@0: nuclear@0: add_unistate("st_light_pos", ST_FLOAT3); nuclear@0: add_unistate("st_light_color", ST_FLOAT3); nuclear@0: add_unistate("st_light_radius", ST_FLOAT); nuclear@0: nuclear@0: add_unistate("st_mtl_diffuse", ST_FLOAT3); nuclear@0: add_unistate("st_mtl_specular", ST_FLOAT3); nuclear@0: add_unistate("st_mtl_shininess", ST_FLOAT); nuclear@0: add_unistate("st_mtl_alpha", ST_FLOAT); nuclear@0: } nuclear@0: nuclear@0: static bool create_screens() nuclear@0: { nuclear@0: Screen *scr; nuclear@0: nuclear@0: // create the debug overlay screen nuclear@0: debug_screen = new DebugScreen; nuclear@0: if(!debug_screen->init()) { nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: // create the starting screen last nuclear@0: scr = new GameScreen; nuclear@0: if(!scr->init()) { nuclear@0: return false; nuclear@0: } nuclear@0: screens.push_back(scr); nuclear@0: nuclear@0: info_log("start-screen: %s\n", scr->get_name()); nuclear@0: push_screen(scr); nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: static void toggle_debug() nuclear@0: { nuclear@0: if(dynamic_cast(current_screen())) { nuclear@0: pop_screen(); nuclear@0: } else { nuclear@0: push_screen(debug_screen); nuclear@0: } nuclear@0: }