Simple OpenGL example with GLFW, GLEW and OculusSDK 0.3.1 — Oculus
Welcome to the Oculus Developer Forums!

Your participation on the forum is subject to the Oculus Code of Conduct.

In general, please be respectful and kind. If you violate the Oculus Code of Conduct, your access to the developer forums may be revoked at the discretion of Oculus staff.

Simple OpenGL example with GLFW, GLEW and OculusSDK 0.3.1

DoZo1971DoZo1971 Posts: 97
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);
}
«13

Comments

  • jhericojherico Posts: 1,419
    Nexus 6
    Good job on this. It's nice to see the whole set of functionality in one file like that.

    You're using an odd mix of new OpenGL and deprecated code, but that's understandable considering the overhead of putting shaders and vertex buffers, index buffers and vertex arrays.

    I would suggest you consider making the cube smaller and moving it closer to the user, so that the per-eye view offset is more apparent.
          float ipd = abs(l_EyeRenderDesc[l_Eye].ViewAdjust.x * 2);
          static const float SIZE = ipd * 5;
          static float A[6][3] = {
            { 0, 0, SIZE },
            { 0, SIZE, 0 },
            { SIZE, 0, 0 },
            { 0, 0, -SIZE },
            { 0, -SIZE, 0 },
            { -SIZE, 0, 0 },
          };
          for (int i = 0; i < 6; ++i) {
            glPushMatrix();
            // Move back a bit to show scene in front of us...
            glTranslatef(A[i][0], A[i][1], A[i][2]);
            // Make the cube spin...
            glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
            glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
            // Render...
            RenderCube(ipd);
            glPopMatrix();
          }
    

    I'd also suggest that you color the sides of the cube to increase the contrast.

    In SetOpenGLState
      ...
      glEnable(GL_COLOR_MATERIAL);
      ...
    

    And in RenderCube()
      glColor3f(1, 0, 0);
      glBegin(GL_QUADS);
      ...
      ... and a different color for each face
    
    Brad Davis - Developer for High Fidelity
    Co-author of Oculus Rift in Action

  • DoZo1971DoZo1971 Posts: 97
    You're using an odd mix of new OpenGL and deprecated code, but that's understandable considering the overhead of putting shaders and vertex buffers, index buffers and vertex arrays.

    Some good old fixed function never harmed anyone. ;-)
    Although the glBegin()/glEnd() stuff is really bad. I think I'll combine with:
    making the cube smaller and moving it closer to the user, so that the per-eye view offset is more apparent.

    ... and make a grid of (smaller) cubes surrounding the viewer. Some near, some far. I'll put that geometry in vertex arrays.

    Thanks,
    Daniel
  • ckoeberckoeber Posts: 68
    Hello,

    When I used the posted example code, the project compiles fine in VC++ 2013 but I get an access violation on the noted part below.

    Any idea why?

    Thank you for your time.
    
    [...]
    
            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...
    /*
    
    Access Violation here!!!
    
    */
    
    	glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, l_TextureId, 0);
    
    /*
    
    End Access Violation
    
    */
    
    	// Set the list of draw buffers...
    	GLenum l_GLDrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
    	glDrawBuffers(1, l_GLDrawBuffers); // "1" is the size of DrawBuffers
    
    [...]
    
    
  • DoZo1971DoZo1971 Posts: 97
    Did Glew initialize properly?

    You could change
    // Don't forget to initialize Glew...
    glewInit();
    
    to
    // Don't forget to initialize Glew...
    GLenum l_Result = glewInit();
    if (l_Result!=GLEW_OK)	
    {
    	printf("glewInit() error.\n");
    	exit(EXIT_FAILURE);
    }
    
    and check.
  • Which version of glfw are you using??

    It does not work with the 3.x version!
  • DoZo1971DoZo1971 Posts: 97
    I'm using glfw-3.0.4. Windows 7, 32-bit, Visual Studio 2012.
    Could you be a bit more specific than "It's not working"?
  • ckoeberckoeber Posts: 68
    My problem from earlier is that, as seac02developer mentioned, this doesn't work on the OpenGL 3.1 specification.

    So I switched to an OpenGL 4.4 supporting AMD R9 280x card but now I get the following screen where the code executes but it doesn't look good at all.

    See the attached image.

    What gives?

    QeHihk9.png
  • DoZo1971DoZo1971 Posts: 97
    Interesting image you've got there.
    Did you make the GLFWwindow windowed? It should be full screen, without window decorations.
    Is this a complete screenshot? It looks like the right 1/4 part is missing.
    There is some distortion going on, the right part actually looks ok. Don't know what is happening to the "left eye" part.

    On my AMD machine, ovrHmd_Configure(...) asserts when it is trying to compile the shaders, and I really don't want to edit their code. It works for me on my nVidia machine though, with OpenGL 4.3.

    If you take the code below, you can toggle fullscreen or not. And resize. Maybe then it is more visible what it is going on:
    #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>
    
    const bool l_FullScreen = true;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;
    
    // =============================================================================
    
    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 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();
    
    	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...
    		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);
    	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...
    	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
    
    	// 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<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, -0.5f);
    			// Make the cube spin...
    			glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    			glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    			// Render...
    			RenderCube(0.2f);
    
    			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 its 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);
    }
    
  • DoZo1971DoZo1971 Posts: 97
    edited April 2014
    This is what you *should* see (in windowed mode).
    The image is a bit too high, something going on between GLFW and Oculus and window decorations. In full screen mode it is centered correctly.

  • ckoeberckoeber Posts: 68
    Thank you so much! I will try your code out.

    Also, do you have an idea on how one would go about making this OpenGL 3.1 compatible?

    I tried changing this line
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, l_TextureId, 0);
    

    To this line
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, l_TextureId, 0);
    

    But all I get is a blank screen.

    Anything else I can do?
  • ckoeberckoeber Posts: 68
    DoZo1971 wrote:
    This is what you *should* see (in windowed mode).
    The image is a bit too high, something going on between GLFW and Oculus and window decorations. In full screen mode it is centered correctly.

    I tried this but the same results.

    AMD's OpenGL implementation is different?
  • ckoeberckoeber Posts: 68
    DoZo1971 wrote:
    Interesting image you've got there.
    Did you make the GLFWwindow windowed? It should be full screen, without window decorations.
    Is this a complete screenshot? It looks like the right 1/4 part is missing.
    There is some distortion going on, the right part actually looks ok. Don't know what is happening to the "left eye" part.

    On my AMD machine, ovrHmd_Configure(...) asserts when it is trying to compile the shaders, and I really don't want to edit their code. It works for me on my nVidia machine though, with OpenGL 4.3.

    If you take the code below, you can toggle fullscreen or not. And resize. Maybe then it is more visible what it is going on:

    Working with this code now, will send another update when done.
  • ckoeberckoeber Posts: 68
    So I am trying out some new things with the above code and I am running into some new issues but I am not sure why that is.

    I wanted to implement toggle functionality in the code so when you hit the "T" key the window resizes.

    Here is my header (OpenGLOculusRift.h):
    #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>
    
    enum StandardWindowSizes {
    	Small_Window,
    	Medium_Window,
    	Large_Window,
    	Full_Screen
    };
    
    static void ErrorCallback(int p_Error, const char* p_Description);
    
    static void KeyCallback(GLFWwindow* p_Window, int p_Key, int p_Scancode, int p_Action, int p_Mods);
    
    static void RenderCube(float p_Size);
    
    static void SetOpenGLState(void);
    
    static void WindowSizeCallback(GLFWwindow* p_Window, int p_Width, int p_Height);
    
    int _tmain(int argc, _TCHAR* argv[]);
    
    static void CreateOpenGLWindow();
    
    static void OculusRiftOpenGLInitialization();
    
    static void OpenGLWindowMainDisplay();
    
    static void RecreateOpenGLWindow();
    
    StandardWindowSizes CurrentWindowSize;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;
    ovrSizei l_ClientSize;
    GLFWwindow* Main_Window;
    GLuint MainFrameBufferObjectID;
    GLuint MainTextureID;
    ovrEyeRenderDesc l_EyeRenderDesc[2];
    ovrGLTexture l_EyeTexture[2];
    GLfloat l_SpinX;
    GLfloat l_SpinY;
    int OpenGLMajor;
    int OpenGLMinor;
    
    bool WindowBeingRecreated;
    

    and here is the main body:
    
    // OpenGLOculusRift.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <Windows.h>
    
    #include "OpenGLOculusRift.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);
    	}
    	else if (p_Key == GLFW_KEY_T && p_Action == GLFW_PRESS) {
    		switch (CurrentWindowSize) {
    		/*case StandardWindowSizes::Full_Screen:
    			CurrentWindowSize = StandardWindowSizes::Small_Window;
    			RecreateOpenGLWindow();
    			break;
    		*/
    		case StandardWindowSizes::Small_Window:
    			CurrentWindowSize = StandardWindowSizes::Medium_Window;
    			RecreateOpenGLWindow();
    			break;
    		case StandardWindowSizes::Medium_Window:
    			CurrentWindowSize = StandardWindowSizes::Large_Window;
    			RecreateOpenGLWindow();
    		case StandardWindowSizes::Large_Window:
    			CurrentWindowSize = StandardWindowSizes::Small_Window;
    			RecreateOpenGLWindow();
    		default:
    			CurrentWindowSize = StandardWindowSizes::Small_Window;
    			RecreateOpenGLWindow();
    			break;
    		}
    	}
    		
    }
    
    // =============================================================================
    
    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);
    }
    
    // =============================================================================
    
    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);
    }
    
    // =============================================================================
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	/*
    
    	Hide the console window.
    
    	*/
    
    #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
    	FreeConsole();
    #else
    	/*
    	
    	Same principle for Linux
    	
    	*/
    #endif
    
    	/*
    	
    	Let's start off with a small window.
    	
    	*/
    
    	CurrentWindowSize = StandardWindowSizes::Small_Window;
    
    	/*
    	
    	Let's the rendering subsystem know not to render anything while the window is being resized.
    	
    	*/
    
    	WindowBeingRecreated = true;
    
    	// 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);
    
    	glfwSetErrorCallback(ErrorCallback);
    
    	/*
    	
    	Initialize OpenGL and GLFW
    	
    	*/
    
    	if (!glfwInit()) exit(EXIT_FAILURE);
    
    	/*
    	
    	End Initialization.
    	
    	*/
    	
    	CreateOpenGLWindow();
    	
    
    	// Print the OpenGL version we are using...
    	OpenGLMajor = glfwGetWindowAttrib(Main_Window, GLFW_CONTEXT_VERSION_MAJOR);
    	OpenGLMinor = glfwGetWindowAttrib(Main_Window, GLFW_CONTEXT_VERSION_MINOR);
    	printf("OpenGL: %d.%d\n", OpenGLMajor, OpenGLMinor);
    
    	OculusRiftOpenGLInitialization();
    
    	while (!glfwWindowShouldClose(Main_Window))
    	{
    		OpenGLWindowMainDisplay();
    
    		glfwPollEvents();
    	}
    
    	glfwDestroyWindow(Main_Window);
    
    	glfwTerminate();
    
    	ovrHmd_Destroy(l_Hmd);
    	ovr_Shutdown();
    
    	exit(EXIT_SUCCESS);
    }
    
    static void CreateOpenGLWindow() {
    	
    	switch (CurrentWindowSize) {
    	case StandardWindowSizes::Full_Screen:
    		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...
    		Main_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", glfwGetPrimaryMonitor(), NULL);
    		break;
    	case StandardWindowSizes::Small_Window:
    		l_ClientSize.w = 640;
    		l_ClientSize.h = 480;
    		Main_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
    		break;
    	case StandardWindowSizes::Medium_Window:
    		l_ClientSize.w = 1024;
    		l_ClientSize.h = 768;
    		Main_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
    		break;
    	case StandardWindowSizes::Large_Window:
    		l_ClientSize.w = 1360;
    		l_ClientSize.h = 768;
    		Main_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
    		break;
    	default:
    		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...
    		Main_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", glfwGetPrimaryMonitor(), NULL);
    		break;
    	}
    
    	if (!Main_Window)
    	{
    		glfwTerminate();
    		exit(EXIT_FAILURE);
    	}
    
    	// Make the context current for this window...
    	glfwMakeContextCurrent(Main_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);
    	}
    
    	glfwSetKeyCallback(Main_Window, KeyCallback);
    	glfwSetWindowSizeCallback(Main_Window, WindowSizeCallback);
    }
    
    static void OculusRiftOpenGLInitialization() {
    	// 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...
    	glGenFramebuffers(1, &MainFrameBufferObjectID);
    	glBindFramebuffer(GL_FRAMEBUFFER, MainFrameBufferObjectID);
    
    	
    	glGenTextures(1, &MainTextureID);
    	// "Bind" the newly created texture : all future texture functions will modify this texture...
    	glBindTexture(GL_TEXTURE_2D, MainTextureID);
    	// 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);
    
    	/*
    	
    	Switch based on OpenGL version.
    	
    	*/
    
    	if (OpenGLMajor < 4 && OpenGLMinor < 2) {
    		/*
    		
    		Intel and older drivers.
    		
    		*/
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, MainTextureID, 0);
    	}
    	else {
    		/*
    		
    		Newer systems.
    		
    		*/
    		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, MainTextureID, 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...
    	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(Main_Window);
    	l_Cfg.OGL.Window = glfwGetWin32Window(Main_Window);
    	l_Cfg.OGL.GdiDc = GetDC(l_Cfg.OGL.Window);
    
    	int l_RenderCaps = 0;
    	int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    	
    	ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);
    
    	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 = MainTextureID;
    
    	// 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;
    }
    
    static void OpenGLWindowMainDisplay() {
    
    	if (WindowBeingRecreated == false) {
    		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, MainFrameBufferObjectID);
    		// 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, -0.5f);
    			// Make the cube spin...
    			glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    			glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    			// Render...
    			RenderCube(0.2f);
    
    			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 its work (-sigh-)...
    		glEnable(GL_CULL_FACE);
    		glEnable(GL_DEPTH_TEST);
    		glClearDepth(1);
    		glUseProgramObjectARB(0);
    	}
    }
    
    static void RecreateOpenGLWindow() {
    
    	/*
    	
    	Tells rendering function OpenGLWindowMainDisplay not to process anything while Window being resized.
    	
    	*/
    
    	WindowBeingRecreated = true;
    	
    	glfwDestroyWindow(Main_Window);
    
    	CreateOpenGLWindow();
    
    	OculusRiftOpenGLInitialization();
    
    	/*
    
    	Process normally now.
    
    	*/
    	
    	WindowBeingRecreated = false;
    
    }
    
  • ckoeberckoeber Posts: 68
    So the problem with the above code is that after a few toggles the following line
    
    ovrHmd_EndFrame(l_Hmd);
    
    

    generates an error.

    In addition, nothing renders. Only a cleared screen is shown.

    Any idea of what I am doing wrong?

    Thank you.
  • ckoeberckoeber Posts: 68
    I tried your base code below with no modifications as I was trying to do before.

    This is what I get.

    Only on AMD graphics cards?

    Anyone else seeing this?

    One_Eye_Off.png
    DoZo1971 wrote:
    Interesting image you've got there.
    Did you make the GLFWwindow windowed? It should be full screen, without window decorations.
    Is this a complete screenshot? It looks like the right 1/4 part is missing.
    There is some distortion going on, the right part actually looks ok. Don't know what is happening to the "left eye" part.

    On my AMD machine, ovrHmd_Configure(...) asserts when it is trying to compile the shaders, and I really don't want to edit their code. It works for me on my nVidia machine though, with OpenGL 4.3.

    If you take the code below, you can toggle fullscreen or not. And resize. Maybe then it is more visible what it is going on:
    #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>
    
    const bool l_FullScreen = true;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;
    
    // =============================================================================
    
    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 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();
    
    	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...
    		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);
    	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...
    	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
    
    	// 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<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, -0.5f);
    			// Make the cube spin...
    			glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    			glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    			// Render...
    			RenderCube(0.2f);
    
    			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 its 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);
    }
    
  • DoZo1971DoZo1971 Posts: 97
    Hi,

    What you see on the left eye part is the actual mesh that is being rendered. But for some reason the winding seems all wrong. Triangles are drawn alternately. And then some big colored triangles all over the place, which looks as an undefined somewhere. I would guess it is in the distortion shader (and not, for instance, in the FBO setup, although it would be good to test with stereoscopic rendering but without distortion).

    What if you change the render order of the two eyes? If you replace
    ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder[l_EyeIndex];
    

    with (quick hack)
    ovrEyeType l_Eye = (l_EyeIndex==0 ? ovrEye_Right : ovrEye_Left);
    

    it should render the right eye first and then the left. Does the right eye now look crippled and the left ok?
    If that would be the case, it has to do with the first run through the loop. Meaning that whatever is wrong is "fixed" in
    the call to ovrHmd_EndEyeRender(...).

    Another far-fetched idea: if you place a glFlush() right before ovrHmd_EndFrame(l_Hmd);
    glDisable(GL_DEPTH_TEST);
    glFlush();
    ovrHmd_EndFrame(l_Hmd);
    

    to "make sure" (I know it is far-fetched) that the culling is disabled as well as depth testing.

    Thanks,
    Daniel
  • ckoeberckoeber Posts: 68
    Hello,

    Tried the new code but same thing.

    Here is the complete code:
    
    #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>
    
    const bool l_FullScreen = false;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes[2];
    ovrGLConfig l_Cfg;
    
    // =============================================================================
    
    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 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();
    
    	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...
    		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);
    	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...
    	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
    
    	// 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<ovrEye_Count; l_EyeIndex++)
    		{
    			ovrEyeType l_Eye = (l_EyeIndex == 0 ? ovrEye_Right : ovrEye_Left);
    			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, -0.5f);
    			// Make the cube spin...
    			glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    			glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    			// Render...
    			RenderCube(0.2f);
    
    			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);
    		glFlush();
    		ovrHmd_EndFrame(l_Hmd);
    		// Restore state after Oculus did its 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);
    }
    
    
    

    And here are the results:

    One_Eye_Off_Version2.png
  • DoZo1971DoZo1971 Posts: 97
    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.
    // GLFWFBOTextureTest
    // (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 <math.h>
    
    const bool l_FullScreen = false;
    
    int l_ClientSizeW, l_ClientSizeH;
    
    // =============================================================================
    
    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_ClientSizeW = p_Width;
    	l_ClientSizeH = p_Height;
    }
    
    // =============================================================================
    
    static void PostProcess(size_t p_ClientSizeW, size_t p_ClientSizeH, GLuint p_TextureId)
    {
    	glPushAttrib(GL_TEXTURE_BIT | GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT);
    	glDisable(GL_CULL_FACE);
    	glDisable(GL_COLOR_MATERIAL);
    	glDisable(GL_DEPTH_TEST);
    	glDisable(GL_LIGHTING);
    	glDisable(GL_BLEND);
    	glEnable(GL_TEXTURE_2D);
    
    	// Reset the screen params...
    	glViewport(0, 0, p_ClientSizeW, p_ClientSizeH); 
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    	// Clear the screen...
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	// Make this the current texture...
    	glBindTexture(GL_TEXTURE_2D, p_TextureId);
    
    	// "Left eye"...
    	glBegin(GL_QUADS);
    		glTexCoord2f(0.0f, 0.0f);
    		glVertex3f(-1.0f, -1.0f, 0.0f);
    		glTexCoord2f(0.5f, 0.0f);
    		glVertex3f(0.0f, -1.0f, 0.0f);
    		glTexCoord2f(0.5f, 1.0f);
    		glVertex3f(0.0f, 1.0f, 0.0f);
    		glTexCoord2f(0.0f, 1.0f);
    		glVertex3f(-1.0f, 1.0f, 0.0f);
    	glEnd();
    
    	// "Right eye"...
    	glBegin(GL_QUADS);
    		glTexCoord2f(0.5f, 0.0f);
    		glVertex3f(0.0f, -1.0f, 0.0f);
    		glTexCoord2f(1.0f, 0.0f);
    		glVertex3f(1.0f, -1.0f, 0.0f);
    		glTexCoord2f(1.0f, 1.0f);
    		glVertex3f(1.0f, 1.0f, 0.0f);
    		glTexCoord2f(0.5f, 1.0f);
    		glVertex3f(0.0f, 1.0f, 0.0f);
    	glEnd();
    
    	// Clean up...
    	glBindTexture(GL_TEXTURE_2D, 0);
    	glPopAttrib();
    }
    
    // =============================================================================
    
    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)
    {
    	GLFWwindow* l_Window;
    
    	glfwSetErrorCallback(ErrorCallback);
    
    	if (!glfwInit()) exit(EXIT_FAILURE);
    
    	if (l_FullScreen)
    	{
    		const GLFWvidmode* l_VideoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    		l_ClientSizeW = l_VideoMode->width;
    		l_ClientSizeH = l_VideoMode->height;
    		// Create a fullscreen window with the current resolution...
    		l_Window = glfwCreateWindow(l_ClientSizeW, l_ClientSizeH, "GLFW FBO Texture Test", glfwGetPrimaryMonitor(), NULL);
    	}
    	else
    	{
    		l_ClientSizeW = 640;
    		l_ClientSizeH = 480;
    		// Create a window with the size of your likings...
    		l_Window = glfwCreateWindow(l_ClientSizeW, l_ClientSizeH, "GLFW FBO Texture 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);
    	}
    
    	// Set the size of the FBO we will be rendering to offscreen, can be any size, try a big one...
    	int l_TextureSizeW = 2048;
    	int l_TextureSizeH = 1280;
    
    	// 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_TextureSizeW, l_TextureSizeH, 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_TextureSizeW, l_TextureSizeH);
    	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);
    
    	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);
    
    		// 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);
    
    		glViewport(0,					// StartX
    				   0,					// StartY
    				   l_TextureSizeW/2,	// Width
    				   l_TextureSizeH		// Height
    				  );
    
    		// @TODO Proper projection and modelview matrici for each eye...
    		glMatrixMode(GL_PROJECTION);
    		glLoadIdentity();
    		glFrustum(-0.4f, 0.4f, -0.3f, 0.3f, 0.3f, 10.0f);
    		glMatrixMode(GL_MODELVIEW);
    		glLoadIdentity();
    		glTranslatef(0.0f, 0.0f, -2.0f);
    		glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    		glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    		// Render...
    		RenderCubeFixedFunction();
    
    		glViewport(l_TextureSizeW/2,	// StartX
    				   0,					// StartY
    				   l_TextureSizeW/2,	// Width
    				   l_TextureSizeH		// Height
    				  );
    
    		// @TODO Proper projection and modelview matrici for each eye...
    		glMatrixMode(GL_PROJECTION);
    		glLoadIdentity();
    		glFrustum(-0.4f, 0.4f, -0.3f, 0.3f, 0.3f, 10.0f);
    		glMatrixMode(GL_MODELVIEW);
    		glLoadIdentity();
    		glTranslatef(0.0f, 0.0f, -2.0f);
    		glRotatef(l_SpinX, 1.0f, 0.0f, 0.0f);
    		glRotatef(l_SpinY, 0.0f, 1.0f, 0.0f);
    
    		// Render...
    		RenderCubeVertexArrays();
    		// RenderCubeFixedFunction();
    
    		// Unbind the FBO, back to normal drawing...
    		glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    		PostProcess(l_ClientSizeW, l_ClientSizeH, l_TextureId);
    
            glfwSwapBuffers(l_Window);
    
            glfwPollEvents();
        }
    
        glfwDestroyWindow(l_Window);
    
        glfwTerminate();
    
        exit(EXIT_SUCCESS);
    }
    

    And this is my most recent version of the Oculus example. It won't help your problem but it now uses Vertex Arrays. I'm working on losing the deprecated functions.
    // 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 <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...
    		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<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);
    }
    

    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
  • jhericojherico Posts: 1,419
    Nexus 6
    The fact that the distortion screws up the left eye, but renders the right eye correctly seems to indicate one of several things:
    • Something is messed up in the GL state when you execute endFrame, but is corrected by the work the SDK does to render the distortion mesh. However, whatever is corrected doesn't occur in time for the left eye mesh to be rendered correctly, only the right eye, so presumably it would have to be something called after 'glDrawElements' in the SDK.
    • Somehow the index buffer is getting corrupted or overwritten.
    • Somehow the index buffer inside the distortion mesh object pointer is getting replaced with null. This would cause the renderer to execute glDrawArrays instead of glDrawElements, which would very likely produce something similar to what we're seeing here.

    You might consider seeing if the problem is tied to the 'left eye' or 'first eye rendered'. You can do this by going into the SDK code in CAPI_GL_DistortionRenderer.cpp and find the function void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture).

    Find the line:
        for (int eyeNum = 0; eyeNum < 2; eyeNum++)
    

    and change it to
        for (int eyeNum = 1; eyeNum >= 0; eyeNum--)
    

    This will cause the right eye to render first. If the corruption now appears on the right, then mostly likely my first hypothesis is correct. If it still appears on the left, then something in the left distortion mesh is being corrupted or is missing.
    Brad Davis - Developer for High Fidelity
    Co-author of Oculus Rift in Action

  • ckoeberckoeber Posts: 68
    Thank you very much for your help, jherico.

    I tried your code change but I got the same problem with the same eye. You said this:
    If it still appears on the left, then something in the left distortion mesh is being corrupted or is missing.

    So should I just re-download the SDK? I will try that.
  • ckoeberckoeber Posts: 68
    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:

    Sample_Demo_Direct_X.jpg
  • ckoeberckoeber Posts: 68
    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:

    Simple_FBOTest.png
  • ckoeberckoeber Posts: 68
    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?
  • jhericojherico Posts: 1,419
    Nexus 6
    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

  • ckoeberckoeber Posts: 68
    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.
  • ckoeberckoeber Posts: 68
    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 &lt;Windows.h&gt;
    #include &lt;GL/glew.h&gt;
    #define GLFW_EXPOSE_NATIVE_WIN32
    #define GLFW_EXPOSE_NATIVE_WGL
    #include &lt;GLFW/glfw3.h&gt;
    #include &lt;GLFW/glfw3native.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;stdio.h&gt;
    #include &lt;iostream&gt;
    #include &lt;math.h&gt;
    #include &lt;OVR_CAPI.h&gt;
    #include &lt;OVR_CAPI_GL.h&gt;
    #include &lt;OVR.h&gt;
    
    const bool l_FullScreen = false;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes&#91;2&#93;;
    ovrGLConfig l_Cfg;
    
    GLfloat l_VAPoints&#91;&#93; =
    {
    	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&#91;&#93; =
    {
    	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&#91;&#93; =
    {
    	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&#91;2&#93;;
    	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&#91;&#93; = { 5.0f, 6.0f, 3.0f, 0.0f };
    	GLfloat l_Light0Diffuse&#91;&#93; = { 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&#91;&#93; = { -5.0f, -6.0f, 5.0f, 0.0f };
    	GLfloat l_Light1Diffuse&#91;&#93; = { 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&#91;&#93; = { 0.3f, 0.3f, 0.3f, 1.0f };
    	GLfloat l_MaterialShininess&#91;&#93; = { 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&#91;0&#93;, 1.0f);
    	ovrSizei l_TextureSizeRight = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Right, l_HmdDesc.DefaultEyeFov&#91;1&#93;, 1.0f);
    	ovrSizei l_TextureSize;
    	l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    	l_TextureSize.h = (l_TextureSizeLeft.h&gt;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&#91;1&#93; = { 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&#91;0&#93;.Eye = ovrEye_Left;
    	l_Eyes&#91;1&#93;.Eye = ovrEye_Right;
    	l_Eyes&#91;0&#93;.Fov = l_HmdDesc.DefaultEyeFov&#91;0&#93;;
    	l_Eyes&#91;1&#93;.Fov = l_HmdDesc.DefaultEyeFov&#91;1&#93;;
    	l_Eyes&#91;0&#93;.TextureSize.w = l_TextureSize.w;
    	l_Eyes&#91;0&#93;.TextureSize.h = l_TextureSize.h;
    	l_Eyes&#91;1&#93;.TextureSize.w = l_TextureSize.w;
    	l_Eyes&#91;1&#93;.TextureSize.h = l_TextureSize.h;
    	l_Eyes&#91;0&#93;.RenderViewport.Pos.x = 0;
    	l_Eyes&#91;0&#93;.RenderViewport.Pos.y = 0;
    	l_Eyes&#91;1&#93;.RenderViewport.Pos.x = (l_TextureSize.w + 1) / 2;
    	l_Eyes&#91;1&#93;.RenderViewport.Pos.y = 0;
    	l_Eyes&#91;0&#93;.RenderViewport.Size.w = l_TextureSize.w / 2;
    	l_Eyes&#91;0&#93;.RenderViewport.Size.h = l_TextureSize.h;
    	l_Eyes&#91;1&#93;.RenderViewport.Size.w = l_Eyes&#91;0&#93;.RenderViewport.Size.w;
    	l_Eyes&#91;1&#93;.RenderViewport.Size.h = l_Eyes&#91;0&#93;.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&#91;2&#93;;
    	ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);
    
    	ovrGLTexture l_EyeTexture&#91;2&#93;;
    	l_EyeTexture&#91;0&#93;.OGL.Header.API = ovrRenderAPI_OpenGL;
    	l_EyeTexture&#91;0&#93;.OGL.Header.TextureSize.w = l_TextureSize.w;
    	l_EyeTexture&#91;0&#93;.OGL.Header.TextureSize.h = l_TextureSize.h;
    	l_EyeTexture&#91;0&#93;.OGL.Header.RenderViewport = l_Eyes&#91;0&#93;.RenderViewport;
    	l_EyeTexture&#91;0&#93;.OGL.TexId = l_TextureId;
    
    	// Right eye uses the same texture, but a different rendering viewport...
    	l_EyeTexture&#91;1&#93; = l_EyeTexture&#91;0&#93;;
    	l_EyeTexture&#91;1&#93;.OGL.Header.RenderViewport = l_Eyes&#91;1&#93;.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 &lt; 1; l_EyeIndex++)
    		{
    			ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder&#91;l_EyeIndex&#93;;
    			ovrPosef l_EyePose = ovrHmd_BeginEyeRender(l_Hmd, l_Eye);
    
    			glViewport(l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Pos.x,   // StartX
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Pos.y,   // StartY
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Size.w,   // Width
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Size.h   // Height
    				);
    
    			// Get Projection and ModelView matrici from the device...
    			OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
    				l_EyeRenderDesc&#91;l_Eye&#93;.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&#91;0&#93;&#91;0&#93;));
    			glMatrixMode(GL_MODELVIEW);
    			glLoadIdentity();
    			// Translate for specific eye based on IPD...
    			glTranslatef(l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.x,
    				l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.y,
    				l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.z);
    			// Multiply with orientation retrieved from sensor...
    			glMultMatrixf(&(l_ModelViewMatrix.Transposed().M&#91;0&#93;&#91;0&#93;));
    			// 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&#91;l_Eye&#93;.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:

    Test_Only_One_Eye.png
  • ckoeberckoeber Posts: 68
    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 &lt;Windows.h&gt;
    #include &lt;GL/glew.h&gt;
    #define GLFW_EXPOSE_NATIVE_WIN32
    #define GLFW_EXPOSE_NATIVE_WGL
    #include &lt;GLFW/glfw3.h&gt;
    #include &lt;GLFW/glfw3native.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;stdio.h&gt;
    #include &lt;iostream&gt;
    #include &lt;math.h&gt;
    #include &lt;OVR_CAPI.h&gt;
    #include &lt;OVR_CAPI_GL.h&gt;
    #include &lt;OVR.h&gt;
    
    const bool l_FullScreen = false;
    
    ovrHmd l_Hmd;
    ovrHmdDesc l_HmdDesc;
    ovrEyeDesc l_Eyes&#91;2&#93;;
    ovrGLConfig l_Cfg;
    
    GLfloat l_VAPoints&#91;&#93; =
    {
    	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&#91;&#93; =
    {
    	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&#91;&#93; =
    {
    	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&#91;2&#93;;
    	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&#91;&#93; = { 5.0f, 6.0f, 3.0f, 0.0f };
    	GLfloat l_Light0Diffuse&#91;&#93; = { 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&#91;&#93; = { -5.0f, -6.0f, 5.0f, 0.0f };
    	GLfloat l_Light1Diffuse&#91;&#93; = { 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&#91;&#93; = { 0.3f, 0.3f, 0.3f, 1.0f };
    	GLfloat l_MaterialShininess&#91;&#93; = { 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&#91;0&#93;, 1.0f);
    	ovrSizei l_TextureSizeRight = ovrHmd_GetFovTextureSize(l_Hmd, ovrEye_Right, l_HmdDesc.DefaultEyeFov&#91;1&#93;, 1.0f);
    	ovrSizei l_TextureSize;
    	l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    	l_TextureSize.h = (l_TextureSizeLeft.h&gt;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&#91;1&#93; = { 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&#91;0&#93;.Eye = ovrEye_Left;
    	l_Eyes&#91;1&#93;.Eye = ovrEye_Right;
    	l_Eyes&#91;0&#93;.Fov = l_HmdDesc.DefaultEyeFov&#91;0&#93;;
    	l_Eyes&#91;1&#93;.Fov = l_HmdDesc.DefaultEyeFov&#91;1&#93;;
    	l_Eyes&#91;0&#93;.TextureSize.w = l_TextureSize.w;
    	l_Eyes&#91;0&#93;.TextureSize.h = l_TextureSize.h;
    	l_Eyes&#91;1&#93;.TextureSize.w = l_TextureSize.w;
    	l_Eyes&#91;1&#93;.TextureSize.h = l_TextureSize.h;
    	l_Eyes&#91;0&#93;.RenderViewport.Pos.x = 0;
    	l_Eyes&#91;0&#93;.RenderViewport.Pos.y = 0;
    	l_Eyes&#91;1&#93;.RenderViewport.Pos.x = (l_TextureSize.w + 1) / 2;
    	l_Eyes&#91;1&#93;.RenderViewport.Pos.y = 0;
    	l_Eyes&#91;0&#93;.RenderViewport.Size.w = l_TextureSize.w / 2;
    	l_Eyes&#91;0&#93;.RenderViewport.Size.h = l_TextureSize.h;
    	l_Eyes&#91;1&#93;.RenderViewport.Size.w = l_Eyes&#91;0&#93;.RenderViewport.Size.w;
    	l_Eyes&#91;1&#93;.RenderViewport.Size.h = l_Eyes&#91;0&#93;.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&#91;2&#93;;
    	ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_RenderCaps, l_DistortionCaps, l_Eyes, l_EyeRenderDesc);
    
    	ovrGLTexture l_EyeTexture&#91;2&#93;;
    	l_EyeTexture&#91;0&#93;.OGL.Header.API = ovrRenderAPI_OpenGL;
    	l_EyeTexture&#91;0&#93;.OGL.Header.TextureSize.w = l_TextureSize.w;
    	l_EyeTexture&#91;0&#93;.OGL.Header.TextureSize.h = l_TextureSize.h;
    	l_EyeTexture&#91;0&#93;.OGL.Header.RenderViewport = l_Eyes&#91;0&#93;.RenderViewport;
    	l_EyeTexture&#91;0&#93;.OGL.TexId = l_TextureId;
    
    	// Right eye uses the same texture, but a different rendering viewport...
    	l_EyeTexture&#91;1&#93; = l_EyeTexture&#91;0&#93;;
    	l_EyeTexture&#91;1&#93;.OGL.Header.RenderViewport = l_Eyes&#91;1&#93;.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 &lt; ovrEye_Count; l_EyeIndex++)
    		{
    			ovrEyeType l_Eye = l_HmdDesc.EyeRenderOrder&#91;l_EyeIndex&#93;;
    			ovrPosef l_EyePose = ovrHmd_BeginEyeRender(l_Hmd, l_Eye);
    
    			glViewport(l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Pos.x,   // StartX
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Pos.y,   // StartY
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Size.w,   // Width
    				l_EyeRenderDesc&#91;l_Eye&#93;.Desc.RenderViewport.Size.h   // Height
    				);
    
    			// Get Projection and ModelView matrici from the device...
    			OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
    				l_EyeRenderDesc&#91;l_Eye&#93;.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&#91;0&#93;&#91;0&#93;));
    			glMatrixMode(GL_MODELVIEW);
    			glLoadIdentity();
    			// Translate for specific eye based on IPD...
    			glTranslatef(l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.x,
    				l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.y,
    				l_EyeRenderDesc&#91;l_Eye&#93;.ViewAdjust.z);
    			// Multiply with orientation retrieved from sensor...
    			glMultMatrixf(&(l_ModelViewMatrix.Transposed().M&#91;0&#93;&#91;0&#93;));
    			// 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&#91;l_Eye&#93;.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:

    Test_Only_Right_Eye.png
  • ckoeberckoeber Posts: 68
    So the question is what is vastly different from one eye to another in the core code for OpenGL?
  • jhericojherico Posts: 1,419
    Nexus 6
    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

  • ckoeberckoeber Posts: 68
    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.
Sign In or Register to comment.