oculus2

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