ld33_umonster
diff src/game.cc @ 0:4a6683050e29
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 22 Aug 2015 07:15:00 +0300 |
parents | |
children | 35349df5392d |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/game.cc Sat Aug 22 07:15:00 2015 +0300 1.3 @@ -0,0 +1,219 @@ 1.4 +#include <stdio.h> 1.5 +#include <assert.h> 1.6 +#include "opengl.h" 1.7 +#include "game.h" 1.8 +#include "sdr.h" 1.9 +#include "shader.h" 1.10 +#include "shadow.h" 1.11 +#include "opt.h" 1.12 + 1.13 +static void draw_scene(); 1.14 + 1.15 +int win_width, win_height; 1.16 +unsigned long cur_time; 1.17 +bool dbg_wireframe; 1.18 +int dbg_int; 1.19 + 1.20 +unsigned int sdr_shadow, sdr_shadow_notex; 1.21 + 1.22 +static float cam_theta, cam_phi = 25, cam_dist = 8; 1.23 +static bool bnstate[8]; 1.24 +static int prev_x, prev_y; 1.25 + 1.26 +static unsigned int modkeys; 1.27 + 1.28 + 1.29 +bool game_init() 1.30 +{ 1.31 + if(init_opengl() == -1) { 1.32 + return false; 1.33 + } 1.34 + 1.35 + glEnable(GL_DEPTH_TEST); 1.36 + glEnable(GL_CULL_FACE); 1.37 + glEnable(GL_NORMALIZE); 1.38 + glEnable(GL_LIGHTING); 1.39 + glEnable(GL_LIGHT0); 1.40 + 1.41 + float amb[] = {0.3, 0.3, 0.3, 1.0}; 1.42 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 1.43 + 1.44 + if(glcaps.sep_spec) { 1.45 + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 1.46 + } 1.47 + glEnable(GL_MULTISAMPLE); 1.48 + 1.49 + if(!init_shadow(4096)) { 1.50 + fprintf(stderr, "failed to initialize shadowmaps\n"); 1.51 + return false; 1.52 + } 1.53 + if(!(sdr_shadow = create_program_load("sdr/shadow.v.glsl", "sdr/shadow.p.glsl"))) { 1.54 + return false; 1.55 + } 1.56 + set_uniform_int(sdr_shadow, "tex", 0); 1.57 + set_uniform_int(sdr_shadow, "shadowmap", 1); 1.58 + 1.59 + if(!(sdr_shadow_notex = create_program_load("sdr/shadow.v.glsl", "sdr/shadow-notex.p.glsl"))) { 1.60 + return false; 1.61 + } 1.62 + set_uniform_int(sdr_shadow_notex, "shadowmap", 1); 1.63 + 1.64 + 1.65 + assert(glGetError() == GL_NO_ERROR); 1.66 + return true; 1.67 +} 1.68 + 1.69 +void game_cleanup() 1.70 +{ 1.71 +} 1.72 + 1.73 +void game_update(unsigned long time_msec) 1.74 +{ 1.75 + cur_time = time_msec; 1.76 +} 1.77 + 1.78 +void game_display() 1.79 +{ 1.80 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.81 + 1.82 + glMatrixMode(GL_MODELVIEW); 1.83 + glLoadIdentity(); 1.84 + glTranslatef(0, 0.1, -cam_dist); 1.85 + glRotatef(cam_phi, 1, 0, 0); 1.86 + glRotatef(cam_theta, 0, 1, 0); 1.87 + 1.88 + float lpos[] = {-10, 20, 10, 1}; 1.89 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 1.90 + 1.91 + if(opt.shadows && sdr_shadow) { 1.92 + begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 5); 1.93 + draw_scene(); 1.94 + end_shadow_pass(); 1.95 + 1.96 + glActiveTexture(GL_TEXTURE1); 1.97 + glBindTexture(GL_TEXTURE_2D, get_shadow_tex()); 1.98 + 1.99 + glMatrixMode(GL_TEXTURE); 1.100 + Matrix4x4 shadow_matrix = get_shadow_matrix(); 1.101 + glLoadTransposeMatrixf(shadow_matrix[0]); 1.102 + 1.103 + glActiveTexture(GL_TEXTURE0); 1.104 + glMatrixMode(GL_MODELVIEW); 1.105 + 1.106 + set_shader(sdr_shadow_notex); 1.107 + 1.108 + draw_scene(); 1.109 + 1.110 + glActiveTexture(GL_TEXTURE1); 1.111 + glBindTexture(GL_TEXTURE_2D, 0); 1.112 + glActiveTexture(GL_TEXTURE0); 1.113 + glBindTexture(GL_TEXTURE_2D, 0); 1.114 + } else { 1.115 + draw_scene(); 1.116 + } 1.117 +} 1.118 + 1.119 +static void glmaterial(float r, float g, float b, float spec, float shin) 1.120 +{ 1.121 + float color[] = {r, g, b, 1}; 1.122 + float scolor[] = {spec, spec, spec, 1}; 1.123 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 1.124 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, scolor); 1.125 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin); 1.126 +} 1.127 + 1.128 +static void draw_scene() 1.129 +{ 1.130 + glPushMatrix(); 1.131 + glTranslatef(0, -1, 0); 1.132 + 1.133 + glmaterial(0.5, 0.5, 0.5, 0.8, 40.0); 1.134 + 1.135 + glBegin(GL_QUADS); 1.136 + glNormal3f(0, 1, 0); 1.137 + glVertex3f(-10, 0, 10); 1.138 + glVertex3f(10, 0, 10); 1.139 + glVertex3f(10, 0, -10); 1.140 + glVertex3f(-10, 0, -10); 1.141 + glEnd(); 1.142 + 1.143 + glPopMatrix(); 1.144 + 1.145 + glmaterial(0.2, 0.3, 1.0, 0.8, 60.0); 1.146 + draw_teapot(); 1.147 +} 1.148 + 1.149 + 1.150 +void game_reshape(int x, int y) 1.151 +{ 1.152 + glMatrixMode(GL_PROJECTION); 1.153 + glLoadIdentity(); 1.154 + gluPerspective(45, (float)x / (float)y, 0.2, 200.0); 1.155 + 1.156 + glViewport(0, 0, x, y); 1.157 +} 1.158 + 1.159 +void game_keyboard(int bn, bool press) 1.160 +{ 1.161 + if(press) { 1.162 + switch(bn) { 1.163 + case 27: 1.164 + quit(); 1.165 + 1.166 + case 'w': 1.167 + dbg_wireframe = !dbg_wireframe; 1.168 + redisplay(); 1.169 + break; 1.170 + 1.171 + case 's': 1.172 + opt.shadows = !opt.shadows; 1.173 + redisplay(); 1.174 + break; 1.175 + } 1.176 + } 1.177 +} 1.178 + 1.179 +void game_modifier_key(int key, bool press) 1.180 +{ 1.181 + if(press) { 1.182 + modkeys |= (1 << key); 1.183 + } else { 1.184 + modkeys &= ~(1 << key); 1.185 + } 1.186 +} 1.187 + 1.188 +void game_mbutton(int bn, bool press, int x, int y) 1.189 +{ 1.190 + bnstate[bn] = press; 1.191 + prev_x = x; 1.192 + prev_y = y; 1.193 + 1.194 + if(modkeys) { 1.195 + return; 1.196 + } 1.197 + 1.198 + if(bn == 0) { 1.199 + } 1.200 +} 1.201 + 1.202 +void game_mmotion(int x, int y) 1.203 +{ 1.204 + int dx = x - prev_x; 1.205 + int dy = y - prev_y; 1.206 + prev_x = x; 1.207 + prev_y = y; 1.208 + 1.209 + if(modkeys) { 1.210 + if(bnstate[0]) { 1.211 + cam_theta += dx * 0.5; 1.212 + cam_phi += dy * 0.5; 1.213 + 1.214 + if(cam_phi < -90) cam_phi = -90; 1.215 + if(cam_phi > 90) cam_phi = 90; 1.216 + } 1.217 + if(bnstate[2]) { 1.218 + cam_dist += dy * 0.1; 1.219 + if(cam_dist < 0.0) cam_dist = 0.0; 1.220 + } 1.221 + } 1.222 +}