1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 00:49:54 +00:00
openmw-tes3mp/apps/openmw/mwvr/openxrviewer.cpp

127 lines
4 KiB
C++
Raw Normal View History

#include "openxrviewer.hpp"
#include "openxrmanagerimpl.hpp"
#include "Windows.h"
namespace MWVR
{
OpenXRViewer::OpenXRViewer(
osg::ref_ptr<OpenXRManager> XR,
osg::ref_ptr<OpenXRManager::RealizeOperation> realizeOperation,
osg::ref_ptr<osgViewer::Viewer> viewer,
float metersPerUnit)
: mXR(XR)
, mRealizeOperation(realizeOperation)
, mViewer(viewer)
, mMetersPerUnit(metersPerUnit)
, mConfigured(false)
{
}
OpenXRViewer::~OpenXRViewer(void)
{
}
void
OpenXRViewer::traverse(
osg::NodeVisitor& visitor)
{
osg::ref_ptr<OpenXRManager::RealizeOperation> realizeOperation = nullptr;
if (mRealizeOperation.lock(realizeOperation))
if (mRealizeOperation->realized())
if (configure())
osg::Group::traverse(visitor);
}
bool
OpenXRViewer::configure()
{
if (mConfigured)
return true;
auto context = mViewer->getCamera()->getGraphicsContext();
if (!context->makeCurrent())
{
Log(Debug::Warning) << "OpenXRViewer::configure() failed to make graphics context current.";
return false;
}
context->setSwapCallback(new OpenXRManager::SwapBuffersCallback(mXR));
auto DC = wglGetCurrentDC();
auto GLRC = wglGetCurrentContext();
if (DC != mXR->mPrivate->mGraphicsBinding.hDC)
{
Log(Debug::Warning) << "Graphics DC does not match DC used to construct XR context";
}
if (GLRC != mXR->mPrivate->mGraphicsBinding.hGLRC)
{
Log(Debug::Warning) << "Graphics GLRC does not match GLRC used to construct XR context";
}
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
camera->setName("Main");
osg::Vec4 clearColor = camera->getClearColor();
mViews[LEFT_VIEW] = new OpenXRView(mXR, context->getState(), mMetersPerUnit, 0);
mViews[RIGHT_VIEW] = new OpenXRView(mXR, context->getState(), mMetersPerUnit, 1);
osg::Camera* leftCamera = mViews[LEFT_VIEW]->createCamera(LEFT_VIEW, clearColor, context);
osg::Camera* rightCamera = mViews[RIGHT_VIEW]->createCamera(RIGHT_VIEW, clearColor, context);
leftCamera->setName("LeftEye");
rightCamera->setName("RightEye");
mViewer->addSlave(leftCamera, mViews[LEFT_VIEW]->projectionMatrix(), mViews[LEFT_VIEW]->viewMatrix(), true);
mViewer->addSlave(rightCamera, mViews[RIGHT_VIEW]->projectionMatrix(), mViews[RIGHT_VIEW]->viewMatrix(), true);
mViewer->getSlave(LEFT_VIEW)._updateSlaveCallback = new UpdateSlaveCallback(mXR, mViews[LEFT_VIEW]);
mViewer->getSlave(RIGHT_VIEW)._updateSlaveCallback = new UpdateSlaveCallback(mXR, mViews[RIGHT_VIEW]);
mViewer->setLightingMode(osg::View::SKY_LIGHT);
mViewer->setReleaseContextAtEndOfFrameHint(false);
// Rendering main camera is a waste of time with VR enabled
//camera->setGraphicsContext(nullptr);
mXRInput.reset(new OpenXRInputManager(mXR));
mConfigured = true;
return true;
}
void
OpenXRViewer::UpdateSlaveCallback::updateSlave(
osg::View& view,
osg::View::Slave& slave)
{
mXR->handleEvents();
if (!mXR->sessionRunning())
return;
auto* camera = slave._camera.get();
auto name = camera->getName();
Log(Debug::Debug) << "Updating camera " << name;
if (camera->getName() == "LeftEye")
{
mXR->handleEvents();
mXR->waitFrame();
mXR->beginFrame();
mXR->updateControls();
mXR->updatePoses();
}
auto viewMatrix = view.getCamera()->getViewMatrix() * mView->viewMatrix();
auto projMatrix = mView->projectionMatrix();
camera->setViewMatrix(viewMatrix);
camera->setProjectionMatrix(projMatrix);
}
}