mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-10-12 06:36:32 +00:00
RTT camera
This commit is contained in:
parent
de2354abda
commit
f25be2a44a
6 changed files with 173 additions and 82 deletions
|
@ -4,10 +4,82 @@
|
||||||
#include "openxrmanagerimpl.hpp"
|
#include "openxrmanagerimpl.hpp"
|
||||||
#include <openxr/openxr.h>
|
#include <openxr/openxr.h>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/ClipNode>
|
||||||
|
#include <osg/FrontFace>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
|
#include <components/sceneutil/shadow.hpp>
|
||||||
|
#include <osgViewer/Renderer>
|
||||||
|
#include "../mwrender/util.hpp"
|
||||||
|
|
||||||
namespace MWVR
|
namespace MWVR
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class Menus : public osg::Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Menus()
|
||||||
|
{
|
||||||
|
setRenderOrder(osg::Camera::PRE_RENDER);
|
||||||
|
setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||||
|
setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||||
|
setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water"));
|
||||||
|
setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
|
setName("ReflectionCamera");
|
||||||
|
|
||||||
|
setCullMask(MWRender::Mask_GUI);
|
||||||
|
setNodeMask(MWRender::Mask_RenderToTexture);
|
||||||
|
|
||||||
|
unsigned int rttSize = 1000;
|
||||||
|
setViewport(0, 0, rttSize, rttSize);
|
||||||
|
|
||||||
|
// No need for Update traversal since the mSceneRoot is already updated as part of the main scene graph
|
||||||
|
// A double update would mess with the light collection (in addition to being plain redundant)
|
||||||
|
setUpdateCallback(new MWRender::NoTraverseCallback);
|
||||||
|
|
||||||
|
mMenuTexture = new osg::Texture2D;
|
||||||
|
mMenuTexture->setTextureSize(rttSize, rttSize);
|
||||||
|
mMenuTexture->setInternalFormat(GL_RGB);
|
||||||
|
mMenuTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
||||||
|
mMenuTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||||
|
mMenuTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
mMenuTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
attach(osg::Camera::COLOR_BUFFER, mMenuTexture);
|
||||||
|
|
||||||
|
// XXX: should really flip the FrontFace on each renderable instead of forcing clockwise.
|
||||||
|
//osg::ref_ptr<osg::FrontFace> frontFace(new osg::FrontFace);
|
||||||
|
//frontFace->setMode(osg::FrontFace::CLOCKWISE);
|
||||||
|
//getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
//mClipCullNode = new ClipCullNode;
|
||||||
|
//addChild(mClipCullNode);
|
||||||
|
|
||||||
|
SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScene(osg::Node* scene)
|
||||||
|
{
|
||||||
|
if (mScene)
|
||||||
|
removeChild(mScene);
|
||||||
|
mScene = scene;
|
||||||
|
addChild(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Texture2D* getMenuTexture() const
|
||||||
|
{
|
||||||
|
return mMenuTexture.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<osg::Texture2D> mMenuTexture;
|
||||||
|
osg::ref_ptr<osg::Node> mScene;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PredrawCallback : public osg::Camera::DrawCallback
|
class PredrawCallback : public osg::Camera::DrawCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -38,7 +110,7 @@ namespace MWVR
|
||||||
|
|
||||||
OpenXRMenu::OpenXRMenu(
|
OpenXRMenu::OpenXRMenu(
|
||||||
osg::ref_ptr<osg::Group> parent,
|
osg::ref_ptr<osg::Group> parent,
|
||||||
osg::ref_ptr<osg::Group> menuSubgraph,
|
osg::ref_ptr<osg::Node> menuSubgraph,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
osg::Vec2 extent_meters,
|
osg::Vec2 extent_meters,
|
||||||
Pose pose,
|
Pose pose,
|
||||||
|
@ -50,11 +122,6 @@ namespace MWVR
|
||||||
, mParent(parent)
|
, mParent(parent)
|
||||||
, mMenuSubgraph(menuSubgraph)
|
, mMenuSubgraph(menuSubgraph)
|
||||||
{
|
{
|
||||||
mMenuTexture->setTextureSize(width, height);
|
|
||||||
mMenuTexture->setInternalFormat(GL_RGBA);
|
|
||||||
mMenuTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
|
|
||||||
mMenuTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec3Array> vertices{ new osg::Vec3Array(4) };
|
osg::ref_ptr<osg::Vec3Array> vertices{ new osg::Vec3Array(4) };
|
||||||
osg::ref_ptr<osg::Vec2Array> texCoords{ new osg::Vec2Array(4) };
|
osg::ref_ptr<osg::Vec2Array> texCoords{ new osg::Vec2Array(4) };
|
||||||
osg::ref_ptr<osg::Vec3Array> normals{ new osg::Vec3Array(1) };
|
osg::ref_ptr<osg::Vec3Array> normals{ new osg::Vec3Array(1) };
|
||||||
|
@ -87,7 +154,10 @@ namespace MWVR
|
||||||
mGeometry->setDataVariance(osg::Object::DYNAMIC);
|
mGeometry->setDataVariance(osg::Object::DYNAMIC);
|
||||||
mGeometry->setSupportsDisplayList(false);
|
mGeometry->setSupportsDisplayList(false);
|
||||||
|
|
||||||
mStateSet->setTextureAttributeAndModes(0, mMenuTexture, osg::StateAttribute::ON);
|
mMenuCamera = new Menus();
|
||||||
|
mMenuCamera->setScene(menuSubgraph);
|
||||||
|
|
||||||
|
mStateSet->setTextureAttributeAndModes(0, menuTexture(), osg::StateAttribute::ON);
|
||||||
mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
mGeometry->setStateSet(mStateSet);
|
mGeometry->setStateSet(mStateSet);
|
||||||
|
|
||||||
|
@ -104,58 +174,29 @@ namespace MWVR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mMenuCamera->setClearColor(clearColor);
|
mParent->addChild(mMenuCamera.get());
|
||||||
mMenuCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
|
|
||||||
// This is based on the osgprerender example.
|
|
||||||
// I'm not sure this part is meaningful when all i'm rendering is the GUI.
|
|
||||||
|
|
||||||
//auto& bs = mMenuSubgraph->getBound();
|
|
||||||
//if (!bs.valid())
|
|
||||||
// Log(Debug::Verbose) << "OpenXRMenu: Invalid bound";
|
|
||||||
//float znear = 1.0f * bs.radius();
|
|
||||||
//float zfar = 3.0f * bs.radius();
|
|
||||||
//float proj_top = 0.25f * znear;
|
|
||||||
//float proj_right = 0.5f * znear;
|
|
||||||
//znear *= 0.9f;
|
|
||||||
//zfar *= 1.1f;
|
|
||||||
//mMenuCamera->setProjectionMatrixAsFrustum(-proj_right, proj_right, -proj_top, proj_top, znear, zfar);
|
|
||||||
//mMenuCamera->setViewMatrixAsLookAt(bs.center() - osg::Vec3(0.0f, 2.0f, 0.0f) * bs.radius(), bs.center(), osg::Vec3(0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
|
|
||||||
mMenuCamera->setViewMatrix(viewer->getCamera()->getViewMatrix());
|
|
||||||
mMenuCamera->setProjectionMatrix(viewer->getCamera()->getProjectionMatrix());
|
|
||||||
|
|
||||||
// Camera details
|
|
||||||
mMenuCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
|
||||||
mMenuCamera->setViewport(0, 0, width, height);
|
|
||||||
mMenuCamera->setRenderOrder(osg::Camera::PRE_RENDER);
|
|
||||||
mMenuCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
|
||||||
mMenuCamera->attach(osg::Camera::COLOR_BUFFER, mMenuTexture);
|
|
||||||
mMenuCamera->addChild(mMenuSubgraph);
|
|
||||||
mMenuCamera->setCullMask(MWRender::Mask_GUI);
|
|
||||||
mMenuCamera->setPreDrawCallback(new PredrawCallback(this));
|
|
||||||
mMenuCamera->setPostDrawCallback(new PostdrawCallback(this));
|
|
||||||
mMenuCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
|
||||||
mMenuCamera->setAllowEventFocus(false);
|
|
||||||
|
|
||||||
mParent->addChild(mMenuCamera);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenXRMenu::~OpenXRMenu()
|
OpenXRMenu::~OpenXRMenu()
|
||||||
{
|
{
|
||||||
mParent->removeChild(mTransform);
|
mParent->removeChild(mTransform);
|
||||||
mParent->removeChild(mMenuCamera);
|
mParent->removeChild(mMenuCamera.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRMenu::updateCallback()
|
void OpenXRMenu::updateCallback()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRMenu::postRenderCallback(osg::RenderInfo& renderInfo)
|
osg::Camera* OpenXRMenu::camera()
|
||||||
{
|
{
|
||||||
Log(Debug::Verbose) << "Menu: PostRender";
|
return mMenuCamera.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Texture2D> OpenXRMenu::menuTexture()
|
||||||
|
{
|
||||||
|
if (mMenuCamera)
|
||||||
|
return mMenuCamera->getMenuTexture();
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRMenu::updatePose(Pose pose)
|
void OpenXRMenu::updatePose(Pose pose)
|
||||||
|
@ -164,10 +205,6 @@ namespace MWVR
|
||||||
mTransform->setPosition(pose.position);
|
mTransform->setPosition(pose.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRMenu::preRenderCallback(osg::RenderInfo& renderInfo)
|
|
||||||
{
|
|
||||||
Log(Debug::Verbose) << "Menu: PreRender";
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenXRMenuManager::OpenXRMenuManager(
|
OpenXRMenuManager::OpenXRMenuManager(
|
||||||
osg::ref_ptr<osgViewer::Viewer> viewer)
|
osg::ref_ptr<osgViewer::Viewer> viewer)
|
||||||
|
|
|
@ -13,12 +13,14 @@
|
||||||
struct XrCompositionLayerQuad;
|
struct XrCompositionLayerQuad;
|
||||||
namespace MWVR
|
namespace MWVR
|
||||||
{
|
{
|
||||||
|
class Menus;
|
||||||
|
|
||||||
class OpenXRMenu
|
class OpenXRMenu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenXRMenu(
|
OpenXRMenu(
|
||||||
osg::ref_ptr<osg::Group> parent,
|
osg::ref_ptr<osg::Group> parent,
|
||||||
osg::ref_ptr<osg::Group> menuSubgraph,
|
osg::ref_ptr<osg::Node> menuSubgraph,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
osg::Vec2 extent_meters,
|
osg::Vec2 extent_meters,
|
||||||
Pose pose,
|
Pose pose,
|
||||||
|
@ -32,21 +34,22 @@ namespace MWVR
|
||||||
|
|
||||||
void preRenderCallback(osg::RenderInfo& renderInfo);
|
void preRenderCallback(osg::RenderInfo& renderInfo);
|
||||||
void postRenderCallback(osg::RenderInfo& renderInfo);
|
void postRenderCallback(osg::RenderInfo& renderInfo);
|
||||||
osg::Camera* camera() { return mMenuCamera; }
|
osg::Camera* camera();
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Texture2D> menuTexture();
|
||||||
|
|
||||||
void updatePose(Pose pose);
|
void updatePose(Pose pose);
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
std::string mTitle;
|
std::string mTitle;
|
||||||
osg::ref_ptr<osg::Group> mParent;
|
osg::ref_ptr<osg::Group> mParent;
|
||||||
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
||||||
osg::ref_ptr<osg::Geode> mGeode{ new osg::Geode };
|
osg::ref_ptr<osg::Geode> mGeode{ new osg::Geode };
|
||||||
osg::ref_ptr<osg::PositionAttitudeTransform> mTransform{ new osg::PositionAttitudeTransform };
|
osg::ref_ptr<osg::PositionAttitudeTransform> mTransform{ new osg::PositionAttitudeTransform };
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> mMenuSubgraph;
|
osg::ref_ptr<osg::Node> mMenuSubgraph;
|
||||||
osg::ref_ptr<osg::Camera> mMenuCamera{ new osg::Camera };
|
|
||||||
osg::ref_ptr<osg::Texture2D> mMenuTexture{ new osg::Texture2D };
|
|
||||||
osg::ref_ptr<osg::StateSet> mStateSet{ new osg::StateSet };
|
osg::ref_ptr<osg::StateSet> mStateSet{ new osg::StateSet };
|
||||||
|
osg::ref_ptr<Menus> mMenuCamera;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenXRMenuManager
|
class OpenXRMenuManager
|
||||||
|
@ -61,11 +64,13 @@ namespace MWVR
|
||||||
|
|
||||||
void updatePose(void);
|
void updatePose(void);
|
||||||
|
|
||||||
|
OpenXRMenu* getMenu(void) const { return mMenu.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pose mPose{};
|
Pose mPose{};
|
||||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
||||||
osg::ref_ptr<osg::Group> mMenusRoot{ new osg::Group };
|
osg::ref_ptr<osg::Group> mMenusRoot{ new osg::Group };
|
||||||
osg::ref_ptr<osg::Group> mGuiRoot{ new osg::Group };
|
osg::ref_ptr<osg::Node> mGuiRoot{ nullptr };
|
||||||
std::unique_ptr<OpenXRMenu> mMenu{ nullptr };
|
std::unique_ptr<OpenXRMenu> mMenu{ nullptr };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,8 @@ namespace MWVR
|
||||||
auto state = gc->getState();
|
auto state = gc->getState();
|
||||||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFBO);
|
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFBO);
|
||||||
|
|
||||||
|
Log(Debug::Verbose) << "Bound FBO: " << mFBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRTextureBuffer::endFrame(osg::GraphicsContext* gc, uint32_t blitTarget)
|
void OpenXRTextureBuffer::endFrame(osg::GraphicsContext* gc, uint32_t blitTarget)
|
||||||
|
@ -130,4 +132,17 @@ namespace MWVR
|
||||||
gl->glBlitFramebuffer(0, 0, mWidth, mHeight, x, y, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
gl->glBlitFramebuffer(0, 0, mWidth, mHeight, x, y, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenXRTextureBuffer::blit(osg::GraphicsContext* gc, int x, int y, int w, int h, int blitTarget)
|
||||||
|
{
|
||||||
|
auto* state = gc->getState();
|
||||||
|
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||||
|
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, mBlitFBO);
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, mFBO);
|
||||||
|
gl->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, blitTarget, 0);
|
||||||
|
gl->glBlitFramebuffer(0, 0, mWidth, mHeight, x, y, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
gl->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
|
||||||
|
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,11 @@ namespace MWVR
|
||||||
void endFrame(osg::GraphicsContext* gc, uint32_t blitTarget);
|
void endFrame(osg::GraphicsContext* gc, uint32_t blitTarget);
|
||||||
|
|
||||||
uint32_t fbo(void) const { return mFBO; }
|
uint32_t fbo(void) const { return mFBO; }
|
||||||
|
uint32_t colorBuffer(void) const { return mColorBuffer; }
|
||||||
|
|
||||||
//! Blit to region in currently bound draw fbo
|
//! Blit to region in currently bound draw fbo
|
||||||
void blit(osg::GraphicsContext* gc, int x, int y, int w, int h);
|
void blit(osg::GraphicsContext* gc, int x, int y, int w, int h);
|
||||||
|
void blit(osg::GraphicsContext* gc, int x, int y, int w, int h, int target);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Set aside a weak pointer to the constructor state to use when freeing FBOs, if no state is given to destroy()
|
// Set aside a weak pointer to the constructor state to use when freeing FBOs, if no state is given to destroy()
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace MWVR {
|
||||||
camera->setClearColor(clearColor);
|
camera->setClearColor(clearColor);
|
||||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||||
camera->setRenderOrder(osg::Camera::PRE_RENDER, eye);
|
camera->setRenderOrder(osg::Camera::PRE_RENDER, eye + 2);
|
||||||
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||||
camera->setAllowEventFocus(false);
|
camera->setAllowEventFocus(false);
|
||||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||||
|
@ -50,8 +50,12 @@ namespace MWVR {
|
||||||
return camera.release();
|
return camera.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLint wfbo = 0;
|
||||||
|
static GLint rfbo = 0;
|
||||||
void OpenXRView::prerenderCallback(osg::RenderInfo& renderInfo)
|
void OpenXRView::prerenderCallback(osg::RenderInfo& renderInfo)
|
||||||
{
|
{
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &wfbo);
|
||||||
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfbo);
|
||||||
if (mSwapchain)
|
if (mSwapchain)
|
||||||
{
|
{
|
||||||
mSwapchain->beginFrame(renderInfo.getState()->getGraphicsContext());
|
mSwapchain->beginFrame(renderInfo.getState()->getGraphicsContext());
|
||||||
|
@ -66,6 +70,10 @@ namespace MWVR {
|
||||||
|
|
||||||
mTimer.checkpoint("Postrender");
|
mTimer.checkpoint("Postrender");
|
||||||
Log(Debug::Verbose) << "XRView: PostRender";
|
Log(Debug::Verbose) << "XRView: PostRender";
|
||||||
|
auto state = renderInfo.getState();
|
||||||
|
auto gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||||
|
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, wfbo);
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, rfbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRView::swapBuffers(osg::GraphicsContext* gc)
|
void OpenXRView::swapBuffers(osg::GraphicsContext* gc)
|
||||||
|
|
|
@ -123,12 +123,14 @@ namespace MWVR
|
||||||
leftCamera->setPreDrawCallback(mPreDraw);
|
leftCamera->setPreDrawCallback(mPreDraw);
|
||||||
rightCamera->setPreDrawCallback(mPreDraw);
|
rightCamera->setPreDrawCallback(mPreDraw);
|
||||||
|
|
||||||
leftCamera->setPostDrawCallback(mPostDraw);
|
//leftCamera->setPostDrawCallback(mPostDraw);
|
||||||
rightCamera->setPostDrawCallback(mPostDraw);
|
//rightCamera->setPostDrawCallback(mPostDraw);
|
||||||
|
leftCamera->setFinalDrawCallback(mPostDraw);
|
||||||
|
rightCamera->setFinalDrawCallback(mPostDraw);
|
||||||
|
|
||||||
// Stereo cameras should only draw the scene (AR layers should later add minimap, health, etc.)
|
// Stereo cameras should only draw the scene (AR layers should later add minimap, health, etc.)
|
||||||
//leftCamera->setCullMask(~MWRender::Mask_GUI);
|
leftCamera->setCullMask(~MWRender::Mask_GUI);
|
||||||
//rightCamera->setCullMask(~MWRender::Mask_GUI);
|
rightCamera->setCullMask(~MWRender::Mask_GUI);
|
||||||
|
|
||||||
leftCamera->setName("LeftEye");
|
leftCamera->setName("LeftEye");
|
||||||
rightCamera->setName("RightEye");
|
rightCamera->setName("RightEye");
|
||||||
|
@ -153,19 +155,6 @@ namespace MWVR
|
||||||
// It's just convenient.
|
// It's just convenient.
|
||||||
mMirrorTextureSwapchain.reset(new OpenXRSwapchain(xr, context->getState(), config));
|
mMirrorTextureSwapchain.reset(new OpenXRSwapchain(xr, context->getState(), config));
|
||||||
|
|
||||||
//auto menuView = new OpenXRMenu(xr, config, context->getState(), "MainMenu", osg::Vec2(1.f, 1.f));
|
|
||||||
//mViews["MenuView"] = menuView;
|
|
||||||
//auto menuCamera = mCameras["MenuView"] = menuView->createCamera(2, clearColor, context);
|
|
||||||
|
|
||||||
//mMenus.reset(new OpenXRMenu(mMenusRoot, "MainMenu", osg::Vec2(1.f, 1.f), MWVR::Pose(), config.width, config.height, osg::Vec4(0.f, 0.f, 0.f, 0.f), context));
|
|
||||||
//auto menuCamera = mMenus->camera();
|
|
||||||
//menuCamera->setCullMask(MWRender::Mask_GUI);
|
|
||||||
//menuCamera->setName("MenuView");
|
|
||||||
//menuCamera->setPreDrawCallback(mPreDraw);
|
|
||||||
//menuCamera->setPostDrawCallback(mPostDraw);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//mViewer->addSlave(menuCamera, true);
|
//mViewer->addSlave(menuCamera, true);
|
||||||
mViewer->getSlave(0)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, leftView, context);
|
mViewer->getSlave(0)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, leftView, context);
|
||||||
mViewer->getSlave(1)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, rightView, context);
|
mViewer->getSlave(1)._updateSlaveCallback = new OpenXRWorldView::UpdateSlaveCallback(xr, session, rightView, context);
|
||||||
|
@ -173,14 +162,13 @@ namespace MWVR
|
||||||
mainCamera->getGraphicsContext()->setSwapCallback(new OpenXRViewer::SwapBuffersCallback(this));
|
mainCamera->getGraphicsContext()->setSwapCallback(new OpenXRViewer::SwapBuffersCallback(this));
|
||||||
mainCamera->setGraphicsContext(nullptr);
|
mainCamera->setGraphicsContext(nullptr);
|
||||||
session->setLayer(OpenXRLayerStack::WORLD_VIEW_LAYER, this);
|
session->setLayer(OpenXRLayerStack::WORLD_VIEW_LAYER, this);
|
||||||
//session->setLayer(OpenXRLayerStack::MENU_VIEW_LAYER, dynamic_cast<OpenXRLayer*>(mViews["MenuView"].get()));
|
|
||||||
mConfigured = true;
|
mConfigured = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXRViewer::blitEyesToMirrorTexture(osg::GraphicsContext* gc, bool includeMenu)
|
void OpenXRViewer::blitEyesToMirrorTexture(osg::GraphicsContext* gc, bool includeMenu)
|
||||||
{
|
{
|
||||||
includeMenu = false;
|
//includeMenu = false;
|
||||||
mMirrorTextureSwapchain->beginFrame(gc);
|
mMirrorTextureSwapchain->beginFrame(gc);
|
||||||
|
|
||||||
int mirror_width = 0;
|
int mirror_width = 0;
|
||||||
|
@ -193,15 +181,51 @@ namespace MWVR
|
||||||
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTextureSwapchain->height());
|
||||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTextureSwapchain->height());
|
||||||
|
|
||||||
//if(includeMenu)
|
auto* state = gc->getState();
|
||||||
// mViews["MenuView"]->swapchain().renderBuffer()->blit(gc, 2 * mirror_width, 0, 3 * mirror_width, mMirrorTextureSwapchain->height());
|
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||||
|
|
||||||
|
if (includeMenu)
|
||||||
|
{
|
||||||
|
auto menuManager = OpenXREnvironment::get().getMenuManager();
|
||||||
|
if (menuManager)
|
||||||
|
{
|
||||||
|
auto menu = menuManager->getMenu();
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
auto texture = menu->menuTexture();
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
auto textureObject = texture->getTextureObject(state->getContextID());
|
||||||
|
if (textureObject)
|
||||||
|
{
|
||||||
|
auto textureId = textureObject->id();
|
||||||
|
|
||||||
|
Log(Debug::Verbose) << "texture id: " << textureId;
|
||||||
|
|
||||||
|
GLuint fbo = 0;
|
||||||
|
gl->glGenFramebuffers(1, &fbo);
|
||||||
|
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fbo);
|
||||||
|
gl->glFramebufferTexture2D(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0);
|
||||||
|
gl->glBlitFramebuffer(0, 0, texture->getTextureWidth(), texture->getTextureHeight(), 2 * mirror_width, 0, 3 * mirror_width, mMirrorTextureSwapchain->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
gl->glFramebufferTexture2D(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
|
gl->glDeleteFramebuffers(1, &fbo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Debug::Warning) << "Texture object was null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mMirrorTextureSwapchain->endFrame(gc);
|
mMirrorTextureSwapchain->endFrame(gc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto* state = gc->getState();
|
|
||||||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
|
||||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||||
mMirrorTextureSwapchain->renderBuffer()->blit(gc, 0, 0, mMirrorTextureSwapchain->width(), mMirrorTextureSwapchain->height());
|
mMirrorTextureSwapchain->renderBuffer()->blit(gc, 0, 0, mMirrorTextureSwapchain->width(), mMirrorTextureSwapchain->height());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue