730302eb6a0400adda783056832bb34d93c11c24
[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 #include "opt.h"
11
12 int win_width, win_height;
13 float win_aspect;
14 long time_msec;
15 Mat4 view_matrix;
16
17 static bool should_swap;
18
19 static float cam_theta, cam_phi;
20 static float cam_height = 1.65;
21 static Mesh *mesh_torus;
22
23 static bool bnstate[16];
24 static int prev_x, prev_y;
25
26 bool app_init(int argc, char **argv)
27 {
28         if(!init_options(argc, argv, 0)) {
29                 return false;
30         }
31         app_resize(opt.width, opt.height);
32         app_fullscreen(opt.fullscreen);
33
34         if(init_opengl() == -1) {
35                 return false;
36         }
37
38         glEnable(GL_MULTISAMPLE);
39
40         int aasamples = 0;
41         glGetIntegerv(GL_SAMPLES, &aasamples);
42         printf("got %d samples per pixel\n", aasamples);
43
44         printf("Max anisotropy: %d\n", glcaps.max_aniso);
45
46         glEnable(GL_CULL_FACE);
47         glEnable(GL_DEPTH_TEST);
48
49         if(opt.srgb && GLEW_ARB_framebuffer_sRGB) {
50                 printf("enabling sRGB framebuffer\n");
51                 glEnable(GL_FRAMEBUFFER_SRGB);
52         }
53
54         if(opt.vr) {
55                 if(goatvr_init() == -1) {
56                         return false;
57                 }
58                 goatvr_set_origin_mode(GOATVR_HEAD);
59
60                 goatvr_startvr();
61                 should_swap = goatvr_should_swap() != 0;
62                 cam_height = goatvr_get_eye_height();
63         }
64
65         Mesh::use_custom_sdr_attr = false;
66
67         mesh_torus = new Mesh;
68         gen_torus(mesh_torus, 1.0, 0.25, 32, 32);
69
70         if(!init_backdrop()) {
71                 return false;
72         }
73
74         return true;
75 }
76
77 void app_cleanup()
78 {
79         if(opt.vr) {
80                 goatvr_shutdown();
81         }
82         delete mesh_torus;
83         cleanup_backdrop();
84 }
85
86 void app_draw()
87 {
88         if(opt.vr) {
89                 // VR mode
90                 goatvr_draw_start();
91                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
92
93                 for(int i=0; i<2; i++) {
94                         goatvr_draw_eye(i);
95
96                         glMatrixMode(GL_PROJECTION);
97                         glLoadMatrixf(goatvr_projection_matrix(i, 0.5, 1000.0));
98
99                         view_matrix = goatvr_view_matrix(i);
100                         view_matrix.pre_rotate_x(deg_to_rad(cam_phi));
101                         view_matrix.pre_rotate_y(deg_to_rad(cam_theta));
102                         view_matrix.pre_translate(0, -cam_height, 0);
103
104                         glMatrixMode(GL_MODELVIEW);
105                         glLoadMatrixf(view_matrix[0]);
106
107                         draw_backdrop();
108                 }
109                 goatvr_draw_done();
110
111                 if(should_swap) {
112                         app_swap_buffers();
113                 }
114                 app_redraw();   // in VR mode, force continuous redraw
115
116         } else {
117                 // regular monoscopic mode
118                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
119
120                 view_matrix = Mat4::identity;
121                 view_matrix.pre_rotate_x(deg_to_rad(cam_phi));
122                 view_matrix.pre_rotate_y(deg_to_rad(cam_theta));
123                 view_matrix.pre_translate(0, -cam_height, 0);
124
125                 glMatrixMode(GL_MODELVIEW);
126                 glLoadMatrixf(view_matrix[0]);
127
128                 draw_backdrop();
129
130                 app_swap_buffers();
131         }
132         assert(glGetError() == GL_NO_ERROR);
133 }
134
135 void app_reshape(int x, int y)
136 {
137         glViewport(0, 0, x, y);
138
139         Mat4 mat;
140         mat.perspective(deg_to_rad(50), win_aspect, 0.5, 500.0);
141
142         glMatrixMode(GL_PROJECTION);
143         glLoadMatrixf(mat[0]);
144 }
145
146 void app_keyboard(int key, bool pressed)
147 {
148         if(pressed) {
149                 switch(key) {
150                 case 27:
151                         app_quit();
152                         break;
153
154                 case ' ':
155                         if(opt.vr) {
156                                 goatvr_recenter();
157                         }
158                         break;
159                 }
160         }
161 }
162
163 void app_mouse_button(int bn, bool pressed, int x, int y)
164 {
165         bnstate[bn] = pressed;
166         prev_x = x;
167         prev_y = y;
168 }
169
170 void app_mouse_motion(int x, int y)
171 {
172         int dx = x - prev_x;
173         int dy = y - prev_y;
174         prev_x = x;
175         prev_y = y;
176
177         if(!dx && !dy) return;
178
179         if(bnstate[0]) {
180                 cam_theta += dx * 0.5;
181
182                 if(!opt.vr || !goatvr_have_headtracking()) {
183                         cam_phi += dy * 0.5;
184
185                         if(cam_phi < -90) cam_phi = -90;
186                         if(cam_phi > 90) cam_phi = 90;
187                 }
188         }
189         app_redraw();
190 }