Skip to main content
Up and Coming
May 23, 2014

Simple, one page, OpenGL example (Oculus SDK 0.3.2 Preview)

Hi,

Didn't take too long to modify the earlier example (thread) to work with the new 0.3.2 release.
I think the OGL.Window field in ovrGLConfig is just a leftover because you can pass NULL without any consequences. Luckily, at least, the OGL.WglContext and OGL.GdiDC fields are gone making it easier to do the OSX/Linux port. I'll will try the OSX version this afternoon.

EDIT: Still a bit of OpenGL state restoration to do after ovrHmd_EndFrame() if you want your own vertex arrays to work: GL_ELEMENT_ARRAY_BUFFER and GL_ARRAY_BUFFER.
EDIT: Modified so it should work on Linux (thanks yombo and rjoyce). I don't have a Linux machine so please check. Next up OSX!
EDIT: OSX "support" (big word, just some preprocessor defines). GLFW will create a 2.X context, at least on my machine, so the deprecated functions will work. If not let me know.

Thanks,
Daniel


// GLFWOculusRiftTest
// (c) cThrough 2014 (Daniel Dekkers)
// Version 2014052305 Based on OculusSDK 3.0.2 Preview
// Windows, Linux and OSX

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

const bool l_FullScreen = false;
const bool l_MultiSampling = false;
const bool l_Spin = true;

ovrHmd l_Hmd;
ovrHmdDesc l_HmdDesc;
ovrFovPort l_EyeFov[2];
ovrGLConfig l_Cfg;
ovrEyeRenderDesc l_EyeRenderDesc[2];

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_DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp;
ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_DistortionCaps, l_EyeFov, l_EyeRenderDesc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
}

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

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

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

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

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}

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

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

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

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

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

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

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

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

static void SetOpenGLState(void)
{
// Some state...
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (l_MultiSampling) glEnable(GL_MULTISAMPLE);

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

// Start the sensor which provides the Rift’s pose and motion.
ovrHmd_StartSensor(l_Hmd, ovrSensorCap_Orientation | ovrSensorCap_YawCorrection | ovrSensorCap_Position, ovrSensorCap_Orientation);

GLFWwindow* l_Window;

glfwSetErrorCallback(ErrorCallback);

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

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

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;
l_Window = glfwCreateWindow(l_ClientSize.w, l_ClientSize.h, "GLFW Oculus Rift Test", NULL, NULL);
}

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

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

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

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

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

// 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_EyeFov[0] = l_HmdDesc.DefaultEyeFov[0];
l_EyeFov[1] = l_HmdDesc.DefaultEyeFov[1];

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

int l_DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp;
ovrHmd_ConfigureRendering(l_Hmd, &l_Cfg.Config, l_DistortionCaps, l_EyeFov, l_EyeRenderDesc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);

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.Pos.x = 0;
l_EyeTexture[0].OGL.Header.RenderViewport.Pos.y = 0;
l_EyeTexture[0].OGL.Header.RenderViewport.Size.w = l_TextureSize.w/2;
l_EyeTexture[0].OGL.Header.RenderViewport.Size.h = l_TextureSize.h;
l_EyeTexture[0].OGL.TexId = l_TextureId;

// Right eye the same, except for the x-position in the texture...
l_EyeTexture[1] = l_EyeTexture[0];
l_EyeTexture[1].OGL.Header.RenderViewport.Pos.x = (l_TextureSize.w+1)/2;

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

GLfloat l_SpinX;
GLfloat l_SpinY;

while (!glfwWindowShouldClose(l_Window))
{
if (l_Spin)
{
l_SpinX = (GLfloat) fmod(glfwGetTime()*17.0, 360.0);
l_SpinY = (GLfloat) fmod(glfwGetTime()*23.0, 360.0);
}
else
{
l_SpinX = 30.0f;
l_SpinY = 40.0f;
}

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_EyeTexture[l_Eye].OGL.Header.RenderViewport.Pos.x,
l_EyeTexture[l_Eye].OGL.Header.RenderViewport.Pos.y,
l_EyeTexture[l_Eye].OGL.Header.RenderViewport.Size.w,
l_EyeTexture[l_Eye].OGL.Header.RenderViewport.Size.h
);

// Get Projection and ModelView matrici from the device...
OVR::Matrix4f l_ProjectionMatrix = ovrMatrix4f_Projection(
l_EyeRenderDesc[l_Eye].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);

ovrHmd_EndFrame(l_Hmd);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);

glfwPollEvents();
}

glfwDestroyWindow(l_Window);

glfwTerminate();

ovrHmd_Destroy(l_Hmd);
ovr_Shutdown();

exit(EXIT_SUCCESS);
}

    51 replies

    Participant
    May 24, 2014
    Thanks for this. I'd like a Linux version, specially with the Config parameter to the ovrHmd_ConfigureRendering() function.

    If the Window member is not used (as you say), perhaps the Win and Disp members in Linux version are also not needed?

    I'm trying to do a Java binding to use in my engine.

    Thanks again!
    Participant
    May 24, 2014
    Answering my own question, I've found the part in the SDK where the config is used. It seems the window is optional and if null it's taken fron the active window. Also in Linux The Win and Disp members seem also optional.
    In CAPI_GL_DistortionRenderer.cpp:

    #if defined(OVR_OS_WIN32)
    RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow();
    #elif defined(OVR_OS_LINUX)
    RParams.Disp = (config->OGL.Disp) ? config->OGL.Disp : XOpenDisplay(NULL);
    RParams.Win = config->OGL.Win;
    if (!RParams.Win)
    {
    int unused;
    XGetInputFocus(RParams.Disp, &RParams.Win, &unused);
    }
    #endif
    Participant
    May 24, 2014
    Got this working in Linux (Fedora 20), in my tests you do need Win and Disp set properly, or you get GLX errors/crashes. I don't have my rift on me to test if it actual is talking to the sensor correctly, but I get the rendered distortion to show up.

    My modifications to make it cross platform are:

    #ifdef WIN32
    #include <Windows.h>
    #define GLFW_EXPOSE_NATIVE_WIN32
    #define GLFW_EXPOSE_NATIVE_WGL
    #else
    #include <X11/X.h>
    #include <X11/extensions/Xrandr.h>
    #define GLFW_EXPOSE_NATIVE_X11
    #define GLFW_EXPOSE_NATIVE_GLX
    #endif

    And down on (now) line 349

    l_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    l_Cfg.OGL.Header.Multisample = (l_MultiSampling ? 1 : 0);
    l_Cfg.OGL.Header.RTSize.w = l_ClientSize.w;
    l_Cfg.OGL.Header.RTSize.h = l_ClientSize.h;
    #ifdef WIN32
    l_Cfg.OGL.Window = glfwGetWin32Window(l_Window); // This can be NULL (?)
    #else
    l_Cfg.OGL.Win = glfwGetX11Window(l_Window);
    l_Cfg.OGL.Disp = glfwGetX11Display();
    #endif


    EDIT: FYI, the command I used to compile was:
    $ g++ -o GLFWOculusRiftTest GLFWOculusRiftTest.c -ILibOVR/Include/ -ILibOVR/Src/ -I/usr/include/X11/ LibOVR/Lib/Linux/Release/x86_64/libovr.a -ludev -lpthread -lGL -lX11 -lGLEW -lglfw -lXrandr -g
    Inspiring
    May 24, 2014
    "yombo" wrote:
    I'm trying to do a Java binding to use in my engine.


    I've already created a Java binding for the 0.3.1 version of the SDK. It will be updated soon for the 0.3.2 version. See this thread. If you use maven you can just declare a dependency and use it out of the box.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Participant
    May 24, 2014
    "jherico" wrote:
    "yombo" wrote:
    I'm trying to do a Java binding to use in my engine.


    I've already created a Java binding for the 0.3.1 version of the SDK. It will be updated soon for the 0.3.2 version. See this thread. If you use maven you can just declare a dependency and use it out of the box.


    Yes, I saw it, great! Will it add also Linux support? (since Linux support was re-added in 3.0.2)
    Inspiring
    May 24, 2014
    "ckoeber" wrote:
    did anyone try out multi-sampling out on the default framebuffer?


    I did get mutlisampled framebuffers to work, but only with a large amount of changes to the SDK side code. I don't think it's practical. The multi-sampling framebuffer approach was bugging me, so I decided to take a different tactic to improving the image quality.

    First off, I modified the SDK to support GL 4.4 shaders, and added the 'sample' keyword to the appropriate distortion fragment shader inputs. The SDK side changes are almost trivially small and you can see the full diff here.

    Next I altered my application to create a multi-sampled primary window. I'm using GLFW, so that was a simple matter of calling


    glfwWindowHint(GLFW_SAMPLES, SAMPLE_COUNT);


    before my window creation. Finally, I'm taking the recommended texture size provided by the SDK and scaling it up slightly.


    eyeTextureHeader.TextureSize = ovrHmd_GetFovTextureSize(hmd, eye, hmdDesc.DefaultEyeFov[eye], 1.0f);
    eyeTextureHeader.TextureSize.w *= TEXTURE_MULTIPLIER;
    eyeTextureHeader.TextureSize.h *= TEXTURE_MULTIPLIER;


    That texture size is what I then use to create my (non-multisampled) framebuffer.

    With the changed code I can simulate the old version by setting SAMPLE_COUNT to 0 and TEXTURE_MULTIPLIER to 1.0. The output looks like this:



    If I set sample count to 4 and TEXTURE_MULTIPLIER to 1.4, I get a much sharper looking output image



    Both factors are needed. Increasing SAMPLE_COUNT resolves a lot of the issues with Moiré patterning of high frequency imagery near the edge of the distortion, but it doesn't really do anything to help the jaggies near the center of the image, where the pixel to texel ratio is nearly 1:1. Increasing the TEXTURE_MULTIPLIER improves the jaggies near the center, but actually worsens the Moiré patterning of GL_LINE drawn content as you move away from the center, because it's essentially increasing the frequency. I might explore multi-sampled framebuffers again later, but for the time being, I'm finding this approach significantly simpler to deal with.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Inspiring
    May 24, 2014
    "yombo" wrote:
    "jherico" wrote:
    "yombo" wrote:
    I'm trying to do a Java binding to use in my engine.


    I've already created a Java binding for the 0.3.1 version of the SDK. It will be updated soon for the 0.3.2 version. See this thread. If you use maven you can just declare a dependency and use it out of the box.


    Yes, I saw it, great! Will it add also Linux support? (since Linux support was re-added in 3.0.2)


    It already has Linux support. I do about half of my development on Linux, so one of the first things I did with the Oculus SDK 0.3.1 release was restore Linux functionality to it. The Jocular library depends on a Jocular-platform jar (also available through maven, and should be picked up automatically) that contains binaries for 32 and 64 bit Windows, and 64 bit Linux (no 32 bit... sorry... I didn't feel like setting up a cross-compilation setup).

    I've actually already created the Jocular changes for 0.3.2 (they're on this branch) but I haven't ported over my example code yet, or rebuilt the Jocular-platform library. Should be able to get around to that this weekend.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Participant
    May 24, 2014
    "rjoyce" wrote:
    Got this working in Linux...


    Can the Disp and Win members be obtained without using -lGLEW and -lglfw libraries?
    I've tried obtaining them with the X11 functions the SDK uses internally. They give me values, but it crashes when I call the ovrHmd_ConfigureRendering() function with the Config structure. (Also if I set them to null/0)

    	printf("DEBUG Win0=%lu\n", glConfig.OGL.Win);
    printf("DEBUG Display0=%p\n", glConfig.OGL.Disp );
    glConfig.OGL.Disp = XOpenDisplay( NULL );
    int unused;
    XGetInputFocus( glConfig.OGL.Disp, &glConfig.OGL.Win, &unused );
    printf("DEBUG Win=%lu\n", glConfig.OGL.Win);
    printf("DEBUG Display=%p\n", glConfig.OGL.Disp );

    int distortionCaps = 0;
    if ( chromaAberrationRequired ) {
    distortionCaps |= ovrDistortionCap_Chromatic;
    }
    if ( timeWarpRequired ) {
    distortionCaps |= ovrDistortionCap_TimeWarp;
    }

    printf( "DEBUG 1\n" );

    if ( ! ovrHmd_ConfigureRendering( hmd, &glConfig.Config, distortionCaps, eyeFov, eyeRenderDesc ) ) {
    printf( "DEBUG 1-2\n" );
    return false;
    }


    DEBUG Win0=0
    DEBUG Display0=(nil)
    DEBUG Win=88080397
    DEBUG Display=0x7ffd404cec80
    DEBUG 1
    Inspiring
    May 24, 2014
    "yombo" wrote:
    Can the Disp and Win members be obtained without using -lGLEW and -lglfw libraries?


    They could, but if you're not using glfw, you need to be using some other mechanism to create an OpenGL surface.

    "yombo" wrote:
    I've tried obtaining them with the X11 functions the SDK uses internally. They give me values, but it crashes when I call the ovrHmd_ConfigureRendering() function with the Config structure. (Also if I set them to null/0)


    Is the window you're targeting actually an OpenGL window, or just a regular X window?
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    DoZo1971Author
    Up and Coming
    May 24, 2014
    I'm a bit stuck in porting this example to OSX.

    The distortion renderer still doesn't work for core profiles so (forced move):

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    glfwCreateWindow() returns with:

    Context profiles only exist for OpenGL version 3.2 and above

    Ok,... another forced move:

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

    Now glwfCreateWindow() returns with:

    The targeted version of OS X only supports OpenGL 3.2 and later versions if they are forward-compatible

    Ok,... so do it:

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

    glwfCreateWindow() returns with:

    The targeted version of OS X only supports OpenGL 3.2 and later versions if they use the core profile


    Aaarch...

    PS The initialization(s) of the Rift seem to be working though, and the sensor starts.