conworlds

annotate src/game.cc @ 13:283cdfa7dda2

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