mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 15:57:39 +02:00
HMD compositing and buffer debugging
This commit is contained in:
parent
2340afc48e
commit
09ddad0fe0
9 changed files with 251 additions and 212 deletions
|
@ -57,7 +57,7 @@ void main(void) {
|
|||
}
|
||||
)SCRIBE";
|
||||
|
||||
QOpenGLContext* mainContext;
|
||||
extern QThread* RENDER_THREAD;
|
||||
|
||||
class PresentThread : public QThread, public Dependency {
|
||||
using Mutex = std::mutex;
|
||||
|
@ -107,7 +107,6 @@ public:
|
|||
virtual void run() override {
|
||||
OpenGLDisplayPlugin* currentPlugin{ nullptr };
|
||||
Q_ASSERT(_context);
|
||||
mainContext = _context->contextHandle();
|
||||
while (!_shutdown) {
|
||||
if (_pendingMainThreadOperation) {
|
||||
{
|
||||
|
@ -214,12 +213,6 @@ private:
|
|||
QGLContext* _context { nullptr };
|
||||
};
|
||||
|
||||
|
||||
OpenGLDisplayPlugin::OpenGLDisplayPlugin() {
|
||||
}
|
||||
|
||||
extern QThread* RENDER_THREAD;
|
||||
|
||||
bool OpenGLDisplayPlugin::activate() {
|
||||
if (!_cursorsData.size()) {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
|
@ -285,7 +278,6 @@ bool OpenGLDisplayPlugin::activate() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::deactivate() {
|
||||
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
disconnect(compositorHelper.data());
|
||||
|
||||
|
@ -305,7 +297,6 @@ void OpenGLDisplayPlugin::deactivate() {
|
|||
Parent::deactivate();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::customizeContext() {
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
Q_ASSERT(thread() == presentThread->thread());
|
||||
|
@ -341,6 +332,7 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
gpu::Shader::makeProgram(*program);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setScissorEnable(true);
|
||||
_presentPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
|
@ -384,7 +376,8 @@ void OpenGLDisplayPlugin::uncustomizeContext() {
|
|||
_compositeTexture.reset();
|
||||
withPresentThreadLock([&] {
|
||||
_currentFrame.reset();
|
||||
_newFrameQueue.swap(std::queue<gpu::FramePointer>());
|
||||
std::queue<gpu::FramePointer> empty;
|
||||
_newFrameQueue.swap(empty);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -431,7 +424,6 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) {
|
||||
if (_lockCurrentTexture) {
|
||||
return;
|
||||
|
@ -461,45 +453,45 @@ void OpenGLDisplayPlugin::updateFrameData() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::compositeOverlay() {
|
||||
gpu::Batch batch;
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_overlayPipeline);
|
||||
batch.setResourceTexture(0, _currentFrame->overlay);
|
||||
if (isStereo()) {
|
||||
for_each_eye([&](Eye eye) {
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
render([&](gpu::Batch& batch){
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_overlayPipeline);
|
||||
batch.setResourceTexture(0, _currentFrame->overlay);
|
||||
if (isStereo()) {
|
||||
for_each_eye([&](Eye eye) {
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
} else {
|
||||
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
} else {
|
||||
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
_backend->render(batch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::compositePointer() {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()];
|
||||
auto cursorTransform = DependencyManager::get<CompositorHelper>()->getReticleTransform(glm::mat4());
|
||||
gpu::Batch batch;
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, cursorData.texture);
|
||||
batch.clearViewTransform();
|
||||
batch.setModelTransform(cursorTransform);
|
||||
if (isStereo()) {
|
||||
for_each_eye([&](Eye eye) {
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, cursorData.texture);
|
||||
batch.clearViewTransform();
|
||||
batch.setModelTransform(cursorTransform);
|
||||
if (isStereo()) {
|
||||
for_each_eye([&](Eye eye) {
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
} else {
|
||||
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
} else {
|
||||
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize()));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
_backend->render(batch);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::compositeScene() {
|
||||
|
@ -526,15 +518,15 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::internalPresent() {
|
||||
gpu::Batch presentBatch;
|
||||
presentBatch.enableStereo(false);
|
||||
presentBatch.clearViewTransform();
|
||||
presentBatch.setFramebuffer(gpu::FramebufferPointer());
|
||||
presentBatch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels()));
|
||||
presentBatch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
|
||||
presentBatch.setPipeline(_presentPipeline);
|
||||
presentBatch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
_backend->render(presentBatch);
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.clearViewTransform();
|
||||
batch.setFramebuffer(gpu::FramebufferPointer());
|
||||
batch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels()));
|
||||
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
|
@ -586,7 +578,6 @@ float OpenGLDisplayPlugin::presentRate() const {
|
|||
return _presentRate.rate();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::enableVsync(bool enable) {
|
||||
if (!_vsyncSupported) {
|
||||
return;
|
||||
|
@ -602,7 +593,6 @@ void OpenGLDisplayPlugin::enableVsync(bool enable) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLDisplayPlugin::isVsyncEnabled() {
|
||||
if (!_vsyncSupported) {
|
||||
return true;
|
||||
|
@ -698,3 +688,10 @@ gpu::gl::GLBackend* OpenGLDisplayPlugin::getGLBackend() {
|
|||
}
|
||||
return dynamic_cast<gpu::gl::GLBackend*>(_backend.get());
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::render(std::function<void(gpu::Batch& batch)> f) {
|
||||
gpu::Batch batch;
|
||||
f(batch);
|
||||
batch.flush();
|
||||
_backend->render(batch);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,6 @@ protected:
|
|||
using Condition = std::condition_variable;
|
||||
using TextureEscrow = GLEscrow<gpu::TexturePointer>;
|
||||
public:
|
||||
OpenGLDisplayPlugin();
|
||||
|
||||
// These must be final to ensure proper ordering of operations
|
||||
// between the main thread and the presentation thread
|
||||
bool activate() override final;
|
||||
|
@ -102,6 +100,8 @@ protected:
|
|||
void swapBuffers();
|
||||
ivec4 eyeViewport(Eye eye) const;
|
||||
|
||||
void render(std::function<void(gpu::Batch& batch)> f);
|
||||
|
||||
QThread* _presentThread{ nullptr };
|
||||
std::queue<gpu::FramePointer> _newFrameQueue;
|
||||
RateCounter<> _droppedFrameRate;
|
||||
|
|
|
@ -39,6 +39,7 @@ static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
|||
static const QString DEVELOPER_MENU_PATH = "Developer>" + DisplayPlugin::MENU_PATH();
|
||||
static const bool DEFAULT_MONO_VIEW = true;
|
||||
static const glm::mat4 IDENTITY_MATRIX;
|
||||
static const size_t NUMBER_OF_HANDS = 2;
|
||||
|
||||
//#define LIVE_SHADER_RELOAD 1
|
||||
extern glm::vec3 getPoint(float yaw, float pitch);
|
||||
|
@ -230,28 +231,29 @@ void HmdDisplayPlugin::OverlayRenderer::updatePipeline() {
|
|||
}
|
||||
|
||||
void HmdDisplayPlugin::OverlayRenderer::render(HmdDisplayPlugin& plugin) {
|
||||
updatePipeline();
|
||||
for_each_eye([&](Eye eye){
|
||||
uniforms.mvp = mvps[eye];
|
||||
uniformBuffers[eye]->setSubData(0, uniforms);
|
||||
uniformBuffers[eye]->flush();
|
||||
});
|
||||
gpu::Batch batch;
|
||||
batch.enableStereo(false);
|
||||
batch.setResourceTexture(0, plugin._currentFrame->overlay);
|
||||
batch.setPipeline(pipeline);
|
||||
batch.setInputFormat(format);
|
||||
gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element);
|
||||
gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, posView);
|
||||
batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView);
|
||||
batch.setIndexBuffer(gpu::UINT16, indices, 0);
|
||||
for_each_eye([&](Eye eye){
|
||||
batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]);
|
||||
batch.setViewportTransform(plugin.eyeViewport(eye));
|
||||
batch.drawIndexed(gpu::TRIANGLES, indexCount);
|
||||
plugin.render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setResourceTexture(0, plugin._currentFrame->overlay);
|
||||
batch.setPipeline(pipeline);
|
||||
batch.setInputFormat(format);
|
||||
gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element);
|
||||
gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
||||
batch.setInputBuffer(gpu::Stream::POSITION, posView);
|
||||
batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView);
|
||||
batch.setIndexBuffer(gpu::UINT16, indices, 0);
|
||||
// FIXME use stereo information input to set both MVPs in the uniforms
|
||||
for_each_eye([&](Eye eye) {
|
||||
batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]);
|
||||
batch.setViewportTransform(plugin.eyeViewport(eye));
|
||||
batch.drawIndexed(gpu::TRIANGLES, indexCount);
|
||||
});
|
||||
});
|
||||
// FIXME use stereo information input to set both MVPs in the uniforms
|
||||
plugin._backend->render(batch);
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateLaserProgram() {
|
||||
|
@ -303,38 +305,152 @@ void HmdDisplayPlugin::updatePresentPose() {
|
|||
}
|
||||
|
||||
void HmdDisplayPlugin::compositeScene() {
|
||||
gpu::Batch batch;
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(_compositeFramebuffer);
|
||||
|
||||
batch.setViewportTransform(ivec4(uvec2(), _renderTargetSize));
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1, 1, 0, 1));
|
||||
batch.clearViewTransform();
|
||||
batch.setProjectionTransform(mat4());
|
||||
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
_backend->render(batch);
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(_compositeFramebuffer);
|
||||
batch.setViewportTransform(ivec4(uvec2(), _renderTargetSize));
|
||||
batch.setStateScissorRect(ivec4(uvec2(), _renderTargetSize));
|
||||
batch.clearViewTransform();
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setPipeline(_presentPipeline);
|
||||
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::compositeOverlay() {
|
||||
#if 0
|
||||
if (!_currentFrame) {
|
||||
if (!_currentFrame || !_currentFrame->overlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
_overlay.render(*this);
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::compositePointer() {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()];
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix();
|
||||
// Reconstruct the headpose from the eye poses
|
||||
auto headPosition = vec3(_currentPresentFrameInfo.presentPose[3]);
|
||||
gpu::Batch batch;
|
||||
render([&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, cursorData.texture);
|
||||
batch.clearViewTransform();
|
||||
for_each_eye([&](Eye eye) {
|
||||
auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(eyePose, headPosition);
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
batch.setModelTransform(reticleTransform);
|
||||
batch.setProjectionTransform(_eyeProjections[eye]);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::internalPresent() {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||
|
||||
// Composite together the scene, overlay and mouse cursor
|
||||
hmdPresent();
|
||||
|
||||
if (_enablePreview) {
|
||||
// screen preview mirroring
|
||||
auto window = _container->getPrimaryWidget();
|
||||
auto devicePixelRatio = window->devicePixelRatio();
|
||||
auto windowSize = toGlm(window->size());
|
||||
windowSize *= devicePixelRatio;
|
||||
float windowAspect = aspect(windowSize);
|
||||
float sceneAspect = _enablePreview ? aspect(_renderTargetSize) : _previewAspect;
|
||||
if (_enablePreview && _monoPreview) {
|
||||
sceneAspect /= 2.0f;
|
||||
}
|
||||
float aspectRatio = sceneAspect / windowAspect;
|
||||
|
||||
uvec2 targetViewportSize = windowSize;
|
||||
if (aspectRatio < 1.0f) {
|
||||
targetViewportSize.x *= aspectRatio;
|
||||
} else {
|
||||
targetViewportSize.y /= aspectRatio;
|
||||
}
|
||||
|
||||
uvec2 targetViewportPosition;
|
||||
if (targetViewportSize.x < windowSize.x) {
|
||||
targetViewportPosition.x = (windowSize.x - targetViewportSize.x) / 2;
|
||||
} else if (targetViewportSize.y < windowSize.y) {
|
||||
targetViewportPosition.y = (windowSize.y - targetViewportSize.y) / 2;
|
||||
}
|
||||
|
||||
gpu::Batch presentBatch;
|
||||
presentBatch.enableStereo(false);
|
||||
presentBatch.clearViewTransform();
|
||||
presentBatch.setFramebuffer(gpu::FramebufferPointer());
|
||||
presentBatch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||
presentBatch.setViewportTransform(ivec4(uvec2(0), windowSize));
|
||||
if (_monoPreview) {
|
||||
presentBatch.setStateScissorRect(ivec4(targetViewportPosition, targetViewportSize));
|
||||
targetViewportSize.x *= 2;
|
||||
presentBatch.setViewportTransform(ivec4(targetViewportPosition, targetViewportSize));
|
||||
} else {
|
||||
presentBatch.setStateScissorRect(ivec4(targetViewportPosition, targetViewportSize));
|
||||
presentBatch.setViewportTransform(ivec4(targetViewportPosition, targetViewportSize));
|
||||
}
|
||||
presentBatch.setResourceTexture(0, _compositeTexture);
|
||||
presentBatch.setPipeline(_presentPipeline);
|
||||
presentBatch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
_backend->render(presentBatch);
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
postPreview();
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateFrameData() {
|
||||
// Check if we have old frame data to discard
|
||||
static const uint32_t INVALID_FRAME = (uint32_t)(~0);
|
||||
uint32_t oldFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME;
|
||||
|
||||
Parent::updateFrameData();
|
||||
uint32_t newFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME;
|
||||
|
||||
if (oldFrameIndex != newFrameIndex) {
|
||||
withPresentThreadLock([&] {
|
||||
if (oldFrameIndex != INVALID_FRAME) {
|
||||
auto itr = _frameInfos.find(oldFrameIndex);
|
||||
if (itr != _frameInfos.end()) {
|
||||
_frameInfos.erase(itr);
|
||||
}
|
||||
}
|
||||
if (newFrameIndex != INVALID_FRAME) {
|
||||
_currentPresentFrameInfo = _frameInfos[newFrameIndex];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updatePresentPose();
|
||||
|
||||
if (_currentFrame) {
|
||||
auto batchPose = _currentFrame->pose;
|
||||
auto currentPose = _currentPresentFrameInfo.presentPose;
|
||||
auto correction = glm::inverse(batchPose) * currentPose;
|
||||
getGLBackend()->setCameraCorrection(correction);
|
||||
}
|
||||
|
||||
withPresentThreadLock([&] {
|
||||
_presentHandLasers = _handLasers;
|
||||
_presentHandPoses = _handPoses;
|
||||
_presentUiModelTransform = _uiModelTransform;
|
||||
});
|
||||
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix();
|
||||
|
||||
std::array<vec2, NUMBER_OF_HANDS> handGlowPoints{ { vec2(-1), vec2(-1) } };
|
||||
// compute the glow point interesections
|
||||
for (int i = 0; i < NUMBER_OF_HANDS; ++i) {
|
||||
for (size_t i = 0; i < NUMBER_OF_HANDS; ++i) {
|
||||
if (_presentHandPoses[i] == IDENTITY_MATRIX) {
|
||||
continue;
|
||||
}
|
||||
|
@ -382,133 +498,20 @@ void HmdDisplayPlugin::compositeOverlay() {
|
|||
handGlowPoints[i] = yawPitch;
|
||||
}
|
||||
|
||||
if (!_currentFrame->overlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_eye([&](Eye eye){
|
||||
for_each_eye([&](Eye eye) {
|
||||
auto modelView = glm::inverse(_currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye)) * modelMat;
|
||||
_overlay.mvps[eye] = _eyeProjections[eye] * modelView;
|
||||
});
|
||||
|
||||
// Setup the uniforms
|
||||
{
|
||||
_overlay.uniforms.alpha = _compositeOverlayAlpha;
|
||||
_overlay.uniforms.glowPoints = vec4(handGlowPoints[0], handGlowPoints[1]);
|
||||
_overlay.uniforms.glowColors[0] = _presentHandLasers[0].color;
|
||||
_overlay.uniforms.glowColors[1] = _presentHandLasers[1].color;
|
||||
auto& uniforms = _overlay.uniforms;
|
||||
uniforms.alpha = _compositeOverlayAlpha;
|
||||
uniforms.glowPoints = vec4(handGlowPoints[0], handGlowPoints[1]);
|
||||
uniforms.glowColors[0] = _presentHandLasers[0].color;
|
||||
uniforms.glowColors[1] = _presentHandLasers[1].color;
|
||||
}
|
||||
_overlay.render();
|
||||
#endif
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::compositePointer() {
|
||||
#if 0
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
const auto& cursorData = _cursorsData[cursorManager.getCursor()->getIcon()];
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
// Reconstruct the headpose from the eye poses
|
||||
auto headPosition = vec3(_currentPresentFrameInfo.presentPose[3]);
|
||||
gpu::Batch batch;
|
||||
batch.enableStereo(false);
|
||||
batch.setProjectionTransform(mat4());
|
||||
batch.setFramebuffer(_currentFrame->framebuffer);
|
||||
batch.setPipeline(_cursorPipeline);
|
||||
batch.setResourceTexture(0, cursorData.texture);
|
||||
batch.clearViewTransform();
|
||||
for_each_eye([&](Eye eye) {
|
||||
auto eyePose = _currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(eyePose, headPosition);
|
||||
batch.setViewportTransform(eyeViewport(eye));
|
||||
batch.setModelTransform(reticleTransform);
|
||||
batch.setProjectionTransform(_eyeProjections[eye]);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
_backend->render(batch);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::internalPresent() {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||
|
||||
// Composite together the scene, overlay and mouse cursor
|
||||
hmdPresent();
|
||||
|
||||
/*
|
||||
// screen preview mirroring
|
||||
auto window = _container->getPrimaryWidget();
|
||||
auto devicePixelRatio = window->devicePixelRatio();
|
||||
auto windowSize = toGlm(window->size());
|
||||
windowSize *= devicePixelRatio;
|
||||
float windowAspect = aspect(windowSize);
|
||||
float sceneAspect = _enablePreview ? aspect(_renderTargetSize) : _previewAspect;
|
||||
if (_enablePreview && _monoPreview) {
|
||||
sceneAspect /= 2.0f;
|
||||
}
|
||||
float aspectRatio = sceneAspect / windowAspect;
|
||||
|
||||
uvec2 targetViewportSize = windowSize;
|
||||
if (aspectRatio < 1.0f) {
|
||||
targetViewportSize.x *= aspectRatio;
|
||||
} else {
|
||||
targetViewportSize.y /= aspectRatio;
|
||||
}
|
||||
|
||||
uvec2 targetViewportPosition;
|
||||
if (targetViewportSize.x < windowSize.x) {
|
||||
targetViewportPosition.x = (windowSize.x - targetViewportSize.x) / 2;
|
||||
} else if (targetViewportSize.y < windowSize.y) {
|
||||
targetViewportPosition.y = (windowSize.y - targetViewportSize.y) / 2;
|
||||
}
|
||||
*/
|
||||
|
||||
if (_enablePreview) {
|
||||
gpu::Batch presentBatch;
|
||||
presentBatch.enableStereo(false);
|
||||
presentBatch.clearViewTransform();
|
||||
presentBatch.setFramebuffer(gpu::FramebufferPointer());
|
||||
presentBatch.setViewportTransform(ivec4(uvec2(0), getSurfacePixels()));
|
||||
presentBatch.setResourceTexture(0, _compositeTexture);
|
||||
presentBatch.setPipeline(_presentPipeline);
|
||||
presentBatch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
_backend->render(presentBatch);
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
postPreview();
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::updateFrameData() {
|
||||
// Check if we have old frame data to discard
|
||||
static const uint32_t INVALID_FRAME = (uint32_t)(~0);
|
||||
uint32_t oldFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME;
|
||||
|
||||
Parent::updateFrameData();
|
||||
uint32_t newFrameIndex = _currentFrame ? _currentFrame->frameIndex : INVALID_FRAME;
|
||||
|
||||
if (oldFrameIndex != newFrameIndex) {
|
||||
withPresentThreadLock([&] {
|
||||
if (oldFrameIndex != INVALID_FRAME) {
|
||||
auto itr = _frameInfos.find(oldFrameIndex);
|
||||
if (itr != _frameInfos.end()) {
|
||||
_frameInfos.erase(itr);
|
||||
}
|
||||
}
|
||||
if (newFrameIndex != INVALID_FRAME) {
|
||||
_currentPresentFrameInfo = _frameInfos[newFrameIndex];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updatePresentPose();
|
||||
|
||||
if (_currentFrame) {
|
||||
auto batchPose = _currentFrame->pose;
|
||||
auto currentPose = _currentPresentFrameInfo.presentPose;
|
||||
auto correction = glm::inverse(batchPose) * currentPose;
|
||||
getGLBackend()->setCameraCorrection(correction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glm::mat4 HmdDisplayPlugin::getHeadPose() const {
|
||||
|
|
|
@ -19,8 +19,8 @@ GLBuffer::~GLBuffer() {
|
|||
|
||||
GLBuffer::GLBuffer(const Buffer& buffer, GLuint id) :
|
||||
GLObject(buffer, id),
|
||||
_size((GLuint)buffer._sysmem.getSize()),
|
||||
_stamp(buffer._sysmem.getStamp())
|
||||
_size((GLuint)buffer._renderSysmem.getSize()),
|
||||
_stamp(buffer._renderSysmem.getStamp())
|
||||
{
|
||||
Backend::incrementBufferGPUCount();
|
||||
Backend::updateBufferGPUMemoryUsage(0, _size);
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
GLBufferType* object = Backend::getGPUObject<GLBufferType>(buffer);
|
||||
|
||||
// Has the storage size changed?
|
||||
if (!object || object->_stamp != buffer.getSysmem().getStamp()) {
|
||||
if (!object || object->_stamp != buffer._renderSysmem.getStamp()) {
|
||||
object = new GLBufferType(buffer, object);
|
||||
}
|
||||
|
||||
|
|
|
@ -660,4 +660,33 @@ void Batch::finish(BufferUpdates& updates) {
|
|||
}
|
||||
updates.push_back({ buffer, buffer->getUpdate() });
|
||||
}
|
||||
}
|
||||
|
||||
void Batch::flush() {
|
||||
if (_objectsBuffer && _objectsBuffer->isDirty()) {
|
||||
_objectsBuffer->flush();
|
||||
}
|
||||
|
||||
for (auto& namedCallData : _namedData) {
|
||||
for (auto& buffer : namedCallData.second.buffers) {
|
||||
if (!buffer) {
|
||||
continue;
|
||||
}
|
||||
if (!buffer->isDirty()) {
|
||||
continue;
|
||||
}
|
||||
buffer->flush();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& bufferCacheItem : _buffers._items) {
|
||||
const BufferPointer& buffer = bufferCacheItem._data;
|
||||
if (!buffer) {
|
||||
continue;
|
||||
}
|
||||
if (!buffer->isDirty()) {
|
||||
continue;
|
||||
}
|
||||
buffer->flush();
|
||||
}
|
||||
}
|
|
@ -102,9 +102,13 @@ public:
|
|||
~Batch();
|
||||
|
||||
void clear();
|
||||
|
||||
// Call on the main thread to prepare for passing to the render thread
|
||||
void finish(BufferUpdates& updates);
|
||||
|
||||
|
||||
// Call on the rendering thread for batches that only exist there
|
||||
void flush();
|
||||
|
||||
void preExecute();
|
||||
|
||||
// Batches may need to override the context level stereo settings
|
||||
|
|
|
@ -283,6 +283,7 @@ void Buffer::markDirty(Size offset, Size bytes) {
|
|||
}
|
||||
|
||||
Buffer::Update Buffer::getUpdate() const {
|
||||
++_getUpdateCount;
|
||||
static Update EMPTY_UPDATE;
|
||||
if (!_pages) {
|
||||
return EMPTY_UPDATE;
|
||||
|
@ -315,11 +316,14 @@ Buffer::Update Buffer::getUpdate() const {
|
|||
}
|
||||
|
||||
void Buffer::applyUpdate(const Update& update) {
|
||||
++_applyUpdateCount;
|
||||
_renderPages = update.pages;
|
||||
update.updateOperator(_renderSysmem);
|
||||
}
|
||||
|
||||
void Buffer::flush() {
|
||||
++_getUpdateCount;
|
||||
++_applyUpdateCount;
|
||||
_renderPages = _pages;
|
||||
_renderSysmem.resize(_sysmem.getSize());
|
||||
auto dirtyPages = _pages.getMarkedPages();
|
||||
|
|
|
@ -355,6 +355,8 @@ public:
|
|||
mutable PageManager _renderPages;
|
||||
Sysmem _renderSysmem;
|
||||
|
||||
mutable std::atomic<size_t> _getUpdateCount;
|
||||
mutable std::atomic<size_t> _applyUpdateCount;
|
||||
protected:
|
||||
void markDirty(Size offset, Size bytes);
|
||||
|
||||
|
|
Loading…
Reference in a new issue