diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5746f1f670..c729c08e2b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -621,10 +621,10 @@ void 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()) { - _textureCache.setFrameBufferSize(OculusManager::getRenderTargetSize()); + DependencyManager::get()->setFrameBufferSize(OculusManager::getRenderTargetSize()); } else { QSize fbSize = DependencyManager::get()->getDeviceSize() * getRenderResolutionScale(); - _textureCache.setFrameBufferSize(fbSize); + DependencyManager::get()->setFrameBufferSize(fbSize); } glEnable(GL_LINE_SMOOTH); @@ -714,7 +714,7 @@ void Application::paintGL() { _glowEffect.prepare(); // Viewport is assigned to the size of the framebuffer - QSize size = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->size(); + QSize size = DependencyManager::get()->getPrimaryFramebufferObject()->size(); glViewport(0, 0, size.width(), size.height()); glMatrixMode(GL_MODELVIEW); @@ -2049,6 +2049,9 @@ void Application::init() { // save settings when avatar changes connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings); + + // make sure our texture cache knows about window size changes + DependencyManager::get()->associateWithWidget(glCanvas.data()); } void Application::closeMirrorView() { @@ -2779,7 +2782,7 @@ glm::vec3 Application::getSunDirection() { void Application::updateShadowMap() { PerformanceTimer perfTimer("shadowMap"); - QOpenGLFramebufferObject* fbo = _textureCache.getShadowFramebufferObject(); + QOpenGLFramebufferObject* fbo = DependencyManager::get()->getShadowFramebufferObject(); fbo->bind(); glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -2945,7 +2948,7 @@ void Application::setupWorldLight() { } QImage Application::renderAvatarBillboard() { - _textureCache.getPrimaryFramebufferObject()->bind(); + DependencyManager::get()->getPrimaryFramebufferObject()->bind(); // the "glow" here causes an alpha of one Glower glower; @@ -2958,7 +2961,7 @@ QImage Application::renderAvatarBillboard() { QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); - _textureCache.getPrimaryFramebufferObject()->release(); + DependencyManager::get()->getPrimaryFramebufferObject()->release(); return image; } @@ -3088,7 +3091,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr // draw a red sphere float originSphereRadius = 0.05f; glColor3f(1,0,0); - _geometryCache.renderSphere(originSphereRadius, 15, 15); + DependencyManager::get()->renderSphere(originSphereRadius, 15, 15); // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { @@ -3310,12 +3313,12 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // set the bounds of rear mirror view if (billboard) { - QSize size = getTextureCache()->getFrameBufferSize(); + QSize size = DependencyManager::get()->getFrameBufferSize(); glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); } else { // if not rendering the billboard, the region is in device independent coordinates; must convert to device - QSize size = getTextureCache()->getFrameBufferSize(); + QSize size = DependencyManager::get()->getFrameBufferSize(); float ratio = QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); 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); diff --git a/interface/src/Application.h b/interface/src/Application.h index 31f6d7d50a..32776bcabf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -239,9 +239,7 @@ public: ToolWindow* getToolWindow() { return _toolWindow ; } - GeometryCache* getGeometryCache() { return &_geometryCache; } AnimationCache* getAnimationCache() { return &_animationCache; } - TextureCache* getTextureCache() { return &_textureCache; } DeferredLightingEffect* getDeferredLightingEffect() { return &_deferredLightingEffect; } GlowEffect* getGlowEffect() { return &_glowEffect; } ControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; } @@ -559,9 +557,7 @@ private: QSet _keysPressed; - GeometryCache _geometryCache; AnimationCache _animationCache; - TextureCache _textureCache; DeferredLightingEffect _deferredLightingEffect; GlowEffect _glowEffect; diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 101d16d3ba..bf176e0415 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -450,7 +450,9 @@ void Audio::start() { qDebug() << "Unable to set up audio output because of a problem with output format."; } - _inputFrameBuffer.initialize( _inputFormat.channelCount(), _audioInput->bufferSize() * 8 ); + if (_audioInput) { + _inputFrameBuffer.initialize( _inputFormat.channelCount(), _audioInput->bufferSize() * 8 ); + } _inputGain.initialize(); _sourceGain.initialize(); _noiseSource.initialize(); @@ -1935,6 +1937,9 @@ int Audio::calculateNumberOfFrameSamples(int numBytes) const { } float Audio::getAudioOutputMsecsUnplayed() const { + if (!_audioOutput) { + return 0.0f; + } int bytesAudioOutputUnplayed = _audioOutput->bufferSize() - _audioOutput->bytesFree(); float msecsAudioOutputUnplayed = bytesAudioOutputUnplayed / (float)_outputFormat.bytesForDuration(USECS_PER_MSEC); return msecsAudioOutputUnplayed; diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 0ce43ecdaa..fa8f18ac3f 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -261,7 +261,7 @@ void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); - Application::getInstance()->getGeometryCache()->renderSphere(1.0f, 100, 50); //Draw a unit sphere + DependencyManager::get()->renderSphere(1.0f, 100, 50); //Draw a unit sphere glDepthMask(GL_TRUE); program->release(); diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 002acec9ed..d649a4254b 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -205,7 +205,7 @@ void MetavoxelSystem::render() { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); + DependencyManager::get()->setPrimaryDrawBuffers(true, true); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -251,7 +251,7 @@ void MetavoxelSystem::render() { glPopMatrix(); } - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); + DependencyManager::get()->setPrimaryDrawBuffers(true, false); _baseHeightfieldProgram.release(); @@ -348,7 +348,7 @@ void MetavoxelSystem::render() { } if (!_voxelBaseBatches.isEmpty()) { - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); + DependencyManager::get()->setPrimaryDrawBuffers(true, true); glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); @@ -383,7 +383,7 @@ void MetavoxelSystem::render() { glDisable(GL_ALPHA_TEST); glEnable(GL_BLEND); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); + DependencyManager::get()->setPrimaryDrawBuffers(true, false); if (!_voxelSplatBatches.isEmpty()) { glDepthFunc(GL_LEQUAL); @@ -463,7 +463,7 @@ void MetavoxelSystem::render() { } if (!_hermiteBatches.isEmpty() && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); + DependencyManager::get()->setPrimaryDrawBuffers(true, true); glEnableClientState(GL_VERTEX_ARRAY); @@ -486,7 +486,7 @@ void MetavoxelSystem::render() { glDisableClientState(GL_VERTEX_ARRAY); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); + DependencyManager::get()->setPrimaryDrawBuffers(true, false); } _hermiteBatches.clear(); @@ -797,7 +797,7 @@ void MetavoxelSystem::applyMaterialEdit(const MetavoxelEditMessage& message, boo Q_ARG(bool, reliable)); return; } - QSharedPointer texture = Application::getInstance()->getTextureCache()->getTexture( + QSharedPointer texture = DependencyManager::get()->getTexture( material->getDiffuse(), SPLAT_TEXTURE); if (texture->isLoaded()) { MetavoxelEditMessage newMessage = message; @@ -1177,10 +1177,11 @@ void VoxelBuffer::render(bool cursor) { if (!_materials.isEmpty()) { _networkTextures.resize(_materials.size()); + TextureCache::SharedPointer textureCache = DependencyManager::get(); for (int i = 0; i < _materials.size(); i++) { const SharedObjectPointer material = _materials.at(i); if (material) { - _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture( + _networkTextures[i] = textureCache->getTexture( static_cast(material.data())->getDiffuse(), SPLAT_TEXTURE); } } @@ -2231,10 +2232,11 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g const QVector& materials = node->getMaterial()->getMaterials(); _networkTextures.resize(materials.size()); + TextureCache::SharedPointer textureCache = DependencyManager::get(); for (int i = 0; i < materials.size(); i++) { const SharedObjectPointer& material = materials.at(i); if (material) { - _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture( + _networkTextures[i] = textureCache->getTexture( static_cast(material.data())->getDiffuse(), SPLAT_TEXTURE); } } diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index d9e8ed0c40..29d1596809 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -466,17 +466,19 @@ void ModelUploader::processCheck() { _timer.stop(); switch (reply->error()) { - case QNetworkReply::NoError: + case QNetworkReply::NoError: { QMessageBox::information(NULL, QString("ModelUploader::processCheck()"), QString("Your model is now available in the browser."), QMessageBox::Ok); - Application::getInstance()->getGeometryCache()->refresh(_url); + DependencyManager::get()->refresh(_url); + TextureCache::SharedPointer textureCache = DependencyManager::get(); foreach (const QByteArray& filename, _textureFilenames) { - Application::getInstance()->getTextureCache()->refresh(_textureBase + filename); + textureCache->refresh(_textureBase + filename); } deleteLater(); break; + } case QNetworkReply::ContentNotFoundError: if (--_numberOfChecks) { _timer.start(TIMEOUT); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index c4f2ec8468..2fcc76b267 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -71,22 +71,23 @@ void renderWorldBox() { glPushMatrix(); glTranslatef(MARKER_DISTANCE, 0, 0); glColor3fv(red); - Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); + GeometryCache::SharedPointer geometryCache = DependencyManager::get(); + geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, MARKER_DISTANCE, 0); glColor3fv(green); - Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); + geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, MARKER_DISTANCE); glColor3fv(blue); - Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); + geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glColor3fv(gray); glTranslatef(MARKER_DISTANCE, 0, MARKER_DISTANCE); - Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); + geometryCache->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c680c75056..49a6f436df 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -394,7 +394,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool } else { glTranslatef(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); } - Application::getInstance()->getGeometryCache()->renderSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); + DependencyManager::get()->renderSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); glPopMatrix(); } } @@ -422,7 +422,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); glScalef(height, height, height); - Application::getInstance()->getGeometryCache()->renderSphere(sphereRadius, 15, 15); + DependencyManager::get()->renderSphere(sphereRadius, 15, 15); glPopMatrix(); } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 148abc3546..9d1ee52fde 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -114,7 +114,7 @@ void Hand::render(bool isMine, Model::RenderMode renderMode) { glPushMatrix(); glTranslatef(position.x, position.y, position.z); glColor3f(0.0f, 1.0f, 0.0f); - Application::getInstance()->getGeometryCache()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); + DependencyManager::get()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); glPopMatrix(); } } @@ -179,7 +179,7 @@ void Hand::renderHandTargets(bool isMine) { Avatar::renderJointConnectingCone(root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f); glPushMatrix(); glTranslatef(root.x, root.y, root.z); - Application::getInstance()->getGeometryCache()->renderSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); + DependencyManager::get()->renderSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); glPopMatrix(); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8e40cb8b30..560010a6f5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -394,7 +394,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - Application::getInstance()->getGeometryCache()->renderSphere(0.2f, 10.0f, 10.0f); + DependencyManager::get()->renderSphere(0.2f, 10.0f, 10.0f); glPopMatrix(); // Head Sphere @@ -402,7 +402,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - Application::getInstance()->getGeometryCache()->renderSphere(0.15f, 10.0f, 10.0f); + DependencyManager::get()->renderSphere(0.15f, 10.0f, 10.0f); glPopMatrix(); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 911ebb7412..b707861677 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -554,6 +554,7 @@ void SkeletonModel::renderRagdoll() { float radius1 = 0.008f; float radius2 = 0.01f; glm::vec3 simulationTranslation = _ragdoll->getTranslationInSimulationFrame(); + GeometryCache::SharedPointer geometryCache = DependencyManager::get(); for (int i = 0; i < numPoints; ++i) { glPushMatrix(); // NOTE: ragdollPoints are in simulation-frame but we want them to be model-relative @@ -561,9 +562,9 @@ void SkeletonModel::renderRagdoll() { glTranslatef(position.x, position.y, position.z); // draw each point as a yellow hexagon with black border glColor4f(0.0f, 0.0f, 0.0f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(radius2, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(radius2, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); glColor4f(1.0f, 1.0f, 0.0f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(radius1, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(radius1, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); glPopMatrix(); } glPopMatrix(); @@ -913,7 +914,8 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { endPoint = endPoint - _translation; glTranslatef(endPoint.x, endPoint.y, endPoint.z); glColor4f(0.6f, 0.6f, 0.8f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + GeometryCache::SharedPointer geometryCache = DependencyManager::get(); + geometryCache->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -922,7 +924,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { glm::vec3 axis = endPoint - startPoint; glTranslatef(-axis.x, -axis.y, -axis.z); glColor4f(0.8f, 0.8f, 0.6f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a green cylinder between the two points glm::vec3 origin(0.0f); @@ -948,6 +950,8 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { continue; } + GeometryCache::SharedPointer geometryCache = DependencyManager::get(); + glPushMatrix(); // shapes are stored in simulation-frame but we want position to be model-relative if (shape->getType() == SPHERE_SHAPE) { @@ -955,7 +959,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { glTranslatef(position.x, position.y, position.z); // draw a grey sphere at shape position glColor4f(0.75f, 0.75f, 0.75f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); } else if (shape->getType() == CAPSULE_SHAPE) { CapsuleShape* capsule = static_cast(shape); @@ -965,7 +969,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { endPoint = endPoint - simulationTranslation; glTranslatef(endPoint.x, endPoint.y, endPoint.z); glColor4f(0.6f, 0.6f, 0.8f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -974,7 +978,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { glm::vec3 axis = endPoint - startPoint; glTranslatef(-axis.x, -axis.y, -axis.z); glColor4f(0.8f, 0.8f, 0.6f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + geometryCache->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a green cylinder between the two points glm::vec3 origin(0.0f); diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 15aa129b93..bf1b10d806 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -449,7 +449,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) { Application::getInstance()->getGlowEffect()->prepare(); } else { - Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind(); + DependencyManager::get()->getPrimaryFramebufferObject()->bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -555,8 +555,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p QOpenGLFramebufferObject* fbo = Application::getInstance()->getGlowEffect()->render(true); glBindTexture(GL_TEXTURE_2D, fbo->texture()); } else { - Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->release(); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->texture()); + DependencyManager::get()->getPrimaryFramebufferObject()->release(); + glBindTexture(GL_TEXTURE_2D, DependencyManager::get()->getPrimaryFramebufferObject()->texture()); } // restore our normal viewport diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index f75ed7e8c3..3354f715cb 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -98,7 +98,7 @@ void AmbientOcclusionEffect::render() { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); + glBindTexture(GL_TEXTURE_2D, DependencyManager::get()->getPrimaryDepthTextureID()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); @@ -116,7 +116,7 @@ void AmbientOcclusionEffect::render() { glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_X_INDEX = 0; const int VIEWPORT_WIDTH_INDEX = 2; - QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); + QOpenGLFramebufferObject* primaryFBO = DependencyManager::get()->getPrimaryFramebufferObject(); float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); @@ -141,7 +141,7 @@ void AmbientOcclusionEffect::render() { glActiveTexture(GL_TEXTURE0); // now render secondary to primary with 4x4 blur - Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind(); + DependencyManager::get()->getPrimaryFramebufferObject()->bind(); glEnable(GL_BLEND); glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index be4e457131..157f428f14 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -37,7 +37,7 @@ void DeferredLightingEffect::init() { } void DeferredLightingEffect::bindSimpleProgram() { - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true, true); + DependencyManager::get()->setPrimaryDrawBuffers(true, true, true); _simpleProgram.bind(); _simpleProgram.setUniformValue(_glowIntensityLocation, Application::getInstance()->getGlowEffect()->getIntensity()); glDisable(GL_BLEND); @@ -46,12 +46,12 @@ void DeferredLightingEffect::bindSimpleProgram() { void DeferredLightingEffect::releaseSimpleProgram() { glEnable(GL_BLEND); _simpleProgram.release(); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false); + DependencyManager::get()->setPrimaryDrawBuffers(true, false, false); } void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) { bindSimpleProgram(); - Application::getInstance()->getGeometryCache()->renderSphere(radius, slices, stacks); + DependencyManager::get()->renderSphere(radius, slices, stacks); releaseSimpleProgram(); } @@ -75,7 +75,7 @@ void DeferredLightingEffect::renderWireCube(float size) { void DeferredLightingEffect::renderSolidCone(float base, float height, int slices, int stacks) { bindSimpleProgram(); - Application::getInstance()->getGeometryCache()->renderCone(base, height, slices, stacks); + DependencyManager::get()->renderCone(base, height, slices, stacks); releaseSimpleProgram(); } @@ -117,15 +117,16 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu void DeferredLightingEffect::prepare() { // clear the normal and specular buffers - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false); + TextureCache::SharedPointer textureCache = DependencyManager::get(); + textureCache->setPrimaryDrawBuffers(false, true, false); glClear(GL_COLOR_BUFFER_BIT); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, false, true); + textureCache->setPrimaryDrawBuffers(false, false, true); // clearing to zero alpha for specular causes problems on my Nvidia card; clear to lowest non-zero value instead const float MAX_SPECULAR_EXPONENT = 128.0f; glClearColor(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false); + textureCache->setPrimaryDrawBuffers(true, false, false); } void DeferredLightingEffect::render() { @@ -137,8 +138,10 @@ void DeferredLightingEffect::render() { glDisable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); glDepthMask(false); + + TextureCache::SharedPointer textureCache = DependencyManager::get(); - QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); + QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); primaryFBO->release(); QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); @@ -148,13 +151,13 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); + glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryNormalTextureID()); glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimarySpecularTextureID()); + glBindTexture(GL_TEXTURE_2D, textureCache->getPrimarySpecularTextureID()); glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); + glBindTexture(GL_TEXTURE_2D, textureCache->getPrimaryDepthTextureID()); // get the viewport side (left, right, both) int viewport[4]; @@ -173,7 +176,7 @@ void DeferredLightingEffect::render() { bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled(); if (shadowsEnabled) { glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); + glBindTexture(GL_TEXTURE_2D, textureCache->getShadowDepthTextureID()); program = &_directionalLightShadowMap; locations = &_directionalLightShadowMapLocations; @@ -188,7 +191,7 @@ void DeferredLightingEffect::render() { program->bind(); } program->setUniformValue(locations->shadowScale, - 1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width()); + 1.0f / textureCache->getShadowFramebufferObject()->width()); } else { program->bind(); @@ -234,6 +237,8 @@ void DeferredLightingEffect::render() { const glm::vec3& eyePoint = Application::getInstance()->getDisplayViewFrustum()->getPosition(); float nearRadius = glm::distance(eyePoint, Application::getInstance()->getDisplayViewFrustum()->getNearTopLeft()); + + GeometryCache::SharedPointer geometryCache = DependencyManager::get(); if (!_pointLights.isEmpty()) { _pointLight.bind(); @@ -241,7 +246,7 @@ void DeferredLightingEffect::render() { _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - + foreach (const PointLight& light, _pointLights) { _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); @@ -270,7 +275,7 @@ void DeferredLightingEffect::render() { } else { glTranslatef(light.position.x, light.position.y, light.position.z); - Application::getInstance()->getGeometryCache()->renderSphere(expandedRadius, 32, 32); + geometryCache->renderSphere(expandedRadius, 32, 32); } glPopMatrix(); @@ -323,7 +328,7 @@ void DeferredLightingEffect::render() { glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); glTranslatef(0.0f, 0.0f, -light.radius * (1.0f + SCALE_EXPANSION * 0.5f)); - Application::getInstance()->getGeometryCache()->renderCone(expandedRadius * glm::tan(light.cutoff), + geometryCache->renderCone(expandedRadius * glm::tan(light.cutoff), expandedRadius, 32, 1); } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index d753901243..2c950be485 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -9,19 +9,21 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// include this before QOpenGLBuffer, which includes an earlier version of OpenGL +#include + #include #include #include #include -#include "Application.h" -#include "GeometryCache.h" -#include "Model.h" -#include "world.h" +#include -GeometryCache::GeometryCache() : - _pendingBlenders(0) { +#include "GeometryCache.h" +#include "TextureCache.h" + +GeometryCache::GeometryCache() { } GeometryCache::~GeometryCache() { @@ -505,33 +507,6 @@ QSharedPointer GeometryCache::getGeometry(const QUrl& url, cons return getResource(url, fallback, delayLoad).staticCast(); } -void GeometryCache::noteRequiresBlend(Model* model) { - if (_pendingBlenders < QThread::idealThreadCount()) { - if (model->maybeStartBlender()) { - _pendingBlenders++; - } - return; - } - if (!_modelsRequiringBlends.contains(model)) { - _modelsRequiringBlends.append(model); - } -} - -void GeometryCache::setBlendedVertices(const QPointer& model, int blendNumber, - const QWeakPointer& geometry, const QVector& vertices, const QVector& normals) { - if (!model.isNull()) { - model->setBlendedVertices(blendNumber, geometry, vertices, normals); - } - _pendingBlenders--; - while (!_modelsRequiringBlends.isEmpty()) { - Model* nextModel = _modelsRequiringBlends.takeFirst(); - if (nextModel && nextModel->maybeStartBlender()) { - _pendingBlenders++; - return; - } - } -} - QSharedPointer GeometryCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { QSharedPointer geometry(new NetworkGeometry(url, fallback.staticCast(), delayLoad), @@ -724,6 +699,7 @@ void NetworkGeometry::clearLoadPriority(const QPointer& owner) { void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& url) { if (_meshes.size() > 0) { + TextureCache::SharedPointer textureCache = DependencyManager::get(); for (int i = 0; i < _meshes.size(); i++) { NetworkMesh& mesh = _meshes[i]; for (int j = 0; j < mesh.parts.size(); j++) { @@ -732,19 +708,19 @@ void NetworkGeometry::setTextureWithNameToURL(const QString& name, const QUrl& u QSharedPointer matchingTexture = QSharedPointer(); if (part.diffuseTextureName == name) { part.diffuseTexture = - Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE, + textureCache->getTexture(url, DEFAULT_TEXTURE, _geometry.meshes[i].isEye, QByteArray()); part.diffuseTexture->setLoadPriorities(_loadPriorities); } else if (part.normalTextureName == name) { - part.normalTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE, + part.normalTexture = textureCache->getTexture(url, DEFAULT_TEXTURE, false, QByteArray()); part.normalTexture->setLoadPriorities(_loadPriorities); } else if (part.specularTextureName == name) { - part.specularTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE, + part.specularTexture = textureCache->getTexture(url, DEFAULT_TEXTURE, false, QByteArray()); part.specularTexture->setLoadPriorities(_loadPriorities); } else if (part.emissiveTextureName == name) { - part.emissiveTexture = Application::getInstance()->getTextureCache()->getTexture(url, DEFAULT_TEXTURE, + part.emissiveTexture = textureCache->getTexture(url, DEFAULT_TEXTURE, false, QByteArray()); part.emissiveTexture->setLoadPriorities(_loadPriorities); } @@ -937,6 +913,8 @@ void NetworkGeometry::reinsert() { void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { _geometry = geometry; + + TextureCache::SharedPointer textureCache = DependencyManager::get(); foreach (const FBXMesh& mesh, _geometry.meshes) { NetworkMesh networkMesh; @@ -945,28 +923,28 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { foreach (const FBXMeshPart& part, mesh.parts) { NetworkMeshPart networkPart; if (!part.diffuseTexture.filename.isEmpty()) { - networkPart.diffuseTexture = Application::getInstance()->getTextureCache()->getTexture( + networkPart.diffuseTexture = textureCache->getTexture( _textureBase.resolved(QUrl(part.diffuseTexture.filename)), DEFAULT_TEXTURE, mesh.isEye, part.diffuseTexture.content); networkPart.diffuseTextureName = part.diffuseTexture.name; networkPart.diffuseTexture->setLoadPriorities(_loadPriorities); } if (!part.normalTexture.filename.isEmpty()) { - networkPart.normalTexture = Application::getInstance()->getTextureCache()->getTexture( + networkPart.normalTexture = textureCache->getTexture( _textureBase.resolved(QUrl(part.normalTexture.filename)), NORMAL_TEXTURE, false, part.normalTexture.content); networkPart.normalTextureName = part.normalTexture.name; networkPart.normalTexture->setLoadPriorities(_loadPriorities); } if (!part.specularTexture.filename.isEmpty()) { - networkPart.specularTexture = Application::getInstance()->getTextureCache()->getTexture( + networkPart.specularTexture = textureCache->getTexture( _textureBase.resolved(QUrl(part.specularTexture.filename)), SPECULAR_TEXTURE, false, part.specularTexture.content); networkPart.specularTextureName = part.specularTexture.name; networkPart.specularTexture->setLoadPriorities(_loadPriorities); } if (!part.emissiveTexture.filename.isEmpty()) { - networkPart.emissiveTexture = Application::getInstance()->getTextureCache()->getTexture( + networkPart.emissiveTexture = textureCache->getTexture( _textureBase.resolved(QUrl(part.emissiveTexture.filename)), EMISSIVE_TEXTURE, false, part.emissiveTexture.content); networkPart.emissiveTextureName = part.emissiveTexture.name; diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index 6faad93fe4..bd7c4a43f9 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -26,20 +27,16 @@ #include "gpu/Stream.h" -class Model; class NetworkGeometry; class NetworkMesh; class NetworkTexture; /// Stores cached geometry. -class GeometryCache : public ResourceCache { +class GeometryCache : public ResourceCache { Q_OBJECT + SINGLETON_DEPENDENCY(GeometryCache) public: - - GeometryCache(); - virtual ~GeometryCache(); - void renderHemisphere(int slices, int stacks); void renderSphere(float radius, int slices, int stacks); void renderSquare(int xDivisions, int yDivisions); @@ -52,20 +49,14 @@ public: /// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested QSharedPointer getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false); - /// Adds the specified model to the list requiring vertex blends. - void noteRequiresBlend(Model* model); - -public slots: - - void setBlendedVertices(const QPointer& model, int blendNumber, const QWeakPointer& geometry, - const QVector& vertices, const QVector& normals); - protected: virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra); private: + GeometryCache(); + virtual ~GeometryCache(); typedef QPair IntPair; typedef QPair VerticesIndices; @@ -78,9 +69,6 @@ private: QHash _gridBuffers; QHash > _networkGeometry; - - QList > _modelsRequiringBlends; - int _pendingBlenders; }; /// Geometry loaded from the network. diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 9f953eed60..7ab368550b 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -41,8 +41,8 @@ GlowEffect::~GlowEffect() { QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const { return (_isOddFrame ? - Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(): - Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject()); + DependencyManager::get()->getSecondaryFramebufferObject(): + DependencyManager::get()->getTertiaryFramebufferObject()); } static ProgramObject* createProgram(const QString& name) { @@ -88,7 +88,7 @@ void GlowEffect::init() { } void GlowEffect::prepare() { - Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind(); + DependencyManager::get()->getPrimaryFramebufferObject()->bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _isEmpty = true; @@ -122,7 +122,8 @@ static void maybeRelease(QOpenGLFramebufferObject* fbo) { QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { PerformanceTimer perfTimer("glowEffect"); - QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); + TextureCache::SharedPointer textureCache = DependencyManager::get(); + QOpenGLFramebufferObject* primaryFBO = textureCache->getPrimaryFramebufferObject(); primaryFBO->release(); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); @@ -138,7 +139,7 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { glDepthMask(GL_FALSE); QOpenGLFramebufferObject* destFBO = toTexture ? - Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject() : NULL; + textureCache->getSecondaryFramebufferObject() : NULL; GLCanvas::SharedPointer glCanvas = DependencyManager::get(); if (!Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect) || _isEmpty) { // copy the primary to the screen @@ -160,9 +161,9 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { } else { // diffuse into the secondary/tertiary (alternating between frames) QOpenGLFramebufferObject* oldDiffusedFBO = - Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); + textureCache->getSecondaryFramebufferObject(); QOpenGLFramebufferObject* newDiffusedFBO = - Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); + textureCache->getTertiaryFramebufferObject(); if (_isOddFrame) { qSwap(oldDiffusedFBO, newDiffusedFBO); } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index fd54f67377..2d273df11c 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -749,7 +749,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { } - /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + /*DependencyManager::get()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, mode == DEFAULT_RENDER_MODE); @@ -789,7 +789,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args); // render translucent meshes afterwards - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + //DependencyManager::get()->setPrimaryDrawBuffers(false, true, true); { GLenum buffers[2]; int bufferCount = 0; @@ -814,7 +814,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { GLBATCH(glDepthMask)(false); GLBATCH(glDepthFunc)(GL_LEQUAL); - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + //DependencyManager::get()->setPrimaryDrawBuffers(true); { GLenum buffers[1]; int bufferCount = 0; @@ -997,7 +997,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo _url = url; // if so instructed, keep the current geometry until the new one is loaded - _nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); + _nextBaseGeometry = _nextGeometry = DependencyManager::get()->getGeometry(url, fallback, delayLoad); _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) { applyNextGeometry(); @@ -1149,7 +1149,7 @@ void Blender::run() { } } // post the result to the geometry cache, which will dispatch to the model if still alive - QMetaObject::invokeMethod(Application::getInstance()->getGeometryCache(), "setBlendedVertices", + QMetaObject::invokeMethod(DependencyManager::get().data(), "setBlendedVertices", Q_ARG(const QPointer&, _model), Q_ARG(int, _blendNumber), Q_ARG(const QWeakPointer&, _geometry), Q_ARG(const QVector&, vertices), Q_ARG(const QVector&, normals)); @@ -1312,7 +1312,7 @@ void Model::simulateInternal(float deltaTime) { // post the blender if we're not currently waiting for one to finish if (geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; - Application::getInstance()->getGeometryCache()->noteRequiresBlend(this); + DependencyManager::get()->noteRequiresBlend(this); } } @@ -1705,7 +1705,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { } - /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + /*DependencyManager::get()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, mode == DEFAULT_RENDER_MODE); @@ -1745,7 +1745,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args); // render translucent meshes afterwards - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + //DependencyManager::get()->setPrimaryDrawBuffers(false, true, true); { GLenum buffers[2]; int bufferCount = 0; @@ -1770,7 +1770,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { GLBATCH(glDepthMask)(false); GLBATCH(glDepthFunc)(GL_LEQUAL); - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + //DependencyManager::get()->setPrimaryDrawBuffers(true); { GLenum buffers[1]; int bufferCount = 0; @@ -2324,7 +2324,8 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts); bool dontReduceMaterialSwitches = Menu::getInstance()->isOptionChecked(MenuOption::DontReduceMaterialSwitches); - + + TextureCache::SharedPointer textureCache = DependencyManager::get(); QString lastMaterialID; int meshPartsRendered = 0; updateVisibleJointStates(); @@ -2446,7 +2447,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod if (showDiffuse && diffuseMap) { GLBATCH(glBindTexture)(GL_TEXTURE_2D, diffuseMap->getID()); } else { - GLBATCH(glBindTexture)(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getWhiteTextureID()); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, textureCache->getWhiteTextureID()); } if (locations->texcoordMatrices >= 0) { @@ -2464,7 +2465,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod GLBATCH(glActiveTexture)(GL_TEXTURE1); Texture* normalMap = networkPart.normalTexture.data(); GLBATCH(glBindTexture)(GL_TEXTURE_2D, !normalMap ? - Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID()); + textureCache->getBlueTextureID() : normalMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); } @@ -2472,7 +2473,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->specularTextureUnit); Texture* specularMap = networkPart.specularTexture.data(); GLBATCH(glBindTexture)(GL_TEXTURE_2D, !specularMap ? - Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID()); + textureCache->getWhiteTextureID() : specularMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); } @@ -2493,7 +2494,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); Texture* emissiveMap = networkPart.emissiveTexture.data(); GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ? - Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID()); + textureCache->getWhiteTextureID() : emissiveMap->getID()); GLBATCH(glActiveTexture)(GL_TEXTURE0); } @@ -2544,3 +2545,38 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod return meshPartsRendered; } + +ModelBlender::ModelBlender() : + _pendingBlenders(0) { +} + +ModelBlender::~ModelBlender() { +} + +void ModelBlender::noteRequiresBlend(Model* model) { + if (_pendingBlenders < QThread::idealThreadCount()) { + if (model->maybeStartBlender()) { + _pendingBlenders++; + } + return; + } + if (!_modelsRequiringBlends.contains(model)) { + _modelsRequiringBlends.append(model); + } +} + +void ModelBlender::setBlendedVertices(const QPointer& model, int blendNumber, + const QWeakPointer& geometry, const QVector& vertices, const QVector& normals) { + if (!model.isNull()) { + model->setBlendedVertices(blendNumber, geometry, vertices, normals); + } + _pendingBlenders--; + while (!_modelsRequiringBlends.isEmpty()) { + Model* nextModel = _modelsRequiringBlends.takeFirst(); + if (nextModel && nextModel->maybeStartBlender()) { + _pendingBlenders++; + return; + } + } +} + diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index e875c8f06c..6b097527ae 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -19,6 +19,7 @@ #include "Transform.h" #include #include +#include #include #include @@ -453,12 +454,33 @@ private: static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args); - }; Q_DECLARE_METATYPE(QPointer) Q_DECLARE_METATYPE(QWeakPointer) Q_DECLARE_METATYPE(QVector) +/// Handle management of pending models that need blending +class ModelBlender : public QObject { + Q_OBJECT + SINGLETON_DEPENDENCY(ModelBlender) + +public: + + /// Adds the specified model to the list requiring vertex blends. + void noteRequiresBlend(Model* model); + +public slots: + void setBlendedVertices(const QPointer& model, int blendNumber, const QWeakPointer& geometry, + const QVector& vertices, const QVector& normals); + +private: + ModelBlender(); + virtual ~ModelBlender(); + + QList > _modelsRequiringBlends; + int _pendingBlenders; +}; + #endif // hifi_Model_h diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index ec07d22647..123a8a5384 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -12,16 +12,17 @@ // include this before QGLWidget, which includes an earlier version of OpenGL #include "InterfaceConfig.h" +#include #include #include #include +#include #include #include #include #include -#include "Application.h" #include "TextureCache.h" TextureCache::TextureCache() : @@ -35,7 +36,8 @@ TextureCache::TextureCache() : _secondaryFramebufferObject(NULL), _tertiaryFramebufferObject(NULL), _shadowFramebufferObject(NULL), - _frameBufferSize(100, 100) + _frameBufferSize(100, 100), + _associatedWidget(NULL) { } @@ -350,9 +352,16 @@ QSharedPointer TextureCache::createResource(const QUrl& url, &Resource::allReferencesCleared); } +void TextureCache::associateWithWidget(QGLWidget* widget) { + if (_associatedWidget) { + _associatedWidget->removeEventFilter(this); + } + _associatedWidget = widget; + _associatedWidget->installEventFilter(this); +} + QOpenGLFramebufferObject* TextureCache::createFramebufferObject() { QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(_frameBufferSize); - DependencyManager::get()->installEventFilter(this); glBindTexture(GL_TEXTURE_2D, fbo->texture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index 66734da9cd..a8b5069897 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -14,7 +14,9 @@ #include #include +#include +#include #include #include "InterfaceConfig.h" @@ -30,11 +32,11 @@ enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_T /// Stores cached textures, including render-to-texture targets. class TextureCache : public ResourceCache { Q_OBJECT + SINGLETON_DEPENDENCY(TextureCache) public: - - TextureCache(); - virtual ~TextureCache(); + + void associateWithWidget(QGLWidget* widget); /// Sets the desired texture resolution for the framebuffer objects. void setFrameBufferSize(QSize frameBufferSize); @@ -93,7 +95,8 @@ protected: const QSharedPointer& fallback, bool delayLoad, const void* extra); private: - + TextureCache(); + virtual ~TextureCache(); friend class DilatableNetworkTexture; QOpenGLFramebufferObject* createFramebufferObject(); @@ -115,6 +118,7 @@ private: GLuint _shadowDepthTextureID; QSize _frameBufferSize; + QGLWidget* _associatedWidget; }; /// A simple object wrapper for an OpenGL texture. diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index d84fc97cd8..15372dc057 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -201,7 +201,7 @@ void WindowScriptingInterface::showNonBlockingForm(const QString& title, QScript } // what should we do if someone calls us while we still think we have a dialog showing??? - if (_editDialog) { + if (_nonBlockingFormActive) { qDebug() << "Show Non-Blocking Form called when form already active."; return; } diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index 75f2ebf97f..31bc80b5de 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -354,7 +354,7 @@ void MetavoxelEditor::render() { _gridProgram.bind(); - Application::getInstance()->getGeometryCache()->renderGrid(GRID_DIVISIONS, GRID_DIVISIONS); + DependencyManager::get()->renderGrid(GRID_DIVISIONS, GRID_DIVISIONS); _gridProgram.release(); @@ -917,7 +917,7 @@ void MaterialControl::updateTexture() { _texture.clear(); return; } - _texture = Application::getInstance()->getTextureCache()->getTexture(material->getDiffuse(), SPLAT_TEXTURE); + _texture = DependencyManager::get()->getTexture(material->getDiffuse(), SPLAT_TEXTURE); if (_texture) { if (_texture->isLoaded()) { textureLoaded(); diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index 03daef934d..c095a544b7 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -16,7 +16,7 @@ #include #include "Base3DOverlay.h" -#include "../../renderer/TextureCache.h" +#include "renderer/TextureCache.h" class BillboardOverlay : public Base3DOverlay { Q_OBJECT diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 4bf0d9ce93..d1086ae534 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -87,7 +87,7 @@ void Grid3DOverlay::render(RenderArgs* args) { float scale = MINOR_GRID_DIVISIONS * spacing; glScalef(scale, scale, scale); - Application::getInstance()->getGeometryCache()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS); + DependencyManager::get()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS); } glPopMatrix(); @@ -102,7 +102,7 @@ void Grid3DOverlay::render(RenderArgs* args) { float scale = MAJOR_GRID_DIVISIONS * spacing; glScalef(scale, scale, scale); - Application::getInstance()->getGeometryCache()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS); + DependencyManager::get()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS); } glPopMatrix(); diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 34064675e5..ded1b3917c 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -63,7 +63,7 @@ void Sphere3DOverlay::render(RenderArgs* args) { glScalef(dimensions.x, dimensions.y, dimensions.z); //Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); if (_isSolid) { - Application::getInstance()->getGeometryCache()->renderSphere(1.0f, SLICES, SLICES); + DependencyManager::get()->renderSphere(1.0f, SLICES, SLICES); } else { glutWireSphere(1.0f, SLICES, SLICES); } diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 67f3d585ea..357bfe9c3e 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -9,7 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - #include #include #include // to load voxels from file @@ -1171,7 +1170,7 @@ void VoxelSystem::render() { void VoxelSystem::applyScaleAndBindProgram(bool texture) { if (texture) { bindPerlinModulateProgram(); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID()); + glBindTexture(GL_TEXTURE_2D, DependencyManager::get()->getPermutationNormalTextureID()); } else { _program.bind(); } @@ -1179,7 +1178,7 @@ void VoxelSystem::applyScaleAndBindProgram(bool texture) { glPushMatrix(); glScalef(_treeScale, _treeScale, _treeScale); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); + DependencyManager::get()->setPrimaryDrawBuffers(true, true); } void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { @@ -1193,7 +1192,7 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { _program.release(); } - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); + DependencyManager::get()->setPrimaryDrawBuffers(true, false); } int VoxelSystem::_nodeCount = 0; diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index f033ffa80f..9239527df3 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -62,7 +62,7 @@ public: float getNextOutputFrameLoudness() const; int samplesAvailable() const; - int framesAvailable() const { return samplesAvailable() / _numFrameSamples; } + int framesAvailable() const { return (_numFrameSamples == 0) ? 0 : samplesAvailable() / _numFrameSamples; } int getNumFrameSamples() const { return _numFrameSamples; } diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 097ede23d0..5bb327fe63 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -28,9 +28,13 @@ ResourceCache::ResourceCache(QObject* parent) : } ResourceCache::~ResourceCache() { - // make sure our unused resources know we're out of commission - foreach (const QSharedPointer& resource, _unusedResources) { - resource->setCache(NULL); + // the unused resources may themselves reference resources that will be added to the unused + // list on destruction, so keep clearing until there are no references left + while (!_unusedResources.isEmpty()) { + foreach (const QSharedPointer& resource, _unusedResources) { + resource->setCache(NULL); + } + _unusedResources.clear(); } }