Skip to main content
Up and Coming
November 6, 2014

Simple, one page, OpenGL example (0.4.3 beta)

Hi,

The older simple OpenGL example converted to 0.4.3 beta. Just uses GLEW, GLFW and the OculusSDK.
Slight "ghosting" in the image when you move your head fast and Time Warp is enabled.

Thanks,
Daniel Dekkers

EDIT: Fixed bug where EyeIndex was used instead of Eye in the setup of the textures.
EDIT: Back to a single FBO for both eyes because Oculus seems to favor it and it avoids the FBO struct which makes the order in which setup of the various components is performed slightly more clear.
EDIT: Support Extended Desktop mode as well as Direct mode. OS X only supports extended mode until now (SDK 0.4.3).
EDIT: Cleanup the FBO.
EDIT: Some reordering to more closely follow the setup sequence in the Oculus examples. Added simple camera position so you can walk around a bit.

// GLFWOculusRiftTest
// (c) cThrough 2014 (Daniel Dekkers)
// Version 2014111400 Based on DK2, OculusSDK 4.0.3 beta

#include <GL/glew.h>
#if defined(_WIN32)
#include <Windows.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#elif defined(__linux__)
#include <X11/X.h>
#include <X11/extensions/Xrandr.h>
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include <GLFW/glfw3.h>
#if !defined(__APPLE__)
#include <GLFW/glfw3native.h>
#endif
#include <OVR.h>
#include <OVR_CAPI.h>
#include <OVR_CAPI_GL.h>

const bool l_MultiSampling = false;
const bool l_Spin = false;

int g_DistortionCaps = 0
| ovrDistortionCap_Vignette
| ovrDistortionCap_Chromatic
| ovrDistortionCap_Overdrive
// | ovrDistortionCap_TimeWarp // Turning this on gives ghosting???
;

ovrHmd g_Hmd;
ovrGLConfig g_Cfg;
ovrEyeRenderDesc g_EyeRenderDesc[2];
ovrVector3f g_EyeOffsets[2];
ovrPosef g_EyePoses[2];
ovrTexture g_EyeTextures[2];
OVR::Matrix4f g_ProjectionMatrici[2];
OVR::Sizei g_RenderTargetSize;
ovrVector3f g_CameraPosition;

GLfloat l_VAPoints[] =
{
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f,-0.5f, 0.5f,
0.5f,-0.5f, 0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f, 0.5f,-0.5f,
0.5f, 0.5f,-0.5f,
0.5f,-0.5f,-0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f,-0.5f,
-0.5f, 0.5f,-0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f,-0.5f,-0.5f,
0.5f,-0.5f,-0.5f,
0.5f,-0.5f, 0.5f,
-0.5f,-0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f,-0.5f, 0.5f,
0.5f,-0.5f,-0.5f,
0.5f, 0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f,-0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f,-0.5f
};

GLfloat l_VANormals[] =
{
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 0.0f,-1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
0.0f,-1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f
};

GLuint l_VAIndici[] =
{
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};

// =============================================================================

static void ErrorCallback(int p_Error, const char* p_Description)
{
fputs(p_Description, stderr);
}

// =============================================================================

static void KeyCallback(GLFWwindow* p_Window, int p_Key, int p_Scancode, int p_Action, int p_Mods)
{
if (p_Action==GLFW_PRESS)
{
switch (p_Key)
{
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(p_Window, GL_TRUE);
break;
case GLFW_KEY_R:
ovrHmd_RecenterPose(g_Hmd);
break;
case GLFW_KEY_UP:
g_CameraPosition.z += 0.1f;
break;
case GLFW_KEY_DOWN:
g_CameraPosition.z -= 0.1f;
break;
case GLFW_KEY_LEFT:
g_CameraPosition.x += 0.1f;
break;
case GLFW_KEY_RIGHT:
g_CameraPosition.x -= 0.1f;
break;
}

// Remove HSW on every key...
ovrHSWDisplayState l_HasWarningState;
ovrHmd_GetHSWDisplayState(g_Hmd, &l_HasWarningState);
if (l_HasWarningState.Displayed) ovrHmd_DismissHSWDisplay(g_Hmd);
}
}

// =============================================================================

static void WindowSizeCallback(GLFWwindow* p_Window, int p_Width, int p_Height)
{
if (p_Width>0 && p_Height>0)
{
g_Cfg.OGL.Header.RTSize.w = p_Width;
g_Cfg.OGL.Header.RTSize.h = p_Height;

ovrBool l_ConfigureResult = ovrHmd_ConfigureRendering(g_Hmd, &g_Cfg.Config, g_DistortionCaps, g_Hmd->MaxEyeFov, g_EyeRenderDesc);
glUseProgram(0); // Avoid OpenGL state leak in ovrHmd_ConfigureRendering...
if (!l_ConfigureResult)
{
printf("Configure failed.\n");
exit(EXIT_FAILURE);
}
}
}

// ============================================================================

void RenderCubeVertexArrays(void)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, l_VAPoints);

glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, l_VANormals);

glDrawElements(GL_QUADS, 6*4, GL_UNSIGNED_INT, l_VAIndici);

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}

// ============================================================================

void RenderCubeFixedFunction(void)
{
// Obsolete, remains as a fall back for the vertex arrays version...
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);

glNormal3f( 0.0f, 0.0f,-1.0f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);

glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);

glNormal3f( 0.0f,-1.0f, 0.0f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);

glNormal3f( 1.0f, 0.0f, 0.0f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);

glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glEnd();
}

// ============================================================================

static void SetOpenGLState(void)
{
// Some state...
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (l_MultiSampling) glEnable(GL_MULTISAMPLE); else glDisable(GL_MULTISAMPLE);
glClearColor(0.2f, 0.3f, 0.4f, 1.0f);

// Material...
GLfloat l_MaterialSpecular[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat l_MaterialShininess[] = { 10.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, l_MaterialSpecular);
glMaterialfv(GL_FRONT, GL_SHININESS, l_MaterialShininess);

// Some (stationary) lights, position will be set every frame separately...
GLfloat l_Light0Diffuse[] = { 1.0f, 0.8f, 0.6f, 1.0f };
glLightfv(GL_LIGHT0, GL_DIFFUSE, l_Light0Diffuse);
glEnable(GL_LIGHT0);

GLfloat l_Light1Diffuse[] = { 0.6f, 0.8f, 1.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_DIFFUSE, l_Light1Diffuse);
glEnable(GL_LIGHT1);
}

// ============================================================================

static void SetStaticLightPositions(void)
{
GLfloat l_Light0Position[] = { 3.0f, 4.0f, 2.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_POSITION, l_Light0Position);

GLfloat l_Light1Position[] = { -3.0f, -4.0f, 2.0f, 0.0f };
glLightfv(GL_LIGHT1, GL_POSITION, l_Light1Position);
}

// =============================================================================

int main(void)
{
printf("[R] to recenter, [Esc] to quit, dismiss the HSW with any key (after the hidden timer runs out)...\n");

// Initialize LibOVR...
ovr_Initialize();

// Check for attached head mounted display...
g_Hmd = ovrHmd_Create(0);
if (!g_Hmd)
{
printf("No Oculus Rift device attached, using virtual version...\n");
g_Hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
}

// Create a window...
GLFWwindow* l_Window;

glfwSetErrorCallback(ErrorCallback);

if (!glfwInit()) exit(EXIT_FAILURE);

if (l_MultiSampling) glfwWindowHint(GLFW_SAMPLES, 4); else glfwWindowHint(GLFW_SAMPLES, 0);

// Check to see if we are running in "Direct" or "Extended Desktop" mode...
bool l_DirectMode = ((g_Hmd->HmdCaps & ovrHmdCap_ExtendDesktop)==0);

GLFWmonitor* l_Monitor;
ovrSizei l_ClientSize;
if (l_DirectMode)
{
printf("Running in \"Direct\" mode...\n");
l_Monitor = NULL;

l_ClientSize.w = g_Hmd->Resolution.w/2; // Something reasonable, smaller, but maintain aspect ratio...
l_ClientSize.h = g_Hmd->Resolution.h/2; // Something reasonable, smaller, but maintain aspect ratio...
}
else // Extended Desktop mode...
{
printf("Running in \"Extended Desktop\" mode...\n");
int l_Count;
GLFWmonitor** l_Monitors = glfwGetMonitors(&l_Count);
switch (l_Count)
{
case 0:
printf("No monitors found, exiting...\n");
exit(EXIT_FAILURE);
break;
case 1:
printf("Two monitors expected, found only one, using primary...\n");
l_Monitor = glfwGetPrimaryMonitor();
break;
case 2:
printf("Two monitors found, using second monitor...\n");
l_Monitor = l_Monitors[1];
break;
default:
printf("More than two monitors found, using second monitor...\n");
l_Monitor = l_Monitors[1];
}

l_ClientSize.w = g_Hmd->Resolution.w; // 1920 for DK2...
l_ClientSize.h = g_Hmd->Resolution.h; // 1080 for DK2...
}

// Create the window based on the parameters set above...
l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", l_Monitor, NULL);

// Check if window creation was succesfull...
if (!l_Window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}

// Attach the window in "Direct Mode"...
#if defined(_WIN32)
if (l_DirectMode)
{
ovrBool l_AttachResult = ovrHmd_AttachToWindow(g_Hmd, glfwGetWin32Window(l_Window), NULL, NULL);
if (!l_AttachResult)
{
printf("Could not attach to window...");
exit(EXIT_FAILURE);
}
}
#endif

// Make the context current for this window...
glfwMakeContextCurrent(l_Window);

// Don't forget to initialize Glew, turn glewExperimental on to avoid problem fetching function pointers...
glewExperimental = GL_TRUE;
GLenum l_GlewResult = glewInit();
if (l_GlewResult!=GLEW_OK)
{
printf("glewInit() error.\n");
exit(EXIT_FAILURE);
}

// Print some info about the OpenGL context...
int l_Major = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MAJOR);
int l_Minor = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MINOR);
int l_Profile = glfwGetWindowAttrib(l_Window, GLFW_OPENGL_PROFILE);
printf("OpenGL: %d.%d ", l_Major, l_Minor);
if (l_Major>=3) // Profiles introduced in OpenGL 3.0...
{
if (l_Profile==GLFW_OPENGL_COMPAT_PROFILE) printf("GLFW_OPENGL_COMPAT_PROFILE\n"); else printf("GLFW_OPENGL_CORE_PROFILE\n");
}
printf("Vendor: %s\n", (char*)glGetString(GL_VENDOR));
printf("Renderer: %s\n", (char*)glGetString(GL_RENDERER));

// Create some lights, materials, etc...
SetOpenGLState();

// Find out what the texture sizes should be for each eye separately first...
ovrSizei l_EyeTextureSizes[2];

l_EyeTextureSizes[ovrEye_Left] = ovrHmd_GetFovTextureSize(g_Hmd, ovrEye_Left, g_Hmd->MaxEyeFov[ovrEye_Left], 1.0f);
l_EyeTextureSizes[ovrEye_Right] = ovrHmd_GetFovTextureSize(g_Hmd, ovrEye_Right, g_Hmd->MaxEyeFov[ovrEye_Right], 1.0f);

// Combine for one texture for both eyes...
g_RenderTargetSize.w = l_EyeTextureSizes[ovrEye_Left].w + l_EyeTextureSizes[ovrEye_Right].w;
g_RenderTargetSize.h = (l_EyeTextureSizes[ovrEye_Left].h>l_EyeTextureSizes[ovrEye_Right].h ? l_EyeTextureSizes[ovrEye_Left].h : l_EyeTextureSizes[ovrEye_Right].h);

// Create the FBO being a single one for both eyes (this is open for debate)...
GLuint l_FBOId;
glGenFramebuffers(1, &l_FBOId);
glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);

// The texture we're going to render to...
GLuint l_TextureId;
glGenTextures(1, &l_TextureId);
// "Bind" the newly created texture : all future texture functions will modify this texture...
glBindTexture(GL_TEXTURE_2D, l_TextureId);
// Give an empty image to OpenGL (the last "0")
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_RenderTargetSize.w, g_RenderTargetSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Linear filtering...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Create Depth Buffer...
GLuint l_DepthBufferId;
glGenRenderbuffers(1, &l_DepthBufferId);
glBindRenderbuffer(GL_RENDERBUFFER, l_DepthBufferId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, g_RenderTargetSize.w, g_RenderTargetSize.h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, l_DepthBufferId);

// Set the texture as our colour attachment #0...
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, l_TextureId, 0);

// Set the list of draw buffers...
GLenum l_GLDrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, l_GLDrawBuffers); // "1" is the size of DrawBuffers

// Check if everything is OK...
GLenum l_Check = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (l_Check!=GL_FRAMEBUFFER_COMPLETE)
{
printf("There is a problem with the FBO.\n");
exit(EXIT_FAILURE);
}

// Unbind...
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// Setup textures for each eye...

// Left eye...
g_EyeTextures[ovrEye_Left].Header.API = ovrRenderAPI_OpenGL;
g_EyeTextures[ovrEye_Left].Header.TextureSize = g_RenderTargetSize;
g_EyeTextures[ovrEye_Left].Header.RenderViewport.Pos.x = 0;
g_EyeTextures[ovrEye_Left].Header.RenderViewport.Pos.y = 0;
g_EyeTextures[ovrEye_Left].Header.RenderViewport.Size = l_EyeTextureSizes[ovrEye_Left];
((ovrGLTexture&)(g_EyeTextures[ovrEye_Left])).OGL.TexId = l_TextureId;

// Right eye (mostly the same as left but with the viewport on the right side of the texture)...
g_EyeTextures[ovrEye_Right] = g_EyeTextures[ovrEye_Left];
g_EyeTextures[ovrEye_Right].Header.RenderViewport.Pos.x = (g_RenderTargetSize.w+1)/2;
g_EyeTextures[ovrEye_Right].Header.RenderViewport.Pos.y = 0;

// Oculus Rift eye configurations...
g_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
g_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
g_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
g_Cfg.OGL.Header.Multisample = (l_MultiSampling ? 1 : 0);
#if defined(_WIN32)
g_Cfg.OGL.Window = glfwGetWin32Window(l_Window);
g_Cfg.OGL.DC = GetDC(g_Cfg.OGL.Window);
#elif defined(__linux__)
l_Cfg.OGL.Win = glfwGetX11Window(l_Window);
l_Cfg.OGL.Disp = glfwGetX11Display();
#endif

// Enable capabilities...
// ovrHmd_SetEnabledCaps(g_Hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);

ovrBool l_ConfigureResult = ovrHmd_ConfigureRendering(g_Hmd, &g_Cfg.Config, g_DistortionCaps, g_Hmd->MaxEyeFov, g_EyeRenderDesc);
glUseProgram(0); // Avoid OpenGL state leak in ovrHmd_ConfigureRendering...
if (!l_ConfigureResult)
{
printf("Configure failed.\n");
exit(EXIT_FAILURE);
}

// Start the sensor which provides the Rift’s pose and motion...
uint32_t l_SupportedSensorCaps = ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position;
uint32_t l_RequiredTrackingCaps = 0;
ovrBool l_TrackingResult = ovrHmd_ConfigureTracking(g_Hmd, l_SupportedSensorCaps, l_RequiredTrackingCaps);
if (!l_TrackingResult)
{
printf("Could not start tracking...");
exit(EXIT_FAILURE);
}

// Projection matrici for each eye will not change at runtime, we can set them here...
g_ProjectionMatrici[ovrEye_Left] = ovrMatrix4f_Projection(g_EyeRenderDesc[ovrEye_Left].Fov, 0.3f, 100.0f, true);
g_ProjectionMatrici[ovrEye_Right] = ovrMatrix4f_Projection(g_EyeRenderDesc[ovrEye_Right].Fov, 0.3f, 100.0f, true);

// IPD offset values will not change at runtime, we can set them here...
g_EyeOffsets[ovrEye_Left] = g_EyeRenderDesc[ovrEye_Left].HmdToEyeViewOffset;
g_EyeOffsets[ovrEye_Right] = g_EyeRenderDesc[ovrEye_Right].HmdToEyeViewOffset;

// Initial camera position...
g_CameraPosition.x = 0.0f;
g_CameraPosition.y = 0.0f;
g_CameraPosition.z = -2.0f;

glfwSetKeyCallback(l_Window, KeyCallback);
glfwSetWindowSizeCallback(l_Window, WindowSizeCallback);

GLfloat l_SpinX;
GLfloat l_SpinY;

// Do a single recenter to calibrate orientation to current state of the Rift...
ovrHmd_RecenterPose(g_Hmd);

// Main loop...
unsigned int l_FrameIndex = 0;
while (!glfwWindowShouldClose(l_Window))
{
if (l_Spin)
{
l_SpinX = (GLfloat) fmod(glfwGetTime()*17.0, 360.0);
l_SpinY = (GLfloat) fmod(glfwGetTime()*23.0, 360.0);
}
else
{
l_SpinX = 30.0f;
l_SpinY = 40.0f;
}

// Begin the frame...
ovrHmd_BeginFrame(g_Hmd, l_FrameIndex);

// Get eye poses for both the left and the right eye. g_EyePoses contains all Rift information: orientation, positional tracking and
// the IPD in the form of the input variable g_EyeOffsets.
ovrHmd_GetEyePoses(g_Hmd, l_FrameIndex, g_EyeOffsets, g_EyePoses, NULL);

// Bind the FBO...
glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);

// Clear...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for (int l_EyeIndex=0; l_EyeIndex<ovrEye_Count; l_EyeIndex++)
{
ovrEyeType l_Eye = g_Hmd->EyeRenderOrder[l_EyeIndex];

glViewport(
g_EyeTextures[l_Eye].Header.RenderViewport.Pos.x,
g_EyeTextures[l_Eye].Header.RenderViewport.Pos.y,
g_EyeTextures[l_Eye].Header.RenderViewport.Size.w,
g_EyeTextures[l_Eye].Header.RenderViewport.Size.h
);

// Pass projection matrix on to OpenGL...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixf(&(g_ProjectionMatrici[l_Eye].Transposed().M[0][0]));

// Create the model-view matrix and pass on to OpenGL...
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Multiply with orientation retrieved from sensor...
OVR::Quatf l_Orientation = OVR::Quatf(g_EyePoses[l_Eye].Orientation);
OVR::Matrix4f l_ModelViewMatrix = OVR::Matrix4f(l_Orientation.Inverted());
glMultMatrixf(&(l_ModelViewMatrix.Transposed().M[0][0]));

// Translation due to positional tracking (DK2) and IPD...
glTranslatef(-g_EyePoses[l_Eye].Position.x, -g_EyePoses[l_Eye].Position.y, -g_EyePoses[l_Eye].Position.z);

// Move the world forward a bit to show the scene in front of us...
glTranslatef(g_CameraPosition.x, g_CameraPosition.y, g_CameraPosition.z);

// (Re)set the light positions so they don't move along with the cube...
SetStaticLightPositions();

// Make the cube spin...
glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);

// Render...
// RenderCubeFixedFunction();
RenderCubeVertexArrays();
}

// Back to the default framebuffer...
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// Do everything, distortion, front/back buffer swap...
ovrHmd_EndFrame(g_Hmd, g_EyePoses, g_EyeTextures);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Avoid OpenGL state leak in ovrHmd_EndFrame...
glBindBuffer(GL_ARRAY_BUFFER, 0); // Avoid OpenGL state leak in ovrHmd_EndFrame...

++l_FrameIndex;

glfwPollEvents();
}

// Clean up FBO...
glDeleteRenderbuffers(1, &l_DepthBufferId);
glDeleteTextures(1, &l_TextureId);
glDeleteFramebuffers(1, &l_FBOId);

// Clean up Oculus...
ovrHmd_Destroy(g_Hmd);
ovr_Shutdown();

// Clean up window...
glfwDestroyWindow(l_Window);
glfwTerminate();

exit(EXIT_SUCCESS);
}

    21 replies

    Inspiring
    November 9, 2014
    I've updated my example code to remove the use of oglplus for setting up and using the framebuffer object. I'm still using oglplus to render my actual scene because it means there's way, way less boilerplate than if I set up the rendering of the cubes myself, but since anyone using this presumably has their own scene to render, they can dump oglplus completely and replace my scene rendering with theirs.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    DoZo1971Author
    Up and Coming
    November 10, 2014
    Ok, thanks, some remarks:

    There is a typo "FramebufferWraper" instead of "FramebufferWrapper".

    I'm using VS2012 so I removed some C++11 specifics, ie put uniform initializations in constructors. That's the only thing, do you really want to lose downwards compatibility for that?

    I wouldn't use OGLplus for the setting of the viewport (just use glViewport(...)). Same for the binding of the (default)
    frame buffer and OpenGL state settings like glClearColor(...),... and glClear(...); So then people can really just add their own render function and not be dependent on OGLplus.

    For some reason I was expecting a console application, not a Win32 application. No problem, just changed my CMake ADD_EXECUTABLE(...) entry. But might not be obvious for everyone.

    And then it works for me... but... like in my own simple example, I get lots of weird _com_error exceptions and a less then elegant program closure. I never had these problems with Oculus SDK 0.4.2 or earlier. The series of _com_error exceptions happens when glfwCreateWindow(...) is called but only after ovr_Initialize() is executed with a Rift present. Otherwise (no Rift and/or no ovr_Initialize()) it passes glfwCreateWindow(...) gracefully.

    This is the log:

    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\cThroughBuild\Everything002_050_022\Tests\GLFWOculusRiftBradDavisTest\Debug\GLFWOculusRiftBradDavisTest.exe'. Symbols loaded.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\opengl32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\user32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\lpk.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\usp10.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\glu32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ddraw.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\dciman32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\setupapi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cfgmgr32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\oleaut32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ole32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\devobj.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\dwmapi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp110d.dll'. Symbols loaded.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr110d.dll'. Symbols loaded.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\version.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\dbghelp.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\shell32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\shlwapi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\winmm.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ws2_32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\nsi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\imm32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msctf.dll'. Cannot find or open the PDB file.
    Debug: PerformanceTimer UsingVistaOrLater = 1
    Debug: NtQueryTimerResolution = Min 15600 us, Max 500 us, Current 1000 us
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\dxgi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\d3d9.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\d3d8thk.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\d3d11.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\dxgidebug.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\d3d10core.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\d3d10.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\OVRDisplayRT32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp120.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr120.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\mswsock.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\wship6.dll'. Cannot find or open the PDB file.
    Debug: [NetClient] Connected to a server running version 1.1.0 (my version=1.1.0)
    Debug: Setting up display shim
    Debug: Failed to open file: C:\Users\Daniel Dekkers\AppData\Local/Oculus/Devices.json
    Debug: Using profile Daniel
    Debug: [SharedMemory] Creating factory
    Debug: [SharedMemory] Creating shared memory region: OVRObject00 > 1184 bytes
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\OVRDisplay32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\nvoglv32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\wtsapi32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\gdi32.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\wintrust.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\crypt32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msasn1.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntmarta.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\Wldap32.dll'. Cannot find or open the PDB file.
    The thread 0x3ac has exited with code 0 (0x0).
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\powrprof.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\powrprof.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\winsta.dll'. Cannot find or open the PDB file.
    The thread 0xfd0 has exited with code 0 (0x0).
    The thread 0x117c has exited with code 0 (0x0).
    The thread 0x8ec has exited with code 0 (0x0).
    OpenAdapter10_2 called
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\nvwgf2um.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\psapi.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcrypt.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\shell32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\shell32.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\nvspcap.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\nvapi.dll'. Cannot find or open the PDB file.
    The thread 0xa94 has exited with code 0 (0x0).
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\gdi32.dll'
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcryptprimitives.dll'. Cannot find or open the PDB file.
    OpenAdapter10_2 called
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ole32.dll'. Cannot find or open the PDB file.
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\ole32.dll'
    Debug: GL_VERSION: 4.1.0 NVIDIA 344.60
    OpenAdapter10_2 called
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    Debug: [HSWDisplay] Display()
    Debug: [HSWDisplay GL] DisplayInternal()
    OpenAdapter10_2 called
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF7BC.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    First-chance exception at 0x76B2C42D in GLFWOculusRiftBradDavisTest.exe: Microsoft C++ exception: _com_error at memory location 0x031AF6D0.
    Debug: GL_VERSION: 4.4.0 NVIDIA 344.60
    Debug: [SharedMemory] Creating shared memory region: OVRAppFocus > 16 bytes
    Debug: [HSWDisplay] Dismiss(): Not permitted yet. Queued for timeout in 0.0 seconds.
    Debug: [HSWDisplay GL] DismissInternal()
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d9.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d8thk.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d10.dll'
    'GLFWOculusRiftBradDavisTest.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\d3d10core.dll'
    Debug: [NetClient] Disconnected
    Debug: [SharedMemory] Destroying factory
    The thread 0xaac has exited with code 0 (0x0).
    The thread 0xf40 has exited with code 0 (0x0).
    The thread 0x106c has exited with code 0 (0x0).
    The thread 0x1888 has exited with code 0 (0x0).
    The thread 0x188c has exited with code 0 (0x0).
    The thread 0x1884 has exited with code 0 (0x0).
    The thread 0x18e0 has exited with code 0 (0x0).
    The thread 0x18dc has exited with code 0 (0x0).
    The thread 0x18cc has exited with code 0 (0x0).
    The thread 0x1858 has exited with code 0 (0x0).
    The thread 0x18d4 has exited with code 0 (0x0).
    The thread 0x1714 has exited with code 0 (0x0).
    The thread 0x1600 has exited with code 0 (0x0).
    The thread 0x18d8 has exited with code 0 (0x0).
    The thread 0x16c8 has exited with code 0 (0x0).

    ****************
    ERROR: RT Shim being unloaded before all references reached 0!
    This can be indicative of calling FreeLibrary directly without
    checking DllCanUnloadNow() first, or it could be a leaked reference
    at process exit.

    Outstanding references:
    OVRDirect3D9Ex: 0
    OVRDirect3DDevice9Ex: 0
    OVRDXGIAdapter: 4
    OVRDXGIFactory: 4
    OVRDXGISwapChain: 4
    ****************

    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x032AD380, Refcount: 5. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x00550FD8, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x03673D20, Refcount: 5. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x03676698, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x03B061E8, Refcount: 7. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x03B08B60, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x06604500, Refcount: 5. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x06606E78, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    The program '[5144] GLFWOculusRiftBradDavisTest.exe' has exited with code 0 (0x0).
    DoZo1971Author
    Up and Coming
    November 10, 2014
    Hi,

    I was wondering if these strange errors I'm getting (see previous thread post) might have something to do with the fact that I'm on a multi-GPU machine. In my case a MacBook Pro Retina with both an Intel Iris Pro and a NVIDIA GeForce 750M. During initialization (ie ovr_Initialize(), ovr_Create() and ovrHmd_ConfigureTracking()) the Iris Pro might still active, but after window creation NVIDIA takes over ("automatic processor switching") for the OpenGL context. Would that be causing problems?

    Thanks, Daniel
    Up and Coming
    November 10, 2014
    "DoZo1971" wrote:
    Hi,

    I was wondering if these strange errors I'm getting (see previous thread post) might have something to do with the fact that I'm on a multi-GPU machine. In my case a MacBook Pro Retina with both an Intel Iris Pro and a NVIDIA GeForce 750M. During initialization (ie ovr_Initialize(), ovr_Create() and ovrHmd_ConfigureTracking()) the Iris Pro might still active, but after window creation NVIDIA takes over ("automatic processor switching") for the OpenGL context. Would that be causing problems?

    Thanks, Daniel


    From other threads (including the one CyberReality pinned at the top) mixed GPU's with Intel cards have been known to cause problems.

    Is it possible for you to disable Intel's GPU and then try again?
    DoZo1971Author
    Up and Coming
    November 10, 2014
    Ok, I'll take a look at the thread you mentioned.

    Now I've read somewhere that Oculus themselves use MacBook Pro Retinas doing demos, on Windows via Bootcamp. I guess that would be the exact same configuration that I'm using. So at least they managed to solve it ;-) At the moment I'm even having some doubts if I should use the hdmi output (like I do now) or use one of the thunderbolt ports and buy a thunderbolt->hdmi converter.

    Does the example work on your platform? I just edited it, it's back to one FBO for both eyes. It works for me, despite the strange warnings.

    I wouldn't know how to disable the Intel GPU, but i'll try to find out.

    Thanks, Daniel
    Up and Coming
    November 10, 2014
    "DoZo1971" wrote:
    Ok, I'll take a look at the thread you mentioned.

    Now I've read somewhere that Oculus themselves use MacBook Pro Retinas doing demos, on Windows via Bootcamp. I guess that would be the exact same configuration that I'm using. So at least they managed to solve it ;-) At the moment I'm even having some doubts if I should use the hdmi output (like I do now) or use one of the thunderbolt ports and buy a thunderbolt->hdmi converter.

    Does the example work on your platform? I just edited it, it's back to one FBO for both eyes. It works for me, despite the strange warnings.

    I wouldn't know how to disable the Intel GPU, but i'll try to find out.

    Thanks, Daniel


    Been busy but definitely plan on trying the various examples out.
    DoZo1971Author
    Up and Coming
    November 11, 2014
    Hm...
    GPU-Z doesn't find the Intel Iris Pro. That might figure:

    More bad news about the RMBP and CUDA (Apple's blame, not NV's). If you install Linux or Windows, the Apple EFI bootloader will disable the integrated GPU entirely, forcing the sideloaded OS to run on the discrete GPU fulltime. This is likely simply to give OSX a huge battery life advantage over other OSes. But unfortunately it sucks for CUDA developers. I was planning to develop on all three OSes with one machine.

    In that case that wouldn't be the source of my errors, integrated GPU disabled altogether on Windows on bootcamp.
    Up and Coming
    November 11, 2014
    "DoZo1971" wrote:
    Hm...
    GPU-Z doesn't find the Intel Iris Pro. That might figure:

    More bad news about the RMBP and CUDA (Apple's blame, not NV's). If you install Linux or Windows, the Apple EFI bootloader will disable the integrated GPU entirely, forcing the sideloaded OS to run on the discrete GPU fulltime. This is likely simply to give OSX a huge battery life advantage over other OSes. But unfortunately it sucks for CUDA developers. I was planning to develop on all three OSes with one machine.

    In that case that wouldn't be the source of my errors, integrated GPU disabled altogether on Windows on bootcamp.


    I see; I still have yet to try the new stuff posted in the last few days; as soon as I can I will post feedback.
    DoZo1971Author
    Up and Coming
    November 11, 2014
    Hi,

    Please do. I'm very curious if the warnings are on my system only or show on a "normal desktop model with a single dedicated GPU" as well.

    The good news is that, apart from the warnings, things seem to start working. I've made a port to my wxWidgets based projects today and again... nice direct mode OpenGL. But again, these warnings. So it is not GLFW specific, it is any "window manager" trying to create a OpenGL window after ovr_Initialize() is called with a Rift attached. And it seems to be DirectX related.

    So, summarized:
    Window creation gives:

    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FBA0.
    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FBA0.
    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FAB4.
    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FAB4.


    And when the program ends:

    ****************
    ERROR: RT Shim being unloaded before all references reached 0!
    This can be indicative of calling FreeLibrary directly without
    checking DllCanUnloadNow() first, or it could be a leaked reference
    at process exit.

    Outstanding references:
    OVRDirect3D9Ex: 0
    OVRDirect3DDevice9Ex: 0
    OVRDXGIAdapter: 3
    OVRDXGIFactory: 3
    OVRDXGISwapChain: 3
    ****************

    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x03E4C460, Refcount: 5. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x03E4FCA8, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x0430ECE8, Refcount: 7. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x04311660, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Producer at 0x044994E0, Refcount: 5. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object at 0x0449BE58, Refcount: 2. [ STATE_CREATION WARNING #0: ]
    DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
    The program '[3308] OpenGLOculusRiftTest.exe' has exited with code 0 (0x0).


    Thanks, Daniel
    New Participant
    November 11, 2014
    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FBA0.

    First-chance exception at 0x759DC42D in OpenGLOculusRiftTest.exe: Microsoft C++ exception: _com_error at memory location 0x0399FBA0.

    ERROR: RT Shim being unloaded before all references reached 0!
    This can be indicative of calling FreeLibrary directly without
    checking DllCanUnloadNow() first, or it could be a leaked reference
    at process exit.

    I am getting these exact same errors with my OpenGL 4 application on Windows 7 64-bit, rendering directly to the rift. Aside from that, everything works perfectly.