rev |
line source |
nuclear@2
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <assert.h>
|
nuclear@2
|
3 #include <algorithm>
|
nuclear@2
|
4 #include "opengl.h"
|
nuclear@2
|
5 #include "game.h"
|
nuclear@2
|
6 #include "goatvr.h"
|
nuclear@2
|
7
|
nuclear@2
|
8 static void draw_scene();
|
nuclear@2
|
9 static void toggle_hmd_fullscr();
|
nuclear@2
|
10 static void create_rtarg(int x, int y);
|
nuclear@2
|
11 static int next_pow2(int x);
|
nuclear@2
|
12
|
nuclear@2
|
13 static int win_width, win_height;
|
nuclear@2
|
14 static unsigned int fb_tex;
|
nuclear@2
|
15 static unsigned int fbo, fb_depth;
|
nuclear@2
|
16 static int fb_xsz, fb_ysz;
|
nuclear@2
|
17 static int fb_tex_xsz, fb_tex_ysz;
|
nuclear@2
|
18
|
nuclear@2
|
19 bool game_init()
|
nuclear@2
|
20 {
|
nuclear@2
|
21 init_opengl();
|
nuclear@2
|
22
|
nuclear@2
|
23 if(vr_init() == -1) {
|
nuclear@2
|
24 return false;
|
nuclear@2
|
25 }
|
nuclear@2
|
26
|
nuclear@2
|
27 glEnable(GL_DEPTH_TEST);
|
nuclear@2
|
28 glEnable(GL_CULL_FACE);
|
nuclear@2
|
29
|
nuclear@2
|
30 return true;
|
nuclear@2
|
31 }
|
nuclear@2
|
32
|
nuclear@2
|
33 void game_cleanup()
|
nuclear@2
|
34 {
|
nuclear@2
|
35 vr_shutdown();
|
nuclear@2
|
36 }
|
nuclear@2
|
37
|
nuclear@2
|
38 void game_update(long tm)
|
nuclear@2
|
39 {
|
nuclear@2
|
40 }
|
nuclear@2
|
41
|
nuclear@2
|
42 void game_display()
|
nuclear@2
|
43 {
|
nuclear@2
|
44 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@2
|
45 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@2
|
46
|
nuclear@2
|
47 for(int i=0; i<2; i++) {
|
nuclear@2
|
48 glViewport(i == 0 ? 0 : fb_xsz / 2, 0, fb_xsz / 2, fb_ysz);
|
nuclear@2
|
49 vr_begin(i);
|
nuclear@2
|
50
|
nuclear@2
|
51 float proj[16];
|
nuclear@2
|
52 if(vr_proj_matrix(i, 0.5, 500.0, proj)) {
|
nuclear@2
|
53 glMatrixMode(GL_PROJECTION);
|
nuclear@2
|
54 glLoadMatrixf(proj);
|
nuclear@2
|
55 }
|
nuclear@2
|
56
|
nuclear@2
|
57 glMatrixMode(GL_MODELVIEW);
|
nuclear@2
|
58
|
nuclear@2
|
59 float view[16];
|
nuclear@2
|
60 vr_view_matrix(i, view);
|
nuclear@2
|
61 glLoadMatrixf(view);
|
nuclear@2
|
62 /* move the camera to the eye level of the user */
|
nuclear@2
|
63 glTranslatef(0, -vr_getf_def(VR_EYE_HEIGHT, 1.65), 0);
|
nuclear@2
|
64
|
nuclear@2
|
65 draw_scene();
|
nuclear@2
|
66
|
nuclear@2
|
67 vr_end();
|
nuclear@2
|
68 }
|
nuclear@2
|
69
|
nuclear@2
|
70 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@2
|
71 glViewport(0, 0, win_width, win_height);
|
nuclear@2
|
72
|
nuclear@2
|
73 vr_swap_buffers();
|
nuclear@2
|
74 assert(glGetError() == GL_NO_ERROR);
|
nuclear@2
|
75 }
|
nuclear@2
|
76
|
nuclear@2
|
77 void game_reshape(int x, int y)
|
nuclear@2
|
78 {
|
nuclear@2
|
79 win_width = x;
|
nuclear@2
|
80 win_height = y;
|
nuclear@2
|
81
|
nuclear@2
|
82 create_rtarg(vr_geti_def(VR_RENDER_XRES, x), vr_geti_def(VR_RENDER_YRES, y));
|
nuclear@2
|
83 vr_output_texture(fb_tex, 0, 0, (float)fb_xsz / (float)fb_tex_xsz, (float)fb_ysz / (float)fb_tex_ysz);
|
nuclear@2
|
84
|
nuclear@2
|
85 /* these might be overriden in VR mode (see game_display) */
|
nuclear@2
|
86 glViewport(0, 0, x, y);
|
nuclear@2
|
87 glMatrixMode(GL_PROJECTION);
|
nuclear@2
|
88 glLoadIdentity();
|
nuclear@2
|
89 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
|
nuclear@2
|
90 }
|
nuclear@2
|
91
|
nuclear@2
|
92 void game_keyboard(int key, bool pressed)
|
nuclear@2
|
93 {
|
nuclear@2
|
94 if(pressed) {
|
nuclear@2
|
95 switch(key) {
|
nuclear@2
|
96 case 27:
|
nuclear@2
|
97 exit_game();
|
nuclear@2
|
98 break;
|
nuclear@2
|
99
|
nuclear@2
|
100 case 'f':
|
nuclear@2
|
101 toggle_hmd_fullscr();
|
nuclear@2
|
102 break;
|
nuclear@2
|
103
|
nuclear@2
|
104 case 'r':
|
nuclear@2
|
105 vr_recenter();
|
nuclear@2
|
106 break;
|
nuclear@2
|
107
|
nuclear@2
|
108 default:
|
nuclear@2
|
109 break;
|
nuclear@2
|
110 }
|
nuclear@2
|
111 }
|
nuclear@2
|
112 }
|
nuclear@2
|
113
|
nuclear@2
|
114 void game_mouse_button(int bn, bool state, int x, int y)
|
nuclear@2
|
115 {
|
nuclear@2
|
116 }
|
nuclear@2
|
117
|
nuclear@2
|
118 void game_mouse_motion(int x, int y)
|
nuclear@2
|
119 {
|
nuclear@2
|
120 }
|
nuclear@2
|
121
|
nuclear@2
|
122 static void draw_scene()
|
nuclear@2
|
123 {
|
nuclear@2
|
124 }
|
nuclear@2
|
125
|
nuclear@2
|
126 static void toggle_hmd_fullscr()
|
nuclear@2
|
127 {
|
nuclear@2
|
128 static bool fullscr;
|
nuclear@2
|
129 static int prev_x, prev_y;
|
nuclear@2
|
130 //static int prev_xsz, prev_ysz;
|
nuclear@2
|
131
|
nuclear@2
|
132 fullscr = !fullscr;
|
nuclear@2
|
133 if(fullscr) {
|
nuclear@2
|
134 /* entering fullscreen on the HMD */
|
nuclear@2
|
135 int xoffs = vr_geti_def(VR_WIN_XOFFS, -1);
|
nuclear@2
|
136 int yoffs = vr_geti_def(VR_WIN_YOFFS, -1);
|
nuclear@2
|
137 if(xoffs != -1) {
|
nuclear@2
|
138 get_window_pos(&prev_x, &prev_y);
|
nuclear@2
|
139 move_window(xoffs, yoffs);
|
nuclear@2
|
140 }
|
nuclear@2
|
141
|
nuclear@2
|
142 int xsz = vr_geti_def(VR_DISPLAY_WIDTH, -1);
|
nuclear@2
|
143 int ysz = vr_geti_def(VR_DISPLAY_HEIGHT, -1);
|
nuclear@2
|
144 if(xsz != -1) {
|
nuclear@2
|
145 //prev_xsz = win_width;
|
nuclear@2
|
146 //prev_ysz = win_height;
|
nuclear@2
|
147 resize_window(xsz, ysz);
|
nuclear@2
|
148 }
|
nuclear@2
|
149 enter_fullscreen();
|
nuclear@2
|
150
|
nuclear@2
|
151 } else {
|
nuclear@2
|
152 /* leaving fullscreen */
|
nuclear@2
|
153 leave_fullscreen();
|
nuclear@2
|
154 /*move_window(prev_x, prev_y);
|
nuclear@2
|
155 resize_window(prev_xsz, prev_ysz);*/
|
nuclear@2
|
156 }
|
nuclear@2
|
157 }
|
nuclear@2
|
158
|
nuclear@2
|
159 static void create_rtarg(int x, int y)
|
nuclear@2
|
160 {
|
nuclear@2
|
161 if(x == fb_xsz && y == fb_ysz) {
|
nuclear@2
|
162 return; // nothing changed
|
nuclear@2
|
163 }
|
nuclear@2
|
164
|
nuclear@2
|
165 fb_xsz = x;
|
nuclear@2
|
166 fb_ysz = y;
|
nuclear@2
|
167 fb_tex_xsz = next_pow2(fb_xsz);
|
nuclear@2
|
168 fb_tex_ysz = next_pow2(fb_ysz);
|
nuclear@2
|
169
|
nuclear@2
|
170 if(!fbo) {
|
nuclear@2
|
171 glGenFramebuffers(1, &fbo);
|
nuclear@2
|
172
|
nuclear@2
|
173 glGenTextures(1, &fb_tex);
|
nuclear@2
|
174 glBindTexture(GL_TEXTURE_2D, fb_tex);
|
nuclear@2
|
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@2
|
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@2
|
177
|
nuclear@2
|
178 glGenRenderbuffers(1, &fb_depth);
|
nuclear@2
|
179 }
|
nuclear@2
|
180
|
nuclear@2
|
181 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@2
|
182
|
nuclear@2
|
183 glBindTexture(GL_TEXTURE_2D, fb_tex);
|
nuclear@2
|
184 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_xsz, fb_tex_ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
nuclear@2
|
185 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0);
|
nuclear@2
|
186
|
nuclear@2
|
187 glBindRenderbuffer(GL_RENDERBUFFER, fb_depth);
|
nuclear@2
|
188 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_xsz, fb_tex_ysz);
|
nuclear@2
|
189 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth);
|
nuclear@2
|
190
|
nuclear@2
|
191 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
nuclear@2
|
192 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@2
|
193 }
|
nuclear@2
|
194
|
nuclear@2
|
195 static int next_pow2(int x)
|
nuclear@2
|
196 {
|
nuclear@2
|
197 x -= 1;
|
nuclear@2
|
198 x |= x >> 1;
|
nuclear@2
|
199 x |= x >> 2;
|
nuclear@2
|
200 x |= x >> 4;
|
nuclear@2
|
201 x |= x >> 8;
|
nuclear@2
|
202 x |= x >> 16;
|
nuclear@2
|
203 return x + 1;
|
nuclear@2
|
204 }
|