mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 20:49:56 +00:00
Swapchain refactoring. Use of multisampling. Msaa resolve steps for mirror textures.
This commit is contained in:
parent
df45ee1690
commit
e3c460ae35
8 changed files with 236 additions and 180 deletions
|
@ -132,6 +132,8 @@ if(BUILD_VR_OPENXR)
|
|||
mwvr/openxrmanagerimpl.cpp
|
||||
mwvr/openxrswapchain.hpp
|
||||
mwvr/openxrswapchain.cpp
|
||||
mwvr/openxrswapchainimpl.hpp
|
||||
mwvr/openxrswapchainimpl.cpp
|
||||
mwvr/realisticcombat.hpp
|
||||
mwvr/realisticcombat.cpp
|
||||
mwvr/vranimation.hpp
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "openxrmanagerimpl.hpp"
|
||||
#include "openxrswapchain.hpp"
|
||||
#include "openxrswapchainimpl.hpp"
|
||||
#include "vrtexture.hpp"
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "openxrswapchain.hpp"
|
||||
#include "openxrswapchainimpl.hpp"
|
||||
#include "openxrmanager.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "vrenvironment.hpp"
|
||||
|
@ -13,169 +14,6 @@
|
|||
#include <openxr/openxr_reflection.h>
|
||||
|
||||
namespace MWVR {
|
||||
|
||||
class OpenXRSwapchainImpl
|
||||
{
|
||||
public:
|
||||
enum SubView
|
||||
{
|
||||
LEFT_VIEW = 0,
|
||||
RIGHT_VIEW = 1,
|
||||
SUBVIEW_MAX = RIGHT_VIEW, //!< Used to size subview arrays. Not a valid input.
|
||||
};
|
||||
|
||||
OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config);
|
||||
~OpenXRSwapchainImpl();
|
||||
|
||||
void beginFrame(osg::GraphicsContext* gc);
|
||||
void endFrame(osg::GraphicsContext* gc);
|
||||
void acquire(osg::GraphicsContext* gc);
|
||||
void release(osg::GraphicsContext* gc);
|
||||
|
||||
VRTexture* renderBuffer() const;
|
||||
|
||||
uint32_t acquiredImage() const;
|
||||
|
||||
bool isAcquired() const;
|
||||
|
||||
XrSwapchain mSwapchain = XR_NULL_HANDLE;
|
||||
std::vector<XrSwapchainImageOpenGLKHR> mSwapchainImageBuffers{};
|
||||
//std::vector<osg::ref_ptr<VRTexture> > mTextureBuffers{};
|
||||
XrSwapchainSubImage mSubImage{};
|
||||
int32_t mWidth = -1;
|
||||
int32_t mHeight = -1;
|
||||
int32_t mSamples = -1;
|
||||
int64_t mSwapchainColorFormat = -1;
|
||||
uint32_t mFBO = 0;
|
||||
std::vector<std::unique_ptr<VRTexture> > mRenderBuffers{};
|
||||
int mRenderBuffer{ 0 };
|
||||
uint32_t mAcquiredImageIndex{ 0 };
|
||||
bool mIsAcquired{ false };
|
||||
};
|
||||
|
||||
OpenXRSwapchainImpl::OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mWidth(config.recommendedWidth)
|
||||
, mHeight(config.recommendedHeight)
|
||||
, mSamples(config.recommendedSamples)
|
||||
{
|
||||
if (mWidth <= 0)
|
||||
throw std::invalid_argument("Width must be a positive integer");
|
||||
if (mHeight <= 0)
|
||||
throw std::invalid_argument("Height must be a positive integer");
|
||||
if (mSamples <= 0)
|
||||
throw std::invalid_argument("Samples must be a positive integer");
|
||||
|
||||
auto* xr = Environment::get().getManager();
|
||||
|
||||
// Select a swapchain format.
|
||||
uint32_t swapchainFormatCount;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), 0, &swapchainFormatCount, nullptr));
|
||||
std::vector<int64_t> swapchainFormats(swapchainFormatCount);
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), (uint32_t)swapchainFormats.size(), &swapchainFormatCount, swapchainFormats.data()));
|
||||
|
||||
// List of supported color swapchain formats.
|
||||
constexpr int64_t SupportedColorSwapchainFormats[] = {
|
||||
GL_RGBA8,
|
||||
GL_RGBA8_SNORM,
|
||||
};
|
||||
|
||||
auto swapchainFormatIt =
|
||||
std::find_first_of(swapchainFormats.begin(), swapchainFormats.end(), std::begin(SupportedColorSwapchainFormats),
|
||||
std::end(SupportedColorSwapchainFormats));
|
||||
if (swapchainFormatIt == swapchainFormats.end()) {
|
||||
Log(Debug::Error) << "No swapchain format supported at runtime";
|
||||
}
|
||||
|
||||
mSwapchainColorFormat = *swapchainFormatIt;
|
||||
|
||||
Log(Debug::Verbose) << "Creating swapchain with dimensions Width=" << mWidth << " Heigh=" << mHeight << " SampleCount=" << mSamples;
|
||||
|
||||
// Create the swapchain.
|
||||
XrSwapchainCreateInfo swapchainCreateInfo{ XR_TYPE_SWAPCHAIN_CREATE_INFO };
|
||||
swapchainCreateInfo.arraySize = 1;
|
||||
swapchainCreateInfo.format = mSwapchainColorFormat;
|
||||
swapchainCreateInfo.width = mWidth;
|
||||
swapchainCreateInfo.height = mHeight;
|
||||
swapchainCreateInfo.mipCount = 1;
|
||||
swapchainCreateInfo.faceCount = 1;
|
||||
swapchainCreateInfo.sampleCount = mSamples;
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
CHECK_XRCMD(xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchain));
|
||||
|
||||
uint32_t imageCount = 0;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, 0, &imageCount, nullptr));
|
||||
|
||||
mSwapchainImageBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR });
|
||||
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mSwapchainImageBuffers.data())));
|
||||
//for (const auto& swapchainImage : mSwapchainImageBuffers)
|
||||
// mTextureBuffers.push_back(new VRTexture(state, swapchainImage.image, mWidth, mHeight, 0));
|
||||
for (unsigned i = 0; i < imageCount; i++)
|
||||
mRenderBuffers.emplace_back(new VRTexture(state, mWidth, mHeight, 0));
|
||||
|
||||
mSubImage.swapchain = mSwapchain;
|
||||
mSubImage.imageRect.offset = { 0, 0 };
|
||||
mSubImage.imageRect.extent = { mWidth, mHeight };
|
||||
}
|
||||
|
||||
OpenXRSwapchainImpl::~OpenXRSwapchainImpl()
|
||||
{
|
||||
if (mSwapchain)
|
||||
CHECK_XRCMD(xrDestroySwapchain(mSwapchain));
|
||||
}
|
||||
|
||||
VRTexture* OpenXRSwapchainImpl::renderBuffer() const
|
||||
{
|
||||
return mRenderBuffers[mRenderBuffer].get();
|
||||
}
|
||||
|
||||
uint32_t OpenXRSwapchainImpl::acquiredImage() const
|
||||
{
|
||||
if(isAcquired())
|
||||
return mSwapchainImageBuffers[mAcquiredImageIndex].image;
|
||||
throw std::logic_error("Swapbuffer not acquired before use");
|
||||
}
|
||||
|
||||
bool OpenXRSwapchainImpl::isAcquired() const
|
||||
{
|
||||
return mIsAcquired;
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::beginFrame(osg::GraphicsContext* gc)
|
||||
{
|
||||
mRenderBuffer = (mRenderBuffer + 1) % mRenderBuffers.size();
|
||||
renderBuffer()->beginFrame(gc);
|
||||
}
|
||||
|
||||
int swapCount = 0;
|
||||
|
||||
void OpenXRSwapchainImpl::endFrame(osg::GraphicsContext* gc)
|
||||
{
|
||||
// Blit frame to swapchain
|
||||
acquire(gc);
|
||||
renderBuffer()->endFrame(gc, acquiredImage());
|
||||
release(gc);
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::acquire(osg::GraphicsContext* gc)
|
||||
{
|
||||
XrSwapchainImageAcquireInfo acquireInfo{ XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO };
|
||||
CHECK_XRCMD(xrAcquireSwapchainImage(mSwapchain, &acquireInfo, &mAcquiredImageIndex));
|
||||
|
||||
XrSwapchainImageWaitInfo waitInfo{ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO };
|
||||
waitInfo.timeout = XR_INFINITE_DURATION;
|
||||
CHECK_XRCMD(xrWaitSwapchainImage(mSwapchain, &waitInfo));
|
||||
|
||||
mIsAcquired = true;
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::release(osg::GraphicsContext* gc)
|
||||
{
|
||||
mIsAcquired = false;
|
||||
|
||||
XrSwapchainImageReleaseInfo releaseInfo{ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO };
|
||||
CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchain, &releaseInfo));
|
||||
}
|
||||
|
||||
OpenXRSwapchain::OpenXRSwapchain(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mPrivate(new OpenXRSwapchainImpl(state, config))
|
||||
{
|
||||
|
@ -205,12 +43,6 @@ namespace MWVR {
|
|||
return impl().release(gc);
|
||||
}
|
||||
|
||||
const XrSwapchainSubImage&
|
||||
OpenXRSwapchain::subImage(void) const
|
||||
{
|
||||
return impl().mSubImage;
|
||||
}
|
||||
|
||||
uint32_t OpenXRSwapchain::acquiredImage() const
|
||||
{
|
||||
return impl().acquiredImage();
|
||||
|
@ -218,17 +50,17 @@ namespace MWVR {
|
|||
|
||||
int OpenXRSwapchain::width() const
|
||||
{
|
||||
return impl().mWidth;
|
||||
return impl().width();
|
||||
}
|
||||
|
||||
int OpenXRSwapchain::height() const
|
||||
{
|
||||
return impl().mHeight;
|
||||
return impl().height();
|
||||
}
|
||||
|
||||
int OpenXRSwapchain::samples() const
|
||||
{
|
||||
return impl().mSamples;
|
||||
return impl().samples();
|
||||
}
|
||||
|
||||
bool OpenXRSwapchain::isAcquired() const
|
||||
|
|
|
@ -33,8 +33,6 @@ namespace MWVR
|
|||
void acquire(osg::GraphicsContext* gc);
|
||||
//! Finalize render
|
||||
void release(osg::GraphicsContext* gc);
|
||||
//! Get the view surface
|
||||
const XrSwapchainSubImage& subImage(void) const;
|
||||
//! Currently acquired image
|
||||
uint32_t acquiredImage() const;
|
||||
//! Whether subchain is currently acquired (true) or released (false)
|
||||
|
|
152
apps/openmw/mwvr/openxrswapchainimpl.cpp
Normal file
152
apps/openmw/mwvr/openxrswapchainimpl.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "openxrswapchainimpl.hpp"
|
||||
#include "vrenvironment.hpp"
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <openxr/openxr.h>
|
||||
#include <openxr/openxr_platform.h>
|
||||
#include <openxr/openxr_platform_defines.h>
|
||||
#include <openxr/openxr_reflection.h>
|
||||
|
||||
namespace MWVR {
|
||||
|
||||
|
||||
OpenXRSwapchainImpl::OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config)
|
||||
: mWidth((int)config.recommendedWidth)
|
||||
, mHeight((int)config.recommendedHeight)
|
||||
, mSamples((int)config.recommendedSamples)
|
||||
{
|
||||
if (mWidth <= 0)
|
||||
throw std::invalid_argument("Width must be a positive integer");
|
||||
if (mHeight <= 0)
|
||||
throw std::invalid_argument("Height must be a positive integer");
|
||||
if (mSamples <= 0)
|
||||
throw std::invalid_argument("Samples must be a positive integer");
|
||||
|
||||
auto* xr = Environment::get().getManager();
|
||||
|
||||
// Select a swapchain format.
|
||||
uint32_t swapchainFormatCount;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), 0, &swapchainFormatCount, nullptr));
|
||||
std::vector<int64_t> swapchainFormats(swapchainFormatCount);
|
||||
CHECK_XRCMD(xrEnumerateSwapchainFormats(xr->impl().xrSession(), (uint32_t)swapchainFormats.size(), &swapchainFormatCount, swapchainFormats.data()));
|
||||
|
||||
// List of supported color swapchain formats.
|
||||
constexpr int64_t SupportedColorSwapchainFormats[] = {
|
||||
GL_RGBA8,
|
||||
GL_RGBA8_SNORM,
|
||||
};
|
||||
|
||||
auto swapchainFormatIt =
|
||||
std::find_first_of(swapchainFormats.begin(), swapchainFormats.end(), std::begin(SupportedColorSwapchainFormats),
|
||||
std::end(SupportedColorSwapchainFormats));
|
||||
if (swapchainFormatIt == swapchainFormats.end()) {
|
||||
Log(Debug::Error) << "No swapchain format supported at runtime";
|
||||
}
|
||||
|
||||
mSwapchainColorFormat = *swapchainFormatIt;
|
||||
|
||||
mSamples = Settings::Manager::getInt("antialiasing", "Video");
|
||||
|
||||
while (mSamples > 0)
|
||||
{
|
||||
Log(Debug::Verbose) << "Creating swapchain with dimensions Width=" << mWidth << " Heigh=" << mHeight << " SampleCount=" << mSamples;
|
||||
// Create the swapchain.
|
||||
XrSwapchainCreateInfo swapchainCreateInfo{ XR_TYPE_SWAPCHAIN_CREATE_INFO };
|
||||
swapchainCreateInfo.arraySize = 1;
|
||||
swapchainCreateInfo.format = mSwapchainColorFormat;
|
||||
swapchainCreateInfo.width = mWidth;
|
||||
swapchainCreateInfo.height = mHeight;
|
||||
swapchainCreateInfo.mipCount = 1;
|
||||
swapchainCreateInfo.faceCount = 1;
|
||||
swapchainCreateInfo.sampleCount = 1;
|
||||
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
//CHECK_XRCMD(xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchain));
|
||||
auto res = xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchain);
|
||||
if (XR_SUCCEEDED(res))
|
||||
break;
|
||||
else
|
||||
{
|
||||
Log(Debug::Verbose) << "Failed to create swapchain with SampleCount=" << mSamples << ": " << XrResultString(res);
|
||||
mSamples /= 2;
|
||||
if(mSamples == 0)
|
||||
std::runtime_error(XrResultString(res));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t imageCount = 0;
|
||||
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, 0, &imageCount, nullptr));
|
||||
|
||||
mSwapchainImageBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR });
|
||||
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mSwapchainImageBuffers.data())));
|
||||
//for (const auto& swapchainImage : mSwapchainImageBuffers)
|
||||
// mTextureBuffers.push_back(new VRTexture(state, swapchainImage.image, mWidth, mHeight, 0));
|
||||
for (unsigned i = 0; i < imageCount; i++)
|
||||
mRenderBuffers.emplace_back(new VRTexture(state, mWidth, mHeight, mSamples));
|
||||
|
||||
mSubImage.swapchain = mSwapchain;
|
||||
mSubImage.imageRect.offset = { 0, 0 };
|
||||
mSubImage.imageRect.extent = { mWidth, mHeight };
|
||||
}
|
||||
|
||||
OpenXRSwapchainImpl::~OpenXRSwapchainImpl()
|
||||
{
|
||||
if (mSwapchain)
|
||||
CHECK_XRCMD(xrDestroySwapchain(mSwapchain));
|
||||
}
|
||||
|
||||
VRTexture* OpenXRSwapchainImpl::renderBuffer() const
|
||||
{
|
||||
return mRenderBuffers[mRenderBuffer].get();
|
||||
}
|
||||
|
||||
uint32_t OpenXRSwapchainImpl::acquiredImage() const
|
||||
{
|
||||
if(isAcquired())
|
||||
return mSwapchainImageBuffers[mAcquiredImageIndex].image;
|
||||
throw std::logic_error("Swapbuffer not acquired before use");
|
||||
}
|
||||
|
||||
bool OpenXRSwapchainImpl::isAcquired() const
|
||||
{
|
||||
return mIsAcquired;
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::beginFrame(osg::GraphicsContext* gc)
|
||||
{
|
||||
mRenderBuffer = (mRenderBuffer + 1) % mRenderBuffers.size();
|
||||
renderBuffer()->beginFrame(gc);
|
||||
}
|
||||
|
||||
int swapCount = 0;
|
||||
|
||||
void OpenXRSwapchainImpl::endFrame(osg::GraphicsContext* gc)
|
||||
{
|
||||
// Blit frame to swapchain
|
||||
acquire(gc);
|
||||
renderBuffer()->endFrame(gc, acquiredImage());
|
||||
release(gc);
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::acquire(osg::GraphicsContext* gc)
|
||||
{
|
||||
XrSwapchainImageAcquireInfo acquireInfo{ XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO };
|
||||
CHECK_XRCMD(xrAcquireSwapchainImage(mSwapchain, &acquireInfo, &mAcquiredImageIndex));
|
||||
|
||||
XrSwapchainImageWaitInfo waitInfo{ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO };
|
||||
waitInfo.timeout = XR_INFINITE_DURATION;
|
||||
CHECK_XRCMD(xrWaitSwapchainImage(mSwapchain, &waitInfo));
|
||||
|
||||
mIsAcquired = true;
|
||||
}
|
||||
|
||||
void OpenXRSwapchainImpl::release(osg::GraphicsContext* gc)
|
||||
{
|
||||
mIsAcquired = false;
|
||||
|
||||
XrSwapchainImageReleaseInfo releaseInfo{ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO };
|
||||
CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchain, &releaseInfo));
|
||||
}
|
||||
}
|
50
apps/openmw/mwvr/openxrswapchainimpl.hpp
Normal file
50
apps/openmw/mwvr/openxrswapchainimpl.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef OPENXR_SWAPCHAINIMPL_HPP
|
||||
#define OPENXR_SWAPCHAINIMPL_HPP
|
||||
|
||||
#include "openxrswapchain.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
|
||||
struct XrSwapchainSubImage;
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
||||
class OpenXRSwapchainImpl
|
||||
{
|
||||
public:
|
||||
OpenXRSwapchainImpl(osg::ref_ptr<osg::State> state, SwapchainConfig config);
|
||||
~OpenXRSwapchainImpl();
|
||||
|
||||
void beginFrame(osg::GraphicsContext* gc);
|
||||
void endFrame(osg::GraphicsContext* gc);
|
||||
void acquire(osg::GraphicsContext* gc);
|
||||
void release(osg::GraphicsContext* gc);
|
||||
|
||||
VRTexture* renderBuffer() const;
|
||||
|
||||
uint32_t acquiredImage() const;
|
||||
|
||||
bool isAcquired() const;
|
||||
XrSwapchain xrSwapchain(void) const { return mSwapchain; };
|
||||
XrSwapchainSubImage xrSubImage(void) const { return mSubImage; };
|
||||
int width() const { return mWidth; };
|
||||
int height() const { return mHeight; };
|
||||
int samples() const { return mSamples; };
|
||||
|
||||
XrSwapchain mSwapchain = XR_NULL_HANDLE;
|
||||
std::vector<XrSwapchainImageOpenGLKHR> mSwapchainImageBuffers{};
|
||||
//std::vector<osg::ref_ptr<VRTexture> > mTextureBuffers{};
|
||||
XrSwapchainSubImage mSubImage{};
|
||||
int32_t mWidth = -1;
|
||||
int32_t mHeight = -1;
|
||||
int32_t mSamples = -1;
|
||||
int64_t mSwapchainColorFormat = -1;
|
||||
uint32_t mFBO = 0;
|
||||
std::vector<std::unique_ptr<VRTexture> > mRenderBuffers{};
|
||||
int mRenderBuffer{ 0 };
|
||||
uint32_t mAcquiredImageIndex{ 0 };
|
||||
bool mIsAcquired{ false };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -112,6 +112,14 @@ namespace MWVR
|
|||
mViewer->setReleaseContextAtEndOfFrameHint(false);
|
||||
|
||||
mMirrorTexture.reset(new VRTexture(context->getState(), mainCamera->getViewport()->width(), mainCamera->getViewport()->height(), 0));
|
||||
mMsaaResolveMirrorTexture[(int)Side::LEFT_SIDE].reset(new VRTexture(context->getState(),
|
||||
leftView->swapchain().width(),
|
||||
leftView->swapchain().height(),
|
||||
0));
|
||||
mMsaaResolveMirrorTexture[(int)Side::RIGHT_SIDE].reset(new VRTexture(context->getState(),
|
||||
rightView->swapchain().width(),
|
||||
rightView->swapchain().height(),
|
||||
0));
|
||||
|
||||
mViewer->getSlave(0)._updateSlaveCallback = new VRView::UpdateSlaveCallback(leftView, context);
|
||||
mViewer->getSlave(1)._updateSlaveCallback = new VRView::UpdateSlaveCallback(rightView, context);
|
||||
|
@ -138,15 +146,26 @@ namespace MWVR
|
|||
{
|
||||
auto* state = gc->getState();
|
||||
auto* gl = osg::GLExtensions::Get(state->getContextID(), false);
|
||||
int mirror_width = mMirrorTexture->width() / 2;
|
||||
mMirrorTexture->beginFrame(gc);
|
||||
|
||||
mViews["RightEye"]->swapchain().renderBuffer()->blit(gc, 0, 0, mirror_width, mMirrorTexture->height());
|
||||
mViews["LeftEye"]->swapchain().renderBuffer()->blit(gc, mirror_width, 0, 2 * mirror_width, mMirrorTexture->height());
|
||||
int screenWidth = mCameras["MainCamera"]->getViewport()->width();
|
||||
int mirrorWidth = screenWidth / 2;
|
||||
int screenHeight = mCameras["MainCamera"]->getViewport()->height();
|
||||
const char* viewNames[] = {
|
||||
"RightEye",
|
||||
"LeftEye"
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto& resolveTexture = *mMsaaResolveMirrorTexture[i];
|
||||
resolveTexture.beginFrame(gc);
|
||||
mViews[viewNames[i]]->swapchain().renderBuffer()->blit(gc, 0, 0, resolveTexture.width(), resolveTexture.height());
|
||||
mMirrorTexture->beginFrame(gc);
|
||||
resolveTexture.blit(gc, i * mirrorWidth, 0, (i + 1) * mirrorWidth, screenHeight);
|
||||
}
|
||||
|
||||
gl->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
mMirrorTexture->blit(gc, 0, 0, mMirrorTexture->width(), mMirrorTexture->height());
|
||||
|
||||
mMirrorTexture->blit(gc, 0, 0, screenWidth, screenHeight);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -91,6 +91,8 @@ namespace MWVR
|
|||
osg::ref_ptr<PredrawCallback> mPreDraw{ nullptr };
|
||||
osg::ref_ptr<PostdrawCallback> mPostDraw{ nullptr };
|
||||
osg::GraphicsContext* mMainCameraGC{ nullptr };
|
||||
//std::unique_ptr<VRTexture> mMirrorTexture{ nullptr };
|
||||
std::unique_ptr<VRTexture> mMsaaResolveMirrorTexture[2]{ };
|
||||
std::unique_ptr<VRTexture> mMirrorTexture{ nullptr };
|
||||
|
||||
std::mutex mMutex;
|
||||
|
|
Loading…
Reference in a new issue