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