Files
flightgear/3rdparty/osgXR/src/CompositionLayerQuad.cpp
2022-10-20 20:29:11 +08:00

223 lines
5.9 KiB
C++

// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2022 James Hogan <james@albanarts.com>
#include <osgXR/CompositionLayerQuad>
#include <osgXR/Manager>
#include <osgXR/SubImage>
#include <osgXR/Swapchain>
#include "OpenXR/Compositor.h"
#include "CompositionLayer.h"
#include "Swapchain.h"
using namespace osgXR;
// Internal API
namespace osgXR {
class CompositionLayerPrivateQuad : public CompositionLayer::Private
{
public:
typedef CompositionLayerQuad::EyeVisibility EyeVisibility;
CompositionLayerPrivateQuad(XRState *state) :
CompositionLayer::Private(state),
_eyeVisibility(EyeVisibility::EYES_BOTH),
_orientation(0.0f, 0.0f, 0.0f, 1.0f),
_position(0.0f, 0.0f, -1.0f),
_size(1.0f, 1.0f)
{
}
~CompositionLayerPrivateQuad()
{
}
void setEyeVisibility(EyeVisibility eyes)
{
_eyeVisibility = eyes;
}
EyeVisibility getEyeVisibility() const
{
return _eyeVisibility;
}
void setSubImage(const SubImage &subImage)
{
_subImage = subImage;
}
const SubImage &getSubImage() const
{
return _subImage;
}
void setOrientation(const osg::Quat &quat)
{
_orientation = quat;
}
const osg::Quat &getOrientation() const
{
return _orientation;
}
void setPosition(const osg::Vec3f &pos)
{
_position = pos;
}
const osg::Vec3f &getPosition() const
{
return _position;
}
void setSize(const osg::Vec2f &size)
{
_size = size;
}
const osg::Vec2f &getSize() const
{
return _size;
}
bool setup(OpenXR::Session *session) override
{
Swapchain *swapchain = _subImage.getSwapchain();
if (swapchain)
return Swapchain::Private::get(swapchain)->setup(_state.get(), session);
return false;
}
bool writeCompositionLayerQuad(OpenXR::Session *session,
OpenXR::CompositionLayerQuad *layer) const
{
auto swapchain = Swapchain::Private::get(_subImage.getSwapchain());
bool ret = writeCompositionLayer(session, layer,
swapchain->getForcedAlpha() >= 1.0f);
if (!ret)
return ret;
_quadLayer->setEyeVisibility(static_cast<XrEyeVisibility>(_eyeVisibility));
_quadLayer->setSubImage(swapchain->convertSubImage(_subImage));
_quadLayer->setOrientation(_orientation);
_quadLayer->setPosition(_position);
_quadLayer->setSize(_size);
return true;
}
void endFrame(OpenXR::Session::Frame *frame) override
{
Swapchain *swapchain = _subImage.getSwapchain();
if (!swapchain)
return;
auto *swapchainPriv = Swapchain::Private::get(swapchain);
if (!swapchainPriv->valid())
return;
_quadLayer = new OpenXR::CompositionLayerQuad();
if (writeCompositionLayerQuad(frame->getSession(), _quadLayer))
frame->addLayer(_quadLayer.get());
}
void cleanupSession() override
{
Swapchain *swapchain = _subImage.getSwapchain();
if (swapchain)
Swapchain::Private::get(swapchain)->cleanupSession();
}
protected:
EyeVisibility _eyeVisibility;
SubImage _subImage;
osg::Quat _orientation;
osg::Vec3f _position;
osg::Vec2f _size;
osg::ref_ptr<OpenXR::CompositionLayerQuad> _quadLayer;
};
}
// Public API
CompositionLayerQuad::CompositionLayerQuad(Manager *manager) :
CompositionLayer(new CompositionLayerPrivateQuad(manager->_getXrState()))
{
}
CompositionLayerQuad::~CompositionLayerQuad()
{
}
void CompositionLayerQuad::setEyeVisibility(EyeVisibility eyes)
{
auto priv = static_cast<CompositionLayerPrivateQuad *>(Private::get(this));
priv->setEyeVisibility(eyes);
}
CompositionLayerQuad::EyeVisibility CompositionLayerQuad::getEyeVisibility() const
{
auto priv = static_cast<const CompositionLayerPrivateQuad *>(Private::get(this));
return priv->getEyeVisibility();
}
void CompositionLayerQuad::setSubImage(Swapchain *swapchain)
{
setSubImage((SubImage)swapchain);
}
void CompositionLayerQuad::setSubImage(const SubImage &subImage)
{
auto priv = static_cast<CompositionLayerPrivateQuad *>(Private::get(this));
priv->setSubImage(subImage);
}
const SubImage &CompositionLayerQuad::getSubImage() const
{
auto priv = static_cast<const CompositionLayerPrivateQuad *>(Private::get(this));
return priv->getSubImage();
}
void CompositionLayerQuad::setOrientation(const osg::Quat &quat)
{
auto priv = static_cast<CompositionLayerPrivateQuad *>(Private::get(this));
priv->setOrientation(quat);
}
const osg::Quat &CompositionLayerQuad::getOrientation() const
{
auto priv = static_cast<const CompositionLayerPrivateQuad *>(Private::get(this));
return priv->getOrientation();
}
void CompositionLayerQuad::setPosition(const osg::Vec3f &pos)
{
auto priv = static_cast<CompositionLayerPrivateQuad *>(Private::get(this));
priv->setPosition(pos);
}
const osg::Vec3f &CompositionLayerQuad::getPosition() const
{
auto priv = static_cast<const CompositionLayerPrivateQuad *>(Private::get(this));
return priv->getPosition();
}
void CompositionLayerQuad::setSize(const osg::Vec2f &size)
{
auto priv = static_cast<CompositionLayerPrivateQuad *>(Private::get(this));
priv->setSize(size);
}
const osg::Vec2f &CompositionLayerQuad::getSize() const
{
auto priv = static_cast<const CompositionLayerPrivateQuad *>(Private::get(this));
return priv->getSize();
}