oculus2_psprite
diff src/main.c @ 21:dc7af0f549b2
VR point sprite shooting test
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 22 Jan 2015 06:19:52 +0200 |
parents | 6a3a9840c303 |
children | fe9600396f65 |
line diff
1.1 --- a/src/main.c Wed Jan 21 11:29:30 2015 +0200 1.2 +++ b/src/main.c Thu Jan 22 06:19:52 2015 +0200 1.3 @@ -1,11 +1,3 @@ 1.4 -/* Very simple OculusSDK OpenGL usage example. 1.5 - * 1.6 - * Uses SDL2 (www.libsdl.org) for event handling and OpenGL context management. 1.7 - * Uses GLEW (glew.sourceforge.net) for OpenGL extension wrangling. 1.8 - * 1.9 - * Author: John Tsiombikas <nuclear@member.fsf.org> 1.10 - * This code is in the public domain. Do whatever you like with it. 1.11 - */ 1.12 #include <stdio.h> 1.13 #include <stdlib.h> 1.14 #include <assert.h> 1.15 @@ -24,11 +16,16 @@ 1.16 1.17 #include <OVR_CAPI.h> 1.18 #include <OVR_CAPI_GL.h> 1.19 +#include "projectile.h" 1.20 + 1.21 +#define GUN_Y 1.5 1.22 1.23 int init(void); 1.24 +int init_rift(void); 1.25 void cleanup(void); 1.26 void toggle_hmd_fullscreen(void); 1.27 void display(void); 1.28 +void display_rift(void); 1.29 void draw_scene(void); 1.30 void draw_box(float xsz, float ysz, float zsz, float norm_sign); 1.31 void update_rtarg(int width, int height); 1.32 @@ -38,6 +35,7 @@ 1.33 unsigned int next_pow2(unsigned int x); 1.34 void quat_to_matrix(const float *quat, float *mat); 1.35 unsigned int gen_chess_tex(float r0, float g0, float b0, float r1, float g1, float b1); 1.36 +int parse_args(int argc, char **argv); 1.37 1.38 /* forward declaration to avoid including non-public headers of libovr */ 1.39 OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enable); 1.40 @@ -50,6 +48,7 @@ 1.41 static int fb_width, fb_height; 1.42 static int fb_tex_width, fb_tex_height; 1.43 1.44 +static int use_rift = 1; 1.45 static ovrHmd hmd; 1.46 static ovrSizei eyeres[2]; 1.47 static ovrEyeRenderDesc eye_rdesc[2]; 1.48 @@ -60,9 +59,16 @@ 1.49 1.50 static unsigned int chess_tex; 1.51 1.52 +static float cam_theta, cam_phi; 1.53 + 1.54 1.55 int main(int argc, char **argv) 1.56 { 1.57 + unsigned int msec, prev_frame_msec; 1.58 + 1.59 + if(parse_args(argc, argv) == -1) { 1.60 + return 1; 1.61 + } 1.62 if(init() == -1) { 1.63 return 1; 1.64 } 1.65 @@ -74,7 +80,16 @@ 1.66 goto done; 1.67 } 1.68 } 1.69 - display(); 1.70 + 1.71 + msec = SDL_GetTicks(); 1.72 + update_shots((msec - prev_frame_msec) / 1000.0); 1.73 + prev_frame_msec = msec; 1.74 + 1.75 + if(use_rift) { 1.76 + display_rift(); 1.77 + } else { 1.78 + display(); 1.79 + } 1.80 } 1.81 1.82 done: 1.83 @@ -85,11 +100,13 @@ 1.84 1.85 int init(void) 1.86 { 1.87 - int i, x, y; 1.88 + int x, y; 1.89 unsigned int flags; 1.90 1.91 - /* libovr must be initialized before we create the OpenGL context */ 1.92 - ovr_Initialize(); 1.93 + if(use_rift) { 1.94 + /* libovr must be initialized before we create the OpenGL context */ 1.95 + ovr_Initialize(); 1.96 + } 1.97 1.98 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 1.99 1.100 @@ -106,6 +123,31 @@ 1.101 1.102 glewInit(); 1.103 1.104 + if(use_rift && init_rift() == -1) { 1.105 + return -1; 1.106 + } 1.107 + 1.108 + if(init_shots() == -1) { 1.109 + return -1; 1.110 + } 1.111 + 1.112 + glEnable(GL_DEPTH_TEST); 1.113 + glEnable(GL_CULL_FACE); 1.114 + glEnable(GL_LIGHTING); 1.115 + glEnable(GL_LIGHT0); 1.116 + glEnable(GL_LIGHT1); 1.117 + glEnable(GL_NORMALIZE); 1.118 + 1.119 + glClearColor(0.1, 0.1, 0.1, 1); 1.120 + 1.121 + chess_tex = gen_chess_tex(1.0, 0.7, 0.4, 0.4, 0.7, 1.0); 1.122 + return 0; 1.123 +} 1.124 + 1.125 +int init_rift(void) 1.126 +{ 1.127 + int i; 1.128 + 1.129 if(!(hmd = ovrHmd_Create(0))) { 1.130 fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n"); 1.131 if(!(hmd = ovrHmd_CreateDebug(ovrHmd_DK2))) { 1.132 @@ -192,26 +234,17 @@ 1.133 1.134 /* disable the retarded "health and safety warning" */ 1.135 ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 1.136 - 1.137 - glEnable(GL_DEPTH_TEST); 1.138 - glEnable(GL_CULL_FACE); 1.139 - glEnable(GL_LIGHTING); 1.140 - glEnable(GL_LIGHT0); 1.141 - glEnable(GL_LIGHT1); 1.142 - glEnable(GL_NORMALIZE); 1.143 - 1.144 - glClearColor(0.1, 0.1, 0.1, 1); 1.145 - 1.146 - chess_tex = gen_chess_tex(1.0, 0.7, 0.4, 0.4, 0.7, 1.0); 1.147 return 0; 1.148 } 1.149 1.150 void cleanup(void) 1.151 { 1.152 - if(hmd) { 1.153 - ovrHmd_Destroy(hmd); 1.154 + if(use_rift) { 1.155 + if(hmd) { 1.156 + ovrHmd_Destroy(hmd); 1.157 + } 1.158 + ovr_Shutdown(); 1.159 } 1.160 - ovr_Shutdown(); 1.161 1.162 SDL_Quit(); 1.163 } 1.164 @@ -226,18 +259,22 @@ 1.165 * to the rift's part of the desktop before going fullscreen 1.166 */ 1.167 SDL_GetWindowPosition(win, &prev_x, &prev_y); 1.168 - SDL_SetWindowPosition(win, hmd->WindowsPos.x, hmd->WindowsPos.y); 1.169 + if(use_rift) { 1.170 + SDL_SetWindowPosition(win, hmd->WindowsPos.x, hmd->WindowsPos.y); 1.171 + } 1.172 SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP); 1.173 1.174 #ifdef OVR_OS_LINUX 1.175 - /* on linux for now we have to deal with screen rotation during rendering. The docs are promoting 1.176 - * not rotating the DK2 screen globally 1.177 - */ 1.178 - glcfg.OGL.Header.BackBufferSize.w = hmd->Resolution.h; 1.179 - glcfg.OGL.Header.BackBufferSize.h = hmd->Resolution.w; 1.180 + if(use_rift) { 1.181 + /* on linux for now we have to deal with screen rotation during rendering. The docs are promoting 1.182 + * not rotating the DK2 screen globally 1.183 + */ 1.184 + glcfg.OGL.Header.BackBufferSize.w = hmd->Resolution.h; 1.185 + glcfg.OGL.Header.BackBufferSize.h = hmd->Resolution.w; 1.186 1.187 - distort_caps |= ovrDistortionCap_LinuxDevFullscreen; 1.188 - ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, hmd->DefaultEyeFov, eye_rdesc); 1.189 + distort_caps |= ovrDistortionCap_LinuxDevFullscreen; 1.190 + ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, hmd->DefaultEyeFov, eye_rdesc); 1.191 + } 1.192 #endif 1.193 } else { 1.194 /* return to windowed mode and move the window back to its original position */ 1.195 @@ -245,16 +282,38 @@ 1.196 SDL_SetWindowPosition(win, prev_x, prev_y); 1.197 1.198 #ifdef OVR_OS_LINUX 1.199 - glcfg.OGL.Header.BackBufferSize = hmd->Resolution; 1.200 + if(use_rift) { 1.201 + glcfg.OGL.Header.BackBufferSize = hmd->Resolution; 1.202 1.203 - distort_caps &= ~ovrDistortionCap_LinuxDevFullscreen; 1.204 - ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, hmd->DefaultEyeFov, eye_rdesc); 1.205 + distort_caps &= ~ovrDistortionCap_LinuxDevFullscreen; 1.206 + ovrHmd_ConfigureRendering(hmd, &glcfg.Config, distort_caps, hmd->DefaultEyeFov, eye_rdesc); 1.207 + } 1.208 #endif 1.209 } 1.210 } 1.211 1.212 void display(void) 1.213 { 1.214 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.215 + 1.216 + glMatrixMode(GL_PROJECTION); 1.217 + glLoadIdentity(); 1.218 + gluPerspective(50.0, (float)win_width / (float)win_height, 0.5, 500.0); 1.219 + 1.220 + glMatrixMode(GL_MODELVIEW); 1.221 + glLoadIdentity(); 1.222 + glRotatef(cam_phi, 1, 0, 0); 1.223 + glRotatef(cam_theta, 0, 1, 0); 1.224 + glTranslatef(0, -1.6, 0); /* player height */ 1.225 + 1.226 + draw_scene(); 1.227 + 1.228 + SDL_GL_SwapWindow(win); 1.229 + assert(glGetError() == GL_NO_ERROR); 1.230 +} 1.231 + 1.232 +void display_rift(void) 1.233 +{ 1.234 int i; 1.235 ovrMatrix4f proj; 1.236 ovrPosef pose[2]; 1.237 @@ -330,6 +389,8 @@ 1.238 { 1.239 win_width = x; 1.240 win_height = y; 1.241 + 1.242 + glViewport(0, 0, x, y); 1.243 } 1.244 1.245 void draw_scene(void) 1.246 @@ -390,6 +451,33 @@ 1.247 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); 1.248 draw_box(0.05, 1.2, 6, 1.0); 1.249 draw_box(6, 1.2, 0.05, 1.0); 1.250 + 1.251 + /* draw laser sight */ 1.252 + glPushMatrix(); 1.253 + glTranslatef(0, GUN_Y, 0); 1.254 + glRotatef(-cam_theta, 0, 1, 0); 1.255 + glRotatef(-cam_phi, 1, 0, 0); 1.256 + 1.257 + glPushAttrib(GL_ENABLE_BIT); 1.258 + glDisable(GL_LIGHTING); 1.259 + glEnable(GL_BLEND); 1.260 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1.261 + 1.262 + glDepthMask(0); 1.263 + glLineWidth(3.0); 1.264 + 1.265 + glBegin(GL_LINES); 1.266 + glColor4f(1.0, 0.2, 0.15, 0.4); 1.267 + glVertex3f(0, 0, 0); 1.268 + glVertex3f(0, 0, -100.0); 1.269 + glEnd(); 1.270 + glLineWidth(1.0); 1.271 + 1.272 + glPopAttrib(); 1.273 + 1.274 + glPopMatrix(); 1.275 + 1.276 + draw_shots(); 1.277 } 1.278 1.279 void draw_box(float xsz, float ysz, float zsz, float norm_sign) 1.280 @@ -486,6 +574,20 @@ 1.281 printf("created render target: %dx%d (texture size: %dx%d)\n", width, height, fb_tex_width, fb_tex_height); 1.282 } 1.283 1.284 +void fire(void) 1.285 +{ 1.286 + vec3_t pos = {0, GUN_Y, 0}; 1.287 + vec3_t dir; 1.288 + float theta = DEG_TO_RAD(cam_theta); 1.289 + float phi = DEG_TO_RAD(cam_phi); 1.290 + 1.291 + dir.x = -sin(-theta) * cos(phi); 1.292 + dir.y = -sin(phi); 1.293 + dir.z = -cos(-theta) * cos(phi); 1.294 + 1.295 + shoot(pos, v3_scale(dir, 10.0)); 1.296 +} 1.297 + 1.298 int handle_event(SDL_Event *ev) 1.299 { 1.300 switch(ev->type) { 1.301 @@ -502,6 +604,34 @@ 1.302 case SDL_WINDOWEVENT: 1.303 if(ev->window.event == SDL_WINDOWEVENT_RESIZED) { 1.304 reshape(ev->window.data1, ev->window.data2); 1.305 + } else if(ev->window.event == SDL_WINDOWEVENT_SHOWN) { 1.306 + int xsz, ysz; 1.307 + SDL_GetWindowSize(win, &xsz, &ysz); 1.308 + reshape(xsz, ysz); 1.309 + } 1.310 + break; 1.311 + 1.312 + case SDL_MOUSEBUTTONDOWN: 1.313 + if(ev->button.button == SDL_BUTTON_LEFT) { 1.314 + fire(); 1.315 + } 1.316 + break; 1.317 + 1.318 + case SDL_MOUSEMOTION: 1.319 + { 1.320 + static int prev_x, prev_y; 1.321 + int dx = ev->motion.x - prev_x; 1.322 + int dy = ev->motion.y - prev_y; 1.323 + prev_x = ev->motion.x; 1.324 + prev_y = ev->motion.y; 1.325 + 1.326 + if(ev->motion.state & SDL_BUTTON_RMASK) { 1.327 + cam_theta += dx * 0.5; 1.328 + cam_phi += dy * 0.5; 1.329 + 1.330 + if(cam_phi < -90) cam_phi = -90; 1.331 + if(cam_phi > 90) cam_phi = 90; 1.332 + } 1.333 } 1.334 break; 1.335 1.336 @@ -628,3 +758,23 @@ 1.337 1.338 return tex; 1.339 } 1.340 + 1.341 +int parse_args(int argc, char **argv) 1.342 +{ 1.343 + int i; 1.344 + 1.345 + for(i=1; i<argc; i++) { 1.346 + if(argv[i][0] == '-') { 1.347 + if(strcmp(argv[i], "-novr") == 0) { 1.348 + use_rift = 0; 1.349 + } else { 1.350 + fprintf(stderr, "invalid option: %s\n", argv[i]); 1.351 + return -1; 1.352 + } 1.353 + } else { 1.354 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.355 + return -1; 1.356 + } 1.357 + } 1.358 + return 0; 1.359 +}