Trying to get mac display plugins working:

This commit is contained in:
Brad Davis 2015-07-02 22:29:22 -07:00
parent 6b85db268c
commit ed5835ff05
5 changed files with 203 additions and 47 deletions

View file

@ -16,11 +16,10 @@
#include <display-plugins/stereo/InterleavedStereoDisplayPlugin.h>
#include <display-plugins/Basic2DWindowOpenGLDisplayPlugin.h>
#ifdef Q_OS_WIN
#include <display-plugins/oculus/Oculus_0_6_DisplayPlugin.h>
#else
#include <display-plugins/oculus/Oculus_0_5_DisplayPlugin.h>
#endif
#include <display-plugins/openvr/OpenVrDisplayPlugin.h>
@ -57,10 +56,10 @@ const DisplayPluginList& getDisplayPlugins() {
new NullDisplayPlugin(),
new SideBySideStereoDisplayPlugin(),
// new InterleavedStereoDisplayPlugin(),
#ifdef Q_OS_WIN
new Oculus_0_6_DisplayPlugin(),
#else
#if (OVR_MAJOR_VERSION == 5)
new Oculus_0_5_DisplayPlugin(),
#else
new Oculus_0_6_DisplayPlugin(),
#endif
#ifndef Q_OS_MAC

View file

@ -140,7 +140,8 @@ void OpenGLDisplayPlugin::display(
glEnableVertexAttribArray(_texCoordAttribute);
glVertexAttribPointer(_texCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//glDisableVertexAttribArray(_positionAttribute);
//glDisableVertexAttribArray(_texCoordAttribute);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(_positionAttribute);
glDisableVertexAttribArray(_texCoordAttribute);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
}

View file

@ -37,7 +37,7 @@ const QString Oculus_0_5_DisplayPlugin::NAME("Oculus Rift (0.5)");
const QString & Oculus_0_5_DisplayPlugin::getName() const {
return NAME;
}
bool Oculus_0_5_DisplayPlugin::isSupported() const {
if (!ovr_Initialize(nullptr)) {
return false;
@ -50,6 +50,82 @@ bool Oculus_0_5_DisplayPlugin::isSupported() const {
return result;
}
static const char* OVR_DISTORTION_VS = R"SHADER(#version 120
#pragma line __LINE__
uniform vec2 EyeToSourceUVScale;
uniform vec2 EyeToSourceUVOffset;
uniform mat4 EyeRotationStart;
uniform mat4 EyeRotationEnd;
attribute vec2 Position;
attribute vec4 Color;
attribute vec2 TexCoord0;
attribute vec2 TexCoord1;
attribute vec2 TexCoord2;
varying vec4 oColor;
varying vec2 oTexCoord0;
varying vec2 oTexCoord1;
varying vec2 oTexCoord2;
void main() {
gl_Position.x = Position.x;
gl_Position.y = Position.y;
gl_Position.z = 0.0;
gl_Position.w = 1.0;
// Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
// These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD.
vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );
vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );
vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );
// Apply the two 3x3 timewarp rotations to these vectors.
vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;
vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;
vec3 TransformedBStart = (EyeRotationStart * vec4(TanEyeAngleB, 0)).xyz;
vec3 TransformedREnd = (EyeRotationEnd * vec4(TanEyeAngleR, 0)).xyz;
vec3 TransformedGEnd = (EyeRotationEnd * vec4(TanEyeAngleG, 0)).xyz;
vec3 TransformedBEnd = (EyeRotationEnd * vec4(TanEyeAngleB, 0)).xyz;
// And blend between them.
vec3 TransformedR = mix ( TransformedRStart, TransformedREnd, Color.a );
vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );
vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );
// Project them back onto the Z=1 plane of the rendered images.
float RecipZR = 1.0 / TransformedR.z;
float RecipZG = 1.0 / TransformedG.z;
float RecipZB = 1.0 / TransformedB.z;
vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );
vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );
vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );
// These are now still in TanEyeAngle space.
// Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;
vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;
vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;
oTexCoord0 = SrcCoordR;
oTexCoord1 = SrcCoordG;
oTexCoord2 = SrcCoordB;
oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade.
}
)SHADER";
static const char* OVR_DISTORTION_FS = R"SHADER(#version 120
#pragma line __LINE__
uniform sampler2D Texture0;
#extension GL_ARB_shader_texture_lod : enable
#extension GL_ARB_draw_buffers : enable
#extension GL_EXT_gpu_shader4 : enable
varying vec4 oColor;
varying vec2 oTexCoord0;
void main() {
gl_FragColor = vec4(0, 0, 0, 1); // texture2D(Texture0, oTexCoord0, 0.0);
//gl_FragColor.a = 1.0;
}
)SHADER";
void Oculus_0_5_DisplayPlugin::activate(PluginContainer * container) {
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
@ -68,9 +144,11 @@ void Oculus_0_5_DisplayPlugin::activate(PluginContainer * container) {
QSurfaceFormat format;
initSurfaceFormat(format);
_hmdWindow->setFlags(Qt::FramelessWindowHint);
_hmdWindow->setFormat(format);
_hmdWindow->create();
_hmdWindow->setGeometry(_hmd->WindowsPos.x, _hmd->WindowsPos.y, _hmd->Resolution.w, _hmd->Resolution.h);
//_hmdWindow->setGeometry(_hmd->WindowsPos.x, _hmd->WindowsPos.y, _hmd->Resolution.w, _hmd->Resolution.h);
_hmdWindow->setGeometry(0, -1080, _hmd->Resolution.w, _hmd->Resolution.h);
_hmdWindow->show();
_hmdWindow->installEventFilter(this);
_hmdWindow->makeCurrent();
@ -79,13 +157,11 @@ void Oculus_0_5_DisplayPlugin::activate(PluginContainer * container) {
config.Header.BackBufferSize = _hmd->Resolution;
config.Header.Multisample = 1;
int distortionCaps = 0
| ovrDistortionCap_Vignette
| ovrDistortionCap_Overdrive
| ovrDistortionCap_TimeWarp
;
#if RIFT_SDK_DISTORTION
ovrBool result = ovrHmd_ConfigureRendering(_hmd, &config, 0, _eyeFovs, nullptr);
Q_ASSERT(result);
| ovrDistortionCap_Vignette
| ovrDistortionCap_Overdrive
| ovrDistortionCap_TimeWarp
;
memset(_eyeTextures, 0, sizeof(ovrTexture) * 2);
ovr_for_each_eye([&](ovrEyeType eye) {
auto& header = _eyeTextures[eye].Header;
@ -97,35 +173,70 @@ void Oculus_0_5_DisplayPlugin::activate(PluginContainer * container) {
header.RenderViewport.Pos.x = header.RenderViewport.Size.w;
}
});
#if RIFT_SDK_DISTORTION
ovrBool result = ovrHmd_ConfigureRendering(_hmd, &config, 0, _eyeFovs, nullptr);
Q_ASSERT(result);
#else
compileProgram(_distortProgram, OVR_DISTORTION_VS, OVR_DISTORTION_FS);
auto uniforms = _distortProgram->ActiveUniforms();
for (int i = 0; i < uniforms.Size(); ++i) {
auto uniform = uniforms.At(i);
qDebug() << uniform.Name().c_str() << " @ " << uniform.Index();
if (uniform.Name() == String("EyeToSourceUVScale")) {
_uniformScale = uniform.Index();
} else if (uniform.Name() == String("EyeToSourceUVOffset")) {
_uniformOffset = uniform.Index();
} else if (uniform.Name() == String("EyeRotationStart")) {
_uniformEyeRotStart = uniform.Index();
} else if (uniform.Name() == String("EyeRotationEnd")) {
_uniformEyeRotEnd = uniform.Index();
}
}
auto attribs = _distortProgram->ActiveAttribs();
for (int i = 0; i < attribs.Size(); ++i) {
auto attrib = attribs.At(i);
qDebug() << attrib.Name().c_str() << " @ " << attrib.Index();
if (attrib.Name() == String("Position")) {
_attrPosition = attrib.Index();
} else if (attrib.Name() == String("TexCoord0")) {
_attrTexCoord0 = attrib.Index();
} else if (attrib.Name() == String("TexCoord1")) {
_attrTexCoord1 = attrib.Index();
} else if (attrib.Name() == String("TexCoord2")) {
_attrTexCoord2 = attrib.Index();
}
}
ovr_for_each_eye([&](ovrEyeType eye) {
ovrDistortionMesh meshData;
ovrHmd_CreateDistortionMesh(_hmd, eye, _eyeFovs[eye], distortionCaps, &meshData);
{
auto& buffer = _eyeVertexBuffers[eye];
buffer.reset(new oglplus::Buffer());
buffer->Bind(Buffer::Target::Array);
buffer->Data(Buffer::Target::Array, BufferData(meshData.VertexCount, meshData.pVertexData));
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
{
auto& buffer = _eyeIndexBuffers[eye];
buffer.reset(new oglplus::Buffer());
buffer->Bind(Buffer::Target::ElementArray);
buffer->Data(Buffer::Target::ElementArray, BufferData(meshData.IndexCount, meshData.pIndexData));
_indexCount[eye] = meshData.IndexCount;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
ovrHmd_DestroyDistortionMesh(&meshData);
const auto& header = _eyeTextures[eye].Header;
ovrHmd_GetRenderScaleAndOffset(_eyeFovs[eye], header.TextureSize, header.RenderViewport, _offsetAndScale[eye]);
});
_program = loadDefaultShader();
auto attribs = _program->ActiveAttribs();
for(size_t i = 0; i < attribs.Size(); ++i) {
auto attrib = attribs.At(i);
if (String("Position") == attrib.Name()) {
_positionAttribute = attrib.Index();
} else if (String("TexCoord") == attrib.Name()) {
_texCoordAttribute = attrib.Index();
}
qDebug() << attrib.Name().c_str();
}
_vertexBuffer.reset(new oglplus::Buffer());
_vertexBuffer->Bind(Buffer::Target::Array);
_vertexBuffer->Data(Buffer::Target::Array, BufferData(PLANE_VERTICES));
glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}
void Oculus_0_5_DisplayPlugin::deactivate() {
@ -139,22 +250,22 @@ void Oculus_0_5_DisplayPlugin::deactivate() {
ovr_Shutdown();
}
static ovrFrameTiming timing;
void Oculus_0_5_DisplayPlugin::preRender() {
#if RIFT_SDK_DISTORTION
ovrHmd_BeginFrame(_hmd, _frameIndex);
#else
ovrHmd_BeginFrameTiming(_hmd, _frameIndex);
timing = ovrHmd_BeginFrameTiming(_hmd, _frameIndex);
#endif
}
void Oculus_0_5_DisplayPlugin::preDisplay() {
_hmdWindow->makeCurrent();
}
void Oculus_0_5_DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
++_frameIndex;
// OpenGLDisplayPlugin::display(finalTexture, sceneSize);
#if RIFT_SDK_DISTORTION
ovr_for_each_eye([&](ovrEyeType eye) {
@ -162,8 +273,40 @@ void Oculus_0_5_DisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sc
});
ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures);
#else
ovr_WaitTillTime(timing.TimewarpPointSeconds);
glViewport(0, 0, _hmd->Resolution.w, _hmd->Resolution.h);
//_distortProgram->Bind();
glClearColor(1, 0, 1, 1);
Context::Clear().ColorBuffer();
Context::Disable(Capability::CullFace);
_distortProgram->Bind();
glBindTexture(GL_TEXTURE_2D, finalTexture);
glViewport(0, 0, _hmd->Resolution.w, _hmd->Resolution.h);
// Generates internal compiler error on MSVC 12
ovr_for_each_eye([&](ovrEyeType eye){
glUniform2fv(_uniformOffset, 1, &_offsetAndScale[eye][0].x);
glUniform2fv(_uniformScale, 1, &_offsetAndScale[eye][1].x);
_eyeVertexBuffers[eye]->Bind(Buffer::Target::Array);
glEnableVertexAttribArray(_attrPosition);
glVertexAttribPointer(_attrPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), (void*)offsetof(ovrDistortionVertex, ScreenPosNDC));
glEnableVertexAttribArray(_attrTexCoord0);
glVertexAttribPointer(_attrTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), (void*)offsetof(ovrDistortionVertex, TanEyeAnglesR));
glEnableVertexAttribArray(_attrTexCoord1);
glVertexAttribPointer(_attrTexCoord1, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), (void*)offsetof(ovrDistortionVertex, TanEyeAnglesG));
glEnableVertexAttribArray(_attrTexCoord2);
glVertexAttribPointer(_attrTexCoord2, 2, GL_FLOAT, GL_FALSE, sizeof(ovrDistortionVertex), (void*)offsetof(ovrDistortionVertex, TanEyeAnglesB));
_eyeIndexBuffers[eye]->Bind(Buffer::Target::ElementArray);
glDrawElements(GL_TRIANGLES, _indexCount[eye], GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(_attrPosition);
glDisableVertexAttribArray(_attrTexCoord0);
glDisableVertexAttribArray(_attrTexCoord1);
glDisableVertexAttribArray(_attrTexCoord2);
});
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}
// Pass input events on to the application
@ -173,9 +316,9 @@ bool Oculus_0_5_DisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
/*
The swapbuffer call here is only required if we want to mirror the content to the screen.
However, it should only be done if we can reliably disable v-sync on the mirror surface,
However, it should only be done if we can reliably disable v-sync on the mirror surface,
otherwise the swapbuffer delay will interefere with the framerate of the headset
*/
*/
void Oculus_0_5_DisplayPlugin::finishFrame() {
_hmdWindow->swapBuffers();
_hmdWindow->doneCurrent();

View file

@ -39,11 +39,24 @@ protected:
virtual void finishFrame() override;
private:
#if RIFT_SDK_DISTORTION
ovrTexture _eyeTextures[2];
#if RIFT_SDK_DISTORTION
#else
ovrVector2f _offsetAndScale[2][2];
ProgramPtr _distortProgram;
BufferPtr _eyeIndexBuffers[2];
BufferPtr _eyeVertexBuffers[2];
GLuint _indexCount[2];
GLuint _uniformScale{ -1 };
GLuint _uniformOffset{ -1 };
GLuint _uniformEyeRotStart{ -1 };
GLuint _uniformEyeRotEnd{ -1 };
GLuint _attrPosition{ -1 };
GLuint _attrTexCoord0{ -1 };
GLuint _attrTexCoord1{ -1 };
GLuint _attrTexCoord2{ -1 };
#endif
static const QString NAME;
GlWindow* _hmdWindow;

View file

@ -30,7 +30,7 @@
#include <oglplus/opt/list_init.hpp>
#include <oglplus/shapes/obj_mesh.hpp>
#include "../OglplusHelpers.h"
#include <OglplusHelpers.h>
// A base class for FBO wrappers that need to use the Oculus C