tavli

annotate src/game.cc @ 24:0aadb519b5ee

correct highlighting
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 08 Jul 2015 15:11:58 +0300
parents c3fbf9616dbd
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@18 2 #include <assert.h>
nuclear@16 3 #include "opengl.h"
nuclear@0 4 #include "game.h"
nuclear@1 5 #include "board.h"
nuclear@14 6 #include "scenery.h"
nuclear@15 7 #include "sdr.h"
nuclear@18 8 #include "shadow.h"
nuclear@18 9 #include "opt.h"
nuclear@0 10
nuclear@18 11 static void draw_scene();
nuclear@0 12 static void draw_backdrop();
nuclear@0 13
nuclear@0 14 int win_width, win_height;
nuclear@17 15 unsigned long cur_time;
nuclear@15 16 unsigned int sdr_phong, sdr_phong_notex;
nuclear@18 17 unsigned int sdr_shadow, sdr_shadow_notex;
nuclear@19 18 unsigned int sdr_unlit;
nuclear@14 19 bool wireframe;
nuclear@21 20 int dbg_int;
nuclear@0 21
nuclear@22 22 Ray pick_ray;
nuclear@22 23
nuclear@1 24 static Board board;
nuclear@1 25
nuclear@8 26 static float cam_theta, cam_phi = 45, cam_dist = 3;
nuclear@0 27 static bool bnstate[8];
nuclear@0 28 static int prev_x, prev_y;
nuclear@0 29
nuclear@19 30 static bool dbg_busyloop, dbg_show_shadowmap;
nuclear@0 31
nuclear@0 32 bool game_init()
nuclear@0 33 {
nuclear@16 34 if(init_opengl() == -1) {
nuclear@16 35 return false;
nuclear@16 36 }
nuclear@16 37
nuclear@0 38 glEnable(GL_DEPTH_TEST);
nuclear@0 39 glEnable(GL_CULL_FACE);
nuclear@11 40 glEnable(GL_NORMALIZE);
nuclear@0 41 glEnable(GL_LIGHTING);
nuclear@0 42 glEnable(GL_LIGHT0);
nuclear@0 43
nuclear@19 44 float amb[] = {0.3, 0.3, 0.3, 1.0};
nuclear@19 45 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
nuclear@19 46
nuclear@16 47 if(glcaps.sep_spec) {
nuclear@16 48 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
nuclear@16 49 }
nuclear@16 50
nuclear@16 51 if(glcaps.fsaa) {
nuclear@5 52 glEnable(GL_MULTISAMPLE);
nuclear@5 53 }
nuclear@5 54
nuclear@16 55 if(glcaps.shaders) {
nuclear@16 56 Mesh::use_custom_sdr_attr = false;
nuclear@16 57 if(!(sdr_phong = create_program_load("sdr/phong.v.glsl", "sdr/phong.p.glsl"))) {
nuclear@16 58 return false;
nuclear@16 59 }
nuclear@16 60 if(!(sdr_phong_notex = create_program_load("sdr/phong.v.glsl", "sdr/phong-notex.p.glsl"))) {
nuclear@16 61 return false;
nuclear@16 62 }
nuclear@18 63
nuclear@18 64 if(glcaps.fbo) {
nuclear@19 65 init_shadow(2048);
nuclear@18 66
nuclear@18 67 if(!(sdr_shadow = create_program_load("sdr/shadow.v.glsl", "sdr/shadow.p.glsl"))) {
nuclear@18 68 return false;
nuclear@18 69 }
nuclear@18 70 set_uniform_int(sdr_shadow, "tex", 0);
nuclear@18 71 set_uniform_int(sdr_shadow, "shadowmap", 1);
nuclear@18 72
nuclear@18 73 if(!(sdr_shadow_notex = create_program_load("sdr/shadow.v.glsl", "sdr/shadow-notex.p.glsl"))) {
nuclear@18 74 return false;
nuclear@18 75 }
nuclear@19 76 set_uniform_int(sdr_shadow_notex, "shadowmap", 1);
nuclear@18 77 }
nuclear@15 78 }
nuclear@15 79
nuclear@1 80 if(!board.init()) {
nuclear@1 81 return false;
nuclear@1 82 }
nuclear@17 83 board.setup();
nuclear@1 84
nuclear@14 85 if(!init_scenery()) {
nuclear@14 86 return false;
nuclear@14 87 }
nuclear@14 88
nuclear@18 89 assert(glGetError() == GL_NO_ERROR);
nuclear@0 90 return true;
nuclear@0 91 }
nuclear@0 92
nuclear@0 93 void game_cleanup()
nuclear@0 94 {
nuclear@1 95 board.destroy();
nuclear@14 96 destroy_scenery();
nuclear@18 97 destroy_shadow();
nuclear@0 98 }
nuclear@0 99
nuclear@0 100 void game_update(unsigned long time_msec)
nuclear@0 101 {
nuclear@17 102 cur_time = time_msec;
nuclear@0 103 }
nuclear@0 104
nuclear@0 105 void game_display()
nuclear@0 106 {
nuclear@0 107 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@0 108
nuclear@0 109 glMatrixMode(GL_MODELVIEW);
nuclear@0 110 glLoadIdentity();
nuclear@20 111 glTranslatef(0, 0.1, -cam_dist);
nuclear@0 112 glRotatef(cam_phi, 1, 0, 0);
nuclear@0 113 glRotatef(cam_theta, 0, 1, 0);
nuclear@0 114
nuclear@19 115 float lpos[] = {-10, 20, 10, 1};
nuclear@19 116 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
nuclear@6 117
nuclear@18 118 if(opt.shadows && sdr_shadow) {
nuclear@19 119 begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 4.5);
nuclear@18 120 draw_scene();
nuclear@18 121 end_shadow_pass();
nuclear@18 122
nuclear@18 123 glActiveTexture(GL_TEXTURE1);
nuclear@18 124 glBindTexture(GL_TEXTURE_2D, get_shadow_tex());
nuclear@18 125
nuclear@18 126 glMatrixMode(GL_TEXTURE);
nuclear@18 127 Matrix4x4 shadow_matrix = get_shadow_matrix();
nuclear@19 128 glLoadTransposeMatrixf(shadow_matrix[0]);
nuclear@18 129
nuclear@18 130 glActiveTexture(GL_TEXTURE0);
nuclear@18 131 glMatrixMode(GL_MODELVIEW);
nuclear@18 132
nuclear@18 133 draw_scene();
nuclear@18 134
nuclear@18 135 glActiveTexture(GL_TEXTURE1);
nuclear@18 136 glBindTexture(GL_TEXTURE_2D, 0);
nuclear@18 137 glActiveTexture(GL_TEXTURE0);
nuclear@19 138 glBindTexture(GL_TEXTURE_2D, 0);
nuclear@18 139 } else {
nuclear@18 140 draw_scene();
nuclear@18 141 }
nuclear@15 142
nuclear@19 143 if(dbg_show_shadowmap) {
nuclear@19 144 glMatrixMode(GL_PROJECTION);
nuclear@19 145 glPushMatrix();
nuclear@19 146 glLoadIdentity();
nuclear@19 147 glMatrixMode(GL_MODELVIEW);
nuclear@19 148 glPushMatrix();
nuclear@19 149 glLoadIdentity();
nuclear@19 150 glMatrixMode(GL_TEXTURE);
nuclear@19 151 glLoadIdentity();
nuclear@19 152
nuclear@19 153 glPushAttrib(GL_ENABLE_BIT);
nuclear@19 154 glUseProgram(0);
nuclear@19 155 glBindTexture(GL_TEXTURE_2D, get_shadow_tex());
nuclear@19 156 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
nuclear@19 157 glEnable(GL_TEXTURE_2D);
nuclear@19 158 glDisable(GL_DEPTH_TEST);
nuclear@19 159 glDisable(GL_LIGHTING);
nuclear@19 160 glDisable(GL_BLEND);
nuclear@19 161
nuclear@19 162 glBegin(GL_QUADS);
nuclear@19 163 glColor4f(1, 1, 1, 1);
nuclear@19 164 glTexCoord2f(0, 0); glVertex2f(-1, -1);
nuclear@19 165 glTexCoord2f(1, 0); glVertex2f(1, -1);
nuclear@19 166 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@19 167 glTexCoord2f(0, 1); glVertex2f(-1, 1);
nuclear@19 168 glEnd();
nuclear@19 169
nuclear@19 170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
nuclear@19 171 glBindTexture(GL_TEXTURE_2D, 0);
nuclear@19 172
nuclear@19 173 glPopAttrib();
nuclear@19 174
nuclear@19 175 glMatrixMode(GL_PROJECTION);
nuclear@19 176 glPopMatrix();
nuclear@19 177 glMatrixMode(GL_MODELVIEW);
nuclear@19 178 glPopMatrix();
nuclear@19 179 }
nuclear@19 180
nuclear@15 181 if(dbg_busyloop) {
nuclear@15 182 redisplay();
nuclear@15 183 }
nuclear@0 184 }
nuclear@0 185
nuclear@18 186 static void draw_scene()
nuclear@18 187 {
nuclear@18 188 draw_backdrop();
nuclear@18 189 draw_scenery();
nuclear@18 190 board.draw();
nuclear@18 191 }
nuclear@18 192
nuclear@0 193 static void draw_backdrop()
nuclear@0 194 {
nuclear@0 195 glPushAttrib(GL_ENABLE_BIT);
nuclear@0 196 glDisable(GL_LIGHTING);
nuclear@0 197 glDisable(GL_DEPTH_TEST);
nuclear@0 198
nuclear@0 199 glMatrixMode(GL_PROJECTION);
nuclear@0 200 glPushMatrix();
nuclear@0 201 glLoadIdentity();
nuclear@0 202 glMatrixMode(GL_MODELVIEW);
nuclear@0 203 glPushMatrix();
nuclear@0 204 glLoadIdentity();
nuclear@0 205
nuclear@0 206 glBegin(GL_QUADS);
nuclear@0 207 glColor3f(0.9, 0.8, 0.6);
nuclear@0 208 glVertex2f(-1, -1);
nuclear@0 209 glVertex2f(1, -1);
nuclear@0 210 glColor3f(0.4, 0.5, 0.8);
nuclear@0 211 glVertex2f(1, 1);
nuclear@0 212 glVertex2f(-1, 1);
nuclear@0 213 glEnd();
nuclear@0 214
nuclear@0 215 glMatrixMode(GL_PROJECTION);
nuclear@0 216 glPopMatrix();
nuclear@0 217 glMatrixMode(GL_MODELVIEW);
nuclear@0 218 glPopMatrix();
nuclear@0 219
nuclear@0 220 glPopAttrib();
nuclear@0 221 }
nuclear@0 222
nuclear@0 223 void game_reshape(int x, int y)
nuclear@0 224 {
nuclear@0 225 glMatrixMode(GL_PROJECTION);
nuclear@0 226 glLoadIdentity();
nuclear@5 227 gluPerspective(45, (float)x / (float)y, 0.2, 200.0);
nuclear@0 228
nuclear@0 229 glViewport(0, 0, x, y);
nuclear@0 230 }
nuclear@0 231
nuclear@0 232 void game_keyboard(int bn, bool press)
nuclear@0 233 {
nuclear@0 234 if(press) {
nuclear@0 235 switch(bn) {
nuclear@0 236 case 27:
nuclear@0 237 quit();
nuclear@14 238
nuclear@14 239 case 'w':
nuclear@14 240 wireframe = !wireframe;
nuclear@14 241 redisplay();
nuclear@14 242 break;
nuclear@15 243
nuclear@15 244 case 'd':
nuclear@15 245 dbg_busyloop = !dbg_busyloop;
nuclear@15 246 redisplay();
nuclear@15 247 break;
nuclear@18 248
nuclear@19 249 case 'D':
nuclear@19 250 dbg_show_shadowmap = !dbg_show_shadowmap;
nuclear@19 251 redisplay();
nuclear@19 252 break;
nuclear@19 253
nuclear@18 254 case 's':
nuclear@18 255 opt.shadows = !opt.shadows;
nuclear@18 256 redisplay();
nuclear@18 257 break;
nuclear@21 258
nuclear@21 259 case '=':
nuclear@21 260 dbg_int++;
nuclear@21 261 printf("dbg_int: %d\n", dbg_int);
nuclear@21 262 redisplay();
nuclear@21 263 break;
nuclear@21 264
nuclear@21 265 case '-':
nuclear@21 266 dbg_int--;
nuclear@21 267 printf("dbg_int: %d\n", dbg_int);
nuclear@21 268 redisplay();
nuclear@21 269 break;
nuclear@0 270 }
nuclear@0 271 }
nuclear@0 272 }
nuclear@0 273
nuclear@0 274 void game_mbutton(int bn, bool press, int x, int y)
nuclear@0 275 {
nuclear@0 276 bnstate[bn] = press;
nuclear@0 277 prev_x = x;
nuclear@0 278 prev_y = y;
nuclear@0 279 }
nuclear@0 280
nuclear@0 281 void game_mmotion(int x, int y)
nuclear@0 282 {
nuclear@0 283 int dx = x - prev_x;
nuclear@0 284 int dy = y - prev_y;
nuclear@0 285 prev_x = x;
nuclear@0 286 prev_y = y;
nuclear@0 287
nuclear@0 288 if(bnstate[0]) {
nuclear@0 289 cam_theta += dx * 0.5;
nuclear@0 290 cam_phi += dy * 0.5;
nuclear@0 291
nuclear@0 292 if(cam_phi < -90) cam_phi = -90;
nuclear@0 293 if(cam_phi > 90) cam_phi = 90;
nuclear@0 294 }
nuclear@0 295 if(bnstate[2]) {
nuclear@0 296 cam_dist += dy * 0.1;
nuclear@0 297 if(cam_dist < 0.0) cam_dist = 0.0;
nuclear@22 298 }
nuclear@0 299
nuclear@22 300 // in all cases construct the global pick ray
nuclear@22 301 double viewmat[16], projmat[16];
nuclear@22 302 int vp[4], ysz;
nuclear@22 303 double px, py, pz;
nuclear@22 304
nuclear@22 305 glGetIntegerv(GL_VIEWPORT, vp);
nuclear@22 306 glGetDoublev(GL_MODELVIEW_MATRIX, viewmat);
nuclear@22 307 glGetDoublev(GL_PROJECTION_MATRIX, projmat);
nuclear@22 308
nuclear@22 309 ysz = vp[3] - vp[1];
nuclear@22 310
nuclear@22 311 gluUnProject(x, ysz - y, 0, viewmat, projmat, vp, &px, &py, &pz);
nuclear@22 312 pick_ray.origin = Vector3(px, py, pz);
nuclear@22 313 gluUnProject(x, ysz - y, 1, viewmat, projmat, vp, &px, &py, &pz);
nuclear@22 314 pick_ray.dir = Vector3(px, py, pz) - pick_ray.origin;
nuclear@22 315
nuclear@22 316 board.select_slot(board.slot_hit(pick_ray));
nuclear@22 317
nuclear@22 318 redisplay();
nuclear@0 319 }