8ee198908196e6883316a2f1916e27d59331e4d3
[vrlugburz] / src / game.c
1 #include <assert.h>
2 #include "cgmath/cgmath.h"
3 #include "game.h"
4 #include "opengl.h"
5 #include "level.h"
6 #include "scenefile.h"
7 #include "sdr.h"
8
9 static void draw_level(void);
10
11 struct level lvl;
12
13 int win_width, win_height;
14 float win_aspect;
15 int mouse_x, mouse_y;
16 int bnstate[8];
17
18 float cam_theta, cam_phi, cam_dist = 10;
19 float view_matrix[16], proj_matrix[16];
20
21 unsigned int sdr_foo;
22
23 int game_init(void)
24 {
25         if(init_opengl() == -1) {
26                 return -1;
27         }
28
29         glEnable(GL_DEPTH_TEST);
30         glEnable(GL_CULL_FACE);
31
32         if(!(sdr_foo = create_program_load("sdr/foo.v.glsl", "sdr/foo.p.glsl"))) {
33                 return -1;
34         }
35         glBindAttribLocation(sdr_foo, MESH_ATTR_VERTEX, "apos");
36         glBindAttribLocation(sdr_foo, MESH_ATTR_NORMAL, "anorm");
37         glBindAttribLocation(sdr_foo, MESH_ATTR_TANGENT, "atang");
38         glBindAttribLocation(sdr_foo, MESH_ATTR_TEXCOORD, "atex");
39         link_program(sdr_foo);
40
41         if(load_level(&lvl, "data/test.lvl") == -1) {
42                 return -1;
43         }
44
45         return 0;
46 }
47
48 void game_shutdown(void)
49 {
50         destroy_level(&lvl);
51         free_program(sdr_foo);
52 }
53
54 void game_display(void)
55 {
56         glClearColor(0.1, 0.1, 0.1, 1);
57         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58
59         cgm_midentity(proj_matrix);
60         cgm_mperspective(proj_matrix, cgm_deg_to_rad(50), win_aspect, 0.5, 500.0);
61         glMatrixMode(GL_PROJECTION);
62         glLoadMatrixf(proj_matrix);
63
64         cgm_midentity(view_matrix);
65         cgm_mpretranslate(view_matrix, 0, -1.7, -cam_dist);
66         cgm_mprerotate(view_matrix, cam_phi, 1, 0, 0);
67         cgm_mprerotate(view_matrix, cam_theta, 0, 1, 0);
68         glMatrixMode(GL_MODELVIEW);
69         glLoadMatrixf(view_matrix);
70
71         draw_level();
72
73         game_swap_buffers();
74         assert(glGetError() == GL_NO_ERROR);
75 }
76
77 static void draw_level(void)
78 {
79         int i, j, k;
80         struct cell *cell;
81
82         glUseProgram(sdr_foo);
83
84         cell = lvl.cells;
85         for(i=0; i<lvl.height; i++) {
86                 for(j=0; j<lvl.width; j++) {
87                         for(k=0; k<cell->num_mgrp; k++) {
88                                 draw_meshgroup(cell->mgrp + k);
89                         }
90                         cell++;
91                 }
92         }
93
94         glUseProgram(0);
95 }
96
97 void game_reshape(int x, int y)
98 {
99         glViewport(0, 0, x, y);
100         win_width = x;
101         win_height = y;
102         win_aspect = (float)x / (float)y;
103 }
104
105 void game_keyboard(int key, int press)
106 {
107         if(press && key == 27) {
108                 game_quit();
109                 return;
110         }
111 }
112
113 void game_mbutton(int bn, int press, int x, int y)
114 {
115         bnstate[bn] = press;
116         mouse_x = x;
117         mouse_y = y;
118 }
119
120 void game_mmotion(int x, int y)
121 {
122         int dx = x - mouse_x;
123         int dy = y - mouse_y;
124         mouse_x = x;
125         mouse_y = y;
126
127         if(!(dx | dy)) return;
128
129         if(bnstate[0]) {
130                 cam_theta += cgm_deg_to_rad(dx * 0.5f);
131                 cam_phi += cgm_deg_to_rad(dy * 0.5f);
132                 if(cam_phi < -M_PI/2) cam_phi = -M_PI/2;
133                 if(cam_phi > M_PI/2) cam_phi = M_PI/2;
134         }
135         if(bnstate[2]) {
136                 cam_dist += dy * 0.1;
137                 if(cam_dist < 0) cam_dist = 0;
138         }
139 }