# HG changeset patch # User John Tsiombikas # Date 1409030049 -10800 # Node ID 0984fa94b490dac1af7b99807ecf6c2e187c401f # Parent dbbb4ec77df5dfcb37763ca6200b06b1e60ed2d8 rendering almost works diff -r dbbb4ec77df5 -r 0984fa94b490 oculus2.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oculus2.sln Tue Aug 26 08:14:09 2014 +0300 @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oculus2", "oculus2.vcxproj", "{7A2D6788-B885-455C-8DE6-46D5C7313207}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7A2D6788-B885-455C-8DE6-46D5C7313207}.Debug|Win32.ActiveCfg = Debug|Win32 + {7A2D6788-B885-455C-8DE6-46D5C7313207}.Debug|Win32.Build.0 = Debug|Win32 + {7A2D6788-B885-455C-8DE6-46D5C7313207}.Release|Win32.ActiveCfg = Release|Win32 + {7A2D6788-B885-455C-8DE6-46D5C7313207}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r dbbb4ec77df5 -r 0984fa94b490 oculus2.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oculus2.vcxproj Tue Aug 26 08:14:09 2014 +0300 @@ -0,0 +1,88 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7A2D6788-B885-455C-8DE6-46D5C7313207} + Win32Proj + oculus2 + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + 4305;4244 + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sdl2.lib;sdl2main.lib;opengl32.lib;glew32.lib;libovrd.lib;winmm.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + 4305;4244 + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sdl2.lib;sdl2main.lib;opengl32.lib;glew32.lib;libovr.lib;winmm.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff -r dbbb4ec77df5 -r 0984fa94b490 oculus2.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oculus2.vcxproj.filters Tue Aug 26 08:14:09 2014 +0300 @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h;inl + + + + + src + + + \ No newline at end of file diff -r dbbb4ec77df5 -r 0984fa94b490 src/main.c --- a/src/main.c Tue Aug 26 02:56:45 2014 +0300 +++ b/src/main.c Tue Aug 26 08:14:09 2014 +0300 @@ -1,14 +1,24 @@ #include #include +#include #include #include +#ifdef WIN32 +#define OVR_OS_WIN32 +#endif +#ifdef __APPLE__ +#define OVR_OS_MAC +#endif + #include #include -int init(); -void cleanup(); -void display(); +int init(void); +void cleanup(void); +void display(void); +void draw_scene(void); +void draw_box(float xsz, float ysz, float zsz, float norm_sign); void update_rtarg(int width, int height); int handle_event(SDL_Event *ev); int key_event(int key, int state); @@ -19,6 +29,7 @@ static SDL_Window *win; static SDL_GLContext ctx; +static int win_width, win_height; static unsigned int fbo, fb_tex, fb_depth; static int fb_width, fb_height; @@ -26,6 +37,8 @@ static ovrHmd hmd; static ovrSizei eyeres[2]; +static ovrEyeRenderDesc eye_rdesc[2]; +static ovrGLTexture fb_ovr_tex[2]; int main(void) @@ -52,12 +65,11 @@ } -int init() +int init(void) { - int x, y; + int i, x, y; unsigned int flags, dcaps; union ovrGLConfig glcfg; - ovrEyeRenderDesc eye_rdesc[2]; // this must be called before any OpenGL init according to the docs ovr_Initialize(); @@ -65,7 +77,7 @@ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); x = y = SDL_WINDOWPOS_UNDEFINED; - flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + flags = SDL_WINDOW_OPENGL; if(!(win = SDL_CreateWindow("simple oculus example", x, y, 1280, 800, flags))) { fprintf(stderr, "failed to create window\n"); return -1; @@ -79,23 +91,37 @@ if(!(hmd = ovrHmd_Create(0))) { fprintf(stderr, "failed to open Oculus HMD, falling back to virtual debug HMD\n"); - if(!(hmd = ovrHmd_CreateDebug())) { + if(!(hmd = ovrHmd_CreateDebug(ovrHmd_DK2))) { fprintf(stderr, "failed to create virtual debug HMD\n"); return -1; } } printf("initialized HMD: %s - %s\n", hmd->Manufacturer, hmd->ProductName); - SDL_SetWindowSize(hmd->Resolution.w, hmd->Resolution.h); + SDL_SetWindowSize(win, hmd->Resolution.w, hmd->Resolution.h); ovrHmd_ConfigureTracking(hmd, 0xffffffff, 0); eyeres[0] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0); eyeres[1] = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0); - fb_width = eyeres[0].w + eyres[1].w; + SDL_GetWindowSize(win, &win_width, &win_height); + + fb_width = eyeres[0].w + eyeres[1].w; fb_height = eyeres[0].h > eyeres[1].h ? eyeres[0].h : eyeres[1].h; update_rtarg(fb_width, fb_height); + for(i=0; i<2; i++) { + fb_ovr_tex[i].OGL.Header.API = ovrRenderAPI_OpenGL; + fb_ovr_tex[i].OGL.Header.TextureSize.w = fb_tex_width; + fb_ovr_tex[i].OGL.Header.TextureSize.h = fb_tex_height; + fb_ovr_tex[i].OGL.Header.RenderViewport.Pos.y = 0; + fb_ovr_tex[i].OGL.Header.RenderViewport.Size.w = fb_width / 2.0; + fb_ovr_tex[i].OGL.Header.RenderViewport.Size.h = fb_height; + fb_ovr_tex[i].OGL.TexId = fb_tex; + } + fb_ovr_tex[0].OGL.Header.RenderViewport.Pos.x = 0; + fb_ovr_tex[1].OGL.Header.RenderViewport.Pos.x = fb_width / 2.0; + memset(&glcfg, 0, sizeof glcfg); glcfg.OGL.Header.API = ovrRenderAPI_OpenGL; glcfg.OGL.Header.RTSize = hmd->Resolution; @@ -104,19 +130,22 @@ if(hmd->HmdCaps & ovrHmdCap_ExtendDesktop) { printf("running in \"extended desktop\" mode\n"); } else { +#ifdef WIN32 + void *sys_win = GetActiveWindow(); + glcfg.OGL.Window = sys_win; + glcfg.OGL.DC = wglGetCurrentDC(); + ovrHmd_AttachToWindow(hmd, sys_win, 0, 0); +#endif printf("running in \"direct-hmd\" mode\n"); -#ifdef WIN32 - ovrHmd_AttachToWindow(hmd, GetActiveWindow(), 0, 0); -#endif } - ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCaps_DynamicPrediction); + ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction); - dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWrap; + dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp; if(!ovrHmd_ConfigureRendering(hmd, &glcfg.Config, dcaps, hmd->DefaultEyeFov, eye_rdesc)) { fprintf(stderr, "failed to configure distortion renderer\n"); } - ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); + /* ovrhmd_EnableHSWDisplaySDKRender(hmd, 0); */ glEnable(GL_DEPTH_TEST); @@ -124,12 +153,12 @@ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); - glClearColor(0.05, 0.05, 0.05, 1); + glClearColor(0.5, 0.05, 0.05, 1); return 0; } -void cleanup() +void cleanup(void) { if(hmd) { ovrHmd_Destroy(hmd); @@ -139,11 +168,108 @@ SDL_Quit(); } -void display() +void display(void) { + int i; + ovrMatrix4f proj; + ovrPosef pose[2]; + + ovrHmd_BeginFrame(hmd, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapWindow(win); + /* for each eye ... */ + for(i=0; i<2; i++) { + int eye = hmd->EyeRenderOrder[i]; + + /* vport0(0, 0, width/2, height), vport1(width/2, 0, width/2, height) */ + glViewport(eye == 0 ? 0 : fb_width / 2, 0, fb_width / 2, fb_height); + + proj = ovrMatrix4f_Projection(hmd->DefaultEyeFov[eye], 0.5, 500.0, 1); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj.M[0]); + + pose[eye] = ovrHmd_GetEyePose(hmd, eye); + glMatrixMode(GL_MODELVIEW); + /* TODO: get HMD orientation data and use them */ + glTranslatef(0, -ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, 1.65), 0); + + draw_scene(); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, win_width, win_height); + + ovrHmd_EndFrame(hmd, pose, &fb_ovr_tex[0].Texture); + + assert(glGetError() == GL_NO_ERROR); +} + +void draw_scene(void) +{ + int i; + float lpos[] = {0, 5, 0, 1}; + glLightfv(GL_LIGHT0, GL_POSITION, lpos); + + glTranslatef(0, 5, 0); + draw_box(20, 10, 20, -1.0); + + for(i=0; i<4; i++) { + glPushMatrix(); + if(i & 1) { + glTranslatef(0, 0, i & 2 ? 7.5 : -7.5); + } else { + glTranslatef(i & 2 ? 7.5 : -7.5, 0, 0); + } + draw_box(3, 0, 3, 1.0); + glPopMatrix(); + } +} + +void draw_box(float xsz, float ysz, float zsz, float norm_sign) +{ + glMatrixMode(GL_MODELVIEW); + glScalef(xsz * 0.5, ysz * 0.5, zsz * 0.5); + + if(norm_sign < 0.0) { + glFrontFace(GL_CW); + } + + glBegin(GL_QUADS); + glNormal3f(0, 0, 1 * norm_sign); + glTexCoord2f(0, 0); glVertex3f(-1, -1, 1); + glTexCoord2f(1, 0); glVertex3f(1, -1, 1); + glTexCoord2f(1, 1); glVertex3f(1, 1, 1); + glTexCoord2f(0, 1); glVertex3f(-1, 1, 1); + glNormal3f(1 * norm_sign, 0, 0); + glTexCoord2f(0, 0); glVertex3f(1, -1, 1); + glTexCoord2f(1, 0); glVertex3f(1, -1, -1); + glTexCoord2f(1, 1); glVertex3f(1, 1, -1); + glTexCoord2f(0, 1); glVertex3f(1, 1, 1); + glNormal3f(0, 0, -1 * norm_sign); + glTexCoord2f(0, 0); glVertex3f(1, -1, -1); + glTexCoord2f(1, 0); glVertex3f(-1, -1, -1); + glTexCoord2f(1, 1); glVertex3f(-1, 1, -1); + glTexCoord2f(0, 1); glVertex3f(1, 1, -1); + glNormal3f(-1 * norm_sign, 0, 0); + glTexCoord2f(0, 0); glVertex3f(-1, -1, -1); + glTexCoord2f(1, 0); glVertex3f(-1, -1, 1); + glTexCoord2f(1, 1); glVertex3f(-1, 1, 1); + glTexCoord2f(0, 1); glVertex3f(-1, 1, -1); + glNormal3f(0, 1 * norm_sign, 0); + glTexCoord2f(0, 0); glVertex3f(-1, 1, 1); + glTexCoord2f(1, 0); glVertex3f(1, 1, 1); + glTexCoord2f(1, 1); glVertex3f(1, 1, -1); + glTexCoord2f(0, 1); glVertex3f(-1, 1, -1); + glNormal3f(0, -1 * norm_sign, 0); + glTexCoord2f(0, 0); glVertex3f(-1, -1, -1); + glTexCoord2f(1, 0); glVertex3f(1, -1, -1); + glTexCoord2f(1, 1); glVertex3f(1, -1, 1); + glTexCoord2f(0, 1); glVertex3f(-1, -1, 1); + glEnd(); + + glFrontFace(GL_CCW); } void update_rtarg(int width, int height) @@ -210,3 +336,14 @@ } return 0; } + +unsigned int next_pow2(unsigned int x) +{ + x -= 1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return x + 1; +} \ No newline at end of file