From a3707a09ae7b5cc799962d1909af133a7c0c8917 Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 22 Oct 2014 09:42:55 +0200 Subject: [PATCH 01/11] fix mirror ratio on retina --- interface/src/Application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 145222cd3c..306ca2f4b9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3083,7 +3083,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // if not rendering the billboard, the region is in device independent coordinates; must convert to device QSize size = getTextureCache()->getFrameBufferSize(); float ratio = QApplication::desktop()->windowHandle()->devicePixelRatio(); - ratio = size.height() / (float)_glWidget->getDeviceHeight(); int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; glViewport(x, size.height() - y - height, width, height); glScissor(x, size.height() - y - height, width, height); From ac269e16c02fa81c39f2ec7f0be5d3602f44f175 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 23 Oct 2014 13:19:34 -0700 Subject: [PATCH 02/11] start working on the target framerate control --- interface/src/Application.cpp | 33 +++++++++++++++++++++++++++++++-- interface/src/Application.h | 2 ++ interface/src/GLCanvas.cpp | 2 +- interface/src/Menu.cpp | 10 ++++++++++ interface/src/Menu.h | 2 ++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 145222cd3c..8b3b448eb5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -94,6 +94,10 @@ #include "devices/Leapmotion.h" +#ifdef WIN32 +#include +#endif + using namespace std; // Starfield information @@ -177,8 +181,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _trayIcon(new QSystemTrayIcon(_window)), _lastNackTime(usecTimestampNow()), _lastSendDownstreamAudioStats(usecTimestampNow()), + _renderTargetFramerate(60), _renderResolutionScale(1.0f) { + + + /* QGLFormat trueFormat = _glWidget->format(); + trueFormat.setSwapInterval(0); + _glWidget->setFormat(trueFormat);*/ + int swapInterval = _glWidget->format().swapInterval(); + swapInterval++; + // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -518,9 +531,16 @@ void Application::initializeGL() { qDebug("Error: %s\n", glewGetErrorString(err)); } qDebug("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); + + if (wglewGetExtension("WGL_EXT_swap_control")) { + wglSwapIntervalEXT(0); + int swapInterval = wglGetSwapIntervalEXT(); + swapInterval++; + } #endif + // Before we render anything, let's set up our viewFrustumOffsetCamera with a sufficiently large // field of view and near and far clip to make it interesting. //viewFrustumOffsetCamera.setFieldOfView(90.0); @@ -1391,9 +1411,14 @@ void Application::idle() { PerformanceWarning warn(showWarnings, "idle()"); // Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time we ran - + double targetFramePeriod = 0.0; + if (_renderTargetFramerate > 0) { + targetFramePeriod = 1000.0 / _renderTargetFramerate; + } else if (_renderTargetFramerate < 0) { + targetFramePeriod = IDLE_SIMULATE_MSECS; + } double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0; - if (timeSinceLastUpdate > IDLE_SIMULATE_MSECS) { + if (timeSinceLastUpdate > targetFramePeriod) { _lastTimeUpdated.start(); { PerformanceTimer perfTimer("update"); @@ -4138,6 +4163,10 @@ void Application::takeSnapshot() { _snapshotShareDialog->show(); } +void Application::setRenderTargetFramerate(int framerate) { + _renderTargetFramerate = framerate; +} + void Application::setRenderResolutionScale(float scale) { _renderResolutionScale = scale; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 64c7032403..aeda706c42 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -358,6 +358,7 @@ public slots: void domainSettingsReceived(const QJsonObject& domainSettingsObject); + void setRenderTargetFramerate(int framerate); void setRenderResolutionScale(float scale); void resetSensors(); @@ -609,6 +610,7 @@ private: quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; + int _renderTargetFramerate; float _renderResolutionScale; }; diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 108b9ba829..cec3f62b7d 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -20,7 +20,7 @@ const int MSECS_PER_FRAME_WHEN_THROTTLED = 66; -GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::NoDepthBuffer)), +GLCanvas::GLCanvas() : QGLWidget(QGL::NoDepthBuffer | QGL::NoStencilBuffer), _throttleRendering(false), _idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED) { diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3a213cb64f..2abfc7c94e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -372,6 +372,8 @@ Menu::Menu() : shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false)); shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false)); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderUnleashFramerate, 0, false, this, SLOT(toggleUnleashFramerate())); + QMenu* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution); QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu); resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionOne, 0, false)); @@ -1230,6 +1232,14 @@ void Menu::muteEnvironment() { free(packet); } +void Menu::toggleUnleashFramerate() { + if (isOptionChecked(MenuOption::RenderUnleashFramerate)) { + Application::getInstance()->setRenderTargetFramerate(0); + } else { + Application::getInstance()->setRenderTargetFramerate(-1); + } +} + void Menu::changeRenderResolution(QAction* action) { QString text = action->text(); if (text == MenuOption::RenderResolutionOne) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index a1936050ff..6977d61d6e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -227,6 +227,7 @@ private slots: void displayAddressOfflineMessage(); void displayAddressNotFoundMessage(); void muteEnvironment(); + void toggleUnleashFramerate(); void changeRenderResolution(QAction* action); private: @@ -446,6 +447,7 @@ namespace MenuOption { const QString RenderHeadCollisionShapes = "Show Head Collision Shapes"; const QString RenderLookAtVectors = "Show Look-at Vectors"; const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes"; + const QString RenderUnleashFramerate = "Unleash Framerate"; const QString RenderResolution = "Scale Resolution"; const QString RenderResolutionOne = "1"; const QString RenderResolutionTwoThird = "2/3"; From 9289249df5cda81a0d89dc5c0776920b28d02da1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Oct 2014 15:06:18 -0700 Subject: [PATCH 03/11] add a guard in case SDL somehow forgets about axes --- interface/src/devices/Joystick.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 25b8bc142d..a01b84e098 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -45,10 +45,12 @@ void Joystick::closeJoystick() { #ifdef HAVE_SDL2 void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { - float oldValue = _axes[event.axis]; - float newValue = event.value / MAX_AXIS; - _axes[event.axis] = newValue; - emit axisValueChanged(event.axis, newValue, oldValue); + if (event.axis < _axes.size() - 1) { + float oldValue = _axes[event.axis]; + float newValue = event.value / MAX_AXIS; + _axes[event.axis] = newValue; + emit axisValueChanged(event.axis, newValue, oldValue); + } } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { From c57fc314f08b0725c891bdd144edcd9836b658a2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Oct 2014 15:13:54 -0700 Subject: [PATCH 04/11] just resize axis vector is sdl decides to lie about the number of axes --- interface/src/devices/Joystick.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index a01b84e098..8b225437c2 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -45,12 +45,15 @@ void Joystick::closeJoystick() { #ifdef HAVE_SDL2 void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { - if (event.axis < _axes.size() - 1) { - float oldValue = _axes[event.axis]; - float newValue = event.value / MAX_AXIS; - _axes[event.axis] = newValue; - emit axisValueChanged(event.axis, newValue, oldValue); + if (_axes.size() <= event.axis) { + _axes.resize(event.axis + 1); } + + float oldValue = _axes[event.axis]; + float newValue = event.value / MAX_AXIS; + _axes[event.axis] = newValue; + + emit axisValueChanged(event.axis, newValue, oldValue); } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { From d5d0fbd9d8ecb58101fe960f875fd9d24d4af544 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 Oct 2014 16:08:01 -0700 Subject: [PATCH 05/11] Hair gravity always the same --- interface/src/Hair.cpp | 6 +++--- interface/src/Hair.h | 4 ++-- interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/MyAvatar.cpp | 1 - 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/interface/src/Hair.cpp b/interface/src/Hair.cpp index 6ca0d4a899..acc00c14b0 100644 --- a/interface/src/Hair.cpp +++ b/interface/src/Hair.cpp @@ -38,7 +38,7 @@ Hair::Hair(int strands, _acceleration(0.0f), _angularVelocity(0.0f), _angularAcceleration(0.0f), - _gravity(0.0f), + _gravity(DEFAULT_GRAVITY), _loudness(0.0f) { _hairPosition = new glm::vec3[_strands * _links]; @@ -53,7 +53,7 @@ Hair::Hair(int strands, for (int strand = 0; strand < _strands; strand++) { float strandAngle = randFloat() * PI; float azimuth; - float elevation = PI_OVER_TWO - (randFloat() * 0.10f * PI); + float elevation = - (randFloat() * PI); azimuth = PI_OVER_TWO; if (randFloat() < 0.5f) { azimuth *= -1.0f; @@ -127,7 +127,7 @@ void Hair::simulate(float deltaTime) { _hairPosition[vertexIndex] += randVector() * (QUIESCENT_LOUDNESS + loudnessFactor) * ((float)link / (float)_links); // Add gravity - const float SCALE_GRAVITY = 0.13f; + const float SCALE_GRAVITY = 0.001f; _hairPosition[vertexIndex] += _gravity * deltaTime * SCALE_GRAVITY; // Add linear acceleration diff --git a/interface/src/Hair.h b/interface/src/Hair.h index f799140c53..94378dfd6a 100644 --- a/interface/src/Hair.h +++ b/interface/src/Hair.h @@ -25,9 +25,10 @@ const int HAIR_CONSTRAINTS = 2; const int DEFAULT_HAIR_STRANDS = 20; const int DEFAULT_HAIR_LINKS = 10; -const float DEFAULT_HAIR_RADIUS = 0.15f; +const float DEFAULT_HAIR_RADIUS = 0.075f; const float DEFAULT_HAIR_LINK_LENGTH = 0.06f; const float DEFAULT_HAIR_THICKNESS = 0.025f; +const glm::vec3 DEFAULT_GRAVITY(0.0f, -9.8f, 0.0f); class Hair { public: @@ -41,7 +42,6 @@ public: void setAcceleration(const glm::vec3& acceleration) { _acceleration = acceleration; } void setAngularVelocity(const glm::vec3& angularVelocity) { _angularVelocity = angularVelocity; } void setAngularAcceleration(const glm::vec3& angularAcceleration) { _angularAcceleration = angularAcceleration; } - void setGravity(const glm::vec3& gravity) { _gravity = gravity; } void setLoudness(const float loudness) { _loudness = loudness; } private: diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 169583b14b..b1c4b44104 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -191,7 +191,6 @@ void Avatar::simulate(float deltaTime) { _hair.setAcceleration(getAcceleration() * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularVelocity((getAngularVelocity() + getHead()->getAngularVelocity()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularAcceleration(getAngularAcceleration() * getHead()->getFinalOrientationInWorldFrame()); - _hair.setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setLoudness((float) getHeadData()->getAudioLoudness()); _hair.simulate(deltaTime); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4751abfd84..7576d42325 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -217,7 +217,6 @@ void MyAvatar::simulate(float deltaTime) { _hair.setAcceleration(getAcceleration() * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularVelocity((getAngularVelocity() + getHead()->getAngularVelocity()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setAngularAcceleration(getAngularAcceleration() * getHead()->getFinalOrientationInWorldFrame()); - _hair.setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()) * getHead()->getFinalOrientationInWorldFrame()); _hair.setLoudness((float)getHeadData()->getAudioLoudness()); _hair.simulate(deltaTime); } From f8b423ced6c8f67c3ddf7e3ee2e9f4babf8455f7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Oct 2014 16:12:15 -0700 Subject: [PATCH 06/11] bubble up isAutoRepeat state for KeyEvent --- libraries/script-engine/src/EventTypes.cpp | 12 +++++++++--- libraries/script-engine/src/EventTypes.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/EventTypes.cpp b/libraries/script-engine/src/EventTypes.cpp index 75b3eba1a3..de3ec231ae 100644 --- a/libraries/script-engine/src/EventTypes.cpp +++ b/libraries/script-engine/src/EventTypes.cpp @@ -30,7 +30,8 @@ KeyEvent::KeyEvent() : isMeta(false), isAlt(false), isKeypad(false), - isValid(false) + isValid(false), + isAutoRepeat(false) { }; @@ -44,6 +45,7 @@ KeyEvent::KeyEvent(const QKeyEvent& event) { isAlt = event.modifiers().testFlag(Qt::AltModifier); isKeypad = event.modifiers().testFlag(Qt::KeypadModifier); isValid = true; + isAutoRepeat = event.isAutoRepeat(); // handle special text for special characters... if (key == Qt::Key_F1) { @@ -127,7 +129,8 @@ bool KeyEvent::operator==(const KeyEvent& other) const { && other.isControl == isControl && other.isMeta == isMeta && other.isAlt == isAlt - && other.isKeypad == isKeypad; + && other.isKeypad == isKeypad + && other.isAutoRepeat == isAutoRepeat; } @@ -163,6 +166,7 @@ QScriptValue keyEventToScriptValue(QScriptEngine* engine, const KeyEvent& event) obj.setProperty("isControl", event.isControl); obj.setProperty("isAlt", event.isAlt); obj.setProperty("isKeypad", event.isKeypad); + obj.setProperty("isAutoRepeat", event.isAutoRepeat); return obj; } @@ -173,6 +177,7 @@ void keyEventFromScriptValue(const QScriptValue& object, KeyEvent& event) { event.isControl = object.property("isControl").toVariant().toBool(); event.isAlt = object.property("isAlt").toVariant().toBool(); event.isKeypad = object.property("isKeypad").toVariant().toBool(); + event.isAutoRepeat = object.property("isAutoRepeat").toVariant().toBool(); QScriptValue key = object.property("key"); if (key.isValid()) { @@ -286,7 +291,8 @@ void keyEventFromScriptValue(const QScriptValue& object, KeyEvent& event) { << " event.isControl=" << event.isControl << " event.isMeta=" << event.isMeta << " event.isAlt=" << event.isAlt - << " event.isKeypad=" << event.isKeypad; + << " event.isKeypad=" << event.isKeypad + << " event.isAutoRepeat=" << event.isAutoRepeat; } } diff --git a/libraries/script-engine/src/EventTypes.h b/libraries/script-engine/src/EventTypes.h index 7d4076dbf0..959292039b 100644 --- a/libraries/script-engine/src/EventTypes.h +++ b/libraries/script-engine/src/EventTypes.h @@ -38,6 +38,7 @@ public: bool isAlt; bool isKeypad; bool isValid; + bool isAutoRepeat; }; From 8ae1f980f50edd37ea8527fd5f450b935dc7b79e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Oct 2014 16:13:01 -0700 Subject: [PATCH 07/11] don't make headMove changes if key is auto repeating --- examples/headMove.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 831e77a723..b9330153fc 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -142,7 +142,7 @@ function update(deltaTime) { } Controller.keyPressEvent.connect(function(event) { - if (event.text == "SPACE" && !movingWithHead) { + if (event.text == "SPACE" && !event.isAutoRepeat && !movingWithHead) { keyDownTime = 0.0; movingWithHead = true; headStartPosition = MyAvatar.getTrackedHeadPosition(); @@ -161,7 +161,7 @@ var TIME_FOR_TURN = 0.25; var TURN_AROUND = 180.0; Controller.keyReleaseEvent.connect(function(event) { - if (event.text == "SPACE") { + if (event.text == "SPACE" && !event.isAutoRepeat) { movingWithHead = false; if (keyDownTime < TIME_FOR_TURN_AROUND) { if (keyDownTime < TIME_FOR_TURN) { From 1e832e7bbbe34a755a7c86de2006c2682600b45a Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 Oct 2014 16:38:24 -0700 Subject: [PATCH 08/11] Tour guide script --- examples/guidedTour.js | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/guidedTour.js diff --git a/examples/guidedTour.js b/examples/guidedTour.js new file mode 100644 index 0000000000..fe31e1db30 --- /dev/null +++ b/examples/guidedTour.js @@ -0,0 +1,47 @@ +// +// TourGuide.js +// +// This script will follow another person, if their display name is "Tour Guide" +// +var leaderName = "Tour Guide"; + +var guide; +var isGuide = false; +var lastGuidePosition = { x:0, y:0, z:0 }; +var MIN_CHANGE = 2.0; +var LANDING_DISTANCE = 2.0; +var LANDING_RANDOM = 0.2; + +function update(deltaTime) { + + if (Math.random() < deltaTime) { + guide = AvatarList.avatarWithDisplayName(leaderName); + if (guide && !isGuide) { + print("found a guide!"); + isGuide = true; + } else if (!isGuide) { + print("Lost My Guide"); + isguide = false; + } + } + + if (guide) { + // Check whether guide has moved, update if so + if (Vec3.length(lastGuidePosition) == 0.0) { + lastGuidePosition = guide.position; + } else { + if (Vec3.length(Vec3.subtract(lastGuidePosition, guide.position)) > MIN_CHANGE) { + var meToGuide = Vec3.multiply(Vec3.normalize(Vec3.subtract(guide.position, MyAvatar.position)), LANDING_DISTANCE); + var newPosition = Vec3.subtract(guide.position, meToGuide); + newPosition = Vec3.sum(newPosition, { x: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0, + y: 0, + z: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0 }); + MyAvatar.position = newPosition; + + lastGuidePosition = guide.position; + MyAvatar.orientation = guide.orientation; + } + } + } +} +Script.update.connect(update); \ No newline at end of file From 8684384316aae72442230ff48495ed80b099457d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 24 Oct 2014 16:38:57 -0700 Subject: [PATCH 09/11] Disconnect metavoxel LOD from avatar LOD. --- interface/src/MetavoxelSystem.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 2071ea8c3d..a9bdad8148 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -110,11 +110,9 @@ int SimulateVisitor::visit(MetavoxelInfo& info) { void MetavoxelSystem::simulate(float deltaTime) { // update the lod { - // the LOD threshold is temporarily tied to the avatar LOD parameter QWriteLocker locker(&_lodLock); - const float BASE_LOD_THRESHOLD = 0.01f; - _lod = MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), - BASE_LOD_THRESHOLD * Menu::getInstance()->getAvatarLODDistanceMultiplier()); + const float DEFAULT_LOD_THRESHOLD = 0.01f; + _lod = MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), DEFAULT_LOD_THRESHOLD); } SimulateVisitor simulateVisitor(deltaTime, getLOD()); From 54197b2c2304948add3bc17c259473f34284432c Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 24 Oct 2014 17:10:46 -0700 Subject: [PATCH 10/11] fix for spacing --- examples/guidedTour.js | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/examples/guidedTour.js b/examples/guidedTour.js index fe31e1db30..3416e55d1c 100644 --- a/examples/guidedTour.js +++ b/examples/guidedTour.js @@ -14,34 +14,34 @@ var LANDING_RANDOM = 0.2; function update(deltaTime) { - if (Math.random() < deltaTime) { - guide = AvatarList.avatarWithDisplayName(leaderName); - if (guide && !isGuide) { - print("found a guide!"); - isGuide = true; - } else if (!isGuide) { - print("Lost My Guide"); - isguide = false; - } + if (Math.random() < deltaTime) { + guide = AvatarList.avatarWithDisplayName(leaderName); + if (guide && !isGuide) { + print("found a guide!"); + isGuide = true; + } else if (!isGuide) { + print("Lost My Guide"); + isguide = false; } + } - if (guide) { - // Check whether guide has moved, update if so - if (Vec3.length(lastGuidePosition) == 0.0) { - lastGuidePosition = guide.position; - } else { - if (Vec3.length(Vec3.subtract(lastGuidePosition, guide.position)) > MIN_CHANGE) { - var meToGuide = Vec3.multiply(Vec3.normalize(Vec3.subtract(guide.position, MyAvatar.position)), LANDING_DISTANCE); - var newPosition = Vec3.subtract(guide.position, meToGuide); - newPosition = Vec3.sum(newPosition, { x: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0, - y: 0, - z: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0 }); - MyAvatar.position = newPosition; + if (guide) { + // Check whether guide has moved, update if so + if (Vec3.length(lastGuidePosition) == 0.0) { + lastGuidePosition = guide.position; + } else { + if (Vec3.length(Vec3.subtract(lastGuidePosition, guide.position)) > MIN_CHANGE) { + var meToGuide = Vec3.multiply(Vec3.normalize(Vec3.subtract(guide.position, MyAvatar.position)), LANDING_DISTANCE); + var newPosition = Vec3.subtract(guide.position, meToGuide); + newPosition = Vec3.sum(newPosition, { x: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0, + y: 0, + z: Math.random() * LANDING_RANDOM - LANDING_RANDOM / 2.0 }); + MyAvatar.position = newPosition; - lastGuidePosition = guide.position; - MyAvatar.orientation = guide.orientation; - } - } + lastGuidePosition = guide.position; + MyAvatar.orientation = guide.orientation; + } } + } } Script.update.connect(update); \ No newline at end of file From 80a87b3b447efff8bdebdb5686c2233b7d1c3167 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 24 Oct 2014 17:50:31 -0700 Subject: [PATCH 11/11] framerate is as fast as the display can go --- interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 70 +++++++++++++++++++++++++++-------- interface/src/Application.h | 7 +++- interface/src/Menu.cpp | 47 ++++++++++++++++++++--- interface/src/Menu.h | 12 +++++- interface/src/gpu/Batch.cpp | 3 +- 6 files changed, 114 insertions(+), 27 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index a150a308e0..9c4eeff65b 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -33,7 +33,7 @@ elseif (WIN32) add_definitions(-D_USE_MATH_DEFINES) # apparently needed to get M_PI and other defines from cmath/math.h add_definitions(-DWINDOWS_LEAN_AND_MEAN) # needed to make sure windows doesn't go to crazy with its defines - set(GL_HEADERS "#include \n#include \n#include ") + set(GL_HEADERS "#include \n#include \n#include \n#include ") endif () # set up the external glm library diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1239615b27..bb29bfb244 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -94,10 +94,6 @@ #include "devices/Leapmotion.h" -#ifdef WIN32 -#include -#endif - using namespace std; // Starfield information @@ -183,17 +179,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _trayIcon(new QSystemTrayIcon(_window)), _lastNackTime(usecTimestampNow()), _lastSendDownstreamAudioStats(usecTimestampNow()), - _renderTargetFramerate(60), + _renderTargetFramerate(0), + _isVSyncOn(true), _renderResolutionScale(1.0f) { - - /* QGLFormat trueFormat = _glWidget->format(); - trueFormat.setSwapInterval(0); - _glWidget->setFormat(trueFormat);*/ - int swapInterval = _glWidget->format().swapInterval(); - swapInterval++; - // read the ApplicationInfo.ini file for Name/Version/Domain information QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); @@ -535,13 +525,18 @@ void Application::initializeGL() { qDebug("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); if (wglewGetExtension("WGL_EXT_swap_control")) { - wglSwapIntervalEXT(0); int swapInterval = wglGetSwapIntervalEXT(); - swapInterval++; + qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); } #endif - +#if defined(Q_OS_LINUX) + // TODO: Write the correct code for Linux... + /* if (wglewGetExtension("WGL_EXT_swap_control")) { + int swapInterval = wglGetSwapIntervalEXT(); + qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); + }*/ +#endif // Before we render anything, let's set up our viewFrustumOffsetCamera with a sufficiently large // field of view and near and far clip to make it interesting. @@ -4168,10 +4163,53 @@ void Application::takeSnapshot() { _snapshotShareDialog->show(); } -void Application::setRenderTargetFramerate(int framerate) { +void Application::setRenderTargetFramerate(unsigned int framerate, bool vsyncOn) { + if (vsyncOn != _isVSyncOn) { +#if defined(Q_OS_WIN) + if (wglewGetExtension("WGL_EXT_swap_control")) { + wglSwapIntervalEXT(vsyncOn); + int swapInterval = wglGetSwapIntervalEXT(); + _isVSyncOn = swapInterval; + qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); + } else { + qDebug("V-Sync is FORCED ON on this system\n"); + } +#elif defined(Q_OS_LINUX) + // TODO: write the poper code for linux + /* + if (glQueryExtension.... ("GLX_EXT_swap_control")) { + glxSwapIntervalEXT(vsyncOn); + int swapInterval = xglGetSwapIntervalEXT(); + _isVSyncOn = swapInterval; + qDebug("V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); + } else { + qDebug("V-Sync is FORCED ON on this system\n"); + } + */ +#else + qDebug("V-Sync is FORCED ON on this system\n"); +#endif + } _renderTargetFramerate = framerate; } +bool Application::isVSyncEditable() { +#if defined(Q_OS_WIN) + if (wglewGetExtension("WGL_EXT_swap_control")) { + return true; + } +#elif defined(Q_OS_LINUX) + // TODO: write the poper code for linux + /* + if (glQueryExtension.... ("GLX_EXT_swap_control")) { + return true; + } + */ +#else +#endif + return false; +} + void Application::setRenderResolutionScale(float scale) { _renderResolutionScale = scale; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 60d19f74be..e85c4f4db5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -361,7 +361,11 @@ public slots: void domainSettingsReceived(const QJsonObject& domainSettingsObject); - void setRenderTargetFramerate(int framerate); + void setRenderTargetFramerate(unsigned int framerate, bool vsyncOn = true); + bool isVSyncOn() { return _isVSyncOn; } + bool isVSyncEditable(); + unsigned int getRenderTargetFramerate() const { return _renderTargetFramerate; } + void setRenderResolutionScale(float scale); void resetSensors(); @@ -615,6 +619,7 @@ private: quint64 _lastSendDownstreamAudioStats; int _renderTargetFramerate; + bool _isVSyncOn; float _renderResolutionScale; }; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 44afd13bc9..6538aee644 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -373,7 +373,23 @@ Menu::Menu() : shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false)); shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false)); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderUnleashFramerate, 0, false, this, SLOT(toggleUnleashFramerate())); + { + QMenu* framerateMenu = renderOptionsMenu->addMenu(MenuOption::RenderTargetFramerate); + QActionGroup* framerateGroup = new QActionGroup(framerateMenu); + + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerateUnlimited, 0, true)); + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate60, 0, false)); + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate50, 0, false)); + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate40, 0, false)); + framerateGroup->addAction(addCheckableActionToQMenuAndActionHash(framerateMenu, MenuOption::RenderTargetFramerate30, 0, false)); + connect(framerateMenu, SIGNAL(triggered(QAction*)), this, SLOT(changeRenderTargetFramerate(QAction*))); + +#if defined(Q_OS_MAC) +#else + QAction* vsyncAction = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, this, SLOT(changeVSync())); +#endif + } + QMenu* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution); QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu); @@ -1237,11 +1253,30 @@ void Menu::muteEnvironment() { free(packet); } -void Menu::toggleUnleashFramerate() { - if (isOptionChecked(MenuOption::RenderUnleashFramerate)) { - Application::getInstance()->setRenderTargetFramerate(0); - } else { - Application::getInstance()->setRenderTargetFramerate(-1); +void Menu::changeVSync() { + Application::getInstance()->setRenderTargetFramerate( + Application::getInstance()->getRenderTargetFramerate(), + isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn)); +} +void Menu::changeRenderTargetFramerate(QAction* action) { + bool vsynOn = Application::getInstance()->isVSyncOn(); + unsigned int framerate = Application::getInstance()->getRenderTargetFramerate(); + + QString text = action->text(); + if (text == MenuOption::RenderTargetFramerateUnlimited) { + Application::getInstance()->setRenderTargetFramerate(0, vsynOn); + } + else if (text == MenuOption::RenderTargetFramerate60) { + Application::getInstance()->setRenderTargetFramerate(60, vsynOn); + } + else if (text == MenuOption::RenderTargetFramerate50) { + Application::getInstance()->setRenderTargetFramerate(50, vsynOn); + } + else if (text == MenuOption::RenderTargetFramerate40) { + Application::getInstance()->setRenderTargetFramerate(40, vsynOn); + } + else if (text == MenuOption::RenderTargetFramerate30) { + Application::getInstance()->setRenderTargetFramerate(30, vsynOn); } } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b9878ec9fa..3c96fd0dcd 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -229,7 +229,8 @@ private slots: void displayAddressOfflineMessage(); void displayAddressNotFoundMessage(); void muteEnvironment(); - void toggleUnleashFramerate(); + void changeRenderTargetFramerate(QAction* action); + void changeVSync(); void changeRenderResolution(QAction* action); private: @@ -453,7 +454,14 @@ namespace MenuOption { const QString RenderHeightfields = "Render Heightfields"; const QString RenderLookAtVectors = "Show Look-at Vectors"; const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes"; - const QString RenderUnleashFramerate = "Unleash Framerate"; + const QString RenderTargetFramerate = "Framerate"; + const QString RenderTargetFramerateUnlimited = "Unlimited"; + const QString RenderTargetFramerate60 = "60"; + const QString RenderTargetFramerate50 = "50"; + const QString RenderTargetFramerate40 = "40"; + const QString RenderTargetFramerate30 = "30"; + const QString RenderTargetFramerateVSyncOn = "V-Sync On"; + const QString RenderResolution = "Scale Resolution"; const QString RenderResolutionOne = "1"; const QString RenderResolutionTwoThird = "2/3"; diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 8b36ef8b33..054bc09846 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -17,7 +17,8 @@ //#define DO_IT_NOW(call, offset) runLastCommand(); #define DO_IT_NOW(call, offset) -#define CHECK_GL_ERROR() ::gpu::backend::checkGLError() +//#define CHECK_GL_ERROR() ::gpu::backend::checkGLError() +#define CHECK_GL_ERROR() using namespace gpu;