nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: int init(); nuclear@0: void cleanup(); nuclear@0: void display(); nuclear@0: void update_rtarg(int width, int height); nuclear@0: int handle_event(SDL_Event *ev); nuclear@0: int key_event(int key, int state); nuclear@0: void reshape(int x, int y); nuclear@0: unsigned int next_pow2(unsigned int x); nuclear@0: nuclear@0: OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enable); nuclear@0: nuclear@0: static SDL_Window *win; nuclear@0: static SDL_GLContext ctx; nuclear@0: nuclear@0: static unsigned int fbo, fb_tex, fb_depth; nuclear@0: static int fb_width, fb_height; nuclear@0: static int fb_tex_width, fb_tex_height; nuclear@0: nuclear@0: static ovrHmd hmd; nuclear@0: static ovrSizei eyeres[2]; nuclear@0: nuclear@0: nuclear@0: int main(void) nuclear@0: { nuclear@0: if(init() == -1) { nuclear@0: return 1; nuclear@0: } nuclear@0: nuclear@0: for(;;) { nuclear@0: SDL_Event ev; nuclear@0: nuclear@0: while(SDL_PollEvent(&ev)) { nuclear@0: if(handle_event(&ev) == -1) { nuclear@0: goto done; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: display(); nuclear@0: } nuclear@0: nuclear@0: done: nuclear@0: cleanup(); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: int init() nuclear@0: { nuclear@0: int x, y; nuclear@0: unsigned int flags, dcaps; nuclear@0: union ovrGLConfig glcfg; nuclear@0: ovrEyeRenderDesc eye_rdesc[2]; nuclear@0: nuclear@0: // this must be called before any OpenGL init according to the docs nuclear@0: ovr_Initialize(); nuclear@0: nuclear@0: SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); nuclear@0: nuclear@0: x = y = SDL_WINDOWPOS_UNDEFINED; nuclear@0: flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; nuclear@0: if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) { nuclear@0: fprintf(stderr, "failed to create window\n"); nuclear@0: return -1; nuclear@0: } nuclear@0: if(!(ctx = SDL_GL_CreateContext(win))) { nuclear@0: fprintf(stderr, "failed to create OpenGL context\n"); nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@0: glewInit(); nuclear@0: nuclear@0: if(!(hmd = ovrHmd_Create(0))) { nuclear@0: fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n"); nuclear@0: if(!(hmd = ovrHmd_CreateDebug())) { nuclear@0: fprintf(stderr, "failed to create virtual debug HMD\n"); nuclear@0: return -1; nuclear@0: } nuclear@0: } nuclear@0: printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName); nuclear@0: nuclear@0: SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h); nuclear@0: nuclear@0: ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); nuclear@0: eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0); nuclear@0: eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0); nuclear@0: nuclear@0: fb_width = eyeres[0].w + eyres[1].w; nuclear@0: fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h; nuclear@0: update_rtarg(fb_width, fb_height); nuclear@0: nuclear@0: memset(&glcfg, 0, sizeof glcfg); nuclear@0: glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; nuclear@0: glcfg.OGL.Header.RTSize = hmd->Resolution; nuclear@0: glcfg.OGL.Header.Multisample = 1; nuclear@0: nuclear@0: if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) { nuclear@0: printf("running in \"extended desktop\" mode\n"); nuclear@0: } else { nuclear@0: printf("running in \"direct-hmd\" mode\n"); nuclear@0: #ifdef WIN32 nuclear@0: ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0); nuclear@0: #endif nuclear@0: } nuclear@0: ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction); nuclear@0: nuclear@0: dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap; nuclear@0: if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) { nuclear@0: fprintf(stderr, "failed to configure distortion renderer\n"); nuclear@0: } nuclear@0: nuclear@0: ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); nuclear@0: nuclear@0: nuclear@0: glEnable(GL_DEPTH_TEST); nuclear@0: glEnable(GL_CULL_FACE); nuclear@0: glEnable(GL_LIGHTING); nuclear@0: glEnable(GL_LIGHT0); nuclear@0: nuclear@0: glClearColor(0.05, 0.05, 0.05, 1); nuclear@0: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void cleanup() nuclear@0: { nuclear@0: if(hmd) { nuclear@0: ovrHmd_Destroy(hmd); nuclear@0: } nuclear@0: ovr_Shutdown(); nuclear@0: nuclear@0: SDL_Quit(); nuclear@0: } nuclear@0: nuclear@0: void display() nuclear@0: { nuclear@0: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); nuclear@0: nuclear@0: SDL_GL_SwapWindow(win); nuclear@0: } nuclear@0: nuclear@0: void update_rtarg(int width, int height) nuclear@0: { nuclear@0: if(!fbo) { nuclear@0: glGenFramebuffers(1, &fbo); nuclear@0: glGenTextures(1, &fb_tex); nuclear@0: glGenRenderbuffers(1, &fb_depth); nuclear@0: nuclear@0: glBindTexture(GL_TEXTURE_2D, fb_tex); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nuclear@0: } nuclear@0: nuclear@0: glBindFramebuffer(GL_FRAMEBUFFER, fbo); nuclear@0: nuclear@0: fb_tex_width = next_pow2(width); nuclear@0: fb_tex_height = next_pow2(height); nuclear@0: nuclear@0: glBindTexture(GL_TEXTURE_2D, fb_tex); nuclear@0: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0, nuclear@0: GL_RGBA, GL_UNSIGNED_BYTE, 0); nuclear@0: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0); nuclear@0: nuclear@0: glBindRenderbuffer(GL_RENDERBUFFER, fb_depth); nuclear@0: glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_width, fb_tex_height); nuclear@0: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth); nuclear@0: nuclear@0: if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { nuclear@0: fprintf(stderr, "incomplete framebuffer!\n"); nuclear@0: } nuclear@0: nuclear@0: glBindFramebuffer(GL_FRAMEBUFFER, 0); nuclear@0: printf("created render target: %dx%d (texture size: %dx%d)\n", width, height, fb_tex_width, fb_tex_height); nuclear@0: } nuclear@0: nuclear@0: int handle_event(SDL_Event *ev) nuclear@0: { nuclear@0: switch(ev->type) { nuclear@0: case SDL_KEYDOWN: nuclear@0: case SDL_KEYUP: nuclear@0: if(key_event(ev->key.keysym.sym, ev->key.state == SDL_PRESSED) == -1) { nuclear@0: return -1; nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int key_event(int key, int state) nuclear@0: { nuclear@0: if(state) { nuclear@0: switch(key) { nuclear@0: case 27: nuclear@0: return -1; nuclear@0: nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: return 0; nuclear@0: }