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