oculus2

annotate 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
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <SDL2/SDL.h>
nuclear@0 4 #include <GL/glew.h>
nuclear@0 5
nuclear@0 6 #include <OVR_CAPI.h>
nuclear@0 7 #include <OVR_CAPI_GL.h>
nuclear@0 8
nuclear@0 9 int init();
nuclear@0 10 void cleanup();
nuclear@0 11 void display();
nuclear@0 12 void update_rtarg(int width, int height);
nuclear@0 13 int handle_event(SDL_Event *ev);
nuclear@0 14 int key_event(int key, int state);
nuclear@0 15 void reshape(int x, int y);
nuclear@0 16 unsigned int next_pow2(unsigned int x);
nuclear@0 17
nuclear@0 18 OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enable);
nuclear@0 19
nuclear@0 20 static SDL_Window *win;
nuclear@0 21 static SDL_GLContext ctx;
nuclear@0 22
nuclear@0 23 static unsigned int fbo, fb_tex, fb_depth;
nuclear@0 24 static int fb_width, fb_height;
nuclear@0 25 static int fb_tex_width, fb_tex_height;
nuclear@0 26
nuclear@0 27 static ovrHmd hmd;
nuclear@0 28 static ovrSizei eyeres[2];
nuclear@0 29
nuclear@0 30
nuclear@0 31 int main(void)
nuclear@0 32 {
nuclear@0 33 if(init() == -1) {
nuclear@0 34 return 1;
nuclear@0 35 }
nuclear@0 36
nuclear@0 37 for(;;) {
nuclear@0 38 SDL_Event ev;
nuclear@0 39
nuclear@0 40 while(SDL_PollEvent(&ev)) {
nuclear@0 41 if(handle_event(&ev) == -1) {
nuclear@0 42 goto done;
nuclear@0 43 }
nuclear@0 44 }
nuclear@0 45
nuclear@0 46 display();
nuclear@0 47 }
nuclear@0 48
nuclear@0 49 done:
nuclear@0 50 cleanup();
nuclear@0 51 return 0;
nuclear@0 52 }
nuclear@0 53
nuclear@0 54
nuclear@0 55 int init()
nuclear@0 56 {
nuclear@0 57 int x, y;
nuclear@0 58 unsigned int flags, dcaps;
nuclear@0 59 union ovrGLConfig glcfg;
nuclear@0 60 ovrEyeRenderDesc eye_rdesc[2];
nuclear@0 61
nuclear@0 62 // this must be called before any OpenGL init according to the docs
nuclear@0 63 ovr_Initialize();
nuclear@0 64
nuclear@0 65 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
nuclear@0 66
nuclear@0 67 x = y = SDL_WINDOWPOS_UNDEFINED;
nuclear@0 68 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
nuclear@0 69 if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) {
nuclear@0 70 fprintf(stderr, "failed to create window\n");
nuclear@0 71 return -1;
nuclear@0 72 }
nuclear@0 73 if(!(ctx = SDL_GL_CreateContext(win))) {
nuclear@0 74 fprintf(stderr, "failed to create OpenGL context\n");
nuclear@0 75 return -1;
nuclear@0 76 }
nuclear@0 77
nuclear@0 78 glewInit();
nuclear@0 79
nuclear@0 80 if(!(hmd = ovrHmd_Create(0))) {
nuclear@0 81 fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n");
nuclear@0 82 if(!(hmd = ovrHmd_CreateDebug())) {
nuclear@0 83 fprintf(stderr, "failed to create virtual debug HMD\n");
nuclear@0 84 return -1;
nuclear@0 85 }
nuclear@0 86 }
nuclear@0 87 printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName);
nuclear@0 88
nuclear@0 89 SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h);
nuclear@0 90
nuclear@0 91 ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0);
nuclear@0 92 eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0);
nuclear@0 93 eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0);
nuclear@0 94
nuclear@0 95 fb_width = eyeres[0].w + eyres[1].w;
nuclear@0 96 fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h;
nuclear@0 97 update_rtarg(fb_width, fb_height);
nuclear@0 98
nuclear@0 99 memset(&glcfg, 0, sizeof glcfg);
nuclear@0 100 glcfg.OGL.Header.API = ovrRenderAPI_OpenGL;
nuclear@0 101 glcfg.OGL.Header.RTSize = hmd->Resolution;
nuclear@0 102 glcfg.OGL.Header.Multisample = 1;
nuclear@0 103
nuclear@0 104 if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) {
nuclear@0 105 printf("running in \"extended desktop\" mode\n");
nuclear@0 106 } else {
nuclear@0 107 printf("running in \"direct-hmd\" mode\n");
nuclear@0 108 #ifdef WIN32
nuclear@0 109 ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0);
nuclear@0 110 #endif
nuclear@0 111 }
nuclear@0 112 ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction);
nuclear@0 113
nuclear@0 114 dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap;
nuclear@0 115 if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) {
nuclear@0 116 fprintf(stderr, "failed to configure distortion renderer\n");
nuclear@0 117 }
nuclear@0 118
nuclear@0 119 ovrhmd_EnableHSWDisplaySDKRender(hmd, 0);
nuclear@0 120
nuclear@0 121
nuclear@0 122 glEnable(GL_DEPTH_TEST);
nuclear@0 123 glEnable(GL_CULL_FACE);
nuclear@0 124 glEnable(GL_LIGHTING);
nuclear@0 125 glEnable(GL_LIGHT0);
nuclear@0 126
nuclear@0 127 glClearColor(0.05, 0.05, 0.05, 1);
nuclear@0 128
nuclear@0 129 return 0;
nuclear@0 130 }
nuclear@0 131
nuclear@0 132 void cleanup()
nuclear@0 133 {
nuclear@0 134 if(hmd) {
nuclear@0 135 ovrHmd_Destroy(hmd);
nuclear@0 136 }
nuclear@0 137 ovr_Shutdown();
nuclear@0 138
nuclear@0 139 SDL_Quit();
nuclear@0 140 }
nuclear@0 141
nuclear@0 142 void display()
nuclear@0 143 {
nuclear@0 144 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@0 145
nuclear@0 146 SDL_GL_SwapWindow(win);
nuclear@0 147 }
nuclear@0 148
nuclear@0 149 void update_rtarg(int width, int height)
nuclear@0 150 {
nuclear@0 151 if(!fbo) {
nuclear@0 152 glGenFramebuffers(1, &fbo);
nuclear@0 153 glGenTextures(1, &fb_tex);
nuclear@0 154 glGenRenderbuffers(1, &fb_depth);
nuclear@0 155
nuclear@0 156 glBindTexture(GL_TEXTURE_2D, fb_tex);
nuclear@0 157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@0 158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@0 159 }
nuclear@0 160
nuclear@0 161 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
nuclear@0 162
nuclear@0 163 fb_tex_width = next_pow2(width);
nuclear@0 164 fb_tex_height = next_pow2(height);
nuclear@0 165
nuclear@0 166 glBindTexture(GL_TEXTURE_2D, fb_tex);
nuclear@0 167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0,
nuclear@0 168 GL_RGBA, GL_UNSIGNED_BYTE, 0);
nuclear@0 169 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0);
nuclear@0 170
nuclear@0 171 glBindRenderbuffer(GL_RENDERBUFFER, fb_depth);
nuclear@0 172 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_width, fb_tex_height);
nuclear@0 173 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth);
nuclear@0 174
nuclear@0 175 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
nuclear@0 176 fprintf(stderr, "incomplete framebuffer!\n");
nuclear@0 177 }
nuclear@0 178
nuclear@0 179 glBindFramebuffer(GL_FRAMEBUFFER, 0);
nuclear@0 180 printf("created render target: %dx%d (texture size: %dx%d)\n", width, height, fb_tex_width, fb_tex_height);
nuclear@0 181 }
nuclear@0 182
nuclear@0 183 int handle_event(SDL_Event *ev)
nuclear@0 184 {
nuclear@0 185 switch(ev->type) {
nuclear@0 186 case SDL_KEYDOWN:
nuclear@0 187 case SDL_KEYUP:
nuclear@0 188 if(key_event(ev->key.keysym.sym, ev->key.state == SDL_PRESSED) == -1) {
nuclear@0 189 return -1;
nuclear@0 190 }
nuclear@0 191 break;
nuclear@0 192
nuclear@0 193 default:
nuclear@0 194 break;
nuclear@0 195 }
nuclear@0 196
nuclear@0 197 return 0;
nuclear@0 198 }
nuclear@0 199
nuclear@0 200 int key_event(int key, int state)
nuclear@0 201 {
nuclear@0 202 if(state) {
nuclear@0 203 switch(key) {
nuclear@0 204 case 27:
nuclear@0 205 return -1;
nuclear@0 206
nuclear@0 207 default:
nuclear@0 208 break;
nuclear@0 209 }
nuclear@0 210 }
nuclear@0 211 return 0;
nuclear@0 212 }