vrheights

annotate src/game.cc @ 3:316ec8250af2

added the teapot code for testing
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 25 Sep 2014 17:13:23 +0300
parents b49461618f61
children 690ef7fa791f
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@3 7 #include "teapot.h"
nuclear@2 8
nuclear@2 9 static void draw_scene();
nuclear@2 10 static void toggle_hmd_fullscr();
nuclear@2 11 static void create_rtarg(int x, int y);
nuclear@2 12 static int next_pow2(int x);
nuclear@2 13
nuclear@2 14 static int win_width, win_height;
nuclear@2 15 static unsigned int fb_tex;
nuclear@2 16 static unsigned int fbo, fb_depth;
nuclear@2 17 static int fb_xsz, fb_ysz;
nuclear@2 18 static int fb_tex_xsz, fb_tex_ysz;
nuclear@2 19
nuclear@2 20 bool game_init()
nuclear@2 21 {
nuclear@2 22 init_opengl();
nuclear@2 23
nuclear@2 24 if(vr_init() == -1) {
nuclear@2 25 return false;
nuclear@2 26 }
nuclear@2 27
nuclear@2 28 glEnable(GL_DEPTH_TEST);
nuclear@2 29 glEnable(GL_CULL_FACE);
nuclear@3 30 glEnable(GL_LIGHTING);
nuclear@2 31
nuclear@2 32 return true;
nuclear@2 33 }
nuclear@2 34
nuclear@2 35 void game_cleanup()
nuclear@2 36 {
nuclear@2 37 vr_shutdown();
nuclear@2 38 }
nuclear@2 39
nuclear@2 40 void game_update(long tm)
nuclear@2 41 {
nuclear@2 42 }
nuclear@2 43
nuclear@2 44 void game_display()
nuclear@2 45 {
nuclear@2 46 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@2 47 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@2 48
nuclear@2 49 for(int i=0; i<2; i++) {
nuclear@2 50 glViewport(i == 0 ? 0 : fb_xsz / 2, 0, fb_xsz / 2, fb_ysz);
nuclear@2 51 vr_begin(i);
nuclear@2 52
nuclear@2 53 float proj[16];
nuclear@2 54 if(vr_proj_matrix(i, 0.5, 500.0, proj)) {
nuclear@2 55 glMatrixMode(GL_PROJECTION);
nuclear@2 56 glLoadMatrixf(proj);
nuclear@2 57 }
nuclear@2 58
nuclear@2 59 glMatrixMode(GL_MODELVIEW);
nuclear@2 60
nuclear@2 61 float view[16];
nuclear@2 62 vr_view_matrix(i, view);
nuclear@2 63 glLoadMatrixf(view);
nuclear@2 64 /* move the camera to the eye level of the user */
nuclear@2 65 glTranslatef(0, -vr_getf_def(VR_EYE_HEIGHT, 1.65), 0);
nuclear@2 66
nuclear@2 67 draw_scene();
nuclear@2 68
nuclear@2 69 vr_end();
nuclear@2 70 }
nuclear@2 71
nuclear@2 72 glBindFramebuffer(GL_FRAMEBUFFER, 0);
nuclear@2 73 glViewport(0, 0, win_width, win_height);
nuclear@2 74
nuclear@2 75 vr_swap_buffers();
nuclear@2 76 assert(glGetError() == GL_NO_ERROR);
nuclear@2 77 }
nuclear@2 78
nuclear@2 79 void game_reshape(int x, int y)
nuclear@2 80 {
nuclear@2 81 win_width = x;
nuclear@2 82 win_height = y;
nuclear@2 83
nuclear@2 84 create_rtarg(vr_geti_def(VR_RENDER_XRES, x), vr_geti_def(VR_RENDER_YRES, y));
nuclear@2 85 vr_output_texture(fb_tex, 0, 0, (float)fb_xsz / (float)fb_tex_xsz, (float)fb_ysz / (float)fb_tex_ysz);
nuclear@2 86
nuclear@2 87 /* these might be overriden in VR mode (see game_display) */
nuclear@2 88 glViewport(0, 0, x, y);
nuclear@2 89 glMatrixMode(GL_PROJECTION);
nuclear@2 90 glLoadIdentity();
nuclear@2 91 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
nuclear@2 92 }
nuclear@2 93
nuclear@2 94 void game_keyboard(int key, bool pressed)
nuclear@2 95 {
nuclear@2 96 if(pressed) {
nuclear@2 97 switch(key) {
nuclear@2 98 case 27:
nuclear@2 99 exit_game();
nuclear@2 100 break;
nuclear@2 101
nuclear@2 102 case 'f':
nuclear@2 103 toggle_hmd_fullscr();
nuclear@2 104 break;
nuclear@2 105
nuclear@2 106 case 'r':
nuclear@2 107 vr_recenter();
nuclear@2 108 break;
nuclear@2 109
nuclear@2 110 default:
nuclear@2 111 break;
nuclear@2 112 }
nuclear@2 113 }
nuclear@2 114 }
nuclear@2 115
nuclear@2 116 void game_mouse_button(int bn, bool state, int x, int y)
nuclear@2 117 {
nuclear@2 118 }
nuclear@2 119
nuclear@2 120 void game_mouse_motion(int x, int y)
nuclear@2 121 {
nuclear@2 122 }
nuclear@2 123
nuclear@3 124 static void material(float r, float g, float b, float roughness)
nuclear@3 125 {
nuclear@3 126 float gloss = 1.0 - roughness;
nuclear@3 127 float diffuse[] = {r * roughness, g * roughness, b * roughness, 1.0};
nuclear@3 128 float specular[] = {gloss, gloss, gloss, 1.0};
nuclear@3 129 float shin = gloss * 128.0;
nuclear@3 130
nuclear@3 131 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuse);
nuclear@3 132 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
nuclear@3 133 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shin);
nuclear@3 134 }
nuclear@3 135
nuclear@2 136 static void draw_scene()
nuclear@2 137 {
nuclear@3 138 float lpos[][4] = {
nuclear@3 139 {-0.7, 0.7, 1, 0},
nuclear@3 140 {1, 0, 1, 0}
nuclear@3 141 };
nuclear@3 142 float lcol[][4] = {
nuclear@3 143 {0.9, 0.7, 0.6, 1},
nuclear@3 144 {0.3, 0.4, 0.75, 1}
nuclear@3 145 };
nuclear@3 146 for(int i=0; i<2; i++) {
nuclear@3 147 glEnable(GL_LIGHT0 + i);
nuclear@3 148 glLightfv(GL_LIGHT0 + i, GL_POSITION, lpos[i]);
nuclear@3 149 glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, lcol[i]);
nuclear@3 150 glLightfv(GL_LIGHT0 + i, GL_SPECULAR, lcol[i]);
nuclear@3 151 }
nuclear@3 152
nuclear@3 153 glMatrixMode(GL_MODELVIEW);
nuclear@3 154
nuclear@3 155 material(1, 1, 1, 1);
nuclear@3 156 glBegin(GL_QUADS);
nuclear@3 157 glNormal3f(0, 1, 0);
nuclear@3 158 glVertex3f(-10, 0, 10);
nuclear@3 159 glVertex3f(10, 0, 10);
nuclear@3 160 glVertex3f(10, 0, -10);
nuclear@3 161 glVertex3f(-10, 0, -10);
nuclear@3 162 glEnd();
nuclear@3 163
nuclear@3 164 material(1, 1, 1, 0.4);
nuclear@3 165 glPushMatrix();
nuclear@3 166 glTranslatef(0, 1.3, -10);
nuclear@3 167 glFrontFace(GL_CW);
nuclear@3 168 bezier_teapot(2.0);
nuclear@3 169 glFrontFace(GL_CCW);
nuclear@3 170 glPopMatrix();
nuclear@2 171 }
nuclear@2 172
nuclear@2 173 static void toggle_hmd_fullscr()
nuclear@2 174 {
nuclear@2 175 static bool fullscr;
nuclear@2 176 static int prev_x, prev_y;
nuclear@2 177 //static int prev_xsz, prev_ysz;
nuclear@2 178
nuclear@2 179 fullscr = !fullscr;
nuclear@2 180 if(fullscr) {
nuclear@2 181 /* entering fullscreen on the HMD */
nuclear@2 182 int xoffs = vr_geti_def(VR_WIN_XOFFS, -1);
nuclear@2 183 int yoffs = vr_geti_def(VR_WIN_YOFFS, -1);
nuclear@2 184 if(xoffs != -1) {
nuclear@2 185 get_window_pos(&prev_x, &prev_y);
nuclear@2 186 move_window(xoffs, yoffs);
nuclear@2 187 }
nuclear@2 188
nuclear@2 189 int xsz = vr_geti_def(VR_DISPLAY_WIDTH, -1);
nuclear@2 190 int ysz = vr_geti_def(VR_DISPLAY_HEIGHT, -1);
nuclear@2 191 if(xsz != -1) {
nuclear@2 192 //prev_xsz = win_width;
nuclear@2 193 //prev_ysz = win_height;
nuclear@2 194 resize_window(xsz, ysz);
nuclear@2 195 }
nuclear@2 196 enter_fullscreen();
nuclear@2 197
nuclear@2 198 } else {
nuclear@2 199 /* leaving fullscreen */
nuclear@2 200 leave_fullscreen();
nuclear@2 201 /*move_window(prev_x, prev_y);
nuclear@2 202 resize_window(prev_xsz, prev_ysz);*/
nuclear@2 203 }
nuclear@2 204 }
nuclear@2 205
nuclear@2 206 static void create_rtarg(int x, int y)
nuclear@2 207 {
nuclear@2 208 if(x == fb_xsz && y == fb_ysz) {
nuclear@2 209 return; // nothing changed
nuclear@2 210 }
nuclear@2 211
nuclear@2 212 fb_xsz = x;
nuclear@2 213 fb_ysz = y;
nuclear@2 214 fb_tex_xsz = next_pow2(fb_xsz);
nuclear@2 215 fb_tex_ysz = next_pow2(fb_ysz);
nuclear@2 216
nuclear@2 217 if(!fbo) {
nuclear@2 218 glGenFramebuffers(1, &fbo);
nuclear@2 219
nuclear@2 220 glGenTextures(1, &fb_tex);
nuclear@2 221 glBindTexture(GL_TEXTURE_2D, fb_tex);
nuclear@2 222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@2 223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@2 224
nuclear@2 225 glGenRenderbuffers(1, &fb_depth);
nuclear@2 226 }
nuclear@2 227
nuclear@2 228 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@2 229
nuclear@2 230 glBindTexture(GL_TEXTURE_2D, fb_tex);
nuclear@2 231 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_xsz, fb_tex_ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
nuclear@2 232 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0);
nuclear@2 233
nuclear@2 234 glBindRenderbuffer(GL_RENDERBUFFER, fb_depth);
nuclear@2 235 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_xsz, fb_tex_ysz);
nuclear@2 236 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth);
nuclear@2 237
nuclear@2 238 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
nuclear@2 239 glBindFramebuffer(GL_FRAMEBUFFER, 0);
nuclear@2 240 }
nuclear@2 241
nuclear@2 242 static int next_pow2(int x)
nuclear@2 243 {
nuclear@2 244 x -= 1;
nuclear@2 245 x |= x >> 1;
nuclear@2 246 x |= x >> 2;
nuclear@2 247 x |= x >> 4;
nuclear@2 248 x |= x >> 8;
nuclear@2 249 x |= x >> 16;
nuclear@2 250 return x + 1;
nuclear@2 251 }