Skip to main content
Up and Coming
April 27, 2014

Simple OpenGL example with GLFW, GLEW and OculusSDK 0.3.1

Hi,

Hope this will save you some headaches (and not cause any more).
Only win32, but with GLFW it shouldn't be too hard to port once the OculusSDK becomes cross-platform.

EDIT
This is a one-page sample, 99% plain C. It is based on the OculusSDK 0.3.1 Preview. OpenGL 3.3 and up, compatibility profile.
For nVidia systems it works as-is.
At the time of writing, for AMD systems, it needs some bug fixes and a rebuild of the SDK libraries. This "patch" is advised for nVidia users as well, but not needed.
Load the Visual Studio solution from OculusSDK/Samples. Depending on your Visual Studio [version]: LibOVR_With_Samples_[version].sln.
In CAPI_GL_DistortionRenderer.cpp (LibOVR/CAPI/GL):
Line 142, replace oColor = Color.r with oColor = vec4(oColor)
Line 349, replace oColor = Color.r with oColor = vec4(oColor)
Line 758, replace (int) DistortionMeshVBs[eyeNum]->GetSize() with (int)DistortionMeshIBs[eyeNum]->GetSize()/2
Line 763, replace (int) DistortionMeshVBs[eyeNum]->GetSize() with (int)DistortionMeshIBs[eyeNum]->GetSize()/2
Rebuild the lib (Debug and/or Release).

Thanks,
Daniel Dekkers


#include <Windows.h>
#include <GL/glew.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <OVR_CAPI.h>
#include <OVR_CAPI_GL.h>
#include <OVR.h>

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

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_Key == GLFW_KEY_ESCAPE && p_Action == GLFW_PRESS)
glfwSetWindowShouldClose(p_Window, GL_TRUE);
}

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

static void RenderCube(float p_Size)
{
const float l_SizeDiv2 = p_Size*0.5f;

// A cube...
glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f, 1.0f);
glVertex3f( l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glEnd();

glBegin(GL_QUADS);
glNormal3f( 0.0f, 0.0f,-1.0f);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
glVertex3f( l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glEnd();

glBegin(GL_QUADS);
glNormal3f( 0.0f, 1.0f, 0.0f);
glVertex3f( l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glVertex3f( l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glEnd();

glBegin(GL_QUADS);
glNormal3f( 0.0f,-1.0f, 0.0f);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glEnd();

glBegin(GL_QUADS);
glNormal3f( 1.0f, 0.0f, 0.0f);
glVertex3f( l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glVertex3f( l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glVertex3f( l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
glEnd();

glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2,-l_SizeDiv2);
glVertex3f(-l_SizeDiv2,-l_SizeDiv2, l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2, l_SizeDiv2);
glVertex3f(-l_SizeDiv2, l_SizeDiv2,-l_SizeDiv2);
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);

// Some (stationary) lights...
GLfloat l_Light0Position[] = { 5.0f, 6.0f, 3.0f, 0.0f };
GLfloat l_Light0Diffuse[] = { 1.0f, 0.8f, 0.6f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, l_Light0Position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, l_Light0Diffuse);
glEnable(GL_LIGHT0);

GLfloat l_Light1Position[] = { -5.0f, -6.0f, 5.0f, 0.0f };
GLfloat l_Light1Diffuse[] = { 0.6f, 0.8f, 1.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_POSITION, l_Light1Position);
glLightfv(GL_LIGHT1, GL_DIFFUSE, l_Light1Diffuse);
glEnable(GL_LIGHT1);

// 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);
}

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

int main(void)
{
// Initialize LibOVR...
ovr_Initialize();

ovrHmd l_Hmd = ovrHmd_Create(0);
if (!l_Hmd) l_Hmd = ovrHmd_CreateDebug(ovrHmd_DK1);

ovrHmdDesc l_HmdDesc;
ovrHmd_GetDesc(l_Hmd, &l_HmdDesc);

ovrHmd_StartSensor(l_Hmd, ovrHmdCap_Orientation, 0);

GLFWwindow* l_Window;

glfwSetErrorCallback(ErrorCallback);

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

ovrSizei l_ClientSize;
l_ClientSize.w = l_HmdDesc.Resolution.w; // 1280 for DK1...
l_ClientSize.h = l_HmdDesc.Resolution.h; // 800 for DK1...
// Create a fullscreen window with the Oculus Rift resolution...
l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", glfwGetPrimaryMonitor(), NULL);
if (!l_Window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}

// Print the OpenGL version we are using...
int l_Major = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MAJOR);
int l_Minor = glfwGetWindowAttrib(l_Window, GLFW_CONTEXT_VERSION_MINOR);
printf("OpenGL: %d.%d\n", l_Major, l_Minor);

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

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

// Don't forget to initialize Glew...
glewInit();

// We will do some offscreen rendering, setup FBO...
ovrSizei l_TextureSizeLeft = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Left, l_HmdDesc.DefaultEyeFov[0], 1.0f);
ovrSizei l_TextureSizeRight = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Right, l_HmdDesc.DefaultEyeFov[1], 1.0f);
ovrSizei l_TextureSize;
l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
l_TextureSize.h = (l_TextureSizeLeft.h>l_TextureSizeRight.h ? l_TextureSizeLeft.h : l_TextureSizeRight.h);

// Create FBO...
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, l_TextureSize.w, l_TextureSize.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, l_TextureSize.w, l_TextureSize.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

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

// Oculus Rift eye configurations...
ovrEyeDesc l_Eyes[2];
l_Eyes[0].Eye = ovrEye_Left;
l_Eyes[1].Eye = ovrEye_Right;
l_Eyes[0].Fov = l_HmdDesc.DefaultEyeFov[0];
l_Eyes[1].Fov = l_HmdDesc.DefaultEyeFov[1];
l_Eyes[0].TextureSize.w = l_TextureSize.w;
l_Eyes[0].TextureSize.h = l_TextureSize.h;
l_Eyes[1].TextureSize.w = l_TextureSize.w;
l_Eyes[1].TextureSize.h = l_TextureSize.h;
l_Eyes[0].RenderViewport.Pos.x = 0;
l_Eyes[0].RenderViewport.Pos.y = 0;
l_Eyes[1].RenderViewport.Pos.x = (l_TextureSize.w+1)/2;
l_Eyes[1].RenderViewport.Pos.y = 0;
l_Eyes[0].RenderViewport.Size.w = l_TextureSize.w/2;
l_Eyes[0].RenderViewport.Size.h = l_TextureSize.h;
l_Eyes[1].RenderViewport.Size.w = l_Eyes[0].RenderViewport.Size.w;
l_Eyes[1].RenderViewport.Size.h = l_Eyes[0].RenderViewport.Size.h;

ovrGLConfig l_Cfg;
l_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
l_Cfg.OGL.Header.Multisample = 0;
l_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
l_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
l_Cfg.OGL.WglContext = glfwGetWGLContext(l_Window);
l_Cfg.OGL.Window = glfwGetWin32Window(l_Window);
l_Cfg.OGL.GdiDc = GetDC(l_Cfg.OGL.Window);

int l_RenderCaps = 0;
int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
ovrEyeRenderDesc l_EyeRenderDesc[2];
ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);

ovrGLTexture l_EyeTexture[2];
l_EyeTexture[0].OGL.Header.API = ovrRenderAPI_OpenGL;
l_EyeTexture[0].OGL.Header.TextureSize.w = l_TextureSize.w;
l_EyeTexture[0].OGL.Header.TextureSize.h = l_TextureSize.h;
l_EyeTexture[0].OGL.Header.RenderViewport = l_Eyes[0].RenderViewport;
l_EyeTexture[0].OGL.TexId = l_TextureId;

// Right eye uses the same texture, but a different rendering viewport...
l_EyeTexture[1] = l_EyeTexture[0];
l_EyeTexture[1].OGL.Header.RenderViewport = l_Eyes[1].RenderViewport;

glfwSetKeyCallback(l_Window, KeyCallback);

GLfloat l_SpinX;
GLfloat l_SpinY;

while (!glfwWindowShouldClose(l_Window))
{
l_SpinX = (GLfloat) fmod(glfwGetTime()*17.0, 360.0);
l_SpinY = (GLfloat) fmod(glfwGetTime()*23.0, 360.0);

ovrFrameTiming m_HmdFrameTiming = ovrHmd_BeginFrame(l_Hmd, 0);

// Bind the FBO...
glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);
// Clear...
glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for (int l_EyeIndex=0; l_EyeIndex<ovrEye_Count; l_EyeIndex++)
{
ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder[l_EyeIndex];
ovrPosef l_EyePose = ovrHmd_BeginEyeRender(l_Hmd, l_Eye);

glViewport(l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.x, // StartX
l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.y, // StartY
l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.w, // Width
l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.h // Height
);

// Get Projection and ModelView matrici from the device...
OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
l_EyeRenderDesc[l_Eye].Desc.Fov, 0.3f, 100.0f, true);
OVR::Quatf l_Orientation = OVR::Quatf(l_EyePose.Orientation);
OVR::Matrix4f l_ModelViewMatrix = OVR::Matrix4f(l_Orientation.Inverted());

// Pass matrici on to OpenGL...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixf(&(l_ProjectionMatrix.Transposed().M[0][0]));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Translate for specific eye based on IPD...
glTranslatef(l_EyeRenderDesc[l_Eye].ViewAdjust.x,
l_EyeRenderDesc[l_Eye].ViewAdjust.y,
l_EyeRenderDesc[l_Eye].ViewAdjust.z);
// Multiply with orientation retrieved from sensor...
glMultMatrixf(&(l_ModelViewMatrix.Transposed().M[0][0]));
// Move back a bit to show scene in front of us...
glTranslatef(0.0f, 0.0f, -3.0f);
// Make the cube spin...
glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);

// Render...
RenderCube(1.0f);

ovrHmd_EndEyeRender(l_Hmd, l_Eye, l_EyePose, &l_EyeTexture[l_Eye].Texture);
}

// Unbind the FBO, back to normal drawing...
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// Oculus wants CW orientations, avoid the problem by turning of culling...
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
ovrHmd_EndFrame(l_Hmd);
// Restore state after Oculus did it's work (-sigh-)...
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearDepth(1);
glUseProgramObjectARB(0);

glfwPollEvents();
}

glfwDestroyWindow(l_Window);

glfwTerminate();

ovrHmd_Destroy(l_Hmd);
ovr_Shutdown();

exit(EXIT_SUCCESS);
}

    62 replies

    Up and Coming
    May 1, 2014
    "DoZo1971" wrote:
    Pffff.. I'm clueless.
    Do other examples work on your AMD system? The (DirectX) OculusRoomTiny, OculusWorldDemo samples?
    Have you got any other OpenGL example working so far (that uses OculusSDK 3.0.1)?

    Thanks,
    Daniel


    The DirectX Samples work on the system:

    Up and Coming
    May 1, 2014
    "DoZo1971" wrote:
    Pffff.. I'm clueless.

    You could try this one just to make sure (just copy and paste the text over the existing example).
    It's standard stereoscopic rendering, doesn't use any Oculus stuff but it uses the same off-screen FBO setup.


    This example works:

    Up and Coming
    May 1, 2014
    "DoZo1971" wrote:


    Do other examples work on your AMD system? The (DirectX) OculusRoomTiny, OculusWorldDemo samples?
    Have you got any other OpenGL example working so far (that uses OculusSDK 3.0.1)?

    Thanks,
    Daniel


    As shown below; I got your basic test and the DirectX samples to work.

    Has anyone gotten OpenGL 4.4 and AMD (Radeon) based graphics cards to work with the Oculus Rift?
    Inspiring
    May 1, 2014
    "ckoeber" wrote:
    So should I just re-download the SDK? I will try that.


    If the index buffer is getting corrupted or dropped somehow I don't think redownloading the SDK will help. Especially if you just rebuilt it to add the change I suggested (sorry if I didn't make that clear... you have to make the change and rebuild the SDK from source, or the change will have no effect).

    At this point I would start adding debug output lines to the SDK to find out exactly what code path is being followed. For instance, in renderPrimitives in the CAPI_GL_DistortionRenderer.cpp file:


    if (indices) {
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer);
    glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    } else {
    glDrawArrays(prim, 0, count);
    }


    You need to find out which path is being taken here. If it's glDrawArrays() then that means the pointer that populates indices is somehow getting destroyed or never initialized. If it is calling


    You could do something like this:

    if (indices) {
    std::cout << "Binding index buffer " << ((Buffer*)indices)->GLBuffer << std::endl;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer);
    std::cout << "Calling draw elements" << std::endl;
    glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    } else {
    std::cout << "Calling draw arrays" << std::endl;
    glDrawArrays(prim, 0, count);
    }


    If you try that you'll probably need to include <iostream> as one of the headers near the top of the file. You might also get better luck with OutputDebugString instead of std::cout, depending on your development environment.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Up and Coming
    May 1, 2014
    "jherico" wrote:
    If you try that you'll probably need to include <iostream> as one of the headers near the top of the file. You might also get better luck with OutputDebugString instead of std::cout, depending on your development environment.


    I am using VC++ 2013; I am tring to make changes to LibOVR and getting that build going but I run into these errors:


    Error 1 error C1083: Cannot open include file: '../Shaders/Distortion_vs_refl.h': No such file or directory (..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp) e:\oculus rift\oculussdk31\libovr\src\capi\d3d1x\CAPI_D3D1X_DistortionRenderer.cpp 34 1 LibOVR
    Error 2 error C1083: Cannot open include file: '../Shaders/Distortion_vs_refl.h': No such file or directory (..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp) e:\oculus rift\oculussdk31\libovr\src\capi\d3d1x\CAPI_D3D1X_DistortionRenderer.cpp 34 1 LibOVR



    I checked and I don't have those files.

    So I can't get the build of LibOVR with those debug statements.

    I am using the base, no bullshit, OculusVR 3.1 environment.

    Thoughts? Is there some bug that we need to have Oculus VR to look at for OpenGL 4+ on AMD systems?

    This seems asinine that there isn't a base modern OpenGL codebase that just works for all OpenGL 4.0 systems.

    I am not using some random card; AMD Radeon 290x's are pretty common.
    Up and Coming
    May 2, 2014
    As another test; I editing the example given above as shown below in code to just be the left eye by changing this line:

    for (int l_EyeIndex = 0; l_EyeIndex < ovrEye_Count; l_EyeIndex++)

    to this

    for (int l_EyeIndex = 0; l_EyeIndex < 1; l_EyeIndex++)

    Complete code.


    // GLFWOculusRiftTest
    // (c) cThrough 2014 (Daniel Dekkers)
    // Version 2014050100

    #include <Windows.h>
    #include <GL/glew.h>
    #define GLFW_EXPOSE_NATIVE_WIN32
    #define GLFW_EXPOSE_NATIVE_WGL
    #include <GLFW/glfw3.h>
    #include <GLFW/glfw3native.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <OVR_CAPI.h>
    #include <OVR_CAPI_GL.h>
    #include <OVR.h>

    const bool l_FullScreen = false;

    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;

    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_Key == GLFW_KEY_ESCAPE && p_Action == GLFW_PRESS)
    glfwSetWindowShouldClose(p_Window, GL_TRUE);
    }

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

    static void WindowSizeCallback(GLFWwindow* p_Window, int p_Width, int p_Height)
    {
    l_Cfg.OGL.Header.RTSize.w = p_Width;
    l_Cfg.OGL.Header.RTSize.h = p_Height;

    int l_RenderCaps = 0;
    int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    ovrEyeRenderDesc l_EyeRenderDesc[2];
    ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);
    }

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

    static void RenderCubeFixedFunction(void)
    {
    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);
    glEnd();

    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);
    glEnd();

    glBegin(GL_QUADS);
    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);
    glEnd();

    glBegin(GL_QUADS);
    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);
    glEnd();

    glBegin(GL_QUADS);
    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();

    glBegin(GL_QUADS);
    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();
    }

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

    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);
    }

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

    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);

    // Some (stationary) lights...
    GLfloat l_Light0Position[] = { 5.0f, 6.0f, 3.0f, 0.0f };
    GLfloat l_Light0Diffuse[] = { 1.0f, 0.8f, 0.6f, 1.0f };
    glLightfv(GL_LIGHT0, GL_POSITION, l_Light0Position);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, l_Light0Diffuse);
    glEnable(GL_LIGHT0);

    GLfloat l_Light1Position[] = { -5.0f, -6.0f, 5.0f, 0.0f };
    GLfloat l_Light1Diffuse[] = { 0.6f, 0.8f, 1.0f, 1.0f };
    glLightfv(GL_LIGHT1, GL_POSITION, l_Light1Position);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, l_Light1Diffuse);
    glEnable(GL_LIGHT1);

    // 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);
    }

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

    int main(void)
    {
    // Initialize LibOVR...
    ovr_Initialize();

    l_Hmd = ovrHmd_Create(0);
    if (!l_Hmd) l_Hmd = ovrHmd_CreateDebug(ovrHmd_DK1);

    ovrHmd_GetDesc(l_Hmd, &l_HmdDesc);

    ovrHmd_StartSensor(l_Hmd, ovrHmdCap_Orientation, 0);

    GLFWwindow* l_Window;

    glfwSetErrorCallback(ErrorCallback);

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

    ovrSizei l_ClientSize;
    if (l_FullScreen)
    {
    l_ClientSize.w = l_HmdDesc.Resolution.w; // 1280 for DK1...
    l_ClientSize.h = l_HmdDesc.Resolution.h; // 800 for DK1...
    // Create a fullscreen window with the Oculus Rift resolution...

    l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", glfwGetPrimaryMonitor(), NULL);
    }
    else
    {
    l_ClientSize.w = 640;
    l_ClientSize.h = 480;
    // Create a window with the size of your likings...
    glfwWindowHint(GLFW_SAMPLES, 4);
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
    }

    if (!l_Window)
    {
    glfwTerminate();
    exit(EXIT_FAILURE);
    }

    // Print the OpenGL version we are using...
    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_Profile == GLFW_OPENGL_COMPAT_PROFILE) printf("GLFW_OPENGL_COMPAT_PROFILE\n"); else printf("GLFW_OPENGL_CORE_PROFILE\n");

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

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

    // Don't forget to initialize Glew...
    GLenum l_Result = glewInit();
    if (l_Result != GLEW_OK)
    {
    printf("glewInit() error.\n");
    exit(EXIT_FAILURE);
    }

    // We will do some offscreen rendering, setup FBO...
    ovrSizei l_TextureSizeLeft = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Left, l_HmdDesc.DefaultEyeFov[0], 1.0f);
    ovrSizei l_TextureSizeRight = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Right, l_HmdDesc.DefaultEyeFov[1], 1.0f);
    ovrSizei l_TextureSize;
    l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    l_TextureSize.h = (l_TextureSizeLeft.h>l_TextureSizeRight.h ? l_TextureSizeLeft.h : l_TextureSizeRight.h);

    // Create FBO...
    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, l_TextureSize.w, l_TextureSize.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, l_TextureSize.w, l_TextureSize.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);

    // Oculus Rift eye configurations...
    l_Eyes[0].Eye = ovrEye_Left;
    l_Eyes[1].Eye = ovrEye_Right;
    l_Eyes[0].Fov = l_HmdDesc.DefaultEyeFov[0];
    l_Eyes[1].Fov = l_HmdDesc.DefaultEyeFov[1];
    l_Eyes[0].TextureSize.w = l_TextureSize.w;
    l_Eyes[0].TextureSize.h = l_TextureSize.h;
    l_Eyes[1].TextureSize.w = l_TextureSize.w;
    l_Eyes[1].TextureSize.h = l_TextureSize.h;
    l_Eyes[0].RenderViewport.Pos.x = 0;
    l_Eyes[0].RenderViewport.Pos.y = 0;
    l_Eyes[1].RenderViewport.Pos.x = (l_TextureSize.w + 1) / 2;
    l_Eyes[1].RenderViewport.Pos.y = 0;
    l_Eyes[0].RenderViewport.Size.w = l_TextureSize.w / 2;
    l_Eyes[0].RenderViewport.Size.h = l_TextureSize.h;
    l_Eyes[1].RenderViewport.Size.w = l_Eyes[0].RenderViewport.Size.w;
    l_Eyes[1].RenderViewport.Size.h = l_Eyes[0].RenderViewport.Size.h;

    l_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    l_Cfg.OGL.Header.Multisample = 0;
    l_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
    l_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
    l_Cfg.OGL.WglContext = glfwGetWGLContext(l_Window);
    l_Cfg.OGL.Window = glfwGetWin32Window(l_Window);
    l_Cfg.OGL.GdiDc = GetDC(l_Cfg.OGL.Window);

    int l_RenderCaps = 0;
    int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    ovrEyeRenderDesc l_EyeRenderDesc[2];
    ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);

    ovrGLTexture l_EyeTexture[2];
    l_EyeTexture[0].OGL.Header.API = ovrRenderAPI_OpenGL;
    l_EyeTexture[0].OGL.Header.TextureSize.w = l_TextureSize.w;
    l_EyeTexture[0].OGL.Header.TextureSize.h = l_TextureSize.h;
    l_EyeTexture[0].OGL.Header.RenderViewport = l_Eyes[0].RenderViewport;
    l_EyeTexture[0].OGL.TexId = l_TextureId;

    // Right eye uses the same texture, but a different rendering viewport...
    l_EyeTexture[1] = l_EyeTexture[0];
    l_EyeTexture[1].OGL.Header.RenderViewport = l_Eyes[1].RenderViewport;

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

    GLfloat l_SpinX;
    GLfloat l_SpinY;

    while (!glfwWindowShouldClose(l_Window))
    {
    l_SpinX = (GLfloat)fmod(glfwGetTime()*17.0, 360.0);
    l_SpinY = (GLfloat)fmod(glfwGetTime()*23.0, 360.0);

    ovrFrameTiming m_HmdFrameTiming = ovrHmd_BeginFrame(l_Hmd, 0);

    // Bind the FBO...
    glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);
    // Clear...
    glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (int l_EyeIndex = 0; l_EyeIndex < 1; l_EyeIndex++)
    {
    ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder[l_EyeIndex];
    ovrPosef l_EyePose = ovrHmd_BeginEyeRender(l_Hmd, l_Eye);

    glViewport(l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.x, // StartX
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.y, // StartY
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.w, // Width
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.h // Height
    );

    // Get Projection and ModelView matrici from the device...
    OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
    l_EyeRenderDesc[l_Eye].Desc.Fov, 0.3f, 100.0f, true);
    OVR::Quatf l_Orientation = OVR::Quatf(l_EyePose.Orientation);
    OVR::Matrix4f l_ModelViewMatrix = OVR::Matrix4f(l_Orientation.Inverted());

    // Pass matrici on to OpenGL...
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMultMatrixf(&(l_ProjectionMatrix.Transposed().M[0][0]));
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    // Translate for specific eye based on IPD...
    glTranslatef(l_EyeRenderDesc[l_Eye].ViewAdjust.x,
    l_EyeRenderDesc[l_Eye].ViewAdjust.y,
    l_EyeRenderDesc[l_Eye].ViewAdjust.z);
    // Multiply with orientation retrieved from sensor...
    glMultMatrixf(&(l_ModelViewMatrix.Transposed().M[0][0]));
    // Move back a bit to show scene in front of us...
    glTranslatef(0.0f, 0.0f, -2.0f);
    // 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();

    ovrHmd_EndEyeRender(l_Hmd, l_Eye, l_EyePose, &l_EyeTexture[l_Eye].Texture);
    }

    // Unbind the FBO, back to normal drawing...
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glDisable(GL_CULL_FACE); // Oculus wants CW orientations, avoid the problem by turning of culling...
    glDisable(GL_DEPTH_TEST); // Nothing is drawn with depth test on...
    ovrHmd_EndFrame(l_Hmd);
    glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind GL_ARRAY_BUFFER for my vertex arrays own to work...
    glEnable(GL_CULL_FACE); // Turn back on...
    glEnable(GL_DEPTH_TEST); // Turn back on...
    glClearDepth(1); // Oculus set this to 0 (the near plane), return to normal...
    glUseProgramObjectARB(0); // Oculus shader is still active, turn it off...

    glfwPollEvents();
    }

    glfwDestroyWindow(l_Window);

    glfwTerminate();

    ovrHmd_Destroy(l_Hmd);
    ovr_Shutdown();

    exit(EXIT_SUCCESS);
    }


    Results:

    Up and Coming
    May 2, 2014
    And now, the right eye:

    I editing the example given above as shown below in code by changing this line:

    for (int l_EyeIndex = 0; l_EyeIndex < ovrEye_Count; l_EyeIndex++)

    to this

    for (int l_EyeIndex = 1; l_EyeIndex < ovrEye_Count; l_EyeIndex++)

    Complete code.


    // GLFWOculusRiftTest
    // (c) cThrough 2014 (Daniel Dekkers)
    // Version 2014050100

    #include <Windows.h>
    #include <GL/glew.h>
    #define GLFW_EXPOSE_NATIVE_WIN32
    #define GLFW_EXPOSE_NATIVE_WGL
    #include <GLFW/glfw3.h>
    #include <GLFW/glfw3native.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <OVR_CAPI.h>
    #include <OVR_CAPI_GL.h>
    #include <OVR.h>

    const bool l_FullScreen = false;

    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;

    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_Key == GLFW_KEY_ESCAPE && p_Action == GLFW_PRESS)
    glfwSetWindowShouldClose(p_Window, GL_TRUE);
    }

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

    static void WindowSizeCallback(GLFWwindow* p_Window, int p_Width, int p_Height)
    {
    l_Cfg.OGL.Header.RTSize.w = p_Width;
    l_Cfg.OGL.Header.RTSize.h = p_Height;

    int l_RenderCaps = 0;
    int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    ovrEyeRenderDesc l_EyeRenderDesc[2];
    ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);
    }

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

    static void RenderCubeFixedFunction(void)
    {
    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);
    glEnd();

    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);
    glEnd();

    glBegin(GL_QUADS);
    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);
    glEnd();

    glBegin(GL_QUADS);
    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);
    glEnd();

    glBegin(GL_QUADS);
    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();

    glBegin(GL_QUADS);
    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();
    }

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

    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);
    }

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

    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);

    // Some (stationary) lights...
    GLfloat l_Light0Position[] = { 5.0f, 6.0f, 3.0f, 0.0f };
    GLfloat l_Light0Diffuse[] = { 1.0f, 0.8f, 0.6f, 1.0f };
    glLightfv(GL_LIGHT0, GL_POSITION, l_Light0Position);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, l_Light0Diffuse);
    glEnable(GL_LIGHT0);

    GLfloat l_Light1Position[] = { -5.0f, -6.0f, 5.0f, 0.0f };
    GLfloat l_Light1Diffuse[] = { 0.6f, 0.8f, 1.0f, 1.0f };
    glLightfv(GL_LIGHT1, GL_POSITION, l_Light1Position);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, l_Light1Diffuse);
    glEnable(GL_LIGHT1);

    // 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);
    }

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

    int main(void)
    {
    // Initialize LibOVR...
    ovr_Initialize();

    l_Hmd = ovrHmd_Create(0);
    if (!l_Hmd) l_Hmd = ovrHmd_CreateDebug(ovrHmd_DK1);

    ovrHmd_GetDesc(l_Hmd, &l_HmdDesc);

    ovrHmd_StartSensor(l_Hmd, ovrHmdCap_Orientation, 0);

    GLFWwindow* l_Window;

    glfwSetErrorCallback(ErrorCallback);

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

    ovrSizei l_ClientSize;
    if (l_FullScreen)
    {
    l_ClientSize.w = l_HmdDesc.Resolution.w; // 1280 for DK1...
    l_ClientSize.h = l_HmdDesc.Resolution.h; // 800 for DK1...
    // Create a fullscreen window with the Oculus Rift resolution...

    l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", glfwGetPrimaryMonitor(), NULL);
    }
    else
    {
    l_ClientSize.w = 640;
    l_ClientSize.h = 480;
    // Create a window with the size of your likings...
    glfwWindowHint(GLFW_SAMPLES, 4);
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
    }

    if (!l_Window)
    {
    glfwTerminate();
    exit(EXIT_FAILURE);
    }

    // Print the OpenGL version we are using...
    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_Profile == GLFW_OPENGL_COMPAT_PROFILE) printf("GLFW_OPENGL_COMPAT_PROFILE\n"); else printf("GLFW_OPENGL_CORE_PROFILE\n");

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

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

    // Don't forget to initialize Glew...
    GLenum l_Result = glewInit();
    if (l_Result != GLEW_OK)
    {
    printf("glewInit() error.\n");
    exit(EXIT_FAILURE);
    }

    // We will do some offscreen rendering, setup FBO...
    ovrSizei l_TextureSizeLeft = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Left, l_HmdDesc.DefaultEyeFov[0], 1.0f);
    ovrSizei l_TextureSizeRight = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Right, l_HmdDesc.DefaultEyeFov[1], 1.0f);
    ovrSizei l_TextureSize;
    l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    l_TextureSize.h = (l_TextureSizeLeft.h>l_TextureSizeRight.h ? l_TextureSizeLeft.h : l_TextureSizeRight.h);

    // Create FBO...
    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, l_TextureSize.w, l_TextureSize.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, l_TextureSize.w, l_TextureSize.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);

    // Oculus Rift eye configurations...
    l_Eyes[0].Eye = ovrEye_Left;
    l_Eyes[1].Eye = ovrEye_Right;
    l_Eyes[0].Fov = l_HmdDesc.DefaultEyeFov[0];
    l_Eyes[1].Fov = l_HmdDesc.DefaultEyeFov[1];
    l_Eyes[0].TextureSize.w = l_TextureSize.w;
    l_Eyes[0].TextureSize.h = l_TextureSize.h;
    l_Eyes[1].TextureSize.w = l_TextureSize.w;
    l_Eyes[1].TextureSize.h = l_TextureSize.h;
    l_Eyes[0].RenderViewport.Pos.x = 0;
    l_Eyes[0].RenderViewport.Pos.y = 0;
    l_Eyes[1].RenderViewport.Pos.x = (l_TextureSize.w + 1) / 2;
    l_Eyes[1].RenderViewport.Pos.y = 0;
    l_Eyes[0].RenderViewport.Size.w = l_TextureSize.w / 2;
    l_Eyes[0].RenderViewport.Size.h = l_TextureSize.h;
    l_Eyes[1].RenderViewport.Size.w = l_Eyes[0].RenderViewport.Size.w;
    l_Eyes[1].RenderViewport.Size.h = l_Eyes[0].RenderViewport.Size.h;

    l_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    l_Cfg.OGL.Header.Multisample = 0;
    l_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
    l_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
    l_Cfg.OGL.WglContext = glfwGetWGLContext(l_Window);
    l_Cfg.OGL.Window = glfwGetWin32Window(l_Window);
    l_Cfg.OGL.GdiDc = GetDC(l_Cfg.OGL.Window);

    int l_RenderCaps = 0;
    int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    ovrEyeRenderDesc l_EyeRenderDesc[2];
    ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);

    ovrGLTexture l_EyeTexture[2];
    l_EyeTexture[0].OGL.Header.API = ovrRenderAPI_OpenGL;
    l_EyeTexture[0].OGL.Header.TextureSize.w = l_TextureSize.w;
    l_EyeTexture[0].OGL.Header.TextureSize.h = l_TextureSize.h;
    l_EyeTexture[0].OGL.Header.RenderViewport = l_Eyes[0].RenderViewport;
    l_EyeTexture[0].OGL.TexId = l_TextureId;

    // Right eye uses the same texture, but a different rendering viewport...
    l_EyeTexture[1] = l_EyeTexture[0];
    l_EyeTexture[1].OGL.Header.RenderViewport = l_Eyes[1].RenderViewport;

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

    GLfloat l_SpinX;
    GLfloat l_SpinY;

    while (!glfwWindowShouldClose(l_Window))
    {
    l_SpinX = (GLfloat)fmod(glfwGetTime()*17.0, 360.0);
    l_SpinY = (GLfloat)fmod(glfwGetTime()*23.0, 360.0);

    ovrFrameTiming m_HmdFrameTiming = ovrHmd_BeginFrame(l_Hmd, 0);

    // Bind the FBO...
    glBindFramebuffer(GL_FRAMEBUFFER, l_FBOId);
    // Clear...
    glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for (int l_EyeIndex = 1; l_EyeIndex < ovrEye_Count; l_EyeIndex++)
    {
    ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder[l_EyeIndex];
    ovrPosef l_EyePose = ovrHmd_BeginEyeRender(l_Hmd, l_Eye);

    glViewport(l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.x, // StartX
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.y, // StartY
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.w, // Width
    l_EyeRenderDesc[l_Eye].Desc.RenderViewport.Size.h // Height
    );

    // Get Projection and ModelView matrici from the device...
    OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
    l_EyeRenderDesc[l_Eye].Desc.Fov, 0.3f, 100.0f, true);
    OVR::Quatf l_Orientation = OVR::Quatf(l_EyePose.Orientation);
    OVR::Matrix4f l_ModelViewMatrix = OVR::Matrix4f(l_Orientation.Inverted());

    // Pass matrici on to OpenGL...
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMultMatrixf(&(l_ProjectionMatrix.Transposed().M[0][0]));
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    // Translate for specific eye based on IPD...
    glTranslatef(l_EyeRenderDesc[l_Eye].ViewAdjust.x,
    l_EyeRenderDesc[l_Eye].ViewAdjust.y,
    l_EyeRenderDesc[l_Eye].ViewAdjust.z);
    // Multiply with orientation retrieved from sensor...
    glMultMatrixf(&(l_ModelViewMatrix.Transposed().M[0][0]));
    // Move back a bit to show scene in front of us...
    glTranslatef(0.0f, 0.0f, -2.0f);
    // 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();

    ovrHmd_EndEyeRender(l_Hmd, l_Eye, l_EyePose, &l_EyeTexture[l_Eye].Texture);
    }

    // Unbind the FBO, back to normal drawing...
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glDisable(GL_CULL_FACE); // Oculus wants CW orientations, avoid the problem by turning of culling...
    glDisable(GL_DEPTH_TEST); // Nothing is drawn with depth test on...
    ovrHmd_EndFrame(l_Hmd);
    glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind GL_ARRAY_BUFFER for my vertex arrays own to work...
    glEnable(GL_CULL_FACE); // Turn back on...
    glEnable(GL_DEPTH_TEST); // Turn back on...
    glClearDepth(1); // Oculus set this to 0 (the near plane), return to normal...
    glUseProgramObjectARB(0); // Oculus shader is still active, turn it off...

    glfwPollEvents();
    }

    glfwDestroyWindow(l_Window);

    glfwTerminate();

    ovrHmd_Destroy(l_Hmd);
    ovr_Shutdown();

    exit(EXIT_SUCCESS);
    }


    Results:

    Up and Coming
    May 2, 2014
    So the question is what is vastly different from one eye to another in the core code for OpenGL?
    Inspiring
    May 2, 2014
    "ckoeber" wrote:
    So the question is what is vastly different from one eye to another in the core code for OpenGL?


    Nothing. When you render one eye or the other, you're writing to a texture. when you call endframe it renders both textures to the distortion meshes. For some reason one of your meshes is either messed up or it being rendered incorrectly because of something strange in the OpenGL state.

    If you want to try it, you can clone my SDK repository which has solved the missing headers problem by removing all the DirectX stuff. However, it uses CMake for building, and all the CAPI stuff has been extracted from the core SDK, so it may not be trivial to get it working for you.

    I'll see if I can test your code on my system this evening.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Up and Coming
    May 2, 2014
    Thank you for all of your help thus far.

    Hope we can get a base, modern OpenGL project for the Oculus Rift that works on Nvidia and AMD cards.