oculus2

diff src/main.c @ 2:0984fa94b490

rendering almost works
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 26 Aug 2014 08:14:09 +0300
parents 0a4d62469381
children 096b18432ba7
line diff
     1.1 --- a/src/main.c	Tue Aug 26 02:56:45 2014 +0300
     1.2 +++ b/src/main.c	Tue Aug 26 08:14:09 2014 +0300
     1.3 @@ -1,14 +1,24 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6 +#include <assert.h>
     1.7  #include <SDL2/SDL.h>
     1.8  #include <GL/glew.h>
     1.9  
    1.10 +#ifdef WIN32
    1.11 +#define OVR_OS_WIN32
    1.12 +#endif
    1.13 +#ifdef __APPLE__
    1.14 +#define OVR_OS_MAC
    1.15 +#endif
    1.16 +
    1.17  #include <OVR_CAPI.h>
    1.18  #include <OVR_CAPI_GL.h>
    1.19  
    1.20 -int init();
    1.21 -void cleanup();
    1.22 -void display();
    1.23 +int init(void);
    1.24 +void cleanup(void);
    1.25 +void display(void);
    1.26 +void draw_scene(void);
    1.27 +void draw_box(float xsz, float ysz, float zsz, float norm_sign);
    1.28  void update_rtarg(int width, int height);
    1.29  int handle_event(SDL_Event *ev);
    1.30  int key_event(int key, int state);
    1.31 @@ -19,6 +29,7 @@
    1.32  
    1.33  static SDL_Window *win;
    1.34  static SDL_GLContext ctx;
    1.35 +static int win_width, win_height;
    1.36  
    1.37  static unsigned int fbo, fb_tex, fb_depth;
    1.38  static int fb_width, fb_height;
    1.39 @@ -26,6 +37,8 @@
    1.40  
    1.41  static ovrHmd hmd;
    1.42  static ovrSizei eyeres[2];
    1.43 +static ovrEyeRenderDesc eye_rdesc[2];
    1.44 +static ovrGLTexture fb_ovr_tex[2];
    1.45  
    1.46  
    1.47  int main(void)
    1.48 @@ -52,12 +65,11 @@
    1.49  }
    1.50  
    1.51  
    1.52 -int init()
    1.53 +int init(void)
    1.54  {
    1.55 -	int x, y;
    1.56 +	int i, x, y;
    1.57  	unsigned int flags, dcaps;
    1.58  	union ovrGLConfig glcfg;
    1.59 -	ovrEyeRenderDesc eye_rdesc[2];
    1.60  
    1.61  	// this must be called before any OpenGL init according to the docs
    1.62  	ovr_Initialize();
    1.63 @@ -65,7 +77,7 @@
    1.64  	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
    1.65  
    1.66  	x = y = SDL_WINDOWPOS_UNDEFINED;
    1.67 -	flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
    1.68 +	flags = SDL_WINDOW_OPENGL;
    1.69  	if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) {
    1.70  		fprintf(stderr, "failed to create window\n");
    1.71  		return -1;
    1.72 @@ -79,23 +91,37 @@
    1.73  
    1.74  	if(!(hmd = ovrHmd_Create(0))) {
    1.75  		fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n");
    1.76 -		if(!(hmd = ovrHmd_CreateDebug())) {
    1.77 +		if(!(hmd = ovrHmd_CreateDebug(ovrHmd_DK2))) {
    1.78  			fprintf(stderr, "failed to create virtual debug HMD\n");
    1.79  			return -1;
    1.80  		}
    1.81  	}
    1.82  	printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName);
    1.83  
    1.84 -	SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h);
    1.85 +	SDL_SetWindowSize(win, hmd->Resolution.w, hmd->Resolution.h);
    1.86  
    1.87  	ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0);
    1.88  	eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0);
    1.89  	eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0);
    1.90  
    1.91 -	fb_width = eyeres[0].w + eyres[1].w;
    1.92 +	SDL_GetWindowSize(win, &win_width, &win_height);
    1.93 +
    1.94 +	fb_width = eyeres[0].w + eyeres[1].w;
    1.95  	fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h;
    1.96  	update_rtarg(fb_width, fb_height);
    1.97  
    1.98 +	for(i=0; i<2; i++) {
    1.99 +		fb_ovr_tex[i].OGL.Header.API = ovrRenderAPI_OpenGL;
   1.100 +		fb_ovr_tex[i].OGL.Header.TextureSize.w = fb_tex_width;
   1.101 +		fb_ovr_tex[i].OGL.Header.TextureSize.h = fb_tex_height;
   1.102 +		fb_ovr_tex[i].OGL.Header.RenderViewport.Pos.y = 0;
   1.103 +		fb_ovr_tex[i].OGL.Header.RenderViewport.Size.w = fb_width / 2.0;
   1.104 +		fb_ovr_tex[i].OGL.Header.RenderViewport.Size.h = fb_height;
   1.105 +		fb_ovr_tex[i].OGL.TexId = fb_tex;
   1.106 +	}
   1.107 +	fb_ovr_tex[0].OGL.Header.RenderViewport.Pos.x = 0;
   1.108 +	fb_ovr_tex[1].OGL.Header.RenderViewport.Pos.x = fb_width / 2.0;
   1.109 +
   1.110  	memset(&glcfg, 0, sizeof glcfg);
   1.111  	glcfg.OGL.Header.API = ovrRenderAPI_OpenGL;
   1.112  	glcfg.OGL.Header.RTSize = hmd->Resolution;
   1.113 @@ -104,19 +130,22 @@
   1.114  	if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) {
   1.115  		printf("running in \"extended desktop\" mode\n");
   1.116  	} else {
   1.117 +#ifdef WIN32
   1.118 +		void *sys_win = GetActiveWindow();
   1.119 +		glcfg.OGL.Window = sys_win;
   1.120 +		glcfg.OGL.DC = wglGetCurrentDC();
   1.121 +		ovrHmd_AttachToWindow(hmd, sys_win, 0, 0);
   1.122 +#endif
   1.123  		printf("running in \"direct-hmd\" mode\n");
   1.124 -#ifdef WIN32
   1.125 -		ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0);
   1.126 -#endif
   1.127  	}
   1.128 -	ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction);
   1.129 +	ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
   1.130  
   1.131 -	dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap;
   1.132 +	dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp;
   1.133  	if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) {
   1.134  		fprintf(stderr, "failed to configure distortion renderer\n");
   1.135  	}
   1.136  
   1.137 -	ovrhmd_EnableHSWDisplaySDKRender(hmd, 0);
   1.138 +	/* ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); */
   1.139  
   1.140  
   1.141  	glEnable(GL_DEPTH_TEST);
   1.142 @@ -124,12 +153,12 @@
   1.143  	glEnable(GL_LIGHTING);
   1.144  	glEnable(GL_LIGHT0);
   1.145  
   1.146 -	glClearColor(0.05, 0.05, 0.05, 1);
   1.147 +	glClearColor(0.5, 0.05, 0.05, 1);
   1.148  
   1.149  	return 0;
   1.150  }
   1.151  
   1.152 -void cleanup()
   1.153 +void cleanup(void)
   1.154  {
   1.155  	if(hmd) {
   1.156  		ovrHmd_Destroy(hmd);
   1.157 @@ -139,11 +168,108 @@
   1.158  	SDL_Quit();
   1.159  }
   1.160  
   1.161 -void display()
   1.162 +void display(void)
   1.163  {
   1.164 +	int i;
   1.165 +	ovrMatrix4f proj;
   1.166 +	ovrPosef pose[2];
   1.167 +
   1.168 +	ovrHmd_BeginFrame(hmd, 0);
   1.169 +
   1.170 +	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
   1.171  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   1.172  
   1.173 -	SDL_GL_SwapWindow(win);
   1.174 +	/* for each eye ... */
   1.175 +	for(i=0; i<2; i++) {
   1.176 +		int eye = hmd->EyeRenderOrder[i];
   1.177 +
   1.178 +		/* vport0(0, 0, width/2, height), vport1(width/2, 0, width/2, height) */
   1.179 +		glViewport(eye == 0 ? 0 : fb_width / 2, 0, fb_width / 2, fb_height);
   1.180 +
   1.181 +		proj = ovrMatrix4f_Projection(hmd->DefaultEyeFov[eye], 0.5, 500.0, 1);
   1.182 +		glMatrixMode(GL_PROJECTION);
   1.183 +		glLoadMatrixf(proj.M[0]);
   1.184 +
   1.185 +		pose[eye] = ovrHmd_GetEyePose(hmd, eye);
   1.186 +		glMatrixMode(GL_MODELVIEW);
   1.187 +		/* TODO: get HMD orientation data and use them */
   1.188 +		glTranslatef(0, -ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, 1.65), 0);
   1.189 +
   1.190 +		draw_scene();
   1.191 +	}
   1.192 +
   1.193 +	glBindFramebuffer(GL_FRAMEBUFFER, 0);
   1.194 +	glViewport(0, 0, win_width, win_height);
   1.195 +
   1.196 +	ovrHmd_EndFrame(hmd, pose, &fb_ovr_tex[0].Texture);
   1.197 +
   1.198 +	assert(glGetError() == GL_NO_ERROR);
   1.199 +}
   1.200 +
   1.201 +void draw_scene(void)
   1.202 +{
   1.203 +	int i;
   1.204 +	float lpos[] = {0, 5, 0, 1};
   1.205 +	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
   1.206 +
   1.207 +	glTranslatef(0, 5, 0);
   1.208 +	draw_box(20, 10, 20, -1.0);
   1.209 +
   1.210 +	for(i=0; i<4; i++) {
   1.211 +		glPushMatrix();
   1.212 +		if(i & 1) {
   1.213 +			glTranslatef(0, 0, i & 2 ? 7.5 : -7.5);
   1.214 +		} else {
   1.215 +			glTranslatef(i & 2 ? 7.5 : -7.5, 0, 0);
   1.216 +		}
   1.217 +		draw_box(3, 0, 3, 1.0);
   1.218 +		glPopMatrix();
   1.219 +	}
   1.220 +}
   1.221 +
   1.222 +void draw_box(float xsz, float ysz, float zsz, float norm_sign)
   1.223 +{
   1.224 +	glMatrixMode(GL_MODELVIEW);
   1.225 +	glScalef(xsz * 0.5, ysz * 0.5, zsz * 0.5);
   1.226 +
   1.227 +	if(norm_sign < 0.0) {
   1.228 +		glFrontFace(GL_CW);
   1.229 +	}
   1.230 +
   1.231 +	glBegin(GL_QUADS);
   1.232 +	glNormal3f(0, 0, 1 * norm_sign);
   1.233 +	glTexCoord2f(0, 0); glVertex3f(-1, -1, 1);
   1.234 +	glTexCoord2f(1, 0); glVertex3f(1, -1, 1);
   1.235 +	glTexCoord2f(1, 1); glVertex3f(1, 1, 1);
   1.236 +	glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
   1.237 +	glNormal3f(1 * norm_sign, 0, 0);
   1.238 +	glTexCoord2f(0, 0); glVertex3f(1, -1, 1);
   1.239 +	glTexCoord2f(1, 0); glVertex3f(1, -1, -1);
   1.240 +	glTexCoord2f(1, 1); glVertex3f(1, 1, -1);
   1.241 +	glTexCoord2f(0, 1); glVertex3f(1, 1, 1);
   1.242 +	glNormal3f(0, 0, -1 * norm_sign);
   1.243 +	glTexCoord2f(0, 0); glVertex3f(1, -1, -1);
   1.244 +	glTexCoord2f(1, 0); glVertex3f(-1, -1, -1);
   1.245 +	glTexCoord2f(1, 1); glVertex3f(-1, 1, -1);
   1.246 +	glTexCoord2f(0, 1); glVertex3f(1, 1, -1);
   1.247 +	glNormal3f(-1 * norm_sign, 0, 0);
   1.248 +	glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
   1.249 +	glTexCoord2f(1, 0); glVertex3f(-1, -1, 1);
   1.250 +	glTexCoord2f(1, 1); glVertex3f(-1, 1, 1);
   1.251 +	glTexCoord2f(0, 1); glVertex3f(-1, 1, -1);
   1.252 +	glNormal3f(0, 1 * norm_sign, 0);
   1.253 +	glTexCoord2f(0, 0); glVertex3f(-1, 1, 1);
   1.254 +	glTexCoord2f(1, 0); glVertex3f(1, 1, 1);
   1.255 +	glTexCoord2f(1, 1); glVertex3f(1, 1, -1);
   1.256 +	glTexCoord2f(0, 1); glVertex3f(-1, 1, -1);
   1.257 +	glNormal3f(0, -1 * norm_sign, 0);
   1.258 +	glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
   1.259 +	glTexCoord2f(1, 0); glVertex3f(1, -1, -1);
   1.260 +	glTexCoord2f(1, 1); glVertex3f(1, -1, 1);
   1.261 +	glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
   1.262 +	glEnd();
   1.263 +
   1.264 +	glFrontFace(GL_CCW);
   1.265  }
   1.266  
   1.267  void update_rtarg(int width, int height)
   1.268 @@ -210,3 +336,14 @@
   1.269  	}
   1.270  	return 0;
   1.271  }
   1.272 +
   1.273 +unsigned int next_pow2(unsigned int x)
   1.274 +{
   1.275 +	x -= 1;
   1.276 +	x |= x >> 1;
   1.277 +	x |= x >> 2;
   1.278 +	x |= x >> 4;
   1.279 +	x |= x >> 8;
   1.280 +	x |= x >> 16;
   1.281 +	return x + 1;
   1.282 +}
   1.283 \ No newline at end of file