oculus2
diff src/main.c @ 0:0a4d62469381
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 26 Aug 2014 02:55:17 +0300 |
parents | |
children | 0984fa94b490 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/main.c Tue Aug 26 02:55:17 2014 +0300 1.3 @@ -0,0 +1,212 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <SDL2/SDL.h> 1.7 +#include <GL/glew.h> 1.8 + 1.9 +#include <OVR_CAPI.h> 1.10 +#include <OVR_CAPI_GL.h> 1.11 + 1.12 +int init(); 1.13 +void cleanup(); 1.14 +void display(); 1.15 +void update_rtarg(int width, int height); 1.16 +int handle_event(SDL_Event *ev); 1.17 +int key_event(int key, int state); 1.18 +void reshape(int x, int y); 1.19 +unsigned int next_pow2(unsigned int x); 1.20 + 1.21 +OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enable); 1.22 + 1.23 +static SDL_Window *win; 1.24 +static SDL_GLContext ctx; 1.25 + 1.26 +static unsigned int fbo, fb_tex, fb_depth; 1.27 +static int fb_width, fb_height; 1.28 +static int fb_tex_width, fb_tex_height; 1.29 + 1.30 +static ovrHmd hmd; 1.31 +static ovrSizei eyeres[2]; 1.32 + 1.33 + 1.34 +int main(void) 1.35 +{ 1.36 + if(init() == -1) { 1.37 + return 1; 1.38 + } 1.39 + 1.40 + for(;;) { 1.41 + SDL_Event ev; 1.42 + 1.43 + while(SDL_PollEvent(&ev)) { 1.44 + if(handle_event(&ev) == -1) { 1.45 + goto done; 1.46 + } 1.47 + } 1.48 + 1.49 + display(); 1.50 + } 1.51 + 1.52 +done: 1.53 + cleanup(); 1.54 + return 0; 1.55 +} 1.56 + 1.57 + 1.58 +int init() 1.59 +{ 1.60 + int x, y; 1.61 + unsigned int flags, dcaps; 1.62 + union ovrGLConfig glcfg; 1.63 + ovrEyeRenderDesc eye_rdesc[2]; 1.64 + 1.65 + // this must be called before any OpenGL init according to the docs 1.66 + ovr_Initialize(); 1.67 + 1.68 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 1.69 + 1.70 + x = y = SDL_WINDOWPOS_UNDEFINED; 1.71 + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; 1.72 + if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) { 1.73 + fprintf(stderr, "failed to create window\n"); 1.74 + return -1; 1.75 + } 1.76 + if(!(ctx = SDL_GL_CreateContext(win))) { 1.77 + fprintf(stderr, "failed to create OpenGL context\n"); 1.78 + return -1; 1.79 + } 1.80 + 1.81 + glewInit(); 1.82 + 1.83 + if(!(hmd = ovrHmd_Create(0))) { 1.84 + fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n"); 1.85 + if(!(hmd = ovrHmd_CreateDebug())) { 1.86 + fprintf(stderr, "failed to create virtual debug HMD\n"); 1.87 + return -1; 1.88 + } 1.89 + } 1.90 + printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName); 1.91 + 1.92 + SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h); 1.93 + 1.94 + ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); 1.95 + eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0); 1.96 + eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0); 1.97 + 1.98 + fb_width = eyeres[0].w + eyres[1].w; 1.99 + fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h; 1.100 + update_rtarg(fb_width, fb_height); 1.101 + 1.102 + memset(&glcfg, 0, sizeof glcfg); 1.103 + glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; 1.104 + glcfg.OGL.Header.RTSize = hmd->Resolution; 1.105 + glcfg.OGL.Header.Multisample = 1; 1.106 + 1.107 + if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) { 1.108 + printf("running in \"extended desktop\" mode\n"); 1.109 + } else { 1.110 + printf("running in \"direct-hmd\" mode\n"); 1.111 +#ifdef WIN32 1.112 + ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0); 1.113 +#endif 1.114 + } 1.115 + ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction); 1.116 + 1.117 + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap; 1.118 + if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) { 1.119 + fprintf(stderr, "failed to configure distortion renderer\n"); 1.120 + } 1.121 + 1.122 + ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 1.123 + 1.124 + 1.125 + glEnable(GL_DEPTH_TEST); 1.126 + glEnable(GL_CULL_FACE); 1.127 + glEnable(GL_LIGHTING); 1.128 + glEnable(GL_LIGHT0); 1.129 + 1.130 + glClearColor(0.05, 0.05, 0.05, 1); 1.131 + 1.132 + return 0; 1.133 +} 1.134 + 1.135 +void cleanup() 1.136 +{ 1.137 + if(hmd) { 1.138 + ovrHmd_Destroy(hmd); 1.139 + } 1.140 + ovr_Shutdown(); 1.141 + 1.142 + SDL_Quit(); 1.143 +} 1.144 + 1.145 +void display() 1.146 +{ 1.147 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.148 + 1.149 + SDL_GL_SwapWindow(win); 1.150 +} 1.151 + 1.152 +void update_rtarg(int width, int height) 1.153 +{ 1.154 + if(!fbo) { 1.155 + glGenFramebuffers(1, &fbo); 1.156 + glGenTextures(1, &fb_tex); 1.157 + glGenRenderbuffers(1, &fb_depth); 1.158 + 1.159 + glBindTexture(GL_TEXTURE_2D, fb_tex); 1.160 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.161 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.162 + } 1.163 + 1.164 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 1.165 + 1.166 + fb_tex_width = next_pow2(width); 1.167 + fb_tex_height = next_pow2(height); 1.168 + 1.169 + glBindTexture(GL_TEXTURE_2D, fb_tex); 1.170 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0, 1.171 + GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.172 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0); 1.173 + 1.174 + glBindRenderbuffer(GL_RENDERBUFFER, fb_depth); 1.175 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_width, fb_tex_height); 1.176 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth); 1.177 + 1.178 + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 1.179 + fprintf(stderr, "incomplete framebuffer!\n"); 1.180 + } 1.181 + 1.182 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 1.183 + printf("created render target: %dx%d (texture size: %dx%d)\n", width, height, fb_tex_width, fb_tex_height); 1.184 +} 1.185 + 1.186 +int handle_event(SDL_Event *ev) 1.187 +{ 1.188 + switch(ev->type) { 1.189 + case SDL_KEYDOWN: 1.190 + case SDL_KEYUP: 1.191 + if(key_event(ev->key.keysym.sym, ev->key.state == SDL_PRESSED) == -1) { 1.192 + return -1; 1.193 + } 1.194 + break; 1.195 + 1.196 + default: 1.197 + break; 1.198 + } 1.199 + 1.200 + return 0; 1.201 +} 1.202 + 1.203 +int key_event(int key, int state) 1.204 +{ 1.205 + if(state) { 1.206 + switch(key) { 1.207 + case 27: 1.208 + return -1; 1.209 + 1.210 + default: 1.211 + break; 1.212 + } 1.213 + } 1.214 + return 0; 1.215 +}