conworlds

annotate src/game.cc @ 15:9b0db7dbde6e

hmmm doesn't work properly yes
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 24 Aug 2014 14:36:00 +0300
parents 283cdfa7dda2
children 7a2041ddb7e7 e4257df067a1
rev   line source
nuclear@15 1 #include <math.h>
nuclear@2 2 #include "game.h"
nuclear@13 3 #include "gameopt.h"
nuclear@2 4 #include "opengl.h"
nuclear@2 5 #include "camera.h"
nuclear@2 6 #include "texture.h"
nuclear@4 7 #include "vr/vr.h"
nuclear@2 8
nuclear@7 9 static void game_render_eye(int eye);
nuclear@2 10 static void draw_scene();
nuclear@6 11 static bool setup_rtarg(int x, int y);
nuclear@15 12 static void draw_box(float sz);
nuclear@15 13 static void draw_pyramid(float basesz, float height);
nuclear@15 14
nuclear@6 15
nuclear@7 16 static Texture *rtarg;
nuclear@6 17 static unsigned int fbo, rtarg_depth;
nuclear@7 18 static int rtwidth, rtheight;
nuclear@2 19
nuclear@2 20 static const float move_speed = 10.0f;
nuclear@2 21
nuclear@2 22 static int fb_width, fb_height;
nuclear@2 23 static FlyCamera cam;
nuclear@2 24 static Texture floor_tex;
nuclear@2 25 static bool keystate[256];
nuclear@13 26 static float player_height = 1.68;
nuclear@2 27
nuclear@2 28 bool game_init()
nuclear@2 29 {
nuclear@13 30 if(opt.vr) {
nuclear@13 31 vr_init();
nuclear@13 32 if(opt.vr_module) {
nuclear@13 33 vr_use_module_named(opt.vr_module);
nuclear@13 34 }
nuclear@13 35
nuclear@13 36 player_height = vr_get_optf(VR_OPT_EYE_HEIGHT);
nuclear@13 37 }
nuclear@4 38
nuclear@2 39 glEnable(GL_DEPTH_TEST);
nuclear@2 40 glEnable(GL_CULL_FACE);
nuclear@2 41 glEnable(GL_LIGHTING);
nuclear@2 42 glEnable(GL_LIGHT0);
nuclear@12 43 glEnable(GL_NORMALIZE);
nuclear@2 44
nuclear@2 45 glClearColor(0.1, 0.1, 0.1, 1);
nuclear@2 46
nuclear@6 47
nuclear@2 48 if(!floor_tex.load("data/tiles.png")) {
nuclear@2 49 return false;
nuclear@2 50 }
nuclear@2 51
nuclear@13 52 cam.input_move(0, player_height, 0);
nuclear@2 53 return true;
nuclear@2 54 }
nuclear@2 55
nuclear@2 56 void game_cleanup()
nuclear@2 57 {
nuclear@2 58 floor_tex.destroy();
nuclear@13 59 if(opt.vr) {
nuclear@13 60 vr_shutdown();
nuclear@13 61 }
nuclear@6 62
nuclear@6 63 if(fbo) {
nuclear@6 64 glDeleteFramebuffers(1, &fbo);
nuclear@6 65 glDeleteRenderbuffers(1, &rtarg_depth);
nuclear@7 66 delete rtarg;
nuclear@6 67 }
nuclear@2 68 }
nuclear@2 69
nuclear@2 70 void game_update(unsigned int msec)
nuclear@2 71 {
nuclear@2 72 static unsigned int prev_msec;
nuclear@2 73 float dt = (msec - prev_msec) / 1000.0f;
nuclear@2 74 float offs = dt * move_speed;
nuclear@2 75 prev_msec = msec;
nuclear@2 76
nuclear@2 77 Vector3 move;
nuclear@2 78 float roll = 0.0f;
nuclear@2 79
nuclear@2 80 if(keystate['d'] || keystate['D']) {
nuclear@2 81 move.x += offs;
nuclear@2 82 }
nuclear@2 83 if(keystate['a'] || keystate['A']) {
nuclear@2 84 move.x -= offs;
nuclear@2 85 }
nuclear@2 86 if(keystate['s'] || keystate['S']) {
nuclear@2 87 move.z += offs;
nuclear@2 88 }
nuclear@2 89 if(keystate['w'] || keystate['W']) {
nuclear@2 90 move.z -= offs;
nuclear@2 91 }
nuclear@2 92 if(keystate['e'] || keystate['E']) {
nuclear@2 93 roll += dt;
nuclear@2 94 }
nuclear@2 95 if(keystate['q'] || keystate['Q']) {
nuclear@2 96 roll -= dt;
nuclear@2 97 }
nuclear@2 98
nuclear@2 99 cam.input_move(move.x, move.y, move.z);
nuclear@2 100 cam.input_rotate(0, 0, roll);
nuclear@2 101 }
nuclear@2 102
nuclear@7 103 void game_render()
nuclear@2 104 {
nuclear@13 105 if(opt.vr) {
nuclear@13 106 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@13 107 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@6 108
nuclear@13 109 glViewport(0, 0, rtwidth / 2.0, rtheight);
nuclear@13 110 vr_begin(VR_EYE_LEFT);
nuclear@13 111 game_render_eye(-1);
nuclear@13 112 vr_end();
nuclear@7 113
nuclear@13 114 glViewport(rtwidth / 2, 0, rtwidth / 2.0, rtheight);
nuclear@13 115 vr_begin(VR_EYE_RIGHT);
nuclear@13 116 game_render_eye(1);
nuclear@13 117 vr_end();
nuclear@7 118
nuclear@13 119 glBindFramebuffer(GL_FRAMEBUFFER, 0);
nuclear@13 120 glViewport(0, 0, fb_width, fb_height);
nuclear@8 121
nuclear@13 122 vr_output_texture(rtarg->get_texture_id(), 0, 0, (float)rtwidth / (float)rtarg->get_width(),
nuclear@13 123 (float)rtheight / (float)rtarg->get_height());
nuclear@13 124 } else {
nuclear@13 125 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@13 126
nuclear@13 127 game_render_eye(0);
nuclear@13 128 }
nuclear@9 129
nuclear@9 130 vr_swap_buffers();
nuclear@7 131 }
nuclear@7 132
nuclear@7 133 static void game_render_eye(int eye)
nuclear@7 134 {
nuclear@4 135 float mat[16];
nuclear@2 136 Matrix4x4 view_matrix = cam.get_matrix().inverse();
nuclear@2 137
nuclear@2 138 glMatrixMode(GL_PROJECTION);
nuclear@2 139 glLoadIdentity();
nuclear@11 140 if(eye == 0 || !vr_proj_matrix(eye < 0 ? 0 : 1, 0.5, 500.0, mat)) {
nuclear@4 141 gluPerspective(60.0, (float)fb_width / (float)fb_height, 0.5, 500.0);
nuclear@11 142 } else {
nuclear@7 143 glLoadMatrixf(mat);
nuclear@11 144 }
nuclear@2 145
nuclear@2 146 glMatrixMode(GL_MODELVIEW);
nuclear@11 147 if(eye == 0 || !vr_view_matrix(eye < 0 ? 0 : 1, mat)) {
nuclear@4 148 glLoadIdentity();
nuclear@11 149 } else {
nuclear@15 150 glLoadIdentity();
nuclear@15 151 //glLoadMatrixf(mat);
nuclear@11 152 }
nuclear@4 153 glMultTransposeMatrixf(view_matrix[0]);
nuclear@15 154 glMultMatrixf(mat);
nuclear@2 155
nuclear@2 156 draw_scene();
nuclear@2 157 }
nuclear@2 158
nuclear@2 159 void game_reshape(int x, int y)
nuclear@2 160 {
nuclear@2 161 glViewport(0, 0, x, y);
nuclear@2 162 fb_width = x;
nuclear@2 163 fb_height = y;
nuclear@6 164
nuclear@7 165 int lxres = vr_get_opti(VR_OPT_LEYE_XRES);
nuclear@7 166 if(lxres) {
nuclear@7 167 int lyres = vr_get_opti(VR_OPT_LEYE_YRES);
nuclear@7 168 int rxres = vr_get_opti(VR_OPT_REYE_XRES);
nuclear@7 169 int ryres = vr_get_opti(VR_OPT_REYE_YRES);
nuclear@7 170
nuclear@7 171 rtwidth = lxres + rxres;
nuclear@7 172 rtheight = lyres > ryres ? lyres : ryres;
nuclear@7 173 } else {
nuclear@7 174 rtwidth = x;
nuclear@7 175 rtheight = y;
nuclear@7 176 }
nuclear@7 177
nuclear@7 178 setup_rtarg(rtwidth, rtheight);
nuclear@2 179 }
nuclear@2 180
nuclear@2 181 void game_keyboard(int key, bool pressed, int x, int y)
nuclear@2 182 {
nuclear@2 183 if(pressed) {
nuclear@2 184 switch(key) {
nuclear@2 185 case 27:
nuclear@2 186 exit(0);
nuclear@9 187
nuclear@9 188 case ' ':
nuclear@9 189 vr_recenter();
nuclear@9 190 break;
nuclear@2 191 }
nuclear@2 192 }
nuclear@2 193
nuclear@2 194 if(key < 256) {
nuclear@2 195 keystate[key] = pressed;
nuclear@2 196 }
nuclear@2 197 }
nuclear@2 198
nuclear@2 199 static int prev_x, prev_y;
nuclear@2 200 static bool bnstate[32];
nuclear@2 201
nuclear@2 202 void game_mouse(int bn, bool pressed, int x, int y)
nuclear@2 203 {
nuclear@2 204 bnstate[bn] = pressed;
nuclear@2 205 prev_x = x;
nuclear@2 206 prev_y = y;
nuclear@2 207 }
nuclear@2 208
nuclear@2 209 void game_motion(int x, int y)
nuclear@2 210 {
nuclear@2 211 int dx = x - prev_x;
nuclear@2 212 int dy = y - prev_y;
nuclear@2 213 prev_x = x;
nuclear@2 214 prev_y = y;
nuclear@2 215
nuclear@2 216 if(!dx && !dy) return;
nuclear@2 217
nuclear@2 218 if(bnstate[0]) {
nuclear@2 219 float xrot = dy * 0.5;
nuclear@2 220 float yrot = dx * 0.5;
nuclear@2 221 cam.input_rotate(DEG_TO_RAD(xrot), 0, 0);
nuclear@2 222 cam.input_rotate(0, DEG_TO_RAD(yrot), 0);
nuclear@2 223 }
nuclear@2 224 }
nuclear@2 225
nuclear@3 226 void game_mwheel(int dir)
nuclear@3 227 {
nuclear@3 228 cam.input_move(0, dir * 0.1, 0);
nuclear@3 229 }
nuclear@3 230
nuclear@2 231 void game_6dof_move(float x, float y, float z)
nuclear@2 232 {
nuclear@2 233 cam.input_move(x, y, z);
nuclear@2 234 }
nuclear@2 235
nuclear@2 236 void game_6dof_rotate(float x, float y, float z)
nuclear@2 237 {
nuclear@2 238 cam.input_rotate(x, y, z);
nuclear@2 239 }
nuclear@2 240
nuclear@2 241 static void draw_scene()
nuclear@2 242 {
nuclear@2 243 float lpos[] = {-20, 30, 10, 1};
nuclear@2 244 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
nuclear@2 245
nuclear@2 246 glEnable(GL_TEXTURE_2D);
nuclear@13 247 bind_texture(&floor_tex);
nuclear@2 248
nuclear@2 249 glMatrixMode(GL_TEXTURE);
nuclear@2 250 glScalef(8, 8, 8);
nuclear@2 251
nuclear@2 252 glBegin(GL_QUADS);
nuclear@2 253 glNormal3f(0, 1, 0);
nuclear@2 254 glTexCoord2f(0, 0); glVertex3f(-25, 0, 25);
nuclear@2 255 glTexCoord2f(1, 0); glVertex3f(25, 0, 25);
nuclear@2 256 glTexCoord2f(1, 1); glVertex3f(25, 0, -25);
nuclear@2 257 glTexCoord2f(0, 1); glVertex3f(-25, 0, -25);
nuclear@2 258 glEnd();
nuclear@2 259 glDisable(GL_TEXTURE_2D);
nuclear@2 260 glLoadIdentity();
nuclear@2 261
nuclear@2 262 glMatrixMode(GL_MODELVIEW);
nuclear@2 263
nuclear@12 264 for(int i=0; i<4; i++) {
nuclear@12 265 glPushMatrix();
nuclear@12 266 glTranslatef(i & 1 ? -10 : 10, 0, i & 2 ? -10 : 10);
nuclear@15 267 draw_pyramid(2.0, 2.0);
nuclear@12 268 glPopMatrix();
nuclear@12 269 }
nuclear@2 270 }
nuclear@6 271
nuclear@6 272 static bool setup_rtarg(int x, int y)
nuclear@6 273 {
nuclear@6 274 int tex_width = next_pow2(x);
nuclear@6 275 int tex_height = next_pow2(y);
nuclear@6 276
nuclear@6 277 /* create render targets for each eye */
nuclear@6 278 if(!fbo) {
nuclear@6 279 glGenFramebuffers(1, &fbo);
nuclear@6 280 glGenRenderbuffers(1, &rtarg_depth);
nuclear@7 281 rtarg = new Texture;
nuclear@6 282 }
nuclear@6 283
nuclear@6 284 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@6 285
nuclear@6 286 glBindRenderbuffer(GL_RENDERBUFFER, rtarg_depth);
nuclear@6 287 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_width, tex_height);
nuclear@6 288 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rtarg_depth);
nuclear@6 289
nuclear@7 290 rtarg->create2d(tex_width, tex_height);
nuclear@7 291 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
nuclear@7 292 rtarg->get_texture_id(), 0);
nuclear@6 293
nuclear@6 294 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
nuclear@6 295 fprintf(stderr, "incomplete framebuffer!\n");
nuclear@6 296 return false;
nuclear@6 297 }
nuclear@6 298 glBindFramebuffer(GL_FRAMEBUFFER, 0);
nuclear@7 299
nuclear@7 300 printf("created render target %dx%d (texture: %dx%d)\n", x, y, tex_width, tex_height);
nuclear@6 301 return true;
nuclear@6 302 }
nuclear@15 303
nuclear@15 304 static void draw_box(float sz)
nuclear@15 305 {
nuclear@15 306 float hsz = sz / 2.0;
nuclear@15 307
nuclear@15 308 glBegin(GL_QUADS);
nuclear@15 309 glNormal3f(0, 0, 1);
nuclear@15 310 glVertex3f(-hsz, -hsz, hsz);
nuclear@15 311 glVertex3f(hsz, -hsz, hsz);
nuclear@15 312 glVertex3f(hsz, hsz, hsz);
nuclear@15 313 glVertex3f(-hsz, hsz, hsz);
nuclear@15 314 glNormal3f(1, 0, 0);
nuclear@15 315 glVertex3f(hsz, -hsz, hsz);
nuclear@15 316 glVertex3f(hsz, -hsz, -hsz);
nuclear@15 317 glVertex3f(hsz, hsz, -hsz);
nuclear@15 318 glVertex3f(hsz, hsz, hsz);
nuclear@15 319 glNormal3f(0, 0, -1);
nuclear@15 320 glVertex3f(hsz, -hsz, -hsz);
nuclear@15 321 glVertex3f(-hsz, -hsz, -hsz);
nuclear@15 322 glVertex3f(-hsz, hsz, -hsz);
nuclear@15 323 glVertex3f(hsz, hsz, -hsz);
nuclear@15 324 glNormal3f(-1, 0, 0);
nuclear@15 325 glVertex3f(-hsz, -hsz, -hsz);
nuclear@15 326 glVertex3f(-hsz, -hsz, hsz);
nuclear@15 327 glVertex3f(-hsz, hsz, hsz);
nuclear@15 328 glVertex3f(-hsz, hsz, -hsz);
nuclear@15 329 glNormal3f(0, 1, 0);
nuclear@15 330 glVertex3f(-hsz, hsz, hsz);
nuclear@15 331 glVertex3f(hsz, hsz, hsz);
nuclear@15 332 glVertex3f(hsz, hsz, -hsz);
nuclear@15 333 glVertex3f(-hsz, hsz, -hsz);
nuclear@15 334 glNormal3f(0, -1, 0);
nuclear@15 335 glVertex3f(-hsz, -hsz, -hsz);
nuclear@15 336 glVertex3f(hsz, -hsz, -hsz);
nuclear@15 337 glVertex3f(hsz, -hsz, hsz);
nuclear@15 338 glVertex3f(-hsz, -hsz, hsz);
nuclear@15 339 glEnd();
nuclear@15 340 }
nuclear@15 341
nuclear@15 342 static void draw_pyramid(float basesz, float height)
nuclear@15 343 {
nuclear@15 344 float hsz = basesz / 2.0;
nuclear@15 345 float theta = atan(hsz / height);
nuclear@15 346 float nx = cos(theta);
nuclear@15 347 float ny = sin(theta);
nuclear@15 348
nuclear@15 349 glBegin(GL_TRIANGLES);
nuclear@15 350 glNormal3f(0, ny, nx);
nuclear@15 351 glVertex3f(-hsz, 0, hsz);
nuclear@15 352 glVertex3f(hsz, 0, hsz);
nuclear@15 353 glVertex3f(0, height, 0);
nuclear@15 354 glNormal3f(nx, ny, 0);
nuclear@15 355 glVertex3f(hsz, 0, hsz);
nuclear@15 356 glVertex3f(hsz, 0, -hsz);
nuclear@15 357 glVertex3f(0, height, 0);
nuclear@15 358 glNormal3f(0, ny, -nx);
nuclear@15 359 glVertex3f(hsz, 0, -hsz);
nuclear@15 360 glVertex3f(-hsz, 0, -hsz);
nuclear@15 361 glVertex3f(0, height, 0);
nuclear@15 362 glNormal3f(-nx, ny, 0);
nuclear@15 363 glVertex3f(-hsz, 0, -hsz);
nuclear@15 364 glVertex3f(-hsz, 0, hsz);
nuclear@15 365 glVertex3f(0, height, 0);
nuclear@15 366 glEnd();
nuclear@15 367 }