mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 18:54:02 +02:00
Trying to get mac display plugins working:
This commit is contained in:
parent
6b85db268c
commit
ed5835ff05
5 changed files with 203 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue