Skip to content

Commit

Permalink
Widgets|libappfw: provide VRConfig::RowInterleaved implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gkv311 committed Oct 7, 2016
1 parent 8b33d3a commit 3d7fa34
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 8 deletions.
4 changes: 3 additions & 1 deletion doomsday/apps/client/src/ui/dialogs/vrsettingsdialog.cpp
Expand Up @@ -64,7 +64,9 @@ DENG_GUI_PIMPL(VRSettingsDialog)
<< new ChoiceItem(tr("Side-by-side"), VRConfig::SideBySide)
<< new ChoiceItem(tr("Parallel"), VRConfig::Parallel)
<< new ChoiceItem(tr("Cross-eye"), VRConfig::CrossEye)
<< new ChoiceItem(tr("Hardware stereo"), VRConfig::QuadBuffered);
<< new ChoiceItem(tr("Hardware stereo"), VRConfig::QuadBuffered)
<< new ChoiceItem(tr("Row interleaved"), VRConfig::RowInterleaved)
;

if (vrCfg().oculusRift().isEnabled())
{
Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libappfw/src/vr/vrconfig.cpp
Expand Up @@ -271,6 +271,7 @@ bool VRConfig::modeAppliesDisplacement(StereoMode mode)
case LeftOnly:
case RightOnly:
case QuadBuffered:
case RowInterleaved:
return false;

default:
Expand Down
74 changes: 67 additions & 7 deletions doomsday/sdk/libappfw/src/vrwindowtransform.cpp
Expand Up @@ -34,14 +34,20 @@ DENG2_PIMPL(VRWindowTransform)

GLFramebuffer unwarpedFB;

GLFramebuffer stereoFBRight;
Drawable rowInterDrawable;
GLUniform rowInterUniformTex;

Impl(Public *i)
: Base(i)
, vrCfg(DENG2_BASE_GUI_APP->vr())
, rowInterUniformTex("uTex", GLUniform::Sampler2D)
{}

~Impl()
{
vrCfg.oculusRift().deinit();
stereoFBRight.glDeinit();
}

Canvas &canvas() const
Expand Down Expand Up @@ -131,6 +137,39 @@ DENG2_PIMPL(VRWindowTransform)
vrCfg.enableFrustumShift(); // restore default
}

/**
* Initialize drawable for row-interleaved stereo.
*/
void vrInitRowInterleaved()
{
if (rowInterDrawable.isReady())
{
return;
}

typedef GLBufferT<Vertex2Tex> VBuf;
VBuf *buf = new VBuf;
rowInterDrawable.addBuffer(buf);
rowInterDrawable.program().build(// Vertex shader:
Block("attribute highp vec4 aVertex; "
"attribute highp vec2 aUV; "
"varying highp vec2 vUV; "
"void main(void) {"
"gl_Position = aVertex; "
"vUV = aUV; }"),
// Fragment shader:
Block("uniform sampler2D uTex; "
"varying highp vec2 vUV; "
"void main(void) { "
"if(int(mod(gl_FragCoord.y - 1023.5, 2.0)) != 1) { discard; }\n"
"gl_FragColor = texture2D(uTex, vUV); }"))
<< rowInterUniformTex;
buf->setVertices(gl::TriangleStrip,
VBuf::Builder().makeQuad(Rectanglef(-1, -1, 2, 2), Rectanglef(0, 0, 1, 1)),
gl::Static);
}

bool toReleaseFBRight = true;
void draw()
{
switch (vrCfg.mode())
Expand Down Expand Up @@ -253,15 +292,30 @@ DENG2_PIMPL(VRWindowTransform)
// first scan line is odd or even.
QPoint ulCorner(0, 0);
ulCorner = canvas().mapToGlobal(ulCorner); // widget to screen coordinates
bool rowParityIsEven = ((ulCorner.x() % 2) == 0);
DENG2_UNUSED(rowParityIsEven);
/// @todo - use row parity in shader or stencil, to actually interleave rows.
// Left eye view
vrCfg.setCurrentEye(VRConfig::LeftEye);
bool rowParityIsEven = ((ulCorner.y() % 2) == 0);

// Draw left eye view directly to the screen
vrCfg.setCurrentEye(rowParityIsEven ? VRConfig::LeftEye : VRConfig::RightEye);
drawContent();
// Right eye view
vrCfg.setCurrentEye(VRConfig::RightEye);

// Draw right eye view to FBO
toReleaseFBRight = false;
stereoFBRight.glInit();
stereoFBRight.resize(GLFramebuffer::Size(width(), height()));
stereoFBRight.colorTexture().setFilter(gl::Linear, gl::Linear, gl::MipNone);
stereoFBRight.colorTexture().glApplyParameters();
GLState::push()
.setTarget(stereoFBRight.target())
.setViewport(Rectangleui::fromSize(stereoFBRight.size()))
.apply();
vrCfg.setCurrentEye(rowParityIsEven ? VRConfig::RightEye : VRConfig::LeftEye);
drawContent();
GLState::pop().apply();

// Draw right eye view to the screen from FBO color texture
vrInitRowInterleaved();
rowInterUniformTex = stereoFBRight.colorTexture();
rowInterDrawable.draw();
break;
}

Expand All @@ -273,6 +327,12 @@ DENG2_PIMPL(VRWindowTransform)
break;
}

if(toReleaseFBRight)
{
// release unused FBOs
stereoFBRight.glDeinit();
}

// Restore default VR dynamic parameters
target().unsetActiveRect(true);
vrCfg.setCurrentEye(VRConfig::NeitherEye);
Expand Down

0 comments on commit 3d7fa34

Please sign in to comment.