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