oculus2
changeset 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 |
files | src/main.c |
diffstat | 1 files changed, 40 insertions(+), 1 deletions(-) [+] |
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;