From 1357aee01ed87b6bec905dcac767af4ee62c44a4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 4 Mar 2014 13:03:31 -0800 Subject: [PATCH 1/3] Use mipmaps and trilinear filtering for models. Closes #2180. --- interface/src/renderer/TextureCache.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index d5d3b42155..1c58f93510 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -113,7 +113,8 @@ GLuint TextureCache::getFileTextureID(const QString& filename) { glBindTexture(GL_TEXTURE_2D, id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); _fileTextureIDs.insert(filename, id); @@ -335,7 +336,8 @@ void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor glBindTexture(GL_TEXTURE_2D, getID()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } @@ -388,7 +390,8 @@ QSharedPointer DilatableNetworkTexture::getDilatedTexture(float dilatio glBindTexture(GL_TEXTURE_2D, texture->getID()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } From 3930b3e8247e1382f80db5e058ed6838460a0553 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 5 Mar 2014 17:44:08 -0800 Subject: [PATCH 2/3] Display names are great, but not in the shadow map. Closes #2208. --- interface/src/Application.cpp | 4 ++-- interface/src/avatar/Avatar.cpp | 11 +++++++---- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/AvatarManager.cpp | 16 ++++++++-------- interface/src/avatar/AvatarManager.h | 4 ++-- interface/src/avatar/MyAvatar.cpp | 8 ++++---- interface/src/avatar/MyAvatar.h | 2 +- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1e9d206462..7a7420656a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2383,8 +2383,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR); } - bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); - _avatarManager.renderAvatars(forceRenderMyHead, selfAvatarOnly); + bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); + _avatarManager.renderAvatars(mirrorMode, selfAvatarOnly); if (!selfAvatarOnly) { // Render the world box diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ef6975d223..a304fa1c99 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -201,7 +201,7 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render() { +void Avatar::render(bool forShadowMap) { glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); float lengthToTarget = glm::length(toTarget); @@ -209,7 +209,7 @@ void Avatar::render() { // glow when moving in the distance const float GLOW_DISTANCE = 5.0f; - Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f); + Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); // render body if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { @@ -233,7 +233,7 @@ void Avatar::render() { float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; - if ((sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { + if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); @@ -243,7 +243,10 @@ void Avatar::render() { } } const float DISPLAYNAME_DISTANCE = 10.0f; - setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE); + setShowDisplayName(!forShadowMap && lengthToTarget < DISPLAYNAME_DISTANCE); + if (forShadowMap) { + return; + } renderDisplayName(); if (!_chatMessage.empty()) { diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 8de5da8d50..d5c311a274 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -74,7 +74,7 @@ public: void init(); void simulate(float deltaTime); - void render(); + void render(bool forShadowMap = false); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 847baf782f..57e800a401 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -69,7 +69,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { +void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); @@ -83,16 +83,16 @@ void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { avatar->init(); } if (avatar == static_cast(_myAvatar.data())) { - _myAvatar->render(forceRenderMyHead); + _myAvatar->render(forShadowMapOrMirror); } else { - avatar->render(); + avatar->render(forShadowMapOrMirror); } avatar->setDisplayingLookatVectors(renderLookAtVectors); } - renderAvatarFades(); + renderAvatarFades(forShadowMapOrMirror); } else { // just render myAvatar - _myAvatar->render(forceRenderMyHead, true); + _myAvatar->render(forShadowMapOrMirror); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } @@ -115,13 +115,13 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } } -void AvatarManager::renderAvatarFades() { +void AvatarManager::renderAvatarFades(bool forShadowMap) { // render avatar fades - Glower glower; + Glower glower(forShadowMap ? 0.0f : 1.0f); foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { Avatar* avatar = static_cast(fadingAvatar.data()); - avatar->render(); + avatar->render(forShadowMap); } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index db24d5bf4e..c690dfa966 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -29,7 +29,7 @@ public: MyAvatar* getMyAvatar() { return _myAvatar.data(); } void updateOtherAvatars(float deltaTime); - void renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly = false); + void renderAvatars(bool forShadowMapOrMirror = false, bool selfAvatarOnly = false); void clearOtherAvatars(); @@ -45,7 +45,7 @@ private: void processKillAvatar(const QByteArray& datagram); void simulateAvatarFades(float deltaTime); - void renderAvatarFades(); + void renderAvatarFades(bool forShadowMap); // virtual override AvatarHash::iterator erase(const AvatarHash::iterator& iterator); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 51fcad20ae..407a49dcb5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -452,7 +452,7 @@ void MyAvatar::renderDebugBodyPoints() { } -void MyAvatar::render(bool forceRenderHead, bool avatarOnly) { +void MyAvatar::render(bool forShadowMapOrMirror) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early @@ -466,10 +466,10 @@ void MyAvatar::render(bool forceRenderHead, bool avatarOnly) { _skeletonModel.renderCollisionProxies(1.f); } if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(forceRenderHead); + renderBody(forShadowMapOrMirror); } - setShowDisplayName(!avatarOnly); - if (avatarOnly) { + setShowDisplayName(!forShadowMapOrMirror); + if (forShadowMapOrMirror) { return; } renderDisplayName(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index aeb9e6d968..e9dfbd8bd0 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -35,7 +35,7 @@ public: void simulate(float deltaTime); void updateFromGyros(float deltaTime); - void render(bool forceRenderHead, bool avatarOnly = false); + void render(bool forShadowMapOrMirror = false); void renderDebugBodyPoints(); void renderHeadMouse() const; From ad25455f868608909f6114ef0776c0cc440d9232 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 5 Mar 2014 18:06:14 -0800 Subject: [PATCH 3/3] Track hysteresis for next model separately, but just in case, don't use recursion to fall back on hysteresis value. Closes #2209. --- interface/src/renderer/GeometryCache.cpp | 9 ++++++++- interface/src/renderer/Model.cpp | 5 +++-- interface/src/renderer/Model.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 5b13e2da42..88d2a8962d 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -343,7 +343,14 @@ QSharedPointer NetworkGeometry::getLODOrFallback(float distance // if we previously selected a different distance, make sure we've moved far enough to justify switching const float HYSTERESIS_PROPORTION = 0.1f; if (glm::abs(distance - qMax(hysteresis, lodDistance)) / fabsf(hysteresis - lodDistance) < HYSTERESIS_PROPORTION) { - return getLODOrFallback(hysteresis, hysteresis); + lod = _lodParent; + lodDistance = 0.0f; + it = _lods.upperBound(hysteresis); + if (it != _lods.constBegin()) { + it = it - 1; + lod = it.value(); + lodDistance = it.key(); + } } } if (lod->isLoaded()) { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 1aab0a4dab..0cff3aaa87 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -416,6 +416,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo // if so instructed, keep the current geometry until the new one is loaded _nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); + _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) { applyNextGeometry(); } @@ -784,7 +785,7 @@ void Model::applyCollision(CollisionInfo& collision) { QVector Model::updateGeometry(bool delayLoad) { QVector newJointStates; if (_nextGeometry) { - _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); + _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _nextLODHysteresis, delayLoad); if (!delayLoad) { _nextGeometry->setLoadPriority(this, -_lodDistance); _nextGeometry->ensureLoading(); @@ -827,7 +828,7 @@ void Model::applyNextGeometry() { // delete our local geometry and custom textures deleteGeometry(); _dilatedTextures.clear(); - _lodHysteresis = NetworkGeometry::NO_HYSTERESIS; + _lodHysteresis = _nextLODHysteresis; // we retain a reference to the base geometry so that its reference count doesn't fall to zero _baseGeometry = _nextBaseGeometry; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 524bd9dc79..ae28a8e4fe 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -247,6 +247,7 @@ private: QSharedPointer _nextGeometry; float _lodDistance; float _lodHysteresis; + float _nextLODHysteresis; float _pupilDilation; std::vector _blendshapeCoefficients;