Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
HartLabs's avatar
HartLabs
Honored Guest
12 years ago

C++ OpenGL SFML 2.1X Oculus SDK 0.4.3 Example

Since I had this laying around and people seem to be posting them I thought I would post by C++ OpenGL SFML based on anarkavre's SDL2 example. I updated it for 0.4.3 and using the latest SFML release snapshot.

http://pastebin.com/qqH22Yb6

#include <GL/glew.h>

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Audio.hpp>

#include <iostream>

// Uncomment your platform
#define OVR_OS_WIN32
//#define OVR_OS_MAC
//#define OVR_OS_LINUX
#include "OVR_CAPI_GL.h"
#include "Kernel/OVR_Math.h"

int main(int argc, char *argv[])
{
ovr_Initialize();

sf::Window testWindow;

bool debug = false;

ovrHmd hmd = ovrHmd_Create(0);

int x = 1;
int y = 1;

if (hmd == NULL)
{
hmd = ovrHmd_CreateDebug(ovrHmd_DK1);

debug = true;
}

if (debug == false)
{
x = hmd->WindowsPos.x;
y = hmd->WindowsPos.y;
}

int w = hmd->Resolution.w;
int h = hmd->Resolution.h;

testWindow.create(sf::VideoMode::getDesktopMode(), "TEST SFML DK2", sf::Style::None);

OVR::Sizei recommendedTex0Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0f);
OVR::Sizei recommendedTex1Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0f);

OVR::Sizei renderTargetSize;
renderTargetSize.w = recommendedTex0Size.w + recommendedTex1Size.w;

renderTargetSize.h = recommendedTex0Size.h;
if( recommendedTex1Size.h > renderTargetSize.h)
{
renderTargetSize.h = recommendedTex1Size.h;
}

glewInit();

GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);

GLuint texture;
glGenTextures(1, &texture);

GLuint renderBuffer;
glGenRenderbuffers(1, &renderBuffer);

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderTargetSize.w, renderTargetSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);

glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, renderTargetSize.w, renderTargetSize.h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);

ovrFovPort eyeFov[2] = { hmd->DefaultEyeFov[0], hmd->DefaultEyeFov[1] };

ovrRecti eyeRenderViewport[2];
eyeRenderViewport[0].Pos = OVR::Vector2i(0, 0);
eyeRenderViewport[0].Size = OVR::Sizei(renderTargetSize.w / 2, renderTargetSize.h);
eyeRenderViewport[1].Pos = OVR::Vector2i((renderTargetSize.w + 1) / 2, 0);
eyeRenderViewport[1].Size = eyeRenderViewport[0].Size;

ovrGLTexture eyeTexture[2];
eyeTexture[0].OGL.Header.API = ovrRenderAPI_OpenGL;
eyeTexture[0].OGL.Header.TextureSize = renderTargetSize;
eyeTexture[0].OGL.Header.RenderViewport = eyeRenderViewport[0];
eyeTexture[0].OGL.TexId = texture;

eyeTexture[1] = eyeTexture[0];
eyeTexture[1].OGL.Header.RenderViewport = eyeRenderViewport[1];

ovrGLConfig cfg;
cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
cfg.OGL.Header.RTSize = OVR::Sizei(hmd->Resolution.w, hmd->Resolution.h);
cfg.OGL.Header.Multisample = 1;

#if defined(OVR_OS_WIN32)
if (!(hmd->HmdCaps & ovrHmdCap_ExtendDesktop))
ovrHmd_AttachToWindow(hmd, testWindow.getSystemHandle(), NULL, NULL);

cfg.OGL.Window = testWindow.getSystemHandle();
cfg.OGL.DC = NULL;
#elif defined(OVR_OS_LINUX)
cfg.OGL.Disp = info.info.x11.display;
cfg.OGL.Win = info.info.x11.window;
#endif

ovrEyeRenderDesc eyeRenderDesc[2];

ovrHmd_ConfigureRendering(hmd, &cfg.Config, ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp | ovrDistortionCap_Overdrive, eyeFov, eyeRenderDesc);

ovrHmd_SetEnabledCaps(hmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);

ovrHmd_ConfigureTracking(hmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);

const GLchar *vertexShaderSource[] = {
"#version 150\n"
"uniform mat4 MVPMatrix;\n"
"in vec3 position;\n"
"void main()\n"
"{\n"
" gl_Position = MVPMatrix * vec4(position, 1.0);\n"
"}"
};

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, vertexShaderSource, NULL);
glCompileShader(vertexShader);

const GLchar *fragmentShaderSource[] = {
"#version 150\n"
"out vec4 outputColor;\n"
"void main()\n"
"{\n"
" outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}"
};

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program);

GLuint MVPMatrixLocation = glGetUniformLocation(program, "MVPMatrix");
GLuint positionLocation = glGetAttribLocation(program, "position");

GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);

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

GLuint positionBuffer;
glGenBuffers(1, &positionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionLocation);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);

glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);

//----------------------------------------------------------------------------------------------------------------------------------------------

ovrHmd_DismissHSWDisplay(hmd);

bool running = true;

while (running == true)
{
ovrFrameTiming frameTiming = ovrHmd_BeginFrame(hmd, 0);

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ovrPosef eyeRenderPose[2];

for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
{
ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
ovrVector3f hmdToEyeViewOffset[2];
hmdToEyeViewOffset[0] = eyeRenderDesc[0].HmdToEyeViewOffset;
hmdToEyeViewOffset[1] = eyeRenderDesc[1].HmdToEyeViewOffset;
ovrHmd_GetEyePoses(hmd, 0, hmdToEyeViewOffset, eyeRenderPose, NULL);

OVR::Matrix4f MVPMatrix = OVR::Matrix4f(ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.01f, 10000.0f, true)) * OVR::Matrix4f::Translation(eyeRenderDesc[eye].HmdToEyeViewOffset) * OVR::Matrix4f(OVR::Quatf(eyeRenderPose[eye].Orientation).Inverted());

glUniformMatrix4fv(MVPMatrixLocation, 1, GL_FALSE, &MVPMatrix.Transposed().M[0][0]);

glViewport(eyeRenderViewport[eye].Pos.x, eyeRenderViewport[eye].Pos.y, eyeRenderViewport[eye].Size.w, eyeRenderViewport[eye].Size.h);

glBindVertexArray(vertexArray);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
}

ovrHmd_EndFrame(hmd, eyeRenderPose, &eyeTexture[0].Texture);
}

glDeleteVertexArrays(1, &vertexArray);
glDeleteBuffers(1, &positionBuffer);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteProgram(program);

glDeleteFramebuffers(1, &frameBuffer);
glDeleteTextures(1, &texture);
glDeleteRenderbuffers(1, &renderBuffer);

testWindow.close();

ovrHmd_Destroy(hmd);

ovr_Shutdown();

return 0;
}

Library Directories:

...Includes\SFML\SFML 2.1X Snapshot Nov 2014\SFML-master\extlibs\libs-msvc\x86
...Includes\OculusSDK\LibOVR\Lib\Win32\VS2010
...Includes\OpenGL\glew-1.9.0\lib
...Includes\SFML\SFML 2.1X Snapshot Nov 2014\lib\Release

Include Directories:

...Includes\OpenGL\glew-1.9.0\include
...Includes\OculusSDK\LibOVR\Src
...\Includes\SFML\SFML 2.1X Snapshot Nov 2014\SFML-master\include

Libraries:

glew32s.lib
sfml-main.lib
sfml-window.lib
sfml-graphics.lib
sfml-system.lib
sfml-audio.lib
glu32.lib
opengl32.lib
libovr.lib
ws2_32.lib
winmm.lib
openal32.lib
gdi32.lib
jpeg.lib
freetype.lib
sndfile.lib

Ignore Specific Library:

atls.lib

Add to release folder:

libsndfile-1.dll
openal32.dll

DK2 set to extended desktop mode (for me direct works but only give 37.5 FPS, haven't figured out why yet).