oculus2
changeset 0:0a4d62469381
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 26 Aug 2014 02:55:17 +0300 |
parents | |
children | dbbb4ec77df5 |
files | Makefile src/main.c |
diffstat | 2 files changed, 231 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Makefile Tue Aug 26 02:55:17 2014 +0300 1.3 @@ -0,0 +1,19 @@ 1.4 +src = $(wildcard src/*.c) 1.5 +obj = $(src:.c=.o) 1.6 +bin = oculus2 1.7 + 1.8 +CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl2` 1.9 +LDFLAGS = $(libgl) `pkg-config --libs sdl2` 1.10 + 1.11 +ifeq ($(shell uname -s), Darwin) 1.12 + libgl = -framework OpenGL -lGLEW 1.13 +else 1.14 + libgl = -lGL -lGLU -lGLEW 1.15 +endif 1.16 + 1.17 +$(bin): $(obj) 1.18 + $(CC) -o $@ $(obj) $(LDFLAGS) 1.19 + 1.20 +.PHONY: clean 1.21 +clean: 1.22 + rm -f $(obj) $(bin)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/main.c Tue Aug 26 02:55:17 2014 +0300 2.3 @@ -0,0 +1,212 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 +#include <SDL2/SDL.h> 2.7 +#include <GL/glew.h> 2.8 + 2.9 +#include <OVR_CAPI.h> 2.10 +#include <OVR_CAPI_GL.h> 2.11 + 2.12 +int init(); 2.13 +void cleanup(); 2.14 +void display(); 2.15 +void update_rtarg(int width, int height); 2.16 +int handle_event(SDL_Event *ev); 2.17 +int key_event(int key, int state); 2.18 +void reshape(int x, int y); 2.19 +unsigned int next_pow2(unsigned int x); 2.20 + 2.21 +OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enable); 2.22 + 2.23 +static SDL_Window *win; 2.24 +static SDL_GLContext ctx; 2.25 + 2.26 +static unsigned int fbo, fb_tex, fb_depth; 2.27 +static int fb_width, fb_height; 2.28 +static int fb_tex_width, fb_tex_height; 2.29 + 2.30 +static ovrHmd hmd; 2.31 +static ovrSizei eyeres[2]; 2.32 + 2.33 + 2.34 +int main(void) 2.35 +{ 2.36 + if(init() == -1) { 2.37 + return 1; 2.38 + } 2.39 + 2.40 + for(;;) { 2.41 + SDL_Event ev; 2.42 + 2.43 + while(SDL_PollEvent(&ev)) { 2.44 + if(handle_event(&ev) == -1) { 2.45 + goto done; 2.46 + } 2.47 + } 2.48 + 2.49 + display(); 2.50 + } 2.51 + 2.52 +done: 2.53 + cleanup(); 2.54 + return 0; 2.55 +} 2.56 + 2.57 + 2.58 +int init() 2.59 +{ 2.60 + int x, y; 2.61 + unsigned int flags, dcaps; 2.62 + union ovrGLConfig glcfg; 2.63 + ovrEyeRenderDesc eye_rdesc[2]; 2.64 + 2.65 + // this must be called before any OpenGL init according to the docs 2.66 + ovr_Initialize(); 2.67 + 2.68 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 2.69 + 2.70 + x = y = SDL_WINDOWPOS_UNDEFINED; 2.71 + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; 2.72 + if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) { 2.73 + fprintf(stderr, "failed to create window\n"); 2.74 + return -1; 2.75 + } 2.76 + if(!(ctx = SDL_GL_CreateContext(win))) { 2.77 + fprintf(stderr, "failed to create OpenGL context\n"); 2.78 + return -1; 2.79 + } 2.80 + 2.81 + glewInit(); 2.82 + 2.83 + if(!(hmd = ovrHmd_Create(0))) { 2.84 + fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n"); 2.85 + if(!(hmd = ovrHmd_CreateDebug())) { 2.86 + fprintf(stderr, "failed to create virtual debug HMD\n"); 2.87 + return -1; 2.88 + } 2.89 + } 2.90 + printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName); 2.91 + 2.92 + SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h); 2.93 + 2.94 + ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); 2.95 + eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0); 2.96 + eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0); 2.97 + 2.98 + fb_width = eyeres[0].w + eyres[1].w; 2.99 + fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h; 2.100 + update_rtarg(fb_width, fb_height); 2.101 + 2.102 + memset(&glcfg, 0, sizeof glcfg); 2.103 + glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; 2.104 + glcfg.OGL.Header.RTSize = hmd->Resolution; 2.105 + glcfg.OGL.Header.Multisample = 1; 2.106 + 2.107 + if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) { 2.108 + printf("running in \"extended desktop\" mode\n"); 2.109 + } else { 2.110 + printf("running in \"direct-hmd\" mode\n"); 2.111 +#ifdef WIN32 2.112 + ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0); 2.113 +#endif 2.114 + } 2.115 + ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction); 2.116 + 2.117 + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap; 2.118 + if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) { 2.119 + fprintf(stderr, "failed to configure distortion renderer\n"); 2.120 + } 2.121 + 2.122 + ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); 2.123 + 2.124 + 2.125 + glEnable(GL_DEPTH_TEST); 2.126 + glEnable(GL_CULL_FACE); 2.127 + glEnable(GL_LIGHTING); 2.128 + glEnable(GL_LIGHT0); 2.129 + 2.130 + glClearColor(0.05, 0.05, 0.05, 1); 2.131 + 2.132 + return 0; 2.133 +} 2.134 + 2.135 +void cleanup() 2.136 +{ 2.137 + if(hmd) { 2.138 + ovrHmd_Destroy(hmd); 2.139 + } 2.140 + ovr_Shutdown(); 2.141 + 2.142 + SDL_Quit(); 2.143 +} 2.144 + 2.145 +void display() 2.146 +{ 2.147 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2.148 + 2.149 + SDL_GL_SwapWindow(win); 2.150 +} 2.151 + 2.152 +void update_rtarg(int width, int height) 2.153 +{ 2.154 + if(!fbo) { 2.155 + glGenFramebuffers(1, &fbo); 2.156 + glGenTextures(1, &fb_tex); 2.157 + glGenRenderbuffers(1, &fb_depth); 2.158 + 2.159 + glBindTexture(GL_TEXTURE_2D, fb_tex); 2.160 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 2.161 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 2.162 + } 2.163 + 2.164 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 2.165 + 2.166 + fb_tex_width = next_pow2(width); 2.167 + fb_tex_height = next_pow2(height); 2.168 + 2.169 + glBindTexture(GL_TEXTURE_2D, fb_tex); 2.170 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_tex_width, fb_tex_height, 0, 2.171 + GL_RGBA, GL_UNSIGNED_BYTE, 0); 2.172 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_tex, 0); 2.173 + 2.174 + glBindRenderbuffer(GL_RENDERBUFFER, fb_depth); 2.175 + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, fb_tex_width, fb_tex_height); 2.176 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fb_depth); 2.177 + 2.178 + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 2.179 + fprintf(stderr, "incomplete framebuffer!\n"); 2.180 + } 2.181 + 2.182 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 2.183 + printf("created render target: %dx%d (texture size: %dx%d)\n", width, height, fb_tex_width, fb_tex_height); 2.184 +} 2.185 + 2.186 +int handle_event(SDL_Event *ev) 2.187 +{ 2.188 + switch(ev->type) { 2.189 + case SDL_KEYDOWN: 2.190 + case SDL_KEYUP: 2.191 + if(key_event(ev->key.keysym.sym, ev->key.state == SDL_PRESSED) == -1) { 2.192 + return -1; 2.193 + } 2.194 + break; 2.195 + 2.196 + default: 2.197 + break; 2.198 + } 2.199 + 2.200 + return 0; 2.201 +} 2.202 + 2.203 +int key_event(int key, int state) 2.204 +{ 2.205 + if(state) { 2.206 + switch(key) { 2.207 + case 27: 2.208 + return -1; 2.209 + 2.210 + default: 2.211 + break; 2.212 + } 2.213 + } 2.214 + return 0; 2.215 +}