dungeon_crawler

annotate prototype/src/main.cc @ 42:6d71dd4760f9

added flag to force the use of the fallback renderer
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 30 Aug 2012 05:38:03 +0300
parents acfe0c0110fc
children f3030df27110
rev   line source
nuclear@1 1 #include <stdio.h>
nuclear@1 2 #include <stdlib.h>
nuclear@1 3 #include <assert.h>
nuclear@7 4 #include <unistd.h>
nuclear@1 5 #include "opengl.h"
nuclear@1 6 #include "level.h"
nuclear@1 7 #include "camera.h"
nuclear@5 8 #include "datapath.h"
nuclear@5 9 #include "tileset.h"
nuclear@15 10 #include "renderer.h"
nuclear@41 11 #include "renderer_deferred.h"
nuclear@24 12 #include "cmdcon.h"
nuclear@18 13 #include "cfg.h"
nuclear@38 14 #include "timer.h"
nuclear@1 15
nuclear@17 16 bool init(int xsz, int ysz);
nuclear@5 17 void cleanup();
nuclear@7 18 void idle();
nuclear@1 19 void disp();
nuclear@15 20 void draw();
nuclear@18 21 void view_matrix(int eye);
nuclear@18 22 void proj_matrix(int eye);
nuclear@7 23 void update(unsigned long msec);
nuclear@1 24 void reshape(int x, int y);
nuclear@1 25 void keyb(unsigned char key, int x, int y);
nuclear@7 26 void key_release(unsigned char key, int x, int y);
nuclear@24 27 void keyb_con(unsigned char key, int x, int y);
nuclear@1 28 void mouse(int bn, int state, int x, int y);
nuclear@1 29 void motion(int x, int y);
nuclear@1 30
nuclear@5 31 static TileSet *tileset;
nuclear@1 32 static Level *level;
nuclear@7 33
nuclear@7 34 static FpsCamera cam;
nuclear@7 35 static bool keystate[256];
nuclear@1 36
nuclear@18 37 static float stereo_focus_dist = 0.25;
nuclear@18 38 static float stereo_eye_sep = stereo_focus_dist / 30.0;
nuclear@18 39
nuclear@24 40 static bool show_con;
nuclear@5 41
nuclear@1 42 int main(int argc, char **argv)
nuclear@1 43 {
nuclear@1 44 glutInit(&argc, argv);
nuclear@5 45
nuclear@18 46 if(!cfg.parse_args(argc, argv)) {
nuclear@18 47 return 1;
nuclear@5 48 }
nuclear@5 49
nuclear@18 50 glutInitWindowSize(cfg.width, cfg.height);
nuclear@18 51 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (cfg.stereo ? GLUT_STEREO : 0));
nuclear@18 52 glutCreateWindow("dungeon crawler prototype");
nuclear@1 53
nuclear@7 54 glutIdleFunc(idle);
nuclear@1 55 glutDisplayFunc(disp);
nuclear@1 56 glutReshapeFunc(reshape);
nuclear@1 57 glutKeyboardFunc(keyb);
nuclear@7 58 glutKeyboardUpFunc(key_release);
nuclear@1 59 glutMouseFunc(mouse);
nuclear@1 60 glutMotionFunc(motion);
nuclear@1 61
nuclear@1 62 glewInit();
nuclear@1 63
nuclear@18 64 if(!init(cfg.width, cfg.height)) {
nuclear@5 65 return 1;
nuclear@5 66 }
nuclear@39 67 atexit(cleanup);
nuclear@5 68
nuclear@5 69 glutMainLoop();
nuclear@5 70 }
nuclear@5 71
nuclear@17 72 bool init(int xsz, int ysz)
nuclear@5 73 {
nuclear@41 74 // backup light for the forward crappy renderer
nuclear@1 75 glEnable(GL_LIGHTING);
nuclear@1 76 glEnable(GL_LIGHT0);
nuclear@41 77
nuclear@41 78 float ldir[] = {0, 0, -0.5, 1};
nuclear@1 79 glLightfv(GL_LIGHT0, GL_POSITION, ldir);
nuclear@41 80 float lcol[] = {1, 1, 1, 1};
nuclear@41 81 glLightfv(GL_LIGHT0, GL_DIFFUSE, lcol);
nuclear@41 82 glLightfv(GL_LIGHT0, GL_SPECULAR, lcol);
nuclear@1 83
nuclear@1 84 glEnable(GL_DEPTH_TEST);
nuclear@1 85 glEnable(GL_CULL_FACE);
nuclear@1 86 glEnable(GL_MULTISAMPLE);
nuclear@1 87
nuclear@25 88 add_data_path(".");
nuclear@5 89 add_data_path("data");
nuclear@16 90 add_data_path("sdr");
nuclear@5 91
nuclear@41 92 rend = new DeferredRenderer();
nuclear@42 93 if(!cfg.use_deferred || !rend->init(xsz, ysz)) {
nuclear@41 94 printf("falling back to crappy renderer...\n");
nuclear@41 95
nuclear@41 96 rend = new FwdRenderer();
nuclear@41 97 if(!rend->init(xsz, ysz)) {
nuclear@41 98 fprintf(stderr, "failed to create renderer\n");
nuclear@41 99 return false;
nuclear@41 100 }
nuclear@15 101 }
nuclear@15 102
nuclear@26 103 if(!init_cmdcon()) {
nuclear@26 104 return false;
nuclear@26 105 }
nuclear@26 106
nuclear@5 107 // load a tileset
nuclear@5 108 tileset = new TileSet;
nuclear@18 109 printf("loading tileset: %s\n", cfg.tileset_file);
nuclear@18 110 if(!tileset->load(datafile_path(cfg.tileset_file))) {
nuclear@5 111 return false;
nuclear@5 112 }
nuclear@5 113 set_active_tileset(tileset);
nuclear@5 114
nuclear@1 115 level = new Level;
nuclear@18 116 printf("loading level: %s\n", cfg.level_file);
nuclear@18 117 if(!level->load(datafile_path(cfg.level_file))) {
nuclear@5 118 return false;
nuclear@1 119 }
nuclear@1 120
nuclear@7 121 cam.input_move(0, 0.5, 0);
nuclear@7 122
nuclear@5 123 return true;
nuclear@1 124 }
nuclear@1 125
nuclear@15 126 void cleanup()
nuclear@15 127 {
nuclear@15 128 delete level;
nuclear@15 129 delete tileset;
nuclear@41 130 delete rend;
nuclear@26 131
nuclear@26 132 cleanup_cmdcon();
nuclear@15 133 }
nuclear@15 134
nuclear@7 135 void idle()
nuclear@7 136 {
nuclear@7 137 glutPostRedisplay();
nuclear@7 138 }
nuclear@7 139
nuclear@1 140 void disp()
nuclear@1 141 {
nuclear@38 142 update(get_time_msec());
nuclear@7 143
nuclear@18 144 if(cfg.stereo) {
nuclear@18 145 glDrawBuffer(GL_BACK_LEFT);
nuclear@1 146
nuclear@18 147 glMatrixMode(GL_PROJECTION);
nuclear@18 148 glLoadIdentity();
nuclear@18 149 proj_matrix(-1);
nuclear@18 150 glMatrixMode(GL_MODELVIEW);
nuclear@18 151 glLoadIdentity();
nuclear@18 152 view_matrix(-1);
nuclear@1 153
nuclear@24 154 draw();
nuclear@18 155
nuclear@18 156 glDrawBuffer(GL_BACK_RIGHT);
nuclear@18 157
nuclear@18 158 glMatrixMode(GL_PROJECTION);
nuclear@18 159 glLoadIdentity();
nuclear@18 160 proj_matrix(1);
nuclear@18 161 glMatrixMode(GL_MODELVIEW);
nuclear@18 162 glLoadIdentity();
nuclear@18 163 view_matrix(1);
nuclear@18 164
nuclear@24 165 draw();
nuclear@18 166 } else {
nuclear@18 167 glMatrixMode(GL_PROJECTION);
nuclear@18 168 glLoadIdentity();
nuclear@18 169 proj_matrix(0);
nuclear@18 170 glMatrixMode(GL_MODELVIEW);
nuclear@18 171 glLoadIdentity();
nuclear@18 172 view_matrix(0);
nuclear@18 173
nuclear@24 174 draw();
nuclear@18 175 }
nuclear@1 176
nuclear@1 177 glutSwapBuffers();
nuclear@1 178 assert(glGetError() == GL_NO_ERROR);
nuclear@7 179 }
nuclear@7 180
nuclear@24 181 void draw()
nuclear@24 182 {
nuclear@41 183 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@29 184
nuclear@41 185 rend->render(level);
nuclear@24 186
nuclear@24 187 if(show_con) {
nuclear@24 188 draw_cmdcon();
nuclear@24 189 }
nuclear@24 190 }
nuclear@24 191
nuclear@18 192 void view_matrix(int eye)
nuclear@18 193 {
nuclear@18 194 float offs = stereo_eye_sep * eye * 0.5;
nuclear@18 195 glTranslatef(-offs, 0, 0);
nuclear@18 196 cam.use_inverse();
nuclear@18 197 }
nuclear@18 198
nuclear@18 199 void proj_matrix(int eye)
nuclear@18 200 {
nuclear@18 201 static const float fov = M_PI / 4.0;
nuclear@18 202 static const float near_clip = 0.1;
nuclear@18 203 static const float far_clip = 100.0;
nuclear@18 204
nuclear@18 205 float top = near_clip * tan(fov * 0.5);
nuclear@18 206 float right = top * (float)cfg.width / (float)cfg.height;
nuclear@18 207
nuclear@18 208 float frust_shift = -(float)eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist);
nuclear@18 209 glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip);
nuclear@18 210 }
nuclear@18 211
nuclear@18 212
nuclear@7 213 void update(unsigned long msec)
nuclear@7 214 {
nuclear@7 215 static unsigned long last_upd;
nuclear@7 216
nuclear@7 217 if(last_upd == 0) {
nuclear@7 218 last_upd = msec;
nuclear@7 219 }
nuclear@7 220 float dt = (float)(msec - last_upd) / 1000.0;
nuclear@7 221
nuclear@9 222 float offs = 2.5 * dt;
nuclear@7 223 float dx = 0, dy = 0;
nuclear@7 224
nuclear@7 225 // handle key input
nuclear@7 226 if(keystate['w'] || keystate['W']) {
nuclear@7 227 dy -= offs;
nuclear@7 228 }
nuclear@7 229 if(keystate['s'] || keystate['S']) {
nuclear@7 230 dy += offs;
nuclear@7 231 }
nuclear@7 232 if(keystate['d'] || keystate['D']) {
nuclear@7 233 dx += offs;
nuclear@7 234 }
nuclear@7 235 if(keystate['a'] || keystate['A']) {
nuclear@7 236 dx -= offs;
nuclear@7 237 }
nuclear@7 238
nuclear@7 239 cam.input_move(dx, 0, dy);
nuclear@7 240
nuclear@38 241 level->update(msec, dt);
nuclear@38 242
nuclear@7 243 last_upd = msec;
nuclear@1 244 }
nuclear@1 245
nuclear@1 246 void reshape(int x, int y)
nuclear@1 247 {
nuclear@1 248 glViewport(0, 0, x, y);
nuclear@18 249 cfg.width = x;
nuclear@18 250 cfg.height = y;
nuclear@30 251
nuclear@41 252 rend->resize(x, y);
nuclear@1 253 }
nuclear@1 254
nuclear@18 255 static bool stereo_shift_pressed;
nuclear@18 256
nuclear@1 257 void keyb(unsigned char key, int x, int y)
nuclear@1 258 {
nuclear@1 259 switch(key) {
nuclear@1 260 case 27:
nuclear@1 261 exit(0);
nuclear@18 262
nuclear@24 263 case '`':
nuclear@24 264 show_con = true;
nuclear@24 265 glutKeyboardFunc(keyb_con);
nuclear@24 266 glutKeyboardUpFunc(0);
nuclear@24 267 glutPostRedisplay();
nuclear@24 268 break;
nuclear@24 269
nuclear@18 270 case 'z':
nuclear@18 271 stereo_shift_pressed = true;
nuclear@18 272 break;
nuclear@18 273
nuclear@18 274 case '\n':
nuclear@18 275 case '\r':
nuclear@18 276 {
nuclear@18 277 static bool fullscr;
nuclear@18 278 if(glutGetModifiers() & GLUT_ACTIVE_ALT) {
nuclear@18 279 fullscr = !fullscr;
nuclear@18 280 if(fullscr) {
nuclear@18 281 glutFullScreen();
nuclear@18 282 } else {
nuclear@18 283 glutPositionWindow(20, 20);
nuclear@18 284 }
nuclear@18 285 }
nuclear@18 286 }
nuclear@18 287 break;
nuclear@18 288
nuclear@18 289 default:
nuclear@18 290 break;
nuclear@1 291 }
nuclear@7 292
nuclear@7 293 keystate[key] = true;
nuclear@7 294 }
nuclear@7 295
nuclear@7 296 void key_release(unsigned char key, int x, int y)
nuclear@7 297 {
nuclear@18 298 switch(key) {
nuclear@18 299 case 'z':
nuclear@18 300 stereo_shift_pressed = false;
nuclear@18 301 break;
nuclear@18 302
nuclear@18 303 default:
nuclear@18 304 break;
nuclear@18 305 }
nuclear@18 306
nuclear@7 307 keystate[key] = false;
nuclear@1 308 }
nuclear@1 309
nuclear@24 310 void keyb_con(unsigned char key, int x, int y)
nuclear@24 311 {
nuclear@24 312 if(key == '`' || key == 27) {
nuclear@24 313 show_con = false;
nuclear@24 314 glutKeyboardFunc(keyb);
nuclear@24 315 glutKeyboardUpFunc(key_release);
nuclear@24 316 glutPostRedisplay();
nuclear@24 317 } else {
nuclear@24 318 cmdcon_keypress(key);
nuclear@24 319 }
nuclear@24 320 }
nuclear@24 321
nuclear@1 322 static int prev_x, prev_y;
nuclear@1 323 static bool bnstate[32];
nuclear@1 324
nuclear@1 325 void mouse(int bn, int state, int x, int y)
nuclear@1 326 {
nuclear@1 327 prev_x = x;
nuclear@1 328 prev_y = y;
nuclear@1 329 bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
nuclear@1 330 }
nuclear@1 331
nuclear@1 332 void motion(int x, int y)
nuclear@1 333 {
nuclear@1 334 int dx = x - prev_x;
nuclear@1 335 int dy = y - prev_y;
nuclear@1 336 prev_x = x;
nuclear@1 337 prev_y = y;
nuclear@1 338
nuclear@18 339 if(stereo_shift_pressed) {
nuclear@18 340 if(dy != 0) {
nuclear@18 341 stereo_focus_dist += dy * 0.01;
nuclear@18 342 stereo_eye_sep = stereo_focus_dist / 30.0;
nuclear@18 343 printf("foc: %f, sep: %f\n", stereo_focus_dist, stereo_eye_sep);
nuclear@18 344 glutPostRedisplay();
nuclear@18 345 }
nuclear@18 346 return;
nuclear@18 347 }
nuclear@18 348
nuclear@1 349 if(bnstate[0]) {
nuclear@7 350 cam.input_rotate(dy * 0.01, dx * 0.01, 0);
nuclear@1 351 glutPostRedisplay();
nuclear@1 352 }
nuclear@1 353 if(bnstate[2]) {
nuclear@1 354 cam.input_zoom(dy * 0.1);
nuclear@1 355 glutPostRedisplay();
nuclear@1 356 }
nuclear@1 357 }