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 +}