Merge branch 'master' of https://github.com/highfidelity/hifi into project-freeloco

This commit is contained in:
r3tk0n 2019-04-03 16:17:00 -07:00
commit 17e559f8e8
25 changed files with 445 additions and 223 deletions

View file

@ -497,7 +497,7 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
// it might not fire until after we create a new instance for the same remote avatar, which creates a race
// on the creation of entities for that avatar instance and the deletion of entities for this instance
avatar->removeAvatarEntitiesFromTree();
if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble) {
if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble || removalReason == KillAvatarReason::NoReason) {
emit AvatarInputs::getInstance()->avatarEnteredIgnoreRadius(avatar->getSessionUUID());
emit DependencyManager::get<UsersScriptingInterface>()->enteredIgnoreRadius();

View file

@ -109,7 +109,7 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
return Parent::internalActivate();
}
void Basic2DWindowOpenGLDisplayPlugin::compositeExtra(const gpu::FramebufferPointer& compositeFramebuffer) {
void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() {
#if defined(Q_OS_ANDROID)
auto& virtualPadManager = VirtualPad::Manager::instance();
if(virtualPadManager.getLeftVirtualPad()->isShown()) {
@ -121,7 +121,7 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra(const gpu::FramebufferPoin
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setFramebuffer(compositeFramebuffer);
batch.setFramebuffer(_compositeFramebuffer);
batch.resetViewTransform();
batch.setProjectionTransform(mat4());
batch.setPipeline(_cursorPipeline);
@ -140,7 +140,7 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra(const gpu::FramebufferPoin
});
}
#endif
Parent::compositeExtra(compositeFramebuffer);
Parent::compositeExtra();
}
static const uint32_t MIN_THROTTLE_CHECK_FRAMES = 60;

View file

@ -33,7 +33,7 @@ public:
virtual bool isThrottled() const override;
virtual void compositeExtra(const gpu::FramebufferPointer&) override;
virtual void compositeExtra() override;
virtual void pluginUpdate() override {};

View file

@ -379,6 +379,14 @@ void OpenGLDisplayPlugin::customizeContext() {
scissorState->setDepthTest(gpu::State::DepthTest(false));
scissorState->setScissorEnable(true);
{
#ifdef Q_OS_ANDROID
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB);
#else
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
#endif
_simplePipeline = gpu::Pipeline::create(program, scissorState);
}
{
#ifdef Q_OS_ANDROID
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB);
@ -388,59 +396,29 @@ void OpenGLDisplayPlugin::customizeContext() {
_presentPipeline = gpu::Pipeline::create(program, scissorState);
}
// HUD operator
{
gpu::PipelinePointer hudPipeline;
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
hudPipeline = gpu::Pipeline::create(program, blendState);
}
gpu::PipelinePointer hudMirrorPipeline;
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
hudMirrorPipeline = gpu::Pipeline::create(program, blendState);
}
_hudOperator = [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, const gpu::FramebufferPointer& compositeFramebuffer, bool mirror) {
auto hudStereo = isStereo();
auto hudCompositeFramebufferSize = compositeFramebuffer->getSize();
std::array<glm::ivec4, 2> hudEyeViewports;
for_each_eye([&](Eye eye) {
hudEyeViewports[eye] = eyeViewport(eye);
});
if (hudPipeline && hudTexture) {
batch.enableStereo(false);
batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline);
batch.setResourceTexture(0, hudTexture);
if (hudStereo) {
for_each_eye([&](Eye eye) {
batch.setViewportTransform(hudEyeViewports[eye]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
} else {
batch.setViewportTransform(ivec4(uvec2(0), hudCompositeFramebufferSize));
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
}
};
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
_hudPipeline = gpu::Pipeline::create(program, blendState);
}
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
_mirrorHUDPipeline = gpu::Pipeline::create(program, blendState);
}
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture);
_cursorPipeline = gpu::Pipeline::create(program, blendState);
}
}
updateCompositeFramebuffer();
}
void OpenGLDisplayPlugin::uncustomizeContext() {
_presentPipeline.reset();
_cursorPipeline.reset();
_hudOperator = DEFAULT_HUD_OPERATOR;
_hudPipeline.reset();
_mirrorHUDPipeline.reset();
_compositeFramebuffer.reset();
withPresentThreadLock([&] {
_currentFrame.reset();
_lastFrame = nullptr;
@ -532,16 +510,24 @@ void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const {
});
}
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor) {
renderFromTexture(batch, texture, viewport, scissor, nullptr);
}
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& destFbo, const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) {
void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) {
auto fbo = gpu::FramebufferPointer();
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(destFbo);
batch.setFramebuffer(fbo);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
batch.setStateScissorRect(scissor);
batch.setViewportTransform(viewport);
batch.setResourceTexture(0, texture);
#ifndef USE_GLES
batch.setPipeline(_presentPipeline);
#else
batch.setPipeline(_simplePipeline);
#endif
batch.draw(gpu::TRIANGLE_STRIP, 4);
if (copyFbo) {
gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight());
@ -567,7 +553,7 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur
batch.setViewportTransform(copyFboRect);
batch.setStateScissorRect(copyFboRect);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, {0.0f, 0.0f, 0.0f, 1.0f});
batch.blit(destFbo, sourceRect, copyFbo, copyRect);
batch.blit(fbo, sourceRect, copyFbo, copyRect);
}
}
@ -595,14 +581,41 @@ void OpenGLDisplayPlugin::updateFrameData() {
});
}
void OpenGLDisplayPlugin::compositePointer(const gpu::FramebufferPointer& compositeFramebuffer) {
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> OpenGLDisplayPlugin::getHUDOperator() {
auto hudPipeline = _hudPipeline;
auto hudMirrorPipeline = _mirrorHUDPipeline;
auto hudStereo = isStereo();
auto hudCompositeFramebufferSize = _compositeFramebuffer->getSize();
std::array<glm::ivec4, 2> hudEyeViewports;
for_each_eye([&](Eye eye) {
hudEyeViewports[eye] = eyeViewport(eye);
});
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) {
if (hudPipeline && hudTexture) {
batch.enableStereo(false);
batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline);
batch.setResourceTexture(0, hudTexture);
if (hudStereo) {
for_each_eye([&](Eye eye) {
batch.setViewportTransform(hudEyeViewports[eye]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
} else {
batch.setViewportTransform(ivec4(uvec2(0), hudCompositeFramebufferSize));
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
}
};
}
void OpenGLDisplayPlugin::compositePointer() {
auto& cursorManager = Cursor::Manager::instance();
const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()];
auto cursorTransform = DependencyManager::get<CompositorHelper>()->getReticleTransform(glm::mat4());
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setProjectionTransform(mat4());
batch.setFramebuffer(compositeFramebuffer);
batch.setFramebuffer(_compositeFramebuffer);
batch.setPipeline(_cursorPipeline);
batch.setResourceTexture(0, cursorData.texture);
batch.resetViewTransform();
@ -613,13 +626,34 @@ void OpenGLDisplayPlugin::compositePointer(const gpu::FramebufferPointer& compos
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
} else {
batch.setViewportTransform(ivec4(uvec2(0), compositeFramebuffer->getSize()));
batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize()));
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
});
}
void OpenGLDisplayPlugin::compositeLayers(const gpu::FramebufferPointer& compositeFramebuffer) {
void OpenGLDisplayPlugin::compositeScene() {
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setFramebuffer(_compositeFramebuffer);
batch.setViewportTransform(ivec4(uvec2(), _compositeFramebuffer->getSize()));
batch.setStateScissorRect(ivec4(uvec2(), _compositeFramebuffer->getSize()));
batch.resetViewTransform();
batch.setProjectionTransform(mat4());
batch.setPipeline(_simplePipeline);
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
}
void OpenGLDisplayPlugin::compositeLayers() {
updateCompositeFramebuffer();
{
PROFILE_RANGE_EX(render_detail, "compositeScene", 0xff0077ff, (uint64_t)presentCount())
compositeScene();
}
#ifdef HIFI_ENABLE_NSIGHT_DEBUG
if (false) // do not draw the HUD if running nsight debug
#endif
@ -633,35 +667,23 @@ void OpenGLDisplayPlugin::compositeLayers(const gpu::FramebufferPointer& composi
{
PROFILE_RANGE_EX(render_detail, "compositeExtra", 0xff0077ff, (uint64_t)presentCount())
compositeExtra(compositeFramebuffer);
compositeExtra();
}
// Draw the pointer last so it's on top of everything
auto compositorHelper = DependencyManager::get<CompositorHelper>();
if (compositorHelper->getReticleVisible()) {
PROFILE_RANGE_EX(render_detail, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
compositePointer(compositeFramebuffer);
compositePointer();
}
}
void OpenGLDisplayPlugin::internalPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void OpenGLDisplayPlugin::internalPresent() {
render([&](gpu::Batch& batch) {
// Note: _displayTexture must currently be the same size as the display.
uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels();
auto viewport = ivec4(uvec2(0), dims);
gpu::TexturePointer finalTexture;
if (_displayTexture) {
finalTexture = _displayTexture;
} else if (compositeFramebuffer) {
finalTexture = compositeFramebuffer->getRenderBuffer(0);
} else {
qCWarning(displayPlugins) << "No valid texture for output";
}
if (finalTexture) {
renderFromTexture(batch, finalTexture, viewport, viewport);
}
renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport, viewport);
});
swapBuffers();
_presentRate.increment();
@ -678,7 +700,7 @@ void OpenGLDisplayPlugin::present() {
}
incrementPresentCount();
if (_currentFrame && _currentFrame->framebuffer) {
if (_currentFrame) {
auto correction = getViewCorrection();
getGLBackend()->setCameraCorrection(correction, _prevRenderView);
_prevRenderView = correction * _currentFrame->view;
@ -698,18 +720,18 @@ void OpenGLDisplayPlugin::present() {
// Write all layers to a local framebuffer
{
PROFILE_RANGE_EX(render, "composite", 0xff00ffff, frameId)
compositeLayers(_currentFrame->framebuffer);
compositeLayers();
}
// Take the composite framebuffer and send it to the output device
{
PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId)
internalPresent(_currentFrame->framebuffer);
internalPresent();
}
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
} else if (alwaysPresent()) {
internalPresent(nullptr);
internalPresent();
}
_movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent));
}
@ -766,12 +788,7 @@ bool OpenGLDisplayPlugin::setDisplayTexture(const QString& name) {
}
QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const {
if (!_currentFrame || !_currentFrame->framebuffer) {
return QImage();
}
auto compositeFramebuffer = _currentFrame->framebuffer;
auto size = compositeFramebuffer->getSize();
auto size = _compositeFramebuffer->getSize();
if (isHmd()) {
size.x /= 2;
}
@ -789,7 +806,7 @@ QImage OpenGLDisplayPlugin::getScreenshot(float aspectRatio) const {
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
QImage screenshot(bestSize.x, bestSize.y, QImage::Format_ARGB32);
withOtherThreadContext([&] {
glBackend->downloadFramebuffer(compositeFramebuffer, ivec4(corner, bestSize), screenshot);
glBackend->downloadFramebuffer(_compositeFramebuffer, ivec4(corner, bestSize), screenshot);
});
return screenshot.mirrored(false, true);
}
@ -841,7 +858,7 @@ bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
}
ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye) const {
auto vpSize = glm::uvec2(getRecommendedRenderSize());
uvec2 vpSize = _compositeFramebuffer->getSize();
vpSize.x /= 2;
uvec2 vpPos;
if (eye == Eye::Right) {
@ -874,6 +891,14 @@ void OpenGLDisplayPlugin::render(std::function<void(gpu::Batch& batch)> f) {
OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
}
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
auto renderSize = glm::uvec2(getRecommendedRenderSize());
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
// _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_SRGBA_32, renderSize.x, renderSize.y));
}
}
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) {
#if !defined(USE_GLES)
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();

View file

@ -94,10 +94,14 @@ protected:
// is not populated
virtual bool alwaysPresent() const { return false; }
void updateCompositeFramebuffer();
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
virtual void compositeLayers(const gpu::FramebufferPointer&);
virtual void compositePointer(const gpu::FramebufferPointer&);
virtual void compositeExtra(const gpu::FramebufferPointer&) {};
virtual void compositeLayers();
virtual void compositeScene();
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator();
virtual void compositePointer();
virtual void compositeExtra() {};
// These functions must only be called on the presentation thread
virtual void customizeContext();
@ -112,10 +116,10 @@ protected:
virtual void deactivateSession() {}
// Plugin specific functionality to send the composed scene to the output window or device
virtual void internalPresent(const gpu::FramebufferPointer&);
virtual void internalPresent();
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& destFbo = nullptr, const gpu::FramebufferPointer& copyFbo = nullptr);
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& fbo);
void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor);
virtual void updateFrameData();
virtual glm::mat4 getViewCorrection() { return glm::mat4(); }
@ -138,8 +142,14 @@ protected:
gpu::FramePointer _currentFrame;
gpu::Frame* _lastFrame { nullptr };
mat4 _prevRenderView;
gpu::FramebufferPointer _compositeFramebuffer;
gpu::PipelinePointer _hudPipeline;
gpu::PipelinePointer _mirrorHUDPipeline;
gpu::ShaderPointer _mirrorHUDPS;
gpu::PipelinePointer _simplePipeline;
gpu::PipelinePointer _presentPipeline;
gpu::PipelinePointer _cursorPipeline;
gpu::TexturePointer _displayTexture;
gpu::TexturePointer _displayTexture{};
float _compositeHUDAlpha { 1.0f };
struct CursorData {
@ -175,9 +185,5 @@ protected:
// be serialized through this mutex
mutable Mutex _presentMutex;
float _hudAlpha{ 1.0f };
private:
gpu::PipelinePointer _presentPipeline;
};

View file

@ -24,7 +24,7 @@ public:
protected:
void updatePresentPose() override;
void hmdPresent(const gpu::FramebufferPointer&) override {}
void hmdPresent() override {}
bool isHmdMounted() const override { return true; }
bool internalActivate() override;
private:

View file

@ -114,23 +114,20 @@ void HmdDisplayPlugin::internalDeactivate() {
void HmdDisplayPlugin::customizeContext() {
Parent::customizeContext();
_hudOperator = _hudRenderer.build();
_hudRenderer.build();
}
void HmdDisplayPlugin::uncustomizeContext() {
// This stops the weirdness where if the preview was disabled, on switching back to 2D,
// the vsync was stuck in the disabled state. No idea why that happens though.
_disablePreview = false;
if (_currentFrame && _currentFrame->framebuffer) {
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(_currentFrame->framebuffer);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
});
}
_hudRenderer = {};
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(_compositeFramebuffer);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
});
_hudRenderer = HUDRenderer();
_previewTexture.reset();
Parent::uncustomizeContext();
}
@ -177,11 +174,11 @@ float HmdDisplayPlugin::getLeftCenterPixel() const {
return leftCenterPixel;
}
void HmdDisplayPlugin::internalPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void HmdDisplayPlugin::internalPresent() {
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
// Composite together the scene, hud and mouse cursor
hmdPresent(compositeFramebuffer);
hmdPresent();
if (_displayTexture) {
// Note: _displayTexture must currently be the same size as the display.
@ -263,7 +260,7 @@ void HmdDisplayPlugin::internalPresent(const gpu::FramebufferPointer& compositeF
viewport.z *= 2;
}
renderFromTexture(batch, compositeFramebuffer->getRenderBuffer(0), viewport, scissor, nullptr, fbo);
renderFromTexture(batch, _compositeFramebuffer->getRenderBuffer(0), viewport, scissor, fbo);
});
swapBuffers();
@ -348,7 +345,7 @@ glm::mat4 HmdDisplayPlugin::getViewCorrection() {
}
}
DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
void HmdDisplayPlugin::HUDRenderer::build() {
vertices = std::make_shared<gpu::Buffer>();
indices = std::make_shared<gpu::Buffer>();
@ -383,7 +380,7 @@ DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
indexCount = numberOfRectangles * TRIANGLE_PER_RECTANGLE * VERTEX_PER_TRANGLE;
// Compute indices order
std::vector<GLushort> indexData;
std::vector<GLushort> indices;
for (int i = 0; i < stacks - 1; i++) {
for (int j = 0; j < slices - 1; j++) {
GLushort bottomLeftIndex = i * slices + j;
@ -391,21 +388,24 @@ DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
GLushort topLeftIndex = bottomLeftIndex + slices;
GLushort topRightIndex = topLeftIndex + 1;
// FIXME make a z-order curve for better vertex cache locality
indexData.push_back(topLeftIndex);
indexData.push_back(bottomLeftIndex);
indexData.push_back(topRightIndex);
indices.push_back(topLeftIndex);
indices.push_back(bottomLeftIndex);
indices.push_back(topRightIndex);
indexData.push_back(topRightIndex);
indexData.push_back(bottomLeftIndex);
indexData.push_back(bottomRightIndex);
indices.push_back(topRightIndex);
indices.push_back(bottomLeftIndex);
indices.push_back(bottomRightIndex);
}
}
indices->append(indexData);
this->indices->append(indices);
format = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
format->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
format->setAttribute(gpu::Stream::TEXCOORD, gpu::Stream::TEXCOORD, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
uniformsBuffer = std::make_shared<gpu::Buffer>(sizeof(Uniforms), nullptr);
updatePipeline();
}
void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
if (!pipeline) {
auto program = gpu::Shader::createProgram(shader::render_utils::program::hmd_ui);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
@ -416,6 +416,10 @@ DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
pipeline = gpu::Pipeline::create(program, state);
}
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) {
updatePipeline();
auto hudPipeline = pipeline;
auto hudFormat = format;
@ -424,9 +428,9 @@ DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
auto hudUniformBuffer = uniformsBuffer;
auto hudUniforms = uniforms;
auto hudIndexCount = indexCount;
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, const gpu::FramebufferPointer&, const bool mirror) {
if (pipeline && hudTexture) {
batch.setPipeline(pipeline);
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) {
if (hudPipeline && hudTexture) {
batch.setPipeline(hudPipeline);
batch.setInputFormat(hudFormat);
gpu::BufferView posView(hudVertices, VERTEX_OFFSET, hudVertices->getSize(), VERTEX_STRIDE, hudFormat->getAttributes().at(gpu::Stream::POSITION)._element);
@ -450,7 +454,7 @@ DisplayPlugin::HUDOperator HmdDisplayPlugin::HUDRenderer::build() {
};
}
void HmdDisplayPlugin::compositePointer(const gpu::FramebufferPointer& compositeFramebuffer) {
void HmdDisplayPlugin::compositePointer() {
auto& cursorManager = Cursor::Manager::instance();
const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()];
auto compositorHelper = DependencyManager::get<CompositorHelper>();
@ -459,7 +463,7 @@ void HmdDisplayPlugin::compositePointer(const gpu::FramebufferPointer& composite
render([&](gpu::Batch& batch) {
// FIXME use standard gpu stereo rendering for this.
batch.enableStereo(false);
batch.setFramebuffer(compositeFramebuffer);
batch.setFramebuffer(_compositeFramebuffer);
batch.setPipeline(_cursorPipeline);
batch.setResourceTexture(0, cursorData.texture);
batch.resetViewTransform();
@ -474,6 +478,10 @@ void HmdDisplayPlugin::compositePointer(const gpu::FramebufferPointer& composite
});
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDisplayPlugin::getHUDOperator() {
return _hudRenderer.render(*this);
}
HmdDisplayPlugin::~HmdDisplayPlugin() {
}

View file

@ -53,15 +53,16 @@ signals:
void hmdVisibleChanged(bool visible);
protected:
virtual void hmdPresent(const gpu::FramebufferPointer&) = 0;
virtual void hmdPresent() = 0;
virtual bool isHmdMounted() const = 0;
virtual void postPreview() {};
virtual void updatePresentPose();
bool internalActivate() override;
void internalDeactivate() override;
void compositePointer(const gpu::FramebufferPointer&) override;
void internalPresent(const gpu::FramebufferPointer&) override;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() override;
void compositePointer() override;
void internalPresent() override;
void customizeContext() override;
void uncustomizeContext() override;
void updateFrameData() override;
@ -119,6 +120,8 @@ private:
static const size_t TEXTURE_OFFSET { offsetof(Vertex, uv) };
static const int VERTEX_STRIDE { sizeof(Vertex) };
HUDOperator build();
void build();
void updatePipeline();
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> render(HmdDisplayPlugin& plugin);
} _hudRenderer;
};

View file

@ -37,13 +37,13 @@ glm::uvec2 InterleavedStereoDisplayPlugin::getRecommendedRenderSize() const {
return result;
}
void InterleavedStereoDisplayPlugin::internalPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void InterleavedStereoDisplayPlugin::internalPresent() {
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
batch.resetViewTransform();
batch.setFramebuffer(gpu::FramebufferPointer());
batch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels()));
batch.setResourceTexture(0, compositeFramebuffer->getRenderBuffer(0));
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
batch.setPipeline(_interleavedPresentPipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
});

View file

@ -21,7 +21,7 @@ protected:
// initialize OpenGL context settings needed by the plugin
void customizeContext() override;
void uncustomizeContext() override;
void internalPresent(const gpu::FramebufferPointer&) override;
void internalPresent() override;
private:
static const QString NAME;

View file

@ -711,19 +711,19 @@ glm::mat4 GLTFSerializer::getModelTransform(const GLTFNode& node) {
node.matrix[12], node.matrix[13], node.matrix[14], node.matrix[15]);
} else {
if (node.defined["rotation"] && node.rotation.size() == 4) {
//quat(x,y,z,w) to quat(w,x,y,z)
glm::quat rotquat = glm::quat(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2]);
tmat = glm::mat4_cast(rotquat) * tmat;
}
if (node.defined["scale"] && node.scale.size() == 3) {
glm::vec3 scale = glm::vec3(node.scale[0], node.scale[1], node.scale[2]);
glm::mat4 s = glm::mat4(1.0);
s = glm::scale(s, scale);
tmat = s * tmat;
}
if (node.defined["rotation"] && node.rotation.size() == 4) {
//quat(x,y,z,w) to quat(w,x,y,z)
glm::quat rotquat = glm::quat(node.rotation[3], node.rotation[0], node.rotation[1], node.rotation[2]);
tmat = glm::mat4_cast(rotquat) * tmat;
}
if (node.defined["translation"] && node.translation.size() == 3) {
glm::vec3 trans = glm::vec3(node.translation[0], node.translation[1], node.translation[2]);
glm::mat4 t = glm::mat4(1.0);
@ -734,15 +734,54 @@ glm::mat4 GLTFSerializer::getModelTransform(const GLTFNode& node) {
return tmat;
}
void GLTFSerializer::getSkinInverseBindMatrices(std::vector<std::vector<float>>& inverseBindMatrixValues) {
for (auto &skin : _file.skins) {
GLTFAccessor& indicesAccessor = _file.accessors[skin.inverseBindMatrices];
GLTFBufferView& indicesBufferview = _file.bufferviews[indicesAccessor.bufferView];
GLTFBuffer& indicesBuffer = _file.buffers[indicesBufferview.buffer];
int accBoffset = indicesAccessor.defined["byteOffset"] ? indicesAccessor.byteOffset : 0;
QVector<float> matrices;
addArrayOfType(indicesBuffer.blob,
indicesBufferview.byteOffset + accBoffset,
indicesAccessor.count,
matrices,
indicesAccessor.type,
indicesAccessor.componentType);
inverseBindMatrixValues.push_back(matrices.toStdVector());
}
}
void GLTFSerializer::getNodeQueueByDepthFirstChildren(std::vector<int>& children, int stride, std::vector<int>& result) {
int startingIndex = 0;
int finalIndex = (int)children.size();
if (stride == -1) {
startingIndex = (int)children.size() - 1;
finalIndex = -1;
}
for (int index = startingIndex; index != finalIndex; index += stride) {
int c = children[index];
result.push_back(c);
std::vector<int> nested = _file.nodes[c].children.toStdVector();
if (nested.size() != 0) {
std::sort(nested.begin(), nested.end());
for (int r : nested) {
if (result.end() == std::find(result.begin(), result.end(), r)) {
getNodeQueueByDepthFirstChildren(nested, stride, result);
}
}
}
}
}
bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
int numNodes = _file.nodes.size();
//Build dependencies
QVector<QVector<int>> nodeDependencies(_file.nodes.size());
QVector<QVector<int>> nodeDependencies(numNodes);
int nodecount = 0;
bool hasChildren = false;
foreach(auto &node, _file.nodes) {
//nodes_transforms.push_back(getModelTransform(node));
hasChildren |= !node.children.isEmpty();
foreach(int child, node.children) nodeDependencies[child].push_back(nodecount);
nodecount++;
}
@ -764,26 +803,98 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
nodecount++;
}
HFMJoint joint;
joint.isSkeletonJoint = true;
joint.bindTransformFoundInCluster = false;
joint.distanceToParent = 0;
joint.parentIndex = -1;
hfmModel.joints.resize(_file.nodes.size());
hfmModel.jointIndices["x"] = _file.nodes.size();
int jointInd = 0;
for (auto& node : _file.nodes) {
int size = node.transforms.size();
if (hasChildren) { size--; }
joint.preTransform = glm::mat4(1);
for (int i = 0; i < size; i++) {
joint.preTransform = node.transforms[i] * joint.preTransform;
}
joint.name = node.name;
hfmModel.joints[jointInd] = joint;
jointInd++;
// initialize order in which nodes will be parsed
std::vector<int> nodeQueue;
nodeQueue.reserve(numNodes);
int rootNode = 0;
int finalNode = numNodes;
if (!_file.scenes[_file.scene].nodes.contains(0)) {
rootNode = numNodes - 1;
finalNode = -1;
}
bool rootAtStartOfList = rootNode < finalNode;
int nodeListStride = 1;
if (!rootAtStartOfList) { nodeListStride = -1; }
QVector<int> initialSceneNodes = _file.scenes[_file.scene].nodes;
std::sort(initialSceneNodes.begin(), initialSceneNodes.end());
int sceneRootNode = 0;
int sceneFinalNode = initialSceneNodes.size();
if (!rootAtStartOfList) {
sceneRootNode = initialSceneNodes.size() - 1;
sceneFinalNode = -1;
}
for (int index = sceneRootNode; index != sceneFinalNode; index += nodeListStride) {
int i = initialSceneNodes[index];
nodeQueue.push_back(i);
std::vector<int> children = _file.nodes[i].children.toStdVector();
std::sort(children.begin(), children.end());
getNodeQueueByDepthFirstChildren(children, nodeListStride, nodeQueue);
}
// Build joints
HFMJoint joint;
joint.distanceToParent = 0;
hfmModel.jointIndices["x"] = numNodes;
hfmModel.hasSkeletonJoints = false;
for (int nodeIndex : nodeQueue) {
auto& node = _file.nodes[nodeIndex];
joint.parentIndex = -1;
if (!_file.scenes[_file.scene].nodes.contains(nodeIndex)) {
joint.parentIndex = std::distance(nodeQueue.begin(), std::find(nodeQueue.begin(), nodeQueue.end(), nodeDependencies[nodeIndex][0]));
}
joint.transform = node.transforms.first();
joint.translation = extractTranslation(joint.transform);
joint.rotation = glmExtractRotation(joint.transform);
glm::vec3 scale = extractScale(joint.transform);
joint.postTransform = glm::scale(glm::mat4(), scale);
joint.name = node.name;
joint.isSkeletonJoint = false;
hfmModel.joints.push_back(joint);
}
// Build skeleton
std::vector<glm::mat4> jointInverseBindTransforms;
jointInverseBindTransforms.resize(numNodes);
if (!_file.skins.isEmpty()) {
std::vector<std::vector<float>> inverseBindValues;
getSkinInverseBindMatrices(inverseBindValues);
int jointIndex = finalNode;
while (jointIndex != rootNode) {
rootAtStartOfList ? jointIndex-- : jointIndex++;
int jOffset = nodeQueue[jointIndex];
auto joint = hfmModel.joints[jointIndex];
hfmModel.hasSkeletonJoints = true;
for (int s = 0; s < _file.skins.size(); s++) {
auto skin = _file.skins[s];
joint.isSkeletonJoint = skin.joints.contains(jOffset);
if (joint.isSkeletonJoint) {
std::vector<float> value = inverseBindValues[s];
int matrixCount = 16 * skin.joints.indexOf(jOffset);
jointInverseBindTransforms[jointIndex] =
glm::mat4(value[matrixCount], value[matrixCount + 1], value[matrixCount + 2], value[matrixCount + 3],
value[matrixCount + 4], value[matrixCount + 5], value[matrixCount + 6], value[matrixCount + 7],
value[matrixCount + 8], value[matrixCount + 9], value[matrixCount + 10], value[matrixCount + 11],
value[matrixCount + 12], value[matrixCount + 13], value[matrixCount + 14], value[matrixCount + 15]);
} else {
jointInverseBindTransforms[jointIndex] = glm::mat4();
}
glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * glm::inverse(jointInverseBindTransforms[jointIndex]));
hfmModel.bindExtents.addPoint(bindTranslation);
}
hfmModel.joints[jointIndex] = joint;
}
}
//Build materials
QVector<QString> materialIDs;
@ -803,23 +914,39 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
}
nodecount = 0;
// Build meshes
foreach(auto &node, _file.nodes) {
nodecount = 0;
for (int nodeIndex = rootNode; nodeIndex != finalNode; nodeIndex += nodeListStride) {
auto& node = _file.nodes[nodeIndex];
if (node.defined["mesh"]) {
qCDebug(modelformat) << "node_transforms" << node.transforms;
foreach(auto &primitive, _file.meshes[node.mesh].primitives) {
hfmModel.meshes.append(HFMMesh());
HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1];
HFMCluster cluster;
cluster.jointIndex = nodecount;
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
mesh.clusters.append(cluster);
if (!hfmModel.hasSkeletonJoints) {
HFMCluster cluster;
cluster.jointIndex = nodecount;
cluster.inverseBindMatrix = glm::mat4();
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
mesh.clusters.append(cluster);
} else {
for (int j = rootNode; j != finalNode; j += nodeListStride) {
HFMCluster cluster;
cluster.jointIndex = j;
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
mesh.clusters.append(cluster);
}
}
HFMCluster root;
root.jointIndex = rootNode;
if (root.jointIndex == -1) {
root.jointIndex = 0;
}
root.inverseBindMatrix = jointInverseBindTransforms[root.jointIndex];
root.inverseBindTransform = Transform(root.inverseBindMatrix);
mesh.clusters.append(root);
HFMMeshPart part = HFMMeshPart();
@ -848,6 +975,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
}
QList<QString> keys = primitive.attributes.values.keys();
QVector<uint16_t> clusterJoints;
QVector<float> clusterWeights;
foreach(auto &key, keys) {
int accessorIdx = primitive.attributes.values[key];
@ -949,8 +1078,69 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
for (int n = 0; n < texcoords.size(); n = n + 2) {
mesh.texCoords1.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
}
} else if (key == "JOINTS_0") {
QVector<uint16_t> joints;
success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset,
accessor.count,
joints,
accessor.type,
accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF JOINTS_0 data for model " << _url;
continue;
}
for (int n = 0; n < joints.size(); n++) {
clusterJoints.push_back(joints[n]);
}
} else if (key == "WEIGHTS_0") {
QVector<float> weights;
success = addArrayOfType(buffer.blob,
bufferview.byteOffset + accBoffset,
accessor.count,
weights,
accessor.type,
accessor.componentType);
if (!success) {
qWarning(modelformat) << "There was a problem reading glTF WEIGHTS_0 data for model " << _url;
continue;
}
for (int n = 0; n < weights.size(); n++) {
clusterWeights.push_back(weights[n]);
}
}
}
// adapted from FBXSerializer.cpp
if (hfmModel.hasSkeletonJoints) {
int numClusterIndices = clusterJoints.size();
const int WEIGHTS_PER_VERTEX = 4;
const float ALMOST_HALF = 0.499f;
int numVertices = mesh.vertices.size();
mesh.clusterIndices.fill(mesh.clusters.size() - 1, numClusterIndices);
mesh.clusterWeights.fill(0, numClusterIndices);
for (int c = 0; c < clusterJoints.size(); c++) {
mesh.clusterIndices[c] = _file.skins[node.skin].joints[clusterJoints[c]];
}
// normalize and compress to 16-bits
for (int i = 0; i < numVertices; ++i) {
int j = i * WEIGHTS_PER_VERTEX;
float totalWeight = 0.0f;
for (int k = j; k < j + WEIGHTS_PER_VERTEX; ++k) {
totalWeight += clusterWeights[k];
}
if (totalWeight > 0.0f) {
float weightScalingFactor = (float)(UINT16_MAX) / totalWeight;
for (int k = j; k < j + WEIGHTS_PER_VERTEX; ++k) {
mesh.clusterWeights[k] = (uint16_t)(weightScalingFactor * clusterWeights[k] + ALMOST_HALF);
}
} else {
mesh.clusterWeights[j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF);
}
}
}
if (primitive.defined["material"]) {
@ -959,8 +1149,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
mesh.parts.push_back(part);
// populate the texture coordinates if they don't exist
if (mesh.texCoords.size() == 0) {
for (int i = 0; i < part.triangleIndices.size(); i++) mesh.texCoords.push_back(glm::vec2(0.0, 1.0));
if (mesh.texCoords.size() == 0 && !hfmModel.hasSkeletonJoints) {
for (int i = 0; i < part.triangleIndices.size(); i++) { mesh.texCoords.push_back(glm::vec2(0.0, 1.0)); }
}
mesh.meshExtents.reset();
foreach(const glm::vec3& vertex, mesh.vertices) {

View file

@ -712,6 +712,8 @@ private:
hifi::ByteArray _glbBinary;
glm::mat4 getModelTransform(const GLTFNode& node);
void getSkinInverseBindMatrices(std::vector<std::vector<float>>& inverseBindMatrixValues);
void getNodeQueueByDepthFirstChildren(std::vector<int>& children, int stride, std::vector<int>& result);
bool buildGeometry(HFMModel& hfmModel, const hifi::URL& url);
bool parseGLTF(const hifi::ByteArray& data);

View file

@ -245,7 +245,7 @@ void OculusMobileDisplayPlugin::updatePresentPose() {
});
}
void OculusMobileDisplayPlugin::internalPresent(const gpu::FramebufferPointer& compsiteFramebuffer) {
void OculusMobileDisplayPlugin::internalPresent() {
VrHandler::pollTask();
if (!vrActive()) {
@ -253,12 +253,8 @@ void OculusMobileDisplayPlugin::internalPresent(const gpu::FramebufferPointer& c
return;
}
GLuint sourceTexture = 0;
glm::uvec2 sourceSize;
if (compsiteFramebuffer) {
sourceTexture = getGLBackend()->getTextureID(compsiteFramebuffer->getRenderBuffer(0));
sourceSize = { compsiteFramebuffer->getWidth(), compsiteFramebuffer->getHeight() };
}
auto sourceTexture = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0));
glm::uvec2 sourceSize{ _compositeFramebuffer->getWidth(), _compositeFramebuffer->getHeight() };
VrHandler::presentFrame(sourceTexture, sourceSize, presentTracking);
_presentRate.increment();
}

View file

@ -54,8 +54,8 @@ protected:
void uncustomizeContext() override;
void updatePresentPose() override;
void internalPresent(const gpu::FramebufferPointer&) override;
void hmdPresent(const gpu::FramebufferPointer&) override { throw std::runtime_error("Unused"); }
void internalPresent() override;
void hmdPresent() override { throw std::runtime_error("Unused"); }
bool isHmdMounted() const override;
bool alwaysPresent() const override { return true; }

View file

@ -2,12 +2,6 @@
#include <NumericalConstants.h>
const DisplayPlugin::HUDOperator DisplayPlugin::DEFAULT_HUD_OPERATOR{ std::function<void(gpu::Batch&, const gpu::TexturePointer&, const gpu::FramebufferPointer&, bool mirror)>() };
DisplayPlugin::DisplayPlugin() : _hudOperator{ DEFAULT_HUD_OPERATOR } {
}
int64_t DisplayPlugin::getPaintDelayUsecs() const {
std::lock_guard<std::mutex> lock(_paintDelayMutex);
return _paintDelayTimer.isValid() ? _paintDelayTimer.nsecsElapsed() / NSECS_PER_USEC : 0;
@ -41,8 +35,8 @@ void DisplayPlugin::waitForPresent() {
}
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, const gpu::FramebufferPointer& compositeFramebuffer, bool mirror)> DisplayPlugin::getHUDOperator() {
HUDOperator hudOperator;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> DisplayPlugin::getHUDOperator() {
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> hudOperator;
{
QMutexLocker locker(&_presentMutex);
hudOperator = _hudOperator;
@ -54,5 +48,3 @@ glm::mat4 HmdDisplay::getEyeToHeadTransform(Eye eye) const {
static const glm::mat4 xform;
return xform;
}

View file

@ -121,8 +121,6 @@ class DisplayPlugin : public Plugin, public HmdDisplay {
Q_OBJECT
using Parent = Plugin;
public:
DisplayPlugin();
virtual int getRequiredThreadCount() const { return 0; }
virtual bool isHmd() const { return false; }
virtual int getHmdScreen() const { return -1; }
@ -216,8 +214,7 @@ public:
void waitForPresent();
float getAveragePresentTime() { return _movingAveragePresent.average / (float)USECS_PER_MSEC; } // in msec
using HUDOperator = std::function<void(gpu::Batch&, const gpu::TexturePointer&, const gpu::FramebufferPointer&, bool mirror)>;
virtual HUDOperator getHUDOperator() final;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator();
static const QString& MENU_PATH();
@ -234,8 +231,7 @@ protected:
gpu::ContextPointer _gpuContext;
static const HUDOperator DEFAULT_HUD_OPERATOR;
HUDOperator _hudOperator;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> _hudOperator { std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)>() };
MovingAverage<float, 10> _movingAveragePresent;

View file

@ -126,8 +126,8 @@ void CompositeHUD::run(const RenderContextPointer& renderContext, const gpu::Fra
if (inputs) {
batch.setFramebuffer(inputs);
}
if (renderContext->args->_hudOperator && renderContext->args->_blitFramebuffer) {
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_blitFramebuffer, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
if (renderContext->args->_hudOperator) {
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
}
});
#endif

View file

@ -131,7 +131,7 @@ namespace render {
render::ScenePointer _scene;
int8_t _cameraMode { -1 };
std::function<void(gpu::Batch&, const gpu::TexturePointer&, const gpu::FramebufferPointer&, bool mirror)> _hudOperator;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> _hudOperator;
gpu::TexturePointer _hudTexture;
};

View file

@ -16,7 +16,7 @@ public:
bool isSupported() const override;
protected:
void hmdPresent(const gpu::FramebufferPointer&) override {}
void hmdPresent() override {}
bool isHmdMounted() const override { return true; }
private:

View file

@ -108,16 +108,13 @@ void OculusDisplayPlugin::customizeContext() {
}
void OculusDisplayPlugin::uncustomizeContext() {
#if 0
if (_currentFrame && _currentFrame->framebuffer) {
// Present a final black frame to the HMD
_currentFrame->framebuffer->Bound(FramebufferTarget::Draw, [] {
Context::ClearColor(0, 0, 0, 1);
Context::Clear().ColorBuffer();
});
hmdPresent();
}
// Present a final black frame to the HMD
_compositeFramebuffer->Bound(FramebufferTarget::Draw, [] {
Context::ClearColor(0, 0, 0, 1);
Context::Clear().ColorBuffer();
});
hmdPresent();
#endif
ovr_DestroyTextureSwapChain(_session, _textureSwapChain);
@ -130,7 +127,7 @@ void OculusDisplayPlugin::uncustomizeContext() {
static const uint64_t FRAME_BUDGET = (11 * USECS_PER_MSEC);
static const uint64_t FRAME_OVER_BUDGET = (15 * USECS_PER_MSEC);
void OculusDisplayPlugin::hmdPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void OculusDisplayPlugin::hmdPresent() {
static uint64_t lastSubmitEnd = 0;
if (!_customized) {
@ -160,8 +157,15 @@ void OculusDisplayPlugin::hmdPresent(const gpu::FramebufferPointer& compositeFra
auto fbo = getGLBackend()->getFramebufferID(_outputFramebuffer);
glNamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0, curTexId, 0);
render([&](gpu::Batch& batch) {
auto viewport = ivec4(uvec2(), _outputFramebuffer->getSize());
renderFromTexture(batch, compositeFramebuffer->getRenderBuffer(0), viewport, viewport, _outputFramebuffer);
batch.enableStereo(false);
batch.setFramebuffer(_outputFramebuffer);
batch.setViewportTransform(ivec4(uvec2(), _outputFramebuffer->getSize()));
batch.setStateScissorRect(ivec4(uvec2(), _outputFramebuffer->getSize()));
batch.resetViewTransform();
batch.setProjectionTransform(mat4());
batch.setPipeline(_presentPipeline);
batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
glNamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0, 0, 0);
}

View file

@ -28,7 +28,7 @@ protected:
QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; }
bool internalActivate() override;
void hmdPresent(const gpu::FramebufferPointer&) override;
void hmdPresent() override;
bool isHmdMounted() const override;
void customizeContext() override;
void uncustomizeContext() override;

View file

@ -237,7 +237,7 @@ void OculusLegacyDisplayPlugin::uncustomizeContext() {
Parent::uncustomizeContext();
}
void OculusLegacyDisplayPlugin::hmdPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void OculusLegacyDisplayPlugin::hmdPresent() {
if (!_hswDismissed) {
ovrHSWDisplayState hswState;
ovrHmd_GetHSWDisplayState(_hmd, &hswState);
@ -252,7 +252,7 @@ void OculusLegacyDisplayPlugin::hmdPresent(const gpu::FramebufferPointer& compos
memset(eyePoses, 0, sizeof(ovrPosef) * 2);
eyePoses[0].Orientation = eyePoses[1].Orientation = ovrRotation;
GLint texture = getGLBackend()->getTextureID(compositeFramebuffer->getRenderBuffer(0));
GLint texture = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0));
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
if (_hmdWindow->makeCurrent()) {

View file

@ -39,7 +39,7 @@ protected:
void customizeContext() override;
void uncustomizeContext() override;
void hmdPresent(const gpu::FramebufferPointer&) override;
void hmdPresent() override;
bool isHmdMounted() const override { return true; }
private:

View file

@ -511,13 +511,13 @@ void OpenVrDisplayPlugin::customizeContext() {
Parent::customizeContext();
if (_threadedSubmit) {
// _compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0);
_compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0);
for (size_t i = 0; i < COMPOSITING_BUFFER_SIZE; ++i) {
// if (0 != i) {
if (0 != i) {
_compositeInfos[i].texture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x,
_renderTargetSize.y, gpu::Texture::SINGLE_MIP,
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT));
// }
}
_compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture);
}
_submitThread->_canvas = _submitCanvas;
@ -613,17 +613,17 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
return Parent::beginFrameRender(frameIndex);
}
void OpenVrDisplayPlugin::compositeLayers(const gpu::FramebufferPointer& compositeFramebuffer) {
void OpenVrDisplayPlugin::compositeLayers() {
if (_threadedSubmit) {
++_renderingIndex;
_renderingIndex %= COMPOSITING_BUFFER_SIZE;
auto& newComposite = _compositeInfos[_renderingIndex];
newComposite.pose = _currentPresentFrameInfo.presentPose;
compositeFramebuffer->setRenderBuffer(0, newComposite.texture);
_compositeFramebuffer->setRenderBuffer(0, newComposite.texture);
}
Parent::compositeLayers(compositeFramebuffer);
Parent::compositeLayers();
if (_threadedSubmit) {
auto& newComposite = _compositeInfos[_renderingIndex];
@ -645,13 +645,13 @@ void OpenVrDisplayPlugin::compositeLayers(const gpu::FramebufferPointer& composi
}
}
void OpenVrDisplayPlugin::hmdPresent(const gpu::FramebufferPointer& compositeFramebuffer) {
void OpenVrDisplayPlugin::hmdPresent() {
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
if (_threadedSubmit) {
_submitThread->waitForPresent();
} else {
GLuint glTexId = getGLBackend()->getTextureID(compositeFramebuffer->getRenderBuffer(0));
GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0));
vr::Texture_t vrTexture{ (void*)(uintptr_t)glTexId, vr::TextureType_OpenGL, vr::ColorSpace_Auto };
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);

View file

@ -72,8 +72,8 @@ protected:
void internalDeactivate() override;
void updatePresentPose() override;
void compositeLayers(const gpu::FramebufferPointer&) override;
void hmdPresent(const gpu::FramebufferPointer&) override;
void compositeLayers() override;
void hmdPresent() override;
bool isHmdMounted() const override;
void postPreview() override;