oculus2

diff src/main.c @ 5:cd9f1560b909

added a few comments
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 04 Sep 2014 09:01:01 +0300
parents d64830551c32
children 37c753411934 4d6733229e01
line diff
     1.1 --- a/src/main.c	Thu Sep 04 08:31:12 2014 +0300
     1.2 +++ b/src/main.c	Thu Sep 04 09:01:01 2014 +0300
     1.3 @@ -1,3 +1,9 @@
     1.4 +/* Very simple OculusSDK OpenGL usage example.
     1.5 + * Uses SDL2 for event handling and OpenGL context management.
     1.6 + *
     1.7 + * Author: John Tsiombikas <nuclear@member.fsf.org>
     1.8 + * This code is in the public domain. Do whatever you like with it.
     1.9 + */
    1.10  #include <stdio.h>
    1.11  #include <stdlib.h>
    1.12  #include <assert.h>
    1.13 @@ -102,30 +108,39 @@
    1.14  	}
    1.15  	printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName);
    1.16  
    1.17 +	/* resize our window to match the HMD resolution */
    1.18  	SDL_SetWindowSize(win, hmd->Resolution.w, hmd->Resolution.h);
    1.19  	SDL_SetWindowPosition(win, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
    1.20  	win_width = hmd->Resolution.w;
    1.21  	win_height = hmd->Resolution.h;
    1.22  
    1.23 +	/* enable position and rotation tracking (and anything else they might add in the future) */
    1.24  	ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0);
    1.25 +	/* retrieve the optimal render target resolution for each eye */
    1.26  	eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0);
    1.27  	eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0);
    1.28  
    1.29 +	/* and create a single render target texture to encompass both eyes */
    1.30  	fb_width = eyeres[0].w + eyeres[1].w;
    1.31  	fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h;
    1.32  	update_rtarg(fb_width, fb_height);
    1.33  
    1.34 +	/* fill in the ovrGLTexture structures that describe our render target texture */
    1.35  	for(i=0; i<2; i++) {
    1.36  		fb_ovr_tex[i].OGL.Header.API = ovrRenderAPI_OpenGL;
    1.37  		fb_ovr_tex[i].OGL.Header.TextureSize.w = fb_tex_width;
    1.38  		fb_ovr_tex[i].OGL.Header.TextureSize.h = fb_tex_height;
    1.39 +		/* this next field is the only one that differs between the two eyes */
    1.40  		fb_ovr_tex[i].OGL.Header.RenderViewport.Pos.x = i == 0 ? 0 : fb_width / 2.0;
    1.41  		fb_ovr_tex[i].OGL.Header.RenderViewport.Pos.y = fb_tex_height - fb_height;
    1.42  		fb_ovr_tex[i].OGL.Header.RenderViewport.Size.w = fb_width / 2.0;
    1.43  		fb_ovr_tex[i].OGL.Header.RenderViewport.Size.h = fb_height;
    1.44 -		fb_ovr_tex[i].OGL.TexId = fb_tex;
    1.45 +		fb_ovr_tex[i].OGL.TexId = fb_tex;	/* both eyes will use the same texture id */
    1.46  	}
    1.47  
    1.48 +	/* fill in the ovrGLConfig structure needed by the SDK to draw our stereo pair
    1.49 +	 * to the actual HMD display (SDK-distortion mode)
    1.50 +	 */
    1.51  	memset(&glcfg, 0, sizeof glcfg);
    1.52  	glcfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    1.53  	glcfg.OGL.Header.RTSize = hmd->Resolution;
    1.54 @@ -134,6 +149,10 @@
    1.55  	if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) {
    1.56  		printf("running in \"extended desktop\" mode\n");
    1.57  	} else {
    1.58 +		/* to sucessfully draw to the HMD display in "direct-hmd" mode, we have to
    1.59 +		 * call ovrHmd_AttachToWindow
    1.60 +		 * XXX: this doesn't work properly yet due to bugs in the oculus 0.4.1 sdk/driver
    1.61 +		 */
    1.62  #ifdef WIN32
    1.63  		void *sys_win = GetActiveWindow();
    1.64  		glcfg.OGL.Window = sys_win;
    1.65 @@ -142,13 +161,20 @@
    1.66  #endif
    1.67  		printf("running in \"direct-hmd\" mode\n");
    1.68  	}
    1.69 +
    1.70 +	/* enable low-persistence display and dynamic prediction for lattency compensation */
    1.71  	ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
    1.72  
    1.73 +	/* configure SDK-rendering and enable chromatic abberation correction, vignetting, and
    1.74 +	 * timewrap, which shifts the image before drawing to counter any lattency between the call
    1.75 +	 * to ovrHmd_GetEyePose and ovrHmd_EndFrame.
    1.76 +	 */
    1.77  	dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp;
    1.78  	if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) {
    1.79  		fprintf(stderr, "failed to configure distortion renderer\n");
    1.80  	}
    1.81  
    1.82 +	/* disable the retarded "health and safety warning" */
    1.83  	ovrhmd_EnableHSWDisplaySDKRender(hmd, 0);
    1.84  
    1.85  	glEnable(GL_DEPTH_TEST);
    1.86 @@ -180,10 +206,14 @@
    1.87  	fullscr = !fullscr;
    1.88  
    1.89  	if(fullscr) {
    1.90 +		/* going fullscreen on the rift. save current window position, and move it
    1.91 +		 * to the rift's part of the desktop before going fullscreen
    1.92 +		 */
    1.93  		SDL_GetWindowPosition(win, &prev_x, &prev_y);
    1.94  		SDL_SetWindowPosition(win, hmd->WindowsPos.x, hmd->WindowsPos.y);
    1.95  		SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
    1.96  	} else {
    1.97 +		/* return to windowed mode and move the window back to its original position */
    1.98  		SDL_SetWindowFullscreen(win, 0);
    1.99  		SDL_SetWindowPosition(win, prev_x, prev_y);
   1.100  	}
   1.101 @@ -361,9 +391,11 @@
   1.102  	glFrontFace(GL_CCW);
   1.103  }
   1.104  
   1.105 +/* update_rtarg creates (and/or resizes) the render target used to draw the two stero views */
   1.106  void update_rtarg(int width, int height)
   1.107  {
   1.108  	if(!fbo) {
   1.109 +		/* if fbo does not exist, then nothing does... create every opengl object */
   1.110  		glGenFramebuffers(1, &fbo);
   1.111  		glGenTextures(1, &fb_tex);
   1.112  		glGenRenderbuffers(1, &fb_depth);
   1.113 @@ -375,14 +407,17 @@
   1.114  
   1.115  	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
   1.116  
   1.117 +	/* calculate the next power of two in both dimensions and use that as a texture size */
   1.118  	fb_tex_width = next_pow2(width);
   1.119  	fb_tex_height = next_pow2(height);
   1.120  
   1.121 +	/* create and attach the texture that will be used as a color buffer */
   1.122  	glBindTexture(GL_TEXTURE_2D, fb_tex);
   1.123  	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0,
   1.124  			GL_RGBA, GL_UNSIGNED_BYTE, 0);
   1.125  	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0);
   1.126  
   1.127 +	/* create and attach the renderbuffer that will serve as our z-buffer */
   1.128  	glBindRenderbuffer(GL_RENDERBUFFER, fb_depth);
   1.129  	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_width, fb_tex_height);
   1.130  	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth);
   1.131 @@ -418,11 +453,13 @@
   1.132  int key_event(int key, int state)
   1.133  {
   1.134  	if(state) {
   1.135 +		/*
   1.136  		ovrHSWDisplayState hsw;
   1.137  		ovrHmd_GetHSWDisplayState(hmd, &hsw);
   1.138  		if(hsw.Displayed) {
   1.139  			ovrHmd_DismissHSWDisplay(hmd);
   1.140  		}
   1.141 +		*/
   1.142  
   1.143  		switch(key) {
   1.144  		case 27:
   1.145 @@ -456,6 +493,7 @@
   1.146  	return x + 1;
   1.147  }
   1.148  
   1.149 +/* convert a quaternion to a rotation matrix */
   1.150  void quat_to_matrix(const float *quat, float *mat)
   1.151  {
   1.152  	mat[0] = 1.0 - 2.0 * quat[1] * quat[1] - 2.0 * quat[2] * quat[2];
   1.153 @@ -477,6 +515,7 @@
   1.154  	mat[15] = 1.0f;
   1.155  }
   1.156  
   1.157 +/* generate a chessboard texture with tiles colored (r0, g0, b0) and (r1, g1, b1) */
   1.158  unsigned int gen_chess_tex(float r0, float g0, float b0, float r1, float g1, float b1)
   1.159  {
   1.160  	int i, j;