tavli

annotate src/game.cc @ 21:c3fbf9616dbd

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