d8aa1448865becbf0e29b6a231a4cd3df19a2dcb
[vrfileman] / src / app.cc
1 #include <stdio.h>
2 #include <assert.h>
3 #include "opengl.h"
4 #include "app.h"
5 #include "gmath/gmath.h"
6 #include "mesh.h"
7 #include "meshgen.h"
8 #include "backdrop.h"
9 #include "goatvr.h"
10
11 static bool parse_args(int argc, char **argv);
12
13 int win_width, win_height;
14 float win_aspect;
15 long time_msec;
16
17 static bool use_vr;
18 static bool should_swap;
19
20 static float cam_theta, cam_phi;
21 static float cam_height = 1.65;
22 static Mesh *mesh_torus;
23
24 static bool bnstate[16];
25 static int prev_x, prev_y;
26
27 bool app_init(int argc, char **argv)
28 {
29         if(!parse_args(argc, argv)) {
30                 return false;
31         }
32         if(init_opengl() == -1) {
33                 return false;
34         }
35
36         glEnable(GL_MULTISAMPLE);
37
38         int aasamples = 0;
39         glGetIntegerv(GL_SAMPLES, &aasamples);
40         printf("got %d samples per pixel\n", aasamples);
41
42         glEnable(GL_CULL_FACE);
43         glEnable(GL_DEPTH_TEST);
44         //glEnable(GL_LIGHTING);
45         glEnable(GL_LIGHT0);
46
47         if(GLEW_ARB_framebuffer_sRGB) {
48                 glEnable(GL_FRAMEBUFFER_SRGB);
49         }
50
51         if(use_vr) {
52                 if(goatvr_init() == -1) {
53                         return false;
54                 }
55                 goatvr_set_origin_mode(GOATVR_HEAD);
56
57                 goatvr_startvr();
58                 should_swap = goatvr_should_swap() != 0;
59                 cam_height = goatvr_get_eye_height();
60         }
61
62         Mesh::use_custom_sdr_attr = false;
63
64         mesh_torus = new Mesh;
65         gen_torus(mesh_torus, 1.0, 0.25, 32, 32);
66
67         if(!init_backdrop()) {
68                 return false;
69         }
70
71         return true;
72 }
73
74 void app_cleanup()
75 {
76         if(use_vr) {
77                 goatvr_shutdown();
78         }
79         delete mesh_torus;
80         cleanup_backdrop();
81 }
82
83 void app_draw()
84 {
85         if(use_vr) {
86                 // VR mode
87                 goatvr_draw_start();
88                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
89
90                 for(int i=0; i<2; i++) {
91                         goatvr_draw_eye(i);
92
93                         glMatrixMode(GL_PROJECTION);
94                         glLoadMatrixf(goatvr_projection_matrix(i, 0.5, 1000.0));
95
96                         Mat4 view_mat = goatvr_view_matrix(i);
97                         view_mat.pre_rotate_x(deg_to_rad(cam_phi));
98                         view_mat.pre_rotate_y(deg_to_rad(cam_theta));
99                         view_mat.pre_translate(0, -cam_height, 0);
100
101                         glMatrixMode(GL_MODELVIEW);
102                         glLoadMatrixf(view_mat[0]);
103
104                         draw_backdrop();
105                 }
106                 goatvr_draw_done();
107
108                 if(should_swap) {
109                         app_swap_buffers();
110                 }
111                 app_redraw();   // in VR mode, force continuous redraw
112
113         } else {
114                 // regular monoscopic mode
115                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
116
117                 Mat4 view_mat;
118                 view_mat.pre_rotate_x(deg_to_rad(cam_phi));
119                 view_mat.pre_rotate_y(deg_to_rad(cam_theta));
120                 view_mat.pre_translate(0, -cam_height, 0);
121
122                 glMatrixMode(GL_MODELVIEW);
123                 glLoadMatrixf(view_mat[0]);
124
125                 draw_backdrop();
126
127                 app_swap_buffers();
128         }
129         assert(glGetError() == GL_NO_ERROR);
130 }
131
132 void app_reshape(int x, int y)
133 {
134         glViewport(0, 0, x, y);
135
136         Mat4 mat;
137         mat.perspective(deg_to_rad(50), win_aspect, 0.5, 500.0);
138
139         glMatrixMode(GL_PROJECTION);
140         glLoadMatrixf(mat[0]);
141 }
142
143 void app_keyboard(int key, bool pressed)
144 {
145         if(pressed) {
146                 switch(key) {
147                 case 27:
148                         app_quit();
149                         break;
150
151                 case ' ':
152                         if(use_vr) {
153                                 goatvr_recenter();
154                         }
155                         break;
156                 }
157         }
158 }
159
160 void app_mouse_button(int bn, bool pressed, int x, int y)
161 {
162         bnstate[bn] = pressed;
163         prev_x = x;
164         prev_y = y;
165 }
166
167 void app_mouse_motion(int x, int y)
168 {
169         int dx = x - prev_x;
170         int dy = y - prev_y;
171         prev_x = x;
172         prev_y = y;
173
174         if(!dx && !dy) return;
175
176         if(bnstate[0]) {
177                 cam_theta += dx * 0.5;
178
179                 if(!use_vr || !goatvr_have_headtracking()) {
180                         cam_phi += dy * 0.5;
181
182                         if(cam_phi < -90) cam_phi = -90;
183                         if(cam_phi > 90) cam_phi = 90;
184                 }
185         }
186         app_redraw();
187 }
188
189 static bool parse_args(int argc, char **argv)
190 {
191         for(int i=1; i<argc; i++) {
192                 if(argv[i][0] == '-') {
193                         if(strcmp(argv[i], "-vr") == 0) {
194                                 use_vr = true;
195
196                         } else if(strcmp(argv[i], "-novr") == 0) {
197                                 use_vr = false;
198
199                         } else if(strcmp(argv[i], "-help") == 0) {
200                                 printf("usage: %s [options]\noptions:\n", argv[0]);
201                                 printf(" -vr/-novr: enable/disable VR\n");
202                                 printf(" -help: print usage information and exit\n");
203                                 exit(0);
204                         } else {
205                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
206                                 return false;
207                         }
208                 } else {
209                         fprintf(stderr, "unexpected option: %s\n", argv[i]);
210                         return false;
211                 }
212         }
213         return true;
214 }