mirror of
https://github.com/overte-org/overte.git
synced 2025-07-22 18:13:35 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into fix-release-grab
This commit is contained in:
commit
67944c40a1
50 changed files with 361 additions and 379 deletions
|
@ -88,7 +88,7 @@ FocusScope {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||||
newRecommendedRectJS.width,
|
newRecommendedRectJS.width,
|
||||||
newRecommendedRectJS.height);
|
newRecommendedRectJS.height);
|
||||||
|
@ -271,7 +271,7 @@ FocusScope {
|
||||||
|
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
var newRecommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||||
var windows = d.getTopLevelWindows();
|
var windows = d.getTopLevelWindows();
|
||||||
for (var i = 0; i < windows.length; ++i) {
|
for (var i = 0; i < windows.length; ++i) {
|
||||||
|
@ -410,7 +410,7 @@ FocusScope {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||||
newRecommendedRectJS.width,
|
newRecommendedRectJS.width,
|
||||||
newRecommendedRectJS.height);
|
newRecommendedRectJS.height);
|
||||||
|
@ -442,7 +442,7 @@ FocusScope {
|
||||||
|
|
||||||
var oldRecommendedRect = recommendedRect;
|
var oldRecommendedRect = recommendedRect;
|
||||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
var newRecommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||||
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ FocusScope {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var recommended = Controller.getRecommendedOverlayRect();
|
var recommended = Controller.getRecommendedHUDRect();
|
||||||
var maxX = recommended.x + recommended.width;
|
var maxX = recommended.x + recommended.width;
|
||||||
var maxY = recommended.y + recommended.height;
|
var maxY = recommended.y + recommended.height;
|
||||||
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y);
|
||||||
|
|
|
@ -168,7 +168,7 @@ Item {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: text
|
target: text
|
||||||
color: "#ffffff"
|
color: captionColorOverride !== "" ? captionColorOverride: "#ffffff"
|
||||||
text: tabletButton.hoverText
|
text: tabletButton.hoverText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ Item {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: text
|
target: text
|
||||||
color: "#333333"
|
color: captionColorOverride !== "" ? captionColorOverride: "#333333"
|
||||||
text: tabletButton.activeText
|
text: tabletButton.activeText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ Item {
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: text
|
target: text
|
||||||
color: "#333333"
|
color: captionColorOverride !== "" ? captionColorOverride: "#333333"
|
||||||
text: tabletButton.activeHoverText
|
text: tabletButton.activeHoverText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2016/07/11
|
|
||||||
// Copyright 2013-2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
uniform sampler2D sampler;
|
|
||||||
|
|
||||||
struct OverlayData {
|
|
||||||
mat4 mvp;
|
|
||||||
float alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std140) uniform overlayBuffer {
|
|
||||||
OverlayData overlay;
|
|
||||||
};
|
|
||||||
|
|
||||||
in vec2 vTexCoord;
|
|
||||||
|
|
||||||
out vec4 FragColor;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
FragColor = texture(sampler, vTexCoord);
|
|
||||||
FragColor.a *= overlay.alpha;
|
|
||||||
if (FragColor.a <= 0.0) {
|
|
||||||
discard;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2016/07/11
|
|
||||||
// Copyright 2013-2016 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
struct OverlayData {
|
|
||||||
mat4 mvp;
|
|
||||||
float alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std140) uniform overlayBuffer {
|
|
||||||
OverlayData overlay;
|
|
||||||
};
|
|
||||||
|
|
||||||
mat4 mvp = overlay.mvp;
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 Position;
|
|
||||||
layout(location = 3) in vec2 TexCoord;
|
|
||||||
|
|
||||||
out vec2 vTexCoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = mvp * vec4(Position, 1);
|
|
||||||
vTexCoord = TexCoord;
|
|
||||||
}
|
|
|
@ -5051,6 +5051,7 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale();
|
float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale();
|
||||||
appRenderArgs._sensorToWorldScale = sensorToWorldScale;
|
appRenderArgs._sensorToWorldScale = sensorToWorldScale;
|
||||||
|
appRenderArgs._sensorToWorld = getMyAvatar()->getSensorToWorldMatrix();
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(render, "/buildFrustrumAndArgs");
|
PROFILE_RANGE(render, "/buildFrustrumAndArgs");
|
||||||
{
|
{
|
||||||
|
@ -5092,6 +5093,7 @@ void Application::update(float deltaTime) {
|
||||||
ipdScale *= sensorToWorldScale;
|
ipdScale *= sensorToWorldScale;
|
||||||
|
|
||||||
auto baseProjection = appRenderArgs._renderArgs.getViewFrustum().getProjection();
|
auto baseProjection = appRenderArgs._renderArgs.getViewFrustum().getProjection();
|
||||||
|
|
||||||
if (getActiveDisplayPlugin()->isStereo()) {
|
if (getActiveDisplayPlugin()->isStereo()) {
|
||||||
// Stereo modes will typically have a larger projection matrix overall,
|
// Stereo modes will typically have a larger projection matrix overall,
|
||||||
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
||||||
|
@ -7022,11 +7024,11 @@ glm::uvec2 Application::getUiSize() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect Application::getRecommendedOverlayRect() const {
|
QRect Application::getRecommendedHUDRect() const {
|
||||||
auto uiSize = getUiSize();
|
auto uiSize = getUiSize();
|
||||||
QRect result(0, 0, uiSize.x, uiSize.y);
|
QRect result(0, 0, uiSize.x, uiSize.y);
|
||||||
if (_displayPlugin) {
|
if (_displayPlugin) {
|
||||||
result = getActiveDisplayPlugin()->getRecommendedOverlayRect();
|
result = getActiveDisplayPlugin()->getRecommendedHUDRect();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ public:
|
||||||
QRect getRenderingGeometry() const;
|
QRect getRenderingGeometry() const;
|
||||||
|
|
||||||
glm::uvec2 getUiSize() const;
|
glm::uvec2 getUiSize() const;
|
||||||
QRect getRecommendedOverlayRect() const;
|
QRect getRecommendedHUDRect() const;
|
||||||
QSize getDeviceSize() const;
|
QSize getDeviceSize() const;
|
||||||
bool hasFocus() const;
|
bool hasFocus() const;
|
||||||
|
|
||||||
|
|
|
@ -126,28 +126,18 @@ void Application::paintGL() {
|
||||||
renderArgs._context->setStereoViews(stereoEyeOffsets);
|
renderArgs._context->setStereoViews(stereoEyeOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderArgs._hudOperator = displayPlugin->getHUDOperator();
|
||||||
|
renderArgs._hudTexture = _applicationOverlay.getOverlayTexture();
|
||||||
renderArgs._blitFramebuffer = finalFramebuffer;
|
renderArgs._blitFramebuffer = finalFramebuffer;
|
||||||
runRenderFrame(&renderArgs);
|
runRenderFrame(&renderArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::Batch postCompositeBatch;
|
|
||||||
{
|
|
||||||
PROFILE_RANGE(render, "/postComposite");
|
|
||||||
PerformanceTimer perfTimer("postComposite");
|
|
||||||
renderArgs._batch = &postCompositeBatch;
|
|
||||||
renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()));
|
|
||||||
renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView());
|
|
||||||
_overlays.render3DHUDOverlays(&renderArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto frame = _gpuContext->endFrame();
|
auto frame = _gpuContext->endFrame();
|
||||||
frame->frameIndex = _renderFrameCount;
|
frame->frameIndex = _renderFrameCount;
|
||||||
frame->framebuffer = finalFramebuffer;
|
frame->framebuffer = finalFramebuffer;
|
||||||
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||||
DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
|
DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
|
||||||
};
|
};
|
||||||
frame->overlay = _applicationOverlay.getOverlayTexture();
|
|
||||||
frame->postCompositeBatch = postCompositeBatch;
|
|
||||||
// deliver final scene rendering commands to the display plugin
|
// deliver final scene rendering commands to the display plugin
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(render, "/pluginOutput");
|
PROFILE_RANGE(render, "/pluginOutput");
|
||||||
|
|
|
@ -91,8 +91,8 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
||||||
return qApp->getUiSize();
|
return qApp->getUiSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ControllerScriptingInterface::getRecommendedOverlayRect() const {
|
QVariant ControllerScriptingInterface::getRecommendedHUDRect() const {
|
||||||
auto rect = qApp->getRecommendedOverlayRect();
|
auto rect = qApp->getRecommendedHUDRect();
|
||||||
return qRectToVariant(rect);
|
return qRectToVariant(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ public slots:
|
||||||
virtual void releaseEntityClickEvents();
|
virtual void releaseEntityClickEvents();
|
||||||
|
|
||||||
virtual glm::vec2 getViewportDimensions() const;
|
virtual glm::vec2 getViewportDimensions() const;
|
||||||
virtual QVariant getRecommendedOverlayRect() const;
|
virtual QVariant getRecommendedHUDRect() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void keyPressEvent(const KeyEvent& event);
|
void keyPressEvent(const KeyEvent& event);
|
||||||
|
|
|
@ -29,7 +29,7 @@ int DesktopScriptingInterface::getHeight() {
|
||||||
return size.height();
|
return size.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopScriptingInterface::setOverlayAlpha(float alpha) {
|
void DesktopScriptingInterface::setHUDAlpha(float alpha) {
|
||||||
qApp->getApplicationCompositor().setAlpha(alpha);
|
qApp->getApplicationCompositor().setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class DesktopScriptingInterface : public QObject, public Dependency {
|
||||||
Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus
|
Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE void setOverlayAlpha(float alpha);
|
Q_INVOKABLE void setHUDAlpha(float alpha);
|
||||||
Q_INVOKABLE void show(const QString& path, const QString& title);
|
Q_INVOKABLE void show(const QString& path, const QString& title);
|
||||||
|
|
||||||
int getWidth();
|
int getWidth();
|
||||||
|
|
|
@ -26,7 +26,8 @@ Base3DOverlay::Base3DOverlay() :
|
||||||
_isSolid(DEFAULT_IS_SOLID),
|
_isSolid(DEFAULT_IS_SOLID),
|
||||||
_isDashedLine(DEFAULT_IS_DASHED_LINE),
|
_isDashedLine(DEFAULT_IS_DASHED_LINE),
|
||||||
_ignoreRayIntersection(false),
|
_ignoreRayIntersection(false),
|
||||||
_drawInFront(false)
|
_drawInFront(false),
|
||||||
|
_drawHUDLayer(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
|
||||||
_isDashedLine(base3DOverlay->_isDashedLine),
|
_isDashedLine(base3DOverlay->_isDashedLine),
|
||||||
_ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection),
|
_ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection),
|
||||||
_drawInFront(base3DOverlay->_drawInFront),
|
_drawInFront(base3DOverlay->_drawInFront),
|
||||||
|
_drawHUDLayer(base3DOverlay->_drawHUDLayer),
|
||||||
_isGrabbable(base3DOverlay->_isGrabbable)
|
_isGrabbable(base3DOverlay->_isGrabbable)
|
||||||
{
|
{
|
||||||
setTransform(base3DOverlay->getTransform());
|
setTransform(base3DOverlay->getTransform());
|
||||||
|
@ -125,13 +127,19 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
||||||
bool needRenderItemUpdate = false;
|
bool needRenderItemUpdate = false;
|
||||||
|
|
||||||
auto drawInFront = properties["drawInFront"];
|
auto drawInFront = properties["drawInFront"];
|
||||||
|
|
||||||
if (drawInFront.isValid()) {
|
if (drawInFront.isValid()) {
|
||||||
bool value = drawInFront.toBool();
|
bool value = drawInFront.toBool();
|
||||||
setDrawInFront(value);
|
setDrawInFront(value);
|
||||||
needRenderItemUpdate = true;
|
needRenderItemUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto drawHUDLayer = properties["drawHUDLayer"];
|
||||||
|
if (drawHUDLayer.isValid()) {
|
||||||
|
bool value = drawHUDLayer.toBool();
|
||||||
|
setDrawHUDLayer(value);
|
||||||
|
needRenderItemUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto isGrabbable = properties["grabbable"];
|
auto isGrabbable = properties["grabbable"];
|
||||||
if (isGrabbable.isValid()) {
|
if (isGrabbable.isValid()) {
|
||||||
setIsGrabbable(isGrabbable.toBool());
|
setIsGrabbable(isGrabbable.toBool());
|
||||||
|
@ -269,10 +277,10 @@ void Base3DOverlay::update(float duration) {
|
||||||
// then the correct transform used for rendering is computed in the update transaction and assigned.
|
// then the correct transform used for rendering is computed in the update transaction and assigned.
|
||||||
if (_renderTransformDirty) {
|
if (_renderTransformDirty) {
|
||||||
auto itemID = getRenderItemID();
|
auto itemID = getRenderItemID();
|
||||||
// Capture the render transform value in game loop before
|
|
||||||
auto latestTransform = evalRenderTransform();
|
|
||||||
_renderTransformDirty = false;
|
|
||||||
if (render::Item::isValidID(itemID)) {
|
if (render::Item::isValidID(itemID)) {
|
||||||
|
// Capture the render transform value in game loop before
|
||||||
|
auto latestTransform = evalRenderTransform();
|
||||||
|
_renderTransformDirty = false;
|
||||||
render::ScenePointer scene = qApp->getMain3DScene();
|
render::ScenePointer scene = qApp->getMain3DScene();
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
transaction.updateItem<Overlay>(itemID, [latestTransform](Overlay& data) {
|
transaction.updateItem<Overlay>(itemID, [latestTransform](Overlay& data) {
|
||||||
|
@ -282,8 +290,6 @@ void Base3DOverlay::update(float duration) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scene->enqueueTransaction(transaction);
|
scene->enqueueTransaction(transaction);
|
||||||
} else {
|
|
||||||
setRenderTransform(latestTransform);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
bool getIsSolidLine() const { return !_isDashedLine; }
|
bool getIsSolidLine() const { return !_isDashedLine; }
|
||||||
bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; }
|
bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; }
|
||||||
bool getDrawInFront() const { return _drawInFront; }
|
bool getDrawInFront() const { return _drawInFront; }
|
||||||
|
bool getDrawHUDLayer() const { return _drawHUDLayer; }
|
||||||
bool getIsGrabbable() const { return _isGrabbable; }
|
bool getIsGrabbable() const { return _isGrabbable; }
|
||||||
|
|
||||||
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
|
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
|
||||||
|
@ -48,6 +49,7 @@ public:
|
||||||
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
|
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
|
||||||
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
||||||
virtual void setDrawInFront(bool value) { _drawInFront = value; }
|
virtual void setDrawInFront(bool value) { _drawInFront = value; }
|
||||||
|
virtual void setDrawHUDLayer(bool value) { _drawHUDLayer = value; }
|
||||||
void setIsGrabbable(bool value) { _isGrabbable = value; }
|
void setIsGrabbable(bool value) { _isGrabbable = value; }
|
||||||
|
|
||||||
virtual AABox getBounds() const override = 0;
|
virtual AABox getBounds() const override = 0;
|
||||||
|
@ -81,6 +83,7 @@ protected:
|
||||||
bool _isDashedLine;
|
bool _isDashedLine;
|
||||||
bool _ignoreRayIntersection;
|
bool _ignoreRayIntersection;
|
||||||
bool _drawInFront;
|
bool _drawInFront;
|
||||||
|
bool _drawHUDLayer;
|
||||||
bool _isGrabbable { false };
|
bool _isGrabbable { false };
|
||||||
mutable bool _renderTransformDirty{ true };
|
mutable bool _renderTransformDirty{ true };
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ const render::ShapeKey Circle3DOverlay::getShapeKey() {
|
||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (!getIsSolid() || shouldDrawHUDLayer()) {
|
if (!getIsSolid()) {
|
||||||
builder.withUnlit().withDepthBias();
|
builder.withUnlit().withDepthBias();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -113,7 +113,7 @@ const render::ShapeKey Cube3DOverlay::getShapeKey() {
|
||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (!getIsSolid() || shouldDrawHUDLayer()) {
|
if (!getIsSolid()) {
|
||||||
builder.withUnlit().withDepthBias();
|
builder.withUnlit().withDepthBias();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -132,7 +132,7 @@ void Image3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
const render::ShapeKey Image3DOverlay::getShapeKey() {
|
||||||
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias();
|
||||||
if (_emissive || shouldDrawHUDLayer()) {
|
if (_emissive) {
|
||||||
builder.withUnlit();
|
builder.withUnlit();
|
||||||
}
|
}
|
||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
|
|
|
@ -87,6 +87,10 @@ void ModelOverlay::update(float deltatime) {
|
||||||
_drawInFrontDirty = false;
|
_drawInFrontDirty = false;
|
||||||
_model->setLayeredInFront(getDrawInFront(), scene);
|
_model->setLayeredInFront(getDrawInFront(), scene);
|
||||||
}
|
}
|
||||||
|
if (_drawInHUDDirty) {
|
||||||
|
_drawInHUDDirty = false;
|
||||||
|
_model->setLayeredInHUD(getDrawHUDLayer(), scene);
|
||||||
|
}
|
||||||
scene->enqueueTransaction(transaction);
|
scene->enqueueTransaction(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +115,11 @@ void ModelOverlay::setDrawInFront(bool drawInFront) {
|
||||||
_drawInFrontDirty = true;
|
_drawInFrontDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelOverlay::setDrawHUDLayer(bool drawHUDLayer) {
|
||||||
|
Base3DOverlay::setDrawHUDLayer(drawHUDLayer);
|
||||||
|
_drawInHUDDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelOverlay::setProperties(const QVariantMap& properties) {
|
void ModelOverlay::setProperties(const QVariantMap& properties) {
|
||||||
auto origPosition = getPosition();
|
auto origPosition = getPosition();
|
||||||
auto origRotation = getRotation();
|
auto origRotation = getRotation();
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
|
|
||||||
void setVisible(bool visible) override;
|
void setVisible(bool visible) override;
|
||||||
void setDrawInFront(bool drawInFront) override;
|
void setDrawInFront(bool drawInFront) override;
|
||||||
|
void setDrawHUDLayer(bool drawHUDLayer) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Transform evalRenderTransform() override;
|
Transform evalRenderTransform() override;
|
||||||
|
@ -78,8 +79,6 @@ private:
|
||||||
bool _scaleToFit = { false };
|
bool _scaleToFit = { false };
|
||||||
float _loadPriority { 0.0f };
|
float _loadPriority { 0.0f };
|
||||||
|
|
||||||
bool _visibleDirty { false };
|
|
||||||
bool _drawInFrontDirty { false };
|
|
||||||
AnimationPointer _animation;
|
AnimationPointer _animation;
|
||||||
|
|
||||||
QUrl _animationURL;
|
QUrl _animationURL;
|
||||||
|
@ -97,6 +96,11 @@ private:
|
||||||
QUrl _jointMappingURL;
|
QUrl _jointMappingURL;
|
||||||
bool _jointMappingCompleted { false };
|
bool _jointMappingCompleted { false };
|
||||||
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
|
||||||
|
|
||||||
|
bool _visibleDirty { false };
|
||||||
|
bool _drawInFrontDirty { false };
|
||||||
|
bool _drawInHUDDirty { false };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ModelOverlay_h
|
#endif // hifi_ModelOverlay_h
|
||||||
|
|
|
@ -32,7 +32,6 @@ Overlay::Overlay() :
|
||||||
_colorPulse(0.0f),
|
_colorPulse(0.0f),
|
||||||
_color(DEFAULT_OVERLAY_COLOR),
|
_color(DEFAULT_OVERLAY_COLOR),
|
||||||
_visible(true),
|
_visible(true),
|
||||||
_drawHUDLayer(false),
|
|
||||||
_anchor(NO_ANCHOR)
|
_anchor(NO_ANCHOR)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -51,7 +50,6 @@ Overlay::Overlay(const Overlay* overlay) :
|
||||||
_colorPulse(overlay->_colorPulse),
|
_colorPulse(overlay->_colorPulse),
|
||||||
_color(overlay->_color),
|
_color(overlay->_color),
|
||||||
_visible(overlay->_visible),
|
_visible(overlay->_visible),
|
||||||
_drawHUDLayer(overlay->_drawHUDLayer),
|
|
||||||
_anchor(overlay->_anchor)
|
_anchor(overlay->_anchor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -90,11 +88,6 @@ void Overlay::setProperties(const QVariantMap& properties) {
|
||||||
setColorPulse(properties["colorPulse"].toFloat());
|
setColorPulse(properties["colorPulse"].toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties["drawHUDLayer"].isValid()) {
|
|
||||||
bool drawHUDLayer = properties["drawHUDLayer"].toBool();
|
|
||||||
setDrawHUDLayer(drawHUDLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properties["visible"].isValid()) {
|
if (properties["visible"].isValid()) {
|
||||||
bool visible = properties["visible"].toBool();
|
bool visible = properties["visible"].toBool();
|
||||||
setVisible(visible);
|
setVisible(visible);
|
||||||
|
@ -170,13 +163,6 @@ float Overlay::getAlpha() {
|
||||||
return (_alphaPulse >= 0.0f) ? _alpha * pulseLevel : _alpha * (1.0f - pulseLevel);
|
return (_alphaPulse >= 0.0f) ? _alpha * pulseLevel : _alpha * (1.0f - pulseLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::setDrawHUDLayer(bool drawHUDLayer) {
|
|
||||||
if (drawHUDLayer != _drawHUDLayer) {
|
|
||||||
qApp->getOverlays().setOverlayDrawHUDLayer(getOverlayID(), drawHUDLayer);
|
|
||||||
_drawHUDLayer = drawHUDLayer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pulse travels from min to max, then max to min in one period.
|
// pulse travels from min to max, then max to min in one period.
|
||||||
float Overlay::updatePulse() {
|
float Overlay::updatePulse() {
|
||||||
if (_pulsePeriod <= 0.0f) {
|
if (_pulsePeriod <= 0.0f) {
|
||||||
|
|
|
@ -58,7 +58,6 @@ public:
|
||||||
virtual bool is3D() const = 0;
|
virtual bool is3D() const = 0;
|
||||||
bool isLoaded() { return _isLoaded; }
|
bool isLoaded() { return _isLoaded; }
|
||||||
bool getVisible() const { return _visible; }
|
bool getVisible() const { return _visible; }
|
||||||
bool shouldDrawHUDLayer() const { return _drawHUDLayer; }
|
|
||||||
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
|
virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; };
|
||||||
xColor getColor();
|
xColor getColor();
|
||||||
float getAlpha();
|
float getAlpha();
|
||||||
|
@ -117,7 +116,6 @@ protected:
|
||||||
|
|
||||||
xColor _color;
|
xColor _color;
|
||||||
bool _visible; // should the overlay be drawn at all
|
bool _visible; // should the overlay be drawn at all
|
||||||
bool _drawHUDLayer; // should the overlay be drawn on the HUD layer
|
|
||||||
Anchor _anchor;
|
Anchor _anchor;
|
||||||
|
|
||||||
unsigned int _stackOrder { 0 };
|
unsigned int _stackOrder { 0 };
|
||||||
|
|
|
@ -37,29 +37,22 @@
|
||||||
#include "Web3DOverlay.h"
|
#include "Web3DOverlay.h"
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
#include "render/ShapePipeline.h"
|
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays")
|
Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays")
|
||||||
|
|
||||||
extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false);
|
extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false);
|
||||||
|
|
||||||
void Overlays::cleanupAllOverlays() {
|
void Overlays::cleanupAllOverlays() {
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
||||||
QMap<OverlayID, Overlay::Pointer> overlays3DHUD;
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
overlaysHUD.swap(_overlaysHUD);
|
overlaysHUD.swap(_overlaysHUD);
|
||||||
overlays3DHUD.swap(_overlays3DHUD);
|
|
||||||
overlaysWorld.swap(_overlaysWorld);
|
overlaysWorld.swap(_overlaysWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(Overlay::Pointer overlay, overlaysHUD) {
|
foreach(Overlay::Pointer overlay, overlaysHUD) {
|
||||||
_overlaysToDelete.push_back(overlay);
|
_overlaysToDelete.push_back(overlay);
|
||||||
}
|
}
|
||||||
foreach(Overlay::Pointer overlay, overlays3DHUD) {
|
|
||||||
_overlaysToDelete.push_back(overlay);
|
|
||||||
}
|
|
||||||
foreach(Overlay::Pointer overlay, overlaysWorld) {
|
foreach(Overlay::Pointer overlay, overlaysWorld) {
|
||||||
_overlaysToDelete.push_back(overlay);
|
_overlaysToDelete.push_back(overlay);
|
||||||
}
|
}
|
||||||
|
@ -73,8 +66,6 @@ void Overlays::init() {
|
||||||
#if OVERLAY_PANELS
|
#if OVERLAY_PANELS
|
||||||
_scriptEngine = new QScriptEngine();
|
_scriptEngine = new QScriptEngine();
|
||||||
#endif
|
#endif
|
||||||
_shapePlumber = std::make_shared<render::ShapePlumber>();
|
|
||||||
initOverlay3DPipelines(*_shapePlumber, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::update(float deltatime) {
|
void Overlays::update(float deltatime) {
|
||||||
|
@ -83,9 +74,6 @@ void Overlays::update(float deltatime) {
|
||||||
foreach(const auto& thisOverlay, _overlaysHUD) {
|
foreach(const auto& thisOverlay, _overlaysHUD) {
|
||||||
thisOverlay->update(deltatime);
|
thisOverlay->update(deltatime);
|
||||||
}
|
}
|
||||||
foreach(const auto& thisOverlay, _overlays3DHUD) {
|
|
||||||
thisOverlay->update(deltatime);
|
|
||||||
}
|
|
||||||
foreach(const auto& thisOverlay, _overlaysWorld) {
|
foreach(const auto& thisOverlay, _overlaysWorld) {
|
||||||
thisOverlay->update(deltatime);
|
thisOverlay->update(deltatime);
|
||||||
}
|
}
|
||||||
|
@ -142,23 +130,6 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) {
|
|
||||||
PROFILE_RANGE(render_overlays, __FUNCTION__);
|
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
|
||||||
|
|
||||||
auto textureCache = DependencyManager::get<TextureCache>();
|
|
||||||
|
|
||||||
QMutexLocker lock(&_mutex);
|
|
||||||
foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) {
|
|
||||||
// Reset necessary batch pipeline settings between overlays
|
|
||||||
batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this??
|
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
|
|
||||||
renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey());
|
|
||||||
thisOverlay->render(renderArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Overlays::disable() {
|
void Overlays::disable() {
|
||||||
_enabled = false;
|
_enabled = false;
|
||||||
}
|
}
|
||||||
|
@ -173,8 +144,6 @@ Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
if (_overlaysHUD.contains(id)) {
|
if (_overlaysHUD.contains(id)) {
|
||||||
return _overlaysHUD[id];
|
return _overlaysHUD[id];
|
||||||
} else if (_overlays3DHUD.contains(id)) {
|
|
||||||
return _overlays3DHUD[id];
|
|
||||||
} else if (_overlaysWorld.contains(id)) {
|
} else if (_overlaysWorld.contains(id)) {
|
||||||
return _overlaysWorld[id];
|
return _overlaysWorld[id];
|
||||||
}
|
}
|
||||||
|
@ -232,7 +201,7 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
OverlayID thisID = OverlayID(QUuid::createUuid());
|
OverlayID thisID = OverlayID(QUuid::createUuid());
|
||||||
overlay->setOverlayID(thisID);
|
overlay->setOverlayID(thisID);
|
||||||
overlay->setStackOrder(_stackOrder++);
|
overlay->setStackOrder(_stackOrder++);
|
||||||
if (overlay->is3D() && !overlay->shouldDrawHUDLayer()) {
|
if (overlay->is3D()) {
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
_overlaysWorld[thisID] = overlay;
|
_overlaysWorld[thisID] = overlay;
|
||||||
|
@ -242,9 +211,6 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
overlay->addToScene(overlay, scene, transaction);
|
overlay->addToScene(overlay, scene, transaction);
|
||||||
scene->enqueueTransaction(transaction);
|
scene->enqueueTransaction(transaction);
|
||||||
} else if (overlay->is3D() && overlay->shouldDrawHUDLayer()) {
|
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
_overlays3DHUD[thisID] = overlay;
|
|
||||||
} else {
|
} else {
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
_overlaysHUD[thisID] = overlay;
|
_overlaysHUD[thisID] = overlay;
|
||||||
|
@ -253,28 +219,6 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
return thisID;
|
return thisID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::setOverlayDrawHUDLayer(const OverlayID& id, const bool drawHUDLayer) {
|
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
if (drawHUDLayer && _overlaysWorld.contains(id)) {
|
|
||||||
std::shared_ptr<Overlay> overlay = _overlaysWorld.take(id);
|
|
||||||
render::ScenePointer scene = qApp->getMain3DScene();
|
|
||||||
render::Transaction transaction;
|
|
||||||
auto itemID = overlay->getRenderItemID();
|
|
||||||
if (render::Item::isValidID(itemID)) {
|
|
||||||
overlay->removeFromScene(overlay, scene, transaction);
|
|
||||||
scene->enqueueTransaction(transaction);
|
|
||||||
}
|
|
||||||
_overlays3DHUD[id] = overlay;
|
|
||||||
} else if (!drawHUDLayer && _overlays3DHUD.contains(id)) {
|
|
||||||
std::shared_ptr<Overlay> overlay = _overlays3DHUD.take(id);
|
|
||||||
render::ScenePointer scene = qApp->getMain3DScene();
|
|
||||||
render::Transaction transaction;
|
|
||||||
overlay->addToScene(overlay, scene, transaction);
|
|
||||||
scene->enqueueTransaction(transaction);
|
|
||||||
_overlaysWorld[id] = overlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
|
@ -361,8 +305,6 @@ void Overlays::deleteOverlay(OverlayID id) {
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
if (_overlaysHUD.contains(id)) {
|
if (_overlaysHUD.contains(id)) {
|
||||||
overlayToDelete = _overlaysHUD.take(id);
|
overlayToDelete = _overlaysHUD.take(id);
|
||||||
} else if (_overlays3DHUD.contains(id)) {
|
|
||||||
overlayToDelete = _overlays3DHUD.take(id);
|
|
||||||
} else if (_overlaysWorld.contains(id)) {
|
} else if (_overlaysWorld.contains(id)) {
|
||||||
overlayToDelete = _overlaysWorld.take(id);
|
overlayToDelete = _overlaysWorld.take(id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -771,7 +713,7 @@ bool Overlays::isAddedOverlay(OverlayID id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
return _overlaysHUD.contains(id) || _overlays3DHUD.contains(id) || _overlaysWorld.contains(id);
|
return _overlaysHUD.contains(id) || _overlaysWorld.contains(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) {
|
||||||
|
|
|
@ -90,7 +90,6 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void update(float deltatime);
|
void update(float deltatime);
|
||||||
void renderHUD(RenderArgs* renderArgs);
|
void renderHUD(RenderArgs* renderArgs);
|
||||||
void render3DHUDOverlays(RenderArgs* renderArgs);
|
|
||||||
void disable();
|
void disable();
|
||||||
void enable();
|
void enable();
|
||||||
|
|
||||||
|
@ -103,8 +102,6 @@ public:
|
||||||
OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
|
OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); }
|
||||||
OverlayID addOverlay(const Overlay::Pointer& overlay);
|
OverlayID addOverlay(const Overlay::Pointer& overlay);
|
||||||
|
|
||||||
void setOverlayDrawHUDLayer(const OverlayID& id, const bool drawHUDLayer);
|
|
||||||
|
|
||||||
bool mousePressEvent(QMouseEvent* event);
|
bool mousePressEvent(QMouseEvent* event);
|
||||||
bool mouseDoublePressEvent(QMouseEvent* event);
|
bool mouseDoublePressEvent(QMouseEvent* event);
|
||||||
bool mouseReleaseEvent(QMouseEvent* event);
|
bool mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
@ -334,11 +331,8 @@ private:
|
||||||
|
|
||||||
mutable QMutex _mutex { QMutex::Recursive };
|
mutable QMutex _mutex { QMutex::Recursive };
|
||||||
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
QMap<OverlayID, Overlay::Pointer> _overlaysHUD;
|
||||||
QMap<OverlayID, Overlay::Pointer> _overlays3DHUD;
|
|
||||||
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
QMap<OverlayID, Overlay::Pointer> _overlaysWorld;
|
||||||
|
|
||||||
render::ShapePlumberPointer _shapePlumber;
|
|
||||||
|
|
||||||
#if OVERLAY_PANELS
|
#if OVERLAY_PANELS
|
||||||
QMap<OverlayID, OverlayPanel::Pointer> _panels;
|
QMap<OverlayID, OverlayPanel::Pointer> _panels;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,7 +34,8 @@ namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
|
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
|
||||||
auto builder = ItemKey::Builder().withTypeShape();
|
auto builder = ItemKey::Builder().withTypeShape();
|
||||||
if (overlay->is3D()) {
|
if (overlay->is3D()) {
|
||||||
if (std::static_pointer_cast<Base3DOverlay>(overlay)->getDrawInFront()) {
|
auto overlay3D = std::static_pointer_cast<Base3DOverlay>(overlay);
|
||||||
|
if (overlay3D->getDrawInFront() || overlay3D->getDrawHUDLayer()) {
|
||||||
builder.withLayered();
|
builder.withLayered();
|
||||||
}
|
}
|
||||||
if (overlay->isTransparent()) {
|
if (overlay->isTransparent()) {
|
||||||
|
@ -49,20 +50,17 @@ namespace render {
|
||||||
return overlay->getBounds();
|
return overlay->getBounds();
|
||||||
}
|
}
|
||||||
template <> int payloadGetLayer(const Overlay::Pointer& overlay) {
|
template <> int payloadGetLayer(const Overlay::Pointer& overlay) {
|
||||||
// Magic number while we are defining the layering mechanism:
|
|
||||||
const int LAYER_2D = 2;
|
|
||||||
const int LAYER_3D_FRONT = 1;
|
|
||||||
const int LAYER_3D = 0;
|
|
||||||
|
|
||||||
if (overlay->is3D()) {
|
if (overlay->is3D()) {
|
||||||
auto overlay3D = std::dynamic_pointer_cast<Base3DOverlay>(overlay);
|
auto overlay3D = std::dynamic_pointer_cast<Base3DOverlay>(overlay);
|
||||||
if (overlay3D->getDrawInFront()) {
|
if (overlay3D->getDrawInFront()) {
|
||||||
return LAYER_3D_FRONT;
|
return Item::LAYER_3D_FRONT;
|
||||||
|
} else if (overlay3D->getDrawHUDLayer()) {
|
||||||
|
return Item::LAYER_3D_HUD;
|
||||||
} else {
|
} else {
|
||||||
return LAYER_3D;
|
return Item::LAYER_3D;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return LAYER_2D;
|
return Item::LAYER_2D;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
|
template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ const render::ShapeKey Shape3DOverlay::getShapeKey() {
|
||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (!getIsSolid() || shouldDrawHUDLayer()) {
|
if (!getIsSolid()) {
|
||||||
builder.withUnlit().withDepthBias();
|
builder.withUnlit().withDepthBias();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -60,7 +60,7 @@ const render::ShapeKey Sphere3DOverlay::getShapeKey() {
|
||||||
if (isTransparent()) {
|
if (isTransparent()) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (!getIsSolid() || shouldDrawHUDLayer()) {
|
if (!getIsSolid()) {
|
||||||
builder.withUnlit().withDepthBias();
|
builder.withUnlit().withDepthBias();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
|
|
||||||
void setModelTransform(const Transform& transform) { _modelTransform = transform; }
|
void setModelTransform(const Transform& transform) { _modelTransform = transform; }
|
||||||
const Transform& getModelTransform() const { return _modelTransform; }
|
const Transform& getModelTransform() const { return _modelTransform; }
|
||||||
|
glm::mat4 getUiTransform() const;
|
||||||
|
|
||||||
float getAlpha() const { return _alpha; }
|
float getAlpha() const { return _alpha; }
|
||||||
void setAlpha(float alpha) { if (alpha != _alpha) { emit alphaChanged(); _alpha = alpha; } }
|
void setAlpha(float alpha) { if (alpha != _alpha) { emit alphaChanged(); _alpha = alpha; } }
|
||||||
|
@ -122,7 +123,6 @@ protected slots:
|
||||||
void sendFakeMouseEvent();
|
void sendFakeMouseEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::mat4 getUiTransform() const;
|
|
||||||
void updateTooltips();
|
void updateTooltips();
|
||||||
|
|
||||||
DisplayPluginPointer _currentDisplayPlugin;
|
DisplayPluginPointer _currentDisplayPlugin;
|
||||||
|
|
|
@ -307,7 +307,7 @@ bool OpenGLDisplayPlugin::activate() {
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
connect(compositorHelper.data(), &CompositorHelper::alphaChanged, [this] {
|
connect(compositorHelper.data(), &CompositorHelper::alphaChanged, [this] {
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
auto animation = new QPropertyAnimation(this, "overlayAlpha");
|
auto animation = new QPropertyAnimation(this, "hudAlpha");
|
||||||
animation->setDuration(200);
|
animation->setDuration(200);
|
||||||
animation->setEndValue(compositorHelper->getAlpha());
|
animation->setEndValue(compositorHelper->getAlpha());
|
||||||
animation->start();
|
animation->start();
|
||||||
|
@ -415,7 +415,7 @@ void OpenGLDisplayPlugin::customizeContext() {
|
||||||
state->setBlendFunction(true,
|
state->setBlendFunction(true,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
_overlayPipeline = gpu::Pipeline::create(program, state);
|
_hudPipeline = gpu::Pipeline::create(program, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -437,7 +437,7 @@ void OpenGLDisplayPlugin::customizeContext() {
|
||||||
void OpenGLDisplayPlugin::uncustomizeContext() {
|
void OpenGLDisplayPlugin::uncustomizeContext() {
|
||||||
_presentPipeline.reset();
|
_presentPipeline.reset();
|
||||||
_cursorPipeline.reset();
|
_cursorPipeline.reset();
|
||||||
_overlayPipeline.reset();
|
_hudPipeline.reset();
|
||||||
_compositeFramebuffer.reset();
|
_compositeFramebuffer.reset();
|
||||||
withPresentThreadLock([&] {
|
withPresentThreadLock([&] {
|
||||||
_currentFrame.reset();
|
_currentFrame.reset();
|
||||||
|
@ -562,22 +562,23 @@ void OpenGLDisplayPlugin::updateFrameData() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::compositeOverlay() {
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> OpenGLDisplayPlugin::getHUDOperator() {
|
||||||
render([&](gpu::Batch& batch){
|
return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) {
|
||||||
batch.enableStereo(false);
|
if (_hudPipeline) {
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
batch.enableStereo(false);
|
||||||
batch.setPipeline(_overlayPipeline);
|
batch.setPipeline(_hudPipeline);
|
||||||
batch.setResourceTexture(0, _currentFrame->overlay);
|
batch.setResourceTexture(0, hudTexture);
|
||||||
if (isStereo()) {
|
if (isStereo()) {
|
||||||
for_each_eye([&](Eye eye) {
|
for_each_eye([&](Eye eye) {
|
||||||
batch.setViewportTransform(eyeViewport(eye));
|
batch.setViewportTransform(eyeViewport(eye));
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize()));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
});
|
}
|
||||||
} else {
|
|
||||||
batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize()));
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::compositePointer() {
|
void OpenGLDisplayPlugin::compositePointer() {
|
||||||
|
@ -626,29 +627,15 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
||||||
compositeScene();
|
compositeScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the depth framebuffer after drawing the scene so that the HUD elements can depth test against each other
|
|
||||||
render([&](gpu::Batch& batch) {
|
|
||||||
batch.enableStereo(false);
|
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
|
||||||
batch.clearDepthFramebuffer((float) UINT32_MAX);
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef HIFI_ENABLE_NSIGHT_DEBUG
|
#ifdef HIFI_ENABLE_NSIGHT_DEBUG
|
||||||
if (false) // do not compositeoverlay if running nsight debug
|
if (false) // do not draw the HUD if running nsight debug
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(render_detail, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(render_detail, "handleHUDBatch", 0xff0077ff, (uint64_t)presentCount())
|
||||||
compositeOverlay();
|
auto hudOperator = getHUDOperator();
|
||||||
}
|
withPresentThreadLock([&] {
|
||||||
|
_hudOperator = hudOperator;
|
||||||
// Only render HUD layer 3D overlays in HMD mode
|
|
||||||
if (isHmd()) {
|
|
||||||
PROFILE_RANGE_EX(render_detail, "compositeHUDOverlays", 0xff0077ff, (uint64_t)presentCount())
|
|
||||||
render([&](gpu::Batch& batch) {
|
|
||||||
batch.enableStereo(false);
|
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
|
||||||
});
|
});
|
||||||
_gpuContext->executeBatch(_currentFrame->postCompositeBatch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -656,13 +643,7 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
||||||
compositeExtra();
|
compositeExtra();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the depth buffer again and draw the pointer last so it's on top of everything
|
// Draw the pointer last so it's on top of everything
|
||||||
render([&](gpu::Batch& batch) {
|
|
||||||
batch.enableStereo(false);
|
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
|
||||||
batch.clearDepthFramebuffer((float) UINT32_MAX);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
if (compositorHelper->getReticleVisible()) {
|
if (compositorHelper->getReticleVisible()) {
|
||||||
PROFILE_RANGE_EX(render_detail, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(render_detail, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
||||||
|
@ -844,7 +825,7 @@ void OpenGLDisplayPlugin::assertIsPresentThread() const {
|
||||||
|
|
||||||
bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||||
withNonPresentThreadLock([&] {
|
withNonPresentThreadLock([&] {
|
||||||
_compositeOverlayAlpha = _overlayAlpha;
|
_compositeHUDAlpha = _hudAlpha;
|
||||||
});
|
});
|
||||||
return Parent::beginFrameRender(frameIndex);
|
return Parent::beginFrameRender(frameIndex);
|
||||||
}
|
}
|
||||||
|
@ -887,8 +868,7 @@ OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
|
||||||
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
||||||
auto renderSize = getRecommendedRenderSize();
|
auto renderSize = getRecommendedRenderSize();
|
||||||
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
|
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
|
||||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL);
|
_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_RGBA_32, depthFormat, renderSize.x, renderSize.y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <SimpleMovingAverage.h>
|
#include <SimpleMovingAverage.h>
|
||||||
#include <shared/RateCounter.h>
|
#include <shared/RateCounter.h>
|
||||||
|
|
||||||
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace gl {
|
namespace gl {
|
||||||
class GLBackend;
|
class GLBackend;
|
||||||
|
@ -30,7 +32,7 @@ namespace gpu {
|
||||||
|
|
||||||
class OpenGLDisplayPlugin : public DisplayPlugin {
|
class OpenGLDisplayPlugin : public DisplayPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(float overlayAlpha MEMBER _overlayAlpha)
|
Q_PROPERTY(float hudAlpha MEMBER _hudAlpha)
|
||||||
using Parent = DisplayPlugin;
|
using Parent = DisplayPlugin;
|
||||||
protected:
|
protected:
|
||||||
using Mutex = std::mutex;
|
using Mutex = std::mutex;
|
||||||
|
@ -93,7 +95,7 @@ protected:
|
||||||
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
|
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
|
||||||
virtual void compositeLayers();
|
virtual void compositeLayers();
|
||||||
virtual void compositeScene();
|
virtual void compositeScene();
|
||||||
virtual void compositeOverlay();
|
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&)> getHUDOperator();
|
||||||
virtual void compositePointer();
|
virtual void compositePointer();
|
||||||
virtual void compositeExtra() {};
|
virtual void compositeExtra() {};
|
||||||
|
|
||||||
|
@ -137,12 +139,12 @@ protected:
|
||||||
gpu::FramePointer _currentFrame;
|
gpu::FramePointer _currentFrame;
|
||||||
gpu::Frame* _lastFrame { nullptr };
|
gpu::Frame* _lastFrame { nullptr };
|
||||||
gpu::FramebufferPointer _compositeFramebuffer;
|
gpu::FramebufferPointer _compositeFramebuffer;
|
||||||
gpu::PipelinePointer _overlayPipeline;
|
gpu::PipelinePointer _hudPipeline;
|
||||||
gpu::PipelinePointer _simplePipeline;
|
gpu::PipelinePointer _simplePipeline;
|
||||||
gpu::PipelinePointer _presentPipeline;
|
gpu::PipelinePointer _presentPipeline;
|
||||||
gpu::PipelinePointer _cursorPipeline;
|
gpu::PipelinePointer _cursorPipeline;
|
||||||
gpu::TexturePointer _displayTexture{};
|
gpu::TexturePointer _displayTexture{};
|
||||||
float _compositeOverlayAlpha { 1.0f };
|
float _compositeHUDAlpha { 1.0f };
|
||||||
|
|
||||||
struct CursorData {
|
struct CursorData {
|
||||||
QImage image;
|
QImage image;
|
||||||
|
@ -176,6 +178,6 @@ protected:
|
||||||
// Any resource shared by the main thread and the presentation thread must
|
// Any resource shared by the main thread and the presentation thread must
|
||||||
// be serialized through this mutex
|
// be serialized through this mutex
|
||||||
mutable Mutex _presentMutex;
|
mutable Mutex _presentMutex;
|
||||||
float _overlayAlpha{ 1.0f };
|
float _hudAlpha{ 1.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include "../Logging.h"
|
#include "../Logging.h"
|
||||||
#include "../CompositorHelper.h"
|
#include "../CompositorHelper.h"
|
||||||
|
|
||||||
|
#include "render-utils/hmd_ui_vert.h"
|
||||||
|
#include "render-utils/hmd_ui_frag.h"
|
||||||
|
|
||||||
static const QString MONO_PREVIEW = "Mono Preview";
|
static const QString MONO_PREVIEW = "Mono Preview";
|
||||||
static const QString DISABLE_PREVIEW = "Disable Preview";
|
static const QString DISABLE_PREVIEW = "Disable Preview";
|
||||||
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
||||||
|
@ -46,19 +49,11 @@ static const glm::mat4 IDENTITY_MATRIX;
|
||||||
//#define LIVE_SHADER_RELOAD 1
|
//#define LIVE_SHADER_RELOAD 1
|
||||||
extern glm::vec3 getPoint(float yaw, float pitch);
|
extern glm::vec3 getPoint(float yaw, float pitch);
|
||||||
|
|
||||||
static QString readFile(const QString& filename) {
|
|
||||||
QFile file(filename);
|
|
||||||
file.open(QFile::Text | QFile::ReadOnly);
|
|
||||||
QString result;
|
|
||||||
result.append(QTextStream(&file).readAll());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const {
|
glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const {
|
||||||
return CompositorHelper::VIRTUAL_SCREEN_SIZE;
|
return CompositorHelper::VIRTUAL_SCREEN_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect HmdDisplayPlugin::getRecommendedOverlayRect() const {
|
QRect HmdDisplayPlugin::getRecommendedHUDRect() const {
|
||||||
return CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT;
|
return CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +103,7 @@ void HmdDisplayPlugin::internalDeactivate() {
|
||||||
|
|
||||||
void HmdDisplayPlugin::customizeContext() {
|
void HmdDisplayPlugin::customizeContext() {
|
||||||
Parent::customizeContext();
|
Parent::customizeContext();
|
||||||
_overlayRenderer.build();
|
_hudRenderer.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::uncustomizeContext() {
|
void HmdDisplayPlugin::uncustomizeContext() {
|
||||||
|
@ -121,7 +116,7 @@ void HmdDisplayPlugin::uncustomizeContext() {
|
||||||
batch.setFramebuffer(_compositeFramebuffer);
|
batch.setFramebuffer(_compositeFramebuffer);
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0));
|
||||||
});
|
});
|
||||||
_overlayRenderer = OverlayRenderer();
|
_hudRenderer = HUDRenderer();
|
||||||
_previewTexture.reset();
|
_previewTexture.reset();
|
||||||
Parent::uncustomizeContext();
|
Parent::uncustomizeContext();
|
||||||
}
|
}
|
||||||
|
@ -171,7 +166,7 @@ float HmdDisplayPlugin::getLeftCenterPixel() const {
|
||||||
void HmdDisplayPlugin::internalPresent() {
|
void HmdDisplayPlugin::internalPresent() {
|
||||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(render, __FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||||
|
|
||||||
// Composite together the scene, overlay and mouse cursor
|
// Composite together the scene, hud and mouse cursor
|
||||||
hmdPresent();
|
hmdPresent();
|
||||||
|
|
||||||
if (_displayTexture) {
|
if (_displayTexture) {
|
||||||
|
@ -344,17 +339,9 @@ void HmdDisplayPlugin::updateFrameData() {
|
||||||
auto correction = glm::inverse(batchPose) * currentPose;
|
auto correction = glm::inverse(batchPose) * currentPose;
|
||||||
getGLBackend()->setCameraCorrection(correction);
|
getGLBackend()->setCameraCorrection(correction);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
|
||||||
glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix();
|
|
||||||
|
|
||||||
for_each_eye([&](Eye eye) {
|
|
||||||
auto modelView = glm::inverse(_currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye)) * modelMat;
|
|
||||||
_overlayRenderer.mvps[eye] = _eyeProjections[eye] * modelView;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::OverlayRenderer::build() {
|
void HmdDisplayPlugin::HUDRenderer::build() {
|
||||||
vertices = std::make_shared<gpu::Buffer>();
|
vertices = std::make_shared<gpu::Buffer>();
|
||||||
indices = std::make_shared<gpu::Buffer>();
|
indices = std::make_shared<gpu::Buffer>();
|
||||||
|
|
||||||
|
@ -410,38 +397,20 @@ void HmdDisplayPlugin::OverlayRenderer::build() {
|
||||||
format = std::make_shared<gpu::Stream::Format>(); // 1 for everyone
|
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::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));
|
format->setAttribute(gpu::Stream::TEXCOORD, gpu::Stream::TEXCOORD, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
|
||||||
uniformBuffers[0] = std::make_shared<gpu::Buffer>(sizeof(Uniforms), nullptr);
|
uniformsBuffer = std::make_shared<gpu::Buffer>(sizeof(Uniforms), nullptr);
|
||||||
uniformBuffers[1] = std::make_shared<gpu::Buffer>(sizeof(Uniforms), nullptr);
|
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::OverlayRenderer::updatePipeline() {
|
void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
|
||||||
static const QString vsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui.vert";
|
|
||||||
static const QString fsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui.frag";
|
|
||||||
|
|
||||||
#if LIVE_SHADER_RELOAD
|
|
||||||
static qint64 vsBuiltAge = 0;
|
|
||||||
static qint64 fsBuiltAge = 0;
|
|
||||||
QFileInfo vsInfo(vsFile);
|
|
||||||
QFileInfo fsInfo(fsFile);
|
|
||||||
auto vsAge = vsInfo.lastModified().toMSecsSinceEpoch();
|
|
||||||
auto fsAge = fsInfo.lastModified().toMSecsSinceEpoch();
|
|
||||||
if (!pipeline || vsAge > vsBuiltAge || fsAge > fsBuiltAge) {
|
|
||||||
vsBuiltAge = vsAge;
|
|
||||||
fsBuiltAge = fsAge;
|
|
||||||
#else
|
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
#endif
|
auto vs = gpu::Shader::createVertex(std::string(hmd_ui_vert));
|
||||||
QString vsSource = readFile(vsFile);
|
auto ps = gpu::Shader::createPixel(std::string(hmd_ui_frag));
|
||||||
QString fsSource = readFile(fsFile);
|
|
||||||
auto vs = gpu::Shader::createVertex(vsSource.toLocal8Bit().toStdString());
|
|
||||||
auto ps = gpu::Shader::createPixel(fsSource.toLocal8Bit().toStdString());
|
|
||||||
auto program = gpu::Shader::createProgram(vs, ps);
|
auto program = gpu::Shader::createProgram(vs, ps);
|
||||||
gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet());
|
gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet());
|
||||||
this->uniformsLocation = program->getUniformBuffers().findLocation("overlayBuffer");
|
uniformsLocation = program->getUniformBuffers().findLocation("hudBuffer");
|
||||||
|
|
||||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
state->setDepthTest(gpu::State::DepthTest(false, false, gpu::LESS_EQUAL));
|
state->setDepthTest(gpu::State::DepthTest(true, true, gpu::LESS_EQUAL));
|
||||||
state->setBlendFunction(true,
|
state->setBlendFunction(true,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
@ -450,30 +419,29 @@ void HmdDisplayPlugin::OverlayRenderer::updatePipeline() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::OverlayRenderer::render(HmdDisplayPlugin& plugin) {
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) {
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
for_each_eye([&](Eye eye){
|
return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) {
|
||||||
uniforms.mvp = mvps[eye];
|
if (pipeline) {
|
||||||
uniformBuffers[eye]->setSubData(0, uniforms);
|
batch.setPipeline(pipeline);
|
||||||
});
|
|
||||||
plugin.render([&](gpu::Batch& batch) {
|
batch.setInputFormat(format);
|
||||||
batch.enableStereo(false);
|
gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element);
|
||||||
batch.setFramebuffer(plugin._compositeFramebuffer);
|
gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
||||||
batch.setPipeline(pipeline);
|
batch.setInputBuffer(gpu::Stream::POSITION, posView);
|
||||||
batch.setInputFormat(format);
|
batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView);
|
||||||
gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element);
|
batch.setIndexBuffer(gpu::UINT16, indices, 0);
|
||||||
gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
|
||||||
batch.setInputBuffer(gpu::Stream::POSITION, posView);
|
uniformsBuffer->setSubData(0, uniforms);
|
||||||
batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView);
|
batch.setUniformBuffer(uniformsLocation, uniformsBuffer);
|
||||||
batch.setIndexBuffer(gpu::UINT16, indices, 0);
|
|
||||||
batch.setResourceTexture(0, plugin._currentFrame->overlay);
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
// FIXME use stereo information input to set both MVPs in the uniforms
|
batch.setModelTransform(compositorHelper->getUiTransform());
|
||||||
for_each_eye([&](Eye eye) {
|
batch.setResourceTexture(0, hudTexture);
|
||||||
batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]);
|
|
||||||
batch.setViewportTransform(plugin.eyeViewport(eye));
|
|
||||||
batch.drawIndexed(gpu::TRIANGLES, indexCount);
|
batch.drawIndexed(gpu::TRIANGLES, indexCount);
|
||||||
});
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::compositePointer() {
|
void HmdDisplayPlugin::compositePointer() {
|
||||||
|
@ -500,12 +468,8 @@ void HmdDisplayPlugin::compositePointer() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::compositeOverlay() {
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> HmdDisplayPlugin::getHUDOperator() {
|
||||||
if (!_currentFrame || !_currentFrame->overlay) {
|
return _hudRenderer.render(*this);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_overlayRenderer.render(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HmdDisplayPlugin::~HmdDisplayPlugin() {
|
HmdDisplayPlugin::~HmdDisplayPlugin() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; }
|
glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; }
|
||||||
bool isDisplayVisible() const override { return isHmdMounted(); }
|
bool isDisplayVisible() const override { return isHmdMounted(); }
|
||||||
|
|
||||||
QRect getRecommendedOverlayRect() const override final;
|
QRect getRecommendedHUDRect() const override final;
|
||||||
|
|
||||||
virtual glm::mat4 getHeadPose() const override;
|
virtual glm::mat4 getHeadPose() const override;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ protected:
|
||||||
|
|
||||||
bool internalActivate() override;
|
bool internalActivate() override;
|
||||||
void internalDeactivate() override;
|
void internalDeactivate() override;
|
||||||
void compositeOverlay() override;
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> getHUDOperator() override;
|
||||||
void compositePointer() override;
|
void compositePointer() override;
|
||||||
void internalPresent() override;
|
void internalPresent() override;
|
||||||
void customizeContext() override;
|
void customizeContext() override;
|
||||||
|
@ -91,7 +91,7 @@ private:
|
||||||
gpu::TexturePointer _previewTexture;
|
gpu::TexturePointer _previewTexture;
|
||||||
glm::vec2 _lastWindowSize;
|
glm::vec2 _lastWindowSize;
|
||||||
|
|
||||||
struct OverlayRenderer {
|
struct HUDRenderer {
|
||||||
gpu::Stream::FormatPointer format;
|
gpu::Stream::FormatPointer format;
|
||||||
gpu::BufferPointer vertices;
|
gpu::BufferPointer vertices;
|
||||||
gpu::BufferPointer indices;
|
gpu::BufferPointer indices;
|
||||||
|
@ -99,12 +99,9 @@ private:
|
||||||
gpu::PipelinePointer pipeline;
|
gpu::PipelinePointer pipeline;
|
||||||
int32_t uniformsLocation { -1 };
|
int32_t uniformsLocation { -1 };
|
||||||
|
|
||||||
// FIXME this is stupid, use the built in transformation pipeline
|
gpu::BufferPointer uniformsBuffer;
|
||||||
std::array<gpu::BufferPointer, 2> uniformBuffers;
|
|
||||||
std::array<mat4, 2> mvps;
|
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
mat4 mvp;
|
|
||||||
float alpha { 1.0f };
|
float alpha { 1.0f };
|
||||||
} uniforms;
|
} uniforms;
|
||||||
|
|
||||||
|
@ -119,6 +116,6 @@ private:
|
||||||
|
|
||||||
void build();
|
void build();
|
||||||
void updatePipeline();
|
void updatePipeline();
|
||||||
void render(HmdDisplayPlugin& plugin);
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> render(HmdDisplayPlugin& plugin);
|
||||||
} _overlayRenderer;
|
} _hudRenderer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
void captureNamedDrawCallInfo(std::string name);
|
void captureNamedDrawCallInfo(std::string name);
|
||||||
|
|
||||||
Batch();
|
Batch();
|
||||||
explicit Batch(const Batch& batch);
|
Batch(const Batch& batch);
|
||||||
~Batch();
|
~Batch();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -32,14 +32,10 @@ namespace gpu {
|
||||||
Mat4 pose;
|
Mat4 pose;
|
||||||
/// The collection of batches which make up the frame
|
/// The collection of batches which make up the frame
|
||||||
Batches batches;
|
Batches batches;
|
||||||
/// Single batch containing overlays to be drawn in the composite framebuffer
|
|
||||||
Batch postCompositeBatch;
|
|
||||||
/// The main thread updates to buffers that are applicable for this frame.
|
/// The main thread updates to buffers that are applicable for this frame.
|
||||||
BufferUpdates bufferUpdates;
|
BufferUpdates bufferUpdates;
|
||||||
/// The destination framebuffer in which the results will be placed
|
/// The destination framebuffer in which the results will be placed
|
||||||
FramebufferPointer framebuffer;
|
FramebufferPointer framebuffer;
|
||||||
/// The destination texture containing the 2D overlay
|
|
||||||
TexturePointer overlay;
|
|
||||||
/// How to process the framebuffer when the frame dies. MUST BE THREAD SAFE
|
/// How to process the framebuffer when the frame dies. MUST BE THREAD SAFE
|
||||||
FramebufferRecycler framebufferRecycler;
|
FramebufferRecycler framebufferRecycler;
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,7 @@ glm::uvec2 rectifyToSparseSize(const glm::uvec2& size) {
|
||||||
|
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
enum {
|
QImage::Format QIMAGE_HDR_FORMAT = QImage::Format_RGB30;
|
||||||
QIMAGE_HDR_FORMAT = QImage::Format_RGB30
|
|
||||||
};
|
|
||||||
|
|
||||||
TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) {
|
TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -440,10 +438,8 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, const std::atom
|
||||||
auto mipFormat = texture->getStoredMipFormat();
|
auto mipFormat = texture->getStoredMipFormat();
|
||||||
std::function<glm::vec3(uint32)> unpackFunc;
|
std::function<glm::vec3(uint32)> unpackFunc;
|
||||||
|
|
||||||
nvtt::TextureType textureType = nvtt::TextureType_2D;
|
|
||||||
nvtt::InputFormat inputFormat = nvtt::InputFormat_RGBA_32F;
|
nvtt::InputFormat inputFormat = nvtt::InputFormat_RGBA_32F;
|
||||||
nvtt::WrapMode wrapMode = nvtt::WrapMode_Mirror;
|
nvtt::WrapMode wrapMode = nvtt::WrapMode_Mirror;
|
||||||
nvtt::RoundMode roundMode = nvtt::RoundMode_None;
|
|
||||||
nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None;
|
nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None;
|
||||||
|
|
||||||
nvtt::CompressionOptions compressionOptions;
|
nvtt::CompressionOptions compressionOptions;
|
||||||
|
|
|
@ -34,3 +34,12 @@ void DisplayPlugin::waitForPresent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> DisplayPlugin::getHUDOperator() {
|
||||||
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> hudOperator;
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&_presentMutex);
|
||||||
|
hudOperator = _hudOperator;
|
||||||
|
}
|
||||||
|
return hudOperator;
|
||||||
|
}
|
|
@ -156,8 +156,8 @@ public:
|
||||||
return aspect(getRecommendedRenderSize());
|
return aspect(getRecommendedRenderSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The recommended bounds for primary overlay placement
|
// The recommended bounds for primary HUD placement
|
||||||
virtual QRect getRecommendedOverlayRect() const {
|
virtual QRect getRecommendedHUDRect() const {
|
||||||
const int DESKTOP_SCREEN_PADDING = 50;
|
const int DESKTOP_SCREEN_PADDING = 50;
|
||||||
auto recommendedSize = getRecommendedUiSize() - glm::uvec2(DESKTOP_SCREEN_PADDING);
|
auto recommendedSize = getRecommendedUiSize() - glm::uvec2(DESKTOP_SCREEN_PADDING);
|
||||||
return QRect(0, 0, recommendedSize.x, recommendedSize.y);
|
return QRect(0, 0, recommendedSize.x, recommendedSize.y);
|
||||||
|
@ -204,8 +204,9 @@ public:
|
||||||
|
|
||||||
void waitForPresent();
|
void waitForPresent();
|
||||||
|
|
||||||
static const QString& MENU_PATH();
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> getHUDOperator();
|
||||||
|
|
||||||
|
static const QString& MENU_PATH();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void recommendedFramebufferSizeChanged(const QSize& size);
|
void recommendedFramebufferSizeChanged(const QSize& size);
|
||||||
|
@ -217,6 +218,8 @@ protected:
|
||||||
|
|
||||||
gpu::ContextPointer _gpuContext;
|
gpu::ContextPointer _gpuContext;
|
||||||
|
|
||||||
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> _hudOperator { std::function<void(gpu::Batch&, const gpu::TexturePointer&)>() };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMutex _presentMutex;
|
QMutex _presentMutex;
|
||||||
QWaitCondition _presentCondition;
|
QWaitCondition _presentCondition;
|
||||||
|
|
|
@ -385,7 +385,7 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
builder.withInvisible();
|
builder.withInvisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->isLayeredInFront()) {
|
if (model->isLayeredInFront() || model->isLayeredInHUD()) {
|
||||||
builder.withLayered();
|
builder.withLayered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,15 +404,15 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModelMeshPartPayload::getLayer() const {
|
int ModelMeshPartPayload::getLayer() const {
|
||||||
// MAgic number while we are defining the layering mechanism:
|
|
||||||
const int LAYER_3D_FRONT = 1;
|
|
||||||
const int LAYER_3D = 0;
|
|
||||||
ModelPointer model = _model.lock();
|
ModelPointer model = _model.lock();
|
||||||
if (model && model->isLayeredInFront()) {
|
if (model) {
|
||||||
return LAYER_3D_FRONT;
|
if (model->isLayeredInFront()) {
|
||||||
} else {
|
return Item::LAYER_3D_FRONT;
|
||||||
return LAYER_3D;
|
} else if (model->isLayeredInHUD()) {
|
||||||
|
return Item::LAYER_3D_HUD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return Item::LAYER_3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
|
|
|
@ -603,6 +603,21 @@ void Model::setLayeredInFront(bool layered, const render::ScenePointer& scene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::setLayeredInHUD(bool layered, const render::ScenePointer& scene) {
|
||||||
|
if (_isLayeredInHUD != layered) {
|
||||||
|
_isLayeredInHUD = layered;
|
||||||
|
|
||||||
|
render::Transaction transaction;
|
||||||
|
foreach(auto item, _modelMeshRenderItemsMap.keys()) {
|
||||||
|
transaction.resetItem(item, _modelMeshRenderItemsMap[item]);
|
||||||
|
}
|
||||||
|
foreach(auto item, _collisionRenderItemsMap.keys()) {
|
||||||
|
transaction.resetItem(item, _collisionRenderItemsMap[item]);
|
||||||
|
}
|
||||||
|
scene->enqueueTransaction(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Model::addToScene(const render::ScenePointer& scene,
|
bool Model::addToScene(const render::ScenePointer& scene,
|
||||||
render::Transaction& transaction,
|
render::Transaction& transaction,
|
||||||
render::Item::Status::Getters& statusGetters) {
|
render::Item::Status::Getters& statusGetters) {
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
// new Scene/Engine rendering support
|
// new Scene/Engine rendering support
|
||||||
void setVisibleInScene(bool newValue, const render::ScenePointer& scene);
|
void setVisibleInScene(bool newValue, const render::ScenePointer& scene);
|
||||||
void setLayeredInFront(bool layered, const render::ScenePointer& scene);
|
void setLayeredInFront(bool layered, const render::ScenePointer& scene);
|
||||||
|
void setLayeredInHUD(bool layered, const render::ScenePointer& scene);
|
||||||
bool needsFixupInScene() const;
|
bool needsFixupInScene() const;
|
||||||
|
|
||||||
bool needsReload() const { return _needsReload; }
|
bool needsReload() const { return _needsReload; }
|
||||||
|
@ -101,6 +102,7 @@ public:
|
||||||
bool isVisible() const { return _isVisible; }
|
bool isVisible() const { return _isVisible; }
|
||||||
|
|
||||||
bool isLayeredInFront() const { return _isLayeredInFront; }
|
bool isLayeredInFront() const { return _isLayeredInFront; }
|
||||||
|
bool isLayeredInHUD() const { return _isLayeredInHUD; }
|
||||||
|
|
||||||
virtual void updateRenderItems();
|
virtual void updateRenderItems();
|
||||||
void setRenderItemsNeedUpdate();
|
void setRenderItemsNeedUpdate();
|
||||||
|
@ -411,6 +413,7 @@ protected:
|
||||||
int _renderInfoHasTransparent { false };
|
int _renderInfoHasTransparent { false };
|
||||||
|
|
||||||
bool _isLayeredInFront { false };
|
bool _isLayeredInFront { false };
|
||||||
|
bool _isLayeredInHUD { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _loadingPriority { 0.0f };
|
float _loadingPriority { 0.0f };
|
||||||
|
|
|
@ -186,15 +186,20 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
||||||
task.addJob<DrawBounds>("DrawZones", zones);
|
task.addJob<DrawBounds>("DrawZones", zones);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overlays
|
// Layered Overlays
|
||||||
const auto overlayOpaquesInputs = DrawOverlay3D::Inputs(overlayOpaques, lightingModel).asVarying();
|
const auto filteredOverlaysOpaque = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT);
|
||||||
const auto overlayTransparentsInputs = DrawOverlay3D::Inputs(overlayTransparents, lightingModel).asVarying();
|
const auto filteredOverlaysTransparent = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT);
|
||||||
task.addJob<DrawOverlay3D>("DrawOverlay3DOpaque", overlayOpaquesInputs, true);
|
const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN<FilterLayeredItems::Outputs>(0);
|
||||||
task.addJob<DrawOverlay3D>("DrawOverlay3DTransparent", overlayTransparentsInputs, false);
|
const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN<FilterLayeredItems::Outputs>(0);
|
||||||
|
|
||||||
{ // Debug the bounds of the rendered Overlay items, still look at the zbuffer
|
const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel).asVarying();
|
||||||
task.addJob<DrawBounds>("DrawOverlayOpaqueBounds", overlayOpaques);
|
const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel).asVarying();
|
||||||
task.addJob<DrawBounds>("DrawOverlayTransparentBounds", overlayTransparents);
|
task.addJob<DrawOverlay3D>("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true);
|
||||||
|
task.addJob<DrawOverlay3D>("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false);
|
||||||
|
|
||||||
|
{ // Debug the bounds of the rendered Overlay items that are marked drawInFront, still look at the zbuffer
|
||||||
|
task.addJob<DrawBounds>("DrawOverlayInFrontOpaqueBounds", overlaysInFrontOpaque);
|
||||||
|
task.addJob<DrawBounds>("DrawOverlayInFrontTransparentBounds", overlaysInFrontTransparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugging stages
|
// Debugging stages
|
||||||
|
@ -233,6 +238,22 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
||||||
// AA job to be revisited
|
// AA job to be revisited
|
||||||
task.addJob<Antialiasing>("Antialiasing", primaryFramebuffer);
|
task.addJob<Antialiasing>("Antialiasing", primaryFramebuffer);
|
||||||
|
|
||||||
|
// Composite the HUD and HUD overlays
|
||||||
|
task.addJob<CompositeHUD>("HUD");
|
||||||
|
|
||||||
|
const auto overlaysHUDOpaque = filteredOverlaysOpaque.getN<FilterLayeredItems::Outputs>(1);
|
||||||
|
const auto overlaysHUDTransparent = filteredOverlaysTransparent.getN<FilterLayeredItems::Outputs>(1);
|
||||||
|
|
||||||
|
const auto overlayHUDOpaquesInputs = DrawOverlay3D::Inputs(overlaysHUDOpaque, lightingModel).asVarying();
|
||||||
|
const auto overlayHUDTransparentsInputs = DrawOverlay3D::Inputs(overlaysHUDTransparent, lightingModel).asVarying();
|
||||||
|
task.addJob<DrawOverlay3D>("DrawOverlayHUDOpaque", overlayHUDOpaquesInputs, true);
|
||||||
|
task.addJob<DrawOverlay3D>("DrawOverlayHUDTransparent", overlayHUDTransparentsInputs, false);
|
||||||
|
|
||||||
|
{ // Debug the bounds of the rendered Overlay items that are marked drawHUDLayer, still look at the zbuffer
|
||||||
|
task.addJob<DrawBounds>("DrawOverlayHUDOpaqueBounds", overlaysHUDOpaque);
|
||||||
|
task.addJob<DrawBounds>("DrawOverlayHUDTransparentBounds", overlaysHUDTransparent);
|
||||||
|
}
|
||||||
|
|
||||||
task.addJob<EndGPURangeTimer>("ToneAndPostRangeTimer", toneAndPostRangeTimer);
|
task.addJob<EndGPURangeTimer>("ToneAndPostRangeTimer", toneAndPostRangeTimer);
|
||||||
|
|
||||||
// Blit!
|
// Blit!
|
||||||
|
@ -407,6 +428,18 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompositeHUD::run(const RenderContextPointer& renderContext) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_context);
|
||||||
|
|
||||||
|
// Grab the HUD texture
|
||||||
|
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
||||||
|
if (renderContext->args->_hudOperator) {
|
||||||
|
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
|
void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_context);
|
assert(renderContext->args->_context);
|
||||||
|
|
|
@ -155,6 +155,14 @@ protected:
|
||||||
bool _opaquePass { true };
|
bool _opaquePass { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CompositeHUD {
|
||||||
|
public:
|
||||||
|
using JobModel = render::Job::Model<CompositeHUD>;
|
||||||
|
|
||||||
|
CompositeHUD() {}
|
||||||
|
void run(const render::RenderContextPointer& renderContext);
|
||||||
|
};
|
||||||
|
|
||||||
class Blit {
|
class Blit {
|
||||||
public:
|
public:
|
||||||
using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
|
using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
|
||||||
|
|
37
libraries/render-utils/src/hmd_ui.slf
Normal file
37
libraries/render-utils/src/hmd_ui.slf
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// hmd_ui.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 9/28/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
uniform sampler2D hudTexture;
|
||||||
|
|
||||||
|
struct HUDData {
|
||||||
|
float alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform hudBuffer {
|
||||||
|
HUDData hud;
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec2 _texCoord0;
|
||||||
|
|
||||||
|
out vec4 fragColor0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = texture(hudTexture, _texCoord0);
|
||||||
|
color.a *= hud.alpha;
|
||||||
|
if (color.a <= 0.0) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragColor0 = color;
|
||||||
|
}
|
36
libraries/render-utils/src/hmd_ui.slv
Normal file
36
libraries/render-utils/src/hmd_ui.slv
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// hmd_ui.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 9/28/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include gpu/Inputs.slh@>
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
struct HUDData {
|
||||||
|
float alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform hudBuffer {
|
||||||
|
HUDData hud;
|
||||||
|
};
|
||||||
|
|
||||||
|
out vec2 _texCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
_texCoord0 = inTexCoord0.st;
|
||||||
|
|
||||||
|
// standard transform
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
TransformObject obj = getTransformObject();
|
||||||
|
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||||
|
}
|
|
@ -121,6 +121,9 @@ namespace render {
|
||||||
RenderDetails _details;
|
RenderDetails _details;
|
||||||
render::ScenePointer _scene;
|
render::ScenePointer _scene;
|
||||||
int8_t _cameraMode { -1 };
|
int8_t _cameraMode { -1 };
|
||||||
|
|
||||||
|
std::function<void(gpu::Batch&, const gpu::TexturePointer&)> _hudOperator;
|
||||||
|
gpu::TexturePointer _hudTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,24 @@
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
void FilterLayeredItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
void FilterLayeredItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, Outputs& outputs) {
|
||||||
auto& scene = renderContext->_scene;
|
auto& scene = renderContext->_scene;
|
||||||
|
|
||||||
// Clear previous values
|
ItemBounds matchedItems;
|
||||||
outItems.clear();
|
ItemBounds nonMatchItems;
|
||||||
|
|
||||||
// For each item, filter it into one bucket
|
// For each item, filter it into one bucket
|
||||||
for (auto& itemBound : inItems) {
|
for (auto& itemBound : inItems) {
|
||||||
auto& item = scene->getItem(itemBound.id);
|
auto& item = scene->getItem(itemBound.id);
|
||||||
if (item.getLayer() == _keepLayer) {
|
if (item.getLayer() == _keepLayer) {
|
||||||
outItems.emplace_back(itemBound);
|
matchedItems.emplace_back(itemBound);
|
||||||
|
} else {
|
||||||
|
nonMatchItems.emplace_back(itemBound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputs.edit0() = matchedItems;
|
||||||
|
outputs.edit1() = nonMatchItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SliceItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
void SliceItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) {
|
||||||
|
|
|
@ -65,15 +65,15 @@ namespace render {
|
||||||
// Filter the items belonging to the job's keep layer
|
// Filter the items belonging to the job's keep layer
|
||||||
class FilterLayeredItems {
|
class FilterLayeredItems {
|
||||||
public:
|
public:
|
||||||
using JobModel = Job::ModelIO<FilterLayeredItems, ItemBounds, ItemBounds>;
|
using Outputs = render::VaryingSet2<ItemBounds, ItemBounds>;
|
||||||
|
using JobModel = Job::ModelIO<FilterLayeredItems, ItemBounds, Outputs>;
|
||||||
|
|
||||||
FilterLayeredItems() {}
|
|
||||||
FilterLayeredItems(int keepLayer) :
|
FilterLayeredItems(int keepLayer) :
|
||||||
_keepLayer(keepLayer) {}
|
_keepLayer(keepLayer) {}
|
||||||
|
|
||||||
int _keepLayer { 0 };
|
int _keepLayer;
|
||||||
|
|
||||||
void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems);
|
void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, Outputs& outputs);
|
||||||
};
|
};
|
||||||
|
|
||||||
// SliceItems job config defining the slice range
|
// SliceItems job config defining the slice range
|
||||||
|
|
|
@ -29,6 +29,11 @@ const float Item::Status::Value::CYAN = 180.0f;
|
||||||
const float Item::Status::Value::BLUE = 240.0f;
|
const float Item::Status::Value::BLUE = 240.0f;
|
||||||
const float Item::Status::Value::MAGENTA = 300.0f;
|
const float Item::Status::Value::MAGENTA = 300.0f;
|
||||||
|
|
||||||
|
const int Item::LAYER_2D = 0;
|
||||||
|
const int Item::LAYER_3D = 1;
|
||||||
|
const int Item::LAYER_3D_FRONT = 2;
|
||||||
|
const int Item::LAYER_3D_HUD = 3;
|
||||||
|
|
||||||
void Item::Status::Value::setScale(float scale) {
|
void Item::Status::Value::setScale(float scale) {
|
||||||
_scale = (std::numeric_limits<unsigned short>::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f));
|
_scale = (std::numeric_limits<unsigned short>::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,9 +356,14 @@ public:
|
||||||
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
|
// Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace())
|
||||||
const Bound getBound() const { return _payload->getBound(); }
|
const Bound getBound() const { return _payload->getBound(); }
|
||||||
|
|
||||||
// Get the layer where the item belongs. 0 by default meaning NOT LAYERED
|
// Get the layer where the item belongs.
|
||||||
int getLayer() const { return _payload->getLayer(); }
|
int getLayer() const { return _payload->getLayer(); }
|
||||||
|
|
||||||
|
static const int LAYER_2D;
|
||||||
|
static const int LAYER_3D;
|
||||||
|
static const int LAYER_3D_FRONT;
|
||||||
|
static const int LAYER_3D_HUD;
|
||||||
|
|
||||||
// Render call for the item
|
// Render call for the item
|
||||||
void render(RenderArgs* args) const { _payload->render(args); }
|
void render(RenderArgs* args) const { _payload->render(args); }
|
||||||
|
|
||||||
|
|
|
@ -178,15 +178,26 @@ Column {
|
||||||
onCheckedChanged: { mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked }
|
onCheckedChanged: { mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked }
|
||||||
}
|
}
|
||||||
CheckBox {
|
CheckBox {
|
||||||
text: "Overlay Opaques"
|
text: "Opaques in Front"
|
||||||
checked: mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"]
|
checked: mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"]
|
||||||
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"] = checked }
|
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] = checked }
|
||||||
}
|
}
|
||||||
CheckBox {
|
CheckBox {
|
||||||
text: "Overlay Transparents"
|
text: "Transparents in Front"
|
||||||
checked: mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"]
|
checked: mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"]
|
||||||
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked }
|
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] = checked }
|
||||||
}
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: "Opaques in HUD"
|
||||||
|
checked: mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"]
|
||||||
|
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked }
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: "Transparents in HUD"
|
||||||
|
checked: mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"]
|
||||||
|
onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Column {
|
Column {
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
glow: 1.0,
|
glow: 1.0,
|
||||||
lineWidth: 5,
|
lineWidth: 5,
|
||||||
ignoreRayIntersection: true, // always ignore this
|
ignoreRayIntersection: true, // always ignore this
|
||||||
drawHUDLayer: true, // Even when burried inside of something, show it.
|
drawHUDLayer: true,
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
var halfEnd = {
|
var halfEnd = {
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
ignoreRayIntersection: true,
|
ignoreRayIntersection: true,
|
||||||
drawHUDLayer: true, // Even when burried inside of something, show it.
|
drawHUDLayer: true,
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
var fullPath = {
|
var fullPath = {
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
glow: 1.0,
|
glow: 1.0,
|
||||||
lineWidth: 5,
|
lineWidth: 5,
|
||||||
ignoreRayIntersection: true, // always ignore this
|
ignoreRayIntersection: true, // always ignore this
|
||||||
drawHUDLayer: true, // Even when burried inside of something, show it.
|
drawHUDLayer: true,
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
var fullEnd = {
|
var fullEnd = {
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||||
alpha: 0.9,
|
alpha: 0.9,
|
||||||
ignoreRayIntersection: true,
|
ignoreRayIntersection: true,
|
||||||
drawHUDLayer: true, // Even when burried inside of something, show it.
|
drawHUDLayer: true,
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
var holdPath = {
|
var holdPath = {
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
glow: 1.0,
|
glow: 1.0,
|
||||||
lineWidth: 5,
|
lineWidth: 5,
|
||||||
ignoreRayIntersection: true, // always ignore this
|
ignoreRayIntersection: true, // always ignore this
|
||||||
drawHUDLayer: true, // Even when burried inside of something, show it.
|
drawHUDLayer: true,
|
||||||
parentID: AVATAR_SELF_ID
|
parentID: AVATAR_SELF_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -370,7 +370,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
return Math.min(Math.max(value, min), max);
|
return Math.min(Math.max(value, min), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
var recommendedRect = Controller.getRecommendedOverlayRect();
|
var recommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height };
|
var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height };
|
||||||
that.windowDimensions = recommendedDimmensions; // Controller.getViewportDimensions();
|
that.windowDimensions = recommendedDimmensions; // Controller.getViewportDimensions();
|
||||||
that.origin = { x: recommendedRect.x, y: recommendedRect.y };
|
that.origin = { x: recommendedRect.x, y: recommendedRect.y };
|
||||||
|
@ -378,7 +378,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
// For example, maybe we want "keep the same percentage to whatever two edges are closest to the edge of screen".
|
// For example, maybe we want "keep the same percentage to whatever two edges are closest to the edge of screen".
|
||||||
// If we change that, the places to do so are onResizeViewport, save (maybe), and the initial move based on Settings, below.
|
// If we change that, the places to do so are onResizeViewport, save (maybe), and the initial move based on Settings, below.
|
||||||
that.onResizeViewport = function (newSize) { // Can be overridden or extended by clients.
|
that.onResizeViewport = function (newSize) { // Can be overridden or extended by clients.
|
||||||
var recommendedRect = Controller.getRecommendedOverlayRect();
|
var recommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height };
|
var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height };
|
||||||
var originRelativeX = (that.x - that.origin.x - that.offset.x);
|
var originRelativeX = (that.x - that.origin.x - that.offset.x);
|
||||||
var originRelativeY = (that.y - that.origin.y - that.offset.y);
|
var originRelativeY = (that.y - that.origin.y - that.offset.y);
|
||||||
|
@ -396,7 +396,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
// code once the new toolbar position is well established with users.
|
// code once the new toolbar position is well established with users.
|
||||||
this.isNewPositionKey = optionalPersistenceKey + '.isNewPosition';
|
this.isNewPositionKey = optionalPersistenceKey + '.isNewPosition';
|
||||||
this.save = function () {
|
this.save = function () {
|
||||||
var recommendedRect = Controller.getRecommendedOverlayRect();
|
var recommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var screenSize = { x: recommendedRect.width, y: recommendedRect.height };
|
var screenSize = { x: recommendedRect.width, y: recommendedRect.height };
|
||||||
if (screenSize.x > 0 && screenSize.y > 0) {
|
if (screenSize.x > 0 && screenSize.y > 0) {
|
||||||
// Guard against invalid screen size that can occur at shut-down.
|
// Guard against invalid screen size that can occur at shut-down.
|
||||||
|
@ -443,7 +443,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
that.move(that.dragOffsetX + event.x, that.dragOffsetY + event.y);
|
that.move(that.dragOffsetX + event.x, that.dragOffsetY + event.y);
|
||||||
};
|
};
|
||||||
that.checkResize = function () { // Can be overriden or extended, but usually not. See onResizeViewport.
|
that.checkResize = function () { // Can be overriden or extended, but usually not. See onResizeViewport.
|
||||||
var recommendedRect = Controller.getRecommendedOverlayRect();
|
var recommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var currentWindowSize = { x: recommendedRect.width, y: recommendedRect.height };
|
var currentWindowSize = { x: recommendedRect.width, y: recommendedRect.height };
|
||||||
|
|
||||||
if ((currentWindowSize.x !== that.windowDimensions.x) || (currentWindowSize.y !== that.windowDimensions.y)) {
|
if ((currentWindowSize.x !== that.windowDimensions.x) || (currentWindowSize.y !== that.windowDimensions.y)) {
|
||||||
|
@ -471,7 +471,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit
|
||||||
var savedFraction = isNewPosition ? JSON.parse(Settings.getValue(this.fractionKey) || "0") : 0;
|
var savedFraction = isNewPosition ? JSON.parse(Settings.getValue(this.fractionKey) || "0") : 0;
|
||||||
Settings.setValue(this.isNewPositionKey, true);
|
Settings.setValue(this.isNewPositionKey, true);
|
||||||
|
|
||||||
var recommendedRect = Controller.getRecommendedOverlayRect();
|
var recommendedRect = Controller.getRecommendedHUDRect();
|
||||||
var screenSize = { x: recommendedRect.width, y: recommendedRect.height };
|
var screenSize = { x: recommendedRect.width, y: recommendedRect.height };
|
||||||
if (savedFraction) {
|
if (savedFraction) {
|
||||||
// If we have saved data, keep the toolbar at the same proportion of the screen width/height.
|
// If we have saved data, keep the toolbar at the same proportion of the screen width/height.
|
||||||
|
|
Loading…
Reference in a new issue