fixing file

This commit is contained in:
Sam Gateau 2015-05-09 11:43:21 -07:00
commit d51904b7b3
26 changed files with 388 additions and 180 deletions

View file

@ -32,7 +32,7 @@ var BUTTON_SIZE = 32;
var PADDING = 3;
var offButton = Overlays.addOverlay("image", {
x: screenSize.x / 2 - BUTTON_SIZE,
x: screenSize.x / 2 - BUTTON_SIZE * 2 + PADDING,
y: screenSize.y- (BUTTON_SIZE + PADDING),
width: BUTTON_SIZE,
height: BUTTON_SIZE,
@ -40,6 +40,17 @@ var offButton = Overlays.addOverlay("image", {
color: { red: 255, green: 255, blue: 255},
alpha: 1
});
var deleteButton = Overlays.addOverlay("image", {
x: screenSize.x / 2 - BUTTON_SIZE,
y: screenSize.y- (BUTTON_SIZE + PADDING),
width: BUTTON_SIZE,
height: BUTTON_SIZE,
imageURL: HIFI_PUBLIC_BUCKET + "images/delete.png",
color: { red: 255, green: 255, blue: 255},
alpha: 1
});
var diceButton = Overlays.addOverlay("image", {
x: screenSize.x / 2 + PADDING,
y: screenSize.y - (BUTTON_SIZE + PADDING),
@ -108,6 +119,8 @@ function mousePressEvent(event) {
if (clickedOverlay == offButton) {
deleteDice();
Script.stop();
} else if (clickedOverlay == deleteButton) {
deleteDice();
} else if (clickedOverlay == diceButton) {
var HOW_HARD = 2.0;
var position = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
@ -120,6 +133,7 @@ function mousePressEvent(event) {
function scriptEnding() {
Overlays.deleteOverlay(offButton);
Overlays.deleteOverlay(diceButton);
Overlays.deleteOverlay(deleteButton);
}
Entities.entityCollisionWithEntity.connect(entityCollisionWithEntity);

View file

@ -193,12 +193,15 @@ function update(deltaTime) {
// Add Damping
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
// Update entity
//add damping to angular velocity:
} else {
newVelocity = entityProps.velocity;
}
if (shouldRotate) {
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
} else {
angularVelocity = entityProps.angularVelocity;
}
Entities.editEntity(grabbedEntity, {
velocity: newVelocity,
angularVelocity: angularVelocity

View file

@ -26,6 +26,20 @@
);
};
}
function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) {
return function() {
var properties = {};
properties[group] = {};
properties[group][propertyName] = this.checked;
EventBridge.emitWebEvent(
JSON.stringify({
type: "update",
properties: properties
})
);
};
}
function createEmitNumberPropertyUpdateFunction(propertyName) {
return function() {
EventBridge.emitWebEvent(
@ -286,6 +300,8 @@
var elZoneAtmosphereScatteringWavelengthsX = document.getElementById("property-zone-atmosphere-scattering-wavelengths-x");
var elZoneAtmosphereScatteringWavelengthsY = document.getElementById("property-zone-atmosphere-scattering-wavelengths-y");
var elZoneAtmosphereScatteringWavelengthsZ = document.getElementById("property-zone-atmosphere-scattering-wavelengths-z");
var elZoneAtmosphereHasStars = document.getElementById("property-zone-atmosphere-has-stars");
if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) {
@ -486,7 +502,7 @@
elZoneAtmosphereScatteringWavelengthsX.value = properties.atmosphere.scatteringWavelengths.x;
elZoneAtmosphereScatteringWavelengthsY.value = properties.atmosphere.scatteringWavelengths.y;
elZoneAtmosphereScatteringWavelengthsZ.value = properties.atmosphere.scatteringWavelengths.z;
elZoneAtmosphereHasStars.checked = properties.atmosphere.hasStars;
}
@ -650,6 +666,8 @@
elZoneAtmosphereScatteringWavelengthsX.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
elZoneAtmosphereScatteringWavelengthsY.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
elZoneAtmosphereScatteringWavelengthsZ.addEventListener('change', zoneAtmosphereScatterWavelengthsChangeFunction);
elZoneAtmosphereHasStars.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('atmosphere','hasStars'));
elMoveSelectionToGrid.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
@ -1136,23 +1154,29 @@
<div class="zone-section property">
<div class="label">Atmosphere Mie Scattering</div>
<div class="value">
<input class="coord" type='number' id="property-zone-atmosphere-mie-scattering" min="0" max="0.5" step="0.001"></input>
<input class="coord no-spin" type='number' id="property-zone-atmosphere-mie-scattering" min="0" max="0.5" step="any"></input>
</div>
</div>
<div class="zone-section property">
<div class="label">Atmosphere Rayleigh Scattering</div>
<div class="value">
<input class="coord" type='number' id="property-zone-atmosphere-rayleigh-scattering" min="0" max="0.5" step="0.001"></input>
<input class="coord no-spin" type='number' id="property-zone-atmosphere-rayleigh-scattering" min="0" max="0.5" step="any"></input>
</div>
</div>
<div class="zone-section property">
<div class="label">Atmosphere Scattering Wavelenghts</div>
<div class="value">
<div class="input-area">X <br><input class="coord" type='number' id="property-zone-atmosphere-scattering-wavelengths-x" min="0" max="1" step="0.001"></input></div>
<div class="input-area">Y <br><input class="coord" type='number' id="property-zone-atmosphere-scattering-wavelengths-y" min="0" max="1" step="0.001"></input></div>
<div class="input-area">Z <br><input class="coord" type='number' id="property-zone-atmosphere-scattering-wavelengths-z" min="0" max="1" step="0.001"></input></div>
<div class="input-area">X <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-x" min="0" max="1" step="any"></input></div>
<div class="input-area">Y <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-y" min="0" max="1" step="any"></input></div>
<div class="input-area">Z <br><input class="coord no-spin" type='number' id="property-zone-atmosphere-scattering-wavelengths-z" min="0" max="1" step="any"></input></div>
</div>
</div>
<div class="zone-section property">
<span class="label">Atmosphere Has Stars</span>
<span class="value">
<input type='checkbox' id="property-zone-atmosphere-has-stars">
</span>
</div>
</div>

View file

@ -121,6 +121,14 @@ input.coord {
display: block;
}
input.no-spin::-webkit-outer-spin-button,
input.no-spin::-webkit-inner-spin-button {
display: none;
-webkit-appearance: none;
-moz-appearance: none;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
table#entity-table {
border-collapse: collapse;
font-family: Sans-Serif;

View file

@ -203,7 +203,7 @@ SelectionManager = (function() {
try {
listeners[i]();
} catch (e) {
print("EntitySelectionTool got exception: " = JSON.stringify(e));
print("EntitySelectionTool got exception: " + JSON.stringify(e));
}
}
};

View file

@ -812,8 +812,7 @@ void Application::initializeUi() {
if (devicePixelRatio != oldDevicePixelRatio) {
oldDevicePixelRatio = devicePixelRatio;
qDebug() << "Device pixel ratio changed, triggering GL resize";
resizeGL(_glWidget->width(),
_glWidget->height());
resizeGL();
}
});
}
@ -830,15 +829,7 @@ void Application::paintGL() {
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::paintGL()");
// Set the desired FBO texture size. If it hasn't changed, this does nothing.
// Otherwise, it must rebuild the FBOs
if (OculusManager::isConnected()) {
DependencyManager::get<TextureCache>()->setFrameBufferSize(OculusManager::getRenderTargetSize());
} else {
QSize fbSize = _glWidget->getDeviceSize() * getRenderResolutionScale();
DependencyManager::get<TextureCache>()->setFrameBufferSize(fbSize);
}
resizeGL();
glEnable(GL_LINE_SMOOTH);
@ -915,7 +906,14 @@ void Application::paintGL() {
renderRearViewMirror(_mirrorViewRect);
}
DependencyManager::get<GlowEffect>()->render();
auto finalFbo = DependencyManager::get<GlowEffect>()->render();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y,
0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
{
PerformanceTimer perfTimer("renderOverlay");
@ -960,33 +958,47 @@ void Application::showEditEntitiesHelp() {
InfoView::show(INFO_EDIT_ENTITIES_PATH);
}
void Application::resetCamerasOnResizeGL(Camera& camera, int width, int height) {
void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) {
if (OculusManager::isConnected()) {
OculusManager::configureCamera(camera, width, height);
OculusManager::configureCamera(camera, size.x, size.y);
} else if (TV3DManager::isConnected()) {
TV3DManager::configureCamera(camera, width, height);
TV3DManager::configureCamera(camera, size.x, size.y);
} else {
camera.setAspectRatio((float)width / height);
camera.setAspectRatio((float)size.x / size.y);
camera.setFieldOfView(_fieldOfView.get());
}
}
void Application::resizeGL(int width, int height) {
DependencyManager::get<TextureCache>()->setFrameBufferSize(QSize(width, height));
resetCamerasOnResizeGL(_myCamera, width, height);
void Application::resizeGL() {
// Set the desired FBO texture size. If it hasn't changed, this does nothing.
// Otherwise, it must rebuild the FBOs
QSize renderSize;
if (OculusManager::isConnected()) {
renderSize = OculusManager::getRenderTargetSize();
} else {
renderSize = _glWidget->getDeviceSize() * getRenderResolutionScale();
}
if (_renderResolution == toGlm(renderSize)) {
return;
}
glViewport(0, 0, width, height); // shouldn't this account for the menu???
_renderResolution = toGlm(renderSize);
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
resetCamerasOnResizeGL(_myCamera, _renderResolution);
glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
updateProjectionMatrix();
glLoadIdentity();
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->resize(_glWidget->size());
_glWidget->makeCurrent();
// update Stats width
// let's set horizontal offset to give stats some margin to mirror
int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
Stats::getInstance()->resetWidth(width, horizontalOffset);
Stats::getInstance()->resetWidth(_renderResolution.x, horizontalOffset);
}
void Application::updateProjectionMatrix() {
@ -1824,7 +1836,7 @@ void Application::setFullscreen(bool fullscreen) {
}
void Application::setEnable3DTVMode(bool enable3DTVMode) {
resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
resizeGL();
}
void Application::setEnableVRMode(bool enableVRMode) {
@ -1849,7 +1861,7 @@ void Application::setEnableVRMode(bool enableVRMode) {
_myCamera.setHmdRotation(glm::quat());
}
resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
resizeGL();
updateCursorVisibility();
}
@ -1934,6 +1946,7 @@ void Application::setActiveFaceTracker() {
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::UseCamera);
Menu::getInstance()->getActionForOption(MenuOption::UseAudioForMouth)->setVisible(isUsingDDE);
Menu::getInstance()->getActionForOption(MenuOption::VelocityFilter)->setVisible(isUsingDDE);
Menu::getInstance()->getActionForOption(MenuOption::CalibrateCamera)->setVisible(isUsingDDE);
auto ddeTracker = DependencyManager::get<DdeFaceTracker>();
ddeTracker->setIsMuted(isMuted);
ddeTracker->setEnabled(isUsingDDE && !isMuted);
@ -3228,12 +3241,12 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
_stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha);
}
// draw the sky dome
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
PerformanceTimer perfTimer("atmosphere");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... atmosphere...");
_environment.renderAtmospheres(theCamera);
// draw the sky dome
if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
PerformanceTimer perfTimer("atmosphere");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::displaySide() ... atmosphere...");
_environment.renderAtmospheres(theCamera);
}
}
@ -4637,7 +4650,3 @@ PickRay Application::computePickRay() const {
bool Application::hasFocus() const {
return _glWidget->hasFocus();
}
void Application::resizeGL() {
this->resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
}

View file

@ -163,7 +163,7 @@ public:
void initializeGL();
void initializeUi();
void paintGL();
void resizeGL(int width, int height);
void resizeGL();
void resizeEvent(QResizeEvent * size);
@ -194,7 +194,6 @@ public:
bool hasFocus() const;
PickRay computePickRay() const;
PickRay computeViewPickRay(float xRatio, float yRatio) const;
void resizeGL();
bool isThrottleRendering() const;
@ -463,7 +462,7 @@ private slots:
void setCursorVisible(bool visible);
private:
void resetCamerasOnResizeGL(Camera& camera, int width, int height);
void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size);
void updateProjectionMatrix();
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
@ -662,6 +661,7 @@ private:
QHash<QString, AcceptURLMethod> _acceptedExtensions;
QList<QString> _domainConnectionRefusals;
glm::uvec2 _renderResolution;
};
#endif // hifi_Application_h

View file

@ -64,7 +64,7 @@ void GLCanvas::paintGL() {
}
void GLCanvas::resizeGL(int width, int height) {
Application::getInstance()->resizeGL(width, height);
Application::getInstance()->resizeGL();
}
void GLCanvas::activeChanged(Qt::ApplicationState state) {

View file

@ -392,6 +392,9 @@ Menu::Menu() {
useAudioForMouth->setVisible(false);
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::VelocityFilter, 0, true);
ddeFiltering->setVisible(false);
QAction* ddeCalibrate = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::CalibrateCamera, 0,
DependencyManager::get<DdeFaceTracker>().data(), SLOT(calibrate()));
ddeCalibrate->setVisible(false);
#endif
#if defined(HAVE_FACESHIFT) || defined(HAVE_DDE)
faceTrackingMenu->addSeparator();

View file

@ -154,6 +154,7 @@ namespace MenuOption {
const QString Bookmarks = "Bookmarks";
const QString CascadedShadows = "Cascaded";
const QString CachesSize = "RAM Caches Size";
const QString CalibrateCamera = "Calibrate Camera";
const QString Chat = "Chat...";
const QString Collisions = "Collisions";
const QString Console = "Console...";
@ -181,7 +182,7 @@ namespace MenuOption {
const QString EditEntitiesHelp = "Edit Entities Help...";
const QString Enable3DTVMode = "Enable 3DTV Mode";
const QString EnableCharacterController = "Enable avatar collisions";
const QString EnableGlowEffect = "Enable Glow Effect (Warning: Poor Oculus Performance)";
const QString EnableGlowEffect = "Enable Glow Effect";
const QString EnableVRMode = "Enable VR Mode";
const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
const QString ExpandMyAvatarTiming = "Expand /myAvatar";

View file

@ -20,6 +20,7 @@
#include <GLMHelpers.h>
#include <NumericalConstants.h>
#include "Application.h"
#include "DdeFaceTracker.h"
#include "FaceshiftConstants.h"
#include "InterfaceLogging.h"
@ -86,16 +87,16 @@ static const float DDE_COEFFICIENT_SCALES[] = {
3.0f, // BrowsU_L
3.0f, // BrowsU_R
1.0f, // JawFwd
1.5f, // JawLeft
2.0f, // JawLeft
1.8f, // JawOpen
1.0f, // JawChew
1.5f, // JawRight
2.0f, // JawRight
1.5f, // MouthLeft
1.5f, // MouthRight
1.5f, // MouthFrown_L
1.5f, // MouthFrown_R
1.5f, // MouthSmile_L
1.5f, // MouthSmile_R
2.5f, // MouthSmile_L
2.5f, // MouthSmile_R
1.0f, // MouthDimple_L
1.0f, // MouthDimple_R
1.0f, // LipsStretch_L
@ -106,8 +107,8 @@ static const float DDE_COEFFICIENT_SCALES[] = {
1.0f, // LipsLowerDown
1.0f, // LipsUpperOpen
1.0f, // LipsLowerOpen
2.5f, // LipsFunnel
2.0f, // LipsPucker
1.5f, // LipsFunnel
2.5f, // LipsPucker
1.5f, // ChinLowerRaise
1.5f, // ChinUpperRaise
1.0f, // Sneer
@ -135,7 +136,9 @@ struct Packet {
char name[MAX_NAME_SIZE + 1];
};
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
static const float STARTING_DDE_MESSAGE_TIME = 0.033f;
static const int CALIBRATION_SAMPLES = 150;
#ifdef WIN32
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_lastEyeBlinks' will be default initialized
@ -178,11 +181,18 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
_filteredBrowUp(0.0f),
_lastEyeBlinks(),
_filteredEyeBlinks(),
_lastEyeCoefficients()
_lastEyeCoefficients(),
_isCalibrating(false),
_calibrationValues(),
_calibrationCount(0),
_calibrationBillboard(NULL),
_calibrationBillboardID(0),
_calibrationMessage(QString())
{
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
_coefficientAverages.resize(NUM_FACESHIFT_BLENDSHAPES);
_calibrationValues.resize(NUM_FACESHIFT_BLENDSHAPES);
_eyeStates[0] = EYE_OPEN;
_eyeStates[1] = EYE_OPEN;
@ -195,6 +205,10 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
DdeFaceTracker::~DdeFaceTracker() {
setEnabled(false);
if (_isCalibrating) {
cancelCalibration();
}
}
#ifdef WIN32
@ -212,6 +226,12 @@ void DdeFaceTracker::setEnabled(bool enabled) {
return;
}
#ifdef HAVE_DDE
if (_isCalibrating) {
cancelCalibration();
}
// isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket.
_udpSocket.close();
if (enabled) {
@ -382,10 +402,18 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
_coefficients[DDE_TO_FACESHIFT_MAPPING[i]] = packet.expressions[i];
}
// Calibration
if (_isCalibrating) {
addCalibrationDatum();
}
for (int i = 0; i < NUM_FACESHIFT_BLENDSHAPES; i++) {
_coefficients[i] -= _coefficientAverages[i];
}
// Use BrowsU_C to control both brows' up and down
float browUp = _coefficients[_browUpCenterIndex];
if (isFiltering) {
const float BROW_VELOCITY_FILTER_STRENGTH = 0.75f;
const float BROW_VELOCITY_FILTER_STRENGTH = 0.5f;
float velocity = fabs(browUp - _lastBrowUp) / _averageMessageTime;
float velocityFilter = glm::clamp(velocity * BROW_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
_filteredBrowUp = velocityFilter * browUp + (1.0f - velocityFilter) * _filteredBrowUp;
@ -399,11 +427,11 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
_coefficients[_browDownRightIndex] = -browUp;
// Offset jaw open coefficient
static const float JAW_OPEN_THRESHOLD = 0.16f;
static const float JAW_OPEN_THRESHOLD = 0.1f;
_coefficients[_jawOpenIndex] = _coefficients[_jawOpenIndex] - JAW_OPEN_THRESHOLD;
// Offset smile coefficients
static const float SMILE_THRESHOLD = 0.18f;
static const float SMILE_THRESHOLD = 0.5f;
_coefficients[_mouthSmileLeftIndex] = _coefficients[_mouthSmileLeftIndex] - SMILE_THRESHOLD;
_coefficients[_mouthSmileRightIndex] = _coefficients[_mouthSmileRightIndex] - SMILE_THRESHOLD;
@ -430,7 +458,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
// Change to closing or opening states
const float EYE_CONTROL_HYSTERISIS = 0.25f;
const float EYE_CLOSING_THRESHOLD = 0.95f;
const float EYE_CLOSING_THRESHOLD = 0.8f;
const float EYE_OPENING_THRESHOLD = EYE_CONTROL_THRESHOLD - EYE_CONTROL_HYSTERISIS;
if ((_eyeStates[i] == EYE_OPEN || _eyeStates[i] == EYE_OPENING) && eyeCoefficients[i] > EYE_CLOSING_THRESHOLD) {
_eyeStates[i] = EYE_CLOSING;
@ -510,4 +538,81 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
} else {
qCWarning(interfaceapp) << "DDE Face Tracker: Decode error";
}
if (_isCalibrating && _calibrationCount > CALIBRATION_SAMPLES) {
finishCalibration();
}
}
static const int CALIBRATION_BILLBOARD_WIDTH = 240;
static const int CALIBRATION_BILLBOARD_HEIGHT = 180;
static const int CALIBRATION_BILLBOARD_TOP_MARGIN = 60;
static const int CALIBRATION_BILLBOARD_LEFT_MARGIN = 30;
static const int CALIBRATION_BILLBOARD_FONT_SIZE = 16;
static const float CALIBRATION_BILLBOARD_ALPHA = 0.5f;
static QString CALIBRATION_INSTRUCTION_MESSAGE = "Hold still to calibrate";
void DdeFaceTracker::calibrate() {
if (!_isCalibrating) {
qCDebug(interfaceapp) << "DDE Face Tracker: Calibration started";
_isCalibrating = true;
_calibrationCount = 0;
_calibrationMessage = CALIBRATION_INSTRUCTION_MESSAGE + "\n\n";
_calibrationBillboard = new TextOverlay();
_calibrationBillboard->setTopMargin(CALIBRATION_BILLBOARD_TOP_MARGIN);
_calibrationBillboard->setLeftMargin(CALIBRATION_BILLBOARD_LEFT_MARGIN);
_calibrationBillboard->setFontSize(CALIBRATION_BILLBOARD_FONT_SIZE);
_calibrationBillboard->setText(CALIBRATION_INSTRUCTION_MESSAGE);
_calibrationBillboard->setAlpha(CALIBRATION_BILLBOARD_ALPHA);
glm::vec2 viewport = qApp->getCanvasSize();
_calibrationBillboard->setX((viewport.x - CALIBRATION_BILLBOARD_WIDTH) / 2);
_calibrationBillboard->setY((viewport.y - CALIBRATION_BILLBOARD_HEIGHT) / 2);
_calibrationBillboard->setWidth(CALIBRATION_BILLBOARD_WIDTH);
_calibrationBillboard->setHeight(CALIBRATION_BILLBOARD_HEIGHT);
_calibrationBillboardID = qApp->getOverlays().addOverlay(_calibrationBillboard);
for (int i = 0; i < NUM_FACESHIFT_BLENDSHAPES; i++) {
_calibrationValues[i] = 0.0f;
}
}
}
void DdeFaceTracker::addCalibrationDatum() {
const int LARGE_TICK_INTERVAL = 30;
const int SMALL_TICK_INTERVAL = 6;
int samplesLeft = CALIBRATION_SAMPLES - _calibrationCount;
if (samplesLeft % LARGE_TICK_INTERVAL == 0) {
_calibrationMessage += QString::number(samplesLeft / LARGE_TICK_INTERVAL);
_calibrationBillboard->setText(_calibrationMessage);
} else if (samplesLeft % SMALL_TICK_INTERVAL == 0) {
_calibrationMessage += ".";
_calibrationBillboard->setText(_calibrationMessage);
}
for (int i = 0; i < NUM_FACESHIFT_BLENDSHAPES; i++) {
_calibrationValues[i] += _coefficients[i];
}
_calibrationCount += 1;
}
void DdeFaceTracker::cancelCalibration() {
qApp->getOverlays().deleteOverlay(_calibrationBillboardID);
_calibrationBillboard = NULL;
_isCalibrating = false;
qCDebug(interfaceapp) << "DDE Face Tracker: Calibration cancelled";
}
void DdeFaceTracker::finishCalibration() {
qApp->getOverlays().deleteOverlay(_calibrationBillboardID);
_calibrationBillboard = NULL;
_isCalibrating = false;
for (int i = 0; i < NUM_FACESHIFT_BLENDSHAPES; i++) {
_coefficientAverages[i] = _calibrationValues[i] / (float)CALIBRATION_SAMPLES;
}
qCDebug(interfaceapp) << "DDE Face Tracker: Calibration finished";
}

View file

@ -20,6 +20,7 @@
#include <QUdpSocket>
#include <DependencyManager.h>
#include <ui/overlays/TextOverlay.h>
#include "FaceTracker.h"
@ -51,6 +52,7 @@ public:
public slots:
void setEnabled(bool enabled);
void calibrate();
private slots:
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
@ -121,6 +123,17 @@ private:
float _lastEyeBlinks[2];
float _filteredEyeBlinks[2];
float _lastEyeCoefficients[2];
QVector<float> _coefficientAverages;
bool _isCalibrating;
int _calibrationCount;
QVector<float> _calibrationValues;
TextOverlay* _calibrationBillboard;
int _calibrationBillboardID;
QString _calibrationMessage;
void addCalibrationDatum();
void cancelCalibration();
void finishCalibration();
};
#endif // hifi_DdeFaceTracker_h

View file

@ -627,7 +627,7 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) {
//Full texture viewport for glow effect
glViewport(0, 0, _renderTargetSize.w, _renderTargetSize.h);
finalFbo = DependencyManager::get<GlowEffect>()->render(true);
finalFbo = DependencyManager::get<GlowEffect>()->render();
} else {
finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, 0);

View file

@ -14,7 +14,7 @@
#include <glm/glm.hpp>
#include <GlowEffect.h>
#include "gpu/GLBackend.h"
#include "Application.h"
#include "TV3DManager.h"
@ -163,10 +163,18 @@ void TV3DManager::display(Camera& whichCamera) {
glPopMatrix();
glDisable(GL_SCISSOR_TEST);
auto finalFbo = DependencyManager::get<GlowEffect>()->render();
auto fboSize = finalFbo->getSize();
// Get the ACTUAL device size for the BLIT
deviceSize = qApp->getDeviceSize();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
glBlitFramebuffer(0, 0, fboSize.x, fboSize.y,
0, 0, deviceSize.width(), deviceSize.height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
// reset the viewport to how we started
glViewport(0, 0, deviceSize.width(), deviceSize.height());
DependencyManager::get<GlowEffect>()->render();
}
void TV3DManager::overrideOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,

View file

@ -190,8 +190,8 @@ void ApplicationOverlay::renderOverlay() {
Overlays& overlays = qApp->getOverlays();
_textureFov = glm::radians(_hmdUIAngularSize);
glm::vec2 deviceSize = qApp->getCanvasSize();
_textureAspectRatio = (float)deviceSize.x / (float)deviceSize.y;
glm::vec2 size = qApp->getCanvasSize();
_textureAspectRatio = aspect(size);
//Handle fading and deactivation/activation of UI
@ -204,12 +204,13 @@ void ApplicationOverlay::renderOverlay() {
_overlays.buildFramebufferObject();
_overlays.bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, size.x, size.y);
glPushMatrix(); {
const float NEAR_CLIP = -10000;
const float FAR_CLIP = 10000;
glLoadIdentity();
glOrtho(0, deviceSize.x, deviceSize.y, 0, NEAR_CLIP, FAR_CLIP);
glOrtho(0, size.x, size.y, 0, NEAR_CLIP, FAR_CLIP);
glMatrixMode(GL_MODELVIEW);
@ -269,6 +270,7 @@ void ApplicationOverlay::displayOverlayTexture() {
if (_alpha < 1.0) {
glEnable(GL_BLEND);
}
glViewport(0, 0, qApp->getDeviceSize().width(), qApp->getDeviceSize().height());
static const glm::vec2 topLeft(-1, 1);
static const glm::vec2 bottomRight(1, -1);
@ -1129,8 +1131,9 @@ void ApplicationOverlay::TexturedHemisphere::cleanupVBO() {
}
void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
auto deviceSize = qApp->getDeviceSize();
if (_framebufferObject != NULL && deviceSize == _framebufferObject->size()) {
auto canvasSize = qApp->getCanvasSize();
QSize fboSize = QSize(canvasSize.x, canvasSize.y);
if (_framebufferObject != NULL && fboSize == _framebufferObject->size()) {
// Already build
return;
}
@ -1139,7 +1142,7 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
delete _framebufferObject;
}
_framebufferObject = new QOpenGLFramebufferObject(deviceSize, QOpenGLFramebufferObject::Depth);
_framebufferObject = new QOpenGLFramebufferObject(fboSize, QOpenGLFramebufferObject::Depth);
glBindTexture(GL_TEXTURE_2D, getTexture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View file

@ -450,8 +450,8 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
} else {
_viewState->endOverrideEnvironmentData();
auto stage = scene->getSkyStage();
if (_bestZone->getBackgroundMode() == BACKGROUND_MODE_SKYBOX) {
auto stage = scene->getSkyStage();
stage->getSkybox()->setColor(_bestZone->getSkyboxProperties().getColorVec3());
if (_bestZone->getSkyboxProperties().getURL().isEmpty()) {
stage->getSkybox()->clearCubemap();
@ -461,6 +461,8 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
stage->getSkybox()->setCubemap(cubeMap->getGPUTexture());
}
stage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
} else {
stage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through
}
}
@ -478,7 +480,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
_hasPreviousZone = false;
}
_viewState->endOverrideEnvironmentData();
scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME);
scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application atmosphere through
}
// we must call endScene while we still have the tree locked so that no one deletes a model

View file

@ -16,12 +16,19 @@
#include "EntityItemPropertiesMacros.h"
AtmospherePropertyGroup::AtmospherePropertyGroup() {
_center = glm::vec3(0.0f);
_innerRadius = 0.0f;
_outerRadius = 0.0f;
_mieScattering = 0.0f;
_rayleighScattering = 0.0f;
_scatteringWavelengths = glm::vec3(0.0f);
const glm::vec3 DEFAULT_CENTER = glm::vec3(0.0f, -1000.0f, 0.0f);
const float DEFAULT_INNER_RADIUS = 1000.0f;
const float DEFAULT_OUTER_RADIUS = 1025.0f;
const float DEFAULT_RAYLEIGH_SCATTERING = 0.0025f;
const float DEFAULT_MIE_SCATTERING = 0.0010f;
const glm::vec3 DEFAULT_SCATTERING_WAVELENGTHS = glm::vec3(0.650f, 0.570f, 0.475f);
_center = DEFAULT_CENTER;
_innerRadius = DEFAULT_INNER_RADIUS;
_outerRadius = DEFAULT_OUTER_RADIUS;
_mieScattering = DEFAULT_MIE_SCATTERING;
_rayleighScattering = DEFAULT_RAYLEIGH_SCATTERING;
_scatteringWavelengths = DEFAULT_SCATTERING_WAVELENGTHS;
_hasStars = true;
}

View file

@ -151,10 +151,10 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
_movingStepsWithoutSimulationOwner = 0;
}
int ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
uint32_t ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
if (_movingStepsWithoutSimulationOwner > ownershipClaimDelay) {
qDebug() << "Warning -- claiming something I saw moving." << getName();
//qDebug() << "Warning -- claiming something I saw moving." << getName();
setShouldClaimSimulationOwnership(true);
}
@ -178,7 +178,7 @@ void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) {
const int MAX_NUM_NON_MOVING_UPDATES = 5;
bool EntityMotionState::doesNotNeedToSendUpdate() const {
return !_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES;
return !_body || (_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES);
}
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
@ -232,6 +232,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
_serverPosition += dt * _serverVelocity;
}
// TODO: compensate for simulation offset here
btTransform worldTrans = _body->getWorldTransform();
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
@ -310,86 +311,60 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
return; // never update entities that are unknown
}
bool active = _body->isActive();
if (!active) {
if (_sentMoving) {
// make sure all derivatives are zero
glm::vec3 zero(0.0f);
_entity->setVelocity(zero);
_entity->setAngularVelocity(zero);
_entity->setAcceleration(zero);
}
} else {
float gravityLength = glm::length(_entity->getGravity());
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
// acceleration measured during the most recent simulation step was close to gravity.
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
// only increment this if we haven't reached the threshold yet. this is to avoid
// overflowing the counter.
incrementAccelerationNearlyGravityCount();
}
} else {
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
resetAccelerationNearlyGravityCount();
}
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
// the entity server's estimates include gravity.
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
_entity->setAcceleration(_entity->getGravity());
} else {
_entity->setAcceleration(glm::vec3(0.0f));
}
}
// remember properties for local server prediction
_serverPosition = _entity->getPosition();
_serverRotation = _entity->getRotation();
_serverVelocity = _entity->getVelocity();
_serverAcceleration = _entity->getAcceleration();
_serverAngularVelocity = _entity->getAngularVelocity();
_sentMoving = _serverVelocity != glm::vec3(0.0f) || _serverAngularVelocity != glm::vec3(0.0f);
EntityItemProperties properties = _entity->getProperties();
float gravityLength = glm::length(_entity->getGravity());
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
// acceleration measured during the most recent simulation step was close to gravity.
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
// only increment this if we haven't reached the threshold yet. this is to avoid
// overflowing the counter.
incrementAccelerationNearlyGravityCount();
}
} else {
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
resetAccelerationNearlyGravityCount();
}
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
// the entity server's estimates include gravity.
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
_entity->setAcceleration(_entity->getGravity());
} else {
_entity->setAcceleration(glm::vec3(0.0f));
}
btTransform worldTrans = _body->getWorldTransform();
_serverPosition = bulletToGLM(worldTrans.getOrigin());
properties.setPosition(_serverPosition + ObjectMotionState::getWorldOffset());
_serverRotation = bulletToGLM(worldTrans.getRotation());
// explicitly set the properties that changed
properties.setPosition(_serverPosition);
properties.setRotation(_serverRotation);
bool zeroSpeed = true;
bool zeroSpin = true;
if (_body->isActive()) {
_serverVelocity = bulletToGLM(_body->getLinearVelocity());
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
// if the speeds are very small we zero them out
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 1.0e-4f; // 1cm/sec
zeroSpeed = (glm::length2(_serverVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
if (zeroSpeed) {
_serverVelocity = glm::vec3(0.0f);
}
const float MINIMUM_EXTRAPOLATION_SPIN_SQUARED = 0.004f; // ~0.01 rotation/sec
zeroSpin = glm::length2(_serverAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
if (zeroSpin) {
_serverAngularVelocity = glm::vec3(0.0f);
}
_sentMoving = ! (zeroSpeed && zeroSpin);
} else {
_serverVelocity = _serverAngularVelocity = glm::vec3(0.0f);
_sentMoving = false;
}
properties.setVelocity(_serverVelocity);
_serverGravity = _entity->getGravity();
properties.setGravity(_entity->getGravity());
_serverAcceleration = _entity->getAcceleration();
properties.setAcceleration(_serverAcceleration);
properties.setAngularVelocity(_serverAngularVelocity);
auto nodeList = DependencyManager::get<NodeList>();
QUuid myNodeID = nodeList->getSessionUUID();
QUuid simulatorID = _entity->getSimulatorID();
if (getShouldClaimSimulationOwnership()) {
properties.setSimulatorID(myNodeID);
setShouldClaimSimulationOwnership(false);
} else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) {
// we are the simulator and the entity has stopped. give up "simulator" status
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
} else if (simulatorID == myNodeID && !_body->isActive()) {
// it's not active. don't keep simulation ownership.
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
}
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
// RELIABLE_SEND_HACK: count number of updates for entities at rest
// so we can stop sending them after some limit.
if (_sentMoving) {
_numNonMovingUpdates = 0;
} else {
@ -397,8 +372,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
}
if (_numNonMovingUpdates <= 1) {
// we only update lastEdited when we're sending new physics data
// (i.e. NOT when we just simulate the positions forward, nor when we resend non-moving data)
// NOTE: Andrew & Brad to discuss. Let's make sure we're using lastEdited, lastSimulated, and lastUpdated correctly
quint64 lastSimulated = _entity->getLastSimulated();
_entity->setLastEdited(lastSimulated);
properties.setLastEdited(lastSimulated);
@ -415,6 +388,25 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
properties.setLastEdited(_entity->getLastEdited());
}
auto nodeList = DependencyManager::get<NodeList>();
QUuid myNodeID = nodeList->getSessionUUID();
QUuid simulatorID = _entity->getSimulatorID();
if (getShouldClaimSimulationOwnership()) {
// we think we should own it, so we tell the server that we do,
// but we don't remember that we own it...
// instead we expect the sever to tell us later whose ownership it has accepted
properties.setSimulatorID(myNodeID);
setShouldClaimSimulationOwnership(false);
} else if (simulatorID == myNodeID
&& !_sentMoving
&& _numNonMovingUpdates == MAX_NUM_NON_MOVING_UPDATES) {
// we own it, the entity has stopped, and we're sending the last non-moving update
// --> give up ownership
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
}
if (EntityItem::getSendPhysicsUpdates()) {
EntityItemID id(_entity->getID());
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);

View file

@ -167,7 +167,12 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToAdd() {
_tempVector.push_back(motionState);
entityItr = _pendingAdds.erase(entityItr);
} else {
<<<<<<< HEAD
// qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName();
=======
// TODO: Seth to look into why this case is hit.
//qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName();
>>>>>>> 72e1ea688adad9914d9994b81a96225ac411ba83
++entityItr;
}
} else {

View file

@ -147,6 +147,7 @@ void PhysicsEngine::deleteObjects(VectorOfMotionStates& objects) {
// NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it.
btRigidBody* body = object->getRigidBody();
object->setRigidBody(nullptr);
body->setMotionState(nullptr);
delete body;
object->releaseShape();
delete object;
@ -161,6 +162,7 @@ void PhysicsEngine::deleteObjects(SetOfMotionStates& objects) {
// NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it.
object->setRigidBody(nullptr);
body->setMotionState(nullptr);
delete body;
object->releaseShape();
delete object;

View file

@ -95,4 +95,7 @@ void FboCache::setSize(const QSize& newSize) {
});
}
const QSize& FboCache::getSize() {
return _size;
}

View file

@ -37,6 +37,8 @@ public:
// internal locks and pointers but execute no OpenGL opreations.
void lockTexture(int texture);
void releaseTexture(int texture);
const QSize& getSize();
protected:
QMap<int, QSharedPointer<QOpenGLFramebufferObject>> _fboMap;

View file

@ -129,7 +129,7 @@ static void maybeRelease(const gpu::FramebufferPointer& fbo) {
}
}
gpu::FramebufferPointer GlowEffect::render(bool toTexture) {
gpu::FramebufferPointer GlowEffect::render() {
PerformanceTimer perfTimer("glowEffect");
auto textureCache = DependencyManager::get<TextureCache>();
@ -151,26 +151,24 @@ gpu::FramebufferPointer GlowEffect::render(bool toTexture) {
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
gpu::FramebufferPointer destFBO = toTexture ?
textureCache->getSecondaryFramebuffer() : nullptr;
gpu::FramebufferPointer destFBO = textureCache->getSecondaryFramebuffer();
if (!_enabled || _isEmpty) {
// copy the primary to the screen
if (destFBO && QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO);
if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(), 0, 0, framebufferSize.width(), framebufferSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO);
glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(),
0, 0, framebufferSize.width(), framebufferSize.height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
} else {
maybeBind(destFBO);
if (!destFBO) {
//destFBO->getSize();
glViewport(0, 0, framebufferSize.width(), framebufferSize.height());
}
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
glViewport(0, 0, framebufferSize.width(), framebufferSize.height());
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
renderFullscreenQuad();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
maybeRelease(destFBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
} else {
// diffuse into the secondary/tertiary (alternating between frames)
@ -199,22 +197,18 @@ gpu::FramebufferPointer GlowEffect::render(bool toTexture) {
_diffuseProgram->release();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
destFBO = oldDiffusedFBO;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// add diffused texture to the primary
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(newDiffusedFBO->getRenderBuffer(0)));
if (toTexture) {
destFBO = oldDiffusedFBO;
}
maybeBind(destFBO);
if (!destFBO) {
glViewport(0, 0, framebufferSize.width(), framebufferSize.height());
}
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO));
glViewport(0, 0, framebufferSize.width(), framebufferSize.height());
_addSeparateProgram->bind();
renderFullscreenQuad();
_addSeparateProgram->release();
maybeRelease(destFBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);

View file

@ -52,7 +52,7 @@ public:
/// Renders the glow effect. To be called after rendering the scene.
/// \param toTexture whether to render to a texture, rather than to the frame buffer
/// \return the framebuffer object to which we rendered, or NULL if to the frame buffer
gpu::FramebufferPointer render(bool toTexture = false);
gpu::FramebufferPointer render();
public slots:
void toggleGlowEffect(bool enabled);

View file

@ -117,6 +117,11 @@ QMatrix4x4 fromGlm(const glm::mat4 & m);
QRectF glmToRect(const glm::vec2 & pos, const glm::vec2 & size);
template <typename T>
float aspect(const T& t) {
return (float)t.x / (float)t.y;
}
#define YAW(euler) euler.y
#define PITCH(euler) euler.x
#define ROLL(euler) euler.z

View file

@ -117,8 +117,13 @@ void OffscreenUi::addImportPath(const QString& path) {
void OffscreenUi::resize(const QSize& newSize) {
makeCurrent();
// Clear out any fbos with the old size
qreal pixelRatio = _renderControl->_renderWindow ? _renderControl->_renderWindow->devicePixelRatio() : 1.0;
QSize newOffscreenSize = newSize * pixelRatio;
if (newOffscreenSize == _fboCache.getSize()) {
return;
}
// Clear out any fbos with the old size
qDebug() << "Offscreen UI resizing to " << newSize.width() << "x" << newSize.height() << " with pixel ratio " << pixelRatio;
_fboCache.setSize(newSize * pixelRatio);